@ogygia/core 0.0.0 → 0.11.0
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/LICENSE +21 -0
- package/README.md +7 -1
- package/ambient.d.ts +194 -0
- package/dist/ClientBindingStub.svelte +6 -0
- package/dist/ClientBindingStub.svelte.d.ts +26 -0
- package/dist/KeepHost.svelte +19 -0
- package/dist/KeepHost.svelte.d.ts +10 -0
- package/dist/LakeBoundary.svelte +16 -0
- package/dist/LakeBoundary.svelte.d.ts +11 -0
- package/dist/LateIsland.svelte +22 -0
- package/dist/LateIsland.svelte.d.ts +15 -0
- package/dist/LateIslandAwait.svelte +17 -0
- package/dist/LateIslandAwait.svelte.d.ts +15 -0
- package/dist/LiveHost.svelte +19 -0
- package/dist/LiveHost.svelte.d.ts +10 -0
- package/dist/NestedProvider.svelte +13 -0
- package/dist/NestedProvider.svelte.d.ts +8 -0
- package/dist/OgygiaBoundary.svelte +5 -0
- package/dist/OgygiaBoundary.svelte.d.ts +17 -0
- package/dist/PromiseRegion.svelte +40 -0
- package/dist/PromiseRegion.svelte.d.ts +15 -0
- package/dist/PromiseRegionAwait.svelte +27 -0
- package/dist/PromiseRegionAwait.svelte.d.ts +15 -0
- package/dist/Provide.svelte +27 -0
- package/dist/Provide.svelte.d.ts +8 -0
- package/dist/RawHtml.svelte +9 -0
- package/dist/RawHtml.svelte.d.ts +6 -0
- package/dist/Region.svelte +1173 -0
- package/dist/Region.svelte.d.ts +68 -0
- package/dist/SlotBoundary.svelte +13 -0
- package/dist/SlotBoundary.svelte.d.ts +7 -0
- package/dist/app.d.ts +4 -0
- package/dist/app.js +3 -0
- package/dist/boundary.d.ts +35 -0
- package/dist/boundary.js +127 -0
- package/dist/build-cache.d.ts +13 -0
- package/dist/build-cache.js +77 -0
- package/dist/compiler/blank-styles.d.ts +1 -0
- package/dist/compiler/blank-styles.js +63 -0
- package/dist/compiler/bom.d.ts +2 -0
- package/dist/compiler/bom.js +15 -0
- package/dist/compiler/browser-full.d.ts +8 -0
- package/dist/compiler/browser-full.js +8 -0
- package/dist/compiler/browser.d.ts +11 -0
- package/dist/compiler/browser.js +11 -0
- package/dist/compiler/content/transportables.d.ts +26 -0
- package/dist/compiler/content/transportables.js +219 -0
- package/dist/compiler/ctx.d.ts +180 -0
- package/dist/compiler/ctx.js +183 -0
- package/dist/compiler/debarrel/barrel.d.ts +55 -0
- package/dist/compiler/debarrel/barrel.js +248 -0
- package/dist/compiler/debarrel/options.d.ts +67 -0
- package/dist/compiler/debarrel/options.js +31 -0
- package/dist/compiler/debarrel/parse.d.ts +65 -0
- package/dist/compiler/debarrel/parse.js +256 -0
- package/dist/compiler/debarrel/plugin.d.ts +31 -0
- package/dist/compiler/debarrel/plugin.js +190 -0
- package/dist/compiler/debarrel/rewrite.d.ts +27 -0
- package/dist/compiler/debarrel/rewrite.js +118 -0
- package/dist/compiler/debarrel/svelte.d.ts +13 -0
- package/dist/compiler/debarrel/svelte.js +56 -0
- package/dist/compiler/dev/css-scope.d.ts +16 -0
- package/dist/compiler/dev/css-scope.js +38 -0
- package/dist/compiler/dev/dev-hmr.d.ts +25 -0
- package/dist/compiler/dev/dev-hmr.js +29 -0
- package/dist/compiler/dev/hmr.d.ts +34 -0
- package/dist/compiler/dev/hmr.js +57 -0
- package/dist/compiler/dev/region-bytes.d.ts +34 -0
- package/dist/compiler/dev/region-bytes.js +126 -0
- package/dist/compiler/driver.d.ts +280 -0
- package/dist/compiler/driver.js +1352 -0
- package/dist/compiler/flags.d.ts +16 -0
- package/dist/compiler/flags.js +101 -0
- package/dist/compiler/fouc-css.d.ts +97 -0
- package/dist/compiler/fouc-css.js +335 -0
- package/dist/compiler/free-vars.d.ts +20 -0
- package/dist/compiler/free-vars.js +327 -0
- package/dist/compiler/host.d.ts +65 -0
- package/dist/compiler/host.js +51 -0
- package/dist/compiler/ids.d.ts +84 -0
- package/dist/compiler/ids.js +86 -0
- package/dist/compiler/index.d.ts +11 -0
- package/dist/compiler/index.js +11 -0
- package/dist/compiler/kit.d.ts +129 -0
- package/dist/compiler/kit.js +563 -0
- package/dist/compiler/link/build-output.d.ts +44 -0
- package/dist/compiler/link/build-output.js +147 -0
- package/dist/compiler/link/caps.d.ts +48 -0
- package/dist/compiler/link/caps.js +64 -0
- package/dist/compiler/link/context-detect.d.ts +23 -0
- package/dist/compiler/link/context-detect.js +137 -0
- package/dist/compiler/link/emit-gate.d.ts +11 -0
- package/dist/compiler/link/emit-gate.js +40 -0
- package/dist/compiler/link/entry-shim.d.ts +4 -0
- package/dist/compiler/link/entry-shim.js +29 -0
- package/dist/compiler/link/island-deps.d.ts +142 -0
- package/dist/compiler/link/island-deps.js +525 -0
- package/dist/compiler/link/manifest.d.ts +5 -0
- package/dist/compiler/link/manifest.js +9 -0
- package/dist/compiler/link/page-keys.d.ts +64 -0
- package/dist/compiler/link/page-keys.js +683 -0
- package/dist/compiler/link/registry-stub.d.ts +41 -0
- package/dist/compiler/link/registry-stub.js +212 -0
- package/dist/compiler/link/router-config.d.ts +11 -0
- package/dist/compiler/link/router-config.js +15 -0
- package/dist/compiler/link/router-css.d.ts +22 -0
- package/dist/compiler/link/router-css.js +142 -0
- package/dist/compiler/link/runtime-entry.d.ts +71 -0
- package/dist/compiler/link/runtime-entry.js +132 -0
- package/dist/compiler/link/server-manifest.d.ts +12 -0
- package/dist/compiler/link/server-manifest.js +45 -0
- package/dist/compiler/link/speculation.d.ts +17 -0
- package/dist/compiler/link/speculation.js +36 -0
- package/dist/compiler/link/transport.d.ts +31 -0
- package/dist/compiler/link/transport.js +67 -0
- package/dist/compiler/macros/bake.d.ts +20 -0
- package/dist/compiler/macros/bake.js +317 -0
- package/dist/compiler/macros/browser.d.ts +11 -0
- package/dist/compiler/macros/browser.js +69 -0
- package/dist/compiler/macros/dedent.d.ts +12 -0
- package/dist/compiler/macros/dedent.js +36 -0
- package/dist/compiler/macros/dollar.d.ts +15 -0
- package/dist/compiler/macros/dollar.js +387 -0
- package/dist/compiler/macros/pipeline.d.ts +31 -0
- package/dist/compiler/macros/pipeline.js +106 -0
- package/dist/compiler/macros/source.d.ts +6 -0
- package/dist/compiler/macros/source.js +127 -0
- package/dist/compiler/macros/store.d.ts +17 -0
- package/dist/compiler/macros/store.js +244 -0
- package/dist/compiler/macros/wire.d.ts +14 -0
- package/dist/compiler/macros/wire.js +160 -0
- package/dist/compiler/ownership-stamps.d.ts +6 -0
- package/dist/compiler/ownership-stamps.js +144 -0
- package/dist/compiler/parse/oxc.d.ts +34 -0
- package/dist/compiler/parse/oxc.js +59 -0
- package/dist/compiler/parse/scan.d.ts +43 -0
- package/dist/compiler/parse/scan.js +232 -0
- package/dist/compiler/program.d.ts +140 -0
- package/dist/compiler/program.js +242 -0
- package/dist/compiler/region/emit.d.ts +169 -0
- package/dist/compiler/region/emit.js +286 -0
- package/dist/compiler/region/identity.d.ts +28 -0
- package/dist/compiler/region/identity.js +75 -0
- package/dist/compiler/region/ir.d.ts +65 -0
- package/dist/compiler/region/ir.js +0 -0
- package/dist/compiler/region/transform.d.ts +178 -0
- package/dist/compiler/region/transform.js +1933 -0
- package/dist/compiler/script-request.d.ts +1 -0
- package/dist/compiler/script-request.js +43 -0
- package/dist/context-bridge.d.ts +65 -0
- package/dist/context-bridge.js +217 -0
- package/dist/context-registry.d.ts +40 -0
- package/dist/context-registry.js +15 -0
- package/dist/context.d.ts +72 -0
- package/dist/context.js +158 -0
- package/dist/current-region.d.ts +14 -0
- package/dist/current-region.js +36 -0
- package/dist/document.d.ts +41 -0
- package/dist/document.js +125 -0
- package/dist/entry-hydrate.d.ts +5 -0
- package/dist/entry-hydrate.js +42 -0
- package/dist/escape.d.ts +18 -0
- package/dist/escape.js +37 -0
- package/dist/events/bus.d.ts +33 -0
- package/dist/events/bus.js +153 -0
- package/dist/events/index.d.ts +4 -0
- package/dist/events/index.js +4 -0
- package/dist/events/schema.d.ts +389 -0
- package/dist/events/schema.js +23 -0
- package/dist/events/server-registry.d.ts +7 -0
- package/dist/events/server-registry.js +13 -0
- package/dist/events/sinks.d.ts +64 -0
- package/dist/events/sinks.js +85 -0
- package/dist/fn-transport.d.ts +33 -0
- package/dist/fn-transport.js +140 -0
- package/dist/frame.d.ts +20 -0
- package/dist/frame.js +19 -0
- package/dist/holes-record.d.ts +6 -0
- package/dist/holes-record.js +8 -0
- package/dist/hooks.d.ts +43 -0
- package/dist/hooks.js +1191 -0
- package/dist/hydration-info.d.ts +1 -0
- package/dist/hydration-info.js +31 -0
- package/dist/index.d.ts +21 -0
- package/dist/index.js +17 -0
- package/dist/insights/attr-rules.d.ts +15 -0
- package/dist/insights/attr-rules.js +27 -0
- package/dist/insights/cpu.d.ts +82 -0
- package/dist/insights/cpu.js +177 -0
- package/dist/insights/fp-drift.d.ts +28 -0
- package/dist/insights/fp-drift.js +148 -0
- package/dist/insights/hole-segments.d.ts +26 -0
- package/dist/insights/hole-segments.js +50 -0
- package/dist/insights/html-diff.d.ts +25 -0
- package/dist/insights/html-diff.js +157 -0
- package/dist/insights/hydration-hazards.d.ts +36 -0
- package/dist/insights/hydration-hazards.js +136 -0
- package/dist/insights/hydration-status.d.ts +2 -0
- package/dist/insights/hydration-status.js +0 -0
- package/dist/insights/index.d.ts +14 -0
- package/dist/insights/index.js +12 -0
- package/dist/insights/page-assets.d.ts +211 -0
- package/dist/insights/page-assets.js +608 -0
- package/dist/insights/page-insights.d.ts +749 -0
- package/dist/insights/page-insights.js +2157 -0
- package/dist/insights/session-data.d.ts +108 -0
- package/dist/insights/session-data.js +0 -0
- package/dist/insights/session-insights.d.ts +121 -0
- package/dist/insights/session-insights.js +548 -0
- package/dist/insights/switch.d.ts +53 -0
- package/dist/insights/switch.js +91 -0
- package/dist/insights/testing-version.d.ts +19 -0
- package/dist/insights/testing-version.js +21 -0
- package/dist/insights/third-party.d.ts +75 -0
- package/dist/insights/third-party.js +160 -0
- package/dist/internal-instruments.d.ts +13 -0
- package/dist/internal-instruments.js +12 -0
- package/dist/internal-reconcile.d.ts +3 -0
- package/dist/internal-reconcile.js +3 -0
- package/dist/internal-register.d.ts +7 -0
- package/dist/internal-register.js +7 -0
- package/dist/internal-server.d.ts +7 -0
- package/dist/internal-server.js +7 -0
- package/dist/internal.d.ts +13 -0
- package/dist/internal.js +13 -0
- package/dist/island-graph.d.ts +36 -0
- package/dist/island-graph.js +89 -0
- package/dist/keep-fallback-marker.d.ts +7 -0
- package/dist/keep-fallback-marker.js +9 -0
- package/dist/keep-fallback.d.ts +13 -0
- package/dist/keep-fallback.js +39 -0
- package/dist/kit-paths.d.ts +2 -0
- package/dist/kit-paths.js +39 -0
- package/dist/late-region-registry.d.ts +40 -0
- package/dist/late-region-registry.js +36 -0
- package/dist/live-transport.d.ts +57 -0
- package/dist/live-transport.js +145 -0
- package/dist/markup.d.ts +4 -0
- package/dist/markup.js +4 -0
- package/dist/own-package.d.ts +15 -0
- package/dist/own-package.js +20 -0
- package/dist/page-defer.d.ts +33 -0
- package/dist/page-defer.js +35 -0
- package/dist/page-facts-script.d.ts +7 -0
- package/dist/page-facts-script.js +9 -0
- package/dist/page-seed-registry.d.ts +72 -0
- package/dist/page-seed-registry.js +31 -0
- package/dist/plugin/capability.d.ts +14 -0
- package/dist/plugin/capability.js +44 -0
- package/dist/plugin/client.d.ts +39 -0
- package/dist/plugin/client.js +6 -0
- package/dist/plugin/css.d.ts +3 -0
- package/dist/plugin/css.js +54 -0
- package/dist/plugin/facts.d.ts +42 -0
- package/dist/plugin/facts.js +37 -0
- package/dist/plugin/hooks.d.ts +33 -0
- package/dist/plugin/hooks.js +38 -0
- package/dist/plugin/index.d.ts +127 -0
- package/dist/plugin/index.js +26 -0
- package/dist/plugin/routes.d.ts +32 -0
- package/dist/plugin/routes.js +35 -0
- package/dist/plugin/server.d.ts +27 -0
- package/dist/plugin/server.js +92 -0
- package/dist/plugin/standard-schema.d.ts +27 -0
- package/dist/plugin/standard-schema.js +0 -0
- package/dist/plugin/testing.d.ts +13 -0
- package/dist/plugin/testing.js +54 -0
- package/dist/plugin/utils.d.ts +13 -0
- package/dist/plugin/utils.js +19 -0
- package/dist/portable-form.d.ts +22 -0
- package/dist/portable-form.js +52 -0
- package/dist/preference.d.ts +35 -0
- package/dist/preference.js +84 -0
- package/dist/preload.d.ts +1 -0
- package/dist/preload.js +21 -0
- package/dist/ref-watch.d.ts +31 -0
- package/dist/ref-watch.js +66 -0
- package/dist/ref.d.ts +124 -0
- package/dist/ref.js +272 -0
- package/dist/region-brand.d.ts +8 -0
- package/dist/region-brand.js +10 -0
- package/dist/region-core.d.ts +2 -0
- package/dist/region-core.js +1 -0
- package/dist/region-snippet.d.ts +73 -0
- package/dist/region-snippet.js +351 -0
- package/dist/region.d.ts +127 -0
- package/dist/region.js +162 -0
- package/dist/request-event.d.ts +1 -0
- package/dist/request-event.js +37 -0
- package/dist/router-css.d.ts +39 -0
- package/dist/router-css.js +66 -0
- package/dist/runtime/app-transport.d.ts +2 -0
- package/dist/runtime/app-transport.js +13 -0
- package/dist/runtime/beacon.d.ts +271 -0
- package/dist/runtime/beacon.js +2190 -0
- package/dist/runtime/boot-link.d.ts +1 -0
- package/dist/runtime/boot-link.js +44 -0
- package/dist/runtime/client-hooks.d.ts +5 -0
- package/dist/runtime/client-hooks.js +22 -0
- package/dist/runtime/client-plugins.d.ts +8 -0
- package/dist/runtime/client-plugins.js +34 -0
- package/dist/runtime/concurrency.d.ts +12 -0
- package/dist/runtime/concurrency.js +29 -0
- package/dist/runtime/connected.d.ts +12 -0
- package/dist/runtime/connected.js +16 -0
- package/dist/runtime/context.d.ts +1 -0
- package/dist/runtime/context.js +19 -0
- package/dist/runtime/core.d.ts +15 -0
- package/dist/runtime/core.js +1173 -0
- package/dist/runtime/drift-watch.d.ts +9 -0
- package/dist/runtime/drift-watch.js +60 -0
- package/dist/runtime/entry-locations.d.ts +33 -0
- package/dist/runtime/entry-locations.js +119 -0
- package/dist/runtime/foreign-props.d.ts +8 -0
- package/dist/runtime/foreign-props.js +14 -0
- package/dist/runtime/form-continuity.d.ts +10 -0
- package/dist/runtime/form-continuity.js +107 -0
- package/dist/runtime/frame-nav.d.ts +36 -0
- package/dist/runtime/frame-nav.js +225 -0
- package/dist/runtime/frame-store.d.ts +62 -0
- package/dist/runtime/frame-store.js +214 -0
- package/dist/runtime/frames.d.ts +1 -0
- package/dist/runtime/frames.js +25 -0
- package/dist/runtime/full.d.ts +4 -0
- package/dist/runtime/full.js +32 -0
- package/dist/runtime/hash.d.ts +41 -0
- package/dist/runtime/hash.js +79 -0
- package/dist/runtime/hole-facts.d.ts +8 -0
- package/dist/runtime/hole-facts.js +57 -0
- package/dist/runtime/host-classes.d.ts +24 -0
- package/dist/runtime/host-classes.js +43 -0
- package/dist/runtime/hydrate-core.d.ts +101 -0
- package/dist/runtime/hydrate-core.js +605 -0
- package/dist/runtime/index.d.ts +2 -0
- package/dist/runtime/index.js +1 -0
- package/dist/runtime/interaction-replay.d.ts +11 -0
- package/dist/runtime/interaction-replay.js +70 -0
- package/dist/runtime/interaction.d.ts +33 -0
- package/dist/runtime/interaction.js +217 -0
- package/dist/runtime/island-graph-preload.d.ts +13 -0
- package/dist/runtime/island-graph-preload.js +99 -0
- package/dist/runtime/kit-boot.d.ts +29 -0
- package/dist/runtime/kit-boot.js +60 -0
- package/dist/runtime/kit-page-thread.svelte.d.ts +1 -0
- package/dist/runtime/kit-page-thread.svelte.js +116 -0
- package/dist/runtime/lake-anchors.d.ts +13 -0
- package/dist/runtime/lake-anchors.js +19 -0
- package/dist/runtime/lakes.d.ts +15 -0
- package/dist/runtime/lakes.js +212 -0
- package/dist/runtime/live.d.ts +3 -0
- package/dist/runtime/live.js +17 -0
- package/dist/runtime/load-scheduler.d.ts +53 -0
- package/dist/runtime/load-scheduler.js +317 -0
- package/dist/runtime/morph.d.ts +42 -0
- package/dist/runtime/morph.js +671 -0
- package/dist/runtime/nav-handle.d.ts +25 -0
- package/dist/runtime/nav-handle.js +71 -0
- package/dist/runtime/nav-hooks.d.ts +2 -0
- package/dist/runtime/nav-hooks.js +23 -0
- package/dist/runtime/nearest-attr.d.ts +4 -0
- package/dist/runtime/nearest-attr.js +16 -0
- package/dist/runtime/observe.d.ts +27 -0
- package/dist/runtime/observe.js +63 -0
- package/dist/runtime/own-cost.d.ts +9 -0
- package/dist/runtime/own-cost.js +35 -0
- package/dist/runtime/ownership.d.ts +101 -0
- package/dist/runtime/ownership.js +115 -0
- package/dist/runtime/page-cache.d.ts +23 -0
- package/dist/runtime/page-cache.js +74 -0
- package/dist/runtime/page-defer.d.ts +14 -0
- package/dist/runtime/page-defer.js +103 -0
- package/dist/runtime/parse-html.d.ts +40 -0
- package/dist/runtime/parse-html.js +81 -0
- package/dist/runtime/reconcile.d.ts +41 -0
- package/dist/runtime/reconcile.js +194 -0
- package/dist/runtime/region-attrs.d.ts +95 -0
- package/dist/runtime/region-attrs.js +153 -0
- package/dist/runtime/region-endpoint-url.d.ts +76 -0
- package/dist/runtime/region-endpoint-url.js +169 -0
- package/dist/runtime/region-ids.d.ts +8 -0
- package/dist/runtime/region-ids.js +33 -0
- package/dist/runtime/remote-seeds.d.ts +2 -0
- package/dist/runtime/remote-seeds.js +21 -0
- package/dist/runtime/render-blocking.d.ts +2 -0
- package/dist/runtime/render-blocking.js +30 -0
- package/dist/runtime/restore.d.ts +34 -0
- package/dist/runtime/restore.js +390 -0
- package/dist/runtime/router-nav.d.ts +63 -0
- package/dist/runtime/router-nav.js +740 -0
- package/dist/runtime/router.d.ts +201 -0
- package/dist/runtime/router.js +593 -0
- package/dist/runtime/schedule.d.ts +49 -0
- package/dist/runtime/schedule.js +256 -0
- package/dist/runtime/seeds.d.ts +50 -0
- package/dist/runtime/seeds.js +208 -0
- package/dist/runtime/session.d.ts +52 -0
- package/dist/runtime/session.js +130 -0
- package/dist/runtime/sidecar.d.ts +3 -0
- package/dist/runtime/sidecar.js +56 -0
- package/dist/runtime/slots.d.ts +183 -0
- package/dist/runtime/slots.js +44 -0
- package/dist/runtime/spa-cacheable.d.ts +7 -0
- package/dist/runtime/spa-cacheable.js +18 -0
- package/dist/runtime/speculate-hint.d.ts +1 -0
- package/dist/runtime/speculate-hint.js +35 -0
- package/dist/runtime/svelte-warnings.d.ts +28 -0
- package/dist/runtime/svelte-warnings.js +71 -0
- package/dist/runtime/wire-classes.d.ts +3 -0
- package/dist/runtime/wire-classes.js +69 -0
- package/dist/runtime/wire-format.d.ts +7 -0
- package/dist/runtime/wire-format.js +22 -0
- package/dist/script.d.ts +134 -0
- package/dist/script.js +184 -0
- package/dist/seed-refs.d.ts +105 -0
- package/dist/seed-refs.js +487 -0
- package/dist/server/capability-lifetime.d.ts +28 -0
- package/dist/server/capability-lifetime.js +31 -0
- package/dist/server/dead-kit-resolves.d.ts +1 -0
- package/dist/server/dead-kit-resolves.js +39 -0
- package/dist/server/document-assembly.d.ts +30 -0
- package/dist/server/document-assembly.js +26 -0
- package/dist/server/document-tail.d.ts +113 -0
- package/dist/server/document-tail.js +208 -0
- package/dist/server/endpoint.d.ts +51 -0
- package/dist/server/endpoint.js +90 -0
- package/dist/server/entry-location.d.ts +8 -0
- package/dist/server/entry-location.js +29 -0
- package/dist/server/fingerprint.d.ts +1 -0
- package/dist/server/fingerprint.js +25 -0
- package/dist/server/head-presence.d.ts +45 -0
- package/dist/server/head-presence.js +156 -0
- package/dist/server/hmac.d.ts +38 -0
- package/dist/server/hmac.js +89 -0
- package/dist/server/hole-graph.d.ts +7 -0
- package/dist/server/hole-graph.js +71 -0
- package/dist/server/hole-urls.d.ts +3 -0
- package/dist/server/hole-urls.js +76 -0
- package/dist/server/html-scan.d.ts +19 -0
- package/dist/server/html-scan.js +60 -0
- package/dist/server/kit-context.d.ts +78 -0
- package/dist/server/kit-context.js +110 -0
- package/dist/server/late-wire.d.ts +22 -0
- package/dist/server/late-wire.js +28 -0
- package/dist/server/page-facts.d.ts +25 -0
- package/dist/server/page-facts.js +138 -0
- package/dist/server/page-seed.d.ts +33 -0
- package/dist/server/page-seed.js +60 -0
- package/dist/server/page-stream.d.ts +55 -0
- package/dist/server/page-stream.js +121 -0
- package/dist/server/payload.d.ts +6 -0
- package/dist/server/payload.js +22 -0
- package/dist/server/personal-response.d.ts +6 -0
- package/dist/server/personal-response.js +13 -0
- package/dist/server/props-wire.d.ts +56 -0
- package/dist/server/props-wire.js +178 -0
- package/dist/server/rate-limit.d.ts +22 -0
- package/dist/server/rate-limit.js +63 -0
- package/dist/server/region-css.d.ts +5 -0
- package/dist/server/region-css.js +30 -0
- package/dist/server/region-endpoint.d.ts +35 -0
- package/dist/server/region-endpoint.js +142 -0
- package/dist/server/region-props.d.ts +6 -0
- package/dist/server/region-props.js +44 -0
- package/dist/server/remote-seed-gate.d.ts +50 -0
- package/dist/server/remote-seed-gate.js +66 -0
- package/dist/server/render-cache.d.ts +26 -0
- package/dist/server/render-cache.js +51 -0
- package/dist/server/render-page.d.ts +51 -0
- package/dist/server/render-page.js +176 -0
- package/dist/server/render-region-html.d.ts +2 -0
- package/dist/server/render-region-html.js +19 -0
- package/dist/server/request-stats.d.ts +174 -0
- package/dist/server/request-stats.js +54 -0
- package/dist/server/reversible.d.ts +83 -0
- package/dist/server/reversible.js +994 -0
- package/dist/server/seed-shape.d.ts +22 -0
- package/dist/server/seed-shape.js +24 -0
- package/dist/server/shared-cache.d.ts +35 -0
- package/dist/server/shared-cache.js +104 -0
- package/dist/server/signing-key.d.ts +11 -0
- package/dist/server/signing-key.js +47 -0
- package/dist/server/sized-lru.d.ts +20 -0
- package/dist/server/sized-lru.js +68 -0
- package/dist/server/split-regions.d.ts +81 -0
- package/dist/server/split-regions.js +368 -0
- package/dist/server/stream-regions.d.ts +5 -0
- package/dist/server/stream-regions.js +36 -0
- package/dist/shared-state.d.ts +7 -0
- package/dist/shared-state.js +152 -0
- package/dist/shims/app-environment.d.ts +4 -0
- package/dist/shims/app-environment.js +6 -0
- package/dist/shims/app-navigation.d.ts +33 -0
- package/dist/shims/app-navigation.js +119 -0
- package/dist/shims/app-paths.d.ts +6 -0
- package/dist/shims/app-paths.js +18 -0
- package/dist/shims/app-state.svelte.d.ts +23 -0
- package/dist/shims/app-state.svelte.js +50 -0
- package/dist/shims/app-stores.d.ts +21 -0
- package/dist/shims/app-stores.js +54 -0
- package/dist/shims/kit-bridge.d.ts +29 -0
- package/dist/shims/kit-bridge.js +7 -0
- package/dist/shims/kit-remote/client-stub.d.ts +27 -0
- package/dist/shims/kit-remote/client-stub.js +43 -0
- package/dist/shims/kit-remote/paths-internal-stub.d.ts +3 -0
- package/dist/shims/kit-remote/paths-internal-stub.js +5 -0
- package/dist/shims/kit-remote/remote-cache.d.ts +49 -0
- package/dist/shims/kit-remote/remote-cache.js +73 -0
- package/dist/shims/kit-remote/state-stub.d.ts +8 -0
- package/dist/shims/kit-remote/state-stub.js +8 -0
- package/dist/shims/page-store.svelte.d.ts +39 -0
- package/dist/shims/page-store.svelte.js +77 -0
- package/dist/source.d.ts +29 -0
- package/dist/source.js +87 -0
- package/dist/store-transport.d.ts +86 -0
- package/dist/store-transport.js +229 -0
- package/dist/tool-fetches.d.ts +5 -0
- package/dist/tool-fetches.js +41 -0
- package/dist/transport.d.ts +48 -0
- package/dist/transport.js +181 -0
- package/dist/unscoped-css.d.ts +26 -0
- package/dist/unscoped-css.js +53 -0
- package/dist/vite/dev-maps.d.ts +33 -0
- package/dist/vite/dev-maps.js +140 -0
- package/dist/vite/index.d.ts +19 -0
- package/dist/vite/index.js +820 -0
- package/dist/vite/kit-dirs.d.ts +7 -0
- package/dist/vite/kit-dirs.js +67 -0
- package/dist/vite/late-island.d.ts +25 -0
- package/dist/vite/late-island.js +33 -0
- package/dist/vite/module-map.d.ts +8 -0
- package/dist/vite/module-map.js +144 -0
- package/dist/vite/options.d.ts +208 -0
- package/dist/vite/options.js +74 -0
- package/dist/vite/package-files.d.ts +3 -0
- package/dist/vite/package-files.js +84 -0
- package/dist/vite/paths.d.ts +45 -0
- package/dist/vite/paths.js +112 -0
- package/dist/vite/plugin-api.d.ts +166 -0
- package/dist/vite/plugin-api.js +212 -0
- package/dist/vite/profiler-maps.d.ts +23 -0
- package/dist/vite/profiler-maps.js +178 -0
- package/dist/vite/server-sourcemaps.d.ts +8 -0
- package/dist/vite/server-sourcemaps.js +80 -0
- package/dist/vite/sourcemaps.d.ts +18 -0
- package/dist/vite/sourcemaps.js +80 -0
- package/dist/vite/style-preprocess.d.ts +2 -0
- package/dist/vite/style-preprocess.js +96 -0
- package/package.json +180 -6
|
@@ -0,0 +1,740 @@
|
|
|
1
|
+
import { PageCache } from "./page-cache.js";
|
|
2
|
+
import { boot_link, router_link, slots } from "./slots.js";
|
|
3
|
+
import { dispose_scope } from "../ref.js";
|
|
4
|
+
import { reconcile_body, stamp_region_keys, swap_body } from "./reconcile.js";
|
|
5
|
+
import { apply_soft_invalidate_doc, finish_spa_document, page_seed_of, prepare_spa_document } from "./seeds.js";
|
|
6
|
+
import { spa_html_cacheable } from "./spa-cacheable.js";
|
|
7
|
+
import { pin_region_urls } from "./entry-locations.js";
|
|
8
|
+
import { emit } from "../events/bus.js";
|
|
9
|
+
// src/runtime/router-nav.ts
|
|
10
|
+
/**
|
|
11
|
+
* THE NAVIGATION — the router's heavy half, loaded lazily by ./router.ts on the first prefetch or
|
|
12
|
+
* intercepted click: page fetch + cache, head merge, the body reconcile / morph, seeds, a11y.
|
|
13
|
+
* Nothing here runs at boot; a visitor who never leaves the page never downloads it.
|
|
14
|
+
*
|
|
15
|
+
* A navigation is TWO tasks. The first — this module's `navigate` after the fetch — does everything
|
|
16
|
+
* that needs no live DOM change: parse the HTML, read the route facts, batch the incoming holes,
|
|
17
|
+
* stamp reconcile keys, parse the incoming page seed, drop hints for modules already warm, preload
|
|
18
|
+
* stylesheets. Then it yields. The second task is the view transition's callback and does ONLY the
|
|
19
|
+
* DOM: head merge, seeds, body morph, title. The old single-task swap ran a whole-document regex,
|
|
20
|
+
* two `'*'` walks and a seed parse inside `startViewTransition`, on the frame the transition
|
|
21
|
+
* captures.
|
|
22
|
+
*/
|
|
23
|
+
const KitBoot = { document_has: (doc) => boot_link().KitBoot.document_has(doc) };
|
|
24
|
+
const regions_in_shadow = () => boot_link().regions_in_shadow();
|
|
25
|
+
const session = () => boot_link().runtime_session;
|
|
26
|
+
const is_warmed_module = (entry, base) => boot_link().is_warmed_module(entry, base);
|
|
27
|
+
const warm_island_module = (entry, base) => boot_link().warm_island_module(entry, base);
|
|
28
|
+
const note_entry_location = (entry, src, base) => boot_link().note_entry_location(entry, src, base);
|
|
29
|
+
const register_island_graph = (text, base) => boot_link().register_island_graph(text, base);
|
|
30
|
+
const yield_task = () => boot_link().yield_task();
|
|
31
|
+
const document_key = (url) => router_link().document_key(url);
|
|
32
|
+
const jump_to_hash = (hash) => router_link().jump_to_hash(hash);
|
|
33
|
+
const push_state = (state, url) => router_link().push_state(state, url);
|
|
34
|
+
const replace_state = (state, url) => router_link().replace_state(state, url);
|
|
35
|
+
const DEVTOOLS = typeof __OGYGIA_DEVTOOLS__ !== "undefined" ? __OGYGIA_DEVTOOLS__ : false;
|
|
36
|
+
/** High-res clock for devtools nav timings (guarded — dead when off). */
|
|
37
|
+
const dt_now = () => typeof performance !== "undefined" && performance.now ? performance.now() : Date.now();
|
|
38
|
+
/** Max bytes for the `x-ogygia-known` header — past this we OMIT it, so the server renders every
|
|
39
|
+
* region (the safe full-render fallback). Keeps request headers well under proxy/server limits. */
|
|
40
|
+
const KNOWN_HEADER_CAP = 6144;
|
|
41
|
+
/** SERVER-DELTA NAV is OPT-IN for the first release (a new client↔server protocol). Off → the client
|
|
42
|
+
* never sends `x-ogygia-known`, so `known_region_fps()` is always empty server-side and every region
|
|
43
|
+
* full-renders (the documented safe fallback). Compile-time constant (Vite `define`); typeof-guarded
|
|
44
|
+
* so a plain node import of dist/ without the define falls back to OFF. */
|
|
45
|
+
const SERVER_DELTA = typeof __OGYGIA_SERVER_DELTA__ !== "undefined" ? __OGYGIA_SERVER_DELTA__ : false;
|
|
46
|
+
/** The `Accept` a browser sends for a top-level document navigation (Chromium's value). */
|
|
47
|
+
const DOCUMENT_ACCEPT = "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8";
|
|
48
|
+
/**
|
|
49
|
+
* SERVER-DELTA NAV (D2): headers for a nav/prefetch fetch. Always `x-ogygia-spa`. When `purpose` is
|
|
50
|
+
* not a plain nav, `x-ogygia-purpose` names it (see {@link NavPurpose}). Plus, when the current
|
|
51
|
+
* document has HYDRATED islands carrying a `data-og-fp`, `x-ogygia-known` lists their fingerprints so
|
|
52
|
+
* the server can SKIP re-rendering the ones this page already has live. Only data-hydrated regions
|
|
53
|
+
* are claimed (never assert a region we don't actually have), and the header is omitted past a size
|
|
54
|
+
* cap → the server renders everything (progressive enhancement: every header here is an optimization
|
|
55
|
+
* the server may ignore, and its absence is always correct).
|
|
56
|
+
*/
|
|
57
|
+
function nav_headers(purpose = "nav") {
|
|
58
|
+
const headers = {
|
|
59
|
+
accept: DOCUMENT_ACCEPT,
|
|
60
|
+
"x-ogygia-spa": "1"
|
|
61
|
+
};
|
|
62
|
+
if (purpose !== "nav") headers["x-ogygia-purpose"] = purpose;
|
|
63
|
+
if (!SERVER_DELTA || typeof document === "undefined") return headers;
|
|
64
|
+
const seen = /* @__PURE__ */ new Set();
|
|
65
|
+
for (const el of document.querySelectorAll("ogygia-region[data-og-fp][data-hydrated]")) {
|
|
66
|
+
const fp = el.getAttribute("data-og-fp");
|
|
67
|
+
if (fp) seen.add(fp);
|
|
68
|
+
}
|
|
69
|
+
if (seen.size === 0) return headers;
|
|
70
|
+
const joined = [...seen].join(",");
|
|
71
|
+
if (joined.length <= KNOWN_HEADER_CAP) headers["x-ogygia-known"] = joined;
|
|
72
|
+
return headers;
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* Fold ORPHANED `view-transition-name`s into the page-level cross-fade. A name promotes its element
|
|
76
|
+
* to a standalone transition group, LIFTED OUT of the root snapshot. When the element has no
|
|
77
|
+
* counterpart on the other page — a sidebar full of named nav rows navigating to a marketing page
|
|
78
|
+
* that has none — each one runs a solo enter/exit AND leaves a hole in the root cross-fade: a visible
|
|
79
|
+
* stutter, worst in dev where the destination paints late. Names present on BOTH pages (the docs↔docs
|
|
80
|
+
* active-highlight slide) are KEPT, so matched animations still play. Only INLINE names are touched
|
|
81
|
+
* (nav rows carry theirs inline; the single CSS-set highlight chip is left alone). Returns a restore
|
|
82
|
+
* fn to re-apply the stripped names AFTER the transition, so a page entered across a shell change
|
|
83
|
+
* still animates on its next same-shell nav.
|
|
84
|
+
*/
|
|
85
|
+
function fold_orphan_vt_names(current, incoming) {
|
|
86
|
+
const names_in = (root) => {
|
|
87
|
+
const map = /* @__PURE__ */ new Map();
|
|
88
|
+
for (const el of root.querySelectorAll("[style*=\"view-transition-name\"]")) {
|
|
89
|
+
const n = el.style.getPropertyValue("view-transition-name").trim();
|
|
90
|
+
if (!n || n === "none") continue;
|
|
91
|
+
let arr = map.get(n);
|
|
92
|
+
if (!arr) map.set(n, arr = []);
|
|
93
|
+
arr.push(el);
|
|
94
|
+
}
|
|
95
|
+
return map;
|
|
96
|
+
};
|
|
97
|
+
const cur = names_in(current);
|
|
98
|
+
const inc = names_in(incoming);
|
|
99
|
+
const stripped = [];
|
|
100
|
+
const fold = (map, other) => {
|
|
101
|
+
for (const [name, els] of map) {
|
|
102
|
+
if (other.has(name)) continue;
|
|
103
|
+
for (const el of els) {
|
|
104
|
+
stripped.push([el, name]);
|
|
105
|
+
el.style.setProperty("view-transition-name", "none");
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
};
|
|
109
|
+
fold(cur, inc);
|
|
110
|
+
fold(inc, cur);
|
|
111
|
+
return () => {
|
|
112
|
+
for (const [el, name] of stripped) el.style.setProperty("view-transition-name", name);
|
|
113
|
+
};
|
|
114
|
+
}
|
|
115
|
+
const PREFETCH_TTL_MS = 8e3;
|
|
116
|
+
const PAGE_CACHE_MAX_ENTRIES = 32;
|
|
117
|
+
const PAGE_CACHE_MAX_BYTES = 4e6;
|
|
118
|
+
/** Cap on waiting for a destination stylesheet to load before the body swap (cold-cache FOUC guard). */
|
|
119
|
+
const STYLESHEET_WAIT_MS = 2e3;
|
|
120
|
+
/** Kit remote-function POSTs live under `…/_app/remote/…` (or custom `appDir`). */
|
|
121
|
+
const REMOTE_MUTATION_PATH = /\/remote(?:\/|$|\?)/;
|
|
122
|
+
/** An `<ogygia-region>` open tag's attributes (shared `g` regex — reset `lastIndex` per scan). */
|
|
123
|
+
const REGION_OPEN_TAG_G = /<ogygia-region\b([^>]*)>/g;
|
|
124
|
+
/** One attribute's value in an open tag's attribute text (our own SSR: `name="value"`, no quotes
|
|
125
|
+
* inside a value). Null when absent. @internal Exported for unit tests. */
|
|
126
|
+
function tag_attr(attrs, name) {
|
|
127
|
+
const key = " " + name + "=\"";
|
|
128
|
+
const at = attrs.indexOf(key);
|
|
129
|
+
if (at === -1) return null;
|
|
130
|
+
const from = at + key.length;
|
|
131
|
+
const to = attrs.indexOf("\"", from);
|
|
132
|
+
return to === -1 ? null : attrs.slice(from, to);
|
|
133
|
+
}
|
|
134
|
+
/** The island graph scripts in our own SSR output (island-graph.ts; the JSON is `<`-escaped, so
|
|
135
|
+
* its text never holds a `<`). */
|
|
136
|
+
const ISLAND_GRAPH_SCRIPT_G = /<script type="application\/json" data-ogygia-graph>([^<]*)<\/script>/g;
|
|
137
|
+
/** Stable-ish head node identity without serializing full outerHTML when possible. */
|
|
138
|
+
function head_node_key(node) {
|
|
139
|
+
const tag = node.tagName;
|
|
140
|
+
switch (tag) {
|
|
141
|
+
case "TITLE": return "TITLE";
|
|
142
|
+
case "META": {
|
|
143
|
+
if (node.getAttribute("charset") != null) return "META:charset";
|
|
144
|
+
const http_equiv = node.getAttribute("http-equiv");
|
|
145
|
+
if (http_equiv) return `META:http:${http_equiv}:${node.getAttribute("content") || ""}`;
|
|
146
|
+
const name = node.getAttribute("name") || node.getAttribute("property") || "";
|
|
147
|
+
if (name) return `META:${name}:${node.getAttribute("content") || ""}`;
|
|
148
|
+
return `META:${node.outerHTML}`;
|
|
149
|
+
}
|
|
150
|
+
case "LINK": return `LINK:${node.getAttribute("rel") || ""}:${node.getAttribute("href") || ""}:${node.getAttribute("as") || ""}`;
|
|
151
|
+
case "SCRIPT": {
|
|
152
|
+
const src = node.getAttribute("src");
|
|
153
|
+
if (src) return `SCRIPT:src:${src}:${node.getAttribute("type") || ""}`;
|
|
154
|
+
const type = node.getAttribute("type") || "";
|
|
155
|
+
const text = node.textContent || "";
|
|
156
|
+
return `SCRIPT:inline:${type}:${text.length}:${text.slice(0, 48)}`;
|
|
157
|
+
}
|
|
158
|
+
case "STYLE": {
|
|
159
|
+
if (node.hasAttribute("data-sveltekit")) return "STYLE:data-sveltekit";
|
|
160
|
+
const region_css = node.getAttribute("data-ogygia-region-css");
|
|
161
|
+
if (region_css) return `STYLE:og-css:${region_css}`;
|
|
162
|
+
const vite_id = node.getAttribute("data-vite-dev-id");
|
|
163
|
+
if (vite_id) return `STYLE:vite:${vite_id}`;
|
|
164
|
+
const text = node.textContent || "";
|
|
165
|
+
return `STYLE:${text.length}:${text.slice(0, 48)}`;
|
|
166
|
+
}
|
|
167
|
+
default: return `${tag}:${node.outerHTML}`;
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
/**
|
|
171
|
+
* Head nodes that must survive SPA swaps even when absent from the next SSR head.
|
|
172
|
+
* @internal
|
|
173
|
+
*/
|
|
174
|
+
function keep_head_node_across_spa(node) {
|
|
175
|
+
if (node.tagName === "SCRIPT" && node.getAttribute("type") === "module" && (node.hasAttribute("data-ogygia-runtime") || node.hasAttribute("data-ogygia-dev-hmr"))) return true;
|
|
176
|
+
if (node.tagName === "STYLE" && node.hasAttribute("data-vite-dev-id")) return true;
|
|
177
|
+
if (node.tagName === "LINK" && node.getAttribute("rel") === "stylesheet" && node.hasAttribute("data-vite-dev-id")) return true;
|
|
178
|
+
return false;
|
|
179
|
+
}
|
|
180
|
+
/**
|
|
181
|
+
* Install a `<style>` into the live document. `cloneNode` from a `DOMParser` tree
|
|
182
|
+
* often fails to register the sheet; recreate with textContent instead.
|
|
183
|
+
* @internal
|
|
184
|
+
*/
|
|
185
|
+
function install_head_style(source, head = document.head, before = null) {
|
|
186
|
+
const el = document.createElement("style");
|
|
187
|
+
for (const attr of Array.from(source.attributes)) el.setAttribute(attr.name, attr.value);
|
|
188
|
+
el.textContent = source.textContent || "";
|
|
189
|
+
session().claim_page_head(el);
|
|
190
|
+
head.insertBefore(el, before);
|
|
191
|
+
return el;
|
|
192
|
+
}
|
|
193
|
+
/** Apply STREAMED-page late chunks after an SPA body swap: move each inert
|
|
194
|
+
* `<template data-og-late>` into its `og-late-slot` (stylesheets hoisted first via the same
|
|
195
|
+
* keyed head installer, so the swap never paints unstyled). On a full load the inline boot
|
|
196
|
+
* script in the streamed head does this progressively during parse — this is the swap-path
|
|
197
|
+
* twin. Islands inside the adopted content are custom elements: they connect and wake alone. */
|
|
198
|
+
function apply_late_templates(root) {
|
|
199
|
+
for (const tpl of Array.from(root.querySelectorAll("template[data-og-late]"))) {
|
|
200
|
+
const id = tpl.getAttribute("data-og-late") ?? "";
|
|
201
|
+
const slot = document.querySelector(`og-late-slot[data-og-slot="${CSS.escape(id)}"]`);
|
|
202
|
+
if (slot) {
|
|
203
|
+
const content = tpl.content;
|
|
204
|
+
for (const sheet of Array.from(content.querySelectorAll("link[rel=\"stylesheet\"], style"))) install_head_style(sheet);
|
|
205
|
+
slot.replaceChildren(content);
|
|
206
|
+
}
|
|
207
|
+
tpl.remove();
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
/**
|
|
211
|
+
* Move keyboard focus to `el` without scrolling (so it never fights the post-nav scroll restore),
|
|
212
|
+
* making it momentarily focusable via `tabindex=-1` and then cleaning that up so the target does not
|
|
213
|
+
* linger in the tab order. For `<body>` the attribute is removed immediately (body stays the active
|
|
214
|
+
* element regardless). For a normal element — a `#hash` heading — removing `tabindex` while it is
|
|
215
|
+
* focused would BLUR it back to `<body>`, so the cleanup is deferred to the element's next `blur`.
|
|
216
|
+
*/
|
|
217
|
+
function focus_reset(el) {
|
|
218
|
+
const is_body = el === document.body || el === document.documentElement;
|
|
219
|
+
const had = el.hasAttribute("tabindex");
|
|
220
|
+
const prev = el.getAttribute("tabindex");
|
|
221
|
+
const restore = () => {
|
|
222
|
+
if (had) el.setAttribute("tabindex", prev);
|
|
223
|
+
else el.removeAttribute("tabindex");
|
|
224
|
+
};
|
|
225
|
+
el.tabIndex = -1;
|
|
226
|
+
el.focus({ preventScroll: true });
|
|
227
|
+
if (is_body) restore();
|
|
228
|
+
else el.addEventListener("blur", () => restore(), { once: true });
|
|
229
|
+
}
|
|
230
|
+
/** Head nodes that must never be adopted from SPA HTML (rewrite relative fetches / CSP). */
|
|
231
|
+
function is_dangerous_head_node(node) {
|
|
232
|
+
const tag = node.tagName;
|
|
233
|
+
if (tag === "BASE") return true;
|
|
234
|
+
if (tag === "META") {
|
|
235
|
+
const http_equiv = (node.getAttribute("http-equiv") || "").toLowerCase();
|
|
236
|
+
if (http_equiv === "refresh" || http_equiv === "content-security-policy" || http_equiv === "content-security-policy-report-only") return true;
|
|
237
|
+
}
|
|
238
|
+
return false;
|
|
239
|
+
}
|
|
240
|
+
const page_cache = new PageCache({
|
|
241
|
+
ttlMs: PREFETCH_TTL_MS,
|
|
242
|
+
maxEntries: PAGE_CACHE_MAX_ENTRIES,
|
|
243
|
+
maxBytes: PAGE_CACHE_MAX_BYTES
|
|
244
|
+
});
|
|
245
|
+
const inflight = /* @__PURE__ */ new Map();
|
|
246
|
+
/** Prefetches still waiting in the load scheduler's queue, by href (a click promotes its one). */
|
|
247
|
+
const queued_prefetch = /* @__PURE__ */ new Map();
|
|
248
|
+
/** requested href → the FINAL href a fetch landed on after following server redirects, when it
|
|
249
|
+
* differs. One-shot: `navigate()` reads it to correct the address bar (a redirect is invisible to
|
|
250
|
+
* `fetch` beyond `response.url`), then deletes it. See {@link fetch_page}. */
|
|
251
|
+
const final_url = /* @__PURE__ */ new Map();
|
|
252
|
+
/** Hrefs whose prefetched HTML was already scanned for island entries — parse once. (URL-level
|
|
253
|
+
* import dedupe lives in the shared `warm_island_module`.) */
|
|
254
|
+
const warmed_pages = /* @__PURE__ */ new Set();
|
|
255
|
+
/** (Hard SPA navigations cancel through the router's own handle, `r.nav_gen` / `r.nav_abort`, so a
|
|
256
|
+
* "same document" decision there can stop one in flight: SpaRouter.supersede.) */
|
|
257
|
+
/** Soft invalidate fetches only — aborting these must not cancel a real click nav. */
|
|
258
|
+
let soft_gen = 0;
|
|
259
|
+
let soft_abort = null;
|
|
260
|
+
/** The visually-hidden `aria-live` region that announces each navigation to screen readers. Created
|
|
261
|
+
* lazily on the first nav and reused (a live region must persist so assistive tech observes its
|
|
262
|
+
* mutations). It lives in `<body>` but is DETACHED before each body swap so the reconcile never
|
|
263
|
+
* removes it, then re-attached. See {@link announce} / {@link reset_focus}. */
|
|
264
|
+
let announcer = null;
|
|
265
|
+
function bust_page_cache() {
|
|
266
|
+
page_cache.clear();
|
|
267
|
+
inflight.clear();
|
|
268
|
+
final_url.clear();
|
|
269
|
+
}
|
|
270
|
+
function page_cache_size() {
|
|
271
|
+
return page_cache.size;
|
|
272
|
+
}
|
|
273
|
+
/**
|
|
274
|
+
* Bust the SPA HTML cache after any successful Kit remote mutation (command/form POST).
|
|
275
|
+
* Forms also call `invalidateAll` (soft seed refresh + bust); commands only refresh queries —
|
|
276
|
+
* without this fetch hook, prefetched pages stay stale. Installed once, when this chunk loads —
|
|
277
|
+
* before it there is no cache to bust.
|
|
278
|
+
*/
|
|
279
|
+
function install_remote_mutation_cache_bust() {
|
|
280
|
+
if (typeof window === "undefined" || typeof window.fetch !== "function") return;
|
|
281
|
+
const orig = window.fetch.bind(window);
|
|
282
|
+
window.fetch = async (input, init) => {
|
|
283
|
+
const res = await orig(input, init);
|
|
284
|
+
try {
|
|
285
|
+
const method = (init?.method || (typeof Request !== "undefined" && input instanceof Request ? input.method : "GET")).toUpperCase();
|
|
286
|
+
if (method !== "GET" && method !== "HEAD" && res.ok) {
|
|
287
|
+
const href = typeof input === "string" ? input : input instanceof URL ? input.href : input.url;
|
|
288
|
+
if (REMOTE_MUTATION_PATH.test(href)) bust_page_cache();
|
|
289
|
+
}
|
|
290
|
+
} catch {}
|
|
291
|
+
return res;
|
|
292
|
+
};
|
|
293
|
+
}
|
|
294
|
+
install_remote_mutation_cache_bust();
|
|
295
|
+
function fetch_page(href, signal, purpose = "nav") {
|
|
296
|
+
const cached = page_cache.get(href);
|
|
297
|
+
if (cached != null) return Promise.resolve(cached);
|
|
298
|
+
const pending = inflight.get(href);
|
|
299
|
+
if (pending) {
|
|
300
|
+
if (purpose === "nav") queued_prefetch.get(href)?.promote("user");
|
|
301
|
+
return pending;
|
|
302
|
+
}
|
|
303
|
+
final_url.delete(href);
|
|
304
|
+
const go = () => fetch(href, {
|
|
305
|
+
signal,
|
|
306
|
+
headers: nav_headers(purpose),
|
|
307
|
+
...purpose === "prefetch" ? { priority: "low" } : {}
|
|
308
|
+
});
|
|
309
|
+
let fetched;
|
|
310
|
+
if (purpose === "prefetch") {
|
|
311
|
+
const slot = boot_link().load_slot({
|
|
312
|
+
kind: "content",
|
|
313
|
+
cls: "speculative",
|
|
314
|
+
label: href
|
|
315
|
+
});
|
|
316
|
+
queued_prefetch.set(href, slot.ticket);
|
|
317
|
+
fetched = slot.ready.then((release) => {
|
|
318
|
+
queued_prefetch.delete(href);
|
|
319
|
+
return go().finally(release);
|
|
320
|
+
});
|
|
321
|
+
} else fetched = go();
|
|
322
|
+
const settled = fetched.then(async (res) => {
|
|
323
|
+
if (!(res.headers.get("content-type") || "").includes("text/html")) return {
|
|
324
|
+
html: null,
|
|
325
|
+
cacheable: false
|
|
326
|
+
};
|
|
327
|
+
if (res.redirected && res.url && res.url !== href) final_url.set(href, res.url);
|
|
328
|
+
const html = await res.text();
|
|
329
|
+
const cc = res.headers.get("cache-control") || "";
|
|
330
|
+
return {
|
|
331
|
+
html,
|
|
332
|
+
cacheable: spa_html_cacheable(cc, res.headers.has("set-cookie"))
|
|
333
|
+
};
|
|
334
|
+
}).catch((err) => {
|
|
335
|
+
if (err && err.name === "AbortError") throw err;
|
|
336
|
+
return {
|
|
337
|
+
html: null,
|
|
338
|
+
cacheable: false
|
|
339
|
+
};
|
|
340
|
+
});
|
|
341
|
+
const html_p = settled.then((r) => r.html);
|
|
342
|
+
if (!signal) {
|
|
343
|
+
inflight.set(href, html_p);
|
|
344
|
+
html_p.finally(() => {
|
|
345
|
+
if (inflight.get(href) === html_p) inflight.delete(href);
|
|
346
|
+
});
|
|
347
|
+
settled.then((r) => {
|
|
348
|
+
if (r.html == null) return;
|
|
349
|
+
if (r.cacheable) page_cache.set(href, r.html);
|
|
350
|
+
warm_modules(href, r.html);
|
|
351
|
+
}).catch(() => {});
|
|
352
|
+
}
|
|
353
|
+
return html_p;
|
|
354
|
+
}
|
|
355
|
+
/**
|
|
356
|
+
* Kick off import() for every island module the prefetched page will hydrate, so they are in the
|
|
357
|
+
* browser's module cache before the click. `import()` is idempotent (the loader dedupes by URL),
|
|
358
|
+
* and a warmed-URL guard skips re-parsing / re-importing across repeated hover+viewport triggers.
|
|
359
|
+
* A cheap attribute scan avoids building a whole detached Document during the hover window.
|
|
360
|
+
*/
|
|
361
|
+
function warm_modules(href, html) {
|
|
362
|
+
if (warmed_pages.has(href)) return;
|
|
363
|
+
warmed_pages.add(href);
|
|
364
|
+
ISLAND_GRAPH_SCRIPT_G.lastIndex = 0;
|
|
365
|
+
let g;
|
|
366
|
+
while (g = ISLAND_GRAPH_SCRIPT_G.exec(html)) register_island_graph(g[1], new URL(href, location.href).href);
|
|
367
|
+
REGION_OPEN_TAG_G.lastIndex = 0;
|
|
368
|
+
let m;
|
|
369
|
+
while (m = REGION_OPEN_TAG_G.exec(html)) {
|
|
370
|
+
const entry = tag_attr(m[1], "entry");
|
|
371
|
+
if (!entry) continue;
|
|
372
|
+
note_entry_location(entry, tag_attr(m[1], "src"), href);
|
|
373
|
+
warm_island_module(entry, href);
|
|
374
|
+
}
|
|
375
|
+
}
|
|
376
|
+
/**
|
|
377
|
+
* PREFLIGHT — the incoming document's read-only preparation, in the task BEFORE the transition:
|
|
378
|
+
* • `<link rel="modulepreload">` hints for modules this page already warmed are dropped, so the
|
|
379
|
+
* head merge never re-issues a fetch for bytes the module map holds;
|
|
380
|
+
* • reconcile keys are stamped on the incoming regions (the fingerprint reads, off the DOM change);
|
|
381
|
+
* • the incoming page seed is parsed once, on the document (runtime/seeds.ts) — a kept island's
|
|
382
|
+
* props absorb and the soft-invalidate both reuse that parse inside the transition.
|
|
383
|
+
*/
|
|
384
|
+
function preflight(doc, dest) {
|
|
385
|
+
for (const l of Array.from(doc.querySelectorAll("link[rel=\"modulepreload\"]"))) {
|
|
386
|
+
const href = l.getAttribute("href");
|
|
387
|
+
if (href && is_warmed_module(href, dest.href)) l.remove();
|
|
388
|
+
}
|
|
389
|
+
stamp_region_keys(doc.body);
|
|
390
|
+
page_seed_of(doc);
|
|
391
|
+
}
|
|
392
|
+
async function navigate(r, url, from, { push = true, pop_scroll = null, type = "link", replace = false } = {}) {
|
|
393
|
+
if (!r.run_before(from, url, type)) {
|
|
394
|
+
if (r.nav_target === url.href) r.nav_target = null;
|
|
395
|
+
return;
|
|
396
|
+
}
|
|
397
|
+
const dt_t0 = DEVTOOLS ? dt_now() : 0;
|
|
398
|
+
let dt_reconciled = false;
|
|
399
|
+
const nav_t0 = performance.now();
|
|
400
|
+
let nav_fetched = nav_t0;
|
|
401
|
+
let nav_styled = nav_t0;
|
|
402
|
+
if (DEVTOOLS) emit({
|
|
403
|
+
domain: "nav",
|
|
404
|
+
name: "nav.start",
|
|
405
|
+
from: from.pathname + from.search,
|
|
406
|
+
to: url.pathname + url.search,
|
|
407
|
+
type
|
|
408
|
+
});
|
|
409
|
+
r.nav_abort?.abort();
|
|
410
|
+
r.nav_abort = new AbortController();
|
|
411
|
+
const { signal } = r.nav_abort;
|
|
412
|
+
const gen = ++r.nav_gen;
|
|
413
|
+
r.nav_target = url.href;
|
|
414
|
+
signal.addEventListener("abort", () => {
|
|
415
|
+
if (r.nav_target === url.href) r.nav_target = null;
|
|
416
|
+
});
|
|
417
|
+
if (replace) replace_state({
|
|
418
|
+
...history.state,
|
|
419
|
+
ogygia: true
|
|
420
|
+
}, url.href);
|
|
421
|
+
else if (push) {
|
|
422
|
+
replace_state({
|
|
423
|
+
...history.state,
|
|
424
|
+
scroll: {
|
|
425
|
+
x: scrollX,
|
|
426
|
+
y: scrollY
|
|
427
|
+
}
|
|
428
|
+
});
|
|
429
|
+
push_state({ ogygia: true }, url.href);
|
|
430
|
+
}
|
|
431
|
+
const purpose = type === "popstate" ? "history" : "nav";
|
|
432
|
+
let html;
|
|
433
|
+
try {
|
|
434
|
+
html = await fetch_page(url.href, signal, purpose);
|
|
435
|
+
} catch (err) {
|
|
436
|
+
if (err?.name === "AbortError" || gen !== r.nav_gen) return;
|
|
437
|
+
location.href = url.href;
|
|
438
|
+
return;
|
|
439
|
+
}
|
|
440
|
+
if (gen !== r.nav_gen) return;
|
|
441
|
+
if (html == null) {
|
|
442
|
+
location.href = url.href;
|
|
443
|
+
return;
|
|
444
|
+
}
|
|
445
|
+
nav_fetched = performance.now();
|
|
446
|
+
page_cache.delete(url.href);
|
|
447
|
+
let dest = url;
|
|
448
|
+
const landed = final_url.get(url.href);
|
|
449
|
+
final_url.delete(url.href);
|
|
450
|
+
if (landed) try {
|
|
451
|
+
dest = new URL(landed, url);
|
|
452
|
+
} catch {
|
|
453
|
+
dest = url;
|
|
454
|
+
}
|
|
455
|
+
const hand_off = () => {
|
|
456
|
+
location.href = url.href;
|
|
457
|
+
};
|
|
458
|
+
if (dest.origin !== location.origin) return hand_off();
|
|
459
|
+
const doc = new DOMParser().parseFromString(html, "text/html");
|
|
460
|
+
if (KitBoot.document_has(doc)) return hand_off();
|
|
461
|
+
const marker = doc.querySelector("meta[name=\"ogygia-router\"]");
|
|
462
|
+
if (!marker) return hand_off();
|
|
463
|
+
if (doc.querySelector("meta[name=\"ogygia-first-load\"]")) return hand_off();
|
|
464
|
+
globalThis.__og_restore?.(doc);
|
|
465
|
+
if (dest !== url) replace_state({
|
|
466
|
+
...history.state,
|
|
467
|
+
ogygia: true
|
|
468
|
+
}, dest.href);
|
|
469
|
+
const prefer_reduced_motion = typeof matchMedia === "function" && matchMedia("(prefers-reduced-motion: reduce)").matches;
|
|
470
|
+
const use_vt = marker.getAttribute("content") !== "plain" && !prefer_reduced_motion;
|
|
471
|
+
for (const el of doc.querySelectorAll("ogygia-region")) pin_region_urls(el, dest.href);
|
|
472
|
+
batch_regions(doc, dest.href);
|
|
473
|
+
preflight(doc, dest);
|
|
474
|
+
await preload_stylesheets(doc.head);
|
|
475
|
+
if (gen !== r.nav_gen) return;
|
|
476
|
+
nav_styled = performance.now();
|
|
477
|
+
await yield_task();
|
|
478
|
+
if (gen !== r.nav_gen) return;
|
|
479
|
+
const reconcile = !!slots.morph && !regions_in_shadow() && !document.body.querySelector("[data-og-no-reconcile]") && !doc.body.querySelector("[data-og-no-reconcile]");
|
|
480
|
+
const swap = () => {
|
|
481
|
+
if (gen !== r.nav_gen) return;
|
|
482
|
+
announcer?.remove();
|
|
483
|
+
document.dispatchEvent(new Event("og:before-swap"));
|
|
484
|
+
merge_head(doc.head);
|
|
485
|
+
if (gen !== r.nav_gen) return;
|
|
486
|
+
if (slots.forms.enabled && r.current_url) slots.forms.snapshot(document.body, r.current_url.pathname);
|
|
487
|
+
prepare_spa_document();
|
|
488
|
+
apply_soft_invalidate_doc(doc);
|
|
489
|
+
if (gen !== r.nav_gen) return;
|
|
490
|
+
if (reconcile) {
|
|
491
|
+
reconcile_body(document.body, doc.body, slots.morph);
|
|
492
|
+
dt_reconciled = true;
|
|
493
|
+
document.title = doc.title;
|
|
494
|
+
session().settle_lakes_in(document.body);
|
|
495
|
+
} else {
|
|
496
|
+
if (DEVTOOLS) emit({
|
|
497
|
+
domain: "nav",
|
|
498
|
+
name: "nav.fallback",
|
|
499
|
+
reason: !slots.morph ? "no-morph" : "shadow-region"
|
|
500
|
+
});
|
|
501
|
+
swap_body(document.body, doc.body);
|
|
502
|
+
document.title = doc.title;
|
|
503
|
+
session().settle_lakes_in(document.body);
|
|
504
|
+
dispose_scope("page");
|
|
505
|
+
}
|
|
506
|
+
globalThis.__og_restore_adopt?.();
|
|
507
|
+
session().retire_page_head_copies();
|
|
508
|
+
apply_late_templates(document.body);
|
|
509
|
+
finish_spa_document();
|
|
510
|
+
if (slots.forms.enabled) slots.forms.restore(url.pathname);
|
|
511
|
+
document.dispatchEvent(new Event("og:after-swap"));
|
|
512
|
+
};
|
|
513
|
+
if (use_vt && document.startViewTransition) {
|
|
514
|
+
const restore_vt_names = fold_orphan_vt_names(document.body, doc.body);
|
|
515
|
+
const t = document.startViewTransition(swap);
|
|
516
|
+
t.ready?.catch(() => {});
|
|
517
|
+
(t.finished ?? Promise.resolve()).then(restore_vt_names, restore_vt_names);
|
|
518
|
+
await t.updateCallbackDone.catch(() => {});
|
|
519
|
+
} else swap();
|
|
520
|
+
if (gen !== r.nav_gen) return;
|
|
521
|
+
r.doc_key = document_key(dest);
|
|
522
|
+
r.current_url = dest;
|
|
523
|
+
r.nav_target = null;
|
|
524
|
+
boot_link().beacon_nav({
|
|
525
|
+
from: from.pathname + from.search,
|
|
526
|
+
to: dest.pathname + dest.search,
|
|
527
|
+
type,
|
|
528
|
+
t: nav_t0,
|
|
529
|
+
fetched: nav_fetched,
|
|
530
|
+
styled: nav_styled,
|
|
531
|
+
swapped: performance.now(),
|
|
532
|
+
href: url.href
|
|
533
|
+
});
|
|
534
|
+
if (DEVTOOLS) emit({
|
|
535
|
+
domain: "nav",
|
|
536
|
+
name: "nav.finish",
|
|
537
|
+
to: dest.pathname + dest.search,
|
|
538
|
+
ms: dt_now() - dt_t0,
|
|
539
|
+
reconciled: dt_reconciled,
|
|
540
|
+
vt: !!(use_vt && document.startViewTransition)
|
|
541
|
+
});
|
|
542
|
+
if (replace) {} else if (pop_scroll) {
|
|
543
|
+
const html_el = document.documentElement;
|
|
544
|
+
const prev = html_el.style.scrollBehavior;
|
|
545
|
+
html_el.style.scrollBehavior = "auto";
|
|
546
|
+
try {
|
|
547
|
+
window.scrollTo(pop_scroll.x, pop_scroll.y);
|
|
548
|
+
} finally {
|
|
549
|
+
html_el.style.scrollBehavior = prev;
|
|
550
|
+
}
|
|
551
|
+
} else jump_to_hash(dest.hash);
|
|
552
|
+
announce(dest);
|
|
553
|
+
reset_focus(dest.hash);
|
|
554
|
+
r.run_after(from, dest, type);
|
|
555
|
+
document.dispatchEvent(new Event("og:page-load"));
|
|
556
|
+
if (gen === r.nav_gen) {
|
|
557
|
+
r.nav_abort = null;
|
|
558
|
+
if (r.nav_target === url.href) r.nav_target = null;
|
|
559
|
+
}
|
|
560
|
+
r.scan_preload_links();
|
|
561
|
+
}
|
|
562
|
+
/**
|
|
563
|
+
* Soft invalidate: refresh page/remote seeds for the current URL without navigation.
|
|
564
|
+
*
|
|
565
|
+
* Kit's `invalidateAll` re-runs loads in place — it is **not** a navigation (no
|
|
566
|
+
* `beforeNavigate` / `afterNavigate`). Remote `form()` always calls this on success; a
|
|
567
|
+
* full SPA navigate+VT here was wiping live island state. We bust the HTML cache,
|
|
568
|
+
* re-fetch, merge head, and refresh document seeds only — no VT, no body swap, no
|
|
569
|
+
* island remount, no live query-map clear, no auto-refresh of live queries. Islands
|
|
570
|
+
* that need query updates use `.refresh()`, or `submit().updates(q)` with server
|
|
571
|
+
* `requested(q).refreshAll()` (updates alone does not populate response `q`).
|
|
572
|
+
*
|
|
573
|
+
* Uses a separate abort/generation from hard `navigate()` so soft fetches never cancel
|
|
574
|
+
* an in-flight click navigation (and vice versa).
|
|
575
|
+
*/
|
|
576
|
+
async function invalidate_all() {
|
|
577
|
+
bust_page_cache();
|
|
578
|
+
const url = new URL(location.href);
|
|
579
|
+
soft_abort?.abort();
|
|
580
|
+
soft_abort = new AbortController();
|
|
581
|
+
const { signal } = soft_abort;
|
|
582
|
+
const gen = ++soft_gen;
|
|
583
|
+
let html;
|
|
584
|
+
try {
|
|
585
|
+
html = await fetch_page(url.href, signal);
|
|
586
|
+
} catch (err) {
|
|
587
|
+
if (err?.name === "AbortError" || gen !== soft_gen) return;
|
|
588
|
+
return;
|
|
589
|
+
}
|
|
590
|
+
if (gen !== soft_gen || html == null) return;
|
|
591
|
+
const doc = new DOMParser().parseFromString(html, "text/html");
|
|
592
|
+
if (KitBoot.document_has(doc)) return;
|
|
593
|
+
if (!doc.querySelector("meta[name=\"ogygia-router\"]")) return;
|
|
594
|
+
merge_head(doc.head);
|
|
595
|
+
apply_soft_invalidate_doc(doc);
|
|
596
|
+
}
|
|
597
|
+
/**
|
|
598
|
+
* ACCESSIBILITY — announce the new page. A body swap is invisible to assistive tech: no document
|
|
599
|
+
* `load`, so a screen reader is never told the page changed. Mirror what a full navigation (and
|
|
600
|
+
* SvelteKit) give for free — a visually-hidden `aria-live` region whose text becomes the new
|
|
601
|
+
* `<title>`, so the page is spoken on arrival. The region is created once and reused (it must
|
|
602
|
+
* already be in the DOM when its text changes for AT to observe it); it was detached before the
|
|
603
|
+
* swap so the reconcile couldn't remove it, and is re-attached here before its text is set.
|
|
604
|
+
*/
|
|
605
|
+
function announce(dest) {
|
|
606
|
+
let el = announcer;
|
|
607
|
+
if (!el) {
|
|
608
|
+
el = document.createElement("div");
|
|
609
|
+
el.setAttribute("data-ogygia-announcer", "");
|
|
610
|
+
el.setAttribute("aria-live", "assertive");
|
|
611
|
+
el.setAttribute("aria-atomic", "true");
|
|
612
|
+
el.style.cssText = "position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0 0 0 0);clip-path:inset(50%);white-space:nowrap;border:0";
|
|
613
|
+
announcer = el;
|
|
614
|
+
}
|
|
615
|
+
if (el.parentNode !== document.body) document.body.appendChild(el);
|
|
616
|
+
el.textContent = document.title || dest.pathname;
|
|
617
|
+
}
|
|
618
|
+
/**
|
|
619
|
+
* ACCESSIBILITY — reset keyboard focus after a navigation, so a keyboard or screen-reader user
|
|
620
|
+
* lands at the top of the new page instead of wherever focus was on the old one (a full navigation
|
|
621
|
+
* does this natively; a body swap does not). SvelteKit's algorithm: a `[autofocus]` element wins;
|
|
622
|
+
* else a `#hash` target; else focus falls back to `<body>` (made momentarily focusable). The one
|
|
623
|
+
* ogygia twist: a control INSIDE kept/persisted chrome (`data-ogygia-keep` / `data-persist`) that
|
|
624
|
+
* survived the nav is left focused — the visitor is still using that persistent widget.
|
|
625
|
+
*/
|
|
626
|
+
function reset_focus(hash) {
|
|
627
|
+
const active = document.activeElement;
|
|
628
|
+
if (active && active !== document.body && active.isConnected && active.closest("[data-ogygia-keep],[data-persist]")) return;
|
|
629
|
+
if (hash) {
|
|
630
|
+
const id = decodeURIComponent(hash.slice(1));
|
|
631
|
+
const target = id ? document.getElementById(id) : null;
|
|
632
|
+
if (target) return focus_reset(target);
|
|
633
|
+
}
|
|
634
|
+
const autofocus = document.querySelector("[autofocus]");
|
|
635
|
+
if (autofocus) {
|
|
636
|
+
autofocus.focus();
|
|
637
|
+
return;
|
|
638
|
+
}
|
|
639
|
+
focus_reset(document.body);
|
|
640
|
+
}
|
|
641
|
+
/** Merge <head>: keep nodes present in both, remove stale, add new. Keeps runtime scripts alive. */
|
|
642
|
+
function merge_head(new_head) {
|
|
643
|
+
const current = document.head;
|
|
644
|
+
const owned = session().page_head;
|
|
645
|
+
const current_nodes = /* @__PURE__ */ new Map();
|
|
646
|
+
for (const node of Array.from(current.children)) if (owned.has(node)) current_nodes.set(head_node_key(node), node);
|
|
647
|
+
const next_keys = /* @__PURE__ */ new Set();
|
|
648
|
+
for (const node of Array.from(new_head.children)) {
|
|
649
|
+
if (is_dangerous_head_node(node)) continue;
|
|
650
|
+
next_keys.add(head_node_key(node));
|
|
651
|
+
}
|
|
652
|
+
for (const [key, node] of current_nodes) {
|
|
653
|
+
if (next_keys.has(key)) continue;
|
|
654
|
+
if (keep_head_node_across_spa(node)) continue;
|
|
655
|
+
node.remove();
|
|
656
|
+
}
|
|
657
|
+
const anchor = current.firstChild;
|
|
658
|
+
for (const node of Array.from(new_head.children)) {
|
|
659
|
+
if (is_dangerous_head_node(node)) continue;
|
|
660
|
+
const key = head_node_key(node);
|
|
661
|
+
const existing = current_nodes.get(key);
|
|
662
|
+
if (key === "STYLE:data-sveltekit") {
|
|
663
|
+
existing?.remove();
|
|
664
|
+
install_head_style(node, current, anchor);
|
|
665
|
+
continue;
|
|
666
|
+
}
|
|
667
|
+
if (existing) continue;
|
|
668
|
+
if (node.tagName === "STYLE") install_head_style(node, current, anchor);
|
|
669
|
+
else session().claim_page_head(current.appendChild(node.cloneNode(true)));
|
|
670
|
+
}
|
|
671
|
+
}
|
|
672
|
+
/**
|
|
673
|
+
* Load the destination page's stylesheets into the live `<head>` and resolve once they have
|
|
674
|
+
* applied — call this BEFORE the body swap. A freshly appended `<link rel="stylesheet">` loads
|
|
675
|
+
* asynchronously, so swapping the body first shows the new route unstyled (e.g. a content column
|
|
676
|
+
* at full width) until the sheet arrives. That window is invisible on a warm cache but flashes on
|
|
677
|
+
* the first visit after a deploy, when the route CSS isn't cached yet. Preloading here closes it;
|
|
678
|
+
* `merge_head` then dedupes these by key so nothing is added twice. Capped so a stalled sheet
|
|
679
|
+
* can't hang navigation.
|
|
680
|
+
*/
|
|
681
|
+
function preload_stylesheets(new_head) {
|
|
682
|
+
const present = /* @__PURE__ */ new Set();
|
|
683
|
+
for (const node of Array.from(document.head.children)) if (node.tagName === "LINK" && node.getAttribute("rel") === "stylesheet") present.add(head_node_key(node));
|
|
684
|
+
const pending = [];
|
|
685
|
+
for (const node of Array.from(new_head.children)) {
|
|
686
|
+
if (node.tagName !== "LINK" || node.getAttribute("rel") !== "stylesheet") continue;
|
|
687
|
+
if (is_dangerous_head_node(node)) continue;
|
|
688
|
+
if (node.hasAttribute("disabled")) continue;
|
|
689
|
+
const key = head_node_key(node);
|
|
690
|
+
if (present.has(key)) continue;
|
|
691
|
+
present.add(key);
|
|
692
|
+
const link = node.cloneNode(true);
|
|
693
|
+
pending.push(new Promise((resolve) => {
|
|
694
|
+
link.addEventListener("load", () => resolve(), { once: true });
|
|
695
|
+
link.addEventListener("error", () => resolve(), { once: true });
|
|
696
|
+
}));
|
|
697
|
+
session().claim_page_head(link);
|
|
698
|
+
document.head.insertBefore(link, document.head.firstChild);
|
|
699
|
+
}
|
|
700
|
+
if (!pending.length) return Promise.resolve();
|
|
701
|
+
return Promise.race([Promise.all(pending), new Promise((resolve) => setTimeout(resolve, STYLESHEET_WAIT_MS))]);
|
|
702
|
+
}
|
|
703
|
+
/**
|
|
704
|
+
* SINGLE-FLIGHT NAVIGATION. Collect the incoming page's deferred, load-timed region calls and stream them as
|
|
705
|
+
* one batch. Reads the RENDERED holes (`<ogygia-region render="defer" endpoint>`), so it covers
|
|
706
|
+
* both placed server islands and held `region()` deferred regions alike — authoring syntax is
|
|
707
|
+
* irrelevant. Only `when="load"` (or unset) is batched: a region scheduled `visible`/`idle`/media
|
|
708
|
+
* stays lazy and fetches on its own trigger, so dynamic schedules are preserved, not eagerly pulled.
|
|
709
|
+
*/
|
|
710
|
+
/** `base`: the fetched page's own URL (its relative hrefs resolve against it). */
|
|
711
|
+
function batch_regions(doc, base) {
|
|
712
|
+
const endpoints = [];
|
|
713
|
+
const batched = /* @__PURE__ */ new Set();
|
|
714
|
+
for (const el of Array.from(doc.querySelectorAll("ogygia-region[render=\"defer\"][endpoint]"))) {
|
|
715
|
+
if ((el.getAttribute("when") || "load") !== "load") continue;
|
|
716
|
+
const ep = el.getAttribute("endpoint");
|
|
717
|
+
if (ep) {
|
|
718
|
+
endpoints.push(ep);
|
|
719
|
+
batched.add(ep);
|
|
720
|
+
}
|
|
721
|
+
}
|
|
722
|
+
if (!endpoints.length) return;
|
|
723
|
+
const same_url = (href) => {
|
|
724
|
+
try {
|
|
725
|
+
const u = new URL(href, base);
|
|
726
|
+
return u.pathname + u.search;
|
|
727
|
+
} catch {
|
|
728
|
+
return href;
|
|
729
|
+
}
|
|
730
|
+
};
|
|
731
|
+
const batched_urls = new Set(Array.from(batched, same_url));
|
|
732
|
+
for (const link of Array.from(doc.querySelectorAll("link[rel=\"preload\"][as=\"fetch\"]"))) if (batched_urls.has(same_url(link.getAttribute("href") || ""))) link.remove();
|
|
733
|
+
if (DEVTOOLS) emit({
|
|
734
|
+
domain: "nav",
|
|
735
|
+
name: "nav.batch",
|
|
736
|
+
count: endpoints.length
|
|
737
|
+
});
|
|
738
|
+
slots.frames?.stream?.(endpoints);
|
|
739
|
+
}
|
|
740
|
+
export { DOCUMENT_ACCEPT, apply_late_templates, bust_page_cache, fetch_page, head_node_key, install_head_style, invalidate_all, keep_head_node_across_spa, navigate, page_cache_size, tag_attr };
|