@askrjs/askr 0.0.99 → 0.2.1

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 (63) hide show
  1. package/README.md +3 -2
  2. package/dist/actions/index.d.ts +1 -1
  3. package/dist/actions/index.js +1 -1
  4. package/dist/{activity-d4t3CdzK.js → activity-B2Yy7Wz9.js} +2 -2
  5. package/dist/{activity-D_5x2HXQ.d.ts → activity-DOmzl9Yu.d.ts} +1 -1
  6. package/dist/benchmark.js +7 -7
  7. package/dist/boot/index.d.ts +2 -2
  8. package/dist/boot/index.js +1 -1
  9. package/dist/{boot-DE-JutXH.js → boot-DVwjHCNh.js} +275 -95
  10. package/dist/{cleanup-D7uN-Z1s.js → cleanup-DPtpXtA4.js} +3 -3
  11. package/dist/{component-cleanup-DYG80yhG.js → component-cleanup-DPe8claJ.js} +1 -1
  12. package/dist/{component-internal-D0yE2Ch3.js → component-internal-xW_OnTmC.js} +3 -3
  13. package/dist/components/index.d.ts +1 -1
  14. package/dist/control/index.d.ts +1 -1
  15. package/dist/control/index.js +1 -1
  16. package/dist/{control-C0klPV7Q.js → control-BLVTE1gO.js} +3 -3
  17. package/dist/{csp-nonce-BVybpV1v.js → csp-nonce-CCnMtOW-.js} +1 -1
  18. package/dist/data/index.d.ts +1 -1
  19. package/dist/data/index.js +1 -1
  20. package/dist/{data-CnQwUS76.js → data-CAXqJzoS.js} +2 -2
  21. package/dist/{deferred-BVkZ5T2P.js → deferred-BRw0gbn5.js} +2 -2
  22. package/dist/{effect-BdvdgMvV.js → effect-BQP5o0Kx.js} +1 -1
  23. package/dist/{fastlane-DGo7SxBQ.js → fastlane-DUxiFV9S.js} +1 -1
  24. package/dist/{for-internal-DkBwTG4S.js → for-internal-DKcYl3nl.js} +4 -4
  25. package/dist/foundations/index.d.ts +1 -1
  26. package/dist/foundations/index.js +1 -1
  27. package/dist/foundations/interactions/index.d.ts +8 -1
  28. package/dist/foundations/interactions/index.js +1 -1
  29. package/dist/foundations/state/index.d.ts +1 -1
  30. package/dist/foundations/state/index.js +1 -1
  31. package/dist/foundations/structures/index.d.ts +1 -1
  32. package/dist/foundations/structures/index.js +1 -1
  33. package/dist/fx/index.d.ts +1 -1
  34. package/dist/fx/index.js +12 -11
  35. package/dist/{index-CTIBOqUB.d.ts → index-B1p8bHZE.d.ts} +1 -0
  36. package/dist/{index-S2IqSJib.d.ts → index-zEdpHD86.d.ts} +1 -1
  37. package/dist/index.d.ts +1 -1
  38. package/dist/index.js +8 -8
  39. package/dist/{interactions-B4XaFxt1.js → interactions-B-7vkBgx.js} +3 -2
  40. package/dist/{lifecycle-batch-BH0fax4F.js → lifecycle-batch-BYECQw8T.js} +1 -1
  41. package/dist/{lifecycle-operations-CBzG5PyB.js → lifecycle-operations-DJk_5MrD.js} +1 -1
  42. package/dist/{navigate-eGm4omPj.d.ts → navigate-DUcj-nLs.d.ts} +1 -1
  43. package/dist/{navigate-Cix_Q9ym.js → navigate-DvJvo--6.js} +8 -8
  44. package/dist/{readable-BsdGWsDE.js → readable-D-JIKCg2.js} +2 -0
  45. package/dist/{renderer-tXX_xj86.js → renderer-RjZ8LHbt.js} +120 -12
  46. package/dist/{resolution-ZsIFeQoB.js → resolution-dVYwYXrI.js} +3 -3
  47. package/dist/{resource-operation-B62UQKHV.js → resource-operation-4qFIM02d.js} +3 -3
  48. package/dist/resources/index.d.ts +2 -2
  49. package/dist/resources/index.js +4 -4
  50. package/dist/router/index.d.ts +3 -3
  51. package/dist/router/index.js +6 -6
  52. package/dist/{selector-CyK-sDwB.js → selector-NQiYHwZC.js} +1 -1
  53. package/dist/ssg/index.d.ts +1 -1
  54. package/dist/ssg/index.js +3 -3
  55. package/dist/ssr/index.d.ts +1 -1
  56. package/dist/ssr/index.js +1 -1
  57. package/dist/{ssr-BrdV2jMy.js → ssr-F87AcFMt.js} +6 -6
  58. package/dist/{state-DmkGM_LN.js → state-Ks-sWTQi.js} +2 -2
  59. package/dist/{structures-CPycoyZj.js → structures-C-wmHCi6.js} +3 -3
  60. package/dist/testing/index.d.ts +1 -1
  61. package/dist/testing/index.js +3 -3
  62. package/dist/{verify-hydration-Bo5_tpen.js → verify-hydration-CThsx0pq.js} +1 -1
  63. package/package.json +3 -3
package/README.md CHANGED
@@ -91,8 +91,9 @@ Query and mutation helpers live in `@askrjs/askr/data`.
91
91
  ### Developer error boundaries
92
92
 
93
93
  `ErrorBoundary` is the opt-in boundary primitive for render-time failures. It
94
- renders a visible fallback in development, still logs the underlying error, and
95
- can reset when your app state changes. The boundary protects both initial mount
94
+ renders a visible fallback in every environment (with error details expanded
95
+ by default in development), still logs the underlying error, and can reset via
96
+ a `resetKey` tied to your app state. The boundary protects both initial mount
96
97
  and scheduled post-mount updates. Portal content follows its logical writer
97
98
  boundary and can also recover through a boundary around its host.
98
99
 
@@ -1,2 +1,2 @@
1
- import { a as action, i as ActionValidationError, n as ActionForm, o as defineAction, r as ActionStatus, t as ActionDescriptor } from "../index-CTIBOqUB.js";
1
+ import { a as action, i as ActionValidationError, n as ActionForm, o as defineAction, r as ActionStatus, t as ActionDescriptor } from "../index-B1p8bHZE.js";
2
2
  export { ActionDescriptor, ActionForm, ActionStatus, ActionValidationError, action, defineAction };
@@ -1,6 +1,6 @@
1
1
  import { d as getCurrentAppRenderRuntime } from "../component-scope-4I3yEMkb.js";
2
2
  import { r as getCurrentRenderData } from "../render-context-B7ohlh6t.js";
3
- import { t as state } from "../state-DmkGM_LN.js";
3
+ import { t as state } from "../state-Ks-sWTQi.js";
4
4
  import { jsx, jsxs } from "../jsx-runtime.js";
5
5
  import { c as resolveDataRuntimeState, s as invalidateQueriesForRuntime } from "../data-runtime-7t_Y0iv3.js";
6
6
  //#region src/actions/runtime.ts
@@ -1,6 +1,6 @@
1
1
  import { d as getCurrentAppRenderRuntime, f as getCurrentComponentInstance, i as claimHookIndex } from "./component-scope-4I3yEMkb.js";
2
- import { a as registerCommitOperation } from "./component-internal-D0yE2Ch3.js";
3
- import { l as notifyReadableReaders, o as markReactivePropsDirtySource, s as markReadableDerivedSubscribersDirty, u as recordReadableRead } from "./readable-BsdGWsDE.js";
2
+ import { a as registerCommitOperation } from "./component-internal-xW_OnTmC.js";
3
+ import { l as notifyReadableReaders, o as markReactivePropsDirtySource, s as markReadableDerivedSubscribersDirty, u as recordReadableRead } from "./readable-D-JIKCg2.js";
4
4
  import { n as getActiveRenderContext } from "./render-context-B7ohlh6t.js";
5
5
  import { n as syncRouteActivitySnapshot } from "./route-activity-CNJfpwx-.js";
6
6
  import { b as getActiveRoutes, c as removeRouteBasePath, d as deepFreeze, f as makeQuery, n as computeMatchesFromRoutes, p as parseLocation, y as getActiveRouteBasePath } from "./route-matching-Bo6UqG-5.js";
@@ -1,4 +1,4 @@
1
- import { Ct as RouteParams, Lt as RouteSnapshot } from "./index-CTIBOqUB.js";
1
+ import { Ct as RouteParams, Lt as RouteSnapshot } from "./index-B1p8bHZE.js";
2
2
  //#region src/router/activity.d.ts
3
3
  /** Options for {@link onRouteChange}. */
4
4
  interface RouteChangeOptions {
package/dist/benchmark.js CHANGED
@@ -1,10 +1,10 @@
1
1
  import { r as flushRuntimeScheduler } from "./access-d_DCdwqn.js";
2
- import { t as state } from "./state-DmkGM_LN.js";
3
- import { t as selector } from "./selector-CyK-sDwB.js";
4
- import { t as installRendererBridge } from "./renderer-tXX_xj86.js";
5
- import { i as For } from "./control-C0klPV7Q.js";
2
+ import { t as state } from "./state-Ks-sWTQi.js";
3
+ import { t as selector } from "./selector-NQiYHwZC.js";
4
+ import { t as installRendererBridge } from "./renderer-RjZ8LHbt.js";
5
+ import { i as For } from "./control-BLVTE1gO.js";
6
6
  import { jsx, jsxs } from "./jsx-runtime.js";
7
- import { t as createIsland } from "./boot-DE-JutXH.js";
7
+ import { t as createIsland } from "./boot-DVwjHCNh.js";
8
8
  //#region src/bench/components/benchmark-row.tsx
9
9
  function BenchmarkRow({ item, isSelected, onSelect, onRemove }) {
10
10
  return /* @__PURE__ */ jsxs("tr", {
@@ -63,8 +63,8 @@ function BenchmarkTable({ rows, isSelected, onSelect, onRemove }) {
63
63
  installRendererBridge();
64
64
  const benchmarkMetadata = {
65
65
  packageName: "@askrjs/askr",
66
- packageVersion: "0.0.99",
67
- buildLabel: "0.0.99-local"
66
+ packageVersion: "0.2.1",
67
+ buildLabel: "0.2.1-local"
68
68
  };
69
69
  function getBenchmarkMetadata() {
70
70
  return { ...benchmarkMetadata };
@@ -1,5 +1,5 @@
1
- import { At as RouteRegistry, nn as ComponentFunction, ut as RouteAuthOptions, zt as DataRuntime } from "../index-CTIBOqUB.js";
2
- import { a as ScrollRestorationOptions } from "../navigate-eGm4omPj.js";
1
+ import { At as RouteRegistry, nn as ComponentFunction, ut as RouteAuthOptions, zt as DataRuntime } from "../index-B1p8bHZE.js";
2
+ import { a as ScrollRestorationOptions } from "../navigate-DUcj-nLs.js";
3
3
  //#region src/boot/types.d.ts
4
4
  /** Configuration for {@link createIsland}: mounts one component onto existing DOM. */
5
5
  type IslandConfig = {
@@ -1,2 +1,2 @@
1
- import { a as cleanupApp, i as hydrateSPA, n as createIslands, o as hasApp, r as createSPA, t as createIsland } from "../boot-DE-JutXH.js";
1
+ import { a as cleanupApp, i as hydrateSPA, n as createIslands, o as hasApp, r as createSPA, t as createIsland } from "../boot-DVwjHCNh.js";
2
2
  export { cleanupApp, createIsland, createIslands, createSPA, hasApp, hydrateSPA };
@@ -1,19 +1,19 @@
1
1
  import { S as isProductionEnvironment, r as flushRuntimeScheduler, x as isDevelopmentEnvironment, y as logger } from "./access-d_DCdwqn.js";
2
2
  import { n as Fragment, t as ELEMENT_TYPE } from "./jsx-DRS-qjiN.js";
3
- import { n as createComponentInstance, r as executeComponent } from "./component-internal-D0yE2Ch3.js";
4
- import { t as cleanupComponent } from "./component-cleanup-DYG80yhG.js";
5
- import { p as isPromiseLike } from "./lifecycle-batch-BH0fax4F.js";
6
- import { _ as teardownNodeSubtree, d as removeAllListeners } from "./cleanup-D7uN-Z1s.js";
3
+ import { n as createComponentInstance, r as executeComponent } from "./component-internal-xW_OnTmC.js";
4
+ import { t as cleanupComponent } from "./component-cleanup-DPe8claJ.js";
5
+ import { p as isPromiseLike } from "./lifecycle-batch-BYECQw8T.js";
6
+ import { _ as teardownNodeSubtree, d as removeAllListeners } from "./cleanup-DPtpXtA4.js";
7
7
  import { r as assertExecutionModel, t as _applyManifest } from "./manifest-D6rfj_jC.js";
8
8
  import { d as stopHydrationRenderPhase, l as startHydrationRenderPhase, y as pageRenderEnvelope } from "./render-context-B7ohlh6t.js";
9
- import { a as setStaticChildSlotsCacheEnabled, c as endHydrationDirectListenerMode, d as discardHydrationListenerTransaction, i as registerDeferredHydrationBoundary, l as beginHydrationListenerTransaction, n as activateHydrationBoundary$1, o as withIntrinsicHydrationAdoption, r as clearDeferredHydrationBoundaries, s as beginHydrationDirectListenerMode, t as installRendererBridge, u as commitHydrationListenerTransaction } from "./renderer-tXX_xj86.js";
10
- import { r as validateCspNonce, t as CspNonceScope } from "./csp-nonce-BVybpV1v.js";
9
+ import { a as setStaticChildSlotsCacheEnabled, c as endHydrationDirectListenerMode, d as discardHydrationListenerTransaction, i as registerDeferredHydrationBoundary, l as beginHydrationListenerTransaction, n as activateHydrationBoundary$1, o as withIntrinsicHydrationAdoption, r as clearDeferredHydrationBoundaries, s as beginHydrationDirectListenerMode, t as installRendererBridge, u as commitHydrationListenerTransaction } from "./renderer-RjZ8LHbt.js";
10
+ import { r as validateCspNonce, t as CspNonceScope } from "./csp-nonce-CCnMtOW-.js";
11
11
  import { i as getDefaultDataRuntime } from "./data-runtime-7t_Y0iv3.js";
12
12
  import { a as hydrateDataRuntime } from "./query-registry-Bua3cDyb.js";
13
13
  import { I as lockRouteRegistration, P as hasRegisteredRoutes, _ as clearRouteState, m as _setActiveRouteAuthOptions } from "./route-matching-Bo6UqG-5.js";
14
- import { a as resolveRouteRequest, i as hasRouteRenderData, m as reviveDeferredValue, n as getRouteRenderContext, r as getRouteRenderData } from "./resolution-ZsIFeQoB.js";
15
- import { o as createAppRenderRuntime, r as setServerLocation } from "./activity-d4t3CdzK.js";
16
- import { f as registerAppInstance, g as unregisterAppInstance, i as resolveRouteMeta, o as configureScrollRestoration, r as reconcileRouteMeta, t as initializeNavigation } from "./navigate-Cix_Q9ym.js";
14
+ import { a as resolveRouteRequest, i as hasRouteRenderData, m as reviveDeferredValue, n as getRouteRenderContext, r as getRouteRenderData } from "./resolution-dVYwYXrI.js";
15
+ import { o as createAppRenderRuntime, r as setServerLocation } from "./activity-B2Yy7Wz9.js";
16
+ import { f as registerAppInstance, g as unregisterAppInstance, i as resolveRouteMeta, o as configureScrollRestoration, r as reconcileRouteMeta, t as initializeNavigation } from "./navigate-DvJvo--6.js";
17
17
  import { n as disposeRegisteredDefaultPortalScope, r as getDefaultPortalHost } from "./default-portal-runtime-DvMvWJVp.js";
18
18
  import "./ssr-DSHd_Q9K.js";
19
19
  //#region src/boot/hydration.ts
@@ -108,7 +108,7 @@ function shouldVerifyHydrationMarkup(config) {
108
108
  if (typeof explicit === "boolean") return explicit;
109
109
  return !isProductionEnvironment();
110
110
  }
111
- async function applySelectiveHydration(rootElement, resolved, path, cleanupStrict, hydrateOptions, source, hooks) {
111
+ async function applySelectiveHydration(rootElement, resolved, path, cleanupStrict, hydrateOptions, source, hooks, interactionReplay) {
112
112
  const hasPermanentSkips = (hydrateOptions.skipSelectors?.length ?? 0) > 0;
113
113
  const hasBelowFoldDeferral = !!hydrateOptions.deferBelowFold;
114
114
  const hasSelectiveBoundaries = hasPermanentSkips || hasBelowFoldDeferral;
@@ -126,6 +126,7 @@ async function applySelectiveHydration(rootElement, resolved, path, cleanupStric
126
126
  staticChildSlotsCacheSuspended = true;
127
127
  const foldY = hydrateOptions.foldThreshold ?? window.innerHeight;
128
128
  deferredBoundaries = collectDeferredBelowFoldBoundaries(rootElement, foldY);
129
+ interactionReplay.registerDeferredBoundaries(deferredBoundaries);
129
130
  let selectiveHydrationResourcesReleased = false;
130
131
  let unregisterRootCleanupCallback = () => {};
131
132
  function handleScroll() {
@@ -139,7 +140,9 @@ async function applySelectiveHydration(rootElement, resolved, path, cleanupStric
139
140
  unregisterRootCleanupCallback();
140
141
  window.removeEventListener("scroll", handleScroll);
141
142
  restoreStaticChildSlotsCache();
143
+ interactionReplay.clearDeferredBoundaries();
142
144
  };
145
+ interactionReplay.setOnDeferredBoundariesDrained(releaseSelectiveHydrationResources);
143
146
  unregisterRootCleanupCallback = hooks.registerRootCleanupCallback(rootElement, releaseSelectiveHydrationResources);
144
147
  window.addEventListener("scroll", handleScroll, { passive: true });
145
148
  }
@@ -440,6 +443,175 @@ async function resolveInitialRoute(auth, source) {
440
443
  throw new Error(`[Askr] Route redirect limit exceeded (${MAX_INITIAL_ROUTE_REDIRECTS}).`);
441
444
  }
442
445
  //#endregion
446
+ //#region src/boot/hydration-interaction-replay.ts
447
+ const HYDRATION_INTERACTION_TYPES = [
448
+ "click",
449
+ "dblclick",
450
+ "pointerdown",
451
+ "pointerup",
452
+ "keydown",
453
+ "keyup",
454
+ "input",
455
+ "change",
456
+ "submit"
457
+ ];
458
+ function cloneInteractionEvent(event) {
459
+ const EventConstructor = event.constructor;
460
+ const eventWithDetails = event;
461
+ const init = {
462
+ bubbles: event.bubbles,
463
+ cancelable: event.cancelable,
464
+ composed: event.composed,
465
+ detail: eventWithDetails.detail,
466
+ view: eventWithDetails.view,
467
+ key: eventWithDetails.key,
468
+ code: eventWithDetails.code,
469
+ location: eventWithDetails.location,
470
+ repeat: eventWithDetails.repeat,
471
+ isComposing: eventWithDetails.isComposing,
472
+ ctrlKey: eventWithDetails.ctrlKey,
473
+ shiftKey: eventWithDetails.shiftKey,
474
+ altKey: eventWithDetails.altKey,
475
+ metaKey: eventWithDetails.metaKey,
476
+ button: eventWithDetails.button,
477
+ buttons: eventWithDetails.buttons,
478
+ clientX: eventWithDetails.clientX,
479
+ clientY: eventWithDetails.clientY,
480
+ screenX: eventWithDetails.screenX,
481
+ screenY: eventWithDetails.screenY,
482
+ pointerId: eventWithDetails.pointerId,
483
+ pointerType: eventWithDetails.pointerType,
484
+ isPrimary: eventWithDetails.isPrimary,
485
+ data: eventWithDetails.data,
486
+ inputType: eventWithDetails.inputType
487
+ };
488
+ try {
489
+ return new EventConstructor(event.type, init);
490
+ } catch {
491
+ return new Event(event.type, {
492
+ bubbles: event.bubbles,
493
+ cancelable: event.cancelable,
494
+ composed: event.composed
495
+ });
496
+ }
497
+ }
498
+ /**
499
+ * Capture discrete interactions before hydrated handlers exist, then replay
500
+ * them after the listener transaction commits. Deferred boundaries remain
501
+ * interaction-activatable until they are revealed or the root is cleaned up.
502
+ */
503
+ function beginHydrationInteractionReplay(root, activateBoundary, permanentSkipSelectors = []) {
504
+ const queued = [];
505
+ const deferredBoundaries = /* @__PURE__ */ new Set();
506
+ let active = true;
507
+ let hydratingRoot = true;
508
+ let replaying = false;
509
+ let hadDeferredBoundaries = false;
510
+ let onDeferredBoundariesDrained;
511
+ function isPermanentlySkipped(target) {
512
+ const element = target instanceof Element ? target : target instanceof Node ? target.parentElement : null;
513
+ if (!element) return false;
514
+ return permanentSkipSelectors.some((selector) => {
515
+ try {
516
+ return element.closest(selector) !== null;
517
+ } catch {
518
+ return false;
519
+ }
520
+ });
521
+ }
522
+ function findDeferredBoundary(target) {
523
+ if (!(target instanceof Node)) return;
524
+ for (const boundary of deferredBoundaries) if (boundary.hasAttribute("data-skip-hydrate") && boundary.contains(target)) return boundary;
525
+ }
526
+ function removeCaptureListeners() {
527
+ if (!active) return;
528
+ active = false;
529
+ for (const type of HYDRATION_INTERACTION_TYPES) root.removeEventListener(type, captureInteraction, true);
530
+ }
531
+ function releaseIfFinished() {
532
+ if (!hydratingRoot && deferredBoundaries.size === 0) removeCaptureListeners();
533
+ }
534
+ function notifyIfDeferredBoundariesDrained() {
535
+ if (hadDeferredBoundaries && deferredBoundaries.size === 0) onDeferredBoundariesDrained?.();
536
+ }
537
+ function replayInteraction(interaction) {
538
+ if (!(interaction.target instanceof Node) || !root.contains(interaction.target)) return;
539
+ const boundary = findDeferredBoundary(interaction.target);
540
+ if (boundary) {
541
+ try {
542
+ if (!activateBoundary(boundary)) return;
543
+ } catch {
544
+ return;
545
+ }
546
+ deferredBoundaries.delete(boundary);
547
+ notifyIfDeferredBoundariesDrained();
548
+ }
549
+ replaying = true;
550
+ try {
551
+ interaction.target.dispatchEvent(interaction.event);
552
+ } finally {
553
+ replaying = false;
554
+ }
555
+ releaseIfFinished();
556
+ }
557
+ function captureInteraction(event) {
558
+ if (!active || replaying) return;
559
+ const target = event.target;
560
+ if (!target || isPermanentlySkipped(target)) return;
561
+ const boundary = findDeferredBoundary(target);
562
+ if (!hydratingRoot && !boundary) return;
563
+ event.preventDefault();
564
+ event.stopImmediatePropagation();
565
+ const interaction = {
566
+ target,
567
+ event: cloneInteractionEvent(event)
568
+ };
569
+ if (hydratingRoot) {
570
+ queued.push(interaction);
571
+ return;
572
+ }
573
+ replayInteraction(interaction);
574
+ }
575
+ const installedTypes = [];
576
+ try {
577
+ for (const type of HYDRATION_INTERACTION_TYPES) {
578
+ root.addEventListener(type, captureInteraction, true);
579
+ installedTypes.push(type);
580
+ }
581
+ } catch (error) {
582
+ active = false;
583
+ for (const type of installedTypes) root.removeEventListener(type, captureInteraction, true);
584
+ throw error;
585
+ }
586
+ return {
587
+ registerDeferredBoundaries(boundaries) {
588
+ for (const boundary of boundaries) deferredBoundaries.add(boundary);
589
+ hadDeferredBoundaries ||= boundaries.length > 0;
590
+ },
591
+ setOnDeferredBoundariesDrained(callback) {
592
+ onDeferredBoundariesDrained = callback;
593
+ },
594
+ clearDeferredBoundaries() {
595
+ deferredBoundaries.clear();
596
+ releaseIfFinished();
597
+ },
598
+ complete() {
599
+ if (!active || !hydratingRoot) return;
600
+ hydratingRoot = false;
601
+ const pending = queued.splice(0);
602
+ for (const interaction of pending) replayInteraction(interaction);
603
+ releaseIfFinished();
604
+ },
605
+ abort() {
606
+ queued.length = 0;
607
+ deferredBoundaries.clear();
608
+ onDeferredBoundariesDrained = void 0;
609
+ hydratingRoot = false;
610
+ removeCaptureListeners();
611
+ }
612
+ };
613
+ }
614
+ //#endregion
443
615
  //#region src/boot/index.ts
444
616
  /**
445
617
  * App bootstrap and mount
@@ -570,97 +742,105 @@ async function hydrateSPA(config) {
570
742
  if (manifest.records.length === 0) throw new Error("hydrateSPA requires a route registry with at least one route. If you are enhancing existing HTML, use createIsland instead.");
571
743
  const rootElement = resolveRootElement(config.root);
572
744
  if (!rootElement) throw new Error(`Root element not found: ${config.root}`);
573
- applyDeferredStreamPatches(rootElement);
574
- const hydrationRenderData = takeHydrationRenderData(rootElement);
575
- const hydrationQueryCache = hydrationRenderData?.resources;
576
- if (hydrationQueryCache) hydrateDataRuntime(config.dataRuntime ?? getDefaultDataRuntime(), hydrationQueryCache);
577
- const hydrationRenderDataForApp = hydrationRenderData;
578
- configureScrollRestoration(config.scrollRestoration);
579
- clearRouteState();
580
- _applyManifest(manifest);
581
- const routeAuth = config.auth ?? manifest.auth;
582
- const appRouteSource = {
583
- registry: config.registry,
584
- auth: routeAuth,
585
- runtime: createAppRenderRuntime({
586
- framework: hydrationRenderData?.framework,
587
- route: hydrationRenderData?.route,
588
- hasRoute: hydrationRenderData !== null,
589
- routeRegistry: config.registry,
590
- routeAuth
591
- })
592
- };
593
- _setActiveRouteAuthOptions(routeAuth);
594
- const { path, href: currentUrl, resolved } = await resolveInitialRoute(routeAuth, {
595
- registry: config.registry,
596
- load: false
597
- });
598
- setServerLocation(currentUrl);
599
- if (isProductionEnvironment()) lockRouteRegistration();
600
- if (!resolved) throw new Error(`hydrateSPA: no route found for current path (${path}).`);
601
- if (resolved.kind === "redirect") throw new Error(`hydrateSPA: unresolved redirect for current path (${path}).`);
602
- await reconcileInitialRouteMetadata(resolved);
603
- const hydrationResolved = resolved.kind === "deny" ? {
604
- handler: bindDeniedRouteHandler(resolved.status),
605
- params: {}
606
- } : {
607
- handler: resolved.handler,
608
- params: resolved.params
609
- };
610
- const mountHydratedRoot = (...args) => withIntrinsicHydrationAdoption(() => mountOrUpdate(args[0], args[1], {
611
- ...args[2],
612
- cspNonce: config.cspNonce
613
- }));
614
- if (shouldVerifyHydrationMarkup(config)) {
615
- const { verifyHydrationSyncForUrl } = await import("./verify-hydration-Bo5_tpen.js");
616
- if (!verifyHydrationSyncForUrl({
617
- root: rootElement,
618
- url: currentUrl,
745
+ const interactionReplay = beginHydrationInteractionReplay(rootElement, (boundary) => activateHydrationBoundary(rootElement, boundary), config.hydrate?.skipSelectors);
746
+ try {
747
+ applyDeferredStreamPatches(rootElement);
748
+ const hydrationRenderData = takeHydrationRenderData(rootElement);
749
+ const hydrationQueryCache = hydrationRenderData?.resources;
750
+ if (hydrationQueryCache) hydrateDataRuntime(config.dataRuntime ?? getDefaultDataRuntime(), hydrationQueryCache);
751
+ const hydrationRenderDataForApp = hydrationRenderData;
752
+ configureScrollRestoration(config.scrollRestoration);
753
+ clearRouteState();
754
+ _applyManifest(manifest);
755
+ const routeAuth = config.auth ?? manifest.auth;
756
+ const appRouteSource = {
619
757
  registry: config.registry,
620
- resolved: hydrationResolved,
621
- options: {
622
- data: hydrationRenderDataForApp?.resources,
623
- dataRuntime: config.dataRuntime ?? getDefaultDataRuntime(),
624
- envelope: hydrationRenderDataForApp ?? void 0,
625
- cspNonce: config.cspNonce
626
- }
627
- })) throw new Error("[Askr] Hydration mismatch detected. Server HTML does not match expected server-render output.");
628
- }
629
- const hydrateOptions = config.hydrate;
630
- if (hydrateOptions) {
631
- if (hydrateOptions.deferUntilIdle || hydrateOptions.deferBelowFold) {
632
- if (hydrationRenderDataForApp) startHydrationRenderPhase(hydrationRenderDataForApp);
633
- try {
634
- await applySelectiveHydration(rootElement, hydrationResolved, path, config.cleanupStrict, hydrateOptions, appRouteSource, {
635
- mountOrUpdate: mountHydratedRoot,
636
- registerAppNavigation,
637
- registerRootCleanupCallback,
638
- activateHydrationBoundary
639
- });
640
- } finally {
641
- if (hydrationRenderDataForApp) stopHydrationRenderPhase();
758
+ auth: routeAuth,
759
+ runtime: createAppRenderRuntime({
760
+ framework: hydrationRenderData?.framework,
761
+ route: hydrationRenderData?.route,
762
+ hasRoute: hydrationRenderData !== null,
763
+ routeRegistry: config.registry,
764
+ routeAuth
765
+ })
766
+ };
767
+ _setActiveRouteAuthOptions(routeAuth);
768
+ const { path, href: currentUrl, resolved } = await resolveInitialRoute(routeAuth, {
769
+ registry: config.registry,
770
+ load: false
771
+ });
772
+ setServerLocation(currentUrl);
773
+ if (isProductionEnvironment()) lockRouteRegistration();
774
+ if (!resolved) throw new Error(`hydrateSPA: no route found for current path (${path}).`);
775
+ if (resolved.kind === "redirect") throw new Error(`hydrateSPA: unresolved redirect for current path (${path}).`);
776
+ await reconcileInitialRouteMetadata(resolved);
777
+ const hydrationResolved = resolved.kind === "deny" ? {
778
+ handler: bindDeniedRouteHandler(resolved.status),
779
+ params: {}
780
+ } : {
781
+ handler: resolved.handler,
782
+ params: resolved.params
783
+ };
784
+ const mountHydratedRoot = (...args) => withIntrinsicHydrationAdoption(() => mountOrUpdate(args[0], args[1], {
785
+ ...args[2],
786
+ cspNonce: config.cspNonce
787
+ }));
788
+ if (shouldVerifyHydrationMarkup(config)) {
789
+ const { verifyHydrationSyncForUrl } = await import("./verify-hydration-CThsx0pq.js");
790
+ if (!verifyHydrationSyncForUrl({
791
+ root: rootElement,
792
+ url: currentUrl,
793
+ registry: config.registry,
794
+ resolved: hydrationResolved,
795
+ options: {
796
+ data: hydrationRenderDataForApp?.resources,
797
+ dataRuntime: config.dataRuntime ?? getDefaultDataRuntime(),
798
+ envelope: hydrationRenderDataForApp ?? void 0,
799
+ cspNonce: config.cspNonce
800
+ }
801
+ })) throw new Error("[Askr] Hydration mismatch detected. Server HTML does not match expected server-render output.");
802
+ }
803
+ const hydrateOptions = config.hydrate;
804
+ if (hydrateOptions) {
805
+ if (hydrateOptions.deferUntilIdle || hydrateOptions.deferBelowFold) {
806
+ if (hydrationRenderDataForApp) startHydrationRenderPhase(hydrationRenderDataForApp);
807
+ try {
808
+ await applySelectiveHydration(rootElement, hydrationResolved, path, config.cleanupStrict, hydrateOptions, appRouteSource, {
809
+ mountOrUpdate: mountHydratedRoot,
810
+ registerAppNavigation,
811
+ registerRootCleanupCallback,
812
+ activateHydrationBoundary
813
+ }, interactionReplay);
814
+ } finally {
815
+ if (hydrationRenderDataForApp) stopHydrationRenderPhase();
816
+ }
817
+ interactionReplay.complete();
818
+ return;
642
819
  }
643
- return;
820
+ if (hydrateOptions.skipSelectors?.length) markSkippedElements(rootElement, hydrateOptions.skipSelectors);
644
821
  }
645
- if (hydrateOptions.skipSelectors?.length) markSkippedElements(rootElement, hydrateOptions.skipSelectors);
646
- }
647
- if (hydrationRenderDataForApp) startHydrationRenderPhase(hydrationRenderDataForApp);
648
- const listenerTransaction = beginHydrationListenerTransaction();
649
- beginHydrationDirectListenerMode();
650
- try {
651
- mountHydratedRoot(rootElement, resolved.kind === "deny" ? bindDeniedStatus(resolved.status) : bindResolvedRouteHandler(hydrationResolved), {
652
- cleanupStrict: config.cleanupStrict,
653
- appRuntime: appRouteSource.runtime
654
- });
655
- commitHydrationListenerTransaction(listenerTransaction);
822
+ if (hydrationRenderDataForApp) startHydrationRenderPhase(hydrationRenderDataForApp);
823
+ const listenerTransaction = beginHydrationListenerTransaction();
824
+ beginHydrationDirectListenerMode();
825
+ try {
826
+ mountHydratedRoot(rootElement, resolved.kind === "deny" ? bindDeniedStatus(resolved.status) : bindResolvedRouteHandler(hydrationResolved), {
827
+ cleanupStrict: config.cleanupStrict,
828
+ appRuntime: appRouteSource.runtime
829
+ });
830
+ commitHydrationListenerTransaction(listenerTransaction);
831
+ interactionReplay.complete();
832
+ } catch (error) {
833
+ discardHydrationListenerTransaction(listenerTransaction);
834
+ throw error;
835
+ } finally {
836
+ endHydrationDirectListenerMode();
837
+ if (hydrationRenderDataForApp) stopHydrationRenderPhase();
838
+ }
839
+ await registerAppNavigation(rootElement, path, { ...appRouteSource });
656
840
  } catch (error) {
657
- discardHydrationListenerTransaction(listenerTransaction);
841
+ interactionReplay.abort();
658
842
  throw error;
659
- } finally {
660
- endHydrationDirectListenerMode();
661
- if (hydrationRenderDataForApp) stopHydrationRenderPhase();
662
843
  }
663
- await registerAppNavigation(rootElement, path, { ...appRouteSource });
664
844
  }
665
845
  //#endregion
666
846
  export { cleanupApp as a, hydrateSPA as i, createIslands as n, hasApp as o, createSPA as r, createIsland as t };
@@ -1,8 +1,8 @@
1
1
  import { l as runRuntimeHandlerScope, y as logger } from "./access-d_DCdwqn.js";
2
- import "./fastlane-DGo7SxBQ.js";
2
+ import "./fastlane-DUxiFV9S.js";
3
3
  import { T as withAppRenderRuntime, d as getCurrentAppRenderRuntime } from "./component-scope-4I3yEMkb.js";
4
- import { t as cleanupComponent } from "./component-cleanup-DYG80yhG.js";
5
- import { u as registerLifecycleTransaction } from "./lifecycle-batch-BH0fax4F.js";
4
+ import { t as cleanupComponent } from "./component-cleanup-DPe8claJ.js";
5
+ import { u as registerLifecycleTransaction } from "./lifecycle-batch-BYECQw8T.js";
6
6
  //#region src/runtime/events.ts
7
7
  /**
8
8
  * Event delegation system for Askr
@@ -1,6 +1,6 @@
1
1
  import { S as isProductionEnvironment, x as isDevelopmentEnvironment, y as logger } from "./access-d_DCdwqn.js";
2
2
  import { a as clearCurrentComponentScope, y as restoreCurrentComponentScope } from "./component-scope-4I3yEMkb.js";
3
- import { n as cleanupReadableSubscriptions, t as cleanupReadableSubscriptionSources } from "./readable-BsdGWsDE.js";
3
+ import { n as cleanupReadableSubscriptions, t as cleanupReadableSubscriptionSources } from "./readable-D-JIKCg2.js";
4
4
  //#region src/runtime/state-diagnostics.ts
5
5
  /**
6
6
  * Report state cells that were never read during a component's completed
@@ -1,10 +1,10 @@
1
1
  import { a as markTransparentComponentResult, i as markEagerControlPrimitive } from "./control-C-ApnFs1.js";
2
2
  import { S as isProductionEnvironment, n as enqueueRuntimeTask, o as getRuntimeRenderer, x as isDevelopmentEnvironment, y as logger } from "./access-d_DCdwqn.js";
3
- import { i as tryRuntimeFastLaneSync, n as isBulkCommitActive } from "./fastlane-DGo7SxBQ.js";
3
+ import { i as tryRuntimeFastLaneSync, n as isBulkCommitActive } from "./fastlane-DUxiFV9S.js";
4
4
  import { C as restoreRenderScopedComponent, S as restoreInlineRenderTracking, _ as getSignalForInstance, b as restoreDomCommitScope, c as enterDomCommitScope, f as getCurrentComponentInstance, l as enterRenderScopedComponent, m as getCurrentPortalScope, n as captureInlineComponentScope, o as clearRenderTracking, p as getCurrentInstance, r as captureInlineRenderTracking, s as enterComponentExecutionScope, t as beginRenderTracking, u as exitComponentExecutionScope, v as resetRenderState, x as restoreInlineComponentScope } from "./component-scope-4I3yEMkb.js";
5
5
  import { r as STATIC_CHILDREN, t as ELEMENT_TYPE } from "./jsx-DRS-qjiN.js";
6
- import { i as finalizeReadableSubscriptions } from "./readable-BsdGWsDE.js";
7
- import { a as enqueueLifecycleCommitForInstance, d as discardCommitOperations, f as executeCommittedLifecycleOperations, n as captureInlineRenderSnapshot$1, o as finalizeInlineReadSubscriptions, p as isPromiseLike, r as discardLifecycleCommitBatch, s as flushLifecycleCommitBatch, t as beginLifecycleCommitBatch } from "./lifecycle-batch-BH0fax4F.js";
6
+ import { i as finalizeReadableSubscriptions } from "./readable-D-JIKCg2.js";
7
+ import { a as enqueueLifecycleCommitForInstance, d as discardCommitOperations, f as executeCommittedLifecycleOperations, n as captureInlineRenderSnapshot$1, o as finalizeInlineReadSubscriptions, p as isPromiseLike, r as discardLifecycleCommitBatch, s as flushLifecycleCommitBatch, t as beginLifecycleCommitBatch } from "./lifecycle-batch-BYECQw8T.js";
8
8
  //#region src/runtime/context.ts
9
9
  const TransparentContextScopeComponent = markTransparentComponentResult(ContextScopeComponent);
10
10
  let nextScopeIdentityKey = 0;
@@ -1,4 +1,4 @@
1
- import { in as VNode } from "../index-CTIBOqUB.js";
1
+ import { in as VNode } from "../index-B1p8bHZE.js";
2
2
  import { r as JSXElement, s as Props } from "../types-DkVJhVs9.js";
3
3
  //#region src/common/error-boundary.d.ts
4
4
  type ErrorBoundaryContent = VNode | readonly VNode[];
@@ -1,2 +1,2 @@
1
- import { A as Case, F as ShowProps, I as For, L as ForProps, M as Match, N as MatchProps, P as Show, j as CaseProps } from "../index-CTIBOqUB.js";
1
+ import { A as Case, F as ShowProps, I as For, L as ForProps, M as Match, N as MatchProps, P as Show, j as CaseProps } from "../index-B1p8bHZE.js";
2
2
  export { Case, type CaseProps, For, type ForProps, Match, type MatchProps, Show, type ShowProps };
@@ -1,2 +1,2 @@
1
- import { i as For, n as Match, r as Show, t as Case } from "../control-C0klPV7Q.js";
1
+ import { i as For, n as Match, r as Show, t as Case } from "../control-BLVTE1gO.js";
2
2
  export { Case, For, Match, Show };
@@ -1,9 +1,9 @@
1
1
  import { i as markEagerControlPrimitive, t as __CONTROL_BOUNDARY__ } from "./control-C-ApnFs1.js";
2
2
  import { x as isDevelopmentEnvironment } from "./access-d_DCdwqn.js";
3
3
  import { n as Fragment } from "./jsx-DRS-qjiN.js";
4
- import { m as createShowState, p as createCaseState, s as useForState } from "./for-internal-DkBwTG4S.js";
5
- import { t as createFineGrainedEffect } from "./effect-BdvdgMvV.js";
6
- import { t as state } from "./state-DmkGM_LN.js";
4
+ import { m as createShowState, p as createCaseState, s as useForState } from "./for-internal-DKcYl3nl.js";
5
+ import { t as createFineGrainedEffect } from "./effect-BQP5o0Kx.js";
6
+ import { t as state } from "./state-Ks-sWTQi.js";
7
7
  //#region src/control/shared.ts
8
8
  function normalizeBoundaryChild(value) {
9
9
  if (Array.isArray(value)) {
@@ -1,4 +1,4 @@
1
- import { p as defineScope, y as readScope } from "./component-internal-D0yE2Ch3.js";
1
+ import { p as defineScope, y as readScope } from "./component-internal-xW_OnTmC.js";
2
2
  //#region src/common/url.ts
3
3
  const SAFE_URL_SCHEMES = /* @__PURE__ */ new Set([
4
4
  "http",
@@ -1,2 +1,2 @@
1
- import { Bt as DataRuntimeOptions, Gt as Query, Ht as InvalidateOptions, Jt as QueryKeyPart, Kt as QueryConsistency, Qt as ServerQueryHandler, S as createMutation, Ut as Mutation, Vt as InvalidateOnIntervalOptions, Wt as MutationOptions, Xt as QueryScope, Yt as QueryPrefetchContext, Zt as QueryStaleReason, _ as invalidateOnInterval, b as getDefaultDataRuntime, c as ServerQueryRegistry, d as defineServerQueries, f as dehydrateDataRuntime, g as invalidate, h as serveQuery, l as createQueryPrefetchContext, m as prefetchQuery, p as hydrateDataRuntime, qt as QueryDefinition, s as ServerQueryEntry, u as defineQuery, v as queryScope, x as createQuery, y as createDataRuntime, zt as DataRuntime } from "../index-CTIBOqUB.js";
1
+ import { Bt as DataRuntimeOptions, Gt as Query, Ht as InvalidateOptions, Jt as QueryKeyPart, Kt as QueryConsistency, Qt as ServerQueryHandler, S as createMutation, Ut as Mutation, Vt as InvalidateOnIntervalOptions, Wt as MutationOptions, Xt as QueryScope, Yt as QueryPrefetchContext, Zt as QueryStaleReason, _ as invalidateOnInterval, b as getDefaultDataRuntime, c as ServerQueryRegistry, d as defineServerQueries, f as dehydrateDataRuntime, g as invalidate, h as serveQuery, l as createQueryPrefetchContext, m as prefetchQuery, p as hydrateDataRuntime, qt as QueryDefinition, s as ServerQueryEntry, u as defineQuery, v as queryScope, x as createQuery, y as createDataRuntime, zt as DataRuntime } from "../index-B1p8bHZE.js";
2
2
  export { type DataRuntime, type DataRuntimeOptions, type InvalidateOnIntervalOptions, type InvalidateOptions, type Mutation, type MutationOptions, type Query, type QueryConsistency, type QueryDefinition, type QueryKeyPart, type QueryPrefetchContext, type QueryScope, type QueryStaleReason, type ServerQueryEntry, type ServerQueryHandler, type ServerQueryRegistry, createDataRuntime, createMutation, createQuery, createQueryPrefetchContext, defineQuery, defineServerQueries, dehydrateDataRuntime, getDefaultDataRuntime, hydrateDataRuntime, invalidate, invalidateOnInterval, prefetchQuery, queryScope, serveQuery };
@@ -1,4 +1,4 @@
1
1
  import { i as getDefaultDataRuntime, t as createDataRuntime } from "../data-runtime-7t_Y0iv3.js";
2
- import { c as queryScope, n as createMutation, o as invalidate, s as invalidateOnInterval, t as createQuery } from "../data-CnQwUS76.js";
2
+ import { c as queryScope, n as createMutation, o as invalidate, s as invalidateOnInterval, t as createQuery } from "../data-CAXqJzoS.js";
3
3
  import { a as hydrateDataRuntime, i as dehydrateDataRuntime, n as defineQuery, o as prefetchQuery, r as defineServerQueries, s as serveQuery, t as createQueryPrefetchContext } from "../query-registry-Bua3cDyb.js";
4
4
  export { createDataRuntime, createMutation, createQuery, createQueryPrefetchContext, defineQuery, defineServerQueries, dehydrateDataRuntime, getDefaultDataRuntime, hydrateDataRuntime, invalidate, invalidateOnInterval, prefetchQuery, queryScope, serveQuery };
@@ -1,8 +1,8 @@
1
1
  import { n as enqueueRuntimeTask, y as logger } from "./access-d_DCdwqn.js";
2
2
  import { d as getCurrentAppRenderRuntime, f as getCurrentComponentInstance, i as claimHookIndex } from "./component-scope-4I3yEMkb.js";
3
- import { l as notifyReadableReaders, o as markReactivePropsDirtySource, s as markReadableDerivedSubscribersDirty, u as recordReadableRead } from "./readable-BsdGWsDE.js";
3
+ import { l as notifyReadableReaders, o as markReactivePropsDirtySource, s as markReadableDerivedSubscribersDirty, u as recordReadableRead } from "./readable-D-JIKCg2.js";
4
4
  import { n as getActiveRenderContext } from "./render-context-B7ohlh6t.js";
5
- import { i as routeActive, n as documentVisible, o as timer, s as windowFocused } from "./lifecycle-operations-CBzG5PyB.js";
5
+ import { i as routeActive, n as documentVisible, o as timer, s as windowFocused } from "./lifecycle-operations-DJk_5MrD.js";
6
6
  import { a as getMutationSlotStore, c as resolveDataRuntimeState, i as getDefaultDataRuntime, n as ensureMutationCleanup, o as getQuerySlotStore, r as ensureQueryCleanup, s as invalidateQueriesForRuntime } from "./data-runtime-7t_Y0iv3.js";
7
7
  //#region src/data/query-key.ts
8
8
  function serializeQueryKeyNumber(part) {
@@ -1,9 +1,9 @@
1
1
  import { d as getCurrentAppRenderRuntime, f as getCurrentComponentInstance } from "./component-scope-4I3yEMkb.js";
2
2
  import { i as getExecutionModel } from "./manifest-D6rfj_jC.js";
3
3
  import { n as getActiveRenderContext, r as getCurrentRenderData } from "./render-context-B7ohlh6t.js";
4
- import { t as resource } from "./resource-operation-B62UQKHV.js";
4
+ import { t as resource } from "./resource-operation-4qFIM02d.js";
5
5
  import { A as getDefaultRouteBasePath, C as getCurrentInheritedPolicies, D as getCurrentPathPrefix, E as getCurrentPageScope, F as insertRecordSorted, H as computeRank, L as pushRegistrationScope, N as hasActivePageScope, O as getCurrentScopeKind, S as getCurrentInheritedMeta, T as getCurrentPageChain, U as normalizeRouteSegmentName, W as parseSegments, g as assertRouteRegistrationUnlocked, h as addRouteToStores, w as getCurrentLayoutChain, x as getCurrentInheritedAuthRequirements } from "./route-matching-Bo6UqG-5.js";
6
- import { _ as createRouteHandler, d as DEFERRED_BOUNDARY, p as isDeferred, s as guardHydratedRouteData } from "./resolution-ZsIFeQoB.js";
6
+ import { _ as createRouteHandler, d as DEFERRED_BOUNDARY, p as isDeferred, s as guardHydratedRouteData } from "./resolution-dVYwYXrI.js";
7
7
  import { allOf } from "@askrjs/auth";
8
8
  //#region src/router/access.ts
9
9
  function compileNodePolicies(node) {