social components
inlay.at
atproto
components
sdui
1#!/bin/bash
2# Cross-platform sed -i wrapper (macOS needs '' arg, Linux doesn't)
3sedi() { if [[ "$OSTYPE" == darwin* ]]; then sed -i '' "$@"; else sed -i "$@"; fi; }
4
5# Patch React RSC dev runtime to prevent O(n^2) memory growth.
6#
7# Root cause: In dev mode, React serializes full component props into debug
8# chunks via componentDebugInfo.props=props. As the component tree grows,
9# each component's debug info includes references to ancestor data, causing
10# super-linear memory growth. With ~100 components, the server OOMs at 2GB+.
11#
12# Fix: Replace props=props with props={} in the debug info assignment.
13# This preserves all other debug functionality (component names, stack traces,
14# owner chains) while preventing the quadratic memory explosion.
15#
16# Affects: next/dist/compiled/next-server/app-page-turbo.runtime.dev.js
17# (the actual RSC server runtime loaded by Turbopack in dev mode)
18
19TARGET="node_modules/next/dist/compiled/next-server/app-page-turbo.runtime.dev.js"
20
21if [ ! -f "$TARGET" ]; then
22 echo "[patch-next] Target file not found: $TARGET"
23 exit 0
24fi
25
26SEARCH="componentDebugInfo.props=props,componentDebugInfo.debugStack"
27REPLACE="componentDebugInfo.props={},componentDebugInfo.debugStack"
28
29if grep -q "$REPLACE" "$TARGET"; then
30 echo "[patch-next] OOM patch already applied."
31elif ! grep -q "$SEARCH" "$TARGET"; then
32 echo "[patch-next] WARNING: Search string not found — Next.js version may have changed."
33else
34 sedi "s|$SEARCH|$REPLACE|" "$TARGET"
35 echo "[patch-next] Patched componentDebugInfo.props to prevent RSC dev-mode OOM."
36fi
37
38# ---------------------------------------------------------------------------
39# Patch 2: Fix incomplete hook chain on unwind (React #33580)
40#
41# When a component suspends mid-render, the work-in-progress fiber has an
42# incomplete hook chain. If this fiber is later committed (e.g. Suspense
43# fallback), the incomplete chain replaces the current fiber's complete chain,
44# causing "Rendered more hooks than during the previous render" on re-render.
45#
46# Fix: In resetHooksOnUnwind, clone remaining hooks from the current fiber
47# onto the work-in-progress chain before clearing state.
48# ---------------------------------------------------------------------------
49
50HOOKS_SEARCH='function resetHooksOnUnwind(workInProgress) {'
51HOOKS_INSERT='if (currentHook !== null \&\& workInProgressHook !== null) { var nextCurrentHook = currentHook.next; if (nextCurrentHook !== null) { var tail = workInProgressHook; while (nextCurrentHook !== null) { var clone = { memoizedState: nextCurrentHook.memoizedState, baseState: nextCurrentHook.baseState, baseQueue: nextCurrentHook.baseQueue, queue: nextCurrentHook.queue, next: null }; tail = tail.next = clone; nextCurrentHook = nextCurrentHook.next; } } }'
52HOOKS_PATCHED=0
53
54for f in node_modules/next/dist/compiled/react-dom/cjs/react-dom-client.production.js \
55 node_modules/next/dist/compiled/react-dom/cjs/react-dom-client.development.js \
56 node_modules/next/dist/compiled/react-dom/cjs/react-dom-profiling.profiling.js \
57 node_modules/next/dist/compiled/react-dom/cjs/react-dom-profiling.development.js \
58 node_modules/next/dist/compiled/react-dom-experimental/cjs/react-dom-client.production.js \
59 node_modules/next/dist/compiled/react-dom-experimental/cjs/react-dom-client.development.js \
60 node_modules/next/dist/compiled/react-dom-experimental/cjs/react-dom-profiling.profiling.js \
61 node_modules/next/dist/compiled/react-dom-experimental/cjs/react-dom-profiling.development.js \
62 node_modules/next/dist/compiled/react-dom-experimental/cjs/react-dom-unstable_testing.production.js \
63 node_modules/next/dist/compiled/react-dom-experimental/cjs/react-dom-unstable_testing.development.js; do
64 [ ! -f "$f" ] && continue
65 # Skip if already patched
66 grep -q 'clone remaining hooks from current fiber' "$f" 2>/dev/null && continue
67 if ! grep -q "$HOOKS_SEARCH" "$f"; then
68 echo "[patch-next] WARNING: resetHooksOnUnwind not found in $f"
69 continue
70 fi
71 # Insert the fix after the function opening brace
72 sedi "s|$HOOKS_SEARCH|$HOOKS_SEARCH /* clone remaining hooks from current fiber (#33580) */ $HOOKS_INSERT|" "$f"
73 HOOKS_PATCHED=$((HOOKS_PATCHED + 1))
74done
75
76if [ "$HOOKS_PATCHED" -gt 0 ]; then
77 echo "[patch-next] Patched resetHooksOnUnwind in $HOOKS_PATCHED files (React #33580)."
78else
79 echo "[patch-next] resetHooksOnUnwind already patched or not found."
80fi
81
82# ---------------------------------------------------------------------------
83# Patch 3: Suppress INLAY_MISSING errors from dev error overlay
84#
85# We use errors with digest starting with "INLAY_MISSING" as control flow
86# (similar to how Next.js uses NEXT_REDIRECT / NEXT_NOT_FOUND). These get
87# caught by our error boundaries and rendered as placeholder UI, but the
88# dev overlay still picks them up and shows a red error screen.
89#
90# Fix: In the React root error callbacks (onCaughtError / onUncaughtError),
91# add an INLAY_MISSING digest check alongside the existing isNextRouterError
92# check so these errors are suppressed from the overlay.
93# ---------------------------------------------------------------------------
94
95OVERLAY_TARGET="node_modules/next/dist/client/react-client-callbacks/error-boundary-callbacks.js"
96OVERLAY_SEARCH='isNextRouterError)(thrownValue)) return'
97OVERLAY_REPLACE='isNextRouterError)(thrownValue) || thrownValue?.digest?.startsWith("INLAY_MISSING")) return'
98
99if [ ! -f "$OVERLAY_TARGET" ]; then
100 echo "[patch-next] error-boundary-callbacks.js not found, skipping overlay patch."
101elif grep -q 'INLAY_MISSING' "$OVERLAY_TARGET"; then
102 echo "[patch-next] INLAY_MISSING overlay patch already applied."
103elif ! grep -qF "$OVERLAY_SEARCH" "$OVERLAY_TARGET"; then
104 echo "[patch-next] WARNING: overlay patch search string not found — Next.js version may have changed."
105else
106 sedi "s#$OVERLAY_SEARCH#$OVERLAY_REPLACE#g" "$OVERLAY_TARGET"
107 echo "[patch-next] Patched error-boundary-callbacks.js to suppress INLAY_MISSING from dev overlay."
108fi