@tanstack/redact 0.0.20 → 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (253) hide show
  1. package/dist/core/attributes.js +2 -1
  2. package/dist/core/attributes.js.map +2 -2
  3. package/dist/core/browser.d.ts +9 -0
  4. package/dist/core/browser.js +35 -0
  5. package/dist/core/browser.js.map +7 -0
  6. package/dist/core/index.d.ts +2 -2
  7. package/dist/core/index.js +3 -3
  8. package/dist/core/internal.d.ts +31 -8
  9. package/dist/core/internal.js +3 -1
  10. package/dist/core/internal.js.map +2 -2
  11. package/dist/core/resource-hints.d.ts +7 -0
  12. package/dist/core/resource-hints.js +19 -0
  13. package/dist/core/resource-hints.js.map +7 -0
  14. package/dist/core/types.js +1 -1
  15. package/dist/dom/_all.d.ts +11 -16
  16. package/dist/dom/_all.js +9 -20
  17. package/dist/dom/_all.js.map +2 -2
  18. package/dist/dom/client.d.ts +4 -4
  19. package/dist/dom/client.js +4 -4
  20. package/dist/dom/commit.d.ts +23 -0
  21. package/dist/dom/commit.js +191 -0
  22. package/dist/dom/commit.js.map +7 -0
  23. package/dist/dom/dispatcher.d.ts +4 -22
  24. package/dist/dom/dispatcher.js +184 -126
  25. package/dist/dom/dispatcher.js.map +3 -3
  26. package/dist/dom/dom.d.ts +2 -0
  27. package/dist/dom/dom.js +72 -52
  28. package/dist/dom/dom.js.map +2 -2
  29. package/dist/dom/error-info.d.ts +2 -0
  30. package/dist/dom/error-info.js +16 -0
  31. package/dist/dom/error-info.js.map +7 -0
  32. package/dist/dom/event-replay.js +1 -1
  33. package/dist/dom/features/activity/full.d.ts +1 -0
  34. package/dist/dom/features/activity/full.js +162 -0
  35. package/dist/dom/features/activity/full.js.map +7 -0
  36. package/dist/dom/features/activity/index.d.ts +1 -0
  37. package/dist/dom/features/activity/index.js +3 -0
  38. package/dist/dom/features/activity/index.js.map +7 -0
  39. package/dist/dom/features/activity/stub.d.ts +1 -0
  40. package/dist/dom/features/activity/stub.js +12 -0
  41. package/dist/dom/features/activity/stub.js.map +7 -0
  42. package/dist/dom/features/class/full.js +87 -21
  43. package/dist/dom/features/class/full.js.map +2 -2
  44. package/dist/dom/features/class/index.d.ts +1 -1
  45. package/dist/dom/features/class/index.js +2 -2
  46. package/dist/dom/features/class/stub.js +3 -3
  47. package/dist/dom/features/context/full.d.ts +4 -1
  48. package/dist/dom/features/context/full.js +69 -9
  49. package/dist/dom/features/context/full.js.map +2 -2
  50. package/dist/dom/features/context/index.d.ts +1 -1
  51. package/dist/dom/features/context/index.js +2 -2
  52. package/dist/dom/features/context/stub.d.ts +4 -1
  53. package/dist/dom/features/context/stub.js +15 -4
  54. package/dist/dom/features/context/stub.js.map +2 -2
  55. package/dist/dom/features/forward-ref/full.js +12 -21
  56. package/dist/dom/features/forward-ref/full.js.map +2 -2
  57. package/dist/dom/features/forward-ref/index.d.ts +1 -1
  58. package/dist/dom/features/forward-ref/index.js +2 -2
  59. package/dist/dom/features/forward-ref/stub.js +4 -4
  60. package/dist/dom/features/fragment-refs/index.d.ts +1 -0
  61. package/dist/dom/features/fragment-refs/index.js +8 -0
  62. package/dist/dom/features/fragment-refs/index.js.map +7 -0
  63. package/dist/dom/features/fragment-refs/stub.d.ts +3 -0
  64. package/dist/dom/features/fragment-refs/stub.js +14 -0
  65. package/dist/dom/features/fragment-refs/stub.js.map +7 -0
  66. package/dist/dom/features/hydration/full.d.ts +11 -6
  67. package/dist/dom/features/hydration/full.js +76 -76
  68. package/dist/dom/features/hydration/full.js.map +2 -2
  69. package/dist/dom/features/hydration/index.d.ts +1 -1
  70. package/dist/dom/features/hydration/index.js +2 -2
  71. package/dist/dom/features/hydration/stub.d.ts +7 -2
  72. package/dist/dom/features/hydration/stub.js +1 -1
  73. package/dist/dom/features/hydration/stub.js.map +1 -1
  74. package/dist/dom/features/index.d.ts +8 -7
  75. package/dist/dom/features/index.js +9 -8
  76. package/dist/dom/features/index.js.map +2 -2
  77. package/dist/dom/features/lazy/full.js +4 -4
  78. package/dist/dom/features/lazy/index.d.ts +1 -1
  79. package/dist/dom/features/lazy/index.js +2 -2
  80. package/dist/dom/features/lazy/stub.js +4 -4
  81. package/dist/dom/features/memo/full.js +8 -6
  82. package/dist/dom/features/memo/full.js.map +2 -2
  83. package/dist/dom/features/memo/index.d.ts +1 -1
  84. package/dist/dom/features/memo/index.js +2 -2
  85. package/dist/dom/features/memo/stub.js +4 -4
  86. package/dist/dom/features/portal/full.js +4 -4
  87. package/dist/dom/features/portal/index.d.ts +1 -1
  88. package/dist/dom/features/portal/index.js +2 -2
  89. package/dist/dom/features/portal/stub.js +4 -4
  90. package/dist/dom/features/suspense/full.js +192 -47
  91. package/dist/dom/features/suspense/full.js.map +2 -2
  92. package/dist/dom/features/suspense/index.d.ts +1 -1
  93. package/dist/dom/features/suspense/index.js +2 -2
  94. package/dist/dom/features/suspense/stub.js +4 -4
  95. package/dist/dom/features/view-transition/full.d.ts +6 -0
  96. package/dist/dom/features/view-transition/full.js +280 -0
  97. package/dist/dom/features/view-transition/full.js.map +7 -0
  98. package/dist/dom/features/view-transition/index.d.ts +1 -0
  99. package/dist/dom/features/view-transition/index.js +3 -0
  100. package/dist/dom/features/view-transition/index.js.map +7 -0
  101. package/dist/dom/features/view-transition/resources.d.ts +11 -0
  102. package/dist/dom/features/view-transition/resources.js +108 -0
  103. package/dist/dom/features/view-transition/resources.js.map +7 -0
  104. package/dist/dom/features/view-transition/stub.d.ts +6 -0
  105. package/dist/dom/features/view-transition/stub.js +22 -0
  106. package/dist/dom/features/view-transition/stub.js.map +7 -0
  107. package/dist/dom/features/view-transition/visual.d.ts +14 -0
  108. package/dist/dom/features/view-transition/visual.js +356 -0
  109. package/dist/dom/features/view-transition/visual.js.map +7 -0
  110. package/dist/dom/fragment-instance.d.ts +40 -0
  111. package/dist/dom/fragment-instance.js +324 -0
  112. package/dist/dom/fragment-instance.js.map +7 -0
  113. package/dist/dom/index.d.ts +11 -11
  114. package/dist/dom/index.js +11 -18
  115. package/dist/dom/index.js.map +3 -3
  116. package/dist/dom/portal.d.ts +2 -2
  117. package/dist/dom/portal.js +2 -2
  118. package/dist/dom/portal.js.map +1 -1
  119. package/dist/dom/reconcile.d.ts +32 -3
  120. package/dist/dom/reconcile.js +686 -222
  121. package/dist/dom/reconcile.js.map +2 -2
  122. package/dist/dom/resource-hints.d.ts +6 -0
  123. package/dist/dom/resource-hints.js +115 -0
  124. package/dist/dom/resource-hints.js.map +7 -0
  125. package/dist/dom/resource-store.d.ts +13 -0
  126. package/dist/dom/resource-store.js +43 -0
  127. package/dist/dom/resource-store.js.map +7 -0
  128. package/dist/dom/resources.d.ts +1 -0
  129. package/dist/dom/resources.js +44 -0
  130. package/dist/dom/resources.js.map +7 -0
  131. package/dist/dom/retained-effects.d.ts +6 -0
  132. package/dist/dom/retained-effects.js +49 -0
  133. package/dist/dom/retained-effects.js.map +7 -0
  134. package/dist/dom/root-internal.d.ts +4 -4
  135. package/dist/dom/root-internal.js +2 -2
  136. package/dist/dom/root-internal.js.map +2 -2
  137. package/dist/dom/root.d.ts +5 -5
  138. package/dist/dom/root.js +11 -11
  139. package/dist/dom/root.js.map +2 -2
  140. package/dist/dom/test-utils.js +1 -1
  141. package/dist/react/activity.d.ts +7 -0
  142. package/dist/react/activity.js +8 -0
  143. package/dist/react/activity.js.map +7 -0
  144. package/dist/react/children.d.ts +1 -1
  145. package/dist/react/children.js +3 -3
  146. package/dist/react/children.js.map +1 -1
  147. package/dist/react/class.d.ts +1 -1
  148. package/dist/react/class.js +3 -3
  149. package/dist/react/class.js.map +1 -1
  150. package/dist/react/compiler-runtime.js +2 -2
  151. package/dist/react/context.d.ts +1 -1
  152. package/dist/react/context.js +3 -3
  153. package/dist/react/context.js.map +1 -1
  154. package/dist/react/element.d.ts +6 -3
  155. package/dist/react/element.js +2 -2
  156. package/dist/react/element.js.map +2 -2
  157. package/dist/react/hooks.d.ts +26 -7
  158. package/dist/react/hooks.js +13 -3
  159. package/dist/react/hooks.js.map +2 -2
  160. package/dist/react/index.d.ts +39 -24
  161. package/dist/react/index.js +39 -19
  162. package/dist/react/index.js.map +3 -3
  163. package/dist/react/jsx-runtime.d.ts +2 -2
  164. package/dist/react/jsx-runtime.js +3 -3
  165. package/dist/react/memo.d.ts +1 -1
  166. package/dist/react/memo.js +1 -1
  167. package/dist/react/portal.js +1 -1
  168. package/dist/react/shared-internals.d.ts +15 -5
  169. package/dist/react/shared-internals.js +2 -3
  170. package/dist/react/shared-internals.js.map +2 -2
  171. package/dist/react/suspense.js +1 -1
  172. package/dist/react/view-transition.d.ts +32 -0
  173. package/dist/react/view-transition.js +13 -0
  174. package/dist/react/view-transition.js.map +7 -0
  175. package/dist/scheduler/index.js +1 -1
  176. package/dist/server/bootstrap-script.d.ts +1 -23
  177. package/dist/server/bootstrap-script.js +7 -6
  178. package/dist/server/bootstrap-script.js.map +2 -2
  179. package/dist/server/dispatcher.d.ts +28 -6
  180. package/dist/server/dispatcher.js +33 -15
  181. package/dist/server/dispatcher.js.map +2 -2
  182. package/dist/server/escape.js +16 -15
  183. package/dist/server/escape.js.map +2 -2
  184. package/dist/server/index.d.ts +6 -6
  185. package/dist/server/index.js +7 -7
  186. package/dist/server/renderToString.d.ts +1 -1
  187. package/dist/server/renderToString.js +12 -8
  188. package/dist/server/renderToString.js.map +2 -2
  189. package/dist/server/resource-hints.d.ts +22 -0
  190. package/dist/server/resource-hints.js +148 -0
  191. package/dist/server/resource-hints.js.map +7 -0
  192. package/dist/server/stream.d.ts +15 -2
  193. package/dist/server/stream.js +155 -63
  194. package/dist/server/stream.js.map +2 -2
  195. package/dist/server/walk.d.ts +15 -2
  196. package/dist/server/walk.js +143 -96
  197. package/dist/server/walk.js.map +2 -2
  198. package/dist/vite/index.d.ts +6 -0
  199. package/dist/vite/index.js +22 -6
  200. package/dist/vite/index.js.map +2 -2
  201. package/package.json +1 -1
  202. package/src/core/attributes.ts +1 -0
  203. package/src/core/browser.ts +33 -0
  204. package/src/core/internal.ts +24 -6
  205. package/src/core/resource-hints.ts +36 -0
  206. package/src/dom/_all.ts +1 -7
  207. package/src/dom/commit.ts +186 -0
  208. package/src/dom/dispatcher.ts +190 -134
  209. package/src/dom/dom.ts +70 -54
  210. package/src/dom/error-info.ts +15 -0
  211. package/src/dom/features/activity/full.ts +166 -0
  212. package/src/dom/features/activity/index.ts +1 -0
  213. package/src/dom/features/activity/stub.ts +14 -0
  214. package/src/dom/features/class/full.ts +72 -21
  215. package/src/dom/features/context/full.ts +66 -4
  216. package/src/dom/features/context/stub.ts +6 -0
  217. package/src/dom/features/forward-ref/full.ts +9 -19
  218. package/src/dom/features/fragment-refs/index.ts +1 -0
  219. package/src/dom/features/fragment-refs/stub.ts +3 -0
  220. package/src/dom/features/hydration/full.ts +84 -82
  221. package/src/dom/features/hydration/stub.ts +1 -1
  222. package/src/dom/features/index.ts +1 -0
  223. package/src/dom/features/memo/full.ts +4 -3
  224. package/src/dom/features/suspense/full.ts +187 -50
  225. package/src/dom/features/view-transition/full.ts +288 -0
  226. package/src/dom/features/view-transition/index.ts +1 -0
  227. package/src/dom/features/view-transition/resources.ts +107 -0
  228. package/src/dom/features/view-transition/stub.ts +7 -0
  229. package/src/dom/features/view-transition/visual.ts +406 -0
  230. package/src/dom/fragment-instance.ts +337 -0
  231. package/src/dom/index.ts +6 -7
  232. package/src/dom/portal.ts +1 -1
  233. package/src/dom/reconcile.ts +691 -244
  234. package/src/dom/resource-hints.ts +115 -0
  235. package/src/dom/resource-store.ts +52 -0
  236. package/src/dom/resources.ts +39 -0
  237. package/src/dom/retained-effects.ts +38 -0
  238. package/src/dom/root-internal.ts +4 -4
  239. package/src/dom/root.ts +12 -14
  240. package/src/react/activity.ts +10 -0
  241. package/src/react/element.ts +6 -2
  242. package/src/react/hooks.ts +12 -3
  243. package/src/react/index.ts +18 -0
  244. package/src/react/shared-internals.ts +3 -3
  245. package/src/react/view-transition.ts +41 -0
  246. package/src/server/bootstrap-script.ts +36 -5
  247. package/src/server/dispatcher.ts +35 -13
  248. package/src/server/escape.ts +15 -12
  249. package/src/server/renderToString.ts +7 -5
  250. package/src/server/resource-hints.ts +165 -0
  251. package/src/server/stream.ts +154 -62
  252. package/src/server/walk.ts +72 -11
  253. package/src/vite/index.ts +30 -13
@@ -1,9 +1,10 @@
1
- // packages/redact/src/dom/features/index.ts
2
- import "./portal";
3
- import "./context";
4
- import "./suspense";
5
- import "./memo";
6
- import "./forward-ref";
7
- import "./lazy";
8
- import "./class";
1
+ // src/dom/features/index.ts
2
+ import "./portal/index.js";
3
+ import "./context/index.js";
4
+ import "./suspense/index.js";
5
+ import "./memo/index.js";
6
+ import "./forward-ref/index.js";
7
+ import "./lazy/index.js";
8
+ import "./class/index.js";
9
+ import "./activity/index.js";
9
10
  //# sourceMappingURL=index.js.map
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../src/dom/features/index.ts"],
4
- "sourcesContent": ["// Feature wiring. Each import is a side-effect import that triggers the\n// feature module's self-registration with the reconciler (renderer, type\n// matcher, element marker). A vite plugin can swap any entry to './stub'\n// to disable that feature in the emitted bundle.\nimport './portal'\nimport './context'\nimport './suspense'\nimport './memo'\nimport './forward-ref'\nimport './lazy'\nimport './class'\n"],
5
- "mappings": ";AAIA,OAAO;AACP,OAAO;AACP,OAAO;AACP,OAAO;AACP,OAAO;AACP,OAAO;AACP,OAAO;",
4
+ "sourcesContent": ["// Feature wiring. Each import is a side-effect import that triggers the\n// feature module's self-registration with the reconciler (renderer, type\n// matcher, element marker). A vite plugin can swap any entry to './stub'\n// to disable that feature in the emitted bundle.\nimport './portal'\nimport './context'\nimport './suspense'\nimport './memo'\nimport './forward-ref'\nimport './lazy'\nimport './class'\nimport './activity'\n"],
5
+ "mappings": ";AAIA,OAAO;AACP,OAAO;AACP,OAAO;AACP,OAAO;AACP,OAAO;AACP,OAAO;AACP,OAAO;AACP,OAAO;",
6
6
  "names": []
7
7
  }
@@ -1,6 +1,6 @@
1
- // packages/redact/src/dom/features/lazy/full.ts
2
- import { FiberTag } from "../../../core";
3
- import { REACT_LAZY_TYPE } from "../../../react";
1
+ // src/dom/features/lazy/full.ts
2
+ import { FiberTag } from "../../../core/index.js";
3
+ import { REACT_LAZY_TYPE } from "../../../react/index.js";
4
4
  import {
5
5
  registerRenderer,
6
6
  registerTypeMatcher,
@@ -8,7 +8,7 @@ import {
8
8
  isThenable,
9
9
  handleSuspended,
10
10
  deferHydration
11
- } from "../../reconcile";
11
+ } from "../../reconcile.js";
12
12
  function renderLazy(fiber, domParent, anchor) {
13
13
  const { _payload, _init } = fiber.type;
14
14
  let resolved;
@@ -1 +1 @@
1
- export * from './full';
1
+ export * from "./full.js";
@@ -1,3 +1,3 @@
1
- // packages/redact/src/dom/features/lazy/index.ts
2
- export * from "./full";
1
+ // src/dom/features/lazy/index.ts
2
+ export * from "./full.js";
3
3
  //# sourceMappingURL=index.js.map
@@ -1,13 +1,13 @@
1
- // packages/redact/src/dom/features/lazy/stub.ts
2
- import { FiberTag } from "../../../core";
3
- import { REACT_LAZY_TYPE } from "../../../react";
1
+ // src/dom/features/lazy/stub.ts
2
+ import { FiberTag } from "../../../core/index.js";
3
+ import { REACT_LAZY_TYPE } from "../../../react/index.js";
4
4
  import {
5
5
  registerRenderer,
6
6
  registerTypeMatcher,
7
7
  renderFiber,
8
8
  isThenable,
9
9
  handleSuspended
10
- } from "../../reconcile";
10
+ } from "../../reconcile.js";
11
11
  function renderLazyStub(fiber, domParent, anchor) {
12
12
  const { _payload, _init } = fiber.type;
13
13
  let resolved;
@@ -1,16 +1,17 @@
1
- // packages/redact/src/dom/features/memo/full.ts
2
- import { FiberTag } from "../../../core";
1
+ // src/dom/features/memo/full.ts
2
+ import { FiberTag } from "../../../core/index.js";
3
3
  import {
4
4
  REACT_FORWARD_REF_TYPE,
5
5
  REACT_MEMO_TYPE,
6
6
  REACT_LAZY_TYPE
7
- } from "../../../react";
7
+ } from "../../../react/index.js";
8
8
  import {
9
9
  registerRenderer,
10
10
  registerTypeMatcher,
11
11
  renderFiber,
12
12
  getForceRerenderingFiber
13
- } from "../../reconcile";
13
+ } from "../../reconcile.js";
14
+ import { ownContextChanged, renderContextConsumers } from "../context/index.js";
14
15
  function shallowEqual(a, b) {
15
16
  if (a === b) return true;
16
17
  if (!a || !b) return false;
@@ -26,9 +27,10 @@ function renderMemo(fiber, domParent, anchor) {
26
27
  const { type, compare } = fiber.type;
27
28
  const props = fiber.pp ?? {};
28
29
  const prev = fiber.mp;
29
- const bypassMemo = fiber === getForceRerenderingFiber();
30
+ const bypassMemo = fiber.dy || fiber === getForceRerenderingFiber();
30
31
  const eq = !bypassMemo && prev && (compare ? compare(prev, props) : shallowEqual(prev, props));
31
- if (eq) {
32
+ if (eq && !ownContextChanged(fiber)) {
33
+ renderContextConsumers(fiber);
32
34
  return;
33
35
  }
34
36
  let innerTag;
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../src/dom/features/memo/full.ts"],
4
- "sourcesContent": ["import { FiberTag, type Fiber } from '../../../core'\nimport {\n REACT_FORWARD_REF_TYPE,\n REACT_MEMO_TYPE,\n REACT_LAZY_TYPE,\n} from '../../../react'\nimport {\n registerRenderer,\n registerTypeMatcher,\n renderFiber,\n getForceRerenderingFiber,\n} from '../../reconcile'\n\nfunction shallowEqual(a: any, b: any): boolean {\n if (a === b) return true\n if (!a || !b) return false\n const ak = Object.keys(a)\n const bk = Object.keys(b)\n if (ak.length !== bk.length) return false\n for (const k of ak) {\n if (a[k] !== b[k]) return false\n }\n return true\n}\n\nfunction renderMemo(fiber: Fiber, domParent: Node, anchor: Node | null): void {\n const { type, compare } = fiber.type as any\n const props = fiber.pp ?? {}\n const prev = fiber.mp\n\n // Memo's prop-equality gate guards PARENT-triggered rerenders. If this\n // render is a STATE-triggered rerender of this exact fiber (hook update,\n // useSyncExternalStore notification), props haven't changed by definition \u2014\n // bailing would swallow the state change and the subscriber never re-runs.\n // rerenderFiber tags the fiber so we skip the gate here.\n const bypassMemo = fiber === getForceRerenderingFiber()\n const eq = !bypassMemo && prev && (compare ? compare(prev, props) : shallowEqual(prev, props))\n if (eq) {\n // Re-render children with previous output (already in tree)\n return\n }\n\n // Determine the delegated tag based on the memoized type. `React.memo` can\n // wrap plain functions, class components, OR other special types like\n // `forwardRef`. Without the marker-based branch we'd mistreat\n // `memo(forwardRef(...))` as a Fragment and render nothing.\n let innerTag: FiberTag\n if (typeof type == 'function') {\n innerTag = type.prototype?.isReactComponent ? FiberTag.Class : FiberTag.Function\n } else if (type && typeof type === 'object') {\n const m = (type as any).$$typeof\n if (m === REACT_FORWARD_REF_TYPE) innerTag = FiberTag.ForwardRef\n else if (m === REACT_MEMO_TYPE) innerTag = FiberTag.Memo\n else if (m === REACT_LAZY_TYPE) innerTag = FiberTag.Lazy\n else innerTag = FiberTag.Fragment\n } else {\n innerTag = FiberTag.Fragment\n }\n\n // Swap tag and type for this render pass; this is a \"delegating\" render\n const savedTag = fiber.tag\n const savedType = fiber.type\n fiber.tag = innerTag\n fiber.type = type\n try {\n renderFiber(fiber, domParent, anchor)\n } finally {\n fiber.tag = savedTag\n fiber.type = savedType\n }\n}\n\nregisterTypeMatcher((_type, marker) => (marker === REACT_MEMO_TYPE ? FiberTag.Memo : null))\nregisterRenderer(FiberTag.Memo, renderMemo)\n"],
5
- "mappings": ";AAAA,SAAS,gBAA4B;AACrC;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,OACK;AACP;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AAEP,SAAS,aAAa,GAAQ,GAAiB;AAC7C,MAAI,MAAM,EAAG,QAAO;AACpB,MAAI,CAAC,KAAK,CAAC,EAAG,QAAO;AACrB,QAAM,KAAK,OAAO,KAAK,CAAC;AACxB,QAAM,KAAK,OAAO,KAAK,CAAC;AACxB,MAAI,GAAG,WAAW,GAAG,OAAQ,QAAO;AACpC,aAAW,KAAK,IAAI;AAClB,QAAI,EAAE,CAAC,MAAM,EAAE,CAAC,EAAG,QAAO;AAAA,EAC5B;AACA,SAAO;AACT;AAEA,SAAS,WAAW,OAAc,WAAiB,QAA2B;AAC5E,QAAM,EAAE,MAAM,QAAQ,IAAI,MAAM;AAChC,QAAM,QAAQ,MAAM,MAAM,CAAC;AAC3B,QAAM,OAAO,MAAM;AAOnB,QAAM,aAAa,UAAU,yBAAyB;AACtD,QAAM,KAAK,CAAC,cAAc,SAAS,UAAU,QAAQ,MAAM,KAAK,IAAI,aAAa,MAAM,KAAK;AAC5F,MAAI,IAAI;AAEN;AAAA,EACF;AAMA,MAAI;AACJ,MAAI,OAAO,QAAQ,YAAY;AAC7B,eAAW,KAAK,WAAW,mBAAmB,SAAS,QAAQ,SAAS;AAAA,EAC1E,WAAW,QAAQ,OAAO,SAAS,UAAU;AAC3C,UAAM,IAAK,KAAa;AACxB,QAAI,MAAM,uBAAwB,YAAW,SAAS;AAAA,aAC7C,MAAM,gBAAiB,YAAW,SAAS;AAAA,aAC3C,MAAM,gBAAiB,YAAW,SAAS;AAAA,QAC/C,YAAW,SAAS;AAAA,EAC3B,OAAO;AACL,eAAW,SAAS;AAAA,EACtB;AAGA,QAAM,WAAW,MAAM;AACvB,QAAM,YAAY,MAAM;AACxB,QAAM,MAAM;AACZ,QAAM,OAAO;AACb,MAAI;AACF,gBAAY,OAAO,WAAW,MAAM;AAAA,EACtC,UAAE;AACA,UAAM,MAAM;AACZ,UAAM,OAAO;AAAA,EACf;AACF;AAEA,oBAAoB,CAAC,OAAO,WAAY,WAAW,kBAAkB,SAAS,OAAO,IAAK;AAC1F,iBAAiB,SAAS,MAAM,UAAU;",
4
+ "sourcesContent": ["import { FiberTag, type Fiber } from '../../../core'\nimport {\n REACT_FORWARD_REF_TYPE,\n REACT_MEMO_TYPE,\n REACT_LAZY_TYPE,\n} from '../../../react'\nimport {\n registerRenderer,\n registerTypeMatcher,\n renderFiber,\n getForceRerenderingFiber,\n} from '../../reconcile'\nimport { ownContextChanged, renderContextConsumers } from '../context'\n\nfunction shallowEqual(a: any, b: any): boolean {\n if (a === b) return true\n if (!a || !b) return false\n const ak = Object.keys(a)\n const bk = Object.keys(b)\n if (ak.length !== bk.length) return false\n for (const k of ak) {\n if (a[k] !== b[k]) return false\n }\n return true\n}\n\nfunction renderMemo(fiber: Fiber, domParent: Node, anchor: Node | null): void {\n const { type, compare } = fiber.type as any\n const props = fiber.pp ?? {}\n const prev = fiber.mp\n\n // Memo's prop-equality gate guards PARENT-triggered rerenders. If this\n // render is a STATE-triggered rerender of this exact fiber (hook update,\n // useSyncExternalStore notification), props haven't changed by definition \u2014\n // bailing would swallow the state change and the subscriber never re-runs.\n // rerenderFiber tags the fiber so we skip the gate here.\n const bypassMemo = fiber.dy || fiber === getForceRerenderingFiber()\n const eq = !bypassMemo && prev && (compare ? compare(prev, props) : shallowEqual(prev, props))\n if (eq && !ownContextChanged(fiber)) {\n renderContextConsumers(fiber)\n return\n }\n\n // Determine the delegated tag based on the memoized type. `React.memo` can\n // wrap plain functions, class components, OR other special types like\n // `forwardRef`. Without the marker-based branch we'd mistreat\n // `memo(forwardRef(...))` as a Fragment and render nothing.\n let innerTag: FiberTag\n if (typeof type == 'function') {\n innerTag = type.prototype?.isReactComponent ? FiberTag.Class : FiberTag.Function\n } else if (type && typeof type === 'object') {\n const m = (type as any).$$typeof\n if (m === REACT_FORWARD_REF_TYPE) innerTag = FiberTag.ForwardRef\n else if (m === REACT_MEMO_TYPE) innerTag = FiberTag.Memo\n else if (m === REACT_LAZY_TYPE) innerTag = FiberTag.Lazy\n else innerTag = FiberTag.Fragment\n } else {\n innerTag = FiberTag.Fragment\n }\n\n // Swap tag and type for this render pass; this is a \"delegating\" render\n const savedTag = fiber.tag\n const savedType = fiber.type\n fiber.tag = innerTag\n fiber.type = type\n try {\n renderFiber(fiber, domParent, anchor)\n } finally {\n fiber.tag = savedTag\n fiber.type = savedType\n }\n}\n\nregisterTypeMatcher((_type, marker) => (marker === REACT_MEMO_TYPE ? FiberTag.Memo : null))\nregisterRenderer(FiberTag.Memo, renderMemo)\n"],
5
+ "mappings": ";AAAA,SAAS,gBAA4B;AACrC;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,OACK;AACP;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AACP,SAAS,mBAAmB,8BAA8B;AAE1D,SAAS,aAAa,GAAQ,GAAiB;AAC7C,MAAI,MAAM,EAAG,QAAO;AACpB,MAAI,CAAC,KAAK,CAAC,EAAG,QAAO;AACrB,QAAM,KAAK,OAAO,KAAK,CAAC;AACxB,QAAM,KAAK,OAAO,KAAK,CAAC;AACxB,MAAI,GAAG,WAAW,GAAG,OAAQ,QAAO;AACpC,aAAW,KAAK,IAAI;AAClB,QAAI,EAAE,CAAC,MAAM,EAAE,CAAC,EAAG,QAAO;AAAA,EAC5B;AACA,SAAO;AACT;AAEA,SAAS,WAAW,OAAc,WAAiB,QAA2B;AAC5E,QAAM,EAAE,MAAM,QAAQ,IAAI,MAAM;AAChC,QAAM,QAAQ,MAAM,MAAM,CAAC;AAC3B,QAAM,OAAO,MAAM;AAOnB,QAAM,aAAa,MAAM,MAAM,UAAU,yBAAyB;AAClE,QAAM,KAAK,CAAC,cAAc,SAAS,UAAU,QAAQ,MAAM,KAAK,IAAI,aAAa,MAAM,KAAK;AAC5F,MAAI,MAAM,CAAC,kBAAkB,KAAK,GAAG;AACnC,2BAAuB,KAAK;AAC5B;AAAA,EACF;AAMA,MAAI;AACJ,MAAI,OAAO,QAAQ,YAAY;AAC7B,eAAW,KAAK,WAAW,mBAAmB,SAAS,QAAQ,SAAS;AAAA,EAC1E,WAAW,QAAQ,OAAO,SAAS,UAAU;AAC3C,UAAM,IAAK,KAAa;AACxB,QAAI,MAAM,uBAAwB,YAAW,SAAS;AAAA,aAC7C,MAAM,gBAAiB,YAAW,SAAS;AAAA,aAC3C,MAAM,gBAAiB,YAAW,SAAS;AAAA,QAC/C,YAAW,SAAS;AAAA,EAC3B,OAAO;AACL,eAAW,SAAS;AAAA,EACtB;AAGA,QAAM,WAAW,MAAM;AACvB,QAAM,YAAY,MAAM;AACxB,QAAM,MAAM;AACZ,QAAM,OAAO;AACb,MAAI;AACF,gBAAY,OAAO,WAAW,MAAM;AAAA,EACtC,UAAE;AACA,UAAM,MAAM;AACZ,UAAM,OAAO;AAAA,EACf;AACF;AAEA,oBAAoB,CAAC,OAAO,WAAY,WAAW,kBAAkB,SAAS,OAAO,IAAK;AAC1F,iBAAiB,SAAS,MAAM,UAAU;",
6
6
  "names": []
7
7
  }
@@ -1 +1 @@
1
- export * from './full';
1
+ export * from "./full.js";
@@ -1,3 +1,3 @@
1
- // packages/redact/src/dom/features/memo/index.ts
2
- export * from "./full";
1
+ // src/dom/features/memo/index.ts
2
+ export * from "./full.js";
3
3
  //# sourceMappingURL=index.js.map
@@ -1,11 +1,11 @@
1
- // packages/redact/src/dom/features/memo/stub.ts
2
- import { FiberTag } from "../../../core";
1
+ // src/dom/features/memo/stub.ts
2
+ import { FiberTag } from "../../../core/index.js";
3
3
  import {
4
4
  REACT_FORWARD_REF_TYPE,
5
5
  REACT_MEMO_TYPE,
6
6
  REACT_LAZY_TYPE
7
- } from "../../../react";
8
- import { registerRenderer, registerTypeMatcher, renderFiber } from "../../reconcile";
7
+ } from "../../../react/index.js";
8
+ import { registerRenderer, registerTypeMatcher, renderFiber } from "../../reconcile.js";
9
9
  function renderMemoStub(fiber, domParent, anchor) {
10
10
  const { type } = fiber.type;
11
11
  let innerTag;
@@ -1,13 +1,13 @@
1
- // packages/redact/src/dom/features/portal/full.ts
2
- import { FiberTag } from "../../../core";
3
- import { REACT_PORTAL_TYPE } from "../../../react";
1
+ // src/dom/features/portal/full.ts
2
+ import { FiberTag } from "../../../core/index.js";
3
+ import { REACT_PORTAL_TYPE } from "../../../react/index.js";
4
4
  import {
5
5
  registerRenderer,
6
6
  registerTypeMatcher,
7
7
  registerElementMarker,
8
8
  reconcileChildren,
9
9
  childrenToArray
10
- } from "../../reconcile";
10
+ } from "../../reconcile.js";
11
11
  function renderPortal(fiber, _domParent, _anchor) {
12
12
  const { children, container } = fiber.pp;
13
13
  reconcileChildren(fiber, childrenToArray(children), container, null);
@@ -1 +1 @@
1
- export * from './full';
1
+ export * from "./full.js";
@@ -1,3 +1,3 @@
1
- // packages/redact/src/dom/features/portal/index.ts
2
- export * from "./full";
1
+ // src/dom/features/portal/index.ts
2
+ export * from "./full.js";
3
3
  //# sourceMappingURL=index.js.map
@@ -1,7 +1,7 @@
1
- // packages/redact/src/dom/features/portal/stub.ts
2
- import { FiberTag } from "../../../core";
3
- import { REACT_PORTAL_TYPE } from "../../../react";
4
- import { registerTypeMatcher, registerElementMarker } from "../../reconcile";
1
+ // src/dom/features/portal/stub.ts
2
+ import { FiberTag } from "../../../core/index.js";
3
+ import { REACT_PORTAL_TYPE } from "../../../react/index.js";
4
+ import { registerTypeMatcher, registerElementMarker } from "../../reconcile.js";
5
5
  registerElementMarker(REACT_PORTAL_TYPE);
6
6
  registerTypeMatcher((type) => type === REACT_PORTAL_TYPE ? FiberTag.Fragment : null);
7
7
  //# sourceMappingURL=stub.js.map
@@ -1,6 +1,6 @@
1
- // packages/redact/src/dom/features/suspense/full.ts
2
- import { FiberTag, createFiber } from "../../../core";
3
- import { REACT_SUSPENSE_TYPE } from "../../../react";
1
+ // src/dom/features/suspense/full.ts
2
+ import { FiberTag, createFiber } from "../../../core/index.js";
3
+ import { REACT_SUSPENSE_TYPE, ReactSharedInternals, startTransition } from "../../../react/index.js";
4
4
  import {
5
5
  registerRenderer,
6
6
  registerTypeMatcher,
@@ -15,8 +15,20 @@ import {
15
15
  runEffects,
16
16
  getCurrentRoot,
17
17
  withCurrentRoot,
18
- discardPendingWork
19
- } from "../../reconcile";
18
+ discardPendingWork,
19
+ findSuspenseBoundary,
20
+ RenderSuspenseCapture,
21
+ activityIsDisconnected,
22
+ isActivityHidden,
23
+ attachRef,
24
+ detachRef,
25
+ enqueueEffect,
26
+ flushFiberCommits,
27
+ scheduleLifecycle,
28
+ handleCommitError
29
+ } from "../../reconcile.js";
30
+ import { cleanupEffect } from "../../dispatcher.js";
31
+ import { retainedEffects, inSuspensePrimary, setLayoutDisconnected, walkRetained } from "../../retained-effects.js";
20
32
  import {
21
33
  HydrationCursor,
22
34
  setHydrationCursor,
@@ -24,19 +36,33 @@ import {
24
36
  advanceCursorPast,
25
37
  tryConsumeBoundary,
26
38
  isHydrationBailout
27
- } from "../hydration";
39
+ } from "../hydration/index.js";
40
+ import { hasContextChanged, renderContextConsumers } from "../context/index.js";
41
+ import { checkpointCommit, rewindCommit, queueMutation, onCommitFailure } from "../../commit.js";
28
42
  var suspendHandler = null;
43
+ function scheduleRetry(fiber) {
44
+ const previous = ReactSharedInternals.T;
45
+ ReactSharedInternals.T = null;
46
+ try {
47
+ startTransition(() => scheduleUpdate(fiber));
48
+ } finally {
49
+ ReactSharedInternals.T = previous;
50
+ }
51
+ }
29
52
  function realHandleSuspended(fiber, thenable) {
30
53
  if (suspendHandler) return suspendHandler(thenable);
54
+ const boundary = findSuspenseBoundary(fiber);
55
+ if (boundary) throw new RenderSuspenseCapture(boundary);
31
56
  thenable.then(
32
- () => scheduleUpdate(fiber),
33
- () => scheduleUpdate(fiber)
57
+ () => scheduleRetry(fiber),
58
+ () => scheduleRetry(fiber)
34
59
  );
35
60
  }
36
61
  function renderSuspense(fiber, domParent, anchor) {
37
62
  const props = fiber.pp ?? {};
38
- const state = fiber.ms ??= {};
63
+ let state = fiber.ms ??= {};
39
64
  const root = getCurrentRoot();
65
+ if (root) root.sp = true;
40
66
  if (root?.h && !state.b) {
41
67
  const boundary = tryConsumeBoundary(fiber.parent);
42
68
  if (boundary) {
@@ -48,10 +74,9 @@ function renderSuspense(fiber, domParent, anchor) {
48
74
  fiber.mp = props;
49
75
  return;
50
76
  }
51
- if (state.p) {
77
+ if (state.p && !state.u && props.children === fiber.mp?.children && !hasContextChanged(fiber, false)) {
52
78
  if (state.f) {
53
- state.f.pp = { children: props.fallback };
54
- renderFiber(state.f, domParent, anchor);
79
+ renderFallback(state.f, props.fallback, domParent, anchor);
55
80
  } else {
56
81
  reconcileChildren(fiber, childrenToArray(props.fallback), domParent, anchor);
57
82
  }
@@ -59,7 +84,10 @@ function renderSuspense(fiber, domParent, anchor) {
59
84
  return;
60
85
  }
61
86
  const hadCommittedPrimary = fiber.mp && fiber.child;
87
+ state.u = false;
88
+ const checkpoint = checkpointCommit(fiber);
62
89
  const prevHandler = suspendHandler;
90
+ fiber.cx?.clear();
63
91
  let pendingThenable;
64
92
  suspendHandler = (thenable) => {
65
93
  pendingThenable = thenable;
@@ -70,49 +98,133 @@ function renderSuspense(fiber, domParent, anchor) {
70
98
  suspendHandler = prevHandler;
71
99
  }
72
100
  if (pendingThenable) {
101
+ rewindCommit(checkpoint);
102
+ state = fiber.ms ??= {};
103
+ const previousThenable = state.p;
73
104
  state.p = pendingThenable;
74
105
  const onSettle = () => {
75
- state.p = null;
76
- scheduleUpdate(fiber);
106
+ const current = fiber.ms;
107
+ if (!current || current.p !== pendingThenable) return;
108
+ current.p = null;
109
+ scheduleRetry(fiber);
77
110
  };
78
- pendingThenable.then(onSettle, onSettle);
79
- if (hadCommittedPrimary) {
111
+ if (previousThenable !== pendingThenable) pendingThenable.then(onSettle, onSettle);
112
+ if (hadCommittedPrimary && !state.d) {
80
113
  const hidden = [];
81
114
  let c = hadCommittedPrimary;
115
+ while (c) {
116
+ setUpdateBoundary(c, fiber);
117
+ walkRetained(c, disconnectLayout);
118
+ c = c.sibling;
119
+ }
120
+ c = hadCommittedPrimary;
82
121
  while (c) {
83
122
  hideRootHostDoms(c, hidden);
84
123
  c = c.sibling;
85
124
  }
86
125
  state.d = hidden;
87
- if (!state.f) {
88
- state.f = createFiber(FiberTag.Fragment, null, null);
89
- state.f.parent = fiber;
90
- }
91
- state.f.pp = { children: props.fallback };
92
- renderFiber(state.f, domParent, anchor);
93
- } else {
126
+ } else if (!hadCommittedPrimary) {
94
127
  unmountAllChildren(fiber, domParent);
95
- reconcileChildren(fiber, childrenToArray(props.fallback), domParent, anchor);
96
128
  }
129
+ if (!state.f) {
130
+ state.f = createFiber(FiberTag.Fragment, null, null);
131
+ state.f.parent = fiber;
132
+ }
133
+ renderFallback(state.f, props.fallback, domParent, anchor);
97
134
  } else {
135
+ state.p = null;
136
+ fiber.cx?.clear();
137
+ const wasHidden = !!state.d;
98
138
  if (state.d) {
99
- for (const [el, origDisplay] of state.d) {
100
- el.style.display = origDisplay;
101
- }
139
+ for (let child = fiber.child; child; child = child.sibling) setUpdateBoundary(child, fiber.su);
140
+ const hidden = state.d;
141
+ queueMutation(() => {
142
+ for (const [el, origDisplay] of hidden) el.style.display = origDisplay;
143
+ });
102
144
  state.d = null;
103
145
  }
104
146
  if (state.f) {
105
147
  unmountFiber(state.f, domParent);
106
148
  state.f = null;
107
149
  }
150
+ if (wasHidden) for (let child = fiber.child; child; child = child.sibling) walkRetained(child, reconnectLayout, true);
108
151
  }
109
152
  fiber.mp = props;
110
153
  }
154
+ function renderFallback(fiber, children, domParent, anchor) {
155
+ if (fiber.mp && fiber.mp.children === children && !fiber.su) renderContextConsumers(fiber);
156
+ else {
157
+ fiber.pp = { children };
158
+ renderFiber(fiber, domParent, anchor);
159
+ }
160
+ }
161
+ function disconnectLayout(fiber) {
162
+ if (setLayoutDisconnected(fiber, true) || activityIsDisconnected(fiber)) return;
163
+ queueMutation(() => {
164
+ for (const [hook, effect] of retainedEffects.get(fiber) ?? []) {
165
+ if (effect.t === 1 && !effect.s) cleanupEffect(hook, fiber);
166
+ }
167
+ const cleanup = fiber.rc;
168
+ fiber.rc = null;
169
+ if (cleanup) {
170
+ const index = fiber.cu?.indexOf(cleanup) ?? -1;
171
+ if (index >= 0) fiber.cu.splice(index, 1);
172
+ try {
173
+ cleanup();
174
+ } catch (error) {
175
+ handleCommitError(fiber, error);
176
+ }
177
+ }
178
+ detachRef(fiber.cr ?? fiber.ref, fiber);
179
+ fiber.cr = null;
180
+ const instance = fiber.sn?._fiber === fiber ? fiber.sn : null;
181
+ if (instance?.componentWillUnmount) {
182
+ const props = instance.props, state = instance.state, committed = fiber.ms?.c;
183
+ if (committed) {
184
+ instance.props = committed.props;
185
+ instance.state = committed.state;
186
+ }
187
+ try {
188
+ instance.componentWillUnmount();
189
+ } catch (error) {
190
+ handleCommitError(fiber, error);
191
+ } finally {
192
+ instance.props = props;
193
+ instance.state = state;
194
+ }
195
+ }
196
+ });
197
+ }
198
+ function reconnectLayout(fiber) {
199
+ if (!fiber.ld || isActivityHidden(fiber) || activityIsDisconnected(fiber)) return;
200
+ if (inSuspensePrimary(fiber)) return;
201
+ setLayoutDisconnected(fiber, false);
202
+ const instance = fiber.sn?._fiber === fiber ? fiber.sn : null;
203
+ if (fiber.tag === FiberTag.Host || fiber.tag === FiberTag.Resource) attachRef(fiber, fiber.dom);
204
+ else if (instance || fiber.tag === FiberTag.Fragment) attachRef(fiber, fiber.sn);
205
+ for (const effect of retainedEffects.get(fiber)?.values() ?? []) {
206
+ if (effect.t === 1 && !effect.s) enqueueEffect(fiber, effect);
207
+ }
208
+ if (instance?.componentDidMount) scheduleLifecycle(fiber, () => instance.componentDidMount());
209
+ flushFiberCommits(fiber);
210
+ }
211
+ function setUpdateBoundary(fiber, boundary) {
212
+ fiber.su = boundary ?? null;
213
+ const primary = fiber.tag === FiberTag.Suspense && fiber.ms?.p ? fiber : boundary;
214
+ for (let child = fiber.child; child; child = child.sibling) setUpdateBoundary(child, primary);
215
+ if (fiber.tag === FiberTag.Suspense && fiber.ms?.f) setUpdateBoundary(fiber.ms.f, boundary);
216
+ }
111
217
  function hideRootHostDoms(fiber, out) {
112
218
  if (fiber.tag === FiberTag.Host) {
113
219
  const el = fiber.dom;
114
- out.push([el, el.style.display]);
115
- el.style.display = "none";
220
+ const existing = out.find(([node]) => node === el);
221
+ const entry = existing ?? [el, el.style.display];
222
+ if (!existing) out.push(entry);
223
+ const display = fiber.pp?.style?.display;
224
+ queueMutation(() => {
225
+ if (!existing || el.style.display !== "none" || display === "none") entry[1] = el.style.display;
226
+ el.style.display = "none";
227
+ });
116
228
  return;
117
229
  }
118
230
  if (fiber.tag === FiberTag.Portal) return;
@@ -129,6 +241,12 @@ function hydrateSuspenseBoundary(fiber, props, boundary, domParent, anchor) {
129
241
  e: endMark,
130
242
  r: props.children
131
243
  };
244
+ if (pendingBoundary >= 2) {
245
+ if (pendingBoundary === 3) reportServerFailure(fiber);
246
+ recoverBoundaryHydration(fiber, props.children, startMark.parentNode, startMark, endMark, true);
247
+ fiber.mp = props;
248
+ return;
249
+ }
132
250
  if (!pendingBoundary) {
133
251
  const parent = startMark.parentNode;
134
252
  try {
@@ -137,8 +255,10 @@ function hydrateSuspenseBoundary(fiber, props, boundary, domParent, anchor) {
137
255
  advanceCursorPast(fiber.parent, endMark);
138
256
  } catch (e) {
139
257
  if (!isHydrationBailout(e)) {
140
- clearBoundaryRange(startMark, endMark);
141
- unmountAllChildren(fiber, parent);
258
+ onCommitFailure(() => {
259
+ clearBoundaryRange(startMark, endMark);
260
+ unmountAllChildren(fiber, parent);
261
+ });
142
262
  throw e;
143
263
  }
144
264
  recoverBoundaryHydration(fiber, props.children, parent, startMark, endMark);
@@ -166,19 +286,24 @@ function hydrateSuspenseBoundary(fiber, props, boundary, domParent, anchor) {
166
286
  globalThis.$RH?.(id, () => rehydrateBoundary(fiber));
167
287
  fiber.mp = props;
168
288
  }
169
- function recoverBoundaryHydration(fiber, children, parent, startMark, endMark) {
289
+ function recoverBoundaryHydration(fiber, children, parent, startMark, endMark, retryBoundary = false) {
170
290
  const root = findRoot(fiber);
171
291
  const prevHydrating = root.h;
172
- discardPendingWork(root);
292
+ if (!retryBoundary) discardPendingWork(root);
173
293
  clearBoundaryRange(startMark, endMark);
174
294
  unmountAllChildren(fiber, parent);
175
295
  root.h = false;
176
296
  try {
177
- reconcileChildren(fiber, childrenToArray(children), parent, endMark);
297
+ if (retryBoundary) {
298
+ fiber.ms = {};
299
+ renderSuspense(fiber, parent, endMark);
300
+ } else reconcileChildren(fiber, childrenToArray(children), parent, endMark);
178
301
  advanceCursorPast(fiber.parent, endMark);
179
302
  } catch (clientError) {
180
- clearBoundaryRange(startMark, endMark);
181
- unmountAllChildren(fiber, parent);
303
+ onCommitFailure(() => {
304
+ clearBoundaryRange(startMark, endMark);
305
+ unmountAllChildren(fiber, parent);
306
+ });
182
307
  throw clientError;
183
308
  } finally {
184
309
  root.h = prevHydrating;
@@ -188,14 +313,18 @@ function recoverFallbackHydration(fiber, fallback, parent) {
188
313
  const root = findRoot(fiber);
189
314
  const prevHydrating = root.h;
190
315
  discardPendingWork(root);
191
- parent.textContent = "";
316
+ queueMutation(() => {
317
+ parent.textContent = "";
318
+ });
192
319
  unmountAllChildren(fiber, parent);
193
320
  root.h = false;
194
321
  try {
195
322
  reconcileChildren(fiber, childrenToArray(fallback), parent, null);
196
323
  } catch (clientError) {
197
- parent.textContent = "";
198
- unmountAllChildren(fiber, parent);
324
+ onCommitFailure(() => {
325
+ parent.textContent = "";
326
+ unmountAllChildren(fiber, parent);
327
+ });
199
328
  throw clientError;
200
329
  } finally {
201
330
  root.h = prevHydrating;
@@ -209,6 +338,12 @@ function rehydrateBoundary(fiber) {
209
338
  if (!(root && parent)) return;
210
339
  withCurrentRoot(root, () => {
211
340
  const prevHydrating = root.h;
341
+ if (state.b.data.startsWith("$!") || state.b.data.startsWith("$E")) {
342
+ if (state.b.data.startsWith("$E")) reportServerFailure(fiber);
343
+ recoverBoundaryHydration(fiber, state.r, parent, state.b, state.e, true);
344
+ runEffects(root);
345
+ return;
346
+ }
212
347
  try {
213
348
  unmountAllChildren(fiber, parent);
214
349
  root.h = true;
@@ -216,8 +351,10 @@ function rehydrateBoundary(fiber) {
216
351
  reconcileChildren(fiber, childrenToArray(state.r), parent, null);
217
352
  } catch (e) {
218
353
  if (!isHydrationBailout(e)) {
219
- clearBoundaryRange(state.b, state.e);
220
- unmountAllChildren(fiber, parent);
354
+ onCommitFailure(() => {
355
+ clearBoundaryRange(state.b, state.e);
356
+ unmountAllChildren(fiber, parent);
357
+ });
221
358
  throw e;
222
359
  }
223
360
  recoverBoundaryHydration(fiber, state.r, parent, state.b, state.e);
@@ -228,13 +365,21 @@ function rehydrateBoundary(fiber) {
228
365
  runEffects(root);
229
366
  });
230
367
  }
368
+ function reportServerFailure(fiber) {
369
+ const error = new Error("Switched to client rendering because the server render did not complete.");
370
+ const handler = findRoot(fiber)?.re;
371
+ if (handler) handler(error, { componentStack: null });
372
+ else console.error(error);
373
+ }
231
374
  function clearBoundaryRange(startMark, endMark) {
232
- let node = startMark.nextSibling;
233
- while (node && node !== endMark) {
234
- const next = node.nextSibling;
235
- node.parentNode?.removeChild(node);
236
- node = next;
237
- }
375
+ queueMutation(() => {
376
+ let node = startMark.nextSibling;
377
+ while (node && node !== endMark) {
378
+ const next = node.nextSibling;
379
+ node.parentNode?.removeChild(node);
380
+ node = next;
381
+ }
382
+ });
238
383
  }
239
384
  registerTypeMatcher((type) => type === REACT_SUSPENSE_TYPE ? FiberTag.Suspense : null);
240
385
  registerRenderer(FiberTag.Suspense, renderSuspense);