@absolutejs/absolute 0.20.0-beta.169 → 0.20.0-beta.170
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/CHANGELOG.md +80 -0
- package/README.md +232 -0
- package/changelog.json +228 -0
- package/dist/angular/browser.js +7 -8
- package/dist/angular/browser.js.map +6 -5
- package/dist/angular/components/core/streamingSlotRegistrar.js +6 -2
- package/dist/angular/components/core/streamingSlotRegistry.js +7 -3
- package/dist/angular/index.js +555 -156
- package/dist/angular/index.js.map +29 -23
- package/dist/angular/server.js +555 -156
- package/dist/angular/server.js.map +29 -23
- package/dist/build/buildWorker.js +14 -8
- package/dist/build.js +4949 -1941
- package/dist/build.js.map +72 -42
- package/dist/cli/{add-7azr0c83.js → add-6a7pjkn9.js} +11 -7
- package/dist/cli/{analyze-3cyek6v3.js → analyze-606fshwa.js} +1 -1
- package/dist/cli/{build-25rz8v25.js → build-g81xqbb9.js} +1 -1
- package/dist/cli/{compile-4jnfxts9.js → compile-9y1w9zpj.js} +3 -3
- package/dist/cli/config/server.js +10699 -1538
- package/dist/cli/{dev-9tk5hn2e.js → dev-hyeb89hp.js} +5 -1
- package/dist/cli/{doctor-4nv2c2j3.js → doctor-h55y9hj1.js} +1 -1
- package/dist/cli/{generate-v75p2fct.js → generate-20x1pkf7.js} +4 -4
- package/dist/cli/{htmx-427swtdz.js → htmx-6mz2h7k1.js} +2 -2
- package/dist/cli/{index-bhbs6d5z.js → index-32ge2w1f.js} +12 -4
- package/dist/cli/{index-a4ws2jwd.js → index-3wz3mktm.js} +1 -1
- package/dist/cli/{index-b7hjgknf.js → index-9sksd8c8.js} +13 -4
- package/dist/cli/{index-eyzwc7gz.js → index-qbrzvmh9.js} +4 -2
- package/dist/cli/index-qw98g1p6.js +269 -0
- package/dist/cli/{index-434b7j4a.js → index-vtp20gwf.js} +69 -1
- package/dist/cli/{index-h7qhz02e.js → index-wk0pyxrg.js} +3 -0
- package/dist/cli/{index-k3y8cb6c.js → index-z6f43b20.js} +1 -1
- package/dist/cli/index.js +16 -16
- package/dist/cli/{islands-8sgky9gh.js → islands-dc54e5y1.js} +1 -1
- package/dist/cli/{ls-4m4yqwww.js → ls-b6zz24nt.js} +1 -1
- package/dist/cli/{mobile-hcxjr2gf.js → mobile-ajnnvqtv.js} +3 -3
- package/dist/cli/prerender-fqpp0m1j.js +10 -0
- package/dist/cli/{remove-1ycjx85k.js → remove-t8x1mrxg.js} +4 -4
- package/dist/cli/{start-mbaejxhm.js → start-d6p831ny.js} +3 -3
- package/dist/cli/{typecheck-dr068pmh.js → typecheck-stbt0qt5.js} +6 -1
- package/dist/cli/{workspace-1sycp9g1.js → workspace-61hh6jq1.js} +1 -1
- package/dist/client/chunks/index-6b66nzyf.js +381 -0
- package/dist/client/chunks/index-6b66nzyf.js.map +11 -0
- package/dist/client/chunks/{islands-rc28k5sx.js → islands-s2ta5ajb.js} +5 -2
- package/dist/client/chunks/{islands-rc28k5sx.js.map → islands-s2ta5ajb.js.map} +7 -6
- package/dist/client/index.js +160 -3
- package/dist/client/index.js.map +6 -4
- package/dist/client/navigation.js +764 -0
- package/dist/client/navigation.js.map +10 -0
- package/dist/client/prefetch.js +33 -375
- package/dist/client/prefetch.js.map +3 -4
- package/dist/core/streamingSlotRegistrar.js +5 -2
- package/dist/core/streamingSlotRegistrar.js.map +5 -4
- package/dist/core/streamingSlotRegistry.js +5 -2
- package/dist/core/streamingSlotRegistry.js.map +5 -4
- package/dist/dev/client/cspNonce.ts +28 -0
- package/dist/dev/client/handlers/html.ts +4 -3
- package/dist/dev/client/handlers/htmx.ts +3 -2
- package/dist/dev/client/handlers/svelte.ts +15 -90
- package/dist/dev/client/syncDevtools.ts +2 -1
- package/dist/dev/serverBootstrap.js +11 -4
- package/dist/i18n/index.js +543 -0
- package/dist/i18n/index.js.map +15 -0
- package/dist/index.js +6339 -2233
- package/dist/index.js.map +89 -54
- package/dist/islands/index.js +282 -40
- package/dist/islands/index.js.map +14 -10
- package/dist/mobile/browser.js +7 -2
- package/dist/mobile/browser.js.map +5 -4
- package/dist/mobile/index.js +7 -2
- package/dist/mobile/index.js.map +5 -4
- package/dist/mobile/remoteMacAgentEntry.js +1 -1
- package/dist/react/components/browser/index.js +94 -4
- package/dist/react/components/index.js +150 -10
- package/dist/react/components/index.js.map +15 -10
- package/dist/react/hooks/index.js +479 -13
- package/dist/react/hooks/index.js.map +12 -4
- package/dist/react/index.js +769 -166
- package/dist/react/index.js.map +32 -21
- package/dist/react/router/browser.js +21 -4
- package/dist/react/router/browser.js.map +5 -4
- package/dist/react/router/index.js +21 -4
- package/dist/react/router/index.js.map +5 -4
- package/dist/react/server.js +597 -203
- package/dist/react/server.js.map +25 -15
- package/dist/src/angular/zoneRuntime.d.ts +5 -0
- package/dist/src/build/buildReactServerComponents.d.ts +22 -0
- package/dist/src/build/downlevelAsyncForZone.d.ts +1 -0
- package/dist/src/build/fileRoutes.d.ts +65 -0
- package/dist/src/build/fonts/buildFonts.d.ts +25 -0
- package/dist/src/build/fonts/fallbackMetrics.d.ts +13 -0
- package/dist/src/build/fonts/googleFonts.d.ts +18 -0
- package/dist/src/build/fonts/injectFontTags.d.ts +7 -0
- package/dist/src/build/fonts/parseFontMetrics.d.ts +4 -0
- package/dist/src/build/generateReactIndexes.d.ts +7 -1
- package/dist/src/build/htmlIncludes.d.ts +16 -0
- package/dist/src/build/inlineSourceMapComment.d.ts +1 -0
- package/dist/src/build/scanConventions.d.ts +3 -0
- package/dist/src/build/vitals.d.ts +21 -0
- package/dist/src/client/formActions.d.ts +29 -0
- package/dist/src/client/index.d.ts +2 -0
- package/dist/src/client/navigation.d.ts +16 -0
- package/dist/src/client/prefetch.d.ts +2 -30
- package/dist/src/core/build.d.ts +2 -2
- package/dist/src/core/cspNonce.d.ts +12 -0
- package/dist/src/core/fileRouteAdapter.d.ts +15 -0
- package/dist/src/core/fileRoutes.d.ts +5 -0
- package/dist/src/core/formActionFlash.d.ts +25 -0
- package/dist/src/core/formActions.d.ts +249 -0
- package/dist/src/core/index.d.ts +5 -0
- package/dist/src/core/partialPrerender.d.ts +28 -0
- package/dist/src/core/partialPrerenderServe.d.ts +24 -0
- package/dist/src/core/precompressed.d.ts +11 -1
- package/dist/src/core/prerenderNonce.d.ts +9 -0
- package/dist/src/core/productionRuntime.d.ts +4 -2
- package/dist/src/core/serverOnlyStaticFiles.d.ts +8 -0
- package/dist/src/core/staticHtmlNonce.d.ts +2 -0
- package/dist/src/core/vitals.d.ts +108 -0
- package/dist/src/dev/angular/fastHmrCompiler.d.ts +1 -1
- package/dist/src/dev/client/cspNonce.d.ts +2 -0
- package/dist/src/dev/fileRouteRefresher.d.ts +5 -0
- package/dist/src/dev/importCost/instrument.d.ts +1 -1
- package/dist/src/dev/reactServerComponentsRebuild.d.ts +3 -0
- package/dist/src/i18n/defineMessages.d.ts +5 -0
- package/dist/src/i18n/formatMessage.d.ts +26 -0
- package/dist/src/i18n/index.d.ts +6 -0
- package/dist/src/i18n/intlCache.d.ts +5 -0
- package/dist/src/i18n/routing.d.ts +28 -0
- package/dist/src/i18n/translator.d.ts +11 -0
- package/dist/src/mobile/androidRelease.d.ts +2 -2
- package/dist/src/mobile/iosRelease.d.ts +4 -4
- package/dist/src/mobile/materializedBundle.d.ts +1 -1
- package/dist/src/mobile/mobileInspect.d.ts +1 -1
- package/dist/src/mobile/releaseArtifact.d.ts +2 -2
- package/dist/src/mobile/remoteMacProtocol.d.ts +2 -2
- package/dist/src/plugins/i18n.d.ts +30 -0
- package/dist/src/plugins/index.d.ts +2 -1
- package/dist/src/plugins/secureHeaders.d.ts +48 -0
- package/dist/src/react/components/Head.d.ts +1 -1
- package/dist/src/react/components/StreamSlot.browser.d.ts +1 -0
- package/dist/src/react/components/StreamSlot.d.ts +5 -1
- package/dist/src/react/components/SuspenseSlot.browser.d.ts +2 -0
- package/dist/src/react/components/SuspenseSlot.d.ts +12 -0
- package/dist/src/react/fileRoute.d.ts +18 -0
- package/dist/src/react/hooks/index.d.ts +4 -0
- package/dist/src/react/hooks/useFormAction.d.ts +42 -0
- package/dist/src/react/hooks/useI18n.d.ts +15 -0
- package/dist/src/react/index.d.ts +2 -0
- package/dist/src/react/server.d.ts +2 -0
- package/dist/src/react/serverComponents/constants.d.ts +11 -0
- package/dist/src/react/serverComponents/flightPayload.d.ts +2 -0
- package/dist/src/react/serverComponents/pageHandler.d.ts +14 -0
- package/dist/src/svelte/browser.d.ts +1 -0
- package/dist/src/svelte/fileRoute.d.ts +15 -0
- package/dist/src/svelte/i18n.d.ts +8 -0
- package/dist/src/svelte/index.d.ts +2 -0
- package/dist/src/svelte/lowerAwaitSlotSyntax.d.ts +5 -1
- package/dist/src/svelte/renderToReadableStream.d.ts +10 -2
- package/dist/src/svelte/router/browser.d.ts +3 -1
- package/dist/src/svelte/router/goto.d.ts +13 -10
- package/dist/src/svelte/router/guards.d.ts +43 -0
- package/dist/src/svelte/router/index.d.ts +3 -1
- package/dist/src/svelte/router/lazy.d.ts +17 -0
- package/dist/src/svelte/router/lazyModule.d.ts +29 -0
- package/dist/src/svelte/router/navigation.d.ts +55 -0
- package/dist/src/svelte/router/pushState.d.ts +4 -2
- package/dist/src/svelte/router/scroll.d.ts +34 -0
- package/dist/src/svelte/routerSsr.d.ts +9 -0
- package/dist/src/svelte/server.d.ts +1 -0
- package/dist/src/utils/cspNonceRef.d.ts +8 -0
- package/dist/src/utils/fontAssets.d.ts +17 -0
- package/dist/src/utils/formActionProtocol.d.ts +10 -0
- package/dist/src/utils/generateHeadElement.d.ts +1 -1
- package/dist/src/utils/index.d.ts +1 -0
- package/dist/src/utils/inlinePageCss.d.ts +18 -0
- package/dist/src/utils/loadConfig.d.ts +5 -0
- package/dist/src/utils/localeRef.d.ts +10 -0
- package/dist/src/utils/resolveConvention.d.ts +6 -1
- package/dist/src/utils/streamingSlots.d.ts +5 -0
- package/dist/src/vue/browser.d.ts +2 -0
- package/dist/src/vue/components/Image.d.ts +2 -2
- package/dist/src/vue/index.d.ts +2 -0
- package/dist/src/vue/serverDataPayload.d.ts +32 -0
- package/dist/src/vue/serverDataState.d.ts +9 -0
- package/dist/src/vue/useServerData.browser.d.ts +6 -0
- package/dist/src/vue/useServerData.d.ts +24 -0
- package/dist/svelte/browser.js +330 -3
- package/dist/svelte/browser.js.map +8 -4
- package/dist/svelte/components/AwaitSlot.svelte +5 -0
- package/dist/svelte/components/Head.svelte +50 -0
- package/dist/svelte/components/JsonLd.svelte +9 -1
- package/dist/svelte/components/StreamSlot.svelte +5 -0
- package/dist/svelte/index.js +1017 -117
- package/dist/svelte/index.js.map +38 -24
- package/dist/svelte/router/Link.svelte +40 -8
- package/dist/svelte/router/Route.svelte +157 -12
- package/dist/svelte/router/Route.svelte.d.ts +39 -5
- package/dist/svelte/router/Router.svelte +140 -25
- package/dist/svelte/router/Router.svelte.d.ts +5 -1
- package/dist/svelte/router/browser.ts +10 -0
- package/dist/svelte/router/goto.ts +15 -86
- package/dist/svelte/router/guards.ts +112 -0
- package/dist/svelte/router/index.ts +10 -0
- package/dist/svelte/router/lazy.ts +82 -0
- package/dist/svelte/router/lazyModule.ts +74 -0
- package/dist/svelte/router/navigation.ts +412 -0
- package/dist/svelte/router/pushState.ts +7 -4
- package/dist/svelte/router/scroll.ts +286 -0
- package/dist/svelte/server.js +747 -252
- package/dist/svelte/server.js.map +30 -20
- package/dist/types/angular.d.ts +2 -0
- package/dist/types/build.d.ts +37 -0
- package/dist/types/conventions.d.ts +3 -0
- package/dist/types/fileRoutes.d.ts +72 -0
- package/dist/types/fonts.d.ts +86 -0
- package/dist/types/formAction.d.ts +54 -0
- package/dist/types/globals.d.ts +10 -0
- package/dist/types/i18n.d.ts +185 -0
- package/dist/types/index.d.ts +4 -0
- package/dist/types/metadata.d.ts +11 -0
- package/dist/types/navigation.d.ts +37 -0
- package/dist/types/prefetch.d.ts +10 -0
- package/dist/types/sitemap.d.ts +4 -0
- package/dist/types/svelteRouter.d.ts +89 -2
- package/dist/types/svelteRouter.ts +112 -2
- package/dist/types/vue.d.ts +46 -1
- package/dist/utils/iconVersion.ts +34 -0
- package/dist/vue/browser.js +107 -11
- package/dist/vue/browser.js.map +7 -4
- package/dist/vue/components/index.js +5 -2
- package/dist/vue/components/index.js.map +5 -4
- package/dist/vue/index.js +712 -158
- package/dist/vue/index.js.map +32 -23
- package/dist/vue/server.js +310 -79
- package/dist/vue/server.js.map +20 -15
- package/package.json +9 -1
- package/dist/cli/prerender-mfnwsvyt.js +0 -7
- package/dist/src/plugins/pageRouter.d.ts +0 -1
- /package/dist/cli/{index-j7m8pq48.js → index-rervww4p.js} +0 -0
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../src/client/navigation.ts"],
|
|
4
|
+
"sourcesContent": [
|
|
5
|
+
"/**\n * Cross-framework document navigation.\n *\n * Every framework router (React Router via `<UniversalRouter>`, the Svelte\n * router, vue-router, Angular's router) handles the URLs it has routes for\n * and lets every other link fall through to a real page load. This layer\n * catches those fall-through navigations and turns them into a soft swap:\n *\n * fetch the target HTML → load its stylesheets → tear down the current\n * page (`window.__ABSOLUTE_PAGE_DISPOSE__`) → swap <head>/<body> (in a\n * View Transition where supported) → run the target's scripts → the\n * target's hydration index hydrates the new body.\n *\n * So a React page links to a Svelte page (and back) without a reload, and\n * `createIslandStore` state lives on: the store snapshot sits on\n * `globalThis`, which a swap never resets.\n *\n * import { enableNavigation } from '@absolutejs/absolute/client/navigation';\n * enableNavigation();\n *\n * Opt-in per app (call it from every page that should take part; the\n * first call installs, the rest are no-ops) and opt-out per link with\n * `data-absolute-navigation=\"off\"` (on the link or an ancestor). Any\n * error falls back to a full page load.\n *\n * CSP: a fetched page's inline scripts carry THAT response's nonce, which\n * the current document's policy rejects. Scripts and styles are recreated\n * with the current document's nonce, but only those that carried the\n * fetched response's own nonce — what the browser would have run on a\n * full load is what runs here, nothing more. */\nimport { readPageNonce } from '../dev/client/cspNonce';\nimport type {\n\tDocumentNavigationEventDetail,\n\tDocumentNavigationOutcome,\n\tDocumentNavigationType,\n\tEnableNavigationOptions,\n\tNavigateDocumentOptions\n} from '../../types/navigation';\nimport { consumePrefetch } from './prefetch';\n\n/* Shared by every bundle copy of this module (each framework's client pass\n * bundles its own), and read by the Svelte `<Link>` to decide whether a\n * URL no `<Router>` matches should be handed to the browser. */\nconst RUNTIME_KEY = Symbol.for('absolutejs.navigation');\nconst STATE_KEY = '__absoluteNavigation';\nconst OPT_OUT_SELECTOR = '[data-absolute-navigation=\"off\"]';\nconst MODULE_RUN_PARAM = 'absolute-nav';\nconst ANNOUNCER_ID = 'absolute-navigation-announcer';\nconst ISLAND_STATE_GLOBAL = '__ABS_ISLAND_STATE__';\nconst DISPOSE_GLOBAL = '__ABSOLUTE_PAGE_DISPOSE__';\nconst READY_GLOBAL = '__ABSOLUTE_PAGE_READY__';\nconst STYLESHEET_TIMEOUT_MS = 5_000;\nconst PAGE_READY_TIMEOUT_MS = 10_000;\nconst PAGE_READY_POLL_MS = 16;\nconst SCRIPT_PLACEHOLDER = 'absolute-navigation-script';\nconst ID_RADIX = 36;\n\n/* Globals one page's bootstrap writes for its own hydration. Cleared before\n * the next page's scripts run so it never hydrates with the last page's\n * props. `__ABS_ISLAND_STATE__` is deliberately not here: it is the shared\n * island-store snapshot that must survive. */\nconst PAGE_GLOBALS = [\n\t'__INITIAL_PROPS__',\n\t'__SSR_DIRTY__',\n\t'__ABS_SLOT_HYDRATION_PENDING__',\n\t'__ABS_SVELTE_LAZY_ROUTES__',\n\t'__ABS_SVELTE_ISLAND_HTML__',\n\t'__ABS_SERVER_ISLAND_HTML__',\n\t'__ABSOLUTE_SERVER_DATA__',\n\t'__ABS_ANGULAR_REQUEST_CONTEXT__',\n\tDISPOSE_GLOBAL,\n\tREADY_GLOBAL\n];\n\nconst JAVASCRIPT_TYPES = new Set([\n\t'',\n\t'application/ecmascript',\n\t'application/javascript',\n\t'module',\n\t'speculationrules',\n\t'text/ecmascript',\n\t'text/javascript'\n]);\n\ntype NavigationLike = EventTarget & { currentEntry: unknown };\n\ntype ScrollPosition = { left: number; top: number };\n\n/* Which inline scripts / styles of a fetched page may run here. */\ntype ElementTrust =\n\t{ kind: 'all' } | { kind: 'none' } | { kind: 'nonce'; nonce: string };\n\ntype PendingScript = {\n\tplaceholder: Comment;\n\tsource: HTMLScriptElement;\n\ttrusted: boolean;\n};\n\ntype HeadContext = {\n\tavailable: Map<string, Element[]>;\n\tpreloaded: Set<Element>;\n\ttrust: ElementTrust;\n};\n\ntype IslandStateRef = { live: Record<string, unknown> | undefined };\n\ntype LoadedDocument = {\n\tdocument: Document;\n\ttrust: ElementTrust;\n\turl: URL;\n};\n\ntype NavigationRequest = {\n\t/** Document the destination entry belongs to (traversals). */\n\tdocumentId?: string;\n\treplace: boolean;\n\t/** Scroll position saved for the destination entry (traversals). */\n\tscroll?: ScrollPosition;\n\ttype: DocumentNavigationType;\n\turl: URL;\n};\n\ntype Runtime = {\n\tcontroller: AbortController | undefined;\n\tdocumentId: string;\n\tentryOwners: Map<string, string>;\n\tevaluatedModules: Set<string>;\n\tmoduleRun: number;\n\tnavigating: boolean;\n\tnavigationApi: NavigationLike | undefined;\n\tnonce: string | undefined;\n\toptions: EnableNavigationOptions;\n\trestoreHistory: (() => void) | undefined;\n\tscroll: Map<string, ScrollPosition>;\n\tscrollFrame: number;\n\tteardown: Array<() => void>;\n\ttoken: number;\n};\n\ntype PublicRuntime = {\n\tdisable: () => void;\n\tnavigate: (\n\t\thref: string,\n\t\toptions?: NavigateDocumentOptions\n\t) => Promise<DocumentNavigationOutcome>;\n};\n\nlet runtime: Runtime | undefined;\n\n/* ------------------------------------------------------------------ */\n/* Small helpers */\n/* ------------------------------------------------------------------ */\n\nconst isRecord = (value: unknown): value is Record<string, unknown> =>\n\ttypeof value === 'object' && value !== null && !Array.isArray(value);\n\nconst createId = () =>\n\ttypeof crypto !== 'undefined' && typeof crypto.randomUUID === 'function'\n\t\t? crypto.randomUUID()\n\t\t: `${Date.now().toString(ID_RADIX)}-${Math.random().toString(ID_RADIX).slice(2)}`;\n\nconst delay = (millis: number) =>\n\tnew Promise<void>((resolve) => {\n\t\tsetTimeout(resolve, millis);\n\t});\n\nconst readPublicRuntime = () => {\n\tconst value: unknown = Reflect.get(globalThis, RUNTIME_KEY);\n\tif (!isRecord(value)) return undefined;\n\tconst { disable, navigate } = value;\n\tif (typeof disable !== 'function' || typeof navigate !== 'function') {\n\t\treturn undefined;\n\t}\n\n\treturn value;\n};\n\nconst prefersReducedMotion = () =>\n\ttypeof window.matchMedia === 'function' &&\n\twindow.matchMedia('(prefers-reduced-motion: reduce)').matches;\n\n/* ------------------------------------------------------------------ */\n/* History entries: which document owns which entry */\n/* ------------------------------------------------------------------ */\n\nconst isNavigationLike = (value: unknown): value is NavigationLike =>\n\ttypeof value === 'object' &&\n\tvalue !== null &&\n\t'currentEntry' in value &&\n\ttypeof Reflect.get(value, 'addEventListener') === 'function';\n\nconst readNavigationApi = () => {\n\tconst value: unknown = Reflect.get(window, 'navigation');\n\n\treturn isNavigationLike(value) ? value : undefined;\n};\n\nconst readEntryKey = (api: NavigationLike) => {\n\tconst entry = api.currentEntry;\n\tif (typeof entry !== 'object' || entry === null) return undefined;\n\tconst key: unknown = Reflect.get(entry, 'key');\n\n\treturn typeof key === 'string' ? key : undefined;\n};\n\nconst readStamp = (state: unknown) => {\n\tif (!isRecord(state)) return undefined;\n\tconst stamp = state[STATE_KEY];\n\tif (!isRecord(stamp)) return undefined;\n\tconst { doc, key } = stamp;\n\tif (typeof doc !== 'string' || typeof key !== 'string') return undefined;\n\n\treturn { doc, key };\n};\n\nconst isStampable = (state: unknown) => state === null || isRecord(state);\n\nconst stampState = (state: unknown, doc: string, key: string) => {\n\tif (!isStampable(state)) return state;\n\n\treturn { ...(isRecord(state) ? state : {}), [STATE_KEY]: { doc, key } };\n};\n\n/** Key of the history entry the browser is on right now. */\nconst currentEntryKey = (nav: Runtime) =>\n\tnav.navigationApi\n\t\t? readEntryKey(nav.navigationApi)\n\t\t: readStamp(window.history.state)?.key;\n\n/** Document that owns the current entry. `undefined` = unknown. */\nconst currentEntryOwner = (nav: Runtime) => {\n\tif (!nav.navigationApi) return readStamp(window.history.state)?.doc;\n\tconst key = readEntryKey(nav.navigationApi);\n\n\treturn key === undefined ? undefined : nav.entryOwners.get(key);\n};\n\n/** A traversal landed on an entry another document wrote. Navigation API:\n * every entry this session wrote is in the map, so an unknown one is\n * foreign. History fallback: an entry without a stamp (a hash link, an\n * entry from before `enableNavigation`) stays with the current page. */\nconst isForeignEntry = (nav: Runtime) => {\n\tconst owner = currentEntryOwner(nav);\n\tif (owner === nav.documentId) return false;\n\n\treturn owner !== undefined || nav.navigationApi !== undefined;\n};\n\nconst recordCurrentEntry = (nav: Runtime) => {\n\tif (!nav.navigationApi) return;\n\tconst key = readEntryKey(nav.navigationApi);\n\tif (key !== undefined) nav.entryOwners.set(key, nav.documentId);\n};\n\n/* Navigation API: an entry a router (or a hash link) pushes or replaces\n * belongs to the document on screen. Traversals land on known entries. */\nconst trackEntries = (nav: Runtime, api: NavigationLike) => {\n\tconst onEntryChange = (event: Event) => {\n\t\tif (Reflect.get(event, 'navigationType') === 'traverse') return;\n\t\trecordCurrentEntry(nav);\n\t};\n\tapi.addEventListener('currententrychange', onEntryChange);\n\tnav.teardown.push(() =>\n\t\tapi.removeEventListener('currententrychange', onEntryChange)\n\t);\n\trecordCurrentEntry(nav);\n};\n\n/* History fallback: no entry keys without the Navigation API, so every\n * pushState / replaceState gets a `{ doc, key }` stamp merged into its\n * (object or null) state. Routers keep their own keys next to it. */\nconst patchHistory = (nav: Runtime) => {\n\tconst { history } = window;\n\tconst originalPush = history.pushState;\n\tconst originalReplace = history.replaceState;\n\thistory.pushState = (\n\t\tstate: unknown,\n\t\tunused: string,\n\t\turl?: string | URL | null\n\t) =>\n\t\tReflect.apply(originalPush, history, [\n\t\t\tstampState(state, nav.documentId, createId()),\n\t\t\tunused,\n\t\t\turl\n\t\t]);\n\thistory.replaceState = (\n\t\tstate: unknown,\n\t\tunused: string,\n\t\turl?: string | URL | null\n\t) =>\n\t\tReflect.apply(originalReplace, history, [\n\t\t\tstampState(\n\t\t\t\tstate,\n\t\t\t\tnav.documentId,\n\t\t\t\treadStamp(history.state)?.key ?? createId()\n\t\t\t),\n\t\t\tunused,\n\t\t\turl\n\t\t]);\n\thistory.replaceState(history.state, '');\n\tnav.restoreHistory = () => {\n\t\thistory.pushState = originalPush;\n\t\thistory.replaceState = originalReplace;\n\t};\n};\n\n/* ------------------------------------------------------------------ */\n/* Scroll */\n/* ------------------------------------------------------------------ */\n\nconst recordScroll = (nav: Runtime) => {\n\tif (nav.navigating) return;\n\tconst key = currentEntryKey(nav);\n\tif (key === undefined) return;\n\tnav.scroll.set(key, { left: window.scrollX, top: window.scrollY });\n};\n\nconst trackScroll = (nav: Runtime) => {\n\tconst onScroll = () => {\n\t\tif (nav.scrollFrame !== 0) return;\n\t\tnav.scrollFrame = window.requestAnimationFrame(() => {\n\t\t\tnav.scrollFrame = 0;\n\t\t\trecordScroll(nav);\n\t\t});\n\t};\n\twindow.addEventListener('scroll', onScroll, { passive: true });\n\tnav.teardown.push(() => {\n\t\twindow.removeEventListener('scroll', onScroll);\n\t\tif (nav.scrollFrame !== 0) window.cancelAnimationFrame(nav.scrollFrame);\n\t});\n};\n\nconst scrollToHash = (hash: string) => {\n\tif (hash === '' || hash === '#') return false;\n\tconst id = decodeURIComponent(hash.slice(1));\n\tconst target =\n\t\tdocument.getElementById(id) ?? document.getElementsByName(id)[0];\n\tif (!target) return false;\n\ttarget.scrollIntoView();\n\n\treturn true;\n};\n\nconst applyScroll = (request: NavigationRequest, url: URL) => {\n\tif (request.scroll) {\n\t\twindow.scrollTo(request.scroll.left, request.scroll.top);\n\n\t\treturn;\n\t}\n\tif (scrollToHash(url.hash)) return;\n\twindow.scrollTo(0, 0);\n};\n\n/* Hydrating a document root can put the window back at the top (seen with\n * React 19 on `document`). Once the page is up, a position that was reset\n * to 0 is applied again; a position the user scrolled to stays. */\nconst reapplyScroll = (request: NavigationRequest, url: URL) => {\n\tif (window.scrollY !== 0 || window.scrollX !== 0) return;\n\tif (request.scroll && request.scroll.top + request.scroll.left > 0) {\n\t\twindow.scrollTo(request.scroll.left, request.scroll.top);\n\n\t\treturn;\n\t}\n\tif (!request.scroll) scrollToHash(url.hash);\n};\n\n/* ------------------------------------------------------------------ */\n/* Modules: re-run a page's entry when it is visited again */\n/* ------------------------------------------------------------------ */\n\nconst RELATIVE_SPECIFIER = /^(?:\\/|\\.\\.?\\/|https?:)/;\nconst IMPORT_CALL_RE = /\\bimport\\(\\s*([\"'])([^\"'\\n]+)\\1\\s*\\)/g;\nconst IMPORT_FROM_RE = /\\b(from|import)\\s*([\"'])([^\"'\\n]+)\\2/g;\n\nconst resolveSameOrigin = (specifier: string) => {\n\tif (!RELATIVE_SPECIFIER.test(specifier)) return undefined;\n\ttry {\n\t\tconst url = new URL(specifier, window.location.href);\n\n\t\treturn url.origin === window.location.origin ? url : undefined;\n\t} catch {\n\t\treturn undefined;\n\t}\n};\n\n/* A module URL evaluates once per document, so a page's hydration index\n * that already ran (the user is coming back to it) would be a no-op. Give\n * the revisit a fresh URL; its imports (framework vendor chunks, shared\n * chunks) keep their URLs, so only the entry re-runs. */\nconst moduleUrlFor = (nav: Runtime, specifier: string) => {\n\tconst url = resolveSameOrigin(specifier);\n\tif (!url) return specifier;\n\tif (!nav.evaluatedModules.has(url.href)) {\n\t\tnav.evaluatedModules.add(url.href);\n\n\t\treturn specifier;\n\t}\n\tnav.moduleRun += 1;\n\turl.searchParams.set(MODULE_RUN_PARAM, String(nav.moduleRun));\n\n\treturn url.href;\n};\n\nconst rewriteModuleSpecifiers = (nav: Runtime, source: string) =>\n\tsource\n\t\t.replace(\n\t\t\tIMPORT_CALL_RE,\n\t\t\t(_match, _quote: string, specifier: string) =>\n\t\t\t\t`import(${JSON.stringify(moduleUrlFor(nav, specifier))})`\n\t\t)\n\t\t.replace(\n\t\t\tIMPORT_FROM_RE,\n\t\t\t(match, keyword: string, _quote: string, specifier: string) =>\n\t\t\t\tresolveSameOrigin(specifier)\n\t\t\t\t\t? `${keyword} ${JSON.stringify(moduleUrlFor(nav, specifier))}`\n\t\t\t\t\t: match\n\t\t);\n\nconst rememberSpecifier = (nav: Runtime, specifier: string) => {\n\tconst url = resolveSameOrigin(specifier);\n\tif (url) nav.evaluatedModules.add(url.href);\n};\n\nconst rememberImportCalls = (nav: Runtime, text: string) => {\n\tfor (const match of text.matchAll(IMPORT_CALL_RE)) {\n\t\trememberSpecifier(nav, match[2] ?? '');\n\t}\n};\n\n/** The entries the current document already evaluated. */\nconst rememberDocumentModules = (nav: Runtime) => {\n\tfor (const script of Array.from(document.scripts)) {\n\t\tconst src = script.getAttribute('src');\n\t\tif (src && script.type === 'module') rememberSpecifier(nav, src);\n\t\trememberImportCalls(nav, script.textContent ?? '');\n\t}\n};\n\n/* ------------------------------------------------------------------ */\n/* Fetching and parsing */\n/* ------------------------------------------------------------------ */\n\nconst TRUST_ALL: ElementTrust = { kind: 'all' };\nconst TRUST_NONE: ElementTrust = { kind: 'none' };\n\nconst readTrust = (response: Response) => {\n\tconst policy = response.headers.get('content-security-policy');\n\tif (!policy) return TRUST_ALL;\n\tconst nonce = /'nonce-([^']+)'/.exec(policy)?.[1];\n\tif (!nonce) return TRUST_NONE;\n\tconst trust: ElementTrust = { kind: 'nonce', nonce };\n\n\treturn trust;\n};\n\nconst isTrusted = (element: Element, trust: ElementTrust) => {\n\tif (trust.kind === 'all') return true;\n\tif (trust.kind === 'none') return false;\n\n\treturn element.getAttribute('nonce') === trust.nonce;\n};\n\nconst takePrefetched = async (url: URL) => {\n\tconst pending =\n\t\tconsumePrefetch(url.href) ??\n\t\tconsumePrefetch(`${url.pathname}${url.search}`);\n\tif (!pending) return undefined;\n\tconst response = await pending;\n\n\treturn response.ok ? response : undefined;\n};\n\nconst fetchDocument = async (url: URL, signal: AbortSignal) =>\n\t(await takePrefetched(url)) ??\n\tfetch(url.href, {\n\t\tcredentials: 'same-origin',\n\t\theaders: { Accept: 'text/html' },\n\t\tsignal\n\t});\n\nconst escapeRegExp = (value: string) =>\n\tvalue.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&');\n\n/* DOMParser documents inherit this document's CSP, so a parsed <style>\n * carrying the fetched response's nonce is reported as a violation the\n * moment it is parsed. Elements carrying that response's nonce (what a full\n * load would have run) get this document's nonce before parsing; nothing\n * else gains one. */\nconst adoptResponseNonce = (\n\tnav: Runtime,\n\thtml: string,\n\ttrust: ElementTrust\n) => {\n\tif (trust.kind !== 'nonce' || !nav.nonce) return { html, trust };\n\tconst pattern = new RegExp(\n\t\t`\\\\bnonce=([\"'])${escapeRegExp(trust.nonce)}\\\\1`,\n\t\t'g'\n\t);\n\tconst adopted: ElementTrust = { kind: 'nonce', nonce: nav.nonce };\n\n\treturn {\n\t\thtml: html.replace(pattern, `nonce=\"${nav.nonce}\"`),\n\t\ttrust: adopted\n\t};\n};\n\nconst loadDocument = async (nav: Runtime, url: URL, signal: AbortSignal) => {\n\tconst response = await fetchDocument(url, signal);\n\tconst contentType = response.headers.get('content-type') ?? '';\n\tconst finalUrl = new URL(response.url || url.href);\n\tfinalUrl.hash = url.hash;\n\tif (\n\t\t!response.ok ||\n\t\t!contentType.includes('text/html') ||\n\t\tfinalUrl.origin !== window.location.origin\n\t) {\n\t\tawait response.body?.cancel().catch(() => undefined);\n\n\t\treturn undefined;\n\t}\n\tconst { html, trust } = adoptResponseNonce(\n\t\tnav,\n\t\tawait response.text(),\n\t\treadTrust(response)\n\t);\n\tconst parsed = new DOMParser().parseFromString(html, 'text/html');\n\tconst loaded: LoadedDocument = {\n\t\tdocument: parsed,\n\t\ttrust,\n\t\turl: finalUrl\n\t};\n\n\treturn loaded;\n};\n\nconst isExecutableScript = (script: HTMLScriptElement) =>\n\tJAVASCRIPT_TYPES.has(\n\t\t(script.getAttribute('type') ?? '').trim().toLowerCase()\n\t);\n\n/* Swap each executable <script> for a comment so the parsed (inert)\n * elements never reach the live document; the comment marks where the\n * recreated script goes. */\nconst extractScripts = (loaded: LoadedDocument) =>\n\tArray.from(loaded.document.querySelectorAll('script'))\n\t\t.filter(isExecutableScript)\n\t\t.map((source) => {\n\t\t\tconst placeholder =\n\t\t\t\tloaded.document.createComment(SCRIPT_PLACEHOLDER);\n\t\t\tconst trusted = isTrusted(source, loaded.trust);\n\t\t\tsource.replaceWith(placeholder);\n\t\t\tconst pending: PendingScript = { placeholder, source, trusted };\n\n\t\t\treturn pending;\n\t\t});\n\n/* ------------------------------------------------------------------ */\n/* Stylesheets, head and body */\n/* ------------------------------------------------------------------ */\n\nconst applyNonce = (nav: Runtime, element: Element, trusted: boolean) => {\n\telement.removeAttribute('nonce');\n\t// The attribute (not just the property) so later readers of the page\n\t// nonce (`script[nonce], style[nonce]`) still find a carrier.\n\tif (trusted && nav.nonce) element.setAttribute('nonce', nav.nonce);\n};\n\nconst waitForStylesheet = (link: HTMLLinkElement) =>\n\tnew Promise<void>((resolve) => {\n\t\tconst timer = setTimeout(resolve, STYLESHEET_TIMEOUT_MS);\n\t\tconst done = () => {\n\t\t\tclearTimeout(timer);\n\t\t\tresolve();\n\t\t};\n\t\tlink.addEventListener('load', done, { once: true });\n\t\tlink.addEventListener('error', done, { once: true });\n\t});\n\n/* Load the target's stylesheets before anything is torn down, inert\n * (`media=\"not all\"`) so they can't restyle the page still on screen. */\nconst preloadStylesheets = async (loaded: LoadedDocument) => {\n\tconst links = Array.from(\n\t\tloaded.document.head.querySelectorAll<HTMLLinkElement>(\n\t\t\t'link[rel~=\"stylesheet\"]'\n\t\t)\n\t);\n\tconst media = new Map<HTMLLinkElement, string | null>();\n\tfor (const link of links) {\n\t\tmedia.set(link, link.getAttribute('media'));\n\t\tlink.setAttribute('media', 'not all');\n\t\tdocument.head.append(document.adoptNode(link));\n\t}\n\tawait Promise.all(links.map(waitForStylesheet));\n\n\treturn media;\n};\n\nconst restoreMedia = (media: Map<HTMLLinkElement, string | null>) => {\n\tfor (const [link, value] of media) {\n\t\tif (value === null) link.removeAttribute('media');\n\t\telse link.setAttribute('media', value);\n\t}\n};\n\nconst elementKey = (element: Element) => {\n\tconst attributes = Array.from(element.attributes)\n\t\t.filter((attribute) => attribute.name !== 'nonce')\n\t\t.map((attribute) => `${attribute.name}=${attribute.value}`)\n\t\t.sort()\n\t\t.join('\\u0000');\n\n\treturn `${element.tagName}\\u0001${attributes}\\u0001${element.textContent ?? ''}`;\n};\n\nconst takeMatch = (available: Map<string, Element[]>, node: Element) =>\n\tavailable.get(elementKey(node))?.shift();\n\nconst syncAttributes = (target: Element, source: Element) => {\n\tfor (const attribute of Array.from(target.attributes)) {\n\t\tif (!source.hasAttribute(attribute.name))\n\t\t\ttarget.removeAttribute(attribute.name);\n\t}\n\tfor (const attribute of Array.from(source.attributes)) {\n\t\ttarget.setAttribute(attribute.name, attribute.value);\n\t}\n};\n\nconst indexHead = (preloaded: Set<Element>) => {\n\tconst available = new Map<string, Element[]>();\n\tfor (const child of Array.from(document.head.children)) {\n\t\tif (preloaded.has(child) || child.tagName === 'SCRIPT') continue;\n\t\tconst key = elementKey(child);\n\t\tavailable.set(key, [...(available.get(key) ?? []), child]);\n\t}\n\n\treturn available;\n};\n\nconst resolveHeadNode = (nav: Runtime, node: Node, context: HeadContext) => {\n\tif (!(node instanceof Element) || context.preloaded.has(node)) return node;\n\tconst existing = takeMatch(context.available, node);\n\tif (existing) return existing;\n\tif (node.tagName === 'STYLE') {\n\t\tapplyNonce(nav, node, isTrusted(node, context.trust));\n\t}\n\n\treturn document.adoptNode(node);\n};\n\n/* Keep head elements the two pages share (same tag, attributes and text):\n * no stylesheet reload, no favicon flash. Everything else is replaced.\n * Every node is kept in order, whitespace text and comments included:\n * Svelte hydrates `<svelte:head>` by walking those nodes, and a missing one\n * makes it throw the server markup away and mount again. */\nconst swapHead = (\n\tnav: Runtime,\n\tloaded: LoadedDocument,\n\theadNodes: Node[],\n\tpreloaded: Set<Element>\n) => {\n\tconst context: HeadContext = {\n\t\tavailable: indexHead(preloaded),\n\t\tpreloaded,\n\t\ttrust: loaded.trust\n\t};\n\tconst nextNodes = headNodes.map((node) =>\n\t\tresolveHeadNode(nav, node, context)\n\t);\n\tsyncAttributes(document.head, loaded.document.head);\n\tdocument.head.replaceChildren(...nextNodes);\n};\n\nconst swapBody = (nav: Runtime, loaded: LoadedDocument) => {\n\tfor (const style of Array.from(\n\t\tloaded.document.body.querySelectorAll('style')\n\t)) {\n\t\tapplyNonce(nav, style, isTrusted(style, loaded.trust));\n\t}\n\tconst nextBody = document.adoptNode(loaded.document.body);\n\tdocument.body.replaceWith(nextBody);\n};\n\nconst disposeCurrentPage = async () => {\n\tconst dispose: unknown = Reflect.get(window, DISPOSE_GLOBAL);\n\tReflect.set(window, DISPOSE_GLOBAL, undefined);\n\tReflect.set(window, READY_GLOBAL, undefined);\n\tif (typeof dispose === 'function') await Reflect.apply(dispose, window, []);\n};\n\nconst canTearDown = () =>\n\ttypeof Reflect.get(window, DISPOSE_GLOBAL) === 'function';\n\n/* ------------------------------------------------------------------ */\n/* Scripts */\n/* ------------------------------------------------------------------ */\n\nconst islandStateOf = (value: unknown) => (isRecord(value) ? value : undefined);\n\n/* A page with islands re-seeds `window.__ABS_ISLAND_STATE__` with the\n * server's store state. The live snapshot wins per store, the same rule\n * `initializeIslandStores` applies. */\nconst keepIslandState = (live: Record<string, unknown> | undefined) => {\n\tconst current = islandStateOf(Reflect.get(globalThis, ISLAND_STATE_GLOBAL));\n\tif (!live || current === live) return live;\n\tconst merged: Record<string, unknown> = { ...(current ?? {}), ...live };\n\tReflect.set(globalThis, ISLAND_STATE_GLOBAL, merged);\n\n\treturn merged;\n};\n\nconst loadEvent = (script: HTMLScriptElement) =>\n\tnew Promise<void>((resolve) => {\n\t\tscript.addEventListener('load', () => resolve(), { once: true });\n\t\tscript.addEventListener('error', () => resolve(), { once: true });\n\t});\n\nconst createScript = (nav: Runtime, pending: PendingScript) => {\n\tconst { source } = pending;\n\tconst script = document.createElement('script');\n\tArray.from(source.attributes)\n\t\t.filter(({ name }) => name !== 'nonce' && name !== 'src')\n\t\t.forEach(({ name, value }) => script.setAttribute(name, value));\n\tapplyNonce(nav, script, pending.trusted);\n\tconst src = source.getAttribute('src');\n\tconst isModule = source.type === 'module';\n\tif (src) script.src = isModule ? moduleUrlFor(nav, src) : src;\n\tif (!src) script.text = rewriteModuleSpecifiers(nav, source.text);\n\tif (src && !source.hasAttribute('async')) script.async = false;\n\n\treturn script;\n};\n\nconst runScript = async (\n\tnav: Runtime,\n\tpending: PendingScript,\n\tislandState: IslandStateRef\n) => {\n\tif (!pending.placeholder.isConnected) return;\n\tconst script = createScript(nav, pending);\n\tconst loaded = script.src ? loadEvent(script) : Promise.resolve();\n\tpending.placeholder.replaceWith(script);\n\tislandState.live = keepIslandState(islandState.live);\n\tawait loaded;\n\tislandState.live = keepIslandState(islandState.live);\n};\n\nconst clearPageGlobals = () => {\n\tfor (const name of PAGE_GLOBALS) Reflect.deleteProperty(window, name);\n};\n\n/* In document order, one at a time: an inline script that sets\n * `__INITIAL_PROPS__` has to run before the module that hydrates with it. */\nconst runScripts = (nav: Runtime, scripts: PendingScript[]) => {\n\tconst islandState: IslandStateRef = {\n\t\tlive: islandStateOf(Reflect.get(globalThis, ISLAND_STATE_GLOBAL))\n\t};\n\n\treturn scripts.reduce<Promise<void>>(\n\t\t(previous, pending) =>\n\t\t\tprevious.then(() => runScript(nav, pending, islandState)),\n\t\tPromise.resolve()\n\t);\n};\n\nconst pollForPage = async (deadline: number): Promise<void> => {\n\tif (canTearDown() || Date.now() >= deadline) return;\n\tawait delay(PAGE_READY_POLL_MS);\n\tawait pollForPage(deadline);\n};\n\n/* The hydration index registers `__ABSOLUTE_PAGE_DISPOSE__` once it has\n * mounted — possibly after an `import()` an inline bootstrap started. */\nconst waitForPageReady = async (hasModules: boolean) => {\n\tif (hasModules) await pollForPage(Date.now() + PAGE_READY_TIMEOUT_MS);\n\tconst ready: unknown = Reflect.get(window, READY_GLOBAL);\n\tif (ready instanceof Promise) await ready.catch(() => undefined);\n};\n\nconst loadsModules = (scripts: PendingScript[]) =>\n\tscripts.some(\n\t\t({ source }) =>\n\t\t\tsource.type === 'module' || /\\bimport\\s*\\(/.test(source.text)\n\t);\n\n/* ------------------------------------------------------------------ */\n/* Focus, announcement, events */\n/* ------------------------------------------------------------------ */\n\nconst ensureAnnouncer = () => {\n\tconst existing = document.getElementById(ANNOUNCER_ID);\n\tif (existing) return existing;\n\tconst region = document.createElement('div');\n\tregion.id = ANNOUNCER_ID;\n\tregion.setAttribute('aria-live', 'assertive');\n\tregion.setAttribute('aria-atomic', 'true');\n\tregion.setAttribute('role', 'status');\n\t// CSSOM, not a style attribute: a strict `style-src-attr` can't block it.\n\tObject.assign(region.style, {\n\t\tborder: '0',\n\t\tclip: 'rect(0 0 0 0)',\n\t\theight: '1px',\n\t\tmargin: '-1px',\n\t\toverflow: 'hidden',\n\t\tpadding: '0',\n\t\tposition: 'absolute',\n\t\twhiteSpace: 'nowrap',\n\t\twidth: '1px'\n\t});\n\tdocument.body.append(region);\n\n\treturn region;\n};\n\nconst announcePage = () => {\n\tconst heading = document.querySelector('h1')?.textContent?.trim();\n\tconst text = document.title || heading || window.location.pathname;\n\tensureAnnouncer().textContent = text;\n};\n\nconst resetFocus = () => {\n\tconst autofocus = document.querySelector<HTMLElement>('[autofocus]');\n\tif (autofocus) {\n\t\tautofocus.focus();\n\n\t\treturn;\n\t}\n\tif (document.activeElement instanceof HTMLElement) {\n\t\tdocument.activeElement.blur();\n\t}\n};\n\nconst dispatch = (\n\tname: string,\n\tdetail: DocumentNavigationEventDetail,\n\tcancelable: boolean\n) => window.dispatchEvent(new CustomEvent(name, { cancelable, detail }));\n\n/* ------------------------------------------------------------------ */\n/* The navigation */\n/* ------------------------------------------------------------------ */\n\nconst outcome = (value: DocumentNavigationOutcome) => value;\n\nconst reload = (request: NavigationRequest, committed: boolean) => {\n\tif (committed || request.type === 'traverse') window.location.reload();\n\telse if (request.replace) window.location.replace(request.url.href);\n\telse window.location.assign(request.url.href);\n\n\treturn outcome('reloaded');\n};\n\nconst commitHistory = (nav: Runtime, request: NavigationRequest, url: URL) => {\n\tnav.documentId = request.documentId ?? createId();\n\tif (request.type === 'traverse') {\n\t\trecordCurrentEntry(nav);\n\n\t\treturn;\n\t}\n\tconst key = currentEntryKey(nav);\n\tif (key !== undefined) {\n\t\tnav.scroll.set(key, { left: window.scrollX, top: window.scrollY });\n\t}\n\tconst state = stampState(null, nav.documentId, createId());\n\tif (request.replace) window.history.replaceState(state, '', url.href);\n\telse window.history.pushState(state, '', url.href);\n\trecordCurrentEntry(nav);\n};\n\nconst shouldAnimate = (nav: Runtime) =>\n\tnav.options.viewTransition !== false &&\n\ttypeof Reflect.get(document, 'startViewTransition') === 'function' &&\n\t!prefersReducedMotion();\n\nconst readPromise = (value: unknown, name: string) => {\n\tif (typeof value !== 'object' || value === null) return undefined;\n\tconst promise: unknown = Reflect.get(value, name);\n\n\treturn promise instanceof Promise ? promise : undefined;\n};\n\nconst runSwap = async (nav: Runtime, swap: () => Promise<void>) => {\n\tconst start: unknown = Reflect.get(document, 'startViewTransition');\n\tif (!shouldAnimate(nav) || typeof start !== 'function') {\n\t\tawait swap();\n\n\t\treturn;\n\t}\n\tconst transition: unknown = Reflect.apply(start, document, [swap]);\n\treadPromise(transition, 'ready')?.catch(() => undefined);\n\treadPromise(transition, 'finished')?.catch(() => undefined);\n\tawait readPromise(transition, 'updateCallbackDone');\n};\n\nconst swapDocument = async (\n\tnav: Runtime,\n\trequest: NavigationRequest,\n\tloaded: LoadedDocument,\n\tisStale: () => boolean\n) => {\n\tconst scripts = extractScripts(loaded);\n\t// Before the preload moves the stylesheet links out of the parsed head.\n\tconst headNodes = Array.from(loaded.document.head.childNodes);\n\tconst media = await preloadStylesheets(loaded);\n\tconst preloaded = new Set<Element>(media.keys());\n\t// A newer navigation started while the stylesheets loaded: it owns the\n\t// page now, so drop what this one added and stop.\n\tif (isStale()) {\n\t\tpreloaded.forEach((link) => link.remove());\n\n\t\treturn false;\n\t}\n\t// Outside the View Transition callback: the browser records the scroll\n\t// position of the entry being left when the new one is pushed, and inside\n\t// the callback it reads 0, which it then restores on a later back.\n\tcommitHistory(nav, request, loaded.url);\n\tconst swap = async () => {\n\t\tawait disposeCurrentPage();\n\t\tclearPageGlobals();\n\t\tsyncAttributes(\n\t\t\tdocument.documentElement,\n\t\t\tloaded.document.documentElement\n\t\t);\n\t\tswapHead(nav, loaded, headNodes, preloaded);\n\t\tswapBody(nav, loaded);\n\t\trestoreMedia(media);\n\t\tapplyScroll(request, loaded.url);\n\t};\n\tawait runSwap(nav, swap);\n\tresetFocus();\n\tawait runScripts(nav, scripts);\n\tawait waitForPageReady(loadsModules(scripts));\n\treapplyScroll(request, loaded.url);\n\tannouncePage();\n\n\treturn true;\n};\n\nconst isCurrent = (nav: Runtime, token: number) => nav.token === token;\n\nconst performNavigation = async (nav: Runtime, request: NavigationRequest) => {\n\tnav.token += 1;\n\tconst { token } = nav;\n\tnav.controller?.abort();\n\tconst controller = new AbortController();\n\tnav.controller = controller;\n\tconst detail: DocumentNavigationEventDetail = {\n\t\ttype: request.type,\n\t\turl: request.url.href\n\t};\n\tconst proceed = dispatch(\n\t\t'absolute:before-navigate',\n\t\tdetail,\n\t\trequest.type !== 'traverse'\n\t);\n\tif (!proceed) return outcome('cancelled');\n\tif (!canTearDown()) return reload(request, false);\n\n\tconst committedBefore = nav.documentId;\n\ttry {\n\t\tconst loaded = await loadDocument(nav, request.url, controller.signal);\n\t\tif (!isCurrent(nav, token)) return outcome('superseded');\n\t\tif (!loaded) return reload(request, false);\n\t\tnav.navigating = true;\n\t\tconst swapped = await swapDocument(\n\t\t\tnav,\n\t\t\trequest,\n\t\t\tloaded,\n\t\t\t() => !isCurrent(nav, token)\n\t\t);\n\t\tif (!swapped) return outcome('superseded');\n\t\tdispatch('absolute:after-navigate', detail, false);\n\n\t\treturn outcome('swapped');\n\t} catch (error) {\n\t\tif (!isCurrent(nav, token)) return outcome('superseded');\n\t\tconsole.error('[absolute] navigation failed, loading the page:', error);\n\n\t\treturn reload(request, nav.documentId !== committedBefore);\n\t} finally {\n\t\tif (isCurrent(nav, token)) nav.navigating = false;\n\t}\n};\n\n/* ------------------------------------------------------------------ */\n/* Interception */\n/* ------------------------------------------------------------------ */\n\nconst isModifiedClick = (event: MouseEvent) =>\n\tevent.metaKey || event.ctrlKey || event.shiftKey || event.altKey;\n\nconst isSamePageFragment = (url: URL) =>\n\turl.hash !== '' &&\n\turl.pathname === window.location.pathname &&\n\turl.search === window.location.search;\n\nconst findAnchor = (event: MouseEvent) => {\n\tconst { target } = event;\n\tif (!(target instanceof Element)) return null;\n\n\treturn target.closest<HTMLAnchorElement>('a[href]');\n};\n\nconst isPlainClick = (event: MouseEvent) =>\n\t!event.defaultPrevented && event.button === 0 && !isModifiedClick(event);\n\nconst isOptedOut = (anchor: HTMLAnchorElement) =>\n\t(anchor.target !== '' && anchor.target !== '_self') ||\n\tanchor.hasAttribute('download') ||\n\tanchor.relList.contains('external') ||\n\tanchor.closest(OPT_OUT_SELECTOR) !== null;\n\nconst interceptableUrl = (nav: Runtime, anchor: HTMLAnchorElement) => {\n\tif (isOptedOut(anchor)) return undefined;\n\tconst url = new URL(anchor.href, window.location.href);\n\tif (url.origin !== window.location.origin) return undefined;\n\tif (isSamePageFragment(url)) return undefined;\n\tif (nav.options.shouldIntercept?.(url) === false) return undefined;\n\n\treturn url;\n};\n\n/* Bubble phase on window: runs after every framework router's handler, so\n * a click a router handled (`preventDefault`) never reaches this. */\nconst listenForClicks = (nav: Runtime) => {\n\tconst onClick = (event: MouseEvent) => {\n\t\tif (!isPlainClick(event)) return;\n\t\tconst anchor = findAnchor(event);\n\t\tconst url = anchor ? interceptableUrl(nav, anchor) : undefined;\n\t\tif (!url || !canTearDown()) return;\n\t\tevent.preventDefault();\n\t\tvoid performNavigation(nav, { replace: false, type: 'link', url });\n\t};\n\twindow.addEventListener('click', onClick);\n\tnav.teardown.push(() => window.removeEventListener('click', onClick));\n};\n\n/* Capture phase, so it runs before the routers' popstate listeners: a\n * traversal onto another document's entry is stopped here and swapped. */\nconst listenForTraversals = (nav: Runtime) => {\n\tconst onPopState = (event: PopStateEvent) => {\n\t\tif (!isForeignEntry(nav)) return;\n\t\tevent.stopImmediatePropagation();\n\t\tconst owner = currentEntryOwner(nav);\n\t\tconst key = currentEntryKey(nav);\n\t\tvoid performNavigation(nav, {\n\t\t\tdocumentId: owner,\n\t\t\treplace: false,\n\t\t\tscroll: key === undefined ? undefined : nav.scroll.get(key),\n\t\t\ttype: 'traverse',\n\t\t\turl: new URL(window.location.href)\n\t\t});\n\t};\n\twindow.addEventListener('popstate', onPopState, { capture: true });\n\tnav.teardown.push(() =>\n\t\twindow.removeEventListener('popstate', onPopState, { capture: true })\n\t);\n};\n\n/* ------------------------------------------------------------------ */\n/* Public API */\n/* ------------------------------------------------------------------ */\n\n/** Turn the layer off: listeners removed, history methods restored. */\nexport const disableNavigation = () => {\n\tconst installed = readPublicRuntime();\n\tif (installed && typeof installed.disable === 'function') {\n\t\tReflect.apply(installed.disable, undefined, []);\n\t}\n};\n\nconst teardownRuntime = (nav: Runtime) => {\n\tnav.controller?.abort();\n\tfor (const cleanup of nav.teardown.splice(0)) cleanup();\n\tnav.restoreHistory?.();\n\tReflect.deleteProperty(globalThis, RUNTIME_KEY);\n\tif (runtime === nav) runtime = undefined;\n};\n\nconst navigateWith =\n\t(nav: Runtime) =>\n\t(href: string, options: NavigateDocumentOptions = {}) => {\n\t\tconst url = new URL(href, window.location.href);\n\t\tif (url.origin !== window.location.origin) {\n\t\t\twindow.location.assign(url.href);\n\n\t\t\treturn Promise.resolve<DocumentNavigationOutcome>('reloaded');\n\t\t}\n\n\t\treturn performNavigation(nav, {\n\t\t\treplace: options.replace === true,\n\t\t\ttype: 'navigate',\n\t\t\turl\n\t\t});\n\t};\n\n/**\n * Install cross-framework document navigation for this tab. Idempotent:\n * every page can call it (each framework bundle carries its own copy of\n * this module; the first call wins and its options apply).\n */\nexport const enableNavigation = (options: EnableNavigationOptions = {}) => {\n\tif (typeof window === 'undefined' || readPublicRuntime()) return;\n\tconst navigationApi = readNavigationApi();\n\tconst nav: Runtime = {\n\t\tcontroller: undefined,\n\t\tdocumentId: createId(),\n\t\tentryOwners: new Map(),\n\t\tevaluatedModules: new Set(),\n\t\tmoduleRun: 0,\n\t\tnavigating: false,\n\t\tnavigationApi,\n\t\tnonce: readPageNonce(),\n\t\toptions,\n\t\trestoreHistory: undefined,\n\t\tscroll: new Map(),\n\t\tscrollFrame: 0,\n\t\tteardown: [],\n\t\ttoken: 0\n\t};\n\truntime = nav;\n\tif (navigationApi) trackEntries(nav, navigationApi);\n\telse patchHistory(nav);\n\trememberDocumentModules(nav);\n\ttrackScroll(nav);\n\tlistenForClicks(nav);\n\tlistenForTraversals(nav);\n\tconst publicRuntime: PublicRuntime = {\n\t\tnavigate: navigateWith(nav),\n\t\tdisable: () => teardownRuntime(nav)\n\t};\n\tReflect.set(globalThis, RUNTIME_KEY, publicRuntime);\n};\n\nconst OUTCOMES = new Set<unknown>([\n\t'cancelled',\n\t'reloaded',\n\t'superseded',\n\t'swapped'\n]);\n\nconst isOutcome = (value: unknown): value is DocumentNavigationOutcome =>\n\tOUTCOMES.has(value);\n\n/** Whether `enableNavigation()` is active in this tab. */\nexport const isNavigationEnabled = () =>\n\ttypeof window !== 'undefined' && readPublicRuntime() !== undefined;\n\n/**\n * Navigate to `href` through the layer: a soft swap when it is enabled\n * and the page can be torn down, a normal page load otherwise.\n */\nexport const navigateDocument = async (\n\thref: string,\n\toptions: NavigateDocumentOptions = {}\n) => {\n\tconst installed = readPublicRuntime();\n\tconst navigate = installed?.navigate;\n\tif (typeof navigate === 'function') {\n\t\tconst result: unknown = await Reflect.apply(navigate, undefined, [\n\t\t\thref,\n\t\t\toptions\n\t\t]);\n\t\tif (isOutcome(result)) return result;\n\t}\n\tif (options.replace) window.location.replace(href);\n\telse window.location.assign(href);\n\n\treturn outcome('reloaded');\n};\n"
|
|
6
|
+
],
|
|
7
|
+
"mappings": "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",
|
|
8
|
+
"debugId": "4ABAC329D93956C564756E2164756E21",
|
|
9
|
+
"names": []
|
|
10
|
+
}
|
package/dist/client/prefetch.js
CHANGED
|
@@ -1,379 +1,37 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
var storageKind = (kind) => kind === "route" ? "document" : kind;
|
|
19
|
-
var cacheKey = (kind, url) => `${storageKind(kind)}:${url}`;
|
|
20
|
-
var resolveHref = (url) => {
|
|
21
|
-
if (typeof window === "undefined")
|
|
22
|
-
return url;
|
|
23
|
-
try {
|
|
24
|
-
return new URL(url, window.location.href).href;
|
|
25
|
-
} catch {
|
|
26
|
-
return url;
|
|
27
|
-
}
|
|
28
|
-
};
|
|
29
|
-
var isGloballyDisabled = () => typeof window !== "undefined" && Reflect.get(window, "__ABSOLUTE_PREFETCH__") === false;
|
|
30
|
-
var isSlowConnection = () => {
|
|
31
|
-
if (typeof navigator === "undefined")
|
|
32
|
-
return false;
|
|
33
|
-
const connection = Reflect.get(navigator, "connection");
|
|
34
|
-
if (typeof connection !== "object" || connection === null)
|
|
35
|
-
return false;
|
|
36
|
-
if (Reflect.get(connection, "saveData") === true)
|
|
37
|
-
return true;
|
|
38
|
-
const effectiveType = Reflect.get(connection, "effectiveType");
|
|
39
|
-
return typeof effectiveType === "string" && SLOW_EFFECTIVE_TYPES.has(effectiveType);
|
|
40
|
-
};
|
|
41
|
-
var prefersReducedData = () => {
|
|
42
|
-
if (typeof window === "undefined" || !window.matchMedia)
|
|
43
|
-
return false;
|
|
44
|
-
return window.matchMedia("(prefers-reduced-data: reduce)").matches;
|
|
45
|
-
};
|
|
46
|
-
var canPrefetch = () => typeof window !== "undefined" && !isGloballyDisabled() && !isSlowConnection() && !prefersReducedData();
|
|
47
|
-
var readNodeEnv = () => {
|
|
48
|
-
const processLike = Reflect.get(globalThis, "process");
|
|
49
|
-
if (typeof processLike !== "object" || processLike === null) {
|
|
50
|
-
return;
|
|
51
|
-
}
|
|
52
|
-
const env = Reflect.get(processLike, "env");
|
|
53
|
-
if (typeof env !== "object" || env === null)
|
|
54
|
-
return;
|
|
55
|
-
const value = Reflect.get(env, "NODE_ENV");
|
|
56
|
-
return typeof value === "string" ? value : undefined;
|
|
57
|
-
};
|
|
58
|
-
var isDevelopmentClient = () => {
|
|
59
|
-
if (typeof window === "undefined")
|
|
60
|
-
return false;
|
|
61
|
-
if (Reflect.get(window, "__HMR_FRAMEWORK__") !== undefined)
|
|
62
|
-
return true;
|
|
63
|
-
if (Reflect.get(window, "__HMR_WS__") !== undefined)
|
|
64
|
-
return true;
|
|
65
|
-
if (typeof document !== "undefined" && document.querySelector("script[data-hmr-client]") !== null) {
|
|
66
|
-
return true;
|
|
67
|
-
}
|
|
68
|
-
return readNodeEnv() === "development";
|
|
69
|
-
};
|
|
70
|
-
var isPrefetchableHref = (href) => {
|
|
71
|
-
if (typeof window === "undefined")
|
|
72
|
-
return false;
|
|
73
|
-
if (href === "" || href.startsWith("#"))
|
|
74
|
-
return false;
|
|
75
|
-
try {
|
|
76
|
-
const url = new URL(href, window.location.href);
|
|
77
|
-
if (url.protocol !== "http:" && url.protocol !== "https:")
|
|
78
|
-
return false;
|
|
79
|
-
return url.origin === window.location.origin;
|
|
80
|
-
} catch {
|
|
81
|
-
return false;
|
|
82
|
-
}
|
|
83
|
-
};
|
|
84
|
-
var resolveDefaultPrefetchMode = () => isDevelopmentClient() ? "hover" : "viewport";
|
|
85
|
-
var runQueue = () => {
|
|
86
|
-
while (inFlight < MAX_IN_FLIGHT) {
|
|
87
|
-
const next = queue.shift();
|
|
88
|
-
if (!next)
|
|
89
|
-
return;
|
|
90
|
-
if (next.cancelled)
|
|
91
|
-
continue;
|
|
92
|
-
next.start();
|
|
93
|
-
}
|
|
94
|
-
};
|
|
95
|
-
var finishTask = () => {
|
|
96
|
-
inFlight = Math.max(0, inFlight - 1);
|
|
97
|
-
runQueue();
|
|
98
|
-
};
|
|
99
|
-
var runWhenReleased = async (gate, task, signal) => {
|
|
100
|
-
await gate;
|
|
101
|
-
try {
|
|
102
|
-
return await task(signal);
|
|
103
|
-
} catch {
|
|
104
|
-
return offlineResponse();
|
|
105
|
-
} finally {
|
|
106
|
-
finishTask();
|
|
107
|
-
}
|
|
108
|
-
};
|
|
109
|
-
var enqueue = (task) => {
|
|
110
|
-
const controller = new AbortController;
|
|
111
|
-
let release = () => {
|
|
112
|
-
return;
|
|
113
|
-
};
|
|
114
|
-
const gate = new Promise((resolve) => {
|
|
115
|
-
release = resolve;
|
|
116
|
-
});
|
|
117
|
-
const queued = {
|
|
118
|
-
cancelled: false,
|
|
119
|
-
start: () => {
|
|
120
|
-
inFlight += 1;
|
|
121
|
-
release();
|
|
122
|
-
}
|
|
123
|
-
};
|
|
124
|
-
const promise = runWhenReleased(gate, task, controller.signal);
|
|
125
|
-
queue.push(queued);
|
|
126
|
-
runQueue();
|
|
127
|
-
const abort = () => {
|
|
128
|
-
if (queued.cancelled)
|
|
129
|
-
return;
|
|
130
|
-
queued.cancelled = true;
|
|
131
|
-
controller.abort();
|
|
132
|
-
};
|
|
133
|
-
return { abort, promise };
|
|
134
|
-
};
|
|
135
|
-
var evictOldest = () => {
|
|
136
|
-
const oldest = cache.keys().next();
|
|
137
|
-
if (oldest.done)
|
|
138
|
-
return;
|
|
139
|
-
cache.get(oldest.value)?.abort();
|
|
140
|
-
cache.delete(oldest.value);
|
|
141
|
-
};
|
|
142
|
-
var touch = (key, entry) => {
|
|
143
|
-
cache.delete(key);
|
|
144
|
-
cache.set(key, entry);
|
|
145
|
-
};
|
|
146
|
-
var clearPrefetchCache = () => {
|
|
147
|
-
for (const entry of cache.values())
|
|
148
|
-
entry.abort();
|
|
149
|
-
cache.clear();
|
|
150
|
-
};
|
|
151
|
-
var consumePrefetch = (url, kind = "document") => {
|
|
152
|
-
const key = cacheKey(kind, url);
|
|
153
|
-
const entry = cache.get(key);
|
|
154
|
-
if (!entry)
|
|
155
|
-
return;
|
|
156
|
-
cache.delete(key);
|
|
157
|
-
return entry.promise;
|
|
158
|
-
};
|
|
159
|
-
var hasPrefetched = (url, kind = "document") => cache.has(cacheKey(kind, url));
|
|
160
|
-
var injectLink = (rel, href, asType) => {
|
|
161
|
-
if (typeof document === "undefined")
|
|
162
|
-
return;
|
|
163
|
-
const link = document.createElement("link");
|
|
164
|
-
link.rel = rel;
|
|
165
|
-
link.href = href;
|
|
166
|
-
if (asType)
|
|
167
|
-
link.setAttribute("as", asType);
|
|
168
|
-
document.head.append(link);
|
|
169
|
-
};
|
|
170
|
-
var injectPrefetchFallback = (kind, url) => {
|
|
171
|
-
if (kind !== "document" || !supportsLinkRel("prefetch"))
|
|
172
|
-
return;
|
|
173
|
-
injectLink("prefetch", url, "document");
|
|
174
|
-
};
|
|
175
|
-
var supportsLinkRel = (rel) => {
|
|
176
|
-
if (typeof document === "undefined")
|
|
177
|
-
return false;
|
|
178
|
-
const link = document.createElement("link");
|
|
179
|
-
return typeof link.relList?.supports === "function" && link.relList.supports(rel);
|
|
180
|
-
};
|
|
181
|
-
var prefetchStylesheet = (href) => {
|
|
182
|
-
if (typeof document === "undefined")
|
|
183
|
-
return false;
|
|
184
|
-
const resolved = resolveHref(href);
|
|
185
|
-
if (prefetchedStyles.has(resolved))
|
|
186
|
-
return false;
|
|
187
|
-
prefetchedStyles.add(resolved);
|
|
188
|
-
injectLink("prefetch", href, "style");
|
|
189
|
-
return true;
|
|
190
|
-
};
|
|
191
|
-
var preloadModule = (href) => {
|
|
192
|
-
if (typeof document === "undefined")
|
|
193
|
-
return false;
|
|
194
|
-
const resolved = resolveHref(href);
|
|
195
|
-
if (preloadedModules.has(resolved))
|
|
196
|
-
return false;
|
|
197
|
-
const existing = Array.from(document.querySelectorAll('link[rel="modulepreload"]'));
|
|
198
|
-
if (existing.some((link) => resolveHref(link.href) === resolved)) {
|
|
199
|
-
preloadedModules.add(resolved);
|
|
200
|
-
return false;
|
|
201
|
-
}
|
|
202
|
-
preloadedModules.add(resolved);
|
|
203
|
-
injectLink("modulepreload", href);
|
|
204
|
-
return true;
|
|
205
|
-
};
|
|
206
|
-
var isRecord = (value) => typeof value === "object" && value !== null;
|
|
207
|
-
var isHref = (value) => typeof value === "string" && value.length > 0;
|
|
208
|
-
var warmRouteDataAssets = (envelope) => {
|
|
209
|
-
if (!isRecord(envelope))
|
|
210
|
-
return;
|
|
211
|
-
const { assets } = envelope;
|
|
212
|
-
if (!isRecord(assets))
|
|
213
|
-
return;
|
|
214
|
-
const { client, css, index } = assets;
|
|
215
|
-
for (const href of [index, client].filter(isHref))
|
|
216
|
-
preloadModule(href);
|
|
217
|
-
if (!Array.isArray(css))
|
|
218
|
-
return;
|
|
219
|
-
for (const href of css.filter(isHref))
|
|
220
|
-
prefetchStylesheet(href);
|
|
221
|
-
};
|
|
222
|
-
var warmFromRouteData = async (response) => {
|
|
223
|
-
try {
|
|
224
|
-
warmRouteDataAssets(await response.clone().json());
|
|
225
|
-
} catch {}
|
|
226
|
-
return response;
|
|
227
|
-
};
|
|
228
|
-
var fetchDocument = (url, signal) => fetch(url, { credentials: "same-origin", signal });
|
|
229
|
-
var fetchRouteData = async (url, signal) => {
|
|
230
|
-
const response = await fetch(url, {
|
|
231
|
-
credentials: "same-origin",
|
|
232
|
-
headers: { Accept: ROUTE_DATA_MEDIA_TYPE },
|
|
233
|
-
signal
|
|
234
|
-
});
|
|
235
|
-
const contentType = response.headers.get("content-type") ?? "";
|
|
236
|
-
const isRouteData = response.ok && contentType.includes(ROUTE_DATA_MEDIA_TYPE);
|
|
237
|
-
if (isRouteData)
|
|
238
|
-
return warmFromRouteData(response);
|
|
239
|
-
await response.body?.cancel().catch(() => {
|
|
240
|
-
return;
|
|
241
|
-
});
|
|
242
|
-
const status = response.status === NOT_FOUND || response.status === NOT_ACCEPTABLE ? response.status : NOT_ACCEPTABLE;
|
|
243
|
-
return new Response(null, { status });
|
|
244
|
-
};
|
|
245
|
-
var prefetch = (url, options = {}) => {
|
|
246
|
-
const kind = options.kind ?? "document";
|
|
247
|
-
if (!canPrefetch())
|
|
248
|
-
return;
|
|
249
|
-
if (kind === "module") {
|
|
250
|
-
preloadModule(url);
|
|
251
|
-
return;
|
|
252
|
-
}
|
|
253
|
-
if (kind === "route") {
|
|
254
|
-
prefetch(url, { kind: "document" });
|
|
255
|
-
prefetch(url, { kind: "data" });
|
|
256
|
-
return;
|
|
257
|
-
}
|
|
258
|
-
const key = cacheKey(kind, url);
|
|
259
|
-
const existing = cache.get(key);
|
|
260
|
-
if (existing) {
|
|
261
|
-
touch(key, existing);
|
|
262
|
-
return;
|
|
263
|
-
}
|
|
264
|
-
if (typeof fetch === "undefined") {
|
|
265
|
-
injectPrefetchFallback(kind, url);
|
|
266
|
-
return;
|
|
267
|
-
}
|
|
268
|
-
while (cache.size >= PREFETCH_CACHE_LIMIT)
|
|
269
|
-
evictOldest();
|
|
270
|
-
const { abort, promise } = enqueue((signal) => kind === "data" ? fetchRouteData(url, signal) : fetchDocument(url, signal));
|
|
271
|
-
cache.set(key, { abort, kind, promise, url });
|
|
272
|
-
};
|
|
273
|
-
var supportsSpeculationRules = () => typeof HTMLScriptElement !== "undefined" && typeof HTMLScriptElement.supports === "function" && HTMLScriptElement.supports("speculationrules");
|
|
274
|
-
var speculate = (url) => {
|
|
275
|
-
if (!canPrefetch() || !supportsSpeculationRules())
|
|
276
|
-
return false;
|
|
277
|
-
if (typeof document === "undefined")
|
|
278
|
-
return false;
|
|
279
|
-
const resolved = resolveHref(url);
|
|
280
|
-
if (liveSpeculationRules.has(resolved))
|
|
281
|
-
return false;
|
|
282
|
-
while (liveSpeculationRules.size >= MAX_LIVE_SPECULATION_RULES) {
|
|
283
|
-
const oldest = liveSpeculationRules.keys().next();
|
|
284
|
-
if (oldest.done)
|
|
285
|
-
break;
|
|
286
|
-
liveSpeculationRules.get(oldest.value)?.remove();
|
|
287
|
-
liveSpeculationRules.delete(oldest.value);
|
|
288
|
-
}
|
|
289
|
-
const script = document.createElement("script");
|
|
290
|
-
script.type = "speculationrules";
|
|
291
|
-
script.textContent = JSON.stringify({
|
|
292
|
-
prerender: [{ eagerness: "immediate", urls: [url] }]
|
|
293
|
-
});
|
|
294
|
-
document.head.append(script);
|
|
295
|
-
liveSpeculationRules.set(resolved, script);
|
|
296
|
-
return true;
|
|
297
|
-
};
|
|
298
|
-
var noopHandle = {
|
|
299
|
-
cancel: () => {}
|
|
300
|
-
};
|
|
301
|
-
var scheduleHoverPrefetch = (url, options = {}) => {
|
|
302
|
-
if (typeof window === "undefined")
|
|
303
|
-
return noopHandle;
|
|
304
|
-
const timer = window.setTimeout(() => {
|
|
305
|
-
prefetch(url, { kind: options.kind ?? "route" });
|
|
306
|
-
if (options.prerender)
|
|
307
|
-
speculate(url);
|
|
308
|
-
}, HOVER_DEBOUNCE_MS);
|
|
309
|
-
return {
|
|
310
|
-
cancel: () => window.clearTimeout(timer)
|
|
311
|
-
};
|
|
312
|
-
};
|
|
313
|
-
var viewportTargets = new WeakMap;
|
|
314
|
-
var viewportObserver = null;
|
|
315
|
-
var handleIntersections = (entries) => {
|
|
316
|
-
for (const entry of entries) {
|
|
317
|
-
if (!entry.isIntersecting)
|
|
318
|
-
continue;
|
|
319
|
-
const target = viewportTargets.get(entry.target);
|
|
320
|
-
viewportObserver?.unobserve(entry.target);
|
|
321
|
-
viewportTargets.delete(entry.target);
|
|
322
|
-
if (target)
|
|
323
|
-
prefetch(target.url, target.options);
|
|
324
|
-
}
|
|
325
|
-
};
|
|
326
|
-
var getViewportObserver = () => {
|
|
327
|
-
if (viewportObserver)
|
|
328
|
-
return viewportObserver;
|
|
329
|
-
if (typeof IntersectionObserver === "undefined")
|
|
330
|
-
return null;
|
|
331
|
-
viewportObserver = new IntersectionObserver(handleIntersections, {
|
|
332
|
-
rootMargin: VIEWPORT_ROOT_MARGIN
|
|
333
|
-
});
|
|
334
|
-
return viewportObserver;
|
|
335
|
-
};
|
|
336
|
-
var observeViewport = (element, url, options = {}) => {
|
|
337
|
-
const observer = getViewportObserver();
|
|
338
|
-
if (!observer || !canPrefetch())
|
|
339
|
-
return () => {
|
|
340
|
-
return;
|
|
341
|
-
};
|
|
342
|
-
viewportTargets.set(element, { options, url });
|
|
343
|
-
observer.observe(element);
|
|
344
|
-
return () => {
|
|
345
|
-
observer.unobserve(element);
|
|
346
|
-
viewportTargets.delete(element);
|
|
347
|
-
};
|
|
348
|
-
};
|
|
349
|
-
var resetPrefetchState = () => {
|
|
350
|
-
clearPrefetchCache();
|
|
351
|
-
queue.length = 0;
|
|
352
|
-
preloadedModules.clear();
|
|
353
|
-
prefetchedStyles.clear();
|
|
354
|
-
for (const script of liveSpeculationRules.values())
|
|
355
|
-
script.remove();
|
|
356
|
-
liveSpeculationRules.clear();
|
|
357
|
-
viewportObserver?.disconnect();
|
|
358
|
-
viewportObserver = null;
|
|
359
|
-
};
|
|
1
|
+
import {
|
|
2
|
+
ROUTE_DATA_MEDIA_TYPE2,
|
|
3
|
+
canPrefetch2,
|
|
4
|
+
isDevelopmentClient2,
|
|
5
|
+
isPrefetchableHref2,
|
|
6
|
+
resolveDefaultPrefetchMode2,
|
|
7
|
+
clearPrefetchCache2,
|
|
8
|
+
consumePrefetch2,
|
|
9
|
+
hasPrefetched2,
|
|
10
|
+
prefetchStylesheet2,
|
|
11
|
+
preloadModule2,
|
|
12
|
+
prefetch2,
|
|
13
|
+
speculate2,
|
|
14
|
+
scheduleHoverPrefetch2,
|
|
15
|
+
observeViewport2,
|
|
16
|
+
resetPrefetchState2
|
|
17
|
+
} from "./chunks/index-6b66nzyf.js";
|
|
360
18
|
export {
|
|
361
|
-
ROUTE_DATA_MEDIA_TYPE,
|
|
362
|
-
canPrefetch,
|
|
363
|
-
clearPrefetchCache,
|
|
364
|
-
consumePrefetch,
|
|
365
|
-
hasPrefetched,
|
|
366
|
-
isDevelopmentClient,
|
|
367
|
-
isPrefetchableHref,
|
|
368
|
-
observeViewport,
|
|
369
|
-
prefetch,
|
|
370
|
-
prefetchStylesheet,
|
|
371
|
-
preloadModule,
|
|
372
|
-
resetPrefetchState,
|
|
373
|
-
resolveDefaultPrefetchMode,
|
|
374
|
-
scheduleHoverPrefetch,
|
|
375
|
-
speculate
|
|
19
|
+
ROUTE_DATA_MEDIA_TYPE2 as ROUTE_DATA_MEDIA_TYPE,
|
|
20
|
+
canPrefetch2 as canPrefetch,
|
|
21
|
+
clearPrefetchCache2 as clearPrefetchCache,
|
|
22
|
+
consumePrefetch2 as consumePrefetch,
|
|
23
|
+
hasPrefetched2 as hasPrefetched,
|
|
24
|
+
isDevelopmentClient2 as isDevelopmentClient,
|
|
25
|
+
isPrefetchableHref2 as isPrefetchableHref,
|
|
26
|
+
observeViewport2 as observeViewport,
|
|
27
|
+
prefetch2 as prefetch,
|
|
28
|
+
prefetchStylesheet2 as prefetchStylesheet,
|
|
29
|
+
preloadModule2 as preloadModule,
|
|
30
|
+
resetPrefetchState2 as resetPrefetchState,
|
|
31
|
+
resolveDefaultPrefetchMode2 as resolveDefaultPrefetchMode,
|
|
32
|
+
scheduleHoverPrefetch2 as scheduleHoverPrefetch,
|
|
33
|
+
speculate2 as speculate
|
|
376
34
|
};
|
|
377
35
|
|
|
378
|
-
//# debugId=
|
|
36
|
+
//# debugId=546CCCC476E36A1464756E2164756E21
|
|
379
37
|
//# sourceMappingURL=prefetch.js.map
|
|
@@ -1,10 +1,9 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
|
-
"sources": [
|
|
3
|
+
"sources": [],
|
|
4
4
|
"sourcesContent": [
|
|
5
|
-
"/**\n * Framework-neutral navigation prefetch primitive.\n *\n * Pure DOM + `fetch` — no framework imports — so the React, Vue and Svelte\n * `<Link>` components (and user code) share one cache, one in-flight\n * budget, one IntersectionObserver and one set of data-saver guards.\n *\n * import { prefetch, speculate } from '@absolutejs/absolute/client/prefetch';\n *\n * What a prefetch buys the click that follows:\n * - `'document'` — the HTML lands in the browser's HTTP cache (pages\n * carry a content-hash `ETag`), so the real navigation revalidates\n * with a 304 instead of re-rendering.\n * - `'module'` — `<link rel=\"modulepreload\">` parses + compiles the\n * client module graph ahead of time.\n * - `'data'` — the route-data payload\n * (`application/vnd.absolute.route+json`): the page's props plus the\n * client entry and stylesheets it needs, which are `modulepreload`ed\n * / prefetched as the payload lands. A 404 / 406 from a server that\n * doesn't speak route data is remembered as \"no data\".\n * - `'route'` — `'document'` + `'data'`, i.e. everything a click\n * needs. What a `<Link>` warms on hover / pointerdown.\n * - `speculate()` — a prerender speculation rule; the browser renders\n * the whole target page in a hidden tab so the click is instant.\n *\n * Global opt-out: `window.__ABSOLUTE_PREFETCH__ = false` disables every\n * entry point in this module (useful for analytics-sensitive pages).\n */\nimport type {\n\tHoverPrefetchHandle,\n\tHoverPrefetchOptions,\n\tPrefetchKind,\n\tPrefetchOptions\n} from '../../types/prefetch';\n\nconst PREFETCH_CACHE_LIMIT = 16;\nconst HOVER_DEBOUNCE_MS = 250;\nconst MAX_IN_FLIGHT = 2;\nconst MAX_LIVE_SPECULATION_RULES = 2;\nconst VIEWPORT_ROOT_MARGIN = '128px';\nconst SLOW_EFFECTIVE_TYPES = new Set(['slow-2g', '2g']);\nconst NOT_FOUND = 404;\nconst NOT_ACCEPTABLE = 406;\n\nexport const ROUTE_DATA_MEDIA_TYPE = 'application/vnd.absolute.route+json';\n\ntype CacheEntry = {\n\tabort: () => void;\n\tkind: PrefetchKind;\n\tpromise: Promise<Response>;\n\turl: string;\n};\n\ntype QueuedTask = {\n\tcancelled: boolean;\n\tstart: () => void;\n};\n\nconst cache = new Map<string, CacheEntry>();\nconst queue: QueuedTask[] = [];\nlet inFlight = 0;\n\nconst preloadedModules = new Set<string>();\nconst prefetchedStyles = new Set<string>();\nconst liveSpeculationRules = new Map<string, HTMLScriptElement>();\n\nconst offlineResponse = () => new Response(null, { status: 0 });\n\n/** `'route'` is a compound trigger, not a cache entry of its own: it\n * warms the `'document'` and `'data'` entries, so lookups for it read\n * the document it warmed. */\nconst storageKind = (kind: PrefetchKind) =>\n\tkind === 'route' ? 'document' : kind;\n\nconst cacheKey = (kind: PrefetchKind, url: string) =>\n\t`${storageKind(kind)}:${url}`;\n\nconst resolveHref = (url: string) => {\n\tif (typeof window === 'undefined') return url;\n\n\ttry {\n\t\treturn new URL(url, window.location.href).href;\n\t} catch {\n\t\treturn url;\n\t}\n};\n\n/* ------------------------------------------------------------------ */\n/* Guards */\n/* ------------------------------------------------------------------ */\n\nconst isGloballyDisabled = () =>\n\ttypeof window !== 'undefined' &&\n\tReflect.get(window, '__ABSOLUTE_PREFETCH__') === false;\n\nconst isSlowConnection = () => {\n\tif (typeof navigator === 'undefined') return false;\n\n\tconst connection = Reflect.get(navigator, 'connection');\n\tif (typeof connection !== 'object' || connection === null) return false;\n\tif (Reflect.get(connection, 'saveData') === true) return true;\n\n\tconst effectiveType = Reflect.get(connection, 'effectiveType');\n\n\treturn (\n\t\ttypeof effectiveType === 'string' &&\n\t\tSLOW_EFFECTIVE_TYPES.has(effectiveType)\n\t);\n};\n\nconst prefersReducedData = () => {\n\tif (typeof window === 'undefined' || !window.matchMedia) return false;\n\n\treturn window.matchMedia('(prefers-reduced-data: reduce)').matches;\n};\n\n/** `true` when prefetching is allowed right now: we're in a browser, the\n * page hasn't opted out via `window.__ABSOLUTE_PREFETCH__ = false`, and\n * the user hasn't asked for less data (Save-Data, 2g, reduced-data). */\nexport const canPrefetch = () =>\n\ttypeof window !== 'undefined' &&\n\t!isGloballyDisabled() &&\n\t!isSlowConnection() &&\n\t!prefersReducedData();\n\nconst readNodeEnv = () => {\n\t// Deliberately not the bare `process.env.NODE_ENV` member expression:\n\t// bundlers substitute that at build time, which would bake this\n\t// package's own build environment into the shipped client entry. In a\n\t// browser `process` is undefined and this yields `undefined`.\n\tconst processLike = Reflect.get(globalThis, 'process');\n\tif (typeof processLike !== 'object' || processLike === null) {\n\t\treturn undefined;\n\t}\n\tconst env = Reflect.get(processLike, 'env');\n\tif (typeof env !== 'object' || env === null) return undefined;\n\tconst value = Reflect.get(env, 'NODE_ENV');\n\n\treturn typeof value === 'string' ? value : undefined;\n};\n\n/** Whether the page was served by the AbsoluteJS dev server. The HMR\n * client is only injected in dev, so its markers are the reliable\n * signal; `NODE_ENV` is the fallback for environments that bundle\n * without the dev server (tests, custom hosts). */\nexport const isDevelopmentClient = () => {\n\tif (typeof window === 'undefined') return false;\n\tif (Reflect.get(window, '__HMR_FRAMEWORK__') !== undefined) return true;\n\tif (Reflect.get(window, '__HMR_WS__') !== undefined) return true;\n\tif (\n\t\ttypeof document !== 'undefined' &&\n\t\tdocument.querySelector('script[data-hmr-client]') !== null\n\t) {\n\t\treturn true;\n\t}\n\n\treturn readNodeEnv() === 'development';\n};\n\n/** Same-origin, non-hash, http(s) URL — the only kind worth prefetching. */\nexport const isPrefetchableHref = (href: string) => {\n\tif (typeof window === 'undefined') return false;\n\tif (href === '' || href.startsWith('#')) return false;\n\n\ttry {\n\t\tconst url = new URL(href, window.location.href);\n\t\tif (url.protocol !== 'http:' && url.protocol !== 'https:') return false;\n\n\t\treturn url.origin === window.location.origin;\n\t} catch {\n\t\treturn false;\n\t}\n};\n\n/** Production → `'viewport'` (viewport + hover). Development → `'hover'`\n * only, so a page full of links doesn't fan out into the dev server. */\nexport const resolveDefaultPrefetchMode = () =>\n\tisDevelopmentClient() ? 'hover' : 'viewport';\n\n/* ------------------------------------------------------------------ */\n/* In-flight budget */\n/* ------------------------------------------------------------------ */\n\nconst runQueue = () => {\n\twhile (inFlight < MAX_IN_FLIGHT) {\n\t\tconst next = queue.shift();\n\t\tif (!next) return;\n\t\tif (next.cancelled) continue;\n\t\tnext.start();\n\t}\n};\n\nconst finishTask = () => {\n\tinFlight = Math.max(0, inFlight - 1);\n\trunQueue();\n};\n\n/** Run `task` when one of the `MAX_IN_FLIGHT` slots frees up. The\n * returned promise never rejects — network failures resolve to a\n * status-0 response so consumers can treat \"no prefetch\" uniformly. */\nconst runWhenReleased = async (\n\tgate: Promise<void>,\n\ttask: (signal: AbortSignal) => Promise<Response>,\n\tsignal: AbortSignal\n) => {\n\tawait gate;\n\ttry {\n\t\treturn await task(signal);\n\t} catch {\n\t\treturn offlineResponse();\n\t} finally {\n\t\tfinishTask();\n\t}\n};\n\nconst enqueue = (task: (signal: AbortSignal) => Promise<Response>) => {\n\tconst controller = new AbortController();\n\tlet release: () => void = () => undefined;\n\tconst gate = new Promise<void>((resolve) => {\n\t\trelease = resolve;\n\t});\n\tconst queued: QueuedTask = {\n\t\tcancelled: false,\n\t\tstart: () => {\n\t\t\t// Count the slot synchronously so `runQueue` can't overshoot the\n\t\t\t// budget while the async runner is still waiting on the gate.\n\t\t\tinFlight += 1;\n\t\t\trelease();\n\t\t}\n\t};\n\tconst promise = runWhenReleased(gate, task, controller.signal);\n\tqueue.push(queued);\n\trunQueue();\n\n\tconst abort = () => {\n\t\tif (queued.cancelled) return;\n\t\tqueued.cancelled = true;\n\t\tcontroller.abort();\n\t};\n\n\treturn { abort, promise };\n};\n\n/* ------------------------------------------------------------------ */\n/* Cache */\n/* ------------------------------------------------------------------ */\n\nconst evictOldest = () => {\n\tconst oldest = cache.keys().next();\n\tif (oldest.done) return;\n\tcache.get(oldest.value)?.abort();\n\tcache.delete(oldest.value);\n};\n\nconst touch = (key: string, entry: CacheEntry) => {\n\t// Re-insert so Map iteration order doubles as LRU recency.\n\tcache.delete(key);\n\tcache.set(key, entry);\n};\n\nexport const clearPrefetchCache = () => {\n\tfor (const entry of cache.values()) entry.abort();\n\tcache.clear();\n};\n\n/** Take the prefetched response for `url` out of the cache. Returns\n * `undefined` when nothing was prefetched (or it was evicted). Callers\n * that fetch the same URL themselves can await this instead. */\nexport const consumePrefetch = (\n\turl: string,\n\tkind: PrefetchKind = 'document'\n) => {\n\tconst key = cacheKey(kind, url);\n\tconst entry = cache.get(key);\n\tif (!entry) return undefined;\n\tcache.delete(key);\n\n\treturn entry.promise;\n};\n\n/** Whether `url` is already prefetched (in flight, queued or settled). */\nexport const hasPrefetched = (url: string, kind: PrefetchKind = 'document') =>\n\tcache.has(cacheKey(kind, url));\n\n/* ------------------------------------------------------------------ */\n/* Kinds */\n/* ------------------------------------------------------------------ */\n\nconst injectLink = (rel: string, href: string, asType?: string) => {\n\tif (typeof document === 'undefined') return;\n\tconst link = document.createElement('link');\n\tlink.rel = rel;\n\tlink.href = href;\n\tif (asType) link.setAttribute('as', asType);\n\tdocument.head.append(link);\n};\n\n/** Without `fetch` (very old engines) fall back to a `<link rel=\"prefetch\">`\n * for documents; other kinds have no declarative equivalent. */\nconst injectPrefetchFallback = (kind: PrefetchKind, url: string) => {\n\tif (kind !== 'document' || !supportsLinkRel('prefetch')) return;\n\tinjectLink('prefetch', url, 'document');\n};\n\nconst supportsLinkRel = (rel: string) => {\n\tif (typeof document === 'undefined') return false;\n\tconst link = document.createElement('link');\n\n\treturn (\n\t\ttypeof link.relList?.supports === 'function' &&\n\t\tlink.relList.supports(rel)\n\t);\n};\n\n/** Inject `<link rel=\"prefetch\" as=\"style\">` once per resolved href, so\n * the target page's stylesheets are in the HTTP cache before the click.\n * `prefetch` rather than `preload`: the sheet is for the NEXT document,\n * so preloading it would warn about an unused preload on this one. */\nexport const prefetchStylesheet = (href: string) => {\n\tif (typeof document === 'undefined') return false;\n\tconst resolved = resolveHref(href);\n\tif (prefetchedStyles.has(resolved)) return false;\n\tprefetchedStyles.add(resolved);\n\t// No `relList.supports` gate: a browser that doesn't know `prefetch`\n\t// simply ignores the tag, and there is no fallback worth branching to.\n\tinjectLink('prefetch', href, 'style');\n\n\treturn true;\n};\n\n/** Inject `<link rel=\"modulepreload\">` once per resolved href. Returns\n * `true` when a new tag was added. */\nexport const preloadModule = (href: string) => {\n\tif (typeof document === 'undefined') return false;\n\tconst resolved = resolveHref(href);\n\tif (preloadedModules.has(resolved)) return false;\n\n\tconst existing = Array.from(\n\t\tdocument.querySelectorAll<HTMLLinkElement>('link[rel=\"modulepreload\"]')\n\t);\n\tif (existing.some((link) => resolveHref(link.href) === resolved)) {\n\t\tpreloadedModules.add(resolved);\n\n\t\treturn false;\n\t}\n\n\tpreloadedModules.add(resolved);\n\tinjectLink('modulepreload', href);\n\n\treturn true;\n};\n\nconst isRecord = (value: unknown): value is Record<string, unknown> =>\n\ttypeof value === 'object' && value !== null;\n\nconst isHref = (value: unknown): value is string =>\n\ttypeof value === 'string' && value.length > 0;\n\n/** Warm what a route-data envelope points at: `modulepreload` for the\n * page's client entry (and a separate client module when it has one),\n * `<link rel=\"prefetch\">` for its stylesheets. Anything unexpected in\n * the payload is ignored — a prefetch must never break a page. */\nconst warmRouteDataAssets = (envelope: unknown) => {\n\tif (!isRecord(envelope)) return;\n\tconst { assets } = envelope;\n\tif (!isRecord(assets)) return;\n\tconst { client, css, index } = assets;\n\tfor (const href of [index, client].filter(isHref)) preloadModule(href);\n\tif (!Array.isArray(css)) return;\n\tfor (const href of css.filter(isHref)) prefetchStylesheet(href);\n};\n\n/** Read the envelope out of a clone so the cached response body is still\n * unconsumed for whoever calls `consumePrefetch`. */\nconst warmFromRouteData = async (response: Response) => {\n\ttry {\n\t\twarmRouteDataAssets(await response.clone().json());\n\t} catch {\n\t\t/* malformed payload — the document prefetch still stands */\n\t}\n\n\treturn response;\n};\n\nconst fetchDocument = (url: string, signal: AbortSignal) =>\n\tfetch(url, { credentials: 'same-origin', signal });\n\nconst fetchRouteData = async (url: string, signal: AbortSignal) => {\n\tconst response = await fetch(url, {\n\t\tcredentials: 'same-origin',\n\t\theaders: { Accept: ROUTE_DATA_MEDIA_TYPE },\n\t\tsignal\n\t});\n\tconst contentType = response.headers.get('content-type') ?? '';\n\tconst isRouteData =\n\t\tresponse.ok && contentType.includes(ROUTE_DATA_MEDIA_TYPE);\n\tif (isRouteData) return warmFromRouteData(response);\n\n\t// The server doesn't speak route data (yet) — 404 / 406 / HTML fallback.\n\t// Remember that as \"no data\" so the URL isn't asked again, and drain\n\t// the body so the connection can be reused.\n\tawait response.body?.cancel().catch(() => undefined);\n\tconst status =\n\t\tresponse.status === NOT_FOUND || response.status === NOT_ACCEPTABLE\n\t\t\t? response.status\n\t\t\t: NOT_ACCEPTABLE;\n\n\treturn new Response(null, { status });\n};\n\n/**\n * Prefetch `url`. No-op when the user signalled data-saver / reduced-data\n * / 2g, when the page opted out, or when the URL is already cached. At\n * most two prefetches are in flight at once; the rest queue in order.\n */\nexport const prefetch = (url: string, options: PrefetchOptions = {}) => {\n\tconst kind = options.kind ?? 'document';\n\tif (!canPrefetch()) return;\n\n\tif (kind === 'module') {\n\t\tpreloadModule(url);\n\n\t\treturn;\n\t}\n\n\t// `'route'` is document + data: the HTML for the navigation itself and\n\t// the payload that names the modules and CSS to warm alongside it.\n\tif (kind === 'route') {\n\t\tprefetch(url, { kind: 'document' });\n\t\tprefetch(url, { kind: 'data' });\n\n\t\treturn;\n\t}\n\n\tconst key = cacheKey(kind, url);\n\tconst existing = cache.get(key);\n\tif (existing) {\n\t\ttouch(key, existing);\n\n\t\treturn;\n\t}\n\n\tif (typeof fetch === 'undefined') {\n\t\tinjectPrefetchFallback(kind, url);\n\n\t\treturn;\n\t}\n\n\twhile (cache.size >= PREFETCH_CACHE_LIMIT) evictOldest();\n\n\tconst { abort, promise } = enqueue((signal) =>\n\t\tkind === 'data'\n\t\t\t? fetchRouteData(url, signal)\n\t\t\t: fetchDocument(url, signal)\n\t);\n\tcache.set(key, { abort, kind, promise, url });\n};\n\n/* ------------------------------------------------------------------ */\n/* Speculation rules */\n/* ------------------------------------------------------------------ */\n\nconst supportsSpeculationRules = () =>\n\ttypeof HTMLScriptElement !== 'undefined' &&\n\ttypeof HTMLScriptElement.supports === 'function' &&\n\tHTMLScriptElement.supports('speculationrules');\n\n/**\n * Ask the browser to prerender `url` right away via a speculation-rules\n * script. Deduped per URL and capped to two live rules — the oldest is\n * removed when a third arrives, so a hover trail can't pile up hidden\n * prerendered tabs. Silently no-ops where the API is unsupported.\n */\nexport const speculate = (url: string) => {\n\tif (!canPrefetch() || !supportsSpeculationRules()) return false;\n\tif (typeof document === 'undefined') return false;\n\n\tconst resolved = resolveHref(url);\n\tif (liveSpeculationRules.has(resolved)) return false;\n\n\twhile (liveSpeculationRules.size >= MAX_LIVE_SPECULATION_RULES) {\n\t\tconst oldest = liveSpeculationRules.keys().next();\n\t\tif (oldest.done) break;\n\t\tliveSpeculationRules.get(oldest.value)?.remove();\n\t\tliveSpeculationRules.delete(oldest.value);\n\t}\n\n\tconst script = document.createElement('script');\n\tscript.type = 'speculationrules';\n\tscript.textContent = JSON.stringify({\n\t\tprerender: [{ eagerness: 'immediate', urls: [url] }]\n\t});\n\tdocument.head.append(script);\n\tliveSpeculationRules.set(resolved, script);\n\n\treturn true;\n};\n\n/* ------------------------------------------------------------------ */\n/* Triggers */\n/* ------------------------------------------------------------------ */\n\nconst noopHandle: HoverPrefetchHandle = {\n\tcancel: () => {\n\t\t/* nothing scheduled */\n\t}\n};\n\n/**\n * Wrap a prefetch trigger in a hover-debounce so glancing across many links\n * doesn't fire a fetch storm. The returned handle's `cancel()` aborts the\n * pending hover prefetch (e.g. on `pointerleave`).\n *\n * Defaults to `kind: 'route'` — a hover is deliberate enough to be worth\n * the document AND the route data (and the modules + CSS that payload\n * names). Viewport prefetching stays document-only.\n */\nexport const scheduleHoverPrefetch = (\n\turl: string,\n\toptions: HoverPrefetchOptions = {}\n): HoverPrefetchHandle => {\n\tif (typeof window === 'undefined') return noopHandle;\n\n\tconst timer = window.setTimeout(() => {\n\t\tprefetch(url, { kind: options.kind ?? 'route' });\n\t\tif (options.prerender) speculate(url);\n\t}, HOVER_DEBOUNCE_MS);\n\n\treturn {\n\t\tcancel: () => window.clearTimeout(timer)\n\t};\n};\n\ntype ViewportTarget = {\n\toptions: PrefetchOptions;\n\turl: string;\n};\n\nconst viewportTargets = new WeakMap<Element, ViewportTarget>();\nlet viewportObserver: IntersectionObserver | null = null;\n\nconst handleIntersections = (entries: IntersectionObserverEntry[]) => {\n\tfor (const entry of entries) {\n\t\tif (!entry.isIntersecting) continue;\n\t\tconst target = viewportTargets.get(entry.target);\n\t\tviewportObserver?.unobserve(entry.target);\n\t\tviewportTargets.delete(entry.target);\n\t\tif (target) prefetch(target.url, target.options);\n\t}\n};\n\nconst getViewportObserver = () => {\n\tif (viewportObserver) return viewportObserver;\n\tif (typeof IntersectionObserver === 'undefined') return null;\n\tviewportObserver = new IntersectionObserver(handleIntersections, {\n\t\trootMargin: VIEWPORT_ROOT_MARGIN\n\t});\n\n\treturn viewportObserver;\n};\n\n/**\n * Prefetch `url` once `element` scrolls within 128px of the viewport. One\n * IntersectionObserver is shared by every link on the page. Returns an\n * unobserve function for the caller's unmount hook.\n */\nexport const observeViewport = (\n\telement: Element,\n\turl: string,\n\toptions: PrefetchOptions = {}\n) => {\n\tconst observer = getViewportObserver();\n\tif (!observer || !canPrefetch()) return () => undefined;\n\n\tviewportTargets.set(element, { options, url });\n\tobserver.observe(element);\n\n\treturn () => {\n\t\tobserver.unobserve(element);\n\t\tviewportTargets.delete(element);\n\t};\n};\n\n/** Test / teardown helper — forgets injected modulepreload + speculation\n * rule bookkeeping and cancels any queued fetches. */\nexport const resetPrefetchState = () => {\n\tclearPrefetchCache();\n\tqueue.length = 0;\n\tpreloadedModules.clear();\n\tprefetchedStyles.clear();\n\tfor (const script of liveSpeculationRules.values()) script.remove();\n\tliveSpeculationRules.clear();\n\tviewportObserver?.disconnect();\n\tviewportObserver = null;\n};\n"
|
|
6
5
|
],
|
|
7
|
-
"mappings": "
|
|
8
|
-
"debugId": "
|
|
6
|
+
"mappings": "",
|
|
7
|
+
"debugId": "546CCCC476E36A1464756E2164756E21",
|
|
9
8
|
"names": []
|
|
10
9
|
}
|