@askrjs/askr 0.0.47 → 0.0.49
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.
- package/dist/benchmark.js +6 -6
- package/dist/benchmark.js.map +1 -1
- package/dist/boot/hydration.js +140 -0
- package/dist/boot/hydration.js.map +1 -0
- package/dist/boot/index.d.ts +3 -56
- package/dist/boot/index.d.ts.map +1 -1
- package/dist/boot/index.js +62 -410
- package/dist/boot/index.js.map +1 -1
- package/dist/boot/root-lifecycle.d.ts +15 -0
- package/dist/boot/root-lifecycle.d.ts.map +1 -0
- package/dist/boot/root-lifecycle.js +205 -0
- package/dist/boot/root-lifecycle.js.map +1 -0
- package/dist/boot/route-startup.js +45 -0
- package/dist/boot/route-startup.js.map +1 -0
- package/dist/boot/types.d.ts +62 -0
- package/dist/boot/types.d.ts.map +1 -0
- package/dist/common/component.d.ts +3 -1
- package/dist/common/component.d.ts.map +1 -1
- package/dist/common/jsx.d.ts +1 -1
- package/dist/common/jsx.d.ts.map +1 -1
- package/dist/common/jsx.js.map +1 -1
- package/dist/common/props.d.ts +1 -1
- package/dist/common/render-context.js +55 -0
- package/dist/common/render-context.js.map +1 -0
- package/dist/common/router.d.ts +5 -1
- package/dist/common/router.d.ts.map +1 -1
- package/dist/common/ssr.d.ts +1 -1
- package/dist/common/ssr.js.map +1 -1
- package/dist/common/vnode.d.ts +5 -4
- package/dist/common/vnode.d.ts.map +1 -1
- package/dist/common/vnode.js.map +1 -1
- package/dist/components/error-boundary.d.ts +1 -1
- package/dist/components/error-boundary.js +2 -1
- package/dist/components/error-boundary.js.map +1 -1
- package/dist/components/link.js.map +1 -1
- package/dist/control/for.js +2 -1
- package/dist/control/for.js.map +1 -1
- package/dist/data/data-runtime.d.ts +28 -0
- package/dist/data/data-runtime.d.ts.map +1 -0
- package/dist/data/data-runtime.js +114 -0
- package/dist/data/data-runtime.js.map +1 -0
- package/dist/data/index.d.ts +6 -142
- package/dist/data/index.js +5 -539
- package/dist/data/invalidation.d.ts +9 -0
- package/dist/data/invalidation.d.ts.map +1 -0
- package/dist/data/invalidation.js +27 -0
- package/dist/data/invalidation.js.map +1 -0
- package/dist/data/mutation-cell.d.ts +28 -0
- package/dist/data/mutation-cell.d.ts.map +1 -0
- package/dist/data/mutation-cell.js +132 -0
- package/dist/data/mutation-cell.js.map +1 -0
- package/dist/data/query-cell.d.ts +46 -0
- package/dist/data/query-cell.d.ts.map +1 -0
- package/dist/data/query-cell.js +290 -0
- package/dist/data/query-cell.js.map +1 -0
- package/dist/data/query-key.js +42 -0
- package/dist/data/query-key.js.map +1 -0
- package/dist/data/shared.js +20 -0
- package/dist/data/shared.js.map +1 -0
- package/dist/data/types.d.ts +161 -0
- package/dist/data/types.d.ts.map +1 -0
- package/dist/foundations/icon/icon.d.ts.map +1 -1
- package/dist/foundations/icon/icon.js.map +1 -1
- package/dist/foundations/structures/portal.d.ts +1 -1
- package/dist/foundations/structures/portal.d.ts.map +1 -1
- package/dist/foundations/structures/portal.js +2 -1
- package/dist/foundations/structures/portal.js.map +1 -1
- package/dist/fx/fx.d.ts +1 -1
- package/dist/fx/fx.js +5 -4
- package/dist/fx/fx.js.map +1 -1
- package/dist/fx/timing.d.ts.map +1 -1
- package/dist/fx/timing.js +10 -6
- package/dist/fx/timing.js.map +1 -1
- package/dist/index.d.ts +3 -2
- package/dist/index.js +4 -2
- package/dist/index.js.map +1 -1
- package/dist/jsx/index.d.ts +2 -1
- package/dist/jsx/index.js +3 -2
- package/dist/jsx/types.d.ts +2 -0
- package/dist/jsx/types.js +2 -1
- package/dist/jsx-runtime2.d.ts +2 -1
- package/dist/jsx-runtime2.js +3 -2
- package/dist/renderer/attributes.js +231 -0
- package/dist/renderer/attributes.js.map +1 -0
- package/dist/renderer/boundaries.js +266 -0
- package/dist/renderer/boundaries.js.map +1 -0
- package/dist/renderer/child-shape.js +85 -0
- package/dist/renderer/child-shape.js.map +1 -0
- package/dist/renderer/children.js +3 -2
- package/dist/renderer/children.js.map +1 -1
- package/dist/renderer/cleanup.js +2 -1
- package/dist/renderer/cleanup.js.map +1 -1
- package/dist/renderer/component-host-cleanup.js +68 -0
- package/dist/renderer/component-host-cleanup.js.map +1 -0
- package/dist/renderer/component-host-instances.js +65 -0
- package/dist/renderer/component-host-instances.js.map +1 -0
- package/dist/renderer/component-host.js +247 -0
- package/dist/renderer/component-host.js.map +1 -0
- package/dist/renderer/dom-host.js +13 -0
- package/dist/renderer/dom-host.js.map +1 -0
- package/dist/renderer/dom-internal.js +185 -0
- package/dist/renderer/dom-internal.js.map +1 -0
- package/dist/renderer/dom.js +9 -2356
- package/dist/renderer/element-children.js +279 -0
- package/dist/renderer/element-children.js.map +1 -0
- package/dist/renderer/env.js +2 -1
- package/dist/renderer/error-boundary-dom.js +29 -0
- package/dist/renderer/error-boundary-dom.js.map +1 -0
- package/dist/renderer/evaluate-dom-range.js +85 -0
- package/dist/renderer/evaluate-dom-range.js.map +1 -0
- package/dist/renderer/evaluate-reconcile.js +281 -0
- package/dist/renderer/evaluate-reconcile.js.map +1 -0
- package/dist/renderer/evaluate.js +13 -399
- package/dist/renderer/evaluate.js.map +1 -1
- package/dist/renderer/fastpath.js +6 -5
- package/dist/renderer/fastpath.js.map +1 -1
- package/dist/renderer/for-commit-dom-map.js +83 -0
- package/dist/renderer/for-commit-dom-map.js.map +1 -0
- package/dist/renderer/for-commit-removal.js +36 -0
- package/dist/renderer/for-commit-removal.js.map +1 -0
- package/dist/renderer/for-commit-reorder.js +89 -0
- package/dist/renderer/for-commit-reorder.js.map +1 -0
- package/dist/renderer/for-commit.js +6 -188
- package/dist/renderer/for-commit.js.map +1 -1
- package/dist/renderer/index.js +28 -16
- package/dist/renderer/index.js.map +1 -1
- package/dist/renderer/keyed-children.js +32 -0
- package/dist/renderer/keyed-children.js.map +1 -0
- package/dist/renderer/keyed.js +2 -15
- package/dist/renderer/keyed.js.map +1 -1
- package/dist/renderer/namespaces.js +23 -0
- package/dist/renderer/namespaces.js.map +1 -0
- package/dist/renderer/prop-bindings.js +280 -0
- package/dist/renderer/prop-bindings.js.map +1 -0
- package/dist/renderer/reactive-child-dom.js +133 -0
- package/dist/renderer/reactive-child-dom.js.map +1 -0
- package/dist/renderer/reactive-child-sources.js +184 -0
- package/dist/renderer/reactive-child-sources.js.map +1 -0
- package/dist/renderer/reactive-children.js +294 -0
- package/dist/renderer/reactive-children.js.map +1 -0
- package/dist/renderer/reconcile-commit.js +38 -0
- package/dist/renderer/reconcile-commit.js.map +1 -0
- package/dist/renderer/reconcile-fastpaths.js +106 -0
- package/dist/renderer/reconcile-fastpaths.js.map +1 -0
- package/dist/renderer/reconcile-resolution.js +187 -0
- package/dist/renderer/reconcile-resolution.js.map +1 -0
- package/dist/renderer/reconcile.js +9 -371
- package/dist/renderer/reconcile.js.map +1 -1
- package/dist/renderer/retained-element-rollback.js +276 -0
- package/dist/renderer/retained-element-rollback.js.map +1 -0
- package/dist/renderer/stable-patch.js +82 -0
- package/dist/renderer/stable-patch.js.map +1 -0
- package/dist/renderer/static-reuse.js +96 -0
- package/dist/renderer/static-reuse.js.map +1 -0
- package/dist/renderer/types.js +2 -1
- package/dist/renderer/utils.js +4 -4
- package/dist/renderer/utils.js.map +1 -1
- package/dist/resources/index.d.ts +3 -2
- package/dist/resources/index.js +5 -2
- package/dist/router/access.js +36 -0
- package/dist/router/access.js.map +1 -0
- package/dist/router/activity.d.ts +10 -0
- package/dist/router/activity.d.ts.map +1 -0
- package/dist/router/activity.js +89 -0
- package/dist/router/activity.js.map +1 -0
- package/dist/router/authoring.d.ts +22 -0
- package/dist/router/authoring.d.ts.map +1 -0
- package/dist/router/authoring.js +198 -0
- package/dist/router/authoring.js.map +1 -0
- package/dist/router/index.d.ts +12 -4
- package/dist/router/index.js +9 -2
- package/dist/router/internal-types.d.ts +31 -0
- package/dist/router/internal-types.d.ts.map +1 -0
- package/dist/router/lazy.d.ts +19 -0
- package/dist/router/lazy.d.ts.map +1 -0
- package/dist/router/lazy.js +52 -0
- package/dist/router/lazy.js.map +1 -0
- package/dist/router/manifest.d.ts +10 -0
- package/dist/router/manifest.d.ts.map +1 -0
- package/dist/router/manifest.js +49 -0
- package/dist/router/manifest.js.map +1 -0
- package/dist/router/navigate.d.ts +4 -33
- package/dist/router/navigate.d.ts.map +1 -1
- package/dist/router/navigate.js +17 -414
- package/dist/router/navigate.js.map +1 -1
- package/dist/router/navigation-registry.d.ts +32 -0
- package/dist/router/navigation-registry.d.ts.map +1 -0
- package/dist/router/navigation-registry.js +105 -0
- package/dist/router/navigation-registry.js.map +1 -0
- package/dist/router/navigation-scroll.d.ts +14 -0
- package/dist/router/navigation-scroll.d.ts.map +1 -0
- package/dist/router/navigation-scroll.js +93 -0
- package/dist/router/navigation-scroll.js.map +1 -0
- package/dist/router/navigation-targets.d.ts +31 -0
- package/dist/router/navigation-targets.d.ts.map +1 -0
- package/dist/router/navigation-targets.js +253 -0
- package/dist/router/navigation-targets.js.map +1 -0
- package/dist/router/policy.d.ts +7 -1
- package/dist/router/policy.d.ts.map +1 -1
- package/dist/router/policy.js +27 -9
- package/dist/router/policy.js.map +1 -1
- package/dist/router/rendering.d.ts +10 -0
- package/dist/router/rendering.d.ts.map +1 -0
- package/dist/router/rendering.js +45 -0
- package/dist/router/rendering.js.map +1 -0
- package/dist/router/resolution.d.ts +17 -0
- package/dist/router/resolution.d.ts.map +1 -0
- package/dist/router/resolution.js +253 -0
- package/dist/router/resolution.js.map +1 -0
- package/dist/router/route-query.d.ts +17 -0
- package/dist/router/route-query.d.ts.map +1 -0
- package/dist/router/route-query.js +47 -0
- package/dist/router/route-query.js.map +1 -0
- package/dist/router/route.d.ts +8 -149
- package/dist/router/route.js +8 -854
- package/dist/router/store.d.ts +50 -0
- package/dist/router/store.d.ts.map +1 -0
- package/dist/router/store.js +171 -0
- package/dist/router/store.js.map +1 -0
- package/dist/runtime/access.js +45 -0
- package/dist/runtime/access.js.map +1 -0
- package/dist/runtime/child-scope.d.ts +1 -1
- package/dist/runtime/child-scope.js +4 -1
- package/dist/runtime/child-scope.js.map +1 -1
- package/dist/runtime/component-cleanup.d.ts +16 -0
- package/dist/runtime/component-cleanup.d.ts.map +1 -0
- package/dist/runtime/component-cleanup.js +70 -0
- package/dist/runtime/component-cleanup.js.map +1 -0
- package/dist/runtime/component-commit.js +165 -0
- package/dist/runtime/component-commit.js.map +1 -0
- package/dist/runtime/component-contracts.js +5 -0
- package/dist/runtime/component-facade.d.ts +5 -0
- package/dist/runtime/component-facade.js +4 -0
- package/dist/runtime/component-internal.d.ts +100 -0
- package/dist/runtime/component-internal.d.ts.map +1 -0
- package/dist/runtime/component-internal.js +219 -0
- package/dist/runtime/component-internal.js.map +1 -0
- package/dist/runtime/component-lifecycle.d.ts +49 -0
- package/dist/runtime/component-lifecycle.d.ts.map +1 -0
- package/dist/runtime/component-lifecycle.js +176 -0
- package/dist/runtime/component-lifecycle.js.map +1 -0
- package/dist/runtime/component-scope.d.ts +55 -0
- package/dist/runtime/component-scope.d.ts.map +1 -0
- package/dist/runtime/component-scope.js +154 -0
- package/dist/runtime/component-scope.js.map +1 -0
- package/dist/runtime/component.d.ts +4 -152
- package/dist/runtime/component.js +4 -692
- package/dist/runtime/context.d.ts +1 -1
- package/dist/runtime/context.js +6 -4
- package/dist/runtime/context.js.map +1 -1
- package/dist/runtime/control.d.ts +3 -3
- package/dist/runtime/control.js +2 -1
- package/dist/runtime/control.js.map +1 -1
- package/dist/runtime/derive.d.ts.map +1 -1
- package/dist/runtime/derive.js +6 -5
- package/dist/runtime/derive.js.map +1 -1
- package/dist/runtime/effect.d.ts +1 -1
- package/dist/runtime/effect.d.ts.map +1 -1
- package/dist/runtime/effect.js +2 -2
- package/dist/runtime/effect.js.map +1 -1
- package/dist/runtime/events.js +3 -3
- package/dist/runtime/events.js.map +1 -1
- package/dist/runtime/fastlane.js +13 -27
- package/dist/runtime/fastlane.js.map +1 -1
- package/dist/runtime/for-bench.d.ts +1 -1
- package/dist/runtime/for-bench.js +1 -4
- package/dist/runtime/for-bench.js.map +1 -1
- package/dist/runtime/for-internal.d.ts +43 -0
- package/dist/runtime/for-internal.d.ts.map +1 -0
- package/dist/runtime/for-internal.js +98 -0
- package/dist/runtime/for-internal.js.map +1 -0
- package/dist/runtime/for-reconcile.d.ts +8 -0
- package/dist/runtime/for-reconcile.d.ts.map +1 -0
- package/dist/runtime/for-reconcile.js +389 -0
- package/dist/runtime/for-reconcile.js.map +1 -0
- package/dist/runtime/for-scopes.d.ts +26 -0
- package/dist/runtime/for-scopes.d.ts.map +1 -0
- package/dist/runtime/for-scopes.js +160 -0
- package/dist/runtime/for-scopes.js.map +1 -0
- package/dist/runtime/for-signals.d.ts +30 -0
- package/dist/runtime/for-signals.d.ts.map +1 -0
- package/dist/runtime/for-signals.js +139 -0
- package/dist/runtime/for-signals.js.map +1 -0
- package/dist/runtime/for.d.ts +4 -66
- package/dist/runtime/for.js +5 -773
- package/dist/runtime/lifecycle-operations.d.ts +31 -0
- package/dist/runtime/lifecycle-operations.d.ts.map +1 -0
- package/dist/runtime/lifecycle-operations.js +195 -0
- package/dist/runtime/lifecycle-operations.js.map +1 -0
- package/dist/runtime/operations.d.ts +3 -40
- package/dist/runtime/operations.js +2 -357
- package/dist/runtime/readable.d.ts +2 -3
- package/dist/runtime/readable.d.ts.map +1 -1
- package/dist/runtime/readable.js +6 -5
- package/dist/runtime/readable.js.map +1 -1
- package/dist/runtime/resource-cell.js +2 -2
- package/dist/runtime/resource-cell.js.map +1 -1
- package/dist/runtime/resource-operation.d.ts +13 -0
- package/dist/runtime/resource-operation.d.ts.map +1 -0
- package/dist/runtime/resource-operation.js +170 -0
- package/dist/runtime/resource-operation.js.map +1 -0
- package/dist/runtime/runtime.d.ts +42 -0
- package/dist/runtime/runtime.d.ts.map +1 -0
- package/dist/runtime/runtime.js +59 -0
- package/dist/runtime/runtime.js.map +1 -0
- package/dist/runtime/scheduler.d.ts +5 -1
- package/dist/runtime/scheduler.d.ts.map +1 -1
- package/dist/runtime/scheduler.js +17 -17
- package/dist/runtime/scheduler.js.map +1 -1
- package/dist/runtime/selector.js +4 -3
- package/dist/runtime/selector.js.map +1 -1
- package/dist/runtime/snapshot-source.d.ts +1 -1
- package/dist/runtime/snapshot-source.js +1 -1
- package/dist/runtime/state.js +2 -1
- package/dist/runtime/state.js.map +1 -1
- package/dist/ssg/batch-render.js +2 -1
- package/dist/ssg/batch-render.js.map +1 -1
- package/dist/ssg/create-static-gen.d.ts +9 -3
- package/dist/ssg/create-static-gen.d.ts.map +1 -1
- package/dist/ssg/create-static-gen.js +12 -99
- package/dist/ssg/create-static-gen.js.map +1 -1
- package/dist/ssg/generation-plan.js +70 -0
- package/dist/ssg/generation-plan.js.map +1 -0
- package/dist/ssg/incremental-manifest.js +1 -1
- package/dist/ssg/static-routes.js +101 -0
- package/dist/ssg/static-routes.js.map +1 -0
- package/dist/ssg/types.d.ts +15 -7
- package/dist/ssg/types.d.ts.map +1 -1
- package/dist/ssr/boundaries.js +113 -0
- package/dist/ssr/boundaries.js.map +1 -0
- package/dist/ssr/component-runtime.js +111 -0
- package/dist/ssr/component-runtime.js.map +1 -0
- package/dist/ssr/context.d.ts +3 -1
- package/dist/ssr/context.d.ts.map +1 -1
- package/dist/ssr/context.js +9 -2
- package/dist/ssr/context.js.map +1 -1
- package/dist/ssr/errors.d.ts +2 -0
- package/dist/ssr/errors.js +11 -1
- package/dist/ssr/errors.js.map +1 -1
- package/dist/ssr/escape.js +3 -3
- package/dist/ssr/escape.js.map +1 -1
- package/dist/ssr/hydration-data.js +10 -0
- package/dist/ssr/hydration-data.js.map +1 -0
- package/dist/ssr/hydration-verify.d.ts +12 -0
- package/dist/ssr/hydration-verify.d.ts.map +1 -0
- package/dist/ssr/hydration-verify.js +144 -0
- package/dist/ssr/hydration-verify.js.map +1 -0
- package/dist/ssr/index-internal.d.ts +15 -0
- package/dist/ssr/index-internal.d.ts.map +1 -0
- package/dist/ssr/index-internal.js +19 -0
- package/dist/ssr/index-internal.js.map +1 -0
- package/dist/ssr/index.d.ts +5 -57
- package/dist/ssr/index.js +3 -738
- package/dist/ssr/render-keys.js +9 -32
- package/dist/ssr/render-keys.js.map +1 -1
- package/dist/ssr/render-resolved.d.ts +1 -1
- package/dist/ssr/render-resolved.d.ts.map +1 -1
- package/dist/ssr/render-resolved.js +4 -2
- package/dist/ssr/render-resolved.js.map +1 -1
- package/dist/ssr/render-sync.d.ts +21 -0
- package/dist/ssr/render-sync.d.ts.map +1 -0
- package/dist/ssr/render-sync.js +275 -0
- package/dist/ssr/render-sync.js.map +1 -0
- package/dist/ssr/route-policy-resolution.js +77 -0
- package/dist/ssr/route-policy-resolution.js.map +1 -0
- package/dist/ssr/route-render.d.ts +77 -0
- package/dist/ssr/route-render.d.ts.map +1 -0
- package/dist/ssr/route-render.js +119 -0
- package/dist/ssr/route-render.js.map +1 -0
- package/dist/ssr/sink.d.ts +26 -0
- package/dist/ssr/sink.d.ts.map +1 -0
- package/dist/ssr/types.d.ts +1 -0
- package/dist/ssr/types.d.ts.map +1 -1
- package/dist/ssr/verify-hydration.js.map +1 -1
- package/dist/testing/index.d.ts +1 -2
- package/dist/testing/index.d.ts.map +1 -1
- package/dist/testing/index.js +2 -1
- package/dist/testing/index.js.map +1 -1
- package/package.json +4 -3
- package/dist/data/index.d.ts.map +0 -1
- package/dist/data/index.js.map +0 -1
- package/dist/renderer/dom.js.map +0 -1
- package/dist/router/route.d.ts.map +0 -1
- package/dist/router/route.js.map +0 -1
- package/dist/runtime/component.d.ts.map +0 -1
- package/dist/runtime/component.js.map +0 -1
- package/dist/runtime/for.d.ts.map +0 -1
- package/dist/runtime/for.js.map +0 -1
- package/dist/runtime/operations.d.ts.map +0 -1
- package/dist/runtime/operations.js.map +0 -1
- package/dist/runtime/ssr-bridge.js +0 -24
- package/dist/runtime/ssr-bridge.js.map +0 -1
- package/dist/ssr/index.d.ts.map +0 -1
- package/dist/ssr/index.js.map +0 -1
package/dist/router/navigate.js
CHANGED
|
@@ -1,385 +1,21 @@
|
|
|
1
|
-
import { isDevelopmentEnvironment, isProductionEnvironment } from "../common/env.js";
|
|
2
1
|
import { logger } from "../dev/logger.js";
|
|
3
|
-
import { ELEMENT_TYPE, Fragment } from "../common/jsx.js";
|
|
4
2
|
import { isPromiseLike } from "../common/promise.js";
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
7
|
-
import {
|
|
8
|
-
import "
|
|
9
|
-
import { DefaultPortal, clearDefaultPortalForInstance } from "../foundations/structures/portal.js";
|
|
3
|
+
import { configureScrollRestoration, saveScrollPosition } from "./navigation-scroll.js";
|
|
4
|
+
import { configureNavigationRegistryHost, getCurrentHref, hasRegisteredApps, parseTargetUrl, registerAppInstance, unregisterAppInstance } from "./navigation-registry.js";
|
|
5
|
+
import { applyNavigationTargets, applyPopStateNavigationTargets, beginRouteRequest, cancelRouteRequests, isStaleRouteRequest, resolveNavigationTargetsForApps } from "./navigation-targets.js";
|
|
6
|
+
import { updateRouteQuery } from "./route-query.js";
|
|
10
7
|
//#region src/router/navigate.ts
|
|
11
8
|
/**
|
|
12
9
|
* Client-side navigation with History API
|
|
13
10
|
*/
|
|
14
|
-
let currentInstance = null;
|
|
15
|
-
let currentPathname = "/";
|
|
16
|
-
let currentHref = "/";
|
|
17
11
|
let navigationInitialized = false;
|
|
18
|
-
|
|
19
|
-
let activeRouteRequestController = null;
|
|
20
|
-
const MAX_NAVIGATION_REDIRECTS = 20;
|
|
21
|
-
const registeredApps = [];
|
|
22
|
-
function collectRouteActivityMatches(pathname, apps = registeredApps) {
|
|
23
|
-
const matches = [];
|
|
24
|
-
const seenPaths = /* @__PURE__ */ new Set();
|
|
25
|
-
for (const app of apps) {
|
|
26
|
-
const appMatches = computeRouteActivityMatches(pathname, {
|
|
27
|
-
manifest: app.manifest,
|
|
28
|
-
routes: app.routes
|
|
29
|
-
});
|
|
30
|
-
for (const match of appMatches) {
|
|
31
|
-
if (seenPaths.has(match.path)) continue;
|
|
32
|
-
seenPaths.add(match.path);
|
|
33
|
-
matches.push(match);
|
|
34
|
-
}
|
|
35
|
-
}
|
|
36
|
-
return matches;
|
|
37
|
-
}
|
|
38
|
-
function syncRegisteredRouteSnapshot() {
|
|
39
|
-
if (typeof window === "undefined") return;
|
|
40
|
-
const pathname = window.location.pathname || "/";
|
|
41
|
-
syncCurrentRouteSnapshot(pathname, window.location.search || "", window.location.hash || "", collectRouteActivityMatches(pathname));
|
|
42
|
-
}
|
|
43
|
-
function syncAppRegistrationLocation(app, pathname, href) {
|
|
44
|
-
app.pathname = pathname;
|
|
45
|
-
app.href = href;
|
|
46
|
-
}
|
|
47
|
-
const DEFAULT_SCROLL_RESTORATION = {
|
|
48
|
-
enabled: true,
|
|
49
|
-
navigation: "top",
|
|
50
|
-
history: "restore"
|
|
51
|
-
};
|
|
52
|
-
let scrollRestorationOptions = { ...DEFAULT_SCROLL_RESTORATION };
|
|
53
|
-
const scrollPositions = /* @__PURE__ */ new Map();
|
|
54
|
-
function getWindowHref() {
|
|
55
|
-
if (typeof window === "undefined") return currentHref;
|
|
56
|
-
return `${window.location.pathname}${window.location.search}${window.location.hash}`;
|
|
57
|
-
}
|
|
58
|
-
function normalizeScrollRestorationOptions(options) {
|
|
59
|
-
if (options === false) return {
|
|
60
|
-
enabled: false,
|
|
61
|
-
navigation: DEFAULT_SCROLL_RESTORATION.navigation,
|
|
62
|
-
history: DEFAULT_SCROLL_RESTORATION.history
|
|
63
|
-
};
|
|
64
|
-
if (options === true || options === void 0) return { ...DEFAULT_SCROLL_RESTORATION };
|
|
65
|
-
return {
|
|
66
|
-
enabled: true,
|
|
67
|
-
navigation: options.navigation ?? DEFAULT_SCROLL_RESTORATION.navigation,
|
|
68
|
-
history: options.history ?? DEFAULT_SCROLL_RESTORATION.history
|
|
69
|
-
};
|
|
70
|
-
}
|
|
71
|
-
function readScrollPosition() {
|
|
72
|
-
if (typeof window === "undefined") return {
|
|
73
|
-
x: 0,
|
|
74
|
-
y: 0
|
|
75
|
-
};
|
|
76
|
-
return {
|
|
77
|
-
x: typeof window.scrollX === "number" ? window.scrollX : typeof window.pageXOffset === "number" ? window.pageXOffset : 0,
|
|
78
|
-
y: typeof window.scrollY === "number" ? window.scrollY : typeof window.pageYOffset === "number" ? window.pageYOffset : 0
|
|
79
|
-
};
|
|
80
|
-
}
|
|
81
|
-
function writeHistoryScrollPosition(href, position) {
|
|
82
|
-
if (typeof window === "undefined" || getWindowHref() !== href) return;
|
|
83
|
-
if (typeof window.history?.replaceState !== "function") return;
|
|
84
|
-
const state = window.history.state && typeof window.history.state === "object" ? window.history.state : {};
|
|
85
|
-
window.history.replaceState({
|
|
86
|
-
...state,
|
|
87
|
-
path: href,
|
|
88
|
-
scroll: position
|
|
89
|
-
}, "", href);
|
|
90
|
-
}
|
|
91
|
-
function saveScrollPosition(href) {
|
|
92
|
-
if (!scrollRestorationOptions.enabled || typeof window === "undefined") return;
|
|
93
|
-
const position = readScrollPosition();
|
|
94
|
-
scrollPositions.set(href, position);
|
|
95
|
-
writeHistoryScrollPosition(href, position);
|
|
96
|
-
}
|
|
97
|
-
function scrollToPosition(position) {
|
|
98
|
-
if (typeof window === "undefined" || typeof window.scrollTo !== "function") return;
|
|
99
|
-
window.scrollTo(position.x, position.y);
|
|
100
|
-
}
|
|
101
|
-
function applyNavigationScroll(behavior) {
|
|
102
|
-
if (!scrollRestorationOptions.enabled || behavior === "preserve") return;
|
|
103
|
-
scrollToPosition({
|
|
104
|
-
x: 0,
|
|
105
|
-
y: 0
|
|
106
|
-
});
|
|
107
|
-
}
|
|
108
|
-
function applyHistoryScroll(href, state) {
|
|
109
|
-
if (!scrollRestorationOptions.enabled) return;
|
|
110
|
-
if (scrollRestorationOptions.history === "preserve") return;
|
|
111
|
-
if (scrollRestorationOptions.history === "top") {
|
|
112
|
-
scrollToPosition({
|
|
113
|
-
x: 0,
|
|
114
|
-
y: 0
|
|
115
|
-
});
|
|
116
|
-
return;
|
|
117
|
-
}
|
|
118
|
-
const fromState = state && typeof state === "object" && "scroll" in state ? state.scroll : void 0;
|
|
119
|
-
scrollToPosition((fromState && typeof fromState.x === "number" && typeof fromState.y === "number" ? {
|
|
120
|
-
x: fromState.x,
|
|
121
|
-
y: fromState.y
|
|
122
|
-
} : scrollPositions.get(href)) ?? {
|
|
123
|
-
x: 0,
|
|
124
|
-
y: 0
|
|
125
|
-
});
|
|
126
|
-
}
|
|
127
|
-
function configureScrollRestoration(options) {
|
|
128
|
-
scrollRestorationOptions = normalizeScrollRestorationOptions(options);
|
|
129
|
-
if (typeof window === "undefined") return;
|
|
130
|
-
if ("scrollRestoration" in window.history) try {
|
|
131
|
-
window.history.scrollRestoration = scrollRestorationOptions.enabled ? "manual" : "auto";
|
|
132
|
-
} catch {}
|
|
133
|
-
}
|
|
134
|
-
function parseTargetUrl(path) {
|
|
135
|
-
const pathname = window.location.pathname || "/";
|
|
136
|
-
const search = window.location.search || "";
|
|
137
|
-
const hash = window.location.hash || "";
|
|
138
|
-
const href = typeof window.location.href === "string" ? window.location.href : "";
|
|
139
|
-
const base = href && href !== "about:blank" && !href.startsWith("about:") && !href.startsWith("data:") ? href : `http://localhost${pathname}${search}${hash}`;
|
|
140
|
-
return new URL(path, base);
|
|
141
|
-
}
|
|
142
|
-
function isRenderResult(result) {
|
|
143
|
-
return result !== null && result.kind === "render";
|
|
144
|
-
}
|
|
145
|
-
function getRedirectHistoryMode(replace) {
|
|
146
|
-
return replace === false ? "push" : "replace";
|
|
147
|
-
}
|
|
148
|
-
function getNavigationHistoryMode(options) {
|
|
149
|
-
if (options.history) return options.history;
|
|
150
|
-
return options.replace ? "replace" : "push";
|
|
151
|
-
}
|
|
152
|
-
function beginRouteRequest() {
|
|
153
|
-
activeRouteRequestId += 1;
|
|
154
|
-
activeRouteRequestController?.abort();
|
|
155
|
-
activeRouteRequestController = new AbortController();
|
|
156
|
-
return {
|
|
157
|
-
id: activeRouteRequestId,
|
|
158
|
-
signal: activeRouteRequestController.signal
|
|
159
|
-
};
|
|
160
|
-
}
|
|
161
|
-
function isStaleRouteRequest(requestId) {
|
|
162
|
-
return requestId !== activeRouteRequestId;
|
|
163
|
-
}
|
|
164
|
-
function createDeniedResolvedRoute(status) {
|
|
165
|
-
return {
|
|
166
|
-
handler: () => ({
|
|
167
|
-
type: "div",
|
|
168
|
-
props: { "data-route-denied": String(status) },
|
|
169
|
-
children: [String(status)]
|
|
170
|
-
}),
|
|
171
|
-
params: {}
|
|
172
|
-
};
|
|
173
|
-
}
|
|
174
|
-
function bindResolvedRouteHandler(resolved) {
|
|
175
|
-
return () => resolved.handler(resolved.params);
|
|
176
|
-
}
|
|
177
|
-
function wrapRootRouteHandler(componentFn) {
|
|
178
|
-
const wrappedFn = (props, ctx) => {
|
|
179
|
-
const out = componentFn(props, ctx);
|
|
180
|
-
if (isPromiseLike(out)) throw new Error("Async components are not supported. Components must return synchronously.");
|
|
181
|
-
const portalVNode = {
|
|
182
|
-
$$typeof: ELEMENT_TYPE,
|
|
183
|
-
type: DefaultPortal,
|
|
184
|
-
props: {},
|
|
185
|
-
key: "__default_portal"
|
|
186
|
-
};
|
|
187
|
-
return {
|
|
188
|
-
$$typeof: ELEMENT_TYPE,
|
|
189
|
-
type: Fragment,
|
|
190
|
-
props: { children: out === void 0 || out === null ? [portalVNode] : [out, portalVNode] }
|
|
191
|
-
};
|
|
192
|
-
};
|
|
193
|
-
Object.defineProperty(wrappedFn, "name", { value: componentFn.name || "Component" });
|
|
194
|
-
return wrappedFn;
|
|
195
|
-
}
|
|
196
|
-
function cleanupRouteOwnership(instance) {
|
|
197
|
-
const cleanupErrors = [];
|
|
198
|
-
const children = instance.target ? Array.from(instance.target.childNodes) : [];
|
|
199
|
-
for (const child of children) try {
|
|
200
|
-
cleanupInstancesUnder(child, { strict: instance.cleanupStrict });
|
|
201
|
-
} catch (error) {
|
|
202
|
-
cleanupErrors.push(error);
|
|
203
|
-
}
|
|
204
|
-
try {
|
|
205
|
-
cleanupComponent(instance);
|
|
206
|
-
} catch (error) {
|
|
207
|
-
cleanupErrors.push(error);
|
|
208
|
-
}
|
|
209
|
-
if (cleanupErrors.length > 0) throw new AggregateError(cleanupErrors, "Route cleanup failed");
|
|
210
|
-
}
|
|
211
|
-
function remountResolvedRoute(instance, resolved, pathname, href) {
|
|
212
|
-
clearDefaultPortalForInstance(instance);
|
|
213
|
-
cleanupRouteOwnership(instance);
|
|
214
|
-
instance.fn = wrapRootRouteHandler(bindResolvedRouteHandler(resolved));
|
|
215
|
-
instance.props = {};
|
|
216
|
-
instance.stateValues = [];
|
|
217
|
-
instance.expectedStateIndices = [];
|
|
218
|
-
instance.firstRenderComplete = false;
|
|
219
|
-
instance.stateIndexCheck = -1;
|
|
220
|
-
instance.evaluationGeneration++;
|
|
221
|
-
instance.notifyUpdate = null;
|
|
222
|
-
instance.mountOperations = [];
|
|
223
|
-
instance.commitOperations = [];
|
|
224
|
-
instance.lifecycleSlots = [];
|
|
225
|
-
instance.cleanupFns = [];
|
|
226
|
-
instance._placeholder = void 0;
|
|
227
|
-
instance.hasPendingUpdate = false;
|
|
228
|
-
instance._currentRenderToken = void 0;
|
|
229
|
-
instance.lastRenderToken = 0;
|
|
230
|
-
instance._pendingReadSources = void 0;
|
|
231
|
-
instance._lastReadSources = void 0;
|
|
232
|
-
instance.abortController = null;
|
|
233
|
-
mountComponent(instance);
|
|
234
|
-
currentPathname = pathname;
|
|
235
|
-
currentHref = href;
|
|
236
|
-
return true;
|
|
237
|
-
}
|
|
238
|
-
function rerenderResolvedRoute(instance, pathname, href) {
|
|
239
|
-
currentPathname = pathname;
|
|
240
|
-
currentHref = href;
|
|
241
|
-
instance._enqueueRun?.();
|
|
242
|
-
return true;
|
|
243
|
-
}
|
|
244
|
-
function resolveAppRouteRequest(app, pathname, href, signal) {
|
|
245
|
-
if (app.routes) {
|
|
246
|
-
const resolved = resolveRouteFromRoutes(pathname, app.routes);
|
|
247
|
-
if (!resolved) return null;
|
|
248
|
-
return {
|
|
249
|
-
kind: "render",
|
|
250
|
-
handler: resolved.handler,
|
|
251
|
-
params: resolved.params
|
|
252
|
-
};
|
|
253
|
-
}
|
|
254
|
-
return resolveRouteRequest(href, {
|
|
255
|
-
manifest: app.manifest,
|
|
256
|
-
auth: app.auth,
|
|
257
|
-
signal
|
|
258
|
-
});
|
|
259
|
-
}
|
|
260
|
-
function resolveNavigationTargetsForApps(pathname, href, signal) {
|
|
261
|
-
const apps = [...registeredApps];
|
|
262
|
-
if (apps.length === 1) {
|
|
263
|
-
const app = apps[0];
|
|
264
|
-
const resolved = resolveAppRouteRequest(app, pathname, href, signal);
|
|
265
|
-
if (isPromiseLike(resolved)) return Promise.resolve(resolved).then((next) => [{
|
|
266
|
-
app,
|
|
267
|
-
resolved: next
|
|
268
|
-
}]);
|
|
269
|
-
return [{
|
|
270
|
-
app,
|
|
271
|
-
resolved
|
|
272
|
-
}];
|
|
273
|
-
}
|
|
274
|
-
const syncTargets = [];
|
|
275
|
-
const pendingTargets = [];
|
|
276
|
-
for (const app of apps) {
|
|
277
|
-
const resolved = resolveAppRouteRequest(app, pathname, href, signal);
|
|
278
|
-
if (isPromiseLike(resolved)) {
|
|
279
|
-
pendingTargets.push(Promise.resolve(resolved).then((next) => ({
|
|
280
|
-
app,
|
|
281
|
-
resolved: next
|
|
282
|
-
})));
|
|
283
|
-
continue;
|
|
284
|
-
}
|
|
285
|
-
syncTargets.push({
|
|
286
|
-
app,
|
|
287
|
-
resolved
|
|
288
|
-
});
|
|
289
|
-
}
|
|
290
|
-
if (pendingTargets.length === 0) return syncTargets;
|
|
291
|
-
return Promise.all([...syncTargets.map((target) => Promise.resolve(target)), ...pendingTargets]);
|
|
292
|
-
}
|
|
293
|
-
function applyNavigationTargets(path, options, redirectState, pathname, href, targets) {
|
|
294
|
-
const previousPathname = currentPathname;
|
|
295
|
-
for (const target of targets) {
|
|
296
|
-
const resolved = target.resolved;
|
|
297
|
-
if (!resolved || resolved.kind !== "redirect") continue;
|
|
298
|
-
const redirectTarget = parseTargetUrl(resolved.to);
|
|
299
|
-
const redirectHref = `${redirectTarget.pathname}${redirectTarget.search}${redirectTarget.hash}`;
|
|
300
|
-
if (redirectHref === href) {
|
|
301
|
-
if (isDevelopmentEnvironment()) logger.warn(`Navigation guard redirected to the same path: ${redirectHref}`);
|
|
302
|
-
return;
|
|
303
|
-
}
|
|
304
|
-
if (redirectState.visited.has(redirectHref)) throw new Error(`[Askr] Navigation redirect cycle detected at ${redirectHref}.`);
|
|
305
|
-
if (redirectState.redirects >= MAX_NAVIGATION_REDIRECTS) throw new Error(`[Askr] Navigation redirect limit exceeded (${MAX_NAVIGATION_REDIRECTS}).`);
|
|
306
|
-
redirectState.visited.add(redirectHref);
|
|
307
|
-
redirectState.redirects++;
|
|
308
|
-
navigateWithRedirectState(redirectHref, { history: getRedirectHistoryMode(resolved.replace) }, redirectState);
|
|
309
|
-
return;
|
|
310
|
-
}
|
|
311
|
-
const matchedTargets = targets.filter((target) => target.resolved !== null);
|
|
312
|
-
if (matchedTargets.length === 0) {
|
|
313
|
-
if (isDevelopmentEnvironment()) logger.warn(`No route found for path: ${path}`);
|
|
314
|
-
return;
|
|
315
|
-
}
|
|
316
|
-
saveScrollPosition(currentHref);
|
|
317
|
-
const historyMethod = getNavigationHistoryMode(options) === "replace" ? "replaceState" : "pushState";
|
|
318
|
-
window.history[historyMethod]({ path: href }, "", href);
|
|
319
|
-
syncRegisteredRouteSnapshot();
|
|
320
|
-
for (const target of matchedTargets) {
|
|
321
|
-
const resolved = target.resolved;
|
|
322
|
-
if (resolved.kind === "redirect") continue;
|
|
323
|
-
if (pathname === target.app.pathname && isRenderResult(resolved)) {
|
|
324
|
-
rerenderResolvedRoute(target.app.instance, pathname, href);
|
|
325
|
-
syncAppRegistrationLocation(target.app, pathname, href);
|
|
326
|
-
continue;
|
|
327
|
-
}
|
|
328
|
-
remountResolvedRoute(target.app.instance, resolved.kind === "deny" ? createDeniedResolvedRoute(resolved.status) : {
|
|
329
|
-
handler: resolved.handler,
|
|
330
|
-
params: resolved.params
|
|
331
|
-
}, pathname, href);
|
|
332
|
-
syncAppRegistrationLocation(target.app, pathname, href);
|
|
333
|
-
}
|
|
334
|
-
if (pathname !== previousPathname) applyNavigationScroll(options.scroll ?? scrollRestorationOptions.navigation);
|
|
335
|
-
}
|
|
336
|
-
/** Register the current app instance (called by createSPA/hydrateSPA). */
|
|
337
|
-
function registerAppInstance(instance, path, source = {}) {
|
|
338
|
-
const existingIndex = registeredApps.findIndex((app) => app.instance === instance);
|
|
339
|
-
const registration = {
|
|
340
|
-
instance,
|
|
341
|
-
pathname: path,
|
|
342
|
-
href: getWindowHref(),
|
|
343
|
-
...source
|
|
344
|
-
};
|
|
345
|
-
if (existingIndex >= 0) registeredApps[existingIndex] = registration;
|
|
346
|
-
else registeredApps.push(registration);
|
|
347
|
-
currentInstance = instance;
|
|
348
|
-
currentPathname = path;
|
|
349
|
-
currentHref = getWindowHref();
|
|
350
|
-
syncRegisteredRouteSnapshot();
|
|
351
|
-
if (isProductionEnvironment()) lockRouteRegistration();
|
|
352
|
-
}
|
|
353
|
-
function unregisterAppInstance(instance) {
|
|
354
|
-
const existingIndex = registeredApps.findIndex((app) => app.instance === instance);
|
|
355
|
-
if (existingIndex >= 0) registeredApps.splice(existingIndex, 1);
|
|
356
|
-
syncRegisteredRouteSnapshot();
|
|
357
|
-
if (currentInstance !== instance) return;
|
|
358
|
-
const nextApp = registeredApps.length > 0 ? registeredApps[registeredApps.length - 1] : null;
|
|
359
|
-
currentInstance = nextApp?.instance ?? null;
|
|
360
|
-
if (nextApp) {
|
|
361
|
-
currentPathname = nextApp.pathname;
|
|
362
|
-
currentHref = nextApp.href;
|
|
363
|
-
syncRegisteredRouteSnapshot();
|
|
364
|
-
return;
|
|
365
|
-
}
|
|
366
|
-
activeRouteRequestId += 1;
|
|
367
|
-
activeRouteRequestController?.abort();
|
|
368
|
-
activeRouteRequestController = null;
|
|
369
|
-
currentPathname = "/";
|
|
370
|
-
currentHref = "/";
|
|
371
|
-
if (typeof window === "undefined") syncCurrentRouteSnapshot("/", "", "", []);
|
|
372
|
-
}
|
|
373
|
-
/**
|
|
374
|
-
* Navigate to a new path
|
|
375
|
-
* Updates URL, resolves route, and re-mounts app with new handler
|
|
376
|
-
*/
|
|
12
|
+
configureNavigationRegistryHost({ cancelRouteRequests });
|
|
377
13
|
function navigate(path, options = {}) {
|
|
378
14
|
if (typeof window === "undefined") return;
|
|
379
15
|
const initialTarget = parseTargetUrl(path);
|
|
380
16
|
navigateWithRedirectState(path, options, {
|
|
381
17
|
redirects: 0,
|
|
382
|
-
visited: new Set([`${initialTarget.pathname}${initialTarget.search}${initialTarget.hash}`])
|
|
18
|
+
visited: /* @__PURE__ */ new Set([`${initialTarget.pathname}${initialTarget.search}${initialTarget.hash}`])
|
|
383
19
|
});
|
|
384
20
|
}
|
|
385
21
|
function navigateWithRedirectState(path, options, redirectState) {
|
|
@@ -393,7 +29,7 @@ function navigateWithRedirectState(path, options, redirectState) {
|
|
|
393
29
|
Promise.resolve(resolvedTargets).then((targets) => {
|
|
394
30
|
if (isStaleRouteRequest(request.id)) return;
|
|
395
31
|
try {
|
|
396
|
-
applyNavigationTargets(path, options, redirectState, pathname, href, targets);
|
|
32
|
+
applyNavigationTargets(path, options, redirectState, pathname, href, targets, navigateWithRedirectState);
|
|
397
33
|
} catch (error) {
|
|
398
34
|
logger.error("[Askr] navigation failed:", error);
|
|
399
35
|
}
|
|
@@ -402,56 +38,26 @@ function navigateWithRedirectState(path, options, redirectState) {
|
|
|
402
38
|
});
|
|
403
39
|
return;
|
|
404
40
|
}
|
|
405
|
-
applyNavigationTargets(path, options, redirectState, pathname, href, resolvedTargets);
|
|
41
|
+
applyNavigationTargets(path, options, redirectState, pathname, href, resolvedTargets, navigateWithRedirectState);
|
|
406
42
|
}
|
|
407
|
-
|
|
408
|
-
* Handle browser back/forward buttons
|
|
409
|
-
*/
|
|
410
|
-
function handlePopState(_event) {
|
|
43
|
+
function handlePopState(event) {
|
|
411
44
|
const request = beginRouteRequest();
|
|
412
|
-
const previousHref =
|
|
45
|
+
const previousHref = getCurrentHref();
|
|
413
46
|
const pathname = window.location.pathname;
|
|
414
47
|
const href = `${window.location.pathname}${window.location.search}${window.location.hash}`;
|
|
415
48
|
saveScrollPosition(previousHref);
|
|
416
|
-
if (
|
|
49
|
+
if (!hasRegisteredApps()) return;
|
|
417
50
|
const applyResolved = (targets) => {
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
return;
|
|
423
|
-
}
|
|
424
|
-
for (const target of matchedTargets) {
|
|
425
|
-
const resolved = target.resolved;
|
|
426
|
-
if (resolved.kind !== "redirect") continue;
|
|
427
|
-
navigate(resolved.to, { history: getRedirectHistoryMode(resolved.replace) });
|
|
428
|
-
return;
|
|
429
|
-
}
|
|
430
|
-
syncRegisteredRouteSnapshot();
|
|
431
|
-
for (const target of matchedTargets) {
|
|
432
|
-
const resolved = target.resolved;
|
|
433
|
-
if (pathname === target.app.pathname && isRenderResult(resolved)) {
|
|
434
|
-
rerenderResolvedRoute(target.app.instance, pathname, href);
|
|
435
|
-
syncAppRegistrationLocation(target.app, pathname, href);
|
|
436
|
-
continue;
|
|
437
|
-
}
|
|
438
|
-
if (resolved.kind === "redirect") continue;
|
|
439
|
-
remountResolvedRoute(target.app.instance, resolved.kind === "deny" ? createDeniedResolvedRoute(resolved.status) : {
|
|
440
|
-
handler: resolved.handler,
|
|
441
|
-
params: resolved.params
|
|
442
|
-
}, pathname, href);
|
|
443
|
-
syncAppRegistrationLocation(target.app, pathname, href);
|
|
51
|
+
try {
|
|
52
|
+
applyPopStateNavigationTargets(request.id, pathname, href, event.state, targets, navigate);
|
|
53
|
+
} catch (error) {
|
|
54
|
+
logger.error("[Askr] popstate navigation failed:", error);
|
|
444
55
|
}
|
|
445
|
-
applyHistoryScroll(href, _event.state);
|
|
446
56
|
};
|
|
447
57
|
const resolvedTargets = resolveNavigationTargetsForApps(pathname, href, request.signal);
|
|
448
58
|
if (isPromiseLike(resolvedTargets)) {
|
|
449
59
|
Promise.resolve(resolvedTargets).then((next) => {
|
|
450
|
-
|
|
451
|
-
applyResolved(next);
|
|
452
|
-
} catch (error) {
|
|
453
|
-
logger.error("[Askr] popstate navigation failed:", error);
|
|
454
|
-
}
|
|
60
|
+
applyResolved(next);
|
|
455
61
|
}, (error) => {
|
|
456
62
|
logger.error("[Askr] popstate navigation failed:", error);
|
|
457
63
|
});
|
|
@@ -459,15 +65,12 @@ function handlePopState(_event) {
|
|
|
459
65
|
}
|
|
460
66
|
applyResolved(resolvedTargets);
|
|
461
67
|
}
|
|
462
|
-
/**
|
|
463
|
-
* Setup popstate listener for browser navigation
|
|
464
|
-
*/
|
|
465
68
|
function initializeNavigation() {
|
|
466
69
|
if (typeof window === "undefined" || navigationInitialized) return;
|
|
467
70
|
navigationInitialized = true;
|
|
468
71
|
window.addEventListener("popstate", handlePopState);
|
|
469
72
|
}
|
|
470
73
|
//#endregion
|
|
471
|
-
export { configureScrollRestoration, initializeNavigation, navigate, registerAppInstance, unregisterAppInstance };
|
|
74
|
+
export { configureScrollRestoration, initializeNavigation, navigate, registerAppInstance, unregisterAppInstance, updateRouteQuery };
|
|
472
75
|
|
|
473
76
|
//# sourceMappingURL=navigate.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"navigate.js","names":[],"sources":["../../src/router/navigate.ts"],"sourcesContent":["/**\n * Client-side navigation with History API\n */\n\nimport {\n computeRouteActivityMatches,\n resolveRouteRequest,\n resolveRouteFromRoutes,\n lockRouteRegistration,\n syncCurrentRouteSnapshot,\n type ResolvedRoute,\n} from './route';\nimport {\n cleanupComponent,\n mountComponent,\n type ComponentInstance,\n} from '../runtime/component';\nimport {\n isDevelopmentEnvironment,\n isProductionEnvironment,\n} from '../common/env';\nimport { logger } from '../dev/logger';\nimport type {\n Route,\n RouteAuthOptions,\n RouteManifest,\n RouteRenderResult,\n RouteRequestResult,\n} from '../common/router';\nimport { Fragment, ELEMENT_TYPE } from '../jsx';\nimport {\n DefaultPortal,\n clearDefaultPortalForInstance,\n} from '../foundations/structures/portal';\nimport { isPromiseLike } from '../common/promise';\nimport { cleanupInstancesUnder } from '../renderer/cleanup';\n\n// Global app state for navigation\nlet currentInstance: ComponentInstance | null = null;\nlet currentPathname = '/';\nlet currentHref = '/';\nlet navigationInitialized = false;\nlet activeRouteRequestId = 0;\nlet activeRouteRequestController: AbortController | null = null;\nconst MAX_NAVIGATION_REDIRECTS = 20;\n\ntype AppNavigationSource = {\n manifest?: RouteManifest;\n routes?: readonly Route[];\n auth?: RouteAuthOptions;\n};\n\ntype AppRegistration = AppNavigationSource & {\n instance: ComponentInstance;\n pathname: string;\n href: string;\n};\n\nconst registeredApps: AppRegistration[] = [];\n\nfunction collectRouteActivityMatches(\n pathname: string,\n apps: readonly AppRegistration[] = registeredApps\n) {\n const matches: ReturnType<typeof computeRouteActivityMatches> = [];\n const seenPaths = new Set<string>();\n\n for (const app of apps) {\n const appMatches = computeRouteActivityMatches(pathname, {\n manifest: app.manifest,\n routes: app.routes,\n });\n\n for (const match of appMatches) {\n if (seenPaths.has(match.path)) {\n continue;\n }\n seenPaths.add(match.path);\n matches.push(match);\n }\n }\n\n return matches;\n}\n\nfunction syncRegisteredRouteSnapshot(): void {\n if (typeof window === 'undefined') {\n return;\n }\n\n const pathname = window.location.pathname || '/';\n syncCurrentRouteSnapshot(\n pathname,\n window.location.search || '',\n window.location.hash || '',\n collectRouteActivityMatches(pathname)\n );\n}\n\nfunction syncAppRegistrationLocation(\n app: AppRegistration,\n pathname: string,\n href: string\n): void {\n app.pathname = pathname;\n app.href = href;\n}\n\nexport type NavigationScrollBehavior = 'top' | 'preserve';\nexport type HistoryScrollBehavior = 'restore' | 'top' | 'preserve';\n\nexport type ScrollRestorationOptions = {\n navigation?: NavigationScrollBehavior;\n history?: HistoryScrollBehavior;\n};\n\ntype NormalizedScrollRestorationOptions = {\n enabled: boolean;\n navigation: NavigationScrollBehavior;\n history: HistoryScrollBehavior;\n};\n\nconst DEFAULT_SCROLL_RESTORATION: NormalizedScrollRestorationOptions = {\n enabled: true,\n navigation: 'top',\n history: 'restore',\n};\n\nlet scrollRestorationOptions: NormalizedScrollRestorationOptions = {\n ...DEFAULT_SCROLL_RESTORATION,\n};\n\nconst scrollPositions = new Map<string, { x: number; y: number }>();\n\nexport type NavigateOptions = {\n history?: 'push' | 'replace';\n replace?: boolean;\n scroll?: NavigationScrollBehavior;\n};\n\nfunction getWindowHref(): string {\n if (typeof window === 'undefined') {\n return currentHref;\n }\n\n return `${window.location.pathname}${window.location.search}${window.location.hash}`;\n}\n\nfunction normalizeScrollRestorationOptions(\n options?: boolean | ScrollRestorationOptions\n): NormalizedScrollRestorationOptions {\n if (options === false) {\n return {\n enabled: false,\n navigation: DEFAULT_SCROLL_RESTORATION.navigation,\n history: DEFAULT_SCROLL_RESTORATION.history,\n };\n }\n\n if (options === true || options === undefined) {\n return { ...DEFAULT_SCROLL_RESTORATION };\n }\n\n return {\n enabled: true,\n navigation: options.navigation ?? DEFAULT_SCROLL_RESTORATION.navigation,\n history: options.history ?? DEFAULT_SCROLL_RESTORATION.history,\n };\n}\n\nfunction readScrollPosition(): { x: number; y: number } {\n if (typeof window === 'undefined') {\n return { x: 0, y: 0 };\n }\n\n const x =\n typeof window.scrollX === 'number'\n ? window.scrollX\n : typeof window.pageXOffset === 'number'\n ? window.pageXOffset\n : 0;\n const y =\n typeof window.scrollY === 'number'\n ? window.scrollY\n : typeof window.pageYOffset === 'number'\n ? window.pageYOffset\n : 0;\n\n return { x, y };\n}\n\nfunction writeHistoryScrollPosition(\n href: string,\n position: { x: number; y: number }\n): void {\n if (typeof window === 'undefined' || getWindowHref() !== href) {\n return;\n }\n if (typeof window.history?.replaceState !== 'function') {\n return;\n }\n const state =\n window.history.state && typeof window.history.state === 'object'\n ? window.history.state\n : {};\n\n window.history.replaceState(\n {\n ...state,\n path: href,\n scroll: position,\n },\n '',\n href\n );\n}\n\nfunction saveScrollPosition(href: string): void {\n if (!scrollRestorationOptions.enabled || typeof window === 'undefined') {\n return;\n }\n\n const position = readScrollPosition();\n scrollPositions.set(href, position);\n writeHistoryScrollPosition(href, position);\n}\n\nfunction scrollToPosition(position: { x: number; y: number }): void {\n if (typeof window === 'undefined' || typeof window.scrollTo !== 'function') {\n return;\n }\n\n window.scrollTo(position.x, position.y);\n}\n\nfunction applyNavigationScroll(behavior: NavigationScrollBehavior): void {\n if (!scrollRestorationOptions.enabled || behavior === 'preserve') {\n return;\n }\n\n scrollToPosition({ x: 0, y: 0 });\n}\n\nfunction applyHistoryScroll(href: string, state: PopStateEvent['state']): void {\n if (!scrollRestorationOptions.enabled) {\n return;\n }\n\n if (scrollRestorationOptions.history === 'preserve') {\n return;\n }\n\n if (scrollRestorationOptions.history === 'top') {\n scrollToPosition({ x: 0, y: 0 });\n return;\n }\n\n const fromState =\n state && typeof state === 'object' && 'scroll' in state\n ? (state.scroll as { x?: unknown; y?: unknown })\n : undefined;\n const saved =\n fromState &&\n typeof fromState.x === 'number' &&\n typeof fromState.y === 'number'\n ? { x: fromState.x, y: fromState.y }\n : scrollPositions.get(href);\n\n scrollToPosition(saved ?? { x: 0, y: 0 });\n}\n\nexport function configureScrollRestoration(\n options?: boolean | ScrollRestorationOptions\n): void {\n scrollRestorationOptions = normalizeScrollRestorationOptions(options);\n\n if (typeof window === 'undefined') {\n return;\n }\n\n if ('scrollRestoration' in window.history) {\n try {\n window.history.scrollRestoration = scrollRestorationOptions.enabled\n ? 'manual'\n : 'auto';\n } catch {\n // Ignore environments that expose but do not allow setting scrollRestoration.\n }\n }\n}\n\nfunction parseTargetUrl(path: string): URL {\n const pathname = window.location.pathname || '/';\n const search = window.location.search || '';\n const hash = window.location.hash || '';\n const href =\n typeof window.location.href === 'string' ? window.location.href : '';\n const base =\n href &&\n href !== 'about:blank' &&\n !href.startsWith('about:') &&\n !href.startsWith('data:')\n ? href\n : `http://localhost${pathname}${search}${hash}`;\n\n return new URL(path, base);\n}\n\nfunction isRenderResult(\n result: RouteRequestResult\n): result is RouteRenderResult {\n return result !== null && result.kind === 'render';\n}\n\nfunction getRedirectHistoryMode(\n replace: boolean | undefined\n): 'push' | 'replace' {\n return replace === false ? 'push' : 'replace';\n}\n\nfunction getNavigationHistoryMode(\n options: NavigateOptions\n): 'push' | 'replace' {\n if (options.history) {\n return options.history;\n }\n\n return options.replace ? 'replace' : 'push';\n}\n\nfunction beginRouteRequest(): { id: number; signal: AbortSignal } {\n activeRouteRequestId += 1;\n activeRouteRequestController?.abort();\n activeRouteRequestController = new AbortController();\n\n return {\n id: activeRouteRequestId,\n signal: activeRouteRequestController.signal,\n };\n}\n\nfunction isStaleRouteRequest(requestId: number): boolean {\n return requestId !== activeRouteRequestId;\n}\n\nfunction createDeniedResolvedRoute(status: number): ResolvedRoute {\n return {\n handler: () => ({\n type: 'div',\n props: {\n 'data-route-denied': String(status),\n },\n children: [String(status)],\n }),\n params: {},\n };\n}\n\nfunction bindResolvedRouteHandler(\n resolved: ResolvedRoute\n): ComponentInstance['fn'] {\n return () =>\n resolved.handler(resolved.params) as ReturnType<ComponentInstance['fn']>;\n}\n\nfunction wrapRootRouteHandler(\n componentFn: ComponentInstance['fn']\n): ComponentInstance['fn'] {\n const wrappedFn: ComponentInstance['fn'] = (props, ctx) => {\n const out = componentFn(props, ctx);\n if (isPromiseLike(out)) {\n throw new Error(\n 'Async components are not supported. Components must return synchronously.'\n );\n }\n const portalVNode = {\n $$typeof: ELEMENT_TYPE,\n type: DefaultPortal,\n props: {},\n key: '__default_portal',\n } as unknown;\n\n return {\n $$typeof: ELEMENT_TYPE,\n type: Fragment,\n props: {\n children:\n out === undefined || out === null\n ? [portalVNode]\n : [out, portalVNode],\n },\n } as ReturnType<ComponentInstance['fn']>;\n };\n\n Object.defineProperty(wrappedFn, 'name', {\n value: componentFn.name || 'Component',\n });\n\n return wrappedFn;\n}\n\nfunction cleanupRouteOwnership(instance: ComponentInstance): void {\n const cleanupErrors: unknown[] = [];\n const children = instance.target\n ? Array.from(instance.target.childNodes)\n : [];\n\n for (const child of children) {\n try {\n cleanupInstancesUnder(child, { strict: instance.cleanupStrict });\n } catch (error) {\n cleanupErrors.push(error);\n }\n }\n\n try {\n cleanupComponent(instance);\n } catch (error) {\n cleanupErrors.push(error);\n }\n\n if (cleanupErrors.length > 0) {\n throw new AggregateError(cleanupErrors, 'Route cleanup failed');\n }\n}\n\nfunction remountResolvedRoute(\n instance: ComponentInstance,\n resolved: ResolvedRoute,\n pathname: string,\n href: string\n): boolean {\n // The route handler IS the component function\n // It takes params as props and renders the route\n clearDefaultPortalForInstance(instance);\n cleanupRouteOwnership(instance);\n\n instance.fn = wrapRootRouteHandler(bindResolvedRouteHandler(resolved));\n instance.props = {};\n\n // Reset state to prevent leakage from previous route\n // Each route navigation starts completely fresh\n instance.stateValues = [];\n instance.expectedStateIndices = [];\n instance.firstRenderComplete = false;\n instance.stateIndexCheck = -1;\n // Increment generation to invalidate pending async evaluations from previous route\n instance.evaluationGeneration++;\n instance.notifyUpdate = null;\n instance.mountOperations = [];\n instance.commitOperations = [];\n instance.lifecycleSlots = [];\n instance.cleanupFns = [];\n instance._placeholder = undefined;\n instance.hasPendingUpdate = false;\n instance._currentRenderToken = undefined;\n instance.lastRenderToken = 0;\n instance._pendingReadSources = undefined;\n instance._lastReadSources = undefined;\n\n // Route-local async work should create a fresh abort controller lazily.\n instance.abortController = null;\n\n // Re-execute component against the existing host so reconciliation can\n // preserve any shared layout DOM between sibling routes.\n mountComponent(instance);\n currentPathname = pathname;\n currentHref = href;\n return true;\n}\n\nfunction rerenderResolvedRoute(\n instance: ComponentInstance,\n pathname: string,\n href: string\n): boolean {\n currentPathname = pathname;\n currentHref = href;\n instance._enqueueRun?.();\n return true;\n}\n\nfunction resolveAppRouteRequest(\n app: AppRegistration,\n pathname: string,\n href: string,\n signal: AbortSignal\n): RouteRequestResult | Promise<RouteRequestResult> {\n if (app.routes) {\n const resolved = resolveRouteFromRoutes(pathname, app.routes);\n if (!resolved) {\n return null;\n }\n\n return {\n kind: 'render',\n handler: resolved.handler,\n params: resolved.params,\n };\n }\n\n return resolveRouteRequest(href, {\n manifest: app.manifest,\n auth: app.auth,\n signal,\n });\n}\n\ntype AppNavigationTarget = {\n app: AppRegistration;\n resolved: RouteRequestResult;\n};\n\nfunction resolveNavigationTargetsForApps(\n pathname: string,\n href: string,\n signal: AbortSignal\n): AppNavigationTarget[] | Promise<AppNavigationTarget[]> {\n const apps = [...registeredApps];\n\n if (apps.length === 1) {\n const app = apps[0]!;\n const resolved = resolveAppRouteRequest(app, pathname, href, signal);\n if (isPromiseLike<RouteRequestResult>(resolved)) {\n return Promise.resolve(resolved).then((next) => [\n {\n app,\n resolved: next,\n },\n ]);\n }\n\n return [\n {\n app,\n resolved,\n },\n ];\n }\n\n const syncTargets: AppNavigationTarget[] = [];\n const pendingTargets: Array<Promise<AppNavigationTarget>> = [];\n\n for (const app of apps) {\n const resolved = resolveAppRouteRequest(app, pathname, href, signal);\n if (isPromiseLike<RouteRequestResult>(resolved)) {\n pendingTargets.push(\n Promise.resolve(resolved).then((next) => ({ app, resolved: next }))\n );\n continue;\n }\n\n syncTargets.push({ app, resolved });\n }\n\n if (pendingTargets.length === 0) {\n return syncTargets;\n }\n\n return Promise.all([\n ...syncTargets.map((target) => Promise.resolve(target)),\n ...pendingTargets,\n ]);\n}\n\nfunction applyNavigationTargets(\n path: string,\n options: NavigateOptions,\n redirectState: NavigationRedirectState,\n pathname: string,\n href: string,\n targets: AppNavigationTarget[]\n): void {\n const previousPathname = currentPathname;\n\n for (const target of targets) {\n const resolved = target.resolved;\n if (!resolved || resolved.kind !== 'redirect') {\n continue;\n }\n\n const redirectTarget = parseTargetUrl(resolved.to);\n const redirectHref = `${redirectTarget.pathname}${redirectTarget.search}${redirectTarget.hash}`;\n if (redirectHref === href) {\n if (isDevelopmentEnvironment()) {\n logger.warn(\n `Navigation guard redirected to the same path: ${redirectHref}`\n );\n }\n return;\n }\n\n if (redirectState.visited.has(redirectHref)) {\n throw new Error(\n `[Askr] Navigation redirect cycle detected at ${redirectHref}.`\n );\n }\n if (redirectState.redirects >= MAX_NAVIGATION_REDIRECTS) {\n throw new Error(\n `[Askr] Navigation redirect limit exceeded (${MAX_NAVIGATION_REDIRECTS}).`\n );\n }\n\n redirectState.visited.add(redirectHref);\n redirectState.redirects++;\n navigateWithRedirectState(\n redirectHref,\n {\n history: getRedirectHistoryMode(resolved.replace),\n },\n redirectState\n );\n return;\n }\n\n const matchedTargets = targets.filter((target) => target.resolved !== null);\n if (matchedTargets.length === 0) {\n if (isDevelopmentEnvironment()) {\n logger.warn(`No route found for path: ${path}`);\n }\n return;\n }\n\n saveScrollPosition(currentHref);\n\n const historyMethod =\n getNavigationHistoryMode(options) === 'replace'\n ? 'replaceState'\n : 'pushState';\n window.history[historyMethod]({ path: href }, '', href);\n syncRegisteredRouteSnapshot();\n\n for (const target of matchedTargets) {\n const resolved = target.resolved!;\n if (resolved.kind === 'redirect') {\n continue;\n }\n\n if (pathname === target.app.pathname && isRenderResult(resolved)) {\n rerenderResolvedRoute(target.app.instance, pathname, href);\n syncAppRegistrationLocation(target.app, pathname, href);\n continue;\n }\n\n remountResolvedRoute(\n target.app.instance,\n resolved.kind === 'deny'\n ? createDeniedResolvedRoute(resolved.status)\n : {\n handler: resolved.handler,\n params: resolved.params,\n },\n pathname,\n href\n );\n syncAppRegistrationLocation(target.app, pathname, href);\n }\n\n if (pathname !== previousPathname) {\n applyNavigationScroll(\n options.scroll ?? scrollRestorationOptions.navigation\n );\n }\n}\n\n/** Register the current app instance (called by createSPA/hydrateSPA). */\nexport function registerAppInstance(\n instance: ComponentInstance,\n path: string,\n source: AppNavigationSource = {}\n): void {\n const existingIndex = registeredApps.findIndex(\n (app) => app.instance === instance\n );\n const registration: AppRegistration = {\n instance,\n pathname: path,\n href: getWindowHref(),\n ...source,\n };\n if (existingIndex >= 0) {\n registeredApps[existingIndex] = registration;\n } else {\n registeredApps.push(registration);\n }\n\n currentInstance = instance;\n currentPathname = path;\n currentHref = getWindowHref();\n syncRegisteredRouteSnapshot();\n // Lock further route registrations after the app has started — but allow tests to register routes.\n // Enforce only in production to avoid breaking test infra which registers routes dynamically.\n if (isProductionEnvironment()) {\n lockRouteRegistration();\n }\n}\n\nexport function unregisterAppInstance(instance: ComponentInstance): void {\n const existingIndex = registeredApps.findIndex(\n (app) => app.instance === instance\n );\n if (existingIndex >= 0) {\n registeredApps.splice(existingIndex, 1);\n }\n syncRegisteredRouteSnapshot();\n\n if (currentInstance !== instance) {\n return;\n }\n\n const nextApp =\n registeredApps.length > 0\n ? registeredApps[registeredApps.length - 1]!\n : null;\n currentInstance = nextApp?.instance ?? null;\n if (nextApp) {\n currentPathname = nextApp.pathname;\n currentHref = nextApp.href;\n syncRegisteredRouteSnapshot();\n return;\n }\n\n activeRouteRequestId += 1;\n activeRouteRequestController?.abort();\n activeRouteRequestController = null;\n currentPathname = '/';\n currentHref = '/';\n if (typeof window === 'undefined') {\n syncCurrentRouteSnapshot('/', '', '', []);\n }\n}\n\n/**\n * Navigate to a new path\n * Updates URL, resolves route, and re-mounts app with new handler\n */\nexport function navigate(path: string, options: NavigateOptions = {}): void {\n if (typeof window === 'undefined') {\n return;\n }\n\n const initialTarget = parseTargetUrl(path);\n navigateWithRedirectState(path, options, {\n redirects: 0,\n visited: new Set([\n `${initialTarget.pathname}${initialTarget.search}${initialTarget.hash}`,\n ]),\n });\n}\n\ntype NavigationRedirectState = {\n redirects: number;\n visited: Set<string>;\n};\n\nfunction navigateWithRedirectState(\n path: string,\n options: NavigateOptions,\n redirectState: NavigationRedirectState\n): void {\n if (typeof window === 'undefined') {\n // SSR context\n return;\n }\n\n const request = beginRouteRequest();\n\n const target = parseTargetUrl(path);\n const pathname = target.pathname;\n const href = `${target.pathname}${target.search}${target.hash}`;\n const resolvedTargets = resolveNavigationTargetsForApps(\n pathname,\n href,\n request.signal\n );\n\n if (isPromiseLike(resolvedTargets)) {\n void Promise.resolve(resolvedTargets).then(\n (targets) => {\n if (isStaleRouteRequest(request.id)) {\n return;\n }\n\n try {\n applyNavigationTargets(\n path,\n options,\n redirectState,\n pathname,\n href,\n targets\n );\n } catch (error) {\n logger.error('[Askr] navigation failed:', error);\n }\n },\n (error) => {\n logger.error('[Askr] navigation failed:', error);\n }\n );\n return;\n }\n\n applyNavigationTargets(\n path,\n options,\n redirectState,\n pathname,\n href,\n resolvedTargets\n );\n}\n\n/**\n * Handle browser back/forward buttons\n */\nfunction handlePopState(_event: PopStateEvent): void {\n const request = beginRouteRequest();\n const previousHref = currentHref;\n const pathname = window.location.pathname;\n const href = `${window.location.pathname}${window.location.search}${window.location.hash}`;\n\n saveScrollPosition(previousHref);\n\n if (registeredApps.length === 0) {\n return;\n }\n\n const applyResolved = (targets: AppNavigationTarget[]) => {\n if (isStaleRouteRequest(request.id)) {\n return;\n }\n\n const matchedTargets = targets.filter((target) => target.resolved !== null);\n if (matchedTargets.length === 0) {\n if (isDevelopmentEnvironment()) {\n logger.warn(`No route found for path: ${pathname}`);\n }\n return;\n }\n\n for (const target of matchedTargets) {\n const resolved = target.resolved!;\n if (resolved.kind !== 'redirect') {\n continue;\n }\n\n navigate(resolved.to, {\n history: getRedirectHistoryMode(resolved.replace),\n });\n return;\n }\n\n syncRegisteredRouteSnapshot();\n\n for (const target of matchedTargets) {\n const resolved = target.resolved!;\n if (pathname === target.app.pathname && isRenderResult(resolved)) {\n rerenderResolvedRoute(target.app.instance, pathname, href);\n syncAppRegistrationLocation(target.app, pathname, href);\n continue;\n }\n\n if (resolved.kind === 'redirect') {\n continue;\n }\n\n remountResolvedRoute(\n target.app.instance,\n resolved.kind === 'deny'\n ? createDeniedResolvedRoute(resolved.status)\n : {\n handler: resolved.handler,\n params: resolved.params,\n },\n pathname,\n href\n );\n syncAppRegistrationLocation(target.app, pathname, href);\n }\n\n applyHistoryScroll(href, _event.state);\n };\n\n const resolvedTargets = resolveNavigationTargetsForApps(\n pathname,\n href,\n request.signal\n );\n\n if (isPromiseLike<AppNavigationTarget[]>(resolvedTargets)) {\n void Promise.resolve(resolvedTargets).then(\n (next) => {\n try {\n applyResolved(next);\n } catch (error) {\n logger.error('[Askr] popstate navigation failed:', error);\n }\n },\n (error) => {\n logger.error('[Askr] popstate navigation failed:', error);\n }\n );\n return;\n }\n\n applyResolved(resolvedTargets);\n}\n\n/**\n * Setup popstate listener for browser navigation\n */\nexport function initializeNavigation(): void {\n if (typeof window === 'undefined' || navigationInitialized) {\n return;\n }\n\n navigationInitialized = true;\n window.addEventListener('popstate', handlePopState);\n}\n\n/**\n * Cleanup navigation listeners\n */\nexport function cleanupNavigation(): void {\n activeRouteRequestId += 1;\n activeRouteRequestController?.abort();\n activeRouteRequestController = null;\n\n if (typeof window === 'undefined' || !navigationInitialized) {\n return;\n }\n\n navigationInitialized = false;\n window.removeEventListener('popstate', handlePopState);\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"navigate.js","names":[],"sources":["../../src/router/navigate.ts"],"sourcesContent":["/**\n * Client-side navigation with History API\n */\n\nimport { isPromiseLike } from '../common/promise';\nimport { logger } from '../dev/logger';\nimport { saveScrollPosition } from './navigation-scroll';\nimport {\n configureNavigationRegistryHost,\n getCurrentHref,\n hasRegisteredApps,\n parseTargetUrl,\n} from './navigation-registry';\nimport {\n applyNavigationTargets,\n applyPopStateNavigationTargets,\n beginRouteRequest,\n cancelRouteRequests,\n isStaleRouteRequest,\n resolveNavigationTargetsForApps,\n type AppNavigationTarget,\n type NavigateOptions,\n type NavigationRedirectState,\n} from './navigation-targets';\n\nexport { configureScrollRestoration } from './navigation-scroll';\nexport type {\n HistoryScrollBehavior,\n NavigationScrollBehavior,\n ScrollRestorationOptions,\n} from './navigation-scroll';\nexport {\n registerAppInstance,\n unregisterAppInstance,\n} from './navigation-registry';\nexport { updateRouteQuery } from './route-query';\nexport type {\n RouteQueryParamInput,\n RouteQueryParamValue,\n RouteQueryUpdater,\n RouteQueryUpdates,\n UpdateRouteQueryOptions,\n} from './route-query';\nexport type { NavigateOptions };\n\nlet navigationInitialized = false;\n\nconfigureNavigationRegistryHost({\n cancelRouteRequests,\n});\n\nexport function navigate(path: string, options: NavigateOptions = {}): void {\n if (typeof window === 'undefined') {\n return;\n }\n\n const initialTarget = parseTargetUrl(path);\n navigateWithRedirectState(path, options, {\n redirects: 0,\n visited: new Set([\n `${initialTarget.pathname}${initialTarget.search}${initialTarget.hash}`,\n ]),\n });\n}\n\nfunction navigateWithRedirectState(\n path: string,\n options: NavigateOptions,\n redirectState: NavigationRedirectState\n): void {\n if (typeof window === 'undefined') {\n return;\n }\n\n const request = beginRouteRequest();\n\n const target = parseTargetUrl(path);\n const pathname = target.pathname;\n const href = `${target.pathname}${target.search}${target.hash}`;\n const resolvedTargets = resolveNavigationTargetsForApps(\n pathname,\n href,\n request.signal\n );\n\n if (isPromiseLike(resolvedTargets)) {\n void Promise.resolve(resolvedTargets).then(\n (targets) => {\n if (isStaleRouteRequest(request.id)) {\n return;\n }\n\n try {\n applyNavigationTargets(\n path,\n options,\n redirectState,\n pathname,\n href,\n targets,\n navigateWithRedirectState\n );\n } catch (error) {\n logger.error('[Askr] navigation failed:', error);\n }\n },\n (error) => {\n logger.error('[Askr] navigation failed:', error);\n }\n );\n return;\n }\n\n applyNavigationTargets(\n path,\n options,\n redirectState,\n pathname,\n href,\n resolvedTargets,\n navigateWithRedirectState\n );\n}\n\nfunction handlePopState(event: PopStateEvent): void {\n const request = beginRouteRequest();\n const previousHref = getCurrentHref();\n const pathname = window.location.pathname;\n const href = `${window.location.pathname}${window.location.search}${window.location.hash}`;\n\n saveScrollPosition(previousHref);\n\n if (!hasRegisteredApps()) {\n return;\n }\n\n const applyResolved = (targets: AppNavigationTarget[]) => {\n try {\n applyPopStateNavigationTargets(\n request.id,\n pathname,\n href,\n event.state,\n targets,\n navigate\n );\n } catch (error) {\n logger.error('[Askr] popstate navigation failed:', error);\n }\n };\n\n const resolvedTargets = resolveNavigationTargetsForApps(\n pathname,\n href,\n request.signal\n );\n\n if (isPromiseLike<AppNavigationTarget[]>(resolvedTargets)) {\n void Promise.resolve(resolvedTargets).then(\n (next) => {\n applyResolved(next);\n },\n (error) => {\n logger.error('[Askr] popstate navigation failed:', error);\n }\n );\n return;\n }\n\n applyResolved(resolvedTargets);\n}\n\nexport function initializeNavigation(): void {\n if (typeof window === 'undefined' || navigationInitialized) {\n return;\n }\n\n navigationInitialized = true;\n window.addEventListener('popstate', handlePopState);\n}\n\nexport function cleanupNavigation(): void {\n cancelRouteRequests();\n\n if (typeof window === 'undefined' || !navigationInitialized) {\n return;\n }\n\n navigationInitialized = false;\n window.removeEventListener('popstate', handlePopState);\n}\n"],"mappings":";;;;;;;;;;AA6CA,IAAI,wBAAwB;AAE5B,gCAAgC,EAC9B,oBACF,CAAC;AAED,SAAgB,SAAS,MAAc,UAA2B,CAAC,GAAS;CAC1E,IAAI,OAAO,WAAW,aACpB;CAGF,MAAM,gBAAgB,eAAe,IAAI;CACzC,0BAA0B,MAAM,SAAS;EACvC,WAAW;EACX,yBAAS,IAAI,IAAI,CACf,GAAG,cAAc,WAAW,cAAc,SAAS,cAAc,MACnE,CAAC;CACH,CAAC;AACH;AAEA,SAAS,0BACP,MACA,SACA,eACM;CACN,IAAI,OAAO,WAAW,aACpB;CAGF,MAAM,UAAU,kBAAkB;CAElC,MAAM,SAAS,eAAe,IAAI;CAClC,MAAM,WAAW,OAAO;CACxB,MAAM,OAAO,GAAG,OAAO,WAAW,OAAO,SAAS,OAAO;CACzD,MAAM,kBAAkB,gCACtB,UACA,MACA,QAAQ,MACV;CAEA,IAAI,cAAc,eAAe,GAAG;EAClC,AAAK,QAAQ,QAAQ,eAAe,CAAC,CAAC,MACnC,YAAY;GACX,IAAI,oBAAoB,QAAQ,EAAE,GAChC;GAGF,IAAI;IACF,uBACE,MACA,SACA,eACA,UACA,MACA,SACA,yBACF;GACF,SAAS,OAAO;IACd,OAAO,MAAM,6BAA6B,KAAK;GACjD;EACF,IACC,UAAU;GACT,OAAO,MAAM,6BAA6B,KAAK;EACjD,CACF;EACA;CACF;CAEA,uBACE,MACA,SACA,eACA,UACA,MACA,iBACA,yBACF;AACF;AAEA,SAAS,eAAe,OAA4B;CAClD,MAAM,UAAU,kBAAkB;CAClC,MAAM,eAAe,eAAe;CACpC,MAAM,WAAW,OAAO,SAAS;CACjC,MAAM,OAAO,GAAG,OAAO,SAAS,WAAW,OAAO,SAAS,SAAS,OAAO,SAAS;CAEpF,mBAAmB,YAAY;CAE/B,IAAI,CAAC,kBAAkB,GACrB;CAGF,MAAM,iBAAiB,YAAmC;EACxD,IAAI;GACF,+BACE,QAAQ,IACR,UACA,MACA,MAAM,OACN,SACA,QACF;EACF,SAAS,OAAO;GACd,OAAO,MAAM,sCAAsC,KAAK;EAC1D;CACF;CAEA,MAAM,kBAAkB,gCACtB,UACA,MACA,QAAQ,MACV;CAEA,IAAI,cAAqC,eAAe,GAAG;EACzD,AAAK,QAAQ,QAAQ,eAAe,CAAC,CAAC,MACnC,SAAS;GACR,cAAc,IAAI;EACpB,IACC,UAAU;GACT,OAAO,MAAM,sCAAsC,KAAK;EAC1D,CACF;EACA;CACF;CAEA,cAAc,eAAe;AAC/B;AAEA,SAAgB,uBAA6B;CAC3C,IAAI,OAAO,WAAW,eAAe,uBACnC;CAGF,wBAAwB;CACxB,OAAO,iBAAiB,YAAY,cAAc;AACpD"}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { ComponentInstance } from "../runtime/component-internal.js";
|
|
2
|
+
import { Route, RouteAuthOptions, RouteManifest } from "../common/router.js";
|
|
3
|
+
|
|
4
|
+
//#region src/router/navigation-registry.d.ts
|
|
5
|
+
type AppNavigationSource = {
|
|
6
|
+
manifest?: RouteManifest;
|
|
7
|
+
routes?: readonly Route[];
|
|
8
|
+
auth?: RouteAuthOptions;
|
|
9
|
+
};
|
|
10
|
+
type AppRegistration = AppNavigationSource & {
|
|
11
|
+
instance: ComponentInstance;
|
|
12
|
+
pathname: string;
|
|
13
|
+
href: string;
|
|
14
|
+
};
|
|
15
|
+
type NavigationRegistryHost = {
|
|
16
|
+
cancelRouteRequests(): void;
|
|
17
|
+
};
|
|
18
|
+
declare function configureNavigationRegistryHost(host: NavigationRegistryHost): void;
|
|
19
|
+
declare function getCurrentPathname(): string;
|
|
20
|
+
declare function getCurrentHref(): string;
|
|
21
|
+
declare function setCurrentRouteLocation(pathname: string, href: string): void;
|
|
22
|
+
declare function getWindowHref(): string;
|
|
23
|
+
declare function parseTargetUrl(path: string): URL;
|
|
24
|
+
declare function getRegisteredAppsSnapshot(): AppRegistration[];
|
|
25
|
+
declare function hasRegisteredApps(): boolean;
|
|
26
|
+
declare function syncAppRegistrationLocation(app: AppRegistration, pathname: string, href: string): void;
|
|
27
|
+
declare function syncRegisteredRouteSnapshot(): void;
|
|
28
|
+
declare function registerAppInstance(instance: ComponentInstance, path: string, source?: AppNavigationSource): void;
|
|
29
|
+
declare function unregisterAppInstance(instance: ComponentInstance): void;
|
|
30
|
+
//#endregion
|
|
31
|
+
export { AppNavigationSource, AppRegistration };
|
|
32
|
+
//# sourceMappingURL=navigation-registry.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"navigation-registry.d.ts","names":[],"sources":["../../src/router/navigation-registry.ts"],"mappings":";;;;KASY,mBAAA;EACV,QAAA,GAAW,aAAA;EACX,MAAA,YAAkB,KAAA;EAClB,IAAA,GAAO,gBAAA;AAAA;AAAA,KAGG,eAAA,GAAkB,mBAAA;EAC5B,QAAA,EAAU,iBAAiB;EAC3B,QAAA;EACA,IAAA;AAAA;AAAA,KAGG,sBAAA;EACH,mBAAmB;AAAA;AAAA,iBAUL,+BAAA,CACd,IAA4B,EAAtB,sBAAsB;AAAA,iBAKd,kBAAA;AAAA,iBAIA,cAAA;AAAA,iBAIA,uBAAA,CAAwB,QAAA,UAAkB,IAAY;AAAA,iBAKtD,aAAA;AAAA,iBAQA,cAAA,CAAe,IAAA,WAAe,GAAG;AAAA,iBAiBjC,yBAAA,IAA6B,eAAe;AAAA,iBAI5C,iBAAA;AAAA,iBAIA,2BAAA,CACd,GAAA,EAAK,eAAe,EACpB,QAAA,UACA,IAAA;AAAA,iBA+Bc,2BAAA;AAAA,iBAcA,mBAAA,CACd,QAAA,EAAU,iBAAA,EACV,IAAA,UACA,MAAA,GAAQ,mBAAwB;AAAA,iBA0BlB,qBAAA,CAAsB,QAA2B,EAAjB,iBAAiB"}
|