@askrjs/askr 0.2.4 → 0.3.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 (117) hide show
  1. package/CHANGELOG.md +30 -0
  2. package/dist/access-CEA2pOry.js +1046 -0
  3. package/dist/actions/index.d.ts +16 -2
  4. package/dist/actions/index.js +5 -5
  5. package/dist/{activity-FirwPXA_.js → activity-oy2YFTFF.js} +10 -16
  6. package/dist/benchmark.js +8 -9
  7. package/dist/boot/index.d.ts +19 -9
  8. package/dist/boot/index.js +1 -1
  9. package/dist/{boot-tWyF6121.js → boot-DLplW9h4.js} +700 -441
  10. package/dist/capabilities-Bbf0mlp9.js +42 -0
  11. package/dist/components/index.d.ts +11 -8
  12. package/dist/components/index.js +1 -1
  13. package/dist/{compose-ref-Bfaf4kUC.js → compose-ref-v0qGlHoN.js} +7 -1
  14. package/dist/control/index.d.ts +20 -2
  15. package/dist/control/index.js +1 -1
  16. package/dist/{control-C-wSaq9V.js → control-BR_mrX__.js} +4 -4
  17. package/dist/core.d.ts +163 -0
  18. package/dist/csp-nonce-BfFWcd0w.js +173 -0
  19. package/dist/data/index.d.ts +74 -2
  20. package/dist/data/index.js +3 -3
  21. package/dist/{data-ghKopAbp.js → data-2edW0jhF.js} +108 -122
  22. package/dist/{data-runtime-7t_Y0iv3.js → data-runtime-CxoY98lX.js} +22 -15
  23. package/dist/{deferred-CxjWCkIn.js → deferred-CbgNhf67.js} +5 -5
  24. package/dist/dom-renderer.d.ts +77 -0
  25. package/dist/domains/actions.d.ts +70 -0
  26. package/dist/domains/component.d.ts +119 -0
  27. package/dist/domains/context.d.ts +73 -0
  28. package/dist/domains/control.d.ts +328 -0
  29. package/dist/domains/data.d.ts +461 -0
  30. package/dist/domains/diagnostics.d.ts +21 -0
  31. package/dist/domains/lifecycle.d.ts +112 -0
  32. package/dist/domains/refs.d.ts +18 -0
  33. package/dist/domains/renderer.d.ts +127 -0
  34. package/dist/domains/routing.d.ts +501 -0
  35. package/dist/domains/scheduler.d.ts +79 -0
  36. package/dist/domains/server.d.ts +112 -0
  37. package/dist/domains/state.d.ts +129 -0
  38. package/dist/domains/telemetry.d.ts +29 -0
  39. package/dist/eager-control.d.ts +8 -0
  40. package/dist/{effect-CNwstBBD.js → effect-C3Zsc1k6.js} +14 -41
  41. package/dist/{types-DWVrKn9N.d.ts → elements.d.ts} +79 -42
  42. package/dist/{for-internal-DyBHfKJA.js → for-state-BDykeOJL.js} +598 -494
  43. package/dist/foundations/icon/index.d.ts +67 -16
  44. package/dist/foundations/icon/index.js +1 -1
  45. package/dist/foundations/index.d.ts +26 -3
  46. package/dist/foundations/index.js +1 -1
  47. package/dist/foundations/interactions/index.d.ts +73 -34
  48. package/dist/foundations/interactions/index.js +1 -1
  49. package/dist/foundations/state/index.d.ts +12 -5
  50. package/dist/foundations/state/index.js +1 -1
  51. package/dist/foundations/structures/index.d.ts +44 -3
  52. package/dist/foundations/structures/index.js +1 -1
  53. package/dist/foundations/utilities/index.d.ts +34 -3
  54. package/dist/foundations/utilities/index.js +1 -1
  55. package/dist/fx/index.d.ts +72 -25
  56. package/dist/fx/index.js +8 -8
  57. package/dist/index.d.ts +121 -4
  58. package/dist/index.js +316 -47
  59. package/dist/{component-internal-C4hKKQBF.js → instance-VAFYVJOa.js} +495 -283
  60. package/dist/{interactions-D102JxBR.js → interactions-CTeACdT_.js} +1 -1
  61. package/dist/jsx-dev-runtime.d.ts +51 -11
  62. package/dist/jsx-globals.d.ts +2 -0
  63. package/dist/jsx-runtime-CPJXAOBF.js +43 -0
  64. package/dist/jsx-runtime.d.ts +17 -3
  65. package/dist/jsx-runtime.js +2 -42
  66. package/dist/jsx.d.ts +108 -0
  67. package/dist/{manifest-D6rfj_jC.js → manifest-D1P3UNWV.js} +4 -9
  68. package/dist/{navigate-ZZu1IV0B.js → navigate-prC5V8XV.js} +125 -472
  69. package/dist/{navigate-F4sHgWbw.d.ts → navigation.d.ts} +8 -8
  70. package/dist/{readable-Di1fzSwm.js → notify-DxxuDPeY.js} +96 -34
  71. package/dist/{query-registry-Bua3cDyb.js → query-registry-LrYpQsDJ.js} +1 -1
  72. package/dist/{compose-ref-DOJHoW5X.d.ts → refs.d.ts} +11 -7
  73. package/dist/{ssr-Doog-AfJ.js → render-resolved-BC0W7_5b.js} +165 -558
  74. package/dist/{renderer-Cl23O0hV.js → renderer-CT0HeY58.js} +6825 -5692
  75. package/dist/{resolution-ClD-K7Lz.js → resolution-3DskUkjG.js} +189 -180
  76. package/dist/{resource-operation-Vz1S5h2k.js → resource-18-sFRl9.js} +98 -58
  77. package/dist/resources/index.d.ts +64 -12
  78. package/dist/resources/index.js +214 -8
  79. package/dist/route-activity.d.ts +21 -0
  80. package/dist/{route-matching-Bo6UqG-5.js → route-matching-CUzZ31gT.js} +68 -82
  81. package/dist/router/index.d.ts +378 -79
  82. package/dist/router/index.js +9 -9
  83. package/dist/router-internal-7nuNEHfG.js +36 -0
  84. package/dist/scope-Cq_iYbTR.js +403 -0
  85. package/dist/{selector-CsKuomw0.js → selector-BSPVkjKP.js} +26 -27
  86. package/dist/{shared-CYBH3F8I.js → shared-kU8yvryp.js} +3 -6
  87. package/dist/{snapshot-source-BB42xgwb.js → snapshot-source-An4iKajG.js} +1 -1
  88. package/dist/ssg/index.d.ts +51 -15
  89. package/dist/ssg/index.js +269 -209
  90. package/dist/ssr/index.d.ts +121 -68
  91. package/dist/ssr/index.js +2 -1
  92. package/dist/ssr-CiNm6Vzl.js +393 -0
  93. package/dist/{ssr-DSHd_Q9K.js → ssr-EPjwJH5R.js} +5 -1
  94. package/dist/{state-BGJgYSyQ.js → state-BXJfudq1.js} +10 -15
  95. package/dist/{structures-DFyK5AdQ.js → structures-CjEzfj4h.js} +37 -57
  96. package/dist/{index-CTpMmzgN.d.ts → structures.d.ts} +57 -36
  97. package/dist/testing/index.d.ts +123 -24
  98. package/dist/testing/index.js +24 -61
  99. package/dist/timer-C7uqnJVt.js +85 -0
  100. package/dist/{index-B1gu0_m0.d.ts → utilities.d.ts} +24 -13
  101. package/dist/{verify-hydration-BZPJ_kYa.js → verify-hydration-ikaxotf7.js} +8 -5
  102. package/package.json +12 -14
  103. package/dist/access-BucjYZcX.js +0 -509
  104. package/dist/activity-DooIuxQO.d.ts +0 -14
  105. package/dist/benchmark.d.ts +0 -26
  106. package/dist/cleanup-TXSsApEl.js +0 -535
  107. package/dist/component-cleanup-jdbgjkT1.js +0 -143
  108. package/dist/component-scope-4I3yEMkb.js +0 -195
  109. package/dist/control-Cxag1yqV.d.ts +0 -8
  110. package/dist/csp-nonce-9NFUb7hJ.js +0 -72
  111. package/dist/css-BuPaTOfe.js +0 -70
  112. package/dist/fastlane-BKZduiBQ.js +0 -166
  113. package/dist/index-Dgjbo2gU.d.ts +0 -1456
  114. package/dist/jsx-runtime-Cg7GqY1S.d.ts +0 -2
  115. package/dist/jsx-runtime-gVIaTPw0.d.ts +0 -38
  116. package/dist/lifecycle-batch-63aXFf2S.js +0 -253
  117. package/dist/lifecycle-operations-Q0k3EFnG.js +0 -287
@@ -1,15 +1,19 @@
1
- import { S as isProductionEnvironment, r as flushRuntimeScheduler, s as isRuntimeSchedulerExecuting, x as isDevelopmentEnvironment, y as logger } from "./access-BucjYZcX.js";
2
- import { n as Fragment, t as ELEMENT_TYPE } from "./jsx-DRS-qjiN.js";
3
- import { r as executeComponent } from "./component-internal-C4hKKQBF.js";
4
- import { t as cleanupReadableSubscriptionSources } from "./readable-Di1fzSwm.js";
5
- import { n as cleanupComponentGeneration, t as cleanupComponent } from "./component-cleanup-jdbgjkT1.js";
6
- import { i as drainLifecycleCommitErrors, p as isPromiseLike, r as discardLifecycleCommitBatch, s as flushLifecycleCommitBatch, t as beginLifecycleCommitBatch } from "./lifecycle-batch-63aXFf2S.js";
7
- import { _ as teardownNodeSubtree } from "./cleanup-TXSsApEl.js";
8
- import { t as CspNonceScope } from "./csp-nonce-9NFUb7hJ.js";
9
- import { I as lockRouteRegistration, o as addRouteBasePath, r as computeRouteActivityMatches, y as getActiveRouteBasePath } from "./route-matching-Bo6UqG-5.js";
10
- import { a as resolveRouteRequest, i as hasRouteRenderData, n as getRouteRenderContext, r as getRouteRenderData, u as withoutRouteHydrationMetadata } from "./resolution-ClD-K7Lz.js";
11
- import { a as clearStagedAppRenderRouteLocation, i as syncCurrentRouteSnapshot, o as createAppRenderRuntime, s as stageAppRenderRouteLocation } from "./activity-FirwPXA_.js";
12
- import { r as getDefaultPortalHost, t as clearRegisteredDefaultPortalForInstance } from "./default-portal-runtime-DvMvWJVp.js";
1
+ import { T as isProductionEnvironment, r as flushRuntimeScheduler, u as isRuntimeSchedulerExecuting, v as logger, w as isDevelopmentEnvironment } from "./access-CEA2pOry.js";
2
+ import { P as isPromiseLike } from "./instance-VAFYVJOa.js";
3
+ import { i as commitTransaction, l as registerCommitParticipant, o as discardTransaction, r as beginCommitTransaction } from "./notify-DxxuDPeY.js";
4
+ import { i as syncCurrentRouteSnapshot } from "./activity-oy2YFTFF.js";
5
+ import { a as resolveRouteRequest, i as hasRouteRenderData, n as getRouteRenderContext, r as getRouteRenderData } from "./resolution-3DskUkjG.js";
6
+ import { L as lockRouteRegistration, b as getActiveRouteBasePath, o as addRouteBasePath, r as computeRouteActivityMatches } from "./route-matching-CUzZ31gT.js";
7
+ //#region src/common/root-update.ts
8
+ let rootUpdateHost;
9
+ function configureRootUpdateHost(host) {
10
+ rootUpdateHost = host;
11
+ }
12
+ function prepareRootUpdate(root, input) {
13
+ if (!rootUpdateHost) throw new Error("[Askr] Root update host is not configured.");
14
+ return rootUpdateHost.prepare(root, input);
15
+ }
16
+ //#endregion
13
17
  //#region src/router/navigation-registry.ts
14
18
  let currentInstance = null;
15
19
  let currentPathname = "/";
@@ -422,6 +426,11 @@ function beginRouteRequest() {
422
426
  function isStaleRouteRequest(requestId) {
423
427
  return requestId !== activeRouteRequestId;
424
428
  }
429
+ /**
430
+ * @internal Teardown-only cancellation. Prefer aborting through the signal
431
+ * returned by `beginRouteRequest()`; this exists for registry teardown, where
432
+ * no request owns the abort.
433
+ */
425
434
  function cancelRouteRequests() {
426
435
  activeRouteRequestId += 1;
427
436
  activeRouteRequestController?.abort();
@@ -479,29 +488,6 @@ function createDeniedResolvedRoute(status) {
479
488
  function bindResolvedRouteHandler(resolved) {
480
489
  return () => resolved.handler(resolved.params);
481
490
  }
482
- function wrapRootRouteHandler(componentFn, cspNonce) {
483
- const wrappedFn = (props, ctx) => {
484
- const out = componentFn(props, ctx);
485
- if (isPromiseLike(out)) throw new Error("Async components are not supported. Components must return synchronously.");
486
- const portalVNode = {
487
- $$typeof: ELEMENT_TYPE,
488
- type: getDefaultPortalHost(),
489
- props: { __askrAutoDefaultPortal: true },
490
- key: "__default_portal"
491
- };
492
- const root = {
493
- $$typeof: ELEMENT_TYPE,
494
- type: Fragment,
495
- props: { children: out === void 0 || out === null ? [portalVNode] : [out, portalVNode] }
496
- };
497
- return cspNonce === void 0 ? root : CspNonceScope({
498
- value: cspNonce,
499
- children: root
500
- });
501
- };
502
- Object.defineProperty(wrappedFn, "name", { value: componentFn.name || "Component" });
503
- return wrappedFn;
504
- }
505
491
  function flattenLifecycleErrors(error, result) {
506
492
  if (error instanceof AggregateError) {
507
493
  for (const nested of error.errors) flattenLifecycleErrors(nested, result);
@@ -516,255 +502,6 @@ function reportRouteCleanupErrors(errors) {
516
502
  for (const cleanupError of flattened.length > 0 ? flattened : [error]) logger.error("[Askr] route cleanup failed:", cleanupError);
517
503
  }
518
504
  }
519
- function captureRouteDom(root) {
520
- if (!root) return null;
521
- const nodes = [];
522
- const visit = (node) => {
523
- nodes.push({
524
- node,
525
- children: Array.from(node.childNodes),
526
- attributes: node instanceof Element ? Array.from(node.attributes).map((attribute) => [attribute.name, attribute.value]) : null,
527
- nodeValue: node.nodeValue
528
- });
529
- for (const child of Array.from(node.childNodes)) visit(child);
530
- };
531
- visit(root);
532
- return {
533
- root,
534
- nodes
535
- };
536
- }
537
- function collectProvisionalRouteNodes(snapshot) {
538
- const originalNodes = new Set(snapshot.nodes.map((entry) => entry.node));
539
- const provisional = [];
540
- const visit = (node) => {
541
- if (!originalNodes.has(node)) {
542
- provisional.push(node);
543
- return;
544
- }
545
- for (const child of Array.from(node.childNodes)) visit(child);
546
- };
547
- for (const child of Array.from(snapshot.root.childNodes)) visit(child);
548
- return provisional;
549
- }
550
- function restoreRouteDom(snapshot) {
551
- if (!snapshot) return [];
552
- const errors = [];
553
- for (const node of collectProvisionalRouteNodes(snapshot)) try {
554
- teardownNodeSubtree(node, { strict: true });
555
- } catch (error) {
556
- errors.push(error);
557
- }
558
- for (const entry of snapshot.nodes) {
559
- const { node, attributes } = entry;
560
- try {
561
- if (attributes && node instanceof Element) {
562
- const expected = new Map(attributes);
563
- for (const attribute of Array.from(node.attributes)) if (!expected.has(attribute.name)) node.removeAttribute(attribute.name);
564
- for (const [name, value] of attributes) if (node.getAttribute(name) !== value) node.setAttribute(name, value);
565
- } else if (!(node instanceof Element)) node.nodeValue = entry.nodeValue;
566
- if (node instanceof Element || node instanceof DocumentFragment) node.replaceChildren(...entry.children);
567
- } catch (error) {
568
- errors.push(error);
569
- }
570
- }
571
- return errors;
572
- }
573
- function collectHostInstances(root) {
574
- const instances = [];
575
- const seen = /* @__PURE__ */ new Set();
576
- const pending = [root];
577
- while (pending.length > 0) {
578
- const node = pending.pop();
579
- const host = node;
580
- for (const instance of host.__ASKR_INSTANCES ?? []) if (!seen.has(instance)) {
581
- seen.add(instance);
582
- instances.push(instance);
583
- }
584
- if (host.__ASKR_INSTANCE && !seen.has(host.__ASKR_INSTANCE)) {
585
- seen.add(host.__ASKR_INSTANCE);
586
- instances.push(host.__ASKR_INSTANCE);
587
- }
588
- for (let child = node.lastChild; child; child = child.previousSibling) pending.push(child);
589
- }
590
- return instances;
591
- }
592
- function captureDeferredRouteCleanup(instance) {
593
- return {
594
- instance,
595
- previousOwnershipGeneration: instance._ownershipGeneration,
596
- previousFn: instance.fn,
597
- previousProps: instance.props,
598
- previousExpectedStateIndices: instance.expectedStateIndices,
599
- previousFirstRenderComplete: instance.firstRenderComplete,
600
- previousStateIndexCheck: instance.stateIndexCheck,
601
- previousErrorBoundaryState: instance.errorBoundaryState,
602
- previousTarget: instance.target,
603
- previousDom: captureRouteDom(instance.target),
604
- previousStateValues: instance.stateValues,
605
- previousCleanupFns: instance.cleanupFns,
606
- previousOwnedChildScopes: instance._ownedChildScopes,
607
- previousAbortController: instance.abortController,
608
- previousMountOperations: instance.mountOperations,
609
- previousCommitOperations: instance.commitOperations,
610
- previousLifecycleSlots: instance.lifecycleSlots,
611
- previousLifecycleGeneration: instance.lifecycleGeneration,
612
- previousEvaluationGeneration: instance.evaluationGeneration,
613
- previousHasPendingUpdate: instance.hasPendingUpdate,
614
- previousNotifyUpdate: instance.notifyUpdate,
615
- previousPlaceholder: instance._placeholder,
616
- previousMounted: instance.mounted,
617
- previousCurrentRenderToken: instance._currentRenderToken,
618
- previousLastRenderToken: instance.lastRenderToken,
619
- previousPendingReadSources: instance._pendingReadSources,
620
- previousPendingReadSourceVersions: instance._pendingReadSourceVersions,
621
- previousLastReadSources: instance._lastReadSources,
622
- previousReaderEntries: Array.from(instance._lastReadSources ?? []).map((source) => ({
623
- source,
624
- reader: source._readers?.get(instance)
625
- })),
626
- previousAppRenderRuntime: instance._appRenderRuntime,
627
- previousInstances: instance.target ? collectHostInstances(instance.target) : [],
628
- previousDisposed: false
629
- };
630
- }
631
- function restoreDeferredRouteInstance(deferred) {
632
- const instance = deferred.instance;
633
- const errors = [];
634
- const activeGeneration = instance._ownershipGeneration;
635
- const activeReadSources = instance._lastReadSources;
636
- if (activeGeneration !== deferred.previousOwnershipGeneration) {
637
- try {
638
- cleanupReadableSubscriptionSources(instance, activeReadSources, activeGeneration);
639
- } catch (error) {
640
- errors.push(error);
641
- }
642
- instance._lastReadSources = void 0;
643
- try {
644
- cleanupComponent(instance);
645
- } catch (error) {
646
- errors.push(error);
647
- }
648
- }
649
- errors.push(...restoreRouteDom(deferred.previousDom));
650
- instance.fn = deferred.previousFn;
651
- instance._ownershipGeneration = deferred.previousOwnershipGeneration;
652
- instance.props = deferred.previousProps;
653
- instance.expectedStateIndices = deferred.previousExpectedStateIndices;
654
- instance.firstRenderComplete = deferred.previousFirstRenderComplete;
655
- instance.stateIndexCheck = deferred.previousStateIndexCheck;
656
- instance.errorBoundaryState = deferred.previousErrorBoundaryState;
657
- instance.target = deferred.previousTarget;
658
- instance.stateValues = deferred.previousStateValues;
659
- instance.cleanupFns = deferred.previousCleanupFns;
660
- instance._ownedChildScopes = deferred.previousOwnedChildScopes;
661
- instance.abortController = deferred.previousAbortController;
662
- instance.mountOperations = deferred.previousMountOperations;
663
- instance.commitOperations = deferred.previousCommitOperations;
664
- instance.lifecycleSlots = deferred.previousLifecycleSlots;
665
- instance.lifecycleGeneration = deferred.previousLifecycleGeneration;
666
- instance.evaluationGeneration = deferred.previousEvaluationGeneration;
667
- instance.hasPendingUpdate = deferred.previousHasPendingUpdate;
668
- instance.notifyUpdate = deferred.previousNotifyUpdate;
669
- instance._placeholder = deferred.previousPlaceholder;
670
- instance.mounted = deferred.previousMounted;
671
- instance._currentRenderToken = deferred.previousCurrentRenderToken;
672
- instance.lastRenderToken = deferred.previousLastRenderToken;
673
- instance._pendingReadSources = deferred.previousPendingReadSources;
674
- instance._pendingReadSourceVersions = deferred.previousPendingReadSourceVersions;
675
- instance._lastReadSources = deferred.previousLastReadSources;
676
- instance._appRenderRuntime = deferred.previousAppRenderRuntime;
677
- const previousSources = new Set(deferred.previousReaderEntries.map(({ source }) => source));
678
- for (const source of activeReadSources ?? []) {
679
- if (previousSources.has(source)) continue;
680
- if ((source._readers?.get(instance))?.generation === activeGeneration) {
681
- if (source._readers?.delete(instance) && false);
682
- }
683
- }
684
- for (const { source, reader } of deferred.previousReaderEntries) {
685
- if (!reader) {
686
- if (source._readers?.delete(instance) && false);
687
- continue;
688
- }
689
- let readers = source._readers;
690
- if (!readers) {
691
- readers = /* @__PURE__ */ new Map();
692
- source._readers = readers;
693
- }
694
- readers.has(instance);
695
- readers.set(instance, reader);
696
- }
697
- return errors;
698
- }
699
- function restoreDeferredRouteInstances(deferredCleanups) {
700
- const errors = [];
701
- for (let index = deferredCleanups.length - 1; index >= 0; index -= 1) errors.push(...restoreDeferredRouteInstance(deferredCleanups[index]));
702
- if (errors.length > 0) reportRouteCleanupErrors(errors);
703
- }
704
- function cleanupDeferredRouteInstance(deferred) {
705
- const errors = [];
706
- const instance = deferred.instance;
707
- if (!deferred.previousDisposed) {
708
- deferred.previousDisposed = true;
709
- try {
710
- cleanupComponentGeneration(instance, {
711
- ownershipGeneration: deferred.previousOwnershipGeneration,
712
- cleanupFns: deferred.previousCleanupFns,
713
- ownedChildScopes: deferred.previousOwnedChildScopes,
714
- abortController: deferred.previousAbortController,
715
- readSources: deferred.previousLastReadSources
716
- });
717
- } catch (error) {
718
- errors.push(error);
719
- }
720
- }
721
- const root = instance.target;
722
- const liveInstances = root ? new Set(collectHostInstances(root)) : /* @__PURE__ */ new Set();
723
- for (let index = deferred.previousInstances.length - 1; index >= 0; index--) {
724
- const previous = deferred.previousInstances[index];
725
- if (previous === instance || liveInstances.has(previous)) continue;
726
- try {
727
- cleanupComponent(previous);
728
- } catch (error) {
729
- errors.push(error);
730
- }
731
- }
732
- return errors;
733
- }
734
- function remountResolvedRoute(instance, resolved, pathname, href, existingSnapshot) {
735
- const deferredCleanup = existingSnapshot ?? captureDeferredRouteCleanup(instance);
736
- clearRegisteredDefaultPortalForInstance(instance);
737
- instance.fn = wrapRootRouteHandler(bindResolvedRouteHandler(resolved), instance._cspNonce);
738
- instance.props = {};
739
- instance._ownershipGeneration = {};
740
- instance.stateValues = [];
741
- instance.expectedStateIndices = [];
742
- instance.firstRenderComplete = false;
743
- instance.stateIndexCheck = -1;
744
- instance.evaluationGeneration++;
745
- instance.lifecycleGeneration++;
746
- instance.notifyUpdate = null;
747
- instance.mountOperations = [];
748
- instance.commitOperations = [];
749
- instance.lifecycleSlots = [];
750
- instance.cleanupFns = [];
751
- instance._ownedChildScopes = /* @__PURE__ */ new Set();
752
- instance._placeholder = void 0;
753
- instance.hasPendingUpdate = false;
754
- instance._currentRenderToken = void 0;
755
- instance.lastRenderToken = 0;
756
- instance._pendingReadSources = void 0;
757
- instance._lastReadSources = void 0;
758
- instance.abortController = null;
759
- executeComponent(instance);
760
- setCurrentRouteLocation(pathname, href);
761
- return deferredCleanup;
762
- }
763
- function rerenderResolvedRoute(instance, pathname, href) {
764
- setCurrentRouteLocation(pathname, href);
765
- instance._enqueueRun?.();
766
- return true;
767
- }
768
505
  function resolveAppRouteRequest(app, pathname, href, signal) {
769
506
  return resolveRouteRequest(href, {
770
507
  registry: app.registry,
@@ -781,21 +518,15 @@ function getResolvedRouteHandler(resolved) {
781
518
  params: resolved.params
782
519
  };
783
520
  }
784
- function updateRouteRuntime(instance, resolved, href) {
785
- const current = instance._appRenderRuntime;
786
- const runtime = createAppRenderRuntime({
787
- framework: withoutRouteHydrationMetadata(current?.framework),
788
- dataRuntime: current?.dataRuntime,
789
- routeRegistry: current?.routeRegistry,
790
- routeAuth: current?.routeAuth,
791
- route: resolved?.kind === "render" ? getRouteRenderData(resolved) : void 0,
792
- hasRoute: resolved?.kind === "render" && hasRouteRenderData(resolved)
521
+ function prepareNavigationRoot(target, href, replaceLifetime) {
522
+ const resolved = target.resolved;
523
+ return prepareRootUpdate(target.app.instance, {
524
+ handler: bindResolvedRouteHandler(getResolvedRouteHandler(resolved)),
525
+ href,
526
+ routeData: isRenderResult(resolved) ? getRouteRenderData(resolved) : void 0,
527
+ hasRouteData: isRenderResult(resolved) && hasRouteRenderData(resolved),
528
+ replaceLifetime
793
529
  });
794
- stageAppRenderRouteLocation(runtime, href);
795
- instance._appRenderRuntime = runtime;
796
- }
797
- function clearStagedRouteLocations(targets) {
798
- for (const target of targets) clearStagedAppRenderRouteLocation(target.app.instance._appRenderRuntime);
799
530
  }
800
531
  function resolveNavigationTargetsForApps(pathname, href, signal) {
801
532
  const apps = getRegisteredAppsSnapshot();
@@ -850,79 +581,7 @@ function applyNavigationTargets(requestId, path, options, redirectState, pathnam
850
581
  return;
851
582
  }
852
583
  if (isStaleRouteRequest(requestId)) return;
853
- const samePathTargets = [];
854
- const rootsToPrepare = [];
855
- for (const target of matchedTargets) {
856
- const resolved = target.resolved;
857
- if (resolved.kind === "redirect") continue;
858
- if (pathname === target.app.pathname && isRenderResult(resolved)) {
859
- samePathTargets.push(target);
860
- continue;
861
- }
862
- rootsToPrepare.push(target);
863
- }
864
- const rollbackSnapshots = matchedTargets.map((target) => captureDeferredRouteCleanup(target.app.instance));
865
- const rollbackSnapshotByInstance = new Map(rollbackSnapshots.map((snapshot) => [snapshot.instance, snapshot]));
866
- const deferredCleanups = [];
867
- const cleanupErrors = [];
868
- const previousAppLocations = matchedTargets.map((target) => ({
869
- app: target.app,
870
- pathname: target.app.pathname,
871
- href: target.app.href
872
- }));
873
- const restoreOnExit = () => {
874
- if (!navigationBatchClosed) {
875
- discardLifecycleCommitBatch(navigationBatch);
876
- navigationBatchClosed = true;
877
- }
878
- restoreDeferredRouteInstances(rollbackSnapshots);
879
- for (const previous of previousAppLocations) {
880
- previous.app.pathname = previous.pathname;
881
- previous.app.href = previous.href;
882
- }
883
- setCurrentRouteLocation(previousPathname, previousHref);
884
- };
885
- const navigationBatch = beginLifecycleCommitBatch();
886
- let navigationBatchClosed = false;
887
- try {
888
- for (const target of rootsToPrepare) {
889
- if (isStaleRouteRequest(requestId)) {
890
- restoreOnExit();
891
- return;
892
- }
893
- updateRouteRuntime(target.app.instance, target.resolved, href);
894
- const deferredCleanup = remountResolvedRoute(target.app.instance, getResolvedRouteHandler(target.resolved), pathname, href, rollbackSnapshotByInstance.get(target.app.instance));
895
- deferredCleanups.push(deferredCleanup);
896
- }
897
- if (isStaleRouteRequest(requestId)) {
898
- restoreOnExit();
899
- return;
900
- }
901
- flushRuntimeScheduler();
902
- cleanupErrors.push(...drainLifecycleCommitErrors());
903
- if (isStaleRouteRequest(requestId)) {
904
- restoreOnExit();
905
- return;
906
- }
907
- for (const target of samePathTargets) {
908
- if (isStaleRouteRequest(requestId)) {
909
- restoreOnExit();
910
- return;
911
- }
912
- updateRouteRuntime(target.app.instance, target.resolved, href);
913
- rerenderResolvedRoute(target.app.instance, pathname, href);
914
- }
915
- flushRuntimeScheduler();
916
- cleanupErrors.push(...drainLifecycleCommitErrors());
917
- if (isStaleRouteRequest(requestId)) {
918
- restoreOnExit();
919
- return;
920
- }
921
- flushLifecycleCommitBatch(navigationBatch);
922
- navigationBatchClosed = true;
923
- cleanupErrors.push(...drainLifecycleCommitErrors());
924
- for (const target of matchedTargets) if (target.resolved && target.resolved.kind !== "redirect") syncAppRegistrationLocation(target.app, pathname, href);
925
- if (isStaleRouteRequest(requestId)) return;
584
+ commitNavigationRoots(requestId, pathname, href, matchedTargets, () => {
926
585
  saveScrollPosition(previousHref);
927
586
  const historyMethod = getNavigationHistoryMode(options) === "replace" ? "replaceState" : "pushState";
928
587
  window.history[historyMethod]({
@@ -930,18 +589,9 @@ function applyNavigationTargets(requestId, path, options, redirectState, pathnam
930
589
  askrHasState: Object.prototype.hasOwnProperty.call(options, "state"),
931
590
  askrState: options.state
932
591
  }, "", href);
933
- setCurrentRouteLocation(pathname, href);
934
- clearStagedRouteLocations(matchedTargets);
935
- syncRegisteredRouteSnapshot();
936
- reconcileNavigationMetadata(matchedTargets);
592
+ }, () => {
937
593
  if (pathname !== previousPathname || parseTargetUrl(href).hash) applyNavigationScroll(options.scroll);
938
- for (const deferredCleanup of deferredCleanups) cleanupErrors.push(...cleanupDeferredRouteInstance(deferredCleanup));
939
- for (const error of cleanupErrors) reportRouteCleanupErrors([error]);
940
- } catch (error) {
941
- restoreOnExit();
942
- logger.error("[Askr] navigation failed:", error);
943
- throw error;
944
- }
594
+ });
945
595
  }
946
596
  function applyPopStateNavigationTargets(requestId, previousHref, previousState, pathname, href, state, targets, navigate) {
947
597
  if (isStaleRouteRequest(requestId)) return;
@@ -956,100 +606,86 @@ function applyPopStateNavigationTargets(requestId, previousHref, previousState,
956
606
  navigate(resolved.to, { history: getRedirectHistoryMode(resolved.replace) });
957
607
  return;
958
608
  }
959
- const samePathTargets = [];
960
- const rootsToPrepare = [];
961
- for (const target of matchedTargets) {
962
- const resolved = target.resolved;
963
- if (pathname === target.app.pathname && isRenderResult(resolved)) {
964
- samePathTargets.push(target);
965
- continue;
966
- }
967
- if (resolved.kind === "redirect") continue;
968
- rootsToPrepare.push(target);
969
- }
970
- const previousPathname = getCurrentPathname();
971
609
  saveScrollPosition(previousHref);
972
- const rollbackSnapshots = matchedTargets.map((target) => captureDeferredRouteCleanup(target.app.instance));
973
- const rollbackSnapshotByInstance = new Map(rollbackSnapshots.map((snapshot) => [snapshot.instance, snapshot]));
974
- const deferredCleanups = [];
975
- const cleanupErrors = [];
976
- const previousAppLocations = matchedTargets.map((target) => ({
977
- app: target.app,
978
- pathname: target.app.pathname,
979
- href: target.app.href
980
- }));
981
- const restoreOnExit = () => {
982
- if (!navigationBatchClosed) {
983
- discardLifecycleCommitBatch(navigationBatch);
984
- navigationBatchClosed = true;
985
- }
986
- restoreDeferredRouteInstances(rollbackSnapshots);
987
- for (const previous of previousAppLocations) {
988
- previous.app.pathname = previous.pathname;
989
- previous.app.href = previous.href;
990
- }
991
- setCurrentRouteLocation(previousPathname, previousHref);
992
- };
993
- const navigationBatch = beginLifecycleCommitBatch();
994
- let navigationBatchClosed = false;
995
- try {
996
- for (const target of rootsToPrepare) {
997
- if (isStaleRouteRequest(requestId)) {
998
- restoreOnExit();
999
- return;
610
+ commitNavigationRoots(requestId, pathname, href, matchedTargets, () => {}, () => applyHistoryScroll(href, state), () => {
611
+ window.history.replaceState(previousState, "", previousHref);
612
+ syncRegisteredRouteSnapshot();
613
+ });
614
+ }
615
+ /** Every root joins one transaction. History remains after lifecycle work,
616
+ * so a navigation started by that work can supersede this destination. */
617
+ function commitNavigationRoots(requestId, pathname, href, targets, updateHistory, updateScroll, restoreHistory) {
618
+ const previousPathname = getCurrentPathname();
619
+ const previousHref = getCurrentHref();
620
+ const roots = targets.map((target) => {
621
+ const replaceLifetime = pathname !== target.app.pathname || !isRenderResult(target.resolved);
622
+ return {
623
+ target,
624
+ replaceLifetime,
625
+ previousPathname: target.app.pathname,
626
+ previousHref: target.app.href,
627
+ prepared: prepareNavigationRoot(target, href, replaceLifetime)
628
+ };
629
+ });
630
+ const transaction = beginCommitTransaction();
631
+ let completionFailure;
632
+ registerCommitParticipant({
633
+ rollback() {
634
+ const errors = [];
635
+ for (let index = roots.length - 1; index >= 0; index--) errors.push(...roots[index].prepared.rollback());
636
+ for (const root of roots) {
637
+ root.target.app.pathname = root.previousPathname;
638
+ root.target.app.href = root.previousHref;
1000
639
  }
1001
- updateRouteRuntime(target.app.instance, target.resolved, href);
1002
- const deferredCleanup = remountResolvedRoute(target.app.instance, getResolvedRouteHandler(target.resolved), pathname, href, rollbackSnapshotByInstance.get(target.app.instance));
1003
- deferredCleanups.push(deferredCleanup);
1004
- }
1005
- if (isStaleRouteRequest(requestId)) {
1006
- restoreOnExit();
1007
- return;
1008
- }
1009
- flushRuntimeScheduler();
1010
- cleanupErrors.push(...drainLifecycleCommitErrors());
1011
- if (isStaleRouteRequest(requestId)) {
1012
- restoreOnExit();
1013
- return;
1014
- }
1015
- for (const target of samePathTargets) {
1016
- if (isStaleRouteRequest(requestId)) {
1017
- restoreOnExit();
1018
- return;
640
+ setCurrentRouteLocation(previousPathname, previousHref);
641
+ try {
642
+ restoreHistory?.();
643
+ } catch (error) {
644
+ errors.push(error);
645
+ }
646
+ reportRouteCleanupErrors(errors);
647
+ },
648
+ settle() {
649
+ const errors = [];
650
+ for (const root of roots) errors.push(...root.prepared.retire());
651
+ reportRouteCleanupErrors(errors);
652
+ },
653
+ complete() {
654
+ if (isStaleRouteRequest(requestId)) return;
655
+ try {
656
+ updateHistory();
657
+ setCurrentRouteLocation(pathname, href);
658
+ syncRegisteredRouteSnapshot();
659
+ reconcileNavigationMetadata(targets);
660
+ updateScroll();
661
+ } catch (error) {
662
+ completionFailure = { error };
663
+ throw error;
664
+ } finally {
665
+ for (const root of roots) root.prepared.publish();
1019
666
  }
1020
- updateRouteRuntime(target.app.instance, target.resolved, href);
1021
- rerenderResolvedRoute(target.app.instance, pathname, href);
1022
- }
1023
- flushRuntimeScheduler();
1024
- cleanupErrors.push(...drainLifecycleCommitErrors());
1025
- if (isStaleRouteRequest(requestId)) {
1026
- restoreOnExit();
1027
- return;
1028
- }
1029
- flushLifecycleCommitBatch(navigationBatch);
1030
- navigationBatchClosed = true;
1031
- cleanupErrors.push(...drainLifecycleCommitErrors());
1032
- for (const target of matchedTargets) if (target.resolved && target.resolved.kind !== "redirect") syncAppRegistrationLocation(target.app, pathname, href);
1033
- if (isStaleRouteRequest(requestId)) {
1034
- restoreOnExit();
1035
- return;
1036
667
  }
1037
- setCurrentRouteLocation(pathname, href);
1038
- clearStagedRouteLocations(matchedTargets);
1039
- syncRegisteredRouteSnapshot();
1040
- reconcileNavigationMetadata(matchedTargets);
1041
- applyHistoryScroll(href, state);
1042
- for (const deferredCleanup of deferredCleanups) cleanupErrors.push(...cleanupDeferredRouteInstance(deferredCleanup));
1043
- for (const error of cleanupErrors) reportRouteCleanupErrors([error]);
668
+ });
669
+ try {
670
+ for (const replaceLifetime of [true, false]) {
671
+ for (const root of roots) {
672
+ if (isStaleRouteRequest(requestId)) return;
673
+ if (root.replaceLifetime === replaceLifetime) root.prepared.apply();
674
+ }
675
+ if (isStaleRouteRequest(requestId)) return;
676
+ flushRuntimeScheduler();
677
+ if (isStaleRouteRequest(requestId)) return;
678
+ }
679
+ registerCommitParticipant({ publish() {
680
+ for (const root of roots) syncAppRegistrationLocation(root.target.app, pathname, href);
681
+ } });
682
+ commitTransaction(transaction);
683
+ if (completionFailure) throw completionFailure.error;
1044
684
  } catch (error) {
1045
- restoreOnExit();
1046
- try {
1047
- window.history.replaceState(previousState, "", previousHref);
1048
- syncRegisteredRouteSnapshot();
1049
- } catch (rollbackError) {
1050
- logger.error("[Askr] failed to restore URL after popstate failure:", rollbackError);
1051
- }
685
+ logger.error("[Askr] navigation failed:", error);
1052
686
  throw error;
687
+ } finally {
688
+ discardTransaction(transaction);
1053
689
  }
1054
690
  }
1055
691
  //#endregion
@@ -1058,9 +694,23 @@ function applyPopStateNavigationTargets(requestId, previousHref, previousState,
1058
694
  * Client-side navigation with History API
1059
695
  */
1060
696
  let navigationInitialized = false;
1061
- configureNavigationRegistryHost({ cancelRouteRequests });
697
+ let navigationRegistryHosted = false;
698
+ /**
699
+ * Publish request cancellation to the navigation registry.
700
+ *
701
+ * The registry cannot import this module (it is imported *by* it), so the
702
+ * capability is injected. Doing that at module scope meant whether an app
703
+ * could cancel its in-flight route requests depended on whether anything had
704
+ * imported this module yet; every entry point that can navigate composes it.
705
+ */
706
+ function ensureNavigationRegistryHost() {
707
+ if (navigationRegistryHosted) return;
708
+ navigationRegistryHosted = true;
709
+ configureNavigationRegistryHost({ cancelRouteRequests });
710
+ }
1062
711
  /** Navigate the client-side router to `path` using the History API. */
1063
712
  function navigate(path, options = {}) {
713
+ ensureNavigationRegistryHost();
1064
714
  if (typeof window === "undefined") return;
1065
715
  prepareNavigationFocus();
1066
716
  const targetPath = addRouteBasePath(path, getActiveRouteBasePath());
@@ -1093,6 +743,7 @@ function navigateWithRedirectState(path, options, redirectState) {
1093
743
  logger.error("[Askr] navigation failed:", error);
1094
744
  }
1095
745
  }, (error) => {
746
+ if (isStaleRouteRequest(request.id)) return;
1096
747
  logger.error("[Askr] navigation failed:", error);
1097
748
  });
1098
749
  return;
@@ -1118,6 +769,7 @@ function handlePopState(event) {
1118
769
  Promise.resolve(resolvedTargets).then((next) => {
1119
770
  applyResolved(next);
1120
771
  }, (error) => {
772
+ if (isStaleRouteRequest(request.id)) return;
1121
773
  logger.error("[Askr] popstate navigation failed:", error);
1122
774
  });
1123
775
  return;
@@ -1125,6 +777,7 @@ function handlePopState(event) {
1125
777
  applyResolved(resolvedTargets);
1126
778
  }
1127
779
  function initializeNavigation() {
780
+ ensureNavigationRegistryHost();
1128
781
  if (typeof window === "undefined" || navigationInitialized) return;
1129
782
  navigationInitialized = true;
1130
783
  window.addEventListener("popstate", handlePopState);
@@ -1132,4 +785,4 @@ function initializeNavigation() {
1132
785
  document.addEventListener("click", releaseNavigationFocusCapture);
1133
786
  }
1134
787
  //#endregion
1135
- export { serializeRouteMeta as a, getCurrentHref as c, parseTargetUrl as d, registerAppInstance as f, unregisterAppInstance as g, syncRegisteredRouteSnapshot as h, resolveRouteMeta as i, getRegisteredAppsSnapshot as l, syncAppRegistrationLocation as m, navigate as n, configureScrollRestoration as o, setCurrentRouteLocation as p, reconcileRouteMeta as r, saveScrollPosition as s, initializeNavigation as t, getWindowHref$1 as u };
788
+ export { configureRootUpdateHost as _, serializeRouteMeta as a, getCurrentHref as c, parseTargetUrl as d, registerAppInstance as f, unregisterAppInstance as g, syncRegisteredRouteSnapshot as h, resolveRouteMeta as i, getRegisteredAppsSnapshot as l, syncAppRegistrationLocation as m, navigate as n, configureScrollRestoration as o, setCurrentRouteLocation as p, reconcileRouteMeta as r, saveScrollPosition as s, initializeNavigation as t, getWindowHref$1 as u };