@tanstack/redact 0.0.18 → 0.0.19

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.
@@ -140,7 +140,8 @@ function hydrateRootImpl(container, initialChildren, options) {
140
140
  var HEAD_KEY_ATTRS = {
141
141
  link: ["rel", "href", "sizes", "type"],
142
142
  meta: ["name", "property", "charSet", "httpEquiv"],
143
- script: ["src", "type"]
143
+ script: ["src", "type"],
144
+ style: ["id", "media", "nonce", "title"]
144
145
  };
145
146
  var DOCUMENT_HEAD_TAGS = /* @__PURE__ */ new Set(["base", "link", "meta", "script", "style", "title"]);
146
147
  var CLAIMED = /* @__PURE__ */ new WeakSet();
@@ -233,10 +234,11 @@ function adoptHostDom(fiber, parent) {
233
234
  fiber.dom = candidate;
234
235
  const props = fiber.pp ?? {};
235
236
  const isSvg = tag === "svg" || candidate.namespaceURI === "http://www.w3.org/2000/svg" && tag !== "foreignobject";
237
+ const syncHydrationProps = !props.suppressHydrationWarning && canRecoverHydrationPropMismatch(candidate, tag);
236
238
  validateHydrationProps(fiber, candidate, props, tag, isSvg);
237
239
  for (const k in props) {
238
- if (k === "children") continue;
239
- if (k[0] === "o" && k[1] === "n" && typeof props[k] == "function") {
240
+ if (k === "children" || k === "key" || k === "ref" || k === "suppressHydrationWarning" || k === "suppressContentEditableWarning") continue;
241
+ if (syncHydrationProps || k[0] === "o" && k[1] === "n" && typeof props[k] == "function") {
240
242
  setProp(candidate, k, props[k], void 0, isSvg);
241
243
  }
242
244
  }
@@ -247,16 +249,23 @@ function adoptTextDom(fiber, parent, text) {
247
249
  const cursor = hydrationCursors.get(findHostParent(parent));
248
250
  if (!cursor) return false;
249
251
  const candidate = cursor.take();
250
- if (!candidate) onMismatch(fiber, null);
252
+ if (!candidate) {
253
+ onMismatch(fiber, null);
254
+ return false;
255
+ }
251
256
  if (candidate.nodeType === 3) {
252
257
  if (candidate.data !== text) {
253
- if (true) {
254
- failHydration(
255
- fiber,
256
- new Error(`Hydration text mismatch: expected "${text}" but found "${candidate.data}".`)
257
- );
258
+ const recovered = failHydration(
259
+ fiber,
260
+ true ? new Error(
261
+ `Hydration text mismatch: expected "${text}" but found "${candidate.data}".`
262
+ ) : void 0,
263
+ canRecoverHydrationPropMismatch(candidate)
264
+ );
265
+ if (recovered) {
266
+ ;
267
+ candidate.data = text;
258
268
  }
259
- failHydration(fiber);
260
269
  }
261
270
  fiber.dom = candidate;
262
271
  return true;
@@ -279,23 +288,24 @@ function findHostParent(fiber) {
279
288
  throw new Error();
280
289
  }
281
290
  function onMismatch(fiber, actualNode) {
282
- if (true) {
283
- failHydration(
284
- fiber,
285
- new Error(
286
- `Hydration mismatch: expected <${fiber.type ?? "text"}> but found ${actualNode ? actualNode.nodeType === 1 ? actualNode.tagName : "text" : "nothing"}.`
287
- )
288
- );
289
- }
290
- failHydration(fiber);
291
+ failHydration(
292
+ fiber,
293
+ true ? new Error(
294
+ `Hydration mismatch: expected <${fiber.type ?? "text"}> but found ${actualNode ? actualNode.nodeType === 1 ? actualNode.tagName : "text" : "nothing"}.`
295
+ ) : void 0
296
+ );
291
297
  }
292
- function failHydration(fiber, error = new Error(PROD_HYDRATION_ERROR)) {
298
+ function failHydration(fiber, error = new Error(PROD_HYDRATION_ERROR), recoverInPlace = false) {
293
299
  const root = findRoot(fiber);
294
300
  if (root?.re) {
295
301
  root.re(error);
296
302
  }
303
+ if (recoverInPlace) return true;
297
304
  abortHydration(error, findHostRecoveryParent(fiber) ?? fiber);
298
305
  }
306
+ function canRecoverHydrationPropMismatch(node, tag) {
307
+ return tag === "html" || tag === "head" || tag === "body" || !!node.ownerDocument?.head?.contains(node);
308
+ }
299
309
  function findHostRecoveryParent(fiber) {
300
310
  if (fiber.tag === FiberTag.Text) {
301
311
  let directHost = fiber.parent;
@@ -481,6 +491,7 @@ function createHostElement(type, props) {
481
491
  }
482
492
  function validateHydrationProps(fiber, el, props, tag, isSvg) {
483
493
  if (props.suppressHydrationWarning) return;
494
+ const recoverInPlace = canRecoverHydrationPropMismatch(el, tag);
484
495
  let expected;
485
496
  for (const k in props) {
486
497
  const value = props[k];
@@ -493,13 +504,11 @@ function validateHydrationProps(fiber, el, props, tag, isSvg) {
493
504
  html = probe.innerHTML;
494
505
  }
495
506
  if (el.innerHTML !== html) {
496
- if (true) {
497
- failHydration(
498
- fiber,
499
- new Error(`Hydration HTML mismatch inside <${tag}>.`)
500
- );
501
- }
502
- failHydration(fiber);
507
+ failHydration(
508
+ fiber,
509
+ true ? new Error(`Hydration HTML mismatch inside <${tag}>.`) : void 0,
510
+ recoverInPlace
511
+ );
503
512
  }
504
513
  continue;
505
514
  }
@@ -508,10 +517,11 @@ function validateHydrationProps(fiber, el, props, tag, isSvg) {
508
517
  if (tag === "input" || tag === "textarea") {
509
518
  if (k === "value" || props.value == null) {
510
519
  if (value != null && el.value !== "" + value) {
511
- if (true) {
512
- failHydration(fiber, new Error(`Hydration ${tag} value mismatch on <${tag}>.`));
513
- }
514
- failHydration(fiber);
520
+ failHydration(
521
+ fiber,
522
+ true ? new Error(`Hydration ${tag} value mismatch on <${tag}>.`) : void 0,
523
+ recoverInPlace
524
+ );
515
525
  }
516
526
  }
517
527
  continue;
@@ -520,34 +530,37 @@ function validateHydrationProps(fiber, el, props, tag, isSvg) {
520
530
  if (tag === "input" && (k === "checked" || k === "defaultChecked")) {
521
531
  if (k === "checked" || props.checked == null) {
522
532
  if (value != null && el.checked !== !!value) {
523
- if (true) {
524
- failHydration(fiber, new Error(`Hydration checked mismatch on <input>.`));
525
- }
526
- failHydration(fiber);
533
+ failHydration(
534
+ fiber,
535
+ true ? new Error(`Hydration checked mismatch on <input>.`) : void 0,
536
+ recoverInPlace
537
+ );
527
538
  }
528
539
  }
529
540
  continue;
530
541
  }
531
542
  if (tag === "option" && k === "selected") {
532
543
  if (value != null && el.selected !== !!value) {
533
- if (true) {
534
- failHydration(fiber, new Error(`Hydration selected mismatch on <option>.`));
535
- }
536
- failHydration(fiber);
544
+ failHydration(
545
+ fiber,
546
+ true ? new Error(`Hydration selected mismatch on <option>.`) : void 0,
547
+ recoverInPlace
548
+ );
537
549
  }
538
550
  continue;
539
551
  }
540
552
  if (k === "style") {
541
553
  expected ??= createHostNode(tag, isSvg);
542
554
  setProp(expected, k, value, void 0, isSvg);
543
- if (el.style.cssText !== expected.style.cssText) {
544
- if (true) {
545
- failHydration(
546
- fiber,
547
- new Error(`Hydration style mismatch on <${tag}>.`)
548
- );
549
- }
550
- failHydration(fiber);
555
+ if (!hydrationStylesMatch(
556
+ el.style,
557
+ expected.style
558
+ )) {
559
+ failHydration(
560
+ fiber,
561
+ true ? new Error(`Hydration style mismatch on <${tag}>.`) : void 0,
562
+ recoverInPlace
563
+ );
551
564
  }
552
565
  continue;
553
566
  }
@@ -563,18 +576,25 @@ function validateHydrationProps(fiber, el, props, tag, isSvg) {
563
576
  }
564
577
  const actualValue = el.getAttribute(attr);
565
578
  if (expectedValue !== actualValue) {
566
- if (true) {
567
- failHydration(
568
- fiber,
569
- new Error(
570
- `Hydration attribute mismatch on <${tag}> for "${attr}": expected ${formatHydrationValue(expectedValue)} but found ${formatHydrationValue(actualValue)}.`
571
- )
572
- );
573
- }
574
- failHydration(fiber);
579
+ failHydration(
580
+ fiber,
581
+ true ? new Error(
582
+ `Hydration attribute mismatch on <${tag}> for "${attr}": expected ${formatHydrationValue(expectedValue)} but found ${formatHydrationValue(actualValue)}.`
583
+ ) : void 0,
584
+ recoverInPlace
585
+ );
575
586
  }
576
587
  }
577
588
  }
589
+ function hydrationStylesMatch(actual, expected) {
590
+ for (let index = 0; index < expected.length; index++) {
591
+ const property = expected.item(index);
592
+ if (actual.getPropertyValue(property) !== expected.getPropertyValue(property) || actual.getPropertyPriority(property) !== expected.getPropertyPriority(property)) {
593
+ return false;
594
+ }
595
+ }
596
+ return true;
597
+ }
578
598
  function formatHydrationValue(value) {
579
599
  return value == null ? "nothing" : JSON.stringify(value);
580
600
  }
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../src/dom/features/hydration/full.ts"],
4
- "sourcesContent": ["import {\n FiberTag,\n REACT_ELEMENT_TYPE,\n type Fiber,\n type FiberRoot,\n type ReactElement,\n type ReactNode,\n} from '../../../core'\nimport { attributeName } from '../../../core/attributes'\nimport { createHostNode, setProp } from '../../dom'\nimport { drainReplayQueue } from '../../event-replay'\nimport { discardPendingWork, findRoot, flushSyncWork, renderRoot } from '../../reconcile'\nimport { attachRootFiber, createFiberRoot } from '../../root-internal'\n\n// Re-export from event-replay so all hydration concerns live behind one\n// feature boundary \u2014 the plugin's stub swap strips drainReplayQueue too.\nexport { drainReplayQueue }\n\n/**\n * Preserve the user's scroll position across hydration. If the user scrolled\n * between SSR paint and hydrate (common in dev where JS takes seconds to\n * load), libraries that wire scroll-restoration into a `useLayoutEffect`\n * near the root (e.g. TanStack Router) will run during our synchronous\n * hydrate and call `window.scrollTo(savedFromLastVisit)` \u2014 overwriting the\n * user's fresh scroll. We install a short-lived wrapper around scrollTo that\n * suppresses programmatic calls when a user-initiated scroll happened\n * recently. Only runs in the hydration feature \u2014 the stub skips it.\n */\nexport function installHydrationScrollGuard(): void {\n if (typeof window === 'undefined') return\n const w = window as any\n if (w._r) return\n const time = Date.now\n const guardStartedAt = w._r = time()\n let lastUserScrollAt = 0\n let programmatic = false\n w.addEventListener(\n 'scroll',\n () => {\n if (!programmatic) {\n lastUserScrollAt = time()\n }\n },\n { capture: true, passive: true },\n )\n const origScrollTo = w.scrollTo\n w.scrollTo = function (...args: any[]) {\n const now = time()\n if (\n now - guardStartedAt < 3000 &&\n now - lastUserScrollAt < 1500\n ) {\n return\n }\n programmatic = true\n try {\n return (origScrollTo as any).apply(w, args)\n } finally {\n queueMicrotask(() => {\n programmatic = false\n })\n }\n }\n}\n\n/**\n * Hydration cursor: walks existing DOM children in document order so we can\n * adopt them during fiber tree construction. One cursor per host parent.\n *\n * `endBefore` scopes the cursor to a subrange \u2014 used by rehydrateBoundary()\n * so we only adopt DOM up to the closing `/$` marker for that boundary.\n */\nexport class HydrationCursor {\n n: ChildNode | null\n p: Node\n e: ChildNode | null\n constructor(parent: Node, start: ChildNode | null = null, endBefore: ChildNode | null = null) {\n this.p = parent\n this.n = start ?? parent.firstChild\n this.e = endBefore\n }\n take(): ChildNode | null {\n while (this.n && this.n !== this.e) {\n const n = this.n\n // Skip anything that isn't an element (1) or text (3):\n // comments (8), doctype (10), processing instructions (7), cdata (4).\n if (n.nodeType !== 1 && n.nodeType !== 3) {\n this.n = n.nextSibling\n continue\n }\n this.n = n.nextSibling\n return n\n }\n return null\n }\n /**\n * Position-insensitive lookup for head/html adoption. Scans forward past\n * non-matching nodes without removing them, matching by tag AND the key\n * attributes that identify head elements uniquely (rel/href for links,\n * name/property for meta, src for script). Non-matching nodes stay in\n * place so the SSR'd stylesheet/script order is preserved.\n */\n head(tag: string, props: Record<string, any>): ChildNode | null {\n const target = tag.toLowerCase()\n const keyAttrs = HEAD_KEY_ATTRS[target]\n let scan = this.p.firstChild\n while (scan) {\n if (\n scan.nodeType === 1 &&\n (scan as Element).tagName.toLowerCase() === target &&\n headAttrsMatch(scan as Element, props, keyAttrs)\n ) {\n CLAIMED.add(scan)\n return scan\n }\n scan = scan.nextSibling\n }\n return null\n }\n has(): boolean {\n let n = this.n\n while (n && n !== this.e) {\n if (n.nodeType === 1 || n.nodeType === 3) return true\n n = n.nextSibling\n }\n return false\n }\n}\n\nconst hydrationCursors = new WeakMap<Fiber, HydrationCursor>()\nconst PROD_HYDRATION_ERROR = 'Hydration mismatch.'\n\nexport interface HydrationBailoutError extends Error {\n f: Fiber | null\n}\n\nexport function isHydrationBailout(error: unknown): error is HydrationBailoutError {\n return !!error && (error as any).f !== undefined\n}\n\nexport function abortHydration(cause: unknown, fiber: Fiber | null = null): never {\n const error = (cause instanceof Error ? cause : new Error(PROD_HYDRATION_ERROR)) as HydrationBailoutError\n ;(error as any).f = fiber\n throw error\n}\n\ninterface HydrateRootOptions {\n identifierPrefix?: string\n onRecoverableError?: (error: unknown) => void\n onCaughtError?: (error: unknown) => void\n onUncaughtError?: (error: unknown) => void\n}\n\ninterface HydratedRoot {\n render(children: ReactNode): void\n unmount(): void\n}\n\nexport function hydrateRootImpl(\n container: Element | Document,\n initialChildren: ReactNode,\n options: HydrateRootOptions,\n): HydratedRoot {\n const target = container as any as Element | Document\n const isDocument = (container as Node).nodeType === 9\n const body = isDocument ? (target as Document).body : null\n const root = createFiberRoot(target, options)\n\n installHydrationScrollGuard()\n\n const normalizedInitialChildren =\n isDocument ? normalizeDocumentChildren(initialChildren) : initialChildren\n let hydrationError: unknown = null\n beginHydration(root)\n try {\n flushSyncWork(() => {\n renderRoot(root, normalizedInitialChildren)\n })\n } catch (e) {\n hydrationError = e\n }\n endHydration(root)\n\n if (hydrationError && !recoverHydration(root, hydrationError)) throw hydrationError\n drainReplayQueue()\n\n return {\n render(children) {\n flushSyncWork(() => {\n const normalized = isDocument ? normalizeDocumentChildren(children) : children\n renderRoot(\n root,\n root.c === body ? getStaticDocumentBodyChildren(normalized) ?? normalized : normalized,\n )\n })\n },\n unmount() {\n flushSyncWork(() => {\n renderRoot(root, null)\n })\n },\n }\n}\n\n// Head elements that we match against server DOM by attribute signature.\nconst HEAD_KEY_ATTRS: Record<string, ReadonlyArray<string>> = {\n link: ['rel', 'href', 'sizes', 'type'],\n meta: ['name', 'property', 'charSet', 'httpEquiv'],\n script: ['src', 'type'],\n}\n\nconst DOCUMENT_HEAD_TAGS = new Set(['base', 'link', 'meta', 'script', 'style', 'title'])\n\n// DOM elements already claimed by some fiber during this hydration pass.\nconst CLAIMED = new WeakSet<Node>()\n\nfunction headAttrsMatch(\n el: Element,\n props: Record<string, any>,\n keys: ReadonlyArray<string> | undefined,\n): boolean {\n if (CLAIMED.has(el)) return false\n if (!keys) return true\n for (const k of keys) {\n const propVal = props[k]\n const elVal = el.getAttribute(attributeName(k))\n if (propVal == null && elVal == null) continue\n if (propVal == null || elVal == null || String(propVal) !== elVal) return false\n }\n return true\n}\n\nexport function beginHydration(root: FiberRoot): void {\n root.ic = 0\n root.h = true\n hydrationCursors.set(root.r, new HydrationCursor(root.c))\n}\n\nexport function endHydration(root: FiberRoot): void {\n root.h = false\n hydrationCursors.delete(root.r)\n}\n\n/**\n * Inspect the current cursor position for a streaming-suspense boundary\n * marker emitted by the server. Returns info + advances the cursor past the\n * marker pair (start comment + fallback/real content + end comment).\n */\nexport type BoundaryInfo = [0 | 1, number, Comment, Comment]\n\nexport function tryConsumeBoundary(parent: Fiber): BoundaryInfo | null {\n const cursor = hydrationCursors.get(findHostParent(parent))\n if (!cursor) return null\n const peek = cursor.n\n if (!peek || peek.nodeType !== 8) return null\n const data = (peek as Comment).data\n const m = /^(\\$\\??)(\\d+)$/.exec(data)\n if (!m) return null\n const kind = m[1] === '$?' ? 1 : 0\n const id = Number(m[2])\n const startMark = peek as Comment\n // Advance past the start comment\n cursor.n = startMark.nextSibling\n // Locate end comment: closest <!--/$-->\n let endMark: Comment | null = null\n let scan = startMark.nextSibling\n while (scan) {\n if (scan.nodeType === 8 && (scan as Comment).data === '/$') {\n endMark = scan as Comment\n break\n }\n scan = scan.nextSibling\n }\n if (!endMark) return null\n return [kind, id, startMark, endMark]\n}\n\nexport function advanceCursorPast(parent: Fiber, node: Node): void {\n const cursor = hydrationCursors.get(findHostParent(parent))\n if (!cursor) return\n cursor.n = node.nextSibling\n}\n\nexport function getHydrationCursor(hostFiber: Fiber): HydrationCursor | undefined {\n return hydrationCursors.get(hostFiber)\n}\n\nexport function setHydrationCursor(hostFiber: Fiber, cursor: HydrationCursor): void {\n hydrationCursors.set(hostFiber, cursor)\n}\n\nexport function clearHydrationCursor(hostFiber: Fiber): void {\n hydrationCursors.delete(hostFiber)\n}\n\n/**\n * Try to adopt a DOM node for this host fiber. Returns true if adopted.\n * Attaches existing attrs/children via separate hydrate pass.\n */\nexport function adoptHostDom(fiber: Fiber, parent: Fiber): boolean {\n const hostParent = findHostParent(parent)\n const cursor = hydrationCursors.get(hostParent)\n if (!cursor) return false\n\n const tag = (fiber.type as string).toLowerCase()\n const documentHeadParent =\n cursor.p.nodeType === 9 && DOCUMENT_HEAD_TAGS.has(tag)\n ? (cursor.p as Document).head\n : null\n const parentEl = cursor.p as Element\n const parentTag =\n parentEl.nodeType === 1 ? (parentEl as Element).tagName.toLowerCase() : ''\n const isHeadish = parentTag === 'head' || parentTag === 'html' || !!documentHeadParent\n\n let candidate: ChildNode | null\n if (documentHeadParent) {\n // React 19 can project <meta>/<title>/<link> from anywhere in the tree into\n // document.head. Redact does not have that projection yet, so when a\n // document-root hydration pass sees a top-level head element, adopt it\n // from <head> rather than trying to append it beside <html>.\n candidate = new HydrationCursor(documentHeadParent).head(\n tag,\n fiber.pp ?? {},\n )\n } else if (isHeadish) {\n // Head/html children are position-insensitive \u2014 server may emit them in\n // a different order than the React tree (React 19 head hoisting, etc.).\n // Scan forward without removing non-matching nodes; match on attribute\n // signature so we don't adopt the wrong <link> and clobber its props.\n candidate = cursor.head(tag, fiber.pp ?? {})\n } else {\n candidate = cursor.take()\n }\n\n if (!candidate) {\n // Client expected a host here but the cursor is exhausted \u2014 server gave\n // fewer children than the client tree. Report the structural gap (React\n // fires `onRecoverableError` for this exact case) and let the reconciler\n // mount a fresh DOM for this fiber below.\n // Exception: <head> children are position-insensitive; a missing match\n // there means \"server didn't hoist this one yet\", which we silently mount.\n if (!isHeadish) onMismatch(fiber, null)\n return false\n }\n\n if (candidate.nodeType !== 1 || (candidate as Element).tagName.toLowerCase() !== tag) {\n // mismatch \u2014 log and re-render fresh from this point\n onMismatch(fiber, candidate)\n return false\n }\n fiber.dom = candidate\n // Apply props (attach events, sync IDL props). Don't re-set existing attrs.\n const props = fiber.pp ?? {}\n const isSvg =\n tag === 'svg' ||\n ((candidate as Element).namespaceURI === 'http://www.w3.org/2000/svg' &&\n tag !== 'foreignobject')\n validateHydrationProps(fiber, candidate as Element, props, tag, isSvg)\n for (const k in props) {\n if (k === 'children') continue\n if (k[0] === 'o' && k[1] === 'n' && typeof props[k] == 'function') {\n setProp(candidate as Element, k, props[k], undefined, isSvg)\n }\n // Non-event props: trust the server HTML, skip\n }\n // Set up child cursor for this host's children\n hydrationCursors.set(fiber, new HydrationCursor(candidate))\n return true\n}\n\nexport function adoptTextDom(fiber: Fiber, parent: Fiber, text: string): boolean {\n const cursor = hydrationCursors.get(findHostParent(parent))\n if (!cursor) return false\n const candidate = cursor.take()\n if (!candidate) onMismatch(fiber, null)\n if (candidate.nodeType === 3) {\n if ((candidate as Text).data !== text) {\n if (process.env.NODE_ENV !== 'production') {\n failHydration(\n fiber,\n new Error(`Hydration text mismatch: expected \"${text}\" but found \"${(candidate as Text).data}\".`),\n )\n }\n failHydration(fiber)\n }\n fiber.dom = candidate\n return true\n }\n onMismatch(fiber, candidate)\n return false\n}\n\nexport function findHostParent(fiber: Fiber): Fiber {\n let f: Fiber | null = fiber\n while (f) {\n // A fiber explicitly holding a cursor acts as a boundary for hydration\n // (e.g. Suspense with a scoped cursor during fallback/boundary hydration).\n if (hydrationCursors.has(f)) return f\n if (f.tag === FiberTag.Host || f.tag === FiberTag.Root || f.tag === FiberTag.Portal) {\n return f\n }\n f = f.parent\n }\n if (process.env.NODE_ENV !== 'production') {\n throw new Error('No host parent found')\n }\n throw new Error()\n}\n\nfunction onMismatch(fiber: Fiber, actualNode: ChildNode | null): never {\n if (process.env.NODE_ENV !== 'production') {\n failHydration(\n fiber,\n new Error(\n `Hydration mismatch: expected <${(fiber.type as string) ?? 'text'}> but found ${\n actualNode ? (actualNode.nodeType === 1 ? (actualNode as Element).tagName : 'text') : 'nothing'\n }.`,\n ),\n )\n }\n failHydration(fiber)\n}\n\nfunction failHydration(fiber: Fiber, error: Error = new Error(PROD_HYDRATION_ERROR)): never {\n const root = findRoot(fiber)\n if (root?.re) {\n root.re(error)\n }\n abortHydration(error, findHostRecoveryParent(fiber) ?? fiber)\n}\n\nfunction findHostRecoveryParent(fiber: Fiber): Fiber | null {\n if (fiber.tag === FiberTag.Text) {\n let directHost = fiber.parent\n while (directHost && (directHost.tag !== FiberTag.Host || !directHost.dom)) {\n directHost = directHost.parent\n }\n if (!directHost) return null\n let hasEvent\n const props = directHost.pp ?? directHost.mp\n if (props) {\n for (const k in props) {\n if (k[0] === 'o' && k[1] === 'n' && typeof props[k] == 'function') {\n hasEvent = true\n }\n }\n }\n return findNearestSafeHostAboveComposite(\n hasEvent\n ? directHost.parent\n : directHost.parent?.tag === FiberTag.Host\n ? directHost.parent\n : directHost,\n )\n }\n\n return findNearestSafeHostAboveComposite(fiber.parent)\n}\n\nfunction findNearestSafeHostAboveComposite(fiber: Fiber | null): Fiber | null {\n let host: Fiber | null = null\n let f = fiber\n while (f) {\n if (f.tag === FiberTag.Host && f.dom) {\n if (!isSafeHostRecoveryElement(f)) return null\n const parentTag = f.parent?.tag as number\n if (!host || (parentTag > FiberTag.Text && parentTag < FiberTag.Suspense)) {\n host = f\n }\n }\n f = f.parent\n }\n return host\n}\n\nfunction isSafeHostRecoveryElement(fiber: Fiber): boolean {\n const tag = fiber.type.toLowerCase()\n return tag !== 'html' && tag !== 'head' && tag !== 'body'\n}\n\nexport function recoverHydration(root: FiberRoot, error: unknown): boolean {\n if (!isHydrationBailout(error)) return false\n\n let container = root.c as Element | Document\n let children = root.r.pp?.children ?? null\n const hostRecovery = getRecoverableHostChildren(error)\n if (hostRecovery) {\n container = hostRecovery[0]\n children = hostRecovery[1]\n } else if (container.nodeType === 9) {\n const bodyChildren = getRecoverableDocumentBodyChildren(error)\n if (bodyChildren != null) {\n container = (container as Document).body\n children = bodyChildren\n }\n }\n\n resetAfterHydrationFailure(root, container)\n try {\n flushSyncWork(() => renderRoot(root, children))\n } catch (clientError) {\n resetAfterHydrationFailure(root, container)\n throw clientError\n }\n return true\n}\n\nfunction resetAfterHydrationFailure(\n root: FiberRoot,\n container: Element | Document,\n): void {\n discardPendingWork(root)\n clearHydrationContainer(container)\n attachRootFiber(root, container)\n root.h = false\n}\n\nfunction clearHydrationContainer(container: Element | Document): void {\n if (container.nodeType === 9) {\n let node = container.firstChild\n while (node) {\n const next = node.nextSibling\n if (node.nodeType !== 10 /* DOCUMENT_TYPE_NODE */) {\n container.removeChild(node)\n }\n node = next\n }\n return\n }\n ;(container as Element).textContent = ''\n}\n\nfunction getRecoverableHostChildren(\n error: HydrationBailoutError,\n): [Element, ReactNode] | null {\n const host = error.f\n if (\n host?.tag !== FiberTag.Host ||\n !host.dom ||\n !findNearestSafeHostAboveComposite(host.parent)\n ) {\n return null\n }\n return [host.dom as Element, (host.pp ?? host.mp)?.children ?? null]\n}\n\nfunction getRecoverableDocumentBodyChildren(error: HydrationBailoutError): ReactNode | null {\n const bodyFiber = findBodyAncestor(error.f)\n if (!bodyFiber) return null\n return (bodyFiber.pp ?? bodyFiber.mp)?.children ?? null\n}\n\nfunction findBodyAncestor(fiber: Fiber | null): Fiber | null {\n let f = fiber\n while (f) {\n if (f.tag === FiberTag.Host && f.type === 'body') {\n return f === fiber ? null : f\n }\n f = f.parent\n }\n return null\n}\n\nfunction getStaticDocumentBodyChildren(children: ReactNode): ReactNode | null {\n const list = toChildArray(children)\n const html = list.find((child) => isHostElement(child, 'html')) as ReactElement | undefined\n if (!html) return null\n const htmlChildren = toChildArray(html.props?.children)\n const body = htmlChildren.find((child) => isHostElement(child, 'body')) as ReactElement | undefined\n return body ? body.props?.children ?? null : null\n}\n\nfunction normalizeDocumentChildren(children: ReactNode): ReactNode {\n const list = toChildArray(children)\n const htmlIndex = list.findIndex((child) => isHostElement(child, 'html'))\n if (htmlIndex === -1) return children\n\n const headNodes = list.filter(isHeadElement)\n if (headNodes.length === 0) return children\n\n const htmlElement = list[htmlIndex] as ReactElement\n const normalizedHtml = hoistIntoHtmlHead(htmlElement, headNodes)\n return list\n .filter((child, index) => index === htmlIndex || !isHeadElement(child))\n .map((child) => (child === htmlElement ? normalizedHtml : child))\n}\n\nfunction hoistIntoHtmlHead(htmlElement: ReactElement, headNodes: ReactNode[]): ReactElement {\n const htmlChildren = toChildArray(htmlElement.props?.children)\n const headIndex = htmlChildren.findIndex((child) => isHostElement(child, 'head'))\n let nextChildren: ReactNode[]\n\n if (headIndex === -1) {\n nextChildren = [\n createHostElement('head', { children: headNodes }),\n ...htmlChildren,\n ]\n } else {\n const headElement = htmlChildren[headIndex] as ReactElement\n const existingHeadChildren = toChildArray(headElement.props?.children)\n const nextHead = {\n ...headElement,\n props: {\n ...headElement.props,\n children: [...headNodes, ...existingHeadChildren],\n },\n }\n nextChildren = htmlChildren.map((child, index) => (index === headIndex ? nextHead : child))\n }\n\n return {\n ...htmlElement,\n props: {\n ...htmlElement.props,\n children: nextChildren,\n },\n }\n}\n\nfunction toChildArray(children: unknown): ReactNode[] {\n if (children == null || typeof children === 'boolean') return []\n if (Array.isArray(children)) return children as ReactNode[]\n if (isReactElement(children)) return [children]\n if (typeof children !== 'string' && isIterable(children)) return Array.from(children) as ReactNode[]\n return [children as ReactNode]\n}\n\nfunction isHeadElement(value: ReactNode): boolean {\n return isReactElement(value) && typeof value.type === 'string' && DOCUMENT_HEAD_TAGS.has(value.type)\n}\n\nfunction isHostElement(value: ReactNode, tag: string): boolean {\n return isReactElement(value) && value.type === tag\n}\n\nfunction isReactElement(value: unknown): value is ReactElement {\n return !!value && typeof value === 'object' && (value as ReactElement).$$typeof === REACT_ELEMENT_TYPE\n}\n\nfunction isIterable(value: unknown): value is Iterable<ReactNode> {\n return !!value && typeof (value as { [Symbol.iterator]?: unknown })[Symbol.iterator] == 'function'\n}\n\nfunction createHostElement(type: string, props: Record<string, unknown>): ReactElement {\n return {\n $$typeof: REACT_ELEMENT_TYPE,\n type,\n key: null,\n ref: null,\n props,\n }\n}\n\nfunction validateHydrationProps(\n fiber: Fiber,\n el: Element,\n props: Record<string, any>,\n tag: string,\n isSvg: boolean,\n): void {\n if (props.suppressHydrationWarning) return\n\n let expected: Element | undefined\n\n for (const k in props) {\n const value = props[k]\n if (\n k === 'children' ||\n k === 'key' ||\n k === 'ref' ||\n k === 'suppressHydrationWarning' ||\n k === 'suppressContentEditableWarning' ||\n (k[0] === 'o' && k[1] === 'n' && typeof value == 'function')\n ) continue\n\n if (k === 'dangerouslySetInnerHTML') {\n let html = '' + (value?.__html ?? '')\n if (tag !== 'script' && tag !== 'style') {\n const probe = document.createElement('div')\n probe.innerHTML = html\n html = probe.innerHTML\n }\n if ((el as HTMLElement).innerHTML !== html) {\n if (process.env.NODE_ENV !== 'production') {\n failHydration(\n fiber,\n new Error(`Hydration HTML mismatch inside <${tag}>.`),\n )\n }\n failHydration(fiber)\n }\n continue\n }\n\n if (k === 'value' || k === 'defaultValue') {\n if (tag === 'select') continue\n if (tag === 'input' || tag === 'textarea') {\n if (k === 'value' || props.value == null) {\n if (value != null && (el as HTMLInputElement).value !== '' + value) {\n if (process.env.NODE_ENV !== 'production') {\n failHydration(fiber, new Error(`Hydration ${tag} value mismatch on <${tag}>.`))\n }\n failHydration(fiber)\n }\n }\n continue\n }\n }\n\n if (tag === 'input' && (k === 'checked' || k === 'defaultChecked')) {\n if (k === 'checked' || props.checked == null) {\n if (value != null && (el as HTMLInputElement).checked !== !!value) {\n if (process.env.NODE_ENV !== 'production') {\n failHydration(fiber, new Error(`Hydration checked mismatch on <input>.`))\n }\n failHydration(fiber)\n }\n }\n continue\n }\n\n if (tag === 'option' && k === 'selected') {\n if (value != null && (el as HTMLOptionElement).selected !== !!value) {\n if (process.env.NODE_ENV !== 'production') {\n failHydration(fiber, new Error(`Hydration selected mismatch on <option>.`))\n }\n failHydration(fiber)\n }\n continue\n }\n\n if (k === 'style') {\n expected ??= createHostNode(tag, isSvg)\n setProp(expected, k, value, undefined, isSvg)\n if ((el as HTMLElement).style.cssText !== (expected as HTMLElement).style.cssText) {\n if (process.env.NODE_ENV !== 'production') {\n failHydration(\n fiber,\n new Error(`Hydration style mismatch on <${tag}>.`),\n )\n }\n failHydration(fiber)\n }\n continue\n }\n\n const stringifiedBoolean = k.startsWith('aria-') || k.startsWith('data-')\n const attr = attributeName(k, isSvg)\n\n let expectedValue: string | null\n if (value == null || (value === false && !stringifiedBoolean)) {\n expectedValue = null\n } else {\n expected ??= createHostNode(tag, isSvg)\n setProp(expected, k, value, undefined, isSvg)\n expectedValue = expected.getAttribute(attr)\n }\n const actualValue = el.getAttribute(attr)\n if (expectedValue !== actualValue) {\n if (process.env.NODE_ENV !== 'production') {\n failHydration(\n fiber,\n new Error(\n `Hydration attribute mismatch on <${tag}> for \"${attr}\": ` +\n `expected ${formatHydrationValue(expectedValue)} but found ${formatHydrationValue(actualValue)}.`,\n ),\n )\n }\n failHydration(fiber)\n }\n }\n}\n\nfunction formatHydrationValue(value: string | null): string {\n return value == null ? 'nothing' : JSON.stringify(value)\n}\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["import {\n FiberTag,\n REACT_ELEMENT_TYPE,\n type Fiber,\n type FiberRoot,\n type ReactElement,\n type ReactNode,\n} from '../../../core'\nimport { attributeName } from '../../../core/attributes'\nimport { createHostNode, setProp } from '../../dom'\nimport { drainReplayQueue } from '../../event-replay'\nimport { discardPendingWork, findRoot, flushSyncWork, renderRoot } from '../../reconcile'\nimport { attachRootFiber, createFiberRoot } from '../../root-internal'\n\n// Re-export from event-replay so all hydration concerns live behind one\n// feature boundary \u2014 the plugin's stub swap strips drainReplayQueue too.\nexport { drainReplayQueue }\n\n/**\n * Preserve the user's scroll position across hydration. If the user scrolled\n * between SSR paint and hydrate (common in dev where JS takes seconds to\n * load), libraries that wire scroll-restoration into a `useLayoutEffect`\n * near the root (e.g. TanStack Router) will run during our synchronous\n * hydrate and call `window.scrollTo(savedFromLastVisit)` \u2014 overwriting the\n * user's fresh scroll. We install a short-lived wrapper around scrollTo that\n * suppresses programmatic calls when a user-initiated scroll happened\n * recently. Only runs in the hydration feature \u2014 the stub skips it.\n */\nexport function installHydrationScrollGuard(): void {\n if (typeof window === 'undefined') return\n const w = window as any\n if (w._r) return\n const time = Date.now\n const guardStartedAt = w._r = time()\n let lastUserScrollAt = 0\n let programmatic = false\n w.addEventListener(\n 'scroll',\n () => {\n if (!programmatic) {\n lastUserScrollAt = time()\n }\n },\n { capture: true, passive: true },\n )\n const origScrollTo = w.scrollTo\n w.scrollTo = function (...args: any[]) {\n const now = time()\n if (\n now - guardStartedAt < 3000 &&\n now - lastUserScrollAt < 1500\n ) {\n return\n }\n programmatic = true\n try {\n return (origScrollTo as any).apply(w, args)\n } finally {\n queueMicrotask(() => {\n programmatic = false\n })\n }\n }\n}\n\n/**\n * Hydration cursor: walks existing DOM children in document order so we can\n * adopt them during fiber tree construction. One cursor per host parent.\n *\n * `endBefore` scopes the cursor to a subrange \u2014 used by rehydrateBoundary()\n * so we only adopt DOM up to the closing `/$` marker for that boundary.\n */\nexport class HydrationCursor {\n n: ChildNode | null\n p: Node\n e: ChildNode | null\n constructor(parent: Node, start: ChildNode | null = null, endBefore: ChildNode | null = null) {\n this.p = parent\n this.n = start ?? parent.firstChild\n this.e = endBefore\n }\n take(): ChildNode | null {\n while (this.n && this.n !== this.e) {\n const n = this.n\n // Skip anything that isn't an element (1) or text (3):\n // comments (8), doctype (10), processing instructions (7), cdata (4).\n if (n.nodeType !== 1 && n.nodeType !== 3) {\n this.n = n.nextSibling\n continue\n }\n this.n = n.nextSibling\n return n\n }\n return null\n }\n /**\n * Position-insensitive lookup for head/html adoption. Scans forward past\n * non-matching nodes without removing them, matching by tag AND the key\n * attributes that identify head elements uniquely (rel/href for links,\n * name/property for meta, src for script). Non-matching nodes stay in\n * place so the SSR'd stylesheet/script order is preserved.\n */\n head(tag: string, props: Record<string, any>): ChildNode | null {\n const target = tag.toLowerCase()\n const keyAttrs = HEAD_KEY_ATTRS[target]\n let scan = this.p.firstChild\n while (scan) {\n if (\n scan.nodeType === 1 &&\n (scan as Element).tagName.toLowerCase() === target &&\n headAttrsMatch(scan as Element, props, keyAttrs)\n ) {\n CLAIMED.add(scan)\n return scan\n }\n scan = scan.nextSibling\n }\n return null\n }\n has(): boolean {\n let n = this.n\n while (n && n !== this.e) {\n if (n.nodeType === 1 || n.nodeType === 3) return true\n n = n.nextSibling\n }\n return false\n }\n}\n\nconst hydrationCursors = new WeakMap<Fiber, HydrationCursor>()\nconst PROD_HYDRATION_ERROR = 'Hydration mismatch.'\n\nexport interface HydrationBailoutError extends Error {\n f: Fiber | null\n}\n\nexport function isHydrationBailout(error: unknown): error is HydrationBailoutError {\n return !!error && (error as any).f !== undefined\n}\n\nexport function abortHydration(cause: unknown, fiber: Fiber | null = null): never {\n const error = (cause instanceof Error ? cause : new Error(PROD_HYDRATION_ERROR)) as HydrationBailoutError\n ;(error as any).f = fiber\n throw error\n}\n\ninterface HydrateRootOptions {\n identifierPrefix?: string\n onRecoverableError?: (error: unknown) => void\n onCaughtError?: (error: unknown) => void\n onUncaughtError?: (error: unknown) => void\n}\n\ninterface HydratedRoot {\n render(children: ReactNode): void\n unmount(): void\n}\n\nexport function hydrateRootImpl(\n container: Element | Document,\n initialChildren: ReactNode,\n options: HydrateRootOptions,\n): HydratedRoot {\n const target = container as any as Element | Document\n const isDocument = (container as Node).nodeType === 9\n const body = isDocument ? (target as Document).body : null\n const root = createFiberRoot(target, options)\n\n installHydrationScrollGuard()\n\n const normalizedInitialChildren =\n isDocument ? normalizeDocumentChildren(initialChildren) : initialChildren\n let hydrationError: unknown = null\n beginHydration(root)\n try {\n flushSyncWork(() => {\n renderRoot(root, normalizedInitialChildren)\n })\n } catch (e) {\n hydrationError = e\n }\n endHydration(root)\n\n if (hydrationError && !recoverHydration(root, hydrationError)) throw hydrationError\n drainReplayQueue()\n\n return {\n render(children) {\n flushSyncWork(() => {\n const normalized = isDocument ? normalizeDocumentChildren(children) : children\n renderRoot(\n root,\n root.c === body ? getStaticDocumentBodyChildren(normalized) ?? normalized : normalized,\n )\n })\n },\n unmount() {\n flushSyncWork(() => {\n renderRoot(root, null)\n })\n },\n }\n}\n\n// Head elements that we match against server DOM by attribute signature.\nconst HEAD_KEY_ATTRS: Record<string, ReadonlyArray<string>> = {\n link: ['rel', 'href', 'sizes', 'type'],\n meta: ['name', 'property', 'charSet', 'httpEquiv'],\n script: ['src', 'type'],\n style: ['id', 'media', 'nonce', 'title'],\n}\n\nconst DOCUMENT_HEAD_TAGS = new Set(['base', 'link', 'meta', 'script', 'style', 'title'])\n\n// DOM elements already claimed by some fiber during this hydration pass.\nconst CLAIMED = new WeakSet<Node>()\n\nfunction headAttrsMatch(\n el: Element,\n props: Record<string, any>,\n keys: ReadonlyArray<string> | undefined,\n): boolean {\n if (CLAIMED.has(el)) return false\n if (!keys) return true\n for (const k of keys) {\n const propVal = props[k]\n const elVal = el.getAttribute(attributeName(k))\n if (propVal == null && elVal == null) continue\n if (propVal == null || elVal == null || String(propVal) !== elVal) return false\n }\n return true\n}\n\nexport function beginHydration(root: FiberRoot): void {\n root.ic = 0\n root.h = true\n hydrationCursors.set(root.r, new HydrationCursor(root.c))\n}\n\nexport function endHydration(root: FiberRoot): void {\n root.h = false\n hydrationCursors.delete(root.r)\n}\n\n/**\n * Inspect the current cursor position for a streaming-suspense boundary\n * marker emitted by the server. Returns info + advances the cursor past the\n * marker pair (start comment + fallback/real content + end comment).\n */\nexport type BoundaryInfo = [0 | 1, number, Comment, Comment]\n\nexport function tryConsumeBoundary(parent: Fiber): BoundaryInfo | null {\n const cursor = hydrationCursors.get(findHostParent(parent))\n if (!cursor) return null\n const peek = cursor.n\n if (!peek || peek.nodeType !== 8) return null\n const data = (peek as Comment).data\n const m = /^(\\$\\??)(\\d+)$/.exec(data)\n if (!m) return null\n const kind = m[1] === '$?' ? 1 : 0\n const id = Number(m[2])\n const startMark = peek as Comment\n // Advance past the start comment\n cursor.n = startMark.nextSibling\n // Locate end comment: closest <!--/$-->\n let endMark: Comment | null = null\n let scan = startMark.nextSibling\n while (scan) {\n if (scan.nodeType === 8 && (scan as Comment).data === '/$') {\n endMark = scan as Comment\n break\n }\n scan = scan.nextSibling\n }\n if (!endMark) return null\n return [kind, id, startMark, endMark]\n}\n\nexport function advanceCursorPast(parent: Fiber, node: Node): void {\n const cursor = hydrationCursors.get(findHostParent(parent))\n if (!cursor) return\n cursor.n = node.nextSibling\n}\n\nexport function getHydrationCursor(hostFiber: Fiber): HydrationCursor | undefined {\n return hydrationCursors.get(hostFiber)\n}\n\nexport function setHydrationCursor(hostFiber: Fiber, cursor: HydrationCursor): void {\n hydrationCursors.set(hostFiber, cursor)\n}\n\nexport function clearHydrationCursor(hostFiber: Fiber): void {\n hydrationCursors.delete(hostFiber)\n}\n\n/**\n * Try to adopt a DOM node for this host fiber. Returns true if adopted.\n * Attaches existing attrs/children via separate hydrate pass.\n */\nexport function adoptHostDom(fiber: Fiber, parent: Fiber): boolean {\n const hostParent = findHostParent(parent)\n const cursor = hydrationCursors.get(hostParent)\n if (!cursor) return false\n\n const tag = (fiber.type as string).toLowerCase()\n const documentHeadParent =\n cursor.p.nodeType === 9 && DOCUMENT_HEAD_TAGS.has(tag)\n ? (cursor.p as Document).head\n : null\n const parentEl = cursor.p as Element\n const parentTag =\n parentEl.nodeType === 1 ? (parentEl as Element).tagName.toLowerCase() : ''\n const isHeadish = parentTag === 'head' || parentTag === 'html' || !!documentHeadParent\n\n let candidate: ChildNode | null\n if (documentHeadParent) {\n // React 19 can project <meta>/<title>/<link> from anywhere in the tree into\n // document.head. Redact does not have that projection yet, so when a\n // document-root hydration pass sees a top-level head element, adopt it\n // from <head> rather than trying to append it beside <html>.\n candidate = new HydrationCursor(documentHeadParent).head(\n tag,\n fiber.pp ?? {},\n )\n } else if (isHeadish) {\n // Head/html children are position-insensitive \u2014 server may emit them in\n // a different order than the React tree (React 19 head hoisting, etc.).\n // Scan forward without removing non-matching nodes; match on attribute\n // signature so we don't adopt the wrong <link> and clobber its props.\n candidate = cursor.head(tag, fiber.pp ?? {})\n } else {\n candidate = cursor.take()\n }\n\n if (!candidate) {\n // Client expected a host here but the cursor is exhausted \u2014 server gave\n // fewer children than the client tree. Report the structural gap (React\n // fires `onRecoverableError` for this exact case) and let the reconciler\n // mount a fresh DOM for this fiber below.\n // Exception: <head> children are position-insensitive; a missing match\n // there means \"server didn't hoist this one yet\", which we silently mount.\n if (!isHeadish) onMismatch(fiber, null)\n return false\n }\n\n if (candidate.nodeType !== 1 || (candidate as Element).tagName.toLowerCase() !== tag) {\n // mismatch \u2014 log and re-render fresh from this point\n onMismatch(fiber, candidate)\n return false\n }\n fiber.dom = candidate\n // Apply props (attach events, sync IDL props). Don't re-set existing attrs.\n const props = fiber.pp ?? {}\n const isSvg =\n tag === 'svg' ||\n ((candidate as Element).namespaceURI === 'http://www.w3.org/2000/svg' &&\n tag !== 'foreignobject')\n const syncHydrationProps =\n !props.suppressHydrationWarning &&\n canRecoverHydrationPropMismatch(candidate, tag)\n validateHydrationProps(fiber, candidate as Element, props, tag, isSvg)\n for (const k in props) {\n if (\n k === 'children' ||\n k === 'key' ||\n k === 'ref' ||\n k === 'suppressHydrationWarning' ||\n k === 'suppressContentEditableWarning'\n ) continue\n if (\n syncHydrationProps ||\n (k[0] === 'o' && k[1] === 'n' && typeof props[k] == 'function')\n ) {\n setProp(candidate as Element, k, props[k], undefined, isSvg)\n }\n }\n // Set up child cursor for this host's children\n hydrationCursors.set(fiber, new HydrationCursor(candidate))\n return true\n}\n\nexport function adoptTextDom(fiber: Fiber, parent: Fiber, text: string): boolean {\n const cursor = hydrationCursors.get(findHostParent(parent))\n if (!cursor) return false\n const candidate = cursor.take()\n if (!candidate) {\n onMismatch(fiber, null)\n return false\n }\n if (candidate.nodeType === 3) {\n if ((candidate as Text).data !== text) {\n const recovered = failHydration(\n fiber,\n process.env.NODE_ENV !== 'production'\n ? new Error(\n `Hydration text mismatch: expected \"${text}\" but found \"${(candidate as Text).data}\".`,\n )\n : undefined,\n canRecoverHydrationPropMismatch(candidate),\n )\n if (recovered) {\n ;(candidate as Text).data = text\n }\n }\n fiber.dom = candidate\n return true\n }\n onMismatch(fiber, candidate)\n return false\n}\n\nexport function findHostParent(fiber: Fiber): Fiber {\n let f: Fiber | null = fiber\n while (f) {\n // A fiber explicitly holding a cursor acts as a boundary for hydration\n // (e.g. Suspense with a scoped cursor during fallback/boundary hydration).\n if (hydrationCursors.has(f)) return f\n if (f.tag === FiberTag.Host || f.tag === FiberTag.Root || f.tag === FiberTag.Portal) {\n return f\n }\n f = f.parent\n }\n if (process.env.NODE_ENV !== 'production') {\n throw new Error('No host parent found')\n }\n throw new Error()\n}\n\nfunction onMismatch(fiber: Fiber, actualNode: ChildNode | null): void {\n failHydration(\n fiber,\n process.env.NODE_ENV !== 'production'\n ? new Error(\n `Hydration mismatch: expected <${(fiber.type as string) ?? 'text'}> but found ${\n actualNode ? (actualNode.nodeType === 1 ? (actualNode as Element).tagName : 'text') : 'nothing'\n }.`,\n )\n : undefined,\n )\n}\n\nfunction failHydration(\n fiber: Fiber,\n error: Error = new Error(PROD_HYDRATION_ERROR),\n recoverInPlace = false,\n): boolean {\n const root = findRoot(fiber)\n if (root?.re) {\n root.re(error)\n }\n if (recoverInPlace) return true\n abortHydration(error, findHostRecoveryParent(fiber) ?? fiber)\n}\n\nfunction canRecoverHydrationPropMismatch(node: Node, tag?: string): boolean {\n return (\n tag === 'html' ||\n tag === 'head' ||\n tag === 'body' ||\n !!node.ownerDocument?.head?.contains(node)\n )\n}\n\nfunction findHostRecoveryParent(fiber: Fiber): Fiber | null {\n if (fiber.tag === FiberTag.Text) {\n let directHost = fiber.parent\n while (directHost && (directHost.tag !== FiberTag.Host || !directHost.dom)) {\n directHost = directHost.parent\n }\n if (!directHost) return null\n let hasEvent\n const props = directHost.pp ?? directHost.mp\n if (props) {\n for (const k in props) {\n if (k[0] === 'o' && k[1] === 'n' && typeof props[k] == 'function') {\n hasEvent = true\n }\n }\n }\n return findNearestSafeHostAboveComposite(\n hasEvent\n ? directHost.parent\n : directHost.parent?.tag === FiberTag.Host\n ? directHost.parent\n : directHost,\n )\n }\n\n return findNearestSafeHostAboveComposite(fiber.parent)\n}\n\nfunction findNearestSafeHostAboveComposite(fiber: Fiber | null): Fiber | null {\n let host: Fiber | null = null\n let f = fiber\n while (f) {\n if (f.tag === FiberTag.Host && f.dom) {\n if (!isSafeHostRecoveryElement(f)) return null\n const parentTag = f.parent?.tag as number\n if (!host || (parentTag > FiberTag.Text && parentTag < FiberTag.Suspense)) {\n host = f\n }\n }\n f = f.parent\n }\n return host\n}\n\nfunction isSafeHostRecoveryElement(fiber: Fiber): boolean {\n const tag = fiber.type.toLowerCase()\n return tag !== 'html' && tag !== 'head' && tag !== 'body'\n}\n\nexport function recoverHydration(root: FiberRoot, error: unknown): boolean {\n if (!isHydrationBailout(error)) return false\n\n let container = root.c as Element | Document\n let children = root.r.pp?.children ?? null\n const hostRecovery = getRecoverableHostChildren(error)\n if (hostRecovery) {\n container = hostRecovery[0]\n children = hostRecovery[1]\n } else if (container.nodeType === 9) {\n const bodyChildren = getRecoverableDocumentBodyChildren(error)\n if (bodyChildren != null) {\n container = (container as Document).body\n children = bodyChildren\n }\n }\n\n resetAfterHydrationFailure(root, container)\n try {\n flushSyncWork(() => renderRoot(root, children))\n } catch (clientError) {\n resetAfterHydrationFailure(root, container)\n throw clientError\n }\n return true\n}\n\nfunction resetAfterHydrationFailure(\n root: FiberRoot,\n container: Element | Document,\n): void {\n discardPendingWork(root)\n clearHydrationContainer(container)\n attachRootFiber(root, container)\n root.h = false\n}\n\nfunction clearHydrationContainer(container: Element | Document): void {\n if (container.nodeType === 9) {\n let node = container.firstChild\n while (node) {\n const next = node.nextSibling\n if (node.nodeType !== 10 /* DOCUMENT_TYPE_NODE */) {\n container.removeChild(node)\n }\n node = next\n }\n return\n }\n ;(container as Element).textContent = ''\n}\n\nfunction getRecoverableHostChildren(\n error: HydrationBailoutError,\n): [Element, ReactNode] | null {\n const host = error.f\n if (\n host?.tag !== FiberTag.Host ||\n !host.dom ||\n !findNearestSafeHostAboveComposite(host.parent)\n ) {\n return null\n }\n return [host.dom as Element, (host.pp ?? host.mp)?.children ?? null]\n}\n\nfunction getRecoverableDocumentBodyChildren(error: HydrationBailoutError): ReactNode | null {\n const bodyFiber = findBodyAncestor(error.f)\n if (!bodyFiber) return null\n return (bodyFiber.pp ?? bodyFiber.mp)?.children ?? null\n}\n\nfunction findBodyAncestor(fiber: Fiber | null): Fiber | null {\n let f = fiber\n while (f) {\n if (f.tag === FiberTag.Host && f.type === 'body') {\n return f === fiber ? null : f\n }\n f = f.parent\n }\n return null\n}\n\nfunction getStaticDocumentBodyChildren(children: ReactNode): ReactNode | null {\n const list = toChildArray(children)\n const html = list.find((child) => isHostElement(child, 'html')) as ReactElement | undefined\n if (!html) return null\n const htmlChildren = toChildArray(html.props?.children)\n const body = htmlChildren.find((child) => isHostElement(child, 'body')) as ReactElement | undefined\n return body ? body.props?.children ?? null : null\n}\n\nfunction normalizeDocumentChildren(children: ReactNode): ReactNode {\n const list = toChildArray(children)\n const htmlIndex = list.findIndex((child) => isHostElement(child, 'html'))\n if (htmlIndex === -1) return children\n\n const headNodes = list.filter(isHeadElement)\n if (headNodes.length === 0) return children\n\n const htmlElement = list[htmlIndex] as ReactElement\n const normalizedHtml = hoistIntoHtmlHead(htmlElement, headNodes)\n return list\n .filter((child, index) => index === htmlIndex || !isHeadElement(child))\n .map((child) => (child === htmlElement ? normalizedHtml : child))\n}\n\nfunction hoistIntoHtmlHead(htmlElement: ReactElement, headNodes: ReactNode[]): ReactElement {\n const htmlChildren = toChildArray(htmlElement.props?.children)\n const headIndex = htmlChildren.findIndex((child) => isHostElement(child, 'head'))\n let nextChildren: ReactNode[]\n\n if (headIndex === -1) {\n nextChildren = [\n createHostElement('head', { children: headNodes }),\n ...htmlChildren,\n ]\n } else {\n const headElement = htmlChildren[headIndex] as ReactElement\n const existingHeadChildren = toChildArray(headElement.props?.children)\n const nextHead = {\n ...headElement,\n props: {\n ...headElement.props,\n children: [...headNodes, ...existingHeadChildren],\n },\n }\n nextChildren = htmlChildren.map((child, index) => (index === headIndex ? nextHead : child))\n }\n\n return {\n ...htmlElement,\n props: {\n ...htmlElement.props,\n children: nextChildren,\n },\n }\n}\n\nfunction toChildArray(children: unknown): ReactNode[] {\n if (children == null || typeof children === 'boolean') return []\n if (Array.isArray(children)) return children as ReactNode[]\n if (isReactElement(children)) return [children]\n if (typeof children !== 'string' && isIterable(children)) return Array.from(children) as ReactNode[]\n return [children as ReactNode]\n}\n\nfunction isHeadElement(value: ReactNode): boolean {\n return isReactElement(value) && typeof value.type === 'string' && DOCUMENT_HEAD_TAGS.has(value.type)\n}\n\nfunction isHostElement(value: ReactNode, tag: string): boolean {\n return isReactElement(value) && value.type === tag\n}\n\nfunction isReactElement(value: unknown): value is ReactElement {\n return !!value && typeof value === 'object' && (value as ReactElement).$$typeof === REACT_ELEMENT_TYPE\n}\n\nfunction isIterable(value: unknown): value is Iterable<ReactNode> {\n return !!value && typeof (value as { [Symbol.iterator]?: unknown })[Symbol.iterator] == 'function'\n}\n\nfunction createHostElement(type: string, props: Record<string, unknown>): ReactElement {\n return {\n $$typeof: REACT_ELEMENT_TYPE,\n type,\n key: null,\n ref: null,\n props,\n }\n}\n\nfunction validateHydrationProps(\n fiber: Fiber,\n el: Element,\n props: Record<string, any>,\n tag: string,\n isSvg: boolean,\n): void {\n if (props.suppressHydrationWarning) return\n\n const recoverInPlace = canRecoverHydrationPropMismatch(el, tag)\n let expected: Element | undefined\n\n for (const k in props) {\n const value = props[k]\n if (\n k === 'children' ||\n k === 'key' ||\n k === 'ref' ||\n k === 'suppressHydrationWarning' ||\n k === 'suppressContentEditableWarning' ||\n (k[0] === 'o' && k[1] === 'n' && typeof value == 'function')\n ) continue\n\n if (k === 'dangerouslySetInnerHTML') {\n let html = '' + (value?.__html ?? '')\n if (tag !== 'script' && tag !== 'style') {\n const probe = document.createElement('div')\n probe.innerHTML = html\n html = probe.innerHTML\n }\n if ((el as HTMLElement).innerHTML !== html) {\n failHydration(\n fiber,\n process.env.NODE_ENV !== 'production'\n ? new Error(`Hydration HTML mismatch inside <${tag}>.`)\n : undefined,\n recoverInPlace,\n )\n }\n continue\n }\n\n if (k === 'value' || k === 'defaultValue') {\n if (tag === 'select') continue\n if (tag === 'input' || tag === 'textarea') {\n if (k === 'value' || props.value == null) {\n if (value != null && (el as HTMLInputElement).value !== '' + value) {\n failHydration(\n fiber,\n process.env.NODE_ENV !== 'production'\n ? new Error(`Hydration ${tag} value mismatch on <${tag}>.`)\n : undefined,\n recoverInPlace,\n )\n }\n }\n continue\n }\n }\n\n if (tag === 'input' && (k === 'checked' || k === 'defaultChecked')) {\n if (k === 'checked' || props.checked == null) {\n if (value != null && (el as HTMLInputElement).checked !== !!value) {\n failHydration(\n fiber,\n process.env.NODE_ENV !== 'production'\n ? new Error(`Hydration checked mismatch on <input>.`)\n : undefined,\n recoverInPlace,\n )\n }\n }\n continue\n }\n\n if (tag === 'option' && k === 'selected') {\n if (value != null && (el as HTMLOptionElement).selected !== !!value) {\n failHydration(\n fiber,\n process.env.NODE_ENV !== 'production'\n ? new Error(`Hydration selected mismatch on <option>.`)\n : undefined,\n recoverInPlace,\n )\n }\n continue\n }\n\n if (k === 'style') {\n expected ??= createHostNode(tag, isSvg)\n setProp(expected, k, value, undefined, isSvg)\n if (\n !hydrationStylesMatch(\n (el as HTMLElement).style,\n (expected as HTMLElement).style,\n )\n ) {\n failHydration(\n fiber,\n process.env.NODE_ENV !== 'production'\n ? new Error(`Hydration style mismatch on <${tag}>.`)\n : undefined,\n recoverInPlace,\n )\n }\n continue\n }\n\n const stringifiedBoolean = k.startsWith('aria-') || k.startsWith('data-')\n const attr = attributeName(k, isSvg)\n\n let expectedValue: string | null\n if (value == null || (value === false && !stringifiedBoolean)) {\n expectedValue = null\n } else {\n expected ??= createHostNode(tag, isSvg)\n setProp(expected, k, value, undefined, isSvg)\n expectedValue = expected.getAttribute(attr)\n }\n const actualValue = el.getAttribute(attr)\n if (expectedValue !== actualValue) {\n failHydration(\n fiber,\n process.env.NODE_ENV !== 'production'\n ? new Error(\n `Hydration attribute mismatch on <${tag}> for \"${attr}\": ` +\n `expected ${formatHydrationValue(expectedValue)} but found ${formatHydrationValue(actualValue)}.`,\n )\n : undefined,\n recoverInPlace,\n )\n }\n }\n}\n\nfunction hydrationStylesMatch(\n actual: CSSStyleDeclaration,\n expected: CSSStyleDeclaration,\n): boolean {\n for (let index = 0; index < expected.length; index++) {\n const property = expected.item(index)\n if (\n actual.getPropertyValue(property) !== expected.getPropertyValue(property) ||\n actual.getPropertyPriority(property) !== expected.getPropertyPriority(property)\n ) {\n return false\n }\n }\n return true\n}\n\nfunction formatHydrationValue(value: string | null): string {\n return value == null ? 'nothing' : JSON.stringify(value)\n}\n"],
5
+ "mappings": ";AAAA;AAAA,EACE;AAAA,EACA;AAAA,OAKK;AACP,SAAS,qBAAqB;AAC9B,SAAS,gBAAgB,eAAe;AACxC,SAAS,wBAAwB;AACjC,SAAS,oBAAoB,UAAU,eAAe,kBAAkB;AACxE,SAAS,iBAAiB,uBAAuB;AAgB1C,SAAS,8BAAoC;AAClD,MAAI,OAAO,WAAW,YAAa;AACnC,QAAM,IAAI;AACV,MAAI,EAAE,GAAI;AACV,QAAM,OAAO,KAAK;AAClB,QAAM,iBAAiB,EAAE,KAAK,KAAK;AACnC,MAAI,mBAAmB;AACvB,MAAI,eAAe;AACnB,IAAE;AAAA,IACA;AAAA,IACA,MAAM;AACJ,UAAI,CAAC,cAAc;AACjB,2BAAmB,KAAK;AAAA,MAC1B;AAAA,IACF;AAAA,IACA,EAAE,SAAS,MAAM,SAAS,KAAK;AAAA,EACjC;AACA,QAAM,eAAe,EAAE;AACvB,IAAE,WAAW,YAAa,MAAa;AACrC,UAAM,MAAM,KAAK;AACjB,QACE,MAAM,iBAAiB,OACvB,MAAM,mBAAmB,MACzB;AACA;AAAA,IACF;AACA,mBAAe;AACf,QAAI;AACF,aAAQ,aAAqB,MAAM,GAAG,IAAI;AAAA,IAC5C,UAAE;AACA,qBAAe,MAAM;AACnB,uBAAe;AAAA,MACjB,CAAC;AAAA,IACH;AAAA,EACF;AACF;AASO,IAAM,kBAAN,MAAsB;AAAA,EAC3B;AAAA,EACA;AAAA,EACA;AAAA,EACA,YAAY,QAAc,QAA0B,MAAM,YAA8B,MAAM;AAC5F,SAAK,IAAI;AACT,SAAK,IAAI,SAAS,OAAO;AACzB,SAAK,IAAI;AAAA,EACX;AAAA,EACA,OAAyB;AACvB,WAAO,KAAK,KAAK,KAAK,MAAM,KAAK,GAAG;AAClC,YAAM,IAAI,KAAK;AAGf,UAAI,EAAE,aAAa,KAAK,EAAE,aAAa,GAAG;AACxC,aAAK,IAAI,EAAE;AACX;AAAA,MACF;AACA,WAAK,IAAI,EAAE;AACX,aAAO;AAAA,IACT;AACA,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,KAAK,KAAa,OAA8C;AAC9D,UAAM,SAAS,IAAI,YAAY;AAC/B,UAAM,WAAW,eAAe,MAAM;AACtC,QAAI,OAAO,KAAK,EAAE;AAClB,WAAO,MAAM;AACX,UACE,KAAK,aAAa,KACjB,KAAiB,QAAQ,YAAY,MAAM,UAC5C,eAAe,MAAiB,OAAO,QAAQ,GAC/C;AACA,gBAAQ,IAAI,IAAI;AAChB,eAAO;AAAA,MACT;AACA,aAAO,KAAK;AAAA,IACd;AACA,WAAO;AAAA,EACT;AAAA,EACA,MAAe;AACb,QAAI,IAAI,KAAK;AACb,WAAO,KAAK,MAAM,KAAK,GAAG;AACxB,UAAI,EAAE,aAAa,KAAK,EAAE,aAAa,EAAG,QAAO;AACjD,UAAI,EAAE;AAAA,IACR;AACA,WAAO;AAAA,EACT;AACF;AAEA,IAAM,mBAAmB,oBAAI,QAAgC;AAC7D,IAAM,uBAAuB;AAMtB,SAAS,mBAAmB,OAAgD;AACjF,SAAO,CAAC,CAAC,SAAU,MAAc,MAAM;AACzC;AAEO,SAAS,eAAe,OAAgB,QAAsB,MAAa;AAChF,QAAM,QAAS,iBAAiB,QAAQ,QAAQ,IAAI,MAAM,oBAAoB;AAC7E,EAAC,MAAc,IAAI;AACpB,QAAM;AACR;AAcO,SAAS,gBACd,WACA,iBACA,SACc;AACd,QAAM,SAAS;AACf,QAAM,aAAc,UAAmB,aAAa;AACpD,QAAM,OAAO,aAAc,OAAoB,OAAO;AACtD,QAAM,OAAO,gBAAgB,QAAQ,OAAO;AAE5C,8BAA4B;AAE5B,QAAM,4BACJ,aAAa,0BAA0B,eAAe,IAAI;AAC5D,MAAI,iBAA0B;AAC9B,iBAAe,IAAI;AACnB,MAAI;AACF,kBAAc,MAAM;AAClB,iBAAW,MAAM,yBAAyB;AAAA,IAC5C,CAAC;AAAA,EACH,SAAS,GAAG;AACV,qBAAiB;AAAA,EACnB;AACA,eAAa,IAAI;AAEjB,MAAI,kBAAkB,CAAC,iBAAiB,MAAM,cAAc,EAAG,OAAM;AACrE,mBAAiB;AAEjB,SAAO;AAAA,IACL,OAAO,UAAU;AACf,oBAAc,MAAM;AAClB,cAAM,aAAa,aAAa,0BAA0B,QAAQ,IAAI;AACtE;AAAA,UACE;AAAA,UACA,KAAK,MAAM,OAAO,8BAA8B,UAAU,KAAK,aAAa;AAAA,QAC9E;AAAA,MACF,CAAC;AAAA,IACH;AAAA,IACA,UAAU;AACR,oBAAc,MAAM;AAClB,mBAAW,MAAM,IAAI;AAAA,MACvB,CAAC;AAAA,IACH;AAAA,EACF;AACF;AAGA,IAAM,iBAAwD;AAAA,EAC5D,MAAM,CAAC,OAAO,QAAQ,SAAS,MAAM;AAAA,EACrC,MAAM,CAAC,QAAQ,YAAY,WAAW,WAAW;AAAA,EACjD,QAAQ,CAAC,OAAO,MAAM;AAAA,EACtB,OAAO,CAAC,MAAM,SAAS,SAAS,OAAO;AACzC;AAEA,IAAM,qBAAqB,oBAAI,IAAI,CAAC,QAAQ,QAAQ,QAAQ,UAAU,SAAS,OAAO,CAAC;AAGvF,IAAM,UAAU,oBAAI,QAAc;AAElC,SAAS,eACP,IACA,OACA,MACS;AACT,MAAI,QAAQ,IAAI,EAAE,EAAG,QAAO;AAC5B,MAAI,CAAC,KAAM,QAAO;AAClB,aAAW,KAAK,MAAM;AACpB,UAAM,UAAU,MAAM,CAAC;AACvB,UAAM,QAAQ,GAAG,aAAa,cAAc,CAAC,CAAC;AAC9C,QAAI,WAAW,QAAQ,SAAS,KAAM;AACtC,QAAI,WAAW,QAAQ,SAAS,QAAQ,OAAO,OAAO,MAAM,MAAO,QAAO;AAAA,EAC5E;AACA,SAAO;AACT;AAEO,SAAS,eAAe,MAAuB;AACpD,OAAK,KAAK;AACV,OAAK,IAAI;AACT,mBAAiB,IAAI,KAAK,GAAG,IAAI,gBAAgB,KAAK,CAAC,CAAC;AAC1D;AAEO,SAAS,aAAa,MAAuB;AAClD,OAAK,IAAI;AACT,mBAAiB,OAAO,KAAK,CAAC;AAChC;AASO,SAAS,mBAAmB,QAAoC;AACrE,QAAM,SAAS,iBAAiB,IAAI,eAAe,MAAM,CAAC;AAC1D,MAAI,CAAC,OAAQ,QAAO;AACpB,QAAM,OAAO,OAAO;AACpB,MAAI,CAAC,QAAQ,KAAK,aAAa,EAAG,QAAO;AACzC,QAAM,OAAQ,KAAiB;AAC/B,QAAM,IAAI,iBAAiB,KAAK,IAAI;AACpC,MAAI,CAAC,EAAG,QAAO;AACf,QAAM,OAAO,EAAE,CAAC,MAAM,OAAO,IAAI;AACjC,QAAM,KAAK,OAAO,EAAE,CAAC,CAAC;AACtB,QAAM,YAAY;AAElB,SAAO,IAAI,UAAU;AAErB,MAAI,UAA0B;AAC9B,MAAI,OAAO,UAAU;AACrB,SAAO,MAAM;AACX,QAAI,KAAK,aAAa,KAAM,KAAiB,SAAS,MAAM;AAC1D,gBAAU;AACV;AAAA,IACF;AACA,WAAO,KAAK;AAAA,EACd;AACA,MAAI,CAAC,QAAS,QAAO;AACrB,SAAO,CAAC,MAAM,IAAI,WAAW,OAAO;AACtC;AAEO,SAAS,kBAAkB,QAAe,MAAkB;AACjE,QAAM,SAAS,iBAAiB,IAAI,eAAe,MAAM,CAAC;AAC1D,MAAI,CAAC,OAAQ;AACb,SAAO,IAAI,KAAK;AAClB;AAEO,SAAS,mBAAmB,WAA+C;AAChF,SAAO,iBAAiB,IAAI,SAAS;AACvC;AAEO,SAAS,mBAAmB,WAAkB,QAA+B;AAClF,mBAAiB,IAAI,WAAW,MAAM;AACxC;AAEO,SAAS,qBAAqB,WAAwB;AAC3D,mBAAiB,OAAO,SAAS;AACnC;AAMO,SAAS,aAAa,OAAc,QAAwB;AACjE,QAAM,aAAa,eAAe,MAAM;AACxC,QAAM,SAAS,iBAAiB,IAAI,UAAU;AAC9C,MAAI,CAAC,OAAQ,QAAO;AAEpB,QAAM,MAAO,MAAM,KAAgB,YAAY;AAC/C,QAAM,qBACJ,OAAO,EAAE,aAAa,KAAK,mBAAmB,IAAI,GAAG,IAChD,OAAO,EAAe,OACvB;AACN,QAAM,WAAW,OAAO;AACxB,QAAM,YACJ,SAAS,aAAa,IAAK,SAAqB,QAAQ,YAAY,IAAI;AAC1E,QAAM,YAAY,cAAc,UAAU,cAAc,UAAU,CAAC,CAAC;AAEpE,MAAI;AACJ,MAAI,oBAAoB;AAKtB,gBAAY,IAAI,gBAAgB,kBAAkB,EAAE;AAAA,MAClD;AAAA,MACA,MAAM,MAAM,CAAC;AAAA,IACf;AAAA,EACF,WAAW,WAAW;AAKpB,gBAAY,OAAO,KAAK,KAAK,MAAM,MAAM,CAAC,CAAC;AAAA,EAC7C,OAAO;AACL,gBAAY,OAAO,KAAK;AAAA,EAC1B;AAEA,MAAI,CAAC,WAAW;AAOd,QAAI,CAAC,UAAW,YAAW,OAAO,IAAI;AACtC,WAAO;AAAA,EACT;AAEA,MAAI,UAAU,aAAa,KAAM,UAAsB,QAAQ,YAAY,MAAM,KAAK;AAEpF,eAAW,OAAO,SAAS;AAC3B,WAAO;AAAA,EACT;AACA,QAAM,MAAM;AAEZ,QAAM,QAAQ,MAAM,MAAM,CAAC;AAC3B,QAAM,QACJ,QAAQ,SACN,UAAsB,iBAAiB,gCACvC,QAAQ;AACZ,QAAM,qBACJ,CAAC,MAAM,4BACP,gCAAgC,WAAW,GAAG;AAChD,yBAAuB,OAAO,WAAsB,OAAO,KAAK,KAAK;AACrE,aAAW,KAAK,OAAO;AACrB,QACE,MAAM,cACN,MAAM,SACN,MAAM,SACN,MAAM,8BACN,MAAM,iCACN;AACF,QACE,sBACC,EAAE,CAAC,MAAM,OAAO,EAAE,CAAC,MAAM,OAAO,OAAO,MAAM,CAAC,KAAK,YACpD;AACA,cAAQ,WAAsB,GAAG,MAAM,CAAC,GAAG,QAAW,KAAK;AAAA,IAC7D;AAAA,EACF;AAEA,mBAAiB,IAAI,OAAO,IAAI,gBAAgB,SAAS,CAAC;AAC1D,SAAO;AACT;AAEO,SAAS,aAAa,OAAc,QAAe,MAAuB;AAC/E,QAAM,SAAS,iBAAiB,IAAI,eAAe,MAAM,CAAC;AAC1D,MAAI,CAAC,OAAQ,QAAO;AACpB,QAAM,YAAY,OAAO,KAAK;AAC9B,MAAI,CAAC,WAAW;AACd,eAAW,OAAO,IAAI;AACtB,WAAO;AAAA,EACT;AACA,MAAI,UAAU,aAAa,GAAG;AAC5B,QAAK,UAAmB,SAAS,MAAM;AACrC,YAAM,YAAY;AAAA,QAChB;AAAA,QACA,OACI,IAAI;AAAA,UACF,sCAAsC,IAAI,gBAAiB,UAAmB,IAAI;AAAA,QACpF,IACA;AAAA,QACJ,gCAAgC,SAAS;AAAA,MAC3C;AACA,UAAI,WAAW;AACb;AAAC,QAAC,UAAmB,OAAO;AAAA,MAC9B;AAAA,IACF;AACA,UAAM,MAAM;AACZ,WAAO;AAAA,EACT;AACA,aAAW,OAAO,SAAS;AAC3B,SAAO;AACT;AAEO,SAAS,eAAe,OAAqB;AAClD,MAAI,IAAkB;AACtB,SAAO,GAAG;AAGR,QAAI,iBAAiB,IAAI,CAAC,EAAG,QAAO;AACpC,QAAI,EAAE,QAAQ,SAAS,QAAQ,EAAE,QAAQ,SAAS,QAAQ,EAAE,QAAQ,SAAS,QAAQ;AACnF,aAAO;AAAA,IACT;AACA,QAAI,EAAE;AAAA,EACR;AACA,MAAI,MAAuC;AACzC,UAAM,IAAI,MAAM,sBAAsB;AAAA,EACxC;AACA,QAAM,IAAI,MAAM;AAClB;AAEA,SAAS,WAAW,OAAc,YAAoC;AACpE;AAAA,IACE;AAAA,IACA,OACI,IAAI;AAAA,MACF,iCAAkC,MAAM,QAAmB,MAAM,eAC/D,aAAc,WAAW,aAAa,IAAK,WAAuB,UAAU,SAAU,SACxF;AAAA,IACF,IACA;AAAA,EACN;AACF;AAEA,SAAS,cACP,OACA,QAAe,IAAI,MAAM,oBAAoB,GAC7C,iBAAiB,OACR;AACT,QAAM,OAAO,SAAS,KAAK;AAC3B,MAAI,MAAM,IAAI;AACZ,SAAK,GAAG,KAAK;AAAA,EACf;AACA,MAAI,eAAgB,QAAO;AAC3B,iBAAe,OAAO,uBAAuB,KAAK,KAAK,KAAK;AAC9D;AAEA,SAAS,gCAAgC,MAAY,KAAuB;AAC1E,SACE,QAAQ,UACR,QAAQ,UACR,QAAQ,UACR,CAAC,CAAC,KAAK,eAAe,MAAM,SAAS,IAAI;AAE7C;AAEA,SAAS,uBAAuB,OAA4B;AAC1D,MAAI,MAAM,QAAQ,SAAS,MAAM;AAC/B,QAAI,aAAa,MAAM;AACvB,WAAO,eAAe,WAAW,QAAQ,SAAS,QAAQ,CAAC,WAAW,MAAM;AAC1E,mBAAa,WAAW;AAAA,IAC1B;AACA,QAAI,CAAC,WAAY,QAAO;AACxB,QAAI;AACJ,UAAM,QAAQ,WAAW,MAAM,WAAW;AAC1C,QAAI,OAAO;AACT,iBAAW,KAAK,OAAO;AACrB,YAAI,EAAE,CAAC,MAAM,OAAO,EAAE,CAAC,MAAM,OAAO,OAAO,MAAM,CAAC,KAAK,YAAY;AACjE,qBAAW;AAAA,QACb;AAAA,MACF;AAAA,IACF;AACA,WAAO;AAAA,MACL,WACI,WAAW,SACX,WAAW,QAAQ,QAAQ,SAAS,OAClC,WAAW,SACX;AAAA,IACR;AAAA,EACF;AAEA,SAAO,kCAAkC,MAAM,MAAM;AACvD;AAEA,SAAS,kCAAkC,OAAmC;AAC5E,MAAI,OAAqB;AACzB,MAAI,IAAI;AACR,SAAO,GAAG;AACR,QAAI,EAAE,QAAQ,SAAS,QAAQ,EAAE,KAAK;AACpC,UAAI,CAAC,0BAA0B,CAAC,EAAG,QAAO;AAC1C,YAAM,YAAY,EAAE,QAAQ;AAC5B,UAAI,CAAC,QAAS,YAAY,SAAS,QAAQ,YAAY,SAAS,UAAW;AACzE,eAAO;AAAA,MACT;AAAA,IACF;AACA,QAAI,EAAE;AAAA,EACR;AACA,SAAO;AACT;AAEA,SAAS,0BAA0B,OAAuB;AACxD,QAAM,MAAM,MAAM,KAAK,YAAY;AACnC,SAAO,QAAQ,UAAU,QAAQ,UAAU,QAAQ;AACrD;AAEO,SAAS,iBAAiB,MAAiB,OAAyB;AACzE,MAAI,CAAC,mBAAmB,KAAK,EAAG,QAAO;AAEvC,MAAI,YAAY,KAAK;AACrB,MAAI,WAAW,KAAK,EAAE,IAAI,YAAY;AACtC,QAAM,eAAe,2BAA2B,KAAK;AACrD,MAAI,cAAc;AAChB,gBAAY,aAAa,CAAC;AAC1B,eAAW,aAAa,CAAC;AAAA,EAC3B,WAAW,UAAU,aAAa,GAAG;AACnC,UAAM,eAAe,mCAAmC,KAAK;AAC7D,QAAI,gBAAgB,MAAM;AACxB,kBAAa,UAAuB;AACpC,iBAAW;AAAA,IACb;AAAA,EACF;AAEA,6BAA2B,MAAM,SAAS;AAC1C,MAAI;AACF,kBAAc,MAAM,WAAW,MAAM,QAAQ,CAAC;AAAA,EAChD,SAAS,aAAa;AACpB,+BAA2B,MAAM,SAAS;AAC1C,UAAM;AAAA,EACR;AACA,SAAO;AACT;AAEA,SAAS,2BACP,MACA,WACM;AACN,qBAAmB,IAAI;AACvB,0BAAwB,SAAS;AACjC,kBAAgB,MAAM,SAAS;AAC/B,OAAK,IAAI;AACX;AAEA,SAAS,wBAAwB,WAAqC;AACpE,MAAI,UAAU,aAAa,GAAG;AAC5B,QAAI,OAAO,UAAU;AACrB,WAAO,MAAM;AACX,YAAM,OAAO,KAAK;AAClB,UAAI,KAAK,aAAa,IAA6B;AACjD,kBAAU,YAAY,IAAI;AAAA,MAC5B;AACA,aAAO;AAAA,IACT;AACA;AAAA,EACF;AACA;AAAC,EAAC,UAAsB,cAAc;AACxC;AAEA,SAAS,2BACP,OAC6B;AAC7B,QAAM,OAAO,MAAM;AACnB,MACE,MAAM,QAAQ,SAAS,QACvB,CAAC,KAAK,OACN,CAAC,kCAAkC,KAAK,MAAM,GAC9C;AACA,WAAO;AAAA,EACT;AACA,SAAO,CAAC,KAAK,MAAiB,KAAK,MAAM,KAAK,KAAK,YAAY,IAAI;AACrE;AAEA,SAAS,mCAAmC,OAAgD;AAC1F,QAAM,YAAY,iBAAiB,MAAM,CAAC;AAC1C,MAAI,CAAC,UAAW,QAAO;AACvB,UAAQ,UAAU,MAAM,UAAU,KAAK,YAAY;AACrD;AAEA,SAAS,iBAAiB,OAAmC;AAC3D,MAAI,IAAI;AACR,SAAO,GAAG;AACR,QAAI,EAAE,QAAQ,SAAS,QAAQ,EAAE,SAAS,QAAQ;AAChD,aAAO,MAAM,QAAQ,OAAO;AAAA,IAC9B;AACA,QAAI,EAAE;AAAA,EACR;AACA,SAAO;AACT;AAEA,SAAS,8BAA8B,UAAuC;AAC5E,QAAM,OAAO,aAAa,QAAQ;AAClC,QAAM,OAAO,KAAK,KAAK,CAAC,UAAU,cAAc,OAAO,MAAM,CAAC;AAC9D,MAAI,CAAC,KAAM,QAAO;AAClB,QAAM,eAAe,aAAa,KAAK,OAAO,QAAQ;AACtD,QAAM,OAAO,aAAa,KAAK,CAAC,UAAU,cAAc,OAAO,MAAM,CAAC;AACtE,SAAO,OAAO,KAAK,OAAO,YAAY,OAAO;AAC/C;AAEA,SAAS,0BAA0B,UAAgC;AACjE,QAAM,OAAO,aAAa,QAAQ;AAClC,QAAM,YAAY,KAAK,UAAU,CAAC,UAAU,cAAc,OAAO,MAAM,CAAC;AACxE,MAAI,cAAc,GAAI,QAAO;AAE7B,QAAM,YAAY,KAAK,OAAO,aAAa;AAC3C,MAAI,UAAU,WAAW,EAAG,QAAO;AAEnC,QAAM,cAAc,KAAK,SAAS;AAClC,QAAM,iBAAiB,kBAAkB,aAAa,SAAS;AAC/D,SAAO,KACJ,OAAO,CAAC,OAAO,UAAU,UAAU,aAAa,CAAC,cAAc,KAAK,CAAC,EACrE,IAAI,CAAC,UAAW,UAAU,cAAc,iBAAiB,KAAM;AACpE;AAEA,SAAS,kBAAkB,aAA2B,WAAsC;AAC1F,QAAM,eAAe,aAAa,YAAY,OAAO,QAAQ;AAC7D,QAAM,YAAY,aAAa,UAAU,CAAC,UAAU,cAAc,OAAO,MAAM,CAAC;AAChF,MAAI;AAEJ,MAAI,cAAc,IAAI;AACpB,mBAAe;AAAA,MACb,kBAAkB,QAAQ,EAAE,UAAU,UAAU,CAAC;AAAA,MACjD,GAAG;AAAA,IACL;AAAA,EACF,OAAO;AACL,UAAM,cAAc,aAAa,SAAS;AAC1C,UAAM,uBAAuB,aAAa,YAAY,OAAO,QAAQ;AACrE,UAAM,WAAW;AAAA,MACf,GAAG;AAAA,MACH,OAAO;AAAA,QACL,GAAG,YAAY;AAAA,QACf,UAAU,CAAC,GAAG,WAAW,GAAG,oBAAoB;AAAA,MAClD;AAAA,IACF;AACA,mBAAe,aAAa,IAAI,CAAC,OAAO,UAAW,UAAU,YAAY,WAAW,KAAM;AAAA,EAC5F;AAEA,SAAO;AAAA,IACL,GAAG;AAAA,IACH,OAAO;AAAA,MACL,GAAG,YAAY;AAAA,MACf,UAAU;AAAA,IACZ;AAAA,EACF;AACF;AAEA,SAAS,aAAa,UAAgC;AACpD,MAAI,YAAY,QAAQ,OAAO,aAAa,UAAW,QAAO,CAAC;AAC/D,MAAI,MAAM,QAAQ,QAAQ,EAAG,QAAO;AACpC,MAAI,eAAe,QAAQ,EAAG,QAAO,CAAC,QAAQ;AAC9C,MAAI,OAAO,aAAa,YAAY,WAAW,QAAQ,EAAG,QAAO,MAAM,KAAK,QAAQ;AACpF,SAAO,CAAC,QAAqB;AAC/B;AAEA,SAAS,cAAc,OAA2B;AAChD,SAAO,eAAe,KAAK,KAAK,OAAO,MAAM,SAAS,YAAY,mBAAmB,IAAI,MAAM,IAAI;AACrG;AAEA,SAAS,cAAc,OAAkB,KAAsB;AAC7D,SAAO,eAAe,KAAK,KAAK,MAAM,SAAS;AACjD;AAEA,SAAS,eAAe,OAAuC;AAC7D,SAAO,CAAC,CAAC,SAAS,OAAO,UAAU,YAAa,MAAuB,aAAa;AACtF;AAEA,SAAS,WAAW,OAA8C;AAChE,SAAO,CAAC,CAAC,SAAS,OAAQ,MAA0C,OAAO,QAAQ,KAAK;AAC1F;AAEA,SAAS,kBAAkB,MAAc,OAA8C;AACrF,SAAO;AAAA,IACL,UAAU;AAAA,IACV;AAAA,IACA,KAAK;AAAA,IACL,KAAK;AAAA,IACL;AAAA,EACF;AACF;AAEA,SAAS,uBACP,OACA,IACA,OACA,KACA,OACM;AACN,MAAI,MAAM,yBAA0B;AAEpC,QAAM,iBAAiB,gCAAgC,IAAI,GAAG;AAC9D,MAAI;AAEJ,aAAW,KAAK,OAAO;AACrB,UAAM,QAAQ,MAAM,CAAC;AACrB,QACE,MAAM,cACN,MAAM,SACN,MAAM,SACN,MAAM,8BACN,MAAM,oCACL,EAAE,CAAC,MAAM,OAAO,EAAE,CAAC,MAAM,OAAO,OAAO,SAAS,WACjD;AAEF,QAAI,MAAM,2BAA2B;AACnC,UAAI,OAAO,MAAM,OAAO,UAAU;AAClC,UAAI,QAAQ,YAAY,QAAQ,SAAS;AACvC,cAAM,QAAQ,SAAS,cAAc,KAAK;AAC1C,cAAM,YAAY;AAClB,eAAO,MAAM;AAAA,MACf;AACA,UAAK,GAAmB,cAAc,MAAM;AAC1C;AAAA,UACE;AAAA,UACA,OACI,IAAI,MAAM,mCAAmC,GAAG,IAAI,IACpD;AAAA,UACJ;AAAA,QACF;AAAA,MACF;AACA;AAAA,IACF;AAEA,QAAI,MAAM,WAAW,MAAM,gBAAgB;AACzC,UAAI,QAAQ,SAAU;AACtB,UAAI,QAAQ,WAAW,QAAQ,YAAY;AACzC,YAAI,MAAM,WAAW,MAAM,SAAS,MAAM;AACxC,cAAI,SAAS,QAAS,GAAwB,UAAU,KAAK,OAAO;AAClE;AAAA,cACE;AAAA,cACA,OACI,IAAI,MAAM,aAAa,GAAG,uBAAuB,GAAG,IAAI,IACxD;AAAA,cACJ;AAAA,YACF;AAAA,UACF;AAAA,QACF;AACA;AAAA,MACF;AAAA,IACF;AAEA,QAAI,QAAQ,YAAY,MAAM,aAAa,MAAM,mBAAmB;AAClE,UAAI,MAAM,aAAa,MAAM,WAAW,MAAM;AAC5C,YAAI,SAAS,QAAS,GAAwB,YAAY,CAAC,CAAC,OAAO;AACjE;AAAA,YACE;AAAA,YACA,OACI,IAAI,MAAM,wCAAwC,IAClD;AAAA,YACJ;AAAA,UACF;AAAA,QACF;AAAA,MACF;AACA;AAAA,IACF;AAEA,QAAI,QAAQ,YAAY,MAAM,YAAY;AACxC,UAAI,SAAS,QAAS,GAAyB,aAAa,CAAC,CAAC,OAAO;AACnE;AAAA,UACE;AAAA,UACA,OACI,IAAI,MAAM,0CAA0C,IACpD;AAAA,UACJ;AAAA,QACF;AAAA,MACF;AACA;AAAA,IACF;AAEA,QAAI,MAAM,SAAS;AACjB,mBAAa,eAAe,KAAK,KAAK;AACtC,cAAQ,UAAU,GAAG,OAAO,QAAW,KAAK;AAC5C,UACE,CAAC;AAAA,QACE,GAAmB;AAAA,QACnB,SAAyB;AAAA,MAC5B,GACA;AACA;AAAA,UACE;AAAA,UACA,OACI,IAAI,MAAM,gCAAgC,GAAG,IAAI,IACjD;AAAA,UACJ;AAAA,QACF;AAAA,MACF;AACA;AAAA,IACF;AAEA,UAAM,qBAAqB,EAAE,WAAW,OAAO,KAAK,EAAE,WAAW,OAAO;AACxE,UAAM,OAAO,cAAc,GAAG,KAAK;AAEnC,QAAI;AACJ,QAAI,SAAS,QAAS,UAAU,SAAS,CAAC,oBAAqB;AAC7D,sBAAgB;AAAA,IAClB,OAAO;AACL,mBAAa,eAAe,KAAK,KAAK;AACtC,cAAQ,UAAU,GAAG,OAAO,QAAW,KAAK;AAC5C,sBAAgB,SAAS,aAAa,IAAI;AAAA,IAC5C;AACA,UAAM,cAAc,GAAG,aAAa,IAAI;AACxC,QAAI,kBAAkB,aAAa;AACjC;AAAA,QACE;AAAA,QACA,OACI,IAAI;AAAA,UACF,oCAAoC,GAAG,UAAU,IAAI,eACvC,qBAAqB,aAAa,CAAC,cAAc,qBAAqB,WAAW,CAAC;AAAA,QAClG,IACA;AAAA,QACJ;AAAA,MACF;AAAA,IACF;AAAA,EACF;AACF;AAEA,SAAS,qBACP,QACA,UACS;AACT,WAAS,QAAQ,GAAG,QAAQ,SAAS,QAAQ,SAAS;AACpD,UAAM,WAAW,SAAS,KAAK,KAAK;AACpC,QACE,OAAO,iBAAiB,QAAQ,MAAM,SAAS,iBAAiB,QAAQ,KACxE,OAAO,oBAAoB,QAAQ,MAAM,SAAS,oBAAoB,QAAQ,GAC9E;AACA,aAAO;AAAA,IACT;AAAA,EACF;AACA,SAAO;AACT;AAEA,SAAS,qBAAqB,OAA8B;AAC1D,SAAO,SAAS,OAAO,YAAY,KAAK,UAAU,KAAK;AACzD;",
6
6
  "names": []
7
7
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tanstack/redact",
3
- "version": "0.0.18",
3
+ "version": "0.0.19",
4
4
  "description": "React, redacted. A minimal React-API-compatible drop-in replacement.",
5
5
  "type": "module",
6
6
  "main": "./dist/react/index.js",
@@ -207,6 +207,7 @@ const HEAD_KEY_ATTRS: Record<string, ReadonlyArray<string>> = {
207
207
  link: ['rel', 'href', 'sizes', 'type'],
208
208
  meta: ['name', 'property', 'charSet', 'httpEquiv'],
209
209
  script: ['src', 'type'],
210
+ style: ['id', 'media', 'nonce', 'title'],
210
211
  }
211
212
 
212
213
  const DOCUMENT_HEAD_TAGS = new Set(['base', 'link', 'meta', 'script', 'style', 'title'])
@@ -355,13 +356,24 @@ export function adoptHostDom(fiber: Fiber, parent: Fiber): boolean {
355
356
  tag === 'svg' ||
356
357
  ((candidate as Element).namespaceURI === 'http://www.w3.org/2000/svg' &&
357
358
  tag !== 'foreignobject')
359
+ const syncHydrationProps =
360
+ !props.suppressHydrationWarning &&
361
+ canRecoverHydrationPropMismatch(candidate, tag)
358
362
  validateHydrationProps(fiber, candidate as Element, props, tag, isSvg)
359
363
  for (const k in props) {
360
- if (k === 'children') continue
361
- if (k[0] === 'o' && k[1] === 'n' && typeof props[k] == 'function') {
364
+ if (
365
+ k === 'children' ||
366
+ k === 'key' ||
367
+ k === 'ref' ||
368
+ k === 'suppressHydrationWarning' ||
369
+ k === 'suppressContentEditableWarning'
370
+ ) continue
371
+ if (
372
+ syncHydrationProps ||
373
+ (k[0] === 'o' && k[1] === 'n' && typeof props[k] == 'function')
374
+ ) {
362
375
  setProp(candidate as Element, k, props[k], undefined, isSvg)
363
376
  }
364
- // Non-event props: trust the server HTML, skip
365
377
  }
366
378
  // Set up child cursor for this host's children
367
379
  hydrationCursors.set(fiber, new HydrationCursor(candidate))
@@ -372,16 +384,24 @@ export function adoptTextDom(fiber: Fiber, parent: Fiber, text: string): boolean
372
384
  const cursor = hydrationCursors.get(findHostParent(parent))
373
385
  if (!cursor) return false
374
386
  const candidate = cursor.take()
375
- if (!candidate) onMismatch(fiber, null)
387
+ if (!candidate) {
388
+ onMismatch(fiber, null)
389
+ return false
390
+ }
376
391
  if (candidate.nodeType === 3) {
377
392
  if ((candidate as Text).data !== text) {
378
- if (process.env.NODE_ENV !== 'production') {
379
- failHydration(
380
- fiber,
381
- new Error(`Hydration text mismatch: expected "${text}" but found "${(candidate as Text).data}".`),
382
- )
393
+ const recovered = failHydration(
394
+ fiber,
395
+ process.env.NODE_ENV !== 'production'
396
+ ? new Error(
397
+ `Hydration text mismatch: expected "${text}" but found "${(candidate as Text).data}".`,
398
+ )
399
+ : undefined,
400
+ canRecoverHydrationPropMismatch(candidate),
401
+ )
402
+ if (recovered) {
403
+ ;(candidate as Text).data = text
383
404
  }
384
- failHydration(fiber)
385
405
  }
386
406
  fiber.dom = candidate
387
407
  return true
@@ -407,28 +427,41 @@ export function findHostParent(fiber: Fiber): Fiber {
407
427
  throw new Error()
408
428
  }
409
429
 
410
- function onMismatch(fiber: Fiber, actualNode: ChildNode | null): never {
411
- if (process.env.NODE_ENV !== 'production') {
412
- failHydration(
413
- fiber,
414
- new Error(
415
- `Hydration mismatch: expected <${(fiber.type as string) ?? 'text'}> but found ${
416
- actualNode ? (actualNode.nodeType === 1 ? (actualNode as Element).tagName : 'text') : 'nothing'
417
- }.`,
418
- ),
419
- )
420
- }
421
- failHydration(fiber)
430
+ function onMismatch(fiber: Fiber, actualNode: ChildNode | null): void {
431
+ failHydration(
432
+ fiber,
433
+ process.env.NODE_ENV !== 'production'
434
+ ? new Error(
435
+ `Hydration mismatch: expected <${(fiber.type as string) ?? 'text'}> but found ${
436
+ actualNode ? (actualNode.nodeType === 1 ? (actualNode as Element).tagName : 'text') : 'nothing'
437
+ }.`,
438
+ )
439
+ : undefined,
440
+ )
422
441
  }
423
442
 
424
- function failHydration(fiber: Fiber, error: Error = new Error(PROD_HYDRATION_ERROR)): never {
443
+ function failHydration(
444
+ fiber: Fiber,
445
+ error: Error = new Error(PROD_HYDRATION_ERROR),
446
+ recoverInPlace = false,
447
+ ): boolean {
425
448
  const root = findRoot(fiber)
426
449
  if (root?.re) {
427
450
  root.re(error)
428
451
  }
452
+ if (recoverInPlace) return true
429
453
  abortHydration(error, findHostRecoveryParent(fiber) ?? fiber)
430
454
  }
431
455
 
456
+ function canRecoverHydrationPropMismatch(node: Node, tag?: string): boolean {
457
+ return (
458
+ tag === 'html' ||
459
+ tag === 'head' ||
460
+ tag === 'body' ||
461
+ !!node.ownerDocument?.head?.contains(node)
462
+ )
463
+ }
464
+
432
465
  function findHostRecoveryParent(fiber: Fiber): Fiber | null {
433
466
  if (fiber.tag === FiberTag.Text) {
434
467
  let directHost = fiber.parent
@@ -660,6 +693,7 @@ function validateHydrationProps(
660
693
  ): void {
661
694
  if (props.suppressHydrationWarning) return
662
695
 
696
+ const recoverInPlace = canRecoverHydrationPropMismatch(el, tag)
663
697
  let expected: Element | undefined
664
698
 
665
699
  for (const k in props) {
@@ -681,13 +715,13 @@ function validateHydrationProps(
681
715
  html = probe.innerHTML
682
716
  }
683
717
  if ((el as HTMLElement).innerHTML !== html) {
684
- if (process.env.NODE_ENV !== 'production') {
685
- failHydration(
686
- fiber,
687
- new Error(`Hydration HTML mismatch inside <${tag}>.`),
688
- )
689
- }
690
- failHydration(fiber)
718
+ failHydration(
719
+ fiber,
720
+ process.env.NODE_ENV !== 'production'
721
+ ? new Error(`Hydration HTML mismatch inside <${tag}>.`)
722
+ : undefined,
723
+ recoverInPlace,
724
+ )
691
725
  }
692
726
  continue
693
727
  }
@@ -697,10 +731,13 @@ function validateHydrationProps(
697
731
  if (tag === 'input' || tag === 'textarea') {
698
732
  if (k === 'value' || props.value == null) {
699
733
  if (value != null && (el as HTMLInputElement).value !== '' + value) {
700
- if (process.env.NODE_ENV !== 'production') {
701
- failHydration(fiber, new Error(`Hydration ${tag} value mismatch on <${tag}>.`))
702
- }
703
- failHydration(fiber)
734
+ failHydration(
735
+ fiber,
736
+ process.env.NODE_ENV !== 'production'
737
+ ? new Error(`Hydration ${tag} value mismatch on <${tag}>.`)
738
+ : undefined,
739
+ recoverInPlace,
740
+ )
704
741
  }
705
742
  }
706
743
  continue
@@ -710,10 +747,13 @@ function validateHydrationProps(
710
747
  if (tag === 'input' && (k === 'checked' || k === 'defaultChecked')) {
711
748
  if (k === 'checked' || props.checked == null) {
712
749
  if (value != null && (el as HTMLInputElement).checked !== !!value) {
713
- if (process.env.NODE_ENV !== 'production') {
714
- failHydration(fiber, new Error(`Hydration checked mismatch on <input>.`))
715
- }
716
- failHydration(fiber)
750
+ failHydration(
751
+ fiber,
752
+ process.env.NODE_ENV !== 'production'
753
+ ? new Error(`Hydration checked mismatch on <input>.`)
754
+ : undefined,
755
+ recoverInPlace,
756
+ )
717
757
  }
718
758
  }
719
759
  continue
@@ -721,10 +761,13 @@ function validateHydrationProps(
721
761
 
722
762
  if (tag === 'option' && k === 'selected') {
723
763
  if (value != null && (el as HTMLOptionElement).selected !== !!value) {
724
- if (process.env.NODE_ENV !== 'production') {
725
- failHydration(fiber, new Error(`Hydration selected mismatch on <option>.`))
726
- }
727
- failHydration(fiber)
764
+ failHydration(
765
+ fiber,
766
+ process.env.NODE_ENV !== 'production'
767
+ ? new Error(`Hydration selected mismatch on <option>.`)
768
+ : undefined,
769
+ recoverInPlace,
770
+ )
728
771
  }
729
772
  continue
730
773
  }
@@ -732,14 +775,19 @@ function validateHydrationProps(
732
775
  if (k === 'style') {
733
776
  expected ??= createHostNode(tag, isSvg)
734
777
  setProp(expected, k, value, undefined, isSvg)
735
- if ((el as HTMLElement).style.cssText !== (expected as HTMLElement).style.cssText) {
736
- if (process.env.NODE_ENV !== 'production') {
737
- failHydration(
738
- fiber,
739
- new Error(`Hydration style mismatch on <${tag}>.`),
740
- )
741
- }
742
- failHydration(fiber)
778
+ if (
779
+ !hydrationStylesMatch(
780
+ (el as HTMLElement).style,
781
+ (expected as HTMLElement).style,
782
+ )
783
+ ) {
784
+ failHydration(
785
+ fiber,
786
+ process.env.NODE_ENV !== 'production'
787
+ ? new Error(`Hydration style mismatch on <${tag}>.`)
788
+ : undefined,
789
+ recoverInPlace,
790
+ )
743
791
  }
744
792
  continue
745
793
  }
@@ -757,20 +805,36 @@ function validateHydrationProps(
757
805
  }
758
806
  const actualValue = el.getAttribute(attr)
759
807
  if (expectedValue !== actualValue) {
760
- if (process.env.NODE_ENV !== 'production') {
761
- failHydration(
762
- fiber,
763
- new Error(
764
- `Hydration attribute mismatch on <${tag}> for "${attr}": ` +
765
- `expected ${formatHydrationValue(expectedValue)} but found ${formatHydrationValue(actualValue)}.`,
766
- ),
767
- )
768
- }
769
- failHydration(fiber)
808
+ failHydration(
809
+ fiber,
810
+ process.env.NODE_ENV !== 'production'
811
+ ? new Error(
812
+ `Hydration attribute mismatch on <${tag}> for "${attr}": ` +
813
+ `expected ${formatHydrationValue(expectedValue)} but found ${formatHydrationValue(actualValue)}.`,
814
+ )
815
+ : undefined,
816
+ recoverInPlace,
817
+ )
770
818
  }
771
819
  }
772
820
  }
773
821
 
822
+ function hydrationStylesMatch(
823
+ actual: CSSStyleDeclaration,
824
+ expected: CSSStyleDeclaration,
825
+ ): boolean {
826
+ for (let index = 0; index < expected.length; index++) {
827
+ const property = expected.item(index)
828
+ if (
829
+ actual.getPropertyValue(property) !== expected.getPropertyValue(property) ||
830
+ actual.getPropertyPriority(property) !== expected.getPropertyPriority(property)
831
+ ) {
832
+ return false
833
+ }
834
+ }
835
+ return true
836
+ }
837
+
774
838
  function formatHydrationValue(value: string | null): string {
775
839
  return value == null ? 'nothing' : JSON.stringify(value)
776
840
  }