@ogygia/core 0.0.0 → 0.11.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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 +185 -0
- package/dist/compiler/ctx.js +203 -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,1352 @@
|
|
|
1
|
+
import { createHash, dir_entries, fs, path } from "./host.js";
|
|
2
|
+
import { fnv1a32 } from "../runtime/hash.js";
|
|
3
|
+
import { CLIENT_BINDING_STUB, is_island_path, transformHost, transformTsRegions, wrapperVirtualId } from "./region/transform.js";
|
|
4
|
+
import { clean_stale_ogygia_dirs, hasAnyCsrTrueRoute, kit_dirs, routeCsrIsFalse, routeCsrIsTrue } from "./kit.js";
|
|
5
|
+
import { run_module_macros } from "./macros/pipeline.js";
|
|
6
|
+
import { is_script_request } from "./script-request.js";
|
|
7
|
+
import { generateHydrateFeaturesSource, generateRuntimeEntrySource, resolveFeatures } from "./link/runtime-entry.js";
|
|
8
|
+
import { resolveFoucImportSpec } from "./fouc-css.js";
|
|
9
|
+
import { appendSvelteModuleRegistrations, appendTransportRegistrations, moduleHasTransportable, svelteModuleHasTransportable } from "./content/transportables.js";
|
|
10
|
+
import { APP_SHIM_IMPORT, FOREIGN_HYDRATE_MARK, rewrite_lake_import_to_placeholder } from "./region/emit.js";
|
|
11
|
+
import { island_deps_module } from "./link/island-deps.js";
|
|
12
|
+
import { island_shim_source, runtime_shim_source } from "./link/entry-shim.js";
|
|
13
|
+
import { context_string_keys, source_uses_ogygia_context } from "./link/context-detect.js";
|
|
14
|
+
import { collect_flag_sites } from "./flags.js";
|
|
15
|
+
import { router_css_module, router_css_roots } from "./link/router-css.js";
|
|
16
|
+
import { rate_limit_module, region_ttl_module, route_config_module, route_csr_module, secret_module, server_plugins_module, session_cookie_module, sign_module } from "./link/caps.js";
|
|
17
|
+
import { router_config_module } from "./link/router-config.js";
|
|
18
|
+
import { kit_transport_module, source_crosses_wire, transport_module, transportables_module } from "./link/transport.js";
|
|
19
|
+
import { PAGE_DATA_READS_TOKEN, server_island_ids, server_islands_module, server_manifest_module } from "./link/server-manifest.js";
|
|
20
|
+
import { manifest_module } from "./link/manifest.js";
|
|
21
|
+
import { dev_hmr_client_source } from "./dev/dev-hmr.js";
|
|
22
|
+
import { island_vpaths_affected_by_file, same_module_path } from "./dev/hmr.js";
|
|
23
|
+
import { PROFILER_MAPS_PLACEHOLDER, RESOLVED, V_DEVTOOLS_BOOT, V_DEVTOOLS_BOOT_URL, V_DEVTOOLS_META, V_DEV_HMR, V_DEV_HMR_URL, V_FN_MANIFEST, V_HYDRATE_FEATURES, V_ISLAND_DEPS, V_KIT_TRANSPORT, V_MANIFEST, V_PROFILER_MAPS, V_RATE_LIMIT, V_REGION_ENDPOINT, V_REGION_TTL, V_REQUEST_EVENT, V_ROUTER_CONFIG, V_ROUTER_CSS, V_ROUTE_CONFIG, V_ROUTE_CSR, V_RUNTIME, V_RUNTIME_ENTRY, V_RUNTIME_URL, V_SECRET, V_SERVER_ISLANDS, V_SERVER_MANIFEST, V_SERVER_PLUGINS, V_SESSION_COOKIE, V_SIGN, V_TRANSPORT, V_TRANSPORTABLES, V_TRANSPORTABLES_EAGER } from "./ids.js";
|
|
24
|
+
import { host_key, strip_id } from "./program.js";
|
|
25
|
+
import { mentions_page_store, page_data_keys_answer } from "./link/page-keys.js";
|
|
26
|
+
import { export_names, is_registry_stub_id, registry_client_id, registry_client_path, registry_client_source, registry_stub_names, registry_stub_source, static_script_specs } from "./link/registry-stub.js";
|
|
27
|
+
import { island_host_loaded } from "./link/emit-gate.js";
|
|
28
|
+
import { stamp_opaque } from "./ownership-stamps.js";
|
|
29
|
+
import { strip_bom } from "./bom.js";
|
|
30
|
+
// src/compiler/driver.ts
|
|
31
|
+
/**
|
|
32
|
+
* The `Compiler` — the driver / long-lived compile session. It holds the `Program` (cross-file
|
|
33
|
+
* linker), the resolved `CompileCtx`, and the per-file transform cache, and exposes the file-local
|
|
34
|
+
* front-end as one call: `transform(source, id)` → parse ▸ analyze ▸ lower ▸ emit (today fused inside
|
|
35
|
+
* `transformHost`), memoized. It is bundler-agnostic by construction — it imports no Vite; the adapter
|
|
36
|
+
* drives it. That independence is the design goal: a future REPL is just a second adapter over the
|
|
37
|
+
* same driver, feeding a `CompileCtx` + source and rendering the returned freeze.
|
|
38
|
+
*
|
|
39
|
+
* The transform cache is content-keyed (`hit.code === source`), so a changed source misses and
|
|
40
|
+
* recomputes on its own; the linker's `unregister_host` deliberately does NOT clear it.
|
|
41
|
+
*/
|
|
42
|
+
const performance = globalThis.performance;
|
|
43
|
+
/** The chunk names our content-hashed entries are emitted under (`entry_file_pattern` keys on them). */
|
|
44
|
+
const ISLAND_ENTRY_NAME_PREFIX = "og-region.";
|
|
45
|
+
const RUNTIME_ENTRY_NAME = "og-runtime";
|
|
46
|
+
const LEADING_SLASH = /^\//;
|
|
47
|
+
const BACKSLASH_G = /\\/g;
|
|
48
|
+
const COMPONENT_EXT_RE = /\.(svelte|js|ts)$/;
|
|
49
|
+
/** A Kit route host file (`+page.svelte`, `+layout.ts`, …) — the page node's own client modules. */
|
|
50
|
+
const ROUTE_HOST_FILE_RE = /^\+(page|layout)\.(svelte|ts|js|mjs)$/;
|
|
51
|
+
/** A `.ts`/`.js` module that can be a region registry (a minted `.ts` region host). */
|
|
52
|
+
const TS_REGISTRY_EXT_RE = /\.(ts|js|mjs)$/;
|
|
53
|
+
/** A Svelte rune module (`.svelte.ts` / `.svelte.js`). */
|
|
54
|
+
const SVELTE_RUNE_MODULE_RE = /\.svelte\.(ts|js)$/;
|
|
55
|
+
/** A script module the seed-shaping analysis parses with oxc (`.svelte.ts` included). */
|
|
56
|
+
const SCRIPT_MODULE_RE = /\.(?:[cm]?[jt]sx?)$/;
|
|
57
|
+
const SOURCE_EXT_RE = /\.(svelte|ts|js|mjs|cjs)$/;
|
|
58
|
+
const SERVER_MODULE_EXT_RE = /\.(server|remote)\.(ts|js|mjs)$/;
|
|
59
|
+
const SERVER_DIR_RE = /\/(src\/lib\/server|server)\//;
|
|
60
|
+
/** Static import / export-from / `import()` specifiers, for the island-graph dep walk (shared `g`
|
|
61
|
+
* regex — `walk_dep` resets `lastIndex` before each scan). */
|
|
62
|
+
const IMPORT_SPEC_G = /\bfrom\s*['"]([^'"\n]+)['"]|\bimport\s*['"]([^'"\n]+)['"]|\bimport\s*\(\s*['"]([^'"\n]+)['"]/g;
|
|
63
|
+
/** The extensions an extension-less island import may resolve to (bare, then index files). */
|
|
64
|
+
const ISLAND_DEP_EXTS = [
|
|
65
|
+
"",
|
|
66
|
+
".svelte",
|
|
67
|
+
".ts",
|
|
68
|
+
".js",
|
|
69
|
+
".svelte.ts",
|
|
70
|
+
".svelte.js",
|
|
71
|
+
".mjs"
|
|
72
|
+
];
|
|
73
|
+
const MODULE_SPEC_RE = /(?:^|[\n;])\s*(?:import|export)\b[^;'"()]*?from\s*['"]([^'"]+)['"]|(?:^|[\n;])\s*import\s*['"]([^'"]+)['"]/g;
|
|
74
|
+
/** Where Kit's `$app` alias points (Kit 2 and 3: `resolve.alias` `$app` → `<kit>/src/runtime/app`). */
|
|
75
|
+
const KIT_RUNTIME_APP = "/@sveltejs/kit/src/runtime/app/";
|
|
76
|
+
/**
|
|
77
|
+
* The island shim for an `$app/*` import, by specifier or by where Kit's alias sent it: Vite's alias
|
|
78
|
+
* plugin runs before any plugin's resolveId, so an import the transform did not rewrite (a module
|
|
79
|
+
* that joined the island graph late) arrives as `<kit>/src/runtime/app/state`, `…/state/index.js`.
|
|
80
|
+
*/
|
|
81
|
+
function app_shim_for(source, shims) {
|
|
82
|
+
const direct = shims[source];
|
|
83
|
+
if (direct) return direct;
|
|
84
|
+
const at = source.indexOf(KIT_RUNTIME_APP);
|
|
85
|
+
if (at === -1) return null;
|
|
86
|
+
let name = source.slice(at + 31);
|
|
87
|
+
if (name.endsWith("/index.js")) name = name.slice(0, -9);
|
|
88
|
+
else if (name.endsWith(".js")) name = name.slice(0, -3);
|
|
89
|
+
return shims["$app/" + name] ?? null;
|
|
90
|
+
}
|
|
91
|
+
/** Manifest path for a flag site: package-relative for declared surfaces, root-relative else. */
|
|
92
|
+
function flag_site_file(ctx, full) {
|
|
93
|
+
return (ctx.pkg_identity(full) ?? path.relative(ctx.root, full)).split(path.sep).join("/");
|
|
94
|
+
}
|
|
95
|
+
function extract_module_specs(src) {
|
|
96
|
+
MODULE_SPEC_RE.lastIndex = 0;
|
|
97
|
+
const specs = [];
|
|
98
|
+
let m;
|
|
99
|
+
while (m = MODULE_SPEC_RE.exec(src)) specs.push(m[1] ?? m[2]);
|
|
100
|
+
return specs;
|
|
101
|
+
}
|
|
102
|
+
const fnv = fnv1a32;
|
|
103
|
+
/** Once per module id: a dependency file carries ogygia marks but its package declares no
|
|
104
|
+
* `ogygia.files` — the marks are then silently inert (a `with { }` attribute is valid syntax,
|
|
105
|
+
* it just never rewrites), which is the worst way to fail. Say it loudly, once. */
|
|
106
|
+
const warned_undeclared = /* @__PURE__ */ new Set();
|
|
107
|
+
function warn_undeclared_pkg_marks(id) {
|
|
108
|
+
if (warned_undeclared.has(id)) return;
|
|
109
|
+
warned_undeclared.add(id);
|
|
110
|
+
console.warn(`[ogygia] ${id} uses ogygia marks, but its package declares no \`"ogygia": { "files": [...] }\` — the marks are IGNORED. Add the field to that package's package.json (npm-"files"-style paths/globs) to put it on ogygia's compile surface.`);
|
|
111
|
+
}
|
|
112
|
+
/** The client-hooks boot snippet for a generated runtime entry: an import of the runtime runner and
|
|
113
|
+
* a call that dynamic-imports the app's `hooks.client.*` — empty when the app has none. Runs the
|
|
114
|
+
* file's `init` on boot for csr=false pages (the runner skips a csr=true document). */
|
|
115
|
+
/**
|
|
116
|
+
* DEV: the folder `ogygia/runtime` resolves to — this package's own `exports["./runtime"]` (the
|
|
117
|
+
* dev boot imports that specifier). A published package points it at `dist/runtime` (= the
|
|
118
|
+
* prebuilt `runtime_dir`); this repo's workspace points it at `src/runtime` (`.ts` files). Null
|
|
119
|
+
* when it cannot be read (then `runtime_dir` stands). Once per runtime dir.
|
|
120
|
+
*/
|
|
121
|
+
const dev_runtimes = /* @__PURE__ */ new Map();
|
|
122
|
+
function dev_runtime_of(runtime_dir) {
|
|
123
|
+
if (dev_runtimes.has(runtime_dir)) return dev_runtimes.get(runtime_dir);
|
|
124
|
+
let out = null;
|
|
125
|
+
try {
|
|
126
|
+
const pkg_dir = path.dirname(path.dirname(runtime_dir));
|
|
127
|
+
const exp = JSON.parse(fs.readFileSync(path.join(pkg_dir, "package.json"), "utf8"))?.exports?.["./runtime"];
|
|
128
|
+
const rel = typeof exp === "string" ? exp : exp?.default;
|
|
129
|
+
if (typeof rel === "string") {
|
|
130
|
+
const file = path.join(pkg_dir, rel);
|
|
131
|
+
if (fs.existsSync(file)) out = {
|
|
132
|
+
dir: path.dirname(file),
|
|
133
|
+
ts: file.endsWith(".ts")
|
|
134
|
+
};
|
|
135
|
+
}
|
|
136
|
+
} catch {
|
|
137
|
+
out = null;
|
|
138
|
+
}
|
|
139
|
+
dev_runtimes.set(runtime_dir, out);
|
|
140
|
+
return out;
|
|
141
|
+
}
|
|
142
|
+
/** The plugins' browser halves for a generated boot: one static import each, and the list to pass. */
|
|
143
|
+
function client_plugins_boot(ctx) {
|
|
144
|
+
if (!ctx.client_plugins.length) return {
|
|
145
|
+
imports: "",
|
|
146
|
+
list: ""
|
|
147
|
+
};
|
|
148
|
+
return {
|
|
149
|
+
imports: ctx.client_plugins.map((spec, i) => `import __og_client_${i} from ${JSON.stringify(spec)};\n`).join(""),
|
|
150
|
+
list: `[${ctx.client_plugins.map((_, i) => `__og_client_${i}`).join(", ")}]`
|
|
151
|
+
};
|
|
152
|
+
}
|
|
153
|
+
function client_hooks_boot(ctx) {
|
|
154
|
+
if (!ctx.client_hooks) return {
|
|
155
|
+
imports: "",
|
|
156
|
+
call: ""
|
|
157
|
+
};
|
|
158
|
+
const runner = `${ctx.runtime_dir}/client-hooks.js`.replace(BACKSLASH_G, "/");
|
|
159
|
+
return {
|
|
160
|
+
imports: `import { run_app_client_hooks as __og_run_client_hooks } from ${JSON.stringify(runner)};\n`,
|
|
161
|
+
call: `__og_run_client_hooks(() => import(${JSON.stringify(ctx.client_hooks)}));\n`
|
|
162
|
+
};
|
|
163
|
+
}
|
|
164
|
+
var Compiler = class {
|
|
165
|
+
program;
|
|
166
|
+
transform_cache = /* @__PURE__ */ new Map();
|
|
167
|
+
profiler;
|
|
168
|
+
/** Every `import.meta.og.$` hoist collected across the build (tag → factory source). Filled by
|
|
169
|
+
* `macros()`; drained by the adapter's fn-manifest emit (dev load leg, renderChunk, writeBundle). */
|
|
170
|
+
dollar_hoists = /* @__PURE__ */ new Map();
|
|
171
|
+
/** `prescan()` is once-per-session — guarded so the adapter can call it from any hook. */
|
|
172
|
+
#scanned = false;
|
|
173
|
+
/**
|
|
174
|
+
* DEV: the server-island ids the last emitted `virtual:ogygia/server-manifest` carried. A HOST edit
|
|
175
|
+
* drops its islands' rows (`invalidate_for_file`) and invalidates the manifest; Kit re-imports the
|
|
176
|
+
* handle BEFORE the page transform re-registers them, so that manifest is emitted WITHOUT the ids —
|
|
177
|
+
* and nothing re-invalidated it afterwards: every hole answered 403 until a restart. The adapter
|
|
178
|
+
* asks `server_manifest_stale()` after each transform and invalidates again when a registered
|
|
179
|
+
* server id is missing from this set. `null` until the first emit (nothing to compare).
|
|
180
|
+
*/
|
|
181
|
+
#emitted_server_ids = null;
|
|
182
|
+
/** True (once) when a server island registered since the last manifest emit — re-invalidate it. */
|
|
183
|
+
server_manifest_stale() {
|
|
184
|
+
const emitted = this.#emitted_server_ids;
|
|
185
|
+
if (!emitted) return false;
|
|
186
|
+
for (const id of server_island_ids(this.program)) if (!emitted.has(id)) {
|
|
187
|
+
this.#emitted_server_ids = null;
|
|
188
|
+
return true;
|
|
189
|
+
}
|
|
190
|
+
return false;
|
|
191
|
+
}
|
|
192
|
+
#ctx = null;
|
|
193
|
+
constructor(program, profiler) {
|
|
194
|
+
this.program = program;
|
|
195
|
+
this.profiler = profiler;
|
|
196
|
+
}
|
|
197
|
+
/** Bind the resolved compile context (called once the bundler has resolved the build). */
|
|
198
|
+
configure(ctx) {
|
|
199
|
+
this.#ctx = ctx;
|
|
200
|
+
}
|
|
201
|
+
/**
|
|
202
|
+
* Devtools: the `island id → component name` map, read at call time off the live registry (so a
|
|
203
|
+
* dev-server middleware serves a COMPLETE, current map — no stale virtual-module snapshot). Keys
|
|
204
|
+
* are the island id (`<hash>` in `virtual:ogygia/island/<hash>.js`); values the component's
|
|
205
|
+
* basename. A held/generated island with no source file is skipped (the tab keeps its short hash).
|
|
206
|
+
*/
|
|
207
|
+
region_names() {
|
|
208
|
+
const names = {};
|
|
209
|
+
for (const [iid, vpath] of this.program.by_id) {
|
|
210
|
+
const cp = this.program.registry.get(vpath)?.componentPath;
|
|
211
|
+
if (!cp) continue;
|
|
212
|
+
const base = (cp.split("?")[0].split("#")[0].split("/").pop() || "").replace(COMPONENT_EXT_RE, "");
|
|
213
|
+
if (base && base !== iid) names[iid] = base;
|
|
214
|
+
}
|
|
215
|
+
return names;
|
|
216
|
+
}
|
|
217
|
+
/**
|
|
218
|
+
* Run the module-macro passes (`wire`/`$`/`source`/`store`/auto-brand, the plugins' macros, then
|
|
219
|
+
* `bake`) over one module — the leg that must land before the island transform / svelte compile /
|
|
220
|
+
* ts-region minting sees it. `source` is the CURRENT text (a plugin's pre-transform may already have
|
|
221
|
+
* edited it). Returns `{ code, touched }`; the caller nulls its own sourcemap when `touched`.
|
|
222
|
+
*/
|
|
223
|
+
macros(source, id) {
|
|
224
|
+
const ctx = this.#ctx;
|
|
225
|
+
return run_module_macros(source, id, {
|
|
226
|
+
root: ctx.root,
|
|
227
|
+
resolveAlias: ctx.resolve_alias,
|
|
228
|
+
pkgRoot: ctx.pkg_root,
|
|
229
|
+
dollarHoists: this.dollar_hoists,
|
|
230
|
+
macros: ctx.macros
|
|
231
|
+
}, this.profiler);
|
|
232
|
+
}
|
|
233
|
+
/**
|
|
234
|
+
* Transform a content (`.svx`/`.md`) island source the markdown preprocessor hands back — always
|
|
235
|
+
* wrapper-linked (`linkVirtual: true`), because a preprocessor output is shared across the ssr/client
|
|
236
|
+
* legs and can't take the csr=false stub split; content files aren't routes, so they'd get wrappers
|
|
237
|
+
* anyway. Registers the descriptors and returns the rewritten code, or `null` when it has no islands.
|
|
238
|
+
* This is the transform the adapter installs on the content-island bridge.
|
|
239
|
+
*/
|
|
240
|
+
transform_content_island(source, filename) {
|
|
241
|
+
const result = this.transform(source, filename, {
|
|
242
|
+
ssr: false,
|
|
243
|
+
linkVirtual: true
|
|
244
|
+
});
|
|
245
|
+
if (!result || !result.islands?.length) return null;
|
|
246
|
+
this.program.register(result, filename);
|
|
247
|
+
return result.code;
|
|
248
|
+
}
|
|
249
|
+
/**
|
|
250
|
+
* Lower one file: run the fused parse ▸ analyze ▸ lower ▸ emit front-end and register nothing —
|
|
251
|
+
* the caller registers the returned descriptors into the `Program`. Memoized per
|
|
252
|
+
* `(id, ssr, linkVirtual, routeCsr)`, content-gated on the source.
|
|
253
|
+
*/
|
|
254
|
+
/**
|
|
255
|
+
* The REAL source file a module derives from. A real file is its own origin. A generated entry
|
|
256
|
+
* (a portable-snippet synth, re-processed under its `virtual:ogygia/island/<iid>.svelte` id)
|
|
257
|
+
* resolves through the registry's `hostPath` — transitively, so an entry minted while re-processing
|
|
258
|
+
* another entry still lands on the file the outermost slice was cut from. This is the ONE rule
|
|
259
|
+
* `resolve_id` already applies to an entry's plain imports; threading it into the transform keeps
|
|
260
|
+
* a re-minted marked import (whose resolved path is BAKED into a region module's source, bypassing
|
|
261
|
+
* resolveId) on the same base. Normalized like `transform_module`'s gate (`strip_id`, `/@id/`).
|
|
262
|
+
*/
|
|
263
|
+
#origin_of(id) {
|
|
264
|
+
const { registry } = this.program;
|
|
265
|
+
const bare = (s) => {
|
|
266
|
+
const n = strip_id(s);
|
|
267
|
+
return n.startsWith("/@id/") ? n.slice(5) : n;
|
|
268
|
+
};
|
|
269
|
+
let cur = bare(id);
|
|
270
|
+
const seen = /* @__PURE__ */ new Set([cur]);
|
|
271
|
+
for (;;) {
|
|
272
|
+
const host = registry.get(cur)?.hostPath;
|
|
273
|
+
if (!host) break;
|
|
274
|
+
const next = bare(host);
|
|
275
|
+
if (seen.has(next)) break;
|
|
276
|
+
seen.add(next);
|
|
277
|
+
cur = next;
|
|
278
|
+
}
|
|
279
|
+
return cur;
|
|
280
|
+
}
|
|
281
|
+
transform(source, id, opts = {}) {
|
|
282
|
+
const ctx = this.#ctx;
|
|
283
|
+
const { prof, P, outHash } = this.profiler;
|
|
284
|
+
const ssr = opts.ssr !== false;
|
|
285
|
+
const routesDir = kit_dirs(ctx.root).routes_dir;
|
|
286
|
+
const is_layout_host = path.basename(id) === "+layout.svelte";
|
|
287
|
+
const link_virtual = opts.linkVirtual !== void 0 ? opts.linkVirtual : ssr || !routeCsrIsFalse(id, routesDir) || is_layout_host && hasAnyCsrTrueRoute(routesDir);
|
|
288
|
+
const route_csr = routeCsrIsTrue(id, routesDir) ? true : routeCsrIsFalse(id, routesDir) ? false : void 0;
|
|
289
|
+
const cache_key = `${id}\0${ssr ? "s" : "c"}\0${link_virtual ? "1" : "0"}\0${route_csr === true ? "t" : route_csr === false ? "f" : "n"}`;
|
|
290
|
+
const hit = this.transform_cache.get(cache_key);
|
|
291
|
+
if (hit && hit.code === source) {
|
|
292
|
+
if (P) prof.transformHit++;
|
|
293
|
+
return hit.result;
|
|
294
|
+
}
|
|
295
|
+
const th0 = P ? performance.now() : 0;
|
|
296
|
+
const result = transformHost(source, id, {
|
|
297
|
+
root: ctx.root,
|
|
298
|
+
libDir: ctx.libDir,
|
|
299
|
+
readFile: (abs) => ctx.read_file(abs),
|
|
300
|
+
pathModule: path,
|
|
301
|
+
dev: ctx.is_dev,
|
|
302
|
+
virtualPathFor: (_hostId, iid) => ctx.island_virtual_id(iid),
|
|
303
|
+
wrapperPathFor: (_hostId, iid) => wrapperVirtualId(iid),
|
|
304
|
+
devUrlFor: (virtualPath) => ctx.dev_url_for(virtualPath),
|
|
305
|
+
originOf: (host) => this.#origin_of(host),
|
|
306
|
+
appDir: ctx.app_dir,
|
|
307
|
+
visibleMargin: ctx.visibleMargin,
|
|
308
|
+
presets: ctx.presets,
|
|
309
|
+
importKeys: ctx.import_keys,
|
|
310
|
+
idSalt: ctx.id_salt,
|
|
311
|
+
pkg_identity: (abs) => ctx.pkg_identity(abs),
|
|
312
|
+
linkVirtualIsland: link_virtual,
|
|
313
|
+
clientBindingStub: CLIENT_BINDING_STUB,
|
|
314
|
+
routeCsr: route_csr,
|
|
315
|
+
ssr
|
|
316
|
+
});
|
|
317
|
+
if (P) {
|
|
318
|
+
prof.transformMs += performance.now() - th0;
|
|
319
|
+
prof.transformN++;
|
|
320
|
+
outHash.set(cache_key, fnv(JSON.stringify(result?.code ?? result)));
|
|
321
|
+
}
|
|
322
|
+
this.transform_cache.set(cache_key, {
|
|
323
|
+
code: source,
|
|
324
|
+
result
|
|
325
|
+
});
|
|
326
|
+
return result;
|
|
327
|
+
}
|
|
328
|
+
/**
|
|
329
|
+
* Mint the `.ts` / `.js` regions in one module — `with { wake: … }` load/remote imports become
|
|
330
|
+
* island descriptors. The ts-region half of the front-end, sharing the driver's resolved context
|
|
331
|
+
* (so both the prescan and the transform hook mint identically). Not memoized — the caller gates it
|
|
332
|
+
* on the id + marker; the returned descriptors are the caller's to `register`.
|
|
333
|
+
*/
|
|
334
|
+
ts_regions(source, id) {
|
|
335
|
+
const ctx = this.#ctx;
|
|
336
|
+
return transformTsRegions(source, id, {
|
|
337
|
+
root: ctx.root,
|
|
338
|
+
libDir: ctx.libDir,
|
|
339
|
+
pathModule: path,
|
|
340
|
+
dev: ctx.is_dev,
|
|
341
|
+
virtualPathFor: (_hostId, iid) => ctx.island_virtual_id(iid),
|
|
342
|
+
devUrlFor: (virtualPath) => ctx.dev_url_for(virtualPath),
|
|
343
|
+
appDir: ctx.app_dir,
|
|
344
|
+
importKeys: ctx.import_keys,
|
|
345
|
+
idSalt: ctx.id_salt,
|
|
346
|
+
pkg_identity: (abs) => ctx.pkg_identity(abs)
|
|
347
|
+
});
|
|
348
|
+
}
|
|
349
|
+
/**
|
|
350
|
+
* Discover every island up front — walk `src/`, transform each `.svelte` host and mint each
|
|
351
|
+
* `.ts`/`.js` region, register the descriptors, then complete `island_graph` TRANSITIVELY and
|
|
352
|
+
* finalize the runtime capability marks (so the sticky runtime entry bundles only what the app
|
|
353
|
+
* uses, and its immutable chunk name busts on a feature-set change). Once per session, so the
|
|
354
|
+
* adapter can call it from any hook. Populates the `Program`; the fs walk is the only side effect.
|
|
355
|
+
*/
|
|
356
|
+
prescan() {
|
|
357
|
+
if (this.#scanned) return;
|
|
358
|
+
this.#scanned = true;
|
|
359
|
+
const ctx = this.#ctx;
|
|
360
|
+
const { prof, P } = this.profiler;
|
|
361
|
+
const program = this.program;
|
|
362
|
+
const { registry, island_graph, transportable_modules, runtime_marks } = program;
|
|
363
|
+
const root = ctx.root;
|
|
364
|
+
const src_dir = path.join(root, "src");
|
|
365
|
+
clean_stale_ogygia_dirs(src_dir);
|
|
366
|
+
const page_importers = ctx.page_importers;
|
|
367
|
+
const imports_page_spec = (specs) => page_importers.length > 0 && specs.some((s) => page_importers.includes(s));
|
|
368
|
+
const scan_file = (full, name) => {
|
|
369
|
+
if (name.endsWith(".svelte")) {
|
|
370
|
+
const src = ctx.read_file(full);
|
|
371
|
+
if (src == null) return;
|
|
372
|
+
if (!runtime_marks.context && source_uses_ogygia_context(src)) runtime_marks.context = true;
|
|
373
|
+
if (!program.crosses_wire && source_crosses_wire(src)) program.crosses_wire = true;
|
|
374
|
+
{
|
|
375
|
+
const specs = extract_module_specs(src);
|
|
376
|
+
if (specs.length) program.module_specs.set(full, specs);
|
|
377
|
+
if (imports_page_spec(specs)) program.router_modules.add(full);
|
|
378
|
+
if (specs.includes("@ogygia/flags")) program.flag_sites.push(...collect_flag_sites(src, full, flag_site_file(ctx, full)));
|
|
379
|
+
}
|
|
380
|
+
if (svelteModuleHasTransportable(src, full)) transportable_modules.add(full);
|
|
381
|
+
const result = this.transform(src, full);
|
|
382
|
+
if (result) program.register(result, full);
|
|
383
|
+
} else if ((name.endsWith(".ts") || name.endsWith(".js") || name.endsWith(".mjs")) && !name.endsWith(".d.ts")) {
|
|
384
|
+
const src = ctx.read_file(full);
|
|
385
|
+
if (src == null) return;
|
|
386
|
+
if (!runtime_marks.context && source_uses_ogygia_context(src)) runtime_marks.context = true;
|
|
387
|
+
if (!program.crosses_wire && (name.endsWith(".remote.ts") || name.endsWith(".remote.js") || source_crosses_wire(src))) program.crosses_wire = true;
|
|
388
|
+
{
|
|
389
|
+
const specs = extract_module_specs(src);
|
|
390
|
+
if (specs.length) program.module_specs.set(full, specs);
|
|
391
|
+
if (imports_page_spec(specs)) program.router_modules.add(full);
|
|
392
|
+
if (specs.includes("@ogygia/flags")) program.flag_sites.push(...collect_flag_sites(src, full, flag_site_file(ctx, full)));
|
|
393
|
+
}
|
|
394
|
+
if (moduleHasTransportable(src, full)) transportable_modules.add(full);
|
|
395
|
+
const result = this.ts_regions(src, full);
|
|
396
|
+
if (result) program.register(result, full);
|
|
397
|
+
}
|
|
398
|
+
};
|
|
399
|
+
const walk = (dir) => {
|
|
400
|
+
let entries;
|
|
401
|
+
try {
|
|
402
|
+
entries = dir_entries(dir);
|
|
403
|
+
} catch {
|
|
404
|
+
return;
|
|
405
|
+
}
|
|
406
|
+
for (const entry of entries) {
|
|
407
|
+
const full = path.join(dir, entry.name);
|
|
408
|
+
if (entry.isDirectory()) {
|
|
409
|
+
if (entry.name === "node_modules" || entry.name === ".ogygia") continue;
|
|
410
|
+
walk(full);
|
|
411
|
+
} else scan_file(full, entry.name);
|
|
412
|
+
}
|
|
413
|
+
};
|
|
414
|
+
{
|
|
415
|
+
const __ps = P ? performance.now() : 0;
|
|
416
|
+
walk(src_dir);
|
|
417
|
+
for (const p of ctx.pkg_scan) {
|
|
418
|
+
for (const d of p.dirs) walk(d);
|
|
419
|
+
for (const f of p.files) scan_file(f, f.slice(f.lastIndexOf("/") + 1));
|
|
420
|
+
}
|
|
421
|
+
for (const f of ctx.page_files) {
|
|
422
|
+
program.router_modules.add(f);
|
|
423
|
+
if (!program.module_specs.has(f)) {
|
|
424
|
+
const src = ctx.read_file(f);
|
|
425
|
+
const specs = src == null ? [] : extract_module_specs(src);
|
|
426
|
+
if (specs.length) program.module_specs.set(f, specs);
|
|
427
|
+
}
|
|
428
|
+
}
|
|
429
|
+
if (P) prof.prescanMs += performance.now() - __ps;
|
|
430
|
+
}
|
|
431
|
+
{
|
|
432
|
+
const __ws = P ? performance.now() : 0;
|
|
433
|
+
for (const entry of registry.values()) if (entry.componentPath) this.mark_island_closure(entry.componentPath);
|
|
434
|
+
if (P) prof.prescanMs += performance.now() - __ws;
|
|
435
|
+
}
|
|
436
|
+
if (!runtime_marks.context) {
|
|
437
|
+
const reads = [];
|
|
438
|
+
const island_set = /* @__PURE__ */ new Set();
|
|
439
|
+
for (const file of island_graph) {
|
|
440
|
+
if (!file.endsWith(".svelte") && !SCRIPT_MODULE_RE.test(file)) continue;
|
|
441
|
+
const src = ctx.read_file(file);
|
|
442
|
+
if (src == null) continue;
|
|
443
|
+
const { reads: r, sets } = context_string_keys(src, file.endsWith(".svelte") ? "svelte" : "script");
|
|
444
|
+
for (const k of sets) island_set.add(k);
|
|
445
|
+
if (r.length) reads.push({
|
|
446
|
+
file,
|
|
447
|
+
keys: r
|
|
448
|
+
});
|
|
449
|
+
}
|
|
450
|
+
for (const { file, keys } of reads) for (const key of keys) {
|
|
451
|
+
if (island_set.has(key)) continue;
|
|
452
|
+
console.warn(`[ogygia] island code ${path.relative(root, file)} reads getContext('${key}'), but this app registers no ogygia context provider and no island code sets '${key}'. On a csr=false page a value set with Svelte's setContext in a page/layout does NOT cross the island boundary — the island reads undefined on the client, re-renders a different tree, and Svelte discards its server-rendered DOM on hydration (a silent full re-render). Fix: provide '${key}' with setContext / <Provide> / createContext imported from 'ogygia' (in a csr=false layout); the read stays getContext('${key}').`);
|
|
453
|
+
}
|
|
454
|
+
}
|
|
455
|
+
if (transportable_modules.size > 0) runtime_marks.wire = true;
|
|
456
|
+
runtime_marks.complete = true;
|
|
457
|
+
program.runtime_feature_hash = createHash("sha256").update(resolveFeatures(runtime_marks).join(",")).digest("hex").slice(0, 8);
|
|
458
|
+
}
|
|
459
|
+
/** Files the island-closure walk has already read (see `mark_island_closure`). Lives for the
|
|
460
|
+
* program, so a closure marked at prescan is never re-walked when a later island shares it. */
|
|
461
|
+
#island_closure_seen = /* @__PURE__ */ new Set();
|
|
462
|
+
/**
|
|
463
|
+
* Mark `componentAbs` and EVERYTHING it imports (transitively) as island code, so the `$app/*`
|
|
464
|
+
* shim decision for each of those modules is DETERMINISTIC — before the bundler resolves a single
|
|
465
|
+
* one of them. A module shared between an island and a non-island route is otherwise marked lazily
|
|
466
|
+
* during the bundler's own walk: if its `$app/*` resolves before the island path reaches it, it
|
|
467
|
+
* keeps Kit's real client store — which under `csr = false` is never populated → `page.url`
|
|
468
|
+
* undefined, `page.data` empty → the island crashes or reads nothing at hydrate. Shimming it is
|
|
469
|
+
* right in both worlds: on a Kit-booted document the shim reads Kit's real page (the kit-page
|
|
470
|
+
* thread). (The `?og-region` module-id fork was tried and reverted — it broke Svelte's scoped-CSS
|
|
471
|
+
* emission; membership rides OUTSIDE the module id here, the walk only READS.)
|
|
472
|
+
*
|
|
473
|
+
* Follows relative, `$lib` AND the app's aliases (`kit.alias` / `resolve.alias` — a customer's
|
|
474
|
+
* `$lib_x/utils/boot` import was where the walk used to stop, and its `$app/state` went to whichever
|
|
475
|
+
* page loaded first). Bare package specifiers stop it; the lazy resolveId marking stays their
|
|
476
|
+
* backstop. Called at prescan for every island, and again in dev for an island registered by a
|
|
477
|
+
* later transform (a file added while the server runs). Returns the modules marked for the first
|
|
478
|
+
* time by this call, so a dev caller can drop their cached transforms.
|
|
479
|
+
*/
|
|
480
|
+
/** DEV: modules `mark_island_closure` marked for the first time AFTER prescan — an island a later
|
|
481
|
+
* transform registered (a file added while the server runs). Each may already sit in the dev
|
|
482
|
+
* server's module graph, transformed with Kit's real `$app/*` for a non-island importer; the
|
|
483
|
+
* plugin drains this list and drops those cached transforms so the next load re-resolves them. */
|
|
484
|
+
#closure_added = [];
|
|
485
|
+
#mark_registered_closures(result) {
|
|
486
|
+
if (!this.#ctx.is_dev) return;
|
|
487
|
+
for (const isl of result.islands ?? []) if (isl.componentPath) this.#closure_added.push(...this.mark_island_closure(isl.componentPath));
|
|
488
|
+
}
|
|
489
|
+
/** DEV: take the modules newly marked as island code since the last drain (see above). */
|
|
490
|
+
drain_closure_marks() {
|
|
491
|
+
const out = this.#closure_added;
|
|
492
|
+
this.#closure_added = [];
|
|
493
|
+
return out;
|
|
494
|
+
}
|
|
495
|
+
mark_island_closure(componentAbs) {
|
|
496
|
+
const ctx = this.#ctx;
|
|
497
|
+
const { island_graph } = this.program;
|
|
498
|
+
const aliases = ctx.resolve_alias;
|
|
499
|
+
const added = [];
|
|
500
|
+
const resolve_dep = (spec, importerAbs) => {
|
|
501
|
+
const base = resolveFoucImportSpec(spec, importerAbs, ctx.libDir, aliases);
|
|
502
|
+
if (!base) return null;
|
|
503
|
+
for (const ext of ISLAND_DEP_EXTS) try {
|
|
504
|
+
if (fs.statSync(base + ext).isFile()) return base + ext;
|
|
505
|
+
} catch {}
|
|
506
|
+
for (const ext of ISLAND_DEP_EXTS.slice(1)) {
|
|
507
|
+
const idx = path.join(base, "index" + ext);
|
|
508
|
+
try {
|
|
509
|
+
if (fs.statSync(idx).isFile()) return idx;
|
|
510
|
+
} catch {}
|
|
511
|
+
}
|
|
512
|
+
return null;
|
|
513
|
+
};
|
|
514
|
+
const walk = (abs) => {
|
|
515
|
+
const norm = strip_id(abs);
|
|
516
|
+
if (this.#island_closure_seen.has(norm)) return;
|
|
517
|
+
this.#island_closure_seen.add(norm);
|
|
518
|
+
if (!island_graph.has(norm)) {
|
|
519
|
+
island_graph.add(norm);
|
|
520
|
+
added.push(norm);
|
|
521
|
+
}
|
|
522
|
+
if (!SOURCE_EXT_RE.test(norm)) return;
|
|
523
|
+
const src = ctx.read_file(norm);
|
|
524
|
+
if (src == null) return;
|
|
525
|
+
IMPORT_SPEC_G.lastIndex = 0;
|
|
526
|
+
let m;
|
|
527
|
+
while (m = IMPORT_SPEC_G.exec(src)) {
|
|
528
|
+
const spec = m[1] || m[2] || m[3];
|
|
529
|
+
if (!spec || spec[0] === "\0" || spec.startsWith("$app/") || spec.startsWith("$env/") || spec.startsWith("virtual:")) continue;
|
|
530
|
+
const dep = resolve_dep(spec, norm);
|
|
531
|
+
if (dep) walk(dep);
|
|
532
|
+
}
|
|
533
|
+
};
|
|
534
|
+
walk(componentAbs);
|
|
535
|
+
return added;
|
|
536
|
+
}
|
|
537
|
+
/**
|
|
538
|
+
* Scan ENTRIES for Vite's dep optimizer: every hydrate island's component file and the host file
|
|
539
|
+
* that places it — real, absolute, on-disk source paths. Under `csr = false` Kit ships no client
|
|
540
|
+
* entry and registers only `routes/**\/+*` as scan entries, so Vite's scanner reaches an island
|
|
541
|
+
* only when a route file imports it statically. An island behind a block registry, an
|
|
542
|
+
* `import.meta.og.regions()` glob or a `.remote.ts` mint is never crawled: its client deps are
|
|
543
|
+
* discovered LAZILY on its first wake, and every discovery re-optimizes, rotates the optimizer's
|
|
544
|
+
* browserHash and full-reloads — on a large app a reload storm that never settles. The adapter
|
|
545
|
+
* appends these to `optimizeDeps.entries` (dev) so Vite's OWN scanner crawls them at startup with
|
|
546
|
+
* the full plugin pipeline: its resolver, every plugin's `resolveId` (a `?client` import resolves
|
|
547
|
+
* through vite-plugin-iso-import), a linked workspace package followed as SOURCE and never
|
|
548
|
+
* pre-bundled, the app's `exclude` honoured.
|
|
549
|
+
*
|
|
550
|
+
* Deliberately NOT a self-computed `optimizeDeps.include` list. A resolver that is not Vite's
|
|
551
|
+
* mis-classifies something Vite knows — a plugin query, a workspace link, an `exports` map — and
|
|
552
|
+
* a wrong `include` hands rolldown an id it cannot load: `UNLOADABLE_DEPENDENCY`, a dead dev
|
|
553
|
+
* server (two field-reported regressions). An entry can only ever ADD a crawl root; what the
|
|
554
|
+
* crawl finds is Vite's call. A `defer` island renders on the server (its closure is not client
|
|
555
|
+
* code) and a lake ships no client JS, so neither is an entry; the host file covers a
|
|
556
|
+
* portable-snippet synth, which has no component file of its own. Needs `prescan()`; deduped,
|
|
557
|
+
* sorted, existing source files only.
|
|
558
|
+
*/
|
|
559
|
+
island_scan_entries() {
|
|
560
|
+
const { registry, region_kinds } = this.program;
|
|
561
|
+
const out = /* @__PURE__ */ new Set();
|
|
562
|
+
const add = (p) => {
|
|
563
|
+
if (!p) return;
|
|
564
|
+
const abs = strip_id(p);
|
|
565
|
+
if (!SOURCE_EXT_RE.test(abs)) return;
|
|
566
|
+
try {
|
|
567
|
+
if (fs.statSync(abs).isFile()) out.add(abs);
|
|
568
|
+
} catch {}
|
|
569
|
+
};
|
|
570
|
+
for (const entry of registry.values()) {
|
|
571
|
+
if (entry.role !== "entry" || entry.server) continue;
|
|
572
|
+
if (region_kinds.get(entry.id) !== "hydrate") continue;
|
|
573
|
+
add(entry.componentPath);
|
|
574
|
+
add(entry.hostPath);
|
|
575
|
+
}
|
|
576
|
+
return [...out].sort();
|
|
577
|
+
}
|
|
578
|
+
/** The feature-selected runtime chunk name (immutable-cached). Needs prescan to have run for a
|
|
579
|
+
* non-empty feature hash; both build legs prescan the same source → the same name. */
|
|
580
|
+
runtime_chunk_filename() {
|
|
581
|
+
return this.#ctx.runtime_chunk_filename(this.program.runtime_feature_hash);
|
|
582
|
+
}
|
|
583
|
+
/** Public URL of the runtime chunk (asset prefix + filename — honors a non-root base / assets CDN). */
|
|
584
|
+
runtime_chunk_url() {
|
|
585
|
+
return this.#ctx.runtime_chunk_url(this.program.runtime_feature_hash);
|
|
586
|
+
}
|
|
587
|
+
/**
|
|
588
|
+
* Client-build chunk emit (via the injected `emitFile`): the feature-selected runtime entry (when
|
|
589
|
+
* `emitRuntime`), then one chunk per deduped HYDRATE region id. IDENTITY vs LOCATION: SSR bakes the
|
|
590
|
+
* stable name (`island_public_url`) as the region's identity; the file the browser loads is named
|
|
591
|
+
* by its content (the bundler hashes it), and the bundle end hands the stable → hashed map to the
|
|
592
|
+
* server (the handoff's `entries`). The stable name is emitted too, as a shim of the hashed file.
|
|
593
|
+
* csr=false hosts omit wrapper imports so this emit owns the module. Idempotent per id.
|
|
594
|
+
*/
|
|
595
|
+
#router_css_roots_cache = null;
|
|
596
|
+
/** The server-router component roots (link/router-css.ts). Build: prescan is complete before any
|
|
597
|
+
* consumer runs — memoized. Dev: modules appear lazily (HMR), recompute per call. */
|
|
598
|
+
router_css_roots() {
|
|
599
|
+
const ctx = this.#ctx;
|
|
600
|
+
if (ctx.is_build && this.#router_css_roots_cache) return this.#router_css_roots_cache;
|
|
601
|
+
const sorted = [...new Set(router_css_roots(this.program.router_modules, this.program.module_specs, ctx.libDir))].sort();
|
|
602
|
+
if (ctx.is_build) this.#router_css_roots_cache = sorted;
|
|
603
|
+
return sorted;
|
|
604
|
+
}
|
|
605
|
+
/** Does the program hold ANY hydrate island? The runtime-emission gate needs this because
|
|
606
|
+
* `hasAnyCsrFalseRoute` only inspects Kit PAGE leaves — an app whose islands live solely in
|
|
607
|
+
* router-rendered components (a pure-router / fragment-only service has ZERO `+page` files)
|
|
608
|
+
* answers "no csr=false page" while its documents still `<script src>` the runtime. */
|
|
609
|
+
/**
|
|
610
|
+
* Server-only islands — `render: 'deferred'` with no client chunk — and the component file each
|
|
611
|
+
* renders. Nothing on any page links such a component's CSS (Kit collects stylesheets from the
|
|
612
|
+
* client graph; this subtree is never in it), so the client leg compiles each one's whole tree
|
|
613
|
+
* CSS into a dedicated asset the hole response links (vite/index.ts, `region_css_links`).
|
|
614
|
+
* Sorted for determinism; a component shared by several ids is emitted once (by `abs`).
|
|
615
|
+
*/
|
|
616
|
+
server_island_css_roots() {
|
|
617
|
+
const out = [];
|
|
618
|
+
for (const [iid, vpath] of this.program.by_id) {
|
|
619
|
+
const entry = this.program.registry.get(vpath);
|
|
620
|
+
if (!entry?.server || !entry.componentPath) continue;
|
|
621
|
+
if (this.program.region_kinds.get(iid) === "hydrate") continue;
|
|
622
|
+
out.push({
|
|
623
|
+
iid,
|
|
624
|
+
abs: host_key(entry.componentPath)
|
|
625
|
+
});
|
|
626
|
+
}
|
|
627
|
+
return out.sort((a, b) => a.iid < b.iid ? -1 : a.iid > b.iid ? 1 : 0);
|
|
628
|
+
}
|
|
629
|
+
/** The public URL key a server island's CSS is handed off under (matches `island_url[id]`). */
|
|
630
|
+
island_public_url(iid) {
|
|
631
|
+
return this.#ctx.island_public_url(iid);
|
|
632
|
+
}
|
|
633
|
+
has_hydrate_regions() {
|
|
634
|
+
for (const kind of this.program.region_kinds.values()) if (kind === "hydrate") return true;
|
|
635
|
+
return false;
|
|
636
|
+
}
|
|
637
|
+
/** The server leg's real module graph, for the client-leg handoff (link/emit-gate.ts). */
|
|
638
|
+
ssr_transformed_hosts() {
|
|
639
|
+
return [...this.program.ssr_transformed].sort();
|
|
640
|
+
}
|
|
641
|
+
/**
|
|
642
|
+
* Client leg: the runtime chunk + one deterministic chunk per deduped hydrate region. `loaded` —
|
|
643
|
+
* the server leg's transformed-module set (the handoff the plugin reads) — gates the emit to
|
|
644
|
+
* islands whose HOST the server bundle actually contains; `null` (no handoff: standalone, or a
|
|
645
|
+
* client-only build) keeps every prescanned island, as before. Returns how many were skipped.
|
|
646
|
+
*/
|
|
647
|
+
emit_build_chunks(emitFile, { emitRuntime, loaded = null }) {
|
|
648
|
+
this.island_entry_refs.clear();
|
|
649
|
+
this.runtime_entry_ref = null;
|
|
650
|
+
if (emitRuntime) {
|
|
651
|
+
const feat = this.#ctx.runtime_features(this.program.runtime_feature_hash);
|
|
652
|
+
this.runtime_entry_ref = emitFile({
|
|
653
|
+
type: "chunk",
|
|
654
|
+
id: V_RUNTIME_ENTRY,
|
|
655
|
+
name: RUNTIME_ENTRY_NAME + (feat ? "-" + feat : "")
|
|
656
|
+
});
|
|
657
|
+
}
|
|
658
|
+
const { region_kinds, by_id, emitted_island_chunks, registry } = this.program;
|
|
659
|
+
let skipped = 0;
|
|
660
|
+
for (const [rid, kind] of region_kinds) {
|
|
661
|
+
if (kind !== "hydrate") continue;
|
|
662
|
+
const virtualPath = by_id.get(rid);
|
|
663
|
+
if (!virtualPath) continue;
|
|
664
|
+
if (emitted_island_chunks.has(rid)) continue;
|
|
665
|
+
if (!island_host_loaded(registry.get(virtualPath)?.hostPath, loaded)) {
|
|
666
|
+
skipped++;
|
|
667
|
+
continue;
|
|
668
|
+
}
|
|
669
|
+
this.emit_island_entry(emitFile, rid, virtualPath);
|
|
670
|
+
}
|
|
671
|
+
return skipped;
|
|
672
|
+
}
|
|
673
|
+
/** Client-build refs of each emitted island entry (by island id) and of the runtime entry: the
|
|
674
|
+
* bundle end turns them into the hashed file names the handoff maps the stable names to. */
|
|
675
|
+
island_entry_refs = /* @__PURE__ */ new Map();
|
|
676
|
+
runtime_entry_ref = null;
|
|
677
|
+
/**
|
|
678
|
+
* At the bundle's end (the names are final): each entry's IDENTITY → its LOCATION. `islands` maps
|
|
679
|
+
* an island entry's hashed file to its identity (the collector keys every map by identity);
|
|
680
|
+
* `locations` is what the handoff carries to the server (`entries`): identity → served path.
|
|
681
|
+
* `get_file_name` is the bundler's `this.getFileName`.
|
|
682
|
+
*/
|
|
683
|
+
entry_locations(get_file_name) {
|
|
684
|
+
const islands = /* @__PURE__ */ new Map();
|
|
685
|
+
const locations = {};
|
|
686
|
+
const served = (file) => file.startsWith("/") ? file : "/" + file;
|
|
687
|
+
for (const [rid, ref] of this.island_entry_refs) {
|
|
688
|
+
const file = get_file_name(ref);
|
|
689
|
+
const identity = this.island_public_url(rid);
|
|
690
|
+
islands.set(file, identity);
|
|
691
|
+
locations[identity] = served(file);
|
|
692
|
+
}
|
|
693
|
+
let runtime = null;
|
|
694
|
+
let runtime_file = null;
|
|
695
|
+
if (this.runtime_entry_ref) {
|
|
696
|
+
runtime_file = get_file_name(this.runtime_entry_ref);
|
|
697
|
+
runtime = this.runtime_chunk_url();
|
|
698
|
+
locations[runtime] = served(runtime_file);
|
|
699
|
+
}
|
|
700
|
+
return {
|
|
701
|
+
islands,
|
|
702
|
+
runtime,
|
|
703
|
+
runtime_file,
|
|
704
|
+
locations
|
|
705
|
+
};
|
|
706
|
+
}
|
|
707
|
+
/** One hydrate island's entry, content-hashed by the bundler (its stable-name shim is written at
|
|
708
|
+
* the bundle's end: `entry_shims`). */
|
|
709
|
+
emit_island_entry(emitFile, rid, virtualPath) {
|
|
710
|
+
this.program.emitted_island_chunks.add(rid);
|
|
711
|
+
this.island_entry_refs.set(rid, emitFile({
|
|
712
|
+
type: "chunk",
|
|
713
|
+
id: virtualPath,
|
|
714
|
+
name: ISLAND_ENTRY_NAME_PREFIX + rid
|
|
715
|
+
}));
|
|
716
|
+
}
|
|
717
|
+
/**
|
|
718
|
+
* The output file pattern for one of OUR entries (by the chunk name `emit_island_entry` / the
|
|
719
|
+
* runtime emit gave it), else null (the app's own naming applies). Readable and content-hashed:
|
|
720
|
+
* `<appDir>/immutable/og-region.<iid>.<hash>.js`, `…/og-runtime-<features>.<hash>.js` — the hash is the
|
|
721
|
+
* cache law, the name is for people (a network tab, a CDN rule, a profile). It never equals a
|
|
722
|
+
* stable name, which has no hash segment.
|
|
723
|
+
*/
|
|
724
|
+
entry_file_pattern(chunk_name) {
|
|
725
|
+
if (!chunk_name) return null;
|
|
726
|
+
if (!(chunk_name.startsWith(ISLAND_ENTRY_NAME_PREFIX) || chunk_name === RUNTIME_ENTRY_NAME || chunk_name.startsWith("og-runtime-"))) return null;
|
|
727
|
+
return `${this.#ctx.app_dir}/immutable/[name].[hash].js`;
|
|
728
|
+
}
|
|
729
|
+
/**
|
|
730
|
+
* The stable-name shims (link/entry-shim.ts), for the bundle's end (the names are final): one per
|
|
731
|
+
* island entry, plus the runtime's — each a plain file at the old stable name re-exporting the
|
|
732
|
+
* hashed file. `get_file_name` is the bundler's `this.getFileName`.
|
|
733
|
+
*/
|
|
734
|
+
entry_shims(get_file_name) {
|
|
735
|
+
const ctx = this.#ctx;
|
|
736
|
+
const out = [];
|
|
737
|
+
for (const [rid, ref] of this.island_entry_refs) {
|
|
738
|
+
const fileName = ctx.island_chunk_filename(rid);
|
|
739
|
+
out.push({
|
|
740
|
+
fileName,
|
|
741
|
+
source: island_shim_source(fileName, get_file_name(ref))
|
|
742
|
+
});
|
|
743
|
+
}
|
|
744
|
+
if (this.runtime_entry_ref) {
|
|
745
|
+
const fileName = this.runtime_chunk_filename();
|
|
746
|
+
out.push({
|
|
747
|
+
fileName,
|
|
748
|
+
source: runtime_shim_source(fileName, get_file_name(this.runtime_entry_ref))
|
|
749
|
+
});
|
|
750
|
+
}
|
|
751
|
+
return out;
|
|
752
|
+
}
|
|
753
|
+
/**
|
|
754
|
+
* Emit one ogygia VIRTUAL module's source: the config/capability virtuals (secret / sign / rate-limit
|
|
755
|
+
* / router / session / ttl / manifests / runtime entry+url / transport / dev-hmr / request-event /
|
|
756
|
+
* region-endpoint), and the registered island/region sources (with the client leg's `$app/*`-shim +
|
|
757
|
+
* lake-placeholder rewrites). Returns the source string, or `null` if `id` is not an ogygia virtual —
|
|
758
|
+
* the adapter owns only the FOUC-css virtuals (they carry a Vite `moduleType`) and the Vite build
|
|
759
|
+
* value threaded in here (the `universalHooks` path).
|
|
760
|
+
*/
|
|
761
|
+
emit(id, { ssr, universalHooks, resolve, kitCodec = null }) {
|
|
762
|
+
const ctx = this.#ctx;
|
|
763
|
+
const program = this.program;
|
|
764
|
+
const is_dev = ctx.is_dev;
|
|
765
|
+
if (is_registry_stub_id(id)) return registry_stub_source(registry_stub_names(id));
|
|
766
|
+
const registry_client = registry_client_path(id);
|
|
767
|
+
if (registry_client) return this.#registry_client_emit(registry_client);
|
|
768
|
+
if (id === RESOLVED("virtual:ogygia/runtime-url")) {
|
|
769
|
+
if (!is_dev) this.prescan();
|
|
770
|
+
const url = is_dev ? "/@id/__x00__" + V_RUNTIME : this.runtime_chunk_url();
|
|
771
|
+
return `export default ${JSON.stringify(url)};`;
|
|
772
|
+
}
|
|
773
|
+
if (id === RESOLVED("virtual:ogygia/fn-manifest")) {
|
|
774
|
+
const regs = () => [...this.dollar_hoists.entries()].map(([tag, src]) => `globalThis.__og_reg_fn(${JSON.stringify(tag)}, (${src}));`).join("\n");
|
|
775
|
+
const bridge = `import { __register_fn } from 'ogygia/internal';\nglobalThis.__og_reg_fn = __register_fn;\n`;
|
|
776
|
+
if (is_dev) return bridge + regs();
|
|
777
|
+
return bridge + `/*__OGYGIA_FN_MANIFEST__*/`;
|
|
778
|
+
}
|
|
779
|
+
if (id === RESOLVED("virtual:ogygia/runtime-entry")) {
|
|
780
|
+
this.prescan();
|
|
781
|
+
const { code } = generateRuntimeEntrySource(program.runtime_marks, ctx.runtime_dir, ctx.client_plugins);
|
|
782
|
+
const ch = client_hooks_boot(ctx);
|
|
783
|
+
return ch.imports + code + ch.call;
|
|
784
|
+
}
|
|
785
|
+
if (id === RESOLVED("virtual:ogygia/hydrate-features")) {
|
|
786
|
+
if (!ctx.is_build) {
|
|
787
|
+
const rt = dev_runtime_of(ctx.runtime_dir);
|
|
788
|
+
const code = generateHydrateFeaturesSource({}, rt?.dir ?? ctx.runtime_dir, true).code;
|
|
789
|
+
return rt?.ts ? code.split(".js\";").join(".ts\";") : code;
|
|
790
|
+
}
|
|
791
|
+
this.prescan();
|
|
792
|
+
return `import ${JSON.stringify(V_FN_MANIFEST)};\n` + generateHydrateFeaturesSource(program.runtime_marks, ctx.runtime_dir).code;
|
|
793
|
+
}
|
|
794
|
+
if (id === RESOLVED("virtual:ogygia-runtime")) {
|
|
795
|
+
const ch = client_hooks_boot(ctx);
|
|
796
|
+
const cp = client_plugins_boot(ctx);
|
|
797
|
+
return `import { bootDev } from 'ogygia/runtime';\n${ch.imports}${cp.imports}bootDev(${cp.list});\n${ch.call}`;
|
|
798
|
+
}
|
|
799
|
+
if (id === RESOLVED("virtual:ogygia/dev-hmr")) {
|
|
800
|
+
if (!is_dev) return `export {}`;
|
|
801
|
+
return dev_hmr_client_source();
|
|
802
|
+
}
|
|
803
|
+
if (id === RESOLVED("virtual:ogygia/dev-hmr-url")) {
|
|
804
|
+
if (!is_dev) return `export default '';`;
|
|
805
|
+
return `export default ${JSON.stringify("/@id/__x00__" + V_DEV_HMR)};`;
|
|
806
|
+
}
|
|
807
|
+
if (id === RESOLVED("virtual:ogygia/devtools-boot")) {
|
|
808
|
+
if (!ctx.client_plugins.length) return `export {}`;
|
|
809
|
+
const cp = client_plugins_boot(ctx);
|
|
810
|
+
return (is_dev ? `import '/@vite/env';\n` : "") + cp.imports + `import { boot_client_plugins } from ${JSON.stringify(`${ctx.runtime_dir}/client-plugins.js`.replace(BACKSLASH_G, "/"))};\nimport { beacon_watch } from ${JSON.stringify(`${ctx.runtime_dir}/beacon.js`.replace(BACKSLASH_G, "/"))};\nbeacon_watch();\nboot_client_plugins(${cp.list}, true);\n`;
|
|
811
|
+
}
|
|
812
|
+
if (id === RESOLVED("virtual:ogygia/devtools-meta")) {
|
|
813
|
+
if (is_dev) return `export const names = {};`;
|
|
814
|
+
this.prescan();
|
|
815
|
+
return `export const names = ${JSON.stringify(this.region_names())};`;
|
|
816
|
+
}
|
|
817
|
+
if (id === RESOLVED("virtual:ogygia/devtools-boot-url")) {
|
|
818
|
+
if (!ctx.client_plugins.length || !is_dev) return `export default '';`;
|
|
819
|
+
return `export default ${JSON.stringify("/@id/__x00__" + V_DEVTOOLS_BOOT)};`;
|
|
820
|
+
}
|
|
821
|
+
if (id === RESOLVED("virtual:ogygia/island-deps")) return island_deps_module(ssr, is_dev, path.relative(ctx.root, kit_dirs(ctx.root).out_dir));
|
|
822
|
+
if (id === RESOLVED("virtual:ogygia/transport")) return transport_module(universalHooks, ssr ? null : kitCodec);
|
|
823
|
+
if (id === RESOLVED("virtual:ogygia/kit-transport")) {
|
|
824
|
+
const crosses = this.program.runtime_marks.wire === true || this.program.crosses_wire;
|
|
825
|
+
const transport_spec = `${ctx.runtime_dir}/../transport.js`.replace(BACKSLASH_G, "/");
|
|
826
|
+
return kit_transport_module(crosses, transport_spec);
|
|
827
|
+
}
|
|
828
|
+
if (id === RESOLVED("virtual:ogygia/router-css")) return router_css_module(this.router_css_roots(), {
|
|
829
|
+
root: ctx.root,
|
|
830
|
+
lib_dir: ctx.libDir,
|
|
831
|
+
is_dev,
|
|
832
|
+
read_file: (p) => ctx.read_file(p),
|
|
833
|
+
resolve
|
|
834
|
+
});
|
|
835
|
+
if (id === RESOLVED("virtual:ogygia/secret")) return secret_module(ssr, ctx.build_secret, ctx.id_salt !== "");
|
|
836
|
+
if (id === RESOLVED("virtual:ogygia/sign")) return sign_module(ssr, ctx.hmac_module);
|
|
837
|
+
if (id === RESOLVED("virtual:ogygia/request-event")) {
|
|
838
|
+
if (!ssr) return `export function getRequestEvent() { throw new Error('[ogygia] getRequestEvent is server-only'); }`;
|
|
839
|
+
return `export { getRequestEvent } from '$app/server';`;
|
|
840
|
+
}
|
|
841
|
+
if (id === RESOLVED("virtual:ogygia/region-endpoint")) {
|
|
842
|
+
if (!ssr) return "export function makeRegionEndpoint(_entry, _props) { return ''; }\nexport function mintServerIsland(_entry, _props, _ttl) { return ''; }\nexport function known_region_fps() { return new Set(); }\nexport function islandFingerprint(_entry, _canonical) { return ''; }\nexport function holeCss(_entry) { return []; }";
|
|
843
|
+
return `export { makeRegionEndpoint, mintServerIsland, known_region_fps, islandFingerprint, holeCss } from ${JSON.stringify(ctx.region_endpoint_module)};`;
|
|
844
|
+
}
|
|
845
|
+
if (id === RESOLVED("virtual:ogygia/rate-limit")) return rate_limit_module(ssr, ctx.rate_limit);
|
|
846
|
+
if (id === RESOLVED("virtual:ogygia/server-plugins")) return server_plugins_module(ssr, ctx.server_plugins);
|
|
847
|
+
if (id === RESOLVED("virtual:ogygia/profiler-maps")) return ssr && ctx.is_build && ctx.measure ? `export default ${JSON.stringify(PROFILER_MAPS_PLACEHOLDER)};` : "export default null;";
|
|
848
|
+
if (id === RESOLVED("virtual:ogygia/router-config")) return router_config_module(ctx.router_enabled, ctx.router_view_transitions);
|
|
849
|
+
if (id === RESOLVED("virtual:ogygia/session-cookie")) return session_cookie_module(ssr, ctx.session_cookie);
|
|
850
|
+
if (id === RESOLVED("virtual:ogygia/region-ttl")) return region_ttl_module(ssr, ctx.region_ttl, ctx.renew_window);
|
|
851
|
+
if (id === RESOLVED("virtual:ogygia/route-csr")) return route_csr_module(ssr, kit_dirs(ctx.root).routes_dir);
|
|
852
|
+
if (id === RESOLVED("virtual:ogygia/route-config")) return route_config_module(ssr, kit_dirs(ctx.root).routes_dir, ctx.route_config);
|
|
853
|
+
if (id === RESOLVED("virtual:ogygia/server-manifest")) {
|
|
854
|
+
if (ssr) this.prescan();
|
|
855
|
+
if (ssr && is_dev) this.#emitted_server_ids = new Set(server_island_ids(program));
|
|
856
|
+
return server_manifest_module(ssr, program, is_dev, (vp) => ctx.dev_url_for(vp), (iid) => ctx.island_public_url(iid));
|
|
857
|
+
}
|
|
858
|
+
if (id === RESOLVED("virtual:ogygia/server-islands")) {
|
|
859
|
+
if (ssr) this.prescan();
|
|
860
|
+
return server_islands_module(ssr, program);
|
|
861
|
+
}
|
|
862
|
+
if (id === RESOLVED("virtual:ogygia/manifest")) return manifest_module(is_dev);
|
|
863
|
+
if (id === RESOLVED("virtual:ogygia/transportables-eager")) {
|
|
864
|
+
if (!ssr) return "export {};\n";
|
|
865
|
+
this.prescan();
|
|
866
|
+
return transportables_module(program.transportable_modules, true, (abs) => abs);
|
|
867
|
+
}
|
|
868
|
+
if (id === RESOLVED("virtual:ogygia/transportables")) {
|
|
869
|
+
this.prescan();
|
|
870
|
+
return transportables_module(program.transportable_modules, !!ssr, (abs) => path.relative(ctx.root, abs).split(path.sep).join("/"), program.crosses_wire);
|
|
871
|
+
}
|
|
872
|
+
const srcEntry = program.registry.get(id);
|
|
873
|
+
if (srcEntry && srcEntry.role === "region") return ssr ? srcEntry.ssrSource : srcEntry.clientSource;
|
|
874
|
+
if (srcEntry) {
|
|
875
|
+
let src = !ssr && srcEntry.clientSource ? srcEntry.clientSource : srcEntry.source;
|
|
876
|
+
const foreign = src.indexOf(FOREIGN_HYDRATE_MARK);
|
|
877
|
+
if (foreign !== -1 && (ssr || !ctx.foreign_hydrate)) src = src.slice(0, foreign);
|
|
878
|
+
if (!ssr) {
|
|
879
|
+
src = src.replace(APP_SHIM_IMPORT, (_m, _q, name) => JSON.stringify(ctx.app_shims["$app/" + name]));
|
|
880
|
+
for (const local of srcEntry.lakes ?? []) src = rewrite_lake_import_to_placeholder(src, local, ctx.client_binding_stub_file);
|
|
881
|
+
}
|
|
882
|
+
return src;
|
|
883
|
+
}
|
|
884
|
+
return null;
|
|
885
|
+
}
|
|
886
|
+
/**
|
|
887
|
+
* Resolve an ogygia-owned import id: the virtual-module vocabulary (config/manifest virtuals + FOUC
|
|
888
|
+
* graph + client-binding stub), and the island CLIENT graph — `$app/*` shims for island importers,
|
|
889
|
+
* virtual island/wrapper ids, and relative imports of a generated island module resolved against its
|
|
890
|
+
* host (marking each resolved dep into `island_graph` so its own `$app/*` stays shimmed). `resolve` is
|
|
891
|
+
* the bundler's own resolver (Vite `this.resolve`), threaded in so the driver stays bundler-agnostic.
|
|
892
|
+
* Returns a resolved id / result, or `null` to defer to the bundler. The adapter handles the few
|
|
893
|
+
* package/Kit-specific ids first (ogygia injected imports, Kit's remote runtime, the kit-wire path).
|
|
894
|
+
*/
|
|
895
|
+
async resolve_id(source, importer, { ssr, resolve }) {
|
|
896
|
+
const ctx = this.#ctx;
|
|
897
|
+
const { registry, island_graph } = this.program;
|
|
898
|
+
if (source === "virtual:ogygia/fn-manifest") return RESOLVED(V_FN_MANIFEST);
|
|
899
|
+
if (source === "virtual:ogygia/runtime-url") return RESOLVED(V_RUNTIME_URL);
|
|
900
|
+
if (source === "virtual:ogygia/manifest") return RESOLVED(V_MANIFEST);
|
|
901
|
+
if (source === "virtual:ogygia-runtime") return RESOLVED(V_RUNTIME);
|
|
902
|
+
if (source === "virtual:ogygia/runtime-entry") return RESOLVED(V_RUNTIME_ENTRY);
|
|
903
|
+
if (source === "virtual:ogygia/hydrate-features") return RESOLVED(V_HYDRATE_FEATURES);
|
|
904
|
+
if (source === "virtual:ogygia/dev-hmr") return RESOLVED(V_DEV_HMR);
|
|
905
|
+
if (source === "virtual:ogygia/dev-hmr-url") return RESOLVED(V_DEV_HMR_URL);
|
|
906
|
+
if (source === "virtual:ogygia/devtools-boot") return RESOLVED(V_DEVTOOLS_BOOT);
|
|
907
|
+
if (source === "virtual:ogygia/devtools-boot-url") return RESOLVED(V_DEVTOOLS_BOOT_URL);
|
|
908
|
+
if (source === "virtual:ogygia/devtools-meta") return RESOLVED(V_DEVTOOLS_META);
|
|
909
|
+
if (source === "virtual:ogygia/island-deps") return RESOLVED(V_ISLAND_DEPS);
|
|
910
|
+
if (source === "virtual:ogygia/kit-transport") return RESOLVED(V_KIT_TRANSPORT);
|
|
911
|
+
if (source === "virtual:ogygia/router-css") return RESOLVED(V_ROUTER_CSS);
|
|
912
|
+
if (source === "virtual:ogygia/secret") return RESOLVED(V_SECRET);
|
|
913
|
+
if (source === "virtual:ogygia/sign") return RESOLVED(V_SIGN);
|
|
914
|
+
if (source === "virtual:ogygia/rate-limit") return RESOLVED(V_RATE_LIMIT);
|
|
915
|
+
if (source === "virtual:ogygia/server-plugins") return RESOLVED(V_SERVER_PLUGINS);
|
|
916
|
+
if (source === "virtual:ogygia/profiler-maps") return RESOLVED(V_PROFILER_MAPS);
|
|
917
|
+
if (source === "virtual:ogygia/router-config") return RESOLVED(V_ROUTER_CONFIG);
|
|
918
|
+
if (source === "virtual:ogygia/session-cookie") return RESOLVED(V_SESSION_COOKIE);
|
|
919
|
+
if (source === "virtual:ogygia/region-ttl") return RESOLVED(V_REGION_TTL);
|
|
920
|
+
if (source === "virtual:ogygia/route-csr") return RESOLVED(V_ROUTE_CSR);
|
|
921
|
+
if (source === "virtual:ogygia/route-config") return RESOLVED(V_ROUTE_CONFIG);
|
|
922
|
+
if (source === "virtual:ogygia/server-manifest") return RESOLVED(V_SERVER_MANIFEST);
|
|
923
|
+
if (source === "virtual:ogygia/server-islands") return RESOLVED(V_SERVER_ISLANDS);
|
|
924
|
+
if (source === "virtual:ogygia/request-event") return RESOLVED(V_REQUEST_EVENT);
|
|
925
|
+
if (source === "virtual:ogygia/region-endpoint") return RESOLVED(V_REGION_ENDPOINT);
|
|
926
|
+
if (source === "virtual:ogygia/client-binding-stub") return ctx.client_binding_stub_file;
|
|
927
|
+
if (source.startsWith("virtual:ogygia/fouc-css/") || source.startsWith("virtual:ogygia/fouc-scoped/")) return RESOLVED(source);
|
|
928
|
+
if (source === "virtual:ogygia/transport") return RESOLVED(V_TRANSPORT);
|
|
929
|
+
if (source === "virtual:ogygia/transportables") return RESOLVED(V_TRANSPORTABLES);
|
|
930
|
+
if (source === "virtual:ogygia/transportables-eager") return RESOLVED(V_TRANSPORTABLES_EAGER);
|
|
931
|
+
if (is_registry_stub_id(source)) return RESOLVED(source);
|
|
932
|
+
const registry_stub = await this.#registry_stub_for(source, importer, {
|
|
933
|
+
ssr,
|
|
934
|
+
resolve
|
|
935
|
+
});
|
|
936
|
+
if (registry_stub) return registry_stub;
|
|
937
|
+
const importer_id = importer ? strip_id(importer) : void 0;
|
|
938
|
+
const from_island = importer_id && (registry.has(importer_id) || island_graph.has(importer_id));
|
|
939
|
+
if (!ssr && from_island) {
|
|
940
|
+
const shim = app_shim_for(source, ctx.app_shims);
|
|
941
|
+
if (shim) return shim;
|
|
942
|
+
}
|
|
943
|
+
if (is_island_path(source)) {
|
|
944
|
+
let candidate = source.split("?")[0];
|
|
945
|
+
if (candidate.startsWith("/@id/")) candidate = candidate.slice(5);
|
|
946
|
+
if (candidate.startsWith("/@fs/")) candidate = candidate.slice(4);
|
|
947
|
+
if (registry.has(candidate)) {
|
|
948
|
+
island_graph.add(candidate);
|
|
949
|
+
return candidate;
|
|
950
|
+
}
|
|
951
|
+
const abs = path.isAbsolute(candidate) ? candidate : path.join(ctx.root, candidate.replace(LEADING_SLASH, ""));
|
|
952
|
+
if (registry.has(abs)) {
|
|
953
|
+
island_graph.add(abs);
|
|
954
|
+
return abs;
|
|
955
|
+
}
|
|
956
|
+
}
|
|
957
|
+
if (importer_id && registry.has(importer_id) && !is_island_path(source)) {
|
|
958
|
+
const host = registry.get(importer_id).hostPath ?? "";
|
|
959
|
+
const resolved = await resolve(source, host, { skipSelf: true });
|
|
960
|
+
if (resolved?.id) island_graph.add(strip_id(resolved.id));
|
|
961
|
+
if (!resolved && !source.startsWith(".") && !source.startsWith("\0") && !source.startsWith("virtual:") && !path.isAbsolute(source)) throw new Error(`[ogygia] cannot resolve '${source}' imported by the generated island module for ${path.relative(ctx.root, host)}. That island was marked on a package import, so the specifier must resolve from the host file: check the package is installed and its "exports" map exposes this subpath (with a "svelte" condition for .svelte components).`);
|
|
962
|
+
return resolved;
|
|
963
|
+
}
|
|
964
|
+
if (!ssr && importer_id && island_graph.has(importer_id) && !is_island_path(source)) {
|
|
965
|
+
const resolved = await resolve(source, importer, { skipSelf: true });
|
|
966
|
+
if (resolved?.id) island_graph.add(strip_id(resolved.id));
|
|
967
|
+
return resolved;
|
|
968
|
+
}
|
|
969
|
+
return null;
|
|
970
|
+
}
|
|
971
|
+
/**
|
|
972
|
+
* The client-leg registry decision for one import edge (see link/registry-stub.ts). Fires only on
|
|
973
|
+
* the client leg of a build, for an importer that is either a csr=false ROUTE host (`+page`/
|
|
974
|
+
* `+layout` `.svelte`/`.ts`/`.js` — the page node's own files, whose client JS never runs) or a
|
|
975
|
+
* module already in that variant world (its id carries the variant query), and only when the
|
|
976
|
+
* resolved target is a local `.ts`/`.js` module that IS a region registry or REACHES one through
|
|
977
|
+
* static script imports. The variant world is contagious along script edges only: a registry
|
|
978
|
+
* behind a plain helper (`+page.svelte` → `$lib/factory.ts` → `registry.ts`) gets the same
|
|
979
|
+
* treatment as a direct import, while modules that reach no registry stay shared (no copies).
|
|
980
|
+
* `.svelte` edges never fork (forking a component's id breaks its scoped CSS). Returns the
|
|
981
|
+
* variant id, or `null` to let resolution continue.
|
|
982
|
+
*/
|
|
983
|
+
async #registry_stub_for(source, importer, { ssr, resolve }) {
|
|
984
|
+
const ctx = this.#ctx;
|
|
985
|
+
if (ssr || ctx.is_dev || !ctx.is_build || !importer) return null;
|
|
986
|
+
if (source.startsWith("\0") || source.startsWith("virtual:") || source.startsWith("$app/")) return null;
|
|
987
|
+
if (registry_client_path(importer) == null && !this.#is_csr_false_route_host(importer)) return null;
|
|
988
|
+
const target = await this.#resolve_local_script(source, importer, resolve);
|
|
989
|
+
if (!target) return null;
|
|
990
|
+
this.prescan();
|
|
991
|
+
if (!await this.#reaches_registry(target, resolve)) return null;
|
|
992
|
+
return registry_client_id(target);
|
|
993
|
+
}
|
|
994
|
+
/** True for a csr=false route host file (`+page`/`+layout` `.svelte`/`.ts`/`.js`). A `+page.ts`
|
|
995
|
+
* shares its route's world with the sibling `.svelte` host. */
|
|
996
|
+
#is_csr_false_route_host(importer) {
|
|
997
|
+
const importer_abs = strip_id(importer);
|
|
998
|
+
const routes_dir = kit_dirs(this.#ctx.root).routes_dir;
|
|
999
|
+
if (!importer_abs.startsWith(routes_dir + path.sep)) return false;
|
|
1000
|
+
const m = ROUTE_HOST_FILE_RE.exec(path.basename(importer_abs));
|
|
1001
|
+
if (!m) return false;
|
|
1002
|
+
return routeCsrIsFalse(path.join(importer_abs, "..", `+${m[1]}.svelte`), routes_dir);
|
|
1003
|
+
}
|
|
1004
|
+
/** `source` resolved from `importer` to a local `.ts`/`.js` file on disk, or `null` (virtuals,
|
|
1005
|
+
* components, assets, unresolvable). Package files count only when the prescan registered them
|
|
1006
|
+
* as region hosts (an `ogygia.files` package registry) — package internals are never walked. */
|
|
1007
|
+
async #resolve_local_script(source, importer, resolve) {
|
|
1008
|
+
const memo_key = strip_id(importer) + "\n" + source;
|
|
1009
|
+
const memo = this.#resolve_memo.get(memo_key);
|
|
1010
|
+
if (memo !== void 0) return memo;
|
|
1011
|
+
const target = await this.#resolve_local_script_uncached(source, importer, resolve);
|
|
1012
|
+
this.#resolve_memo.set(memo_key, target);
|
|
1013
|
+
return target;
|
|
1014
|
+
}
|
|
1015
|
+
#resolve_memo = /* @__PURE__ */ new Map();
|
|
1016
|
+
async #resolve_local_script_uncached(source, importer, resolve) {
|
|
1017
|
+
let resolved = null;
|
|
1018
|
+
try {
|
|
1019
|
+
resolved = await resolve(source, importer, { skipSelf: true });
|
|
1020
|
+
} catch {
|
|
1021
|
+
return null;
|
|
1022
|
+
}
|
|
1023
|
+
if (!resolved?.id || resolved.id.startsWith("\0")) return null;
|
|
1024
|
+
const target = strip_id(resolved.id);
|
|
1025
|
+
if (!TS_REGISTRY_EXT_RE.test(target) || !fs.existsSync(target)) return null;
|
|
1026
|
+
const posix = target.split(path.sep).join("/");
|
|
1027
|
+
if (SERVER_MODULE_EXT_RE.test(posix) || SERVER_DIR_RE.test(posix)) return null;
|
|
1028
|
+
if (SVELTE_RUNE_MODULE_RE.test(posix)) return null;
|
|
1029
|
+
return target;
|
|
1030
|
+
}
|
|
1031
|
+
/**
|
|
1032
|
+
* Whether `file` is a region registry or reaches one through static script imports (`.svelte`
|
|
1033
|
+
* and package-internal edges are not walked). Every module is read, parsed and walked AT MOST
|
|
1034
|
+
* ONCE per build: a shared helper reached from thousands of import edges answers from the memo.
|
|
1035
|
+
*
|
|
1036
|
+
* Cycles are why that needs care. A NEGATIVE computed while the walk was inside a cycle may
|
|
1037
|
+
* depend on a file still open above it (that file can still turn out to reach a registry), so it
|
|
1038
|
+
* is not final yet. Tarjan's strongly-connected-components bookkeeping decides exactly when it
|
|
1039
|
+
* is: each open file gets its depth on the walk, every step reports the shallowest open file its
|
|
1040
|
+
* subtree looped back to (`low`), and when a file finishes with `low >= depth` nothing below it
|
|
1041
|
+
* depends on anything above it — the file and every file still parked on the component stack
|
|
1042
|
+
* above it form one finished component, all with the same answer. A positive is always final.
|
|
1043
|
+
* (Keeping only top-level negatives instead, as this did first, re-walked every shared module
|
|
1044
|
+
* once per path to it — a large app's build never finished.)
|
|
1045
|
+
*/
|
|
1046
|
+
async #reaches_registry(file, resolve) {
|
|
1047
|
+
return (await this.#reach(file, resolve, /* @__PURE__ */ new Map(), [])).reaches;
|
|
1048
|
+
}
|
|
1049
|
+
#reach_memo = /* @__PURE__ */ new Map();
|
|
1050
|
+
#specs_memo = /* @__PURE__ */ new Map();
|
|
1051
|
+
async #reach(file, resolve, open, component) {
|
|
1052
|
+
const key = host_key(file);
|
|
1053
|
+
const memo = this.#reach_memo.get(key);
|
|
1054
|
+
if (memo !== void 0) return {
|
|
1055
|
+
reaches: memo,
|
|
1056
|
+
low: Infinity
|
|
1057
|
+
};
|
|
1058
|
+
if (this.program.host_index.has(key)) {
|
|
1059
|
+
this.#reach_memo.set(key, true);
|
|
1060
|
+
return {
|
|
1061
|
+
reaches: true,
|
|
1062
|
+
low: Infinity
|
|
1063
|
+
};
|
|
1064
|
+
}
|
|
1065
|
+
const open_depth = open.get(key);
|
|
1066
|
+
if (open_depth !== void 0) return {
|
|
1067
|
+
reaches: false,
|
|
1068
|
+
low: open_depth
|
|
1069
|
+
};
|
|
1070
|
+
if (file.includes("/node_modules/")) return {
|
|
1071
|
+
reaches: false,
|
|
1072
|
+
low: Infinity
|
|
1073
|
+
};
|
|
1074
|
+
const depth = open.size;
|
|
1075
|
+
open.set(key, depth);
|
|
1076
|
+
const parked = component.length;
|
|
1077
|
+
component.push(key);
|
|
1078
|
+
let reaches = false;
|
|
1079
|
+
let low = Infinity;
|
|
1080
|
+
for (const spec of this.#script_specs(key, file)) {
|
|
1081
|
+
const target = await this.#resolve_local_script(spec, file, resolve);
|
|
1082
|
+
if (!target) continue;
|
|
1083
|
+
const step = await this.#reach(target, resolve, open, component);
|
|
1084
|
+
if (step.low < low) low = step.low;
|
|
1085
|
+
if (step.reaches) {
|
|
1086
|
+
reaches = true;
|
|
1087
|
+
break;
|
|
1088
|
+
}
|
|
1089
|
+
}
|
|
1090
|
+
open.delete(key);
|
|
1091
|
+
if (reaches) {
|
|
1092
|
+
this.#reach_memo.set(key, true);
|
|
1093
|
+
component.length = parked + 1;
|
|
1094
|
+
component.pop();
|
|
1095
|
+
return {
|
|
1096
|
+
reaches: true,
|
|
1097
|
+
low: Infinity
|
|
1098
|
+
};
|
|
1099
|
+
}
|
|
1100
|
+
if (low >= depth) {
|
|
1101
|
+
for (let i = parked; i < component.length; i++) this.#reach_memo.set(component[i], false);
|
|
1102
|
+
component.length = parked;
|
|
1103
|
+
return {
|
|
1104
|
+
reaches: false,
|
|
1105
|
+
low: Infinity
|
|
1106
|
+
};
|
|
1107
|
+
}
|
|
1108
|
+
return {
|
|
1109
|
+
reaches: false,
|
|
1110
|
+
low
|
|
1111
|
+
};
|
|
1112
|
+
}
|
|
1113
|
+
/** A module's static script specifiers, read and parsed once per build. */
|
|
1114
|
+
#script_specs(key, file) {
|
|
1115
|
+
let specs = this.#specs_memo.get(key);
|
|
1116
|
+
if (specs === void 0) {
|
|
1117
|
+
const src = this.#ctx.read_file(file);
|
|
1118
|
+
specs = src == null ? [] : static_script_specs(src, file) ?? [];
|
|
1119
|
+
this.#specs_memo.set(key, specs);
|
|
1120
|
+
}
|
|
1121
|
+
return specs;
|
|
1122
|
+
}
|
|
1123
|
+
/** The client-leg registry source (link/registry-stub.ts): marks blanked, plain imports kept. A
|
|
1124
|
+
* registry that does not parse falls back to the names-only stub. */
|
|
1125
|
+
#registry_client_emit(file) {
|
|
1126
|
+
const ctx = this.#ctx;
|
|
1127
|
+
const src = ctx.read_file(file);
|
|
1128
|
+
if (src == null) return null;
|
|
1129
|
+
const keys = ctx.import_keys;
|
|
1130
|
+
const region_keys = /* @__PURE__ */ new Set([
|
|
1131
|
+
keys.wake,
|
|
1132
|
+
keys.render,
|
|
1133
|
+
keys.preset,
|
|
1134
|
+
keys.region
|
|
1135
|
+
]);
|
|
1136
|
+
return registry_client_source(src, file, region_keys) ?? registry_stub_source([...export_names(src)]);
|
|
1137
|
+
}
|
|
1138
|
+
/**
|
|
1139
|
+
* The per-file transform pass: content-preset tagging ▸ `import.meta.og.*` macros ▸ the host-island
|
|
1140
|
+
* transform (`.svelte`) ▸ ts/js region minting (`.ts/.js`) ▸ the client `$app/*` shim. Registers the
|
|
1141
|
+
* discovered descriptors into the `Program`, and (client build only) emits the deterministic chunk for
|
|
1142
|
+
* any hydrate island a library component declares that the prescan couldn't see — via the `emitFile`
|
|
1143
|
+
* callback (the one Vite primitive threaded in). Returns the Vite transform result, or `null` if the
|
|
1144
|
+
* module was untouched. `prescan()` runs first so `island_graph` is complete before any module lowers.
|
|
1145
|
+
*/
|
|
1146
|
+
async transform_module(code, id, { ssr, emitFile }) {
|
|
1147
|
+
const ctx = this.#ctx;
|
|
1148
|
+
const program = this.program;
|
|
1149
|
+
const { registry, island_graph, emitted_island_chunks } = program;
|
|
1150
|
+
const root = ctx.root;
|
|
1151
|
+
code = strip_bom(code);
|
|
1152
|
+
this.prescan();
|
|
1153
|
+
if (registry_client_path(id) != null) return null;
|
|
1154
|
+
const id_n = strip_id(id);
|
|
1155
|
+
if (ssr && ctx.is_build) program.ssr_transformed.add(host_key(id_n));
|
|
1156
|
+
if (ctx.is_build && mentions_page_store(code)) {
|
|
1157
|
+
const clean = id.split("?")[0].split("\\").join("/");
|
|
1158
|
+
const kind = clean.endsWith(".svelte") ? "svelte" : SCRIPT_MODULE_RE.test(clean) ? "script" : null;
|
|
1159
|
+
if (kind) {
|
|
1160
|
+
const { keys, reason, pending } = page_data_keys_answer(code, clean, kind);
|
|
1161
|
+
if (keys !== null) program.page_keys.set(clean, keys);
|
|
1162
|
+
if (reason) program.page_key_reasons.set(clean, reason);
|
|
1163
|
+
if (pending.length) program.page_pending.set(clean, pending);
|
|
1164
|
+
else program.page_pending.delete(clean);
|
|
1165
|
+
}
|
|
1166
|
+
}
|
|
1167
|
+
let out = code;
|
|
1168
|
+
let map = null;
|
|
1169
|
+
let touched = false;
|
|
1170
|
+
const macroed = await this.macros(out, id_n);
|
|
1171
|
+
if (macroed.touched) {
|
|
1172
|
+
out = macroed.code;
|
|
1173
|
+
map = null;
|
|
1174
|
+
touched = true;
|
|
1175
|
+
}
|
|
1176
|
+
const in_node_modules = id_n.includes("/node_modules/");
|
|
1177
|
+
const bare_v = id_n.startsWith("/@id/") ? id_n.slice(5) : id_n;
|
|
1178
|
+
const portable_entry = id_n.endsWith(".svelte") && is_island_path(bare_v) && registry.get(bare_v)?.portable === true;
|
|
1179
|
+
if (id_n.endsWith(".svelte") && is_script_request(id) && (!is_island_path(bare_v) || portable_entry) && (!in_node_modules || ctx.in_declared_pkg(bare_v) || ctx.has_island_hint(code))) {
|
|
1180
|
+
const result = this.transform(out, id_n, { ssr });
|
|
1181
|
+
if (result) {
|
|
1182
|
+
program.register(result, id_n);
|
|
1183
|
+
this.#mark_registered_closures(result);
|
|
1184
|
+
out = result.code;
|
|
1185
|
+
map = result.map;
|
|
1186
|
+
touched = true;
|
|
1187
|
+
if (ctx.is_build && !ssr) for (const isl of result.islands ?? []) {
|
|
1188
|
+
if ((isl.kind ?? (isl.server ? "defer" : "hydrate")) !== "hydrate" || !isl.virtualPath || emitted_island_chunks.has(isl.id)) continue;
|
|
1189
|
+
this.emit_island_entry(emitFile, isl.id, isl.virtualPath);
|
|
1190
|
+
}
|
|
1191
|
+
}
|
|
1192
|
+
if (!id_n.startsWith(ctx.pkg_root)) {
|
|
1193
|
+
const withReg = appendSvelteModuleRegistrations(out, id_n, root, path);
|
|
1194
|
+
if (withReg !== null) {
|
|
1195
|
+
out = withReg;
|
|
1196
|
+
map = null;
|
|
1197
|
+
touched = true;
|
|
1198
|
+
}
|
|
1199
|
+
}
|
|
1200
|
+
}
|
|
1201
|
+
const nm_ts = id_n.endsWith(".ts") || id_n.endsWith(".js") || id_n.endsWith(".mjs") ? id_n.includes("/node_modules/") : null;
|
|
1202
|
+
if (nm_ts === true && !id_n.startsWith(ctx.pkg_root) && !ctx.in_declared_pkg(id_n) && ctx.has_island_hint(out) && ctx.has_marked_import(out, id_n)) warn_undeclared_pkg_marks(id_n);
|
|
1203
|
+
if (nm_ts !== null && (nm_ts === false || ctx.in_declared_pkg(id_n)) && !is_island_path(id_n)) {
|
|
1204
|
+
const result = this.ts_regions(out, id_n);
|
|
1205
|
+
if (result) {
|
|
1206
|
+
program.register(result, id_n);
|
|
1207
|
+
this.#mark_registered_closures(result);
|
|
1208
|
+
out = result.code;
|
|
1209
|
+
map = result.map;
|
|
1210
|
+
touched = true;
|
|
1211
|
+
}
|
|
1212
|
+
if (!id_n.startsWith(ctx.pkg_root)) {
|
|
1213
|
+
const registered = appendTransportRegistrations(out, id_n, root, path);
|
|
1214
|
+
if (registered !== null) {
|
|
1215
|
+
out = registered;
|
|
1216
|
+
touched = true;
|
|
1217
|
+
}
|
|
1218
|
+
}
|
|
1219
|
+
}
|
|
1220
|
+
if (!ssr && island_graph.has(id_n) && (id_n.endsWith(".svelte") || SCRIPT_MODULE_RE.test(id_n))) {
|
|
1221
|
+
const rewritten = out.replace(APP_SHIM_IMPORT, (_m, _q, name) => JSON.stringify(ctx.app_shims["$app/" + name]));
|
|
1222
|
+
if (rewritten !== out) {
|
|
1223
|
+
out = rewritten;
|
|
1224
|
+
map = null;
|
|
1225
|
+
touched = true;
|
|
1226
|
+
}
|
|
1227
|
+
}
|
|
1228
|
+
if (ssr && !id.includes("?") && id_n.endsWith(".svelte") && !is_island_path(bare_v) && (!in_node_modules || ctx.in_declared_pkg(id_n))) {
|
|
1229
|
+
const stamped = stamp_opaque(out, id_n);
|
|
1230
|
+
if (stamped !== null) {
|
|
1231
|
+
out = stamped;
|
|
1232
|
+
map = null;
|
|
1233
|
+
touched = true;
|
|
1234
|
+
}
|
|
1235
|
+
}
|
|
1236
|
+
return touched ? {
|
|
1237
|
+
code: out,
|
|
1238
|
+
map
|
|
1239
|
+
} : null;
|
|
1240
|
+
}
|
|
1241
|
+
/**
|
|
1242
|
+
* Patch the fn-manifest placeholder in a finished chunk with the collected `og.$` factory
|
|
1243
|
+
* registrations — every transform has run by renderChunk, so `dollar_hoists` is complete. Registrations
|
|
1244
|
+
* go through the globalThis bridge the placeholder module installed (rename-proof under minification).
|
|
1245
|
+
* Returns the patched chunk, or `null` if this chunk carries no placeholder.
|
|
1246
|
+
*/
|
|
1247
|
+
patch_fn_manifest(code) {
|
|
1248
|
+
if (!code.includes("/*__OGYGIA_FN_MANIFEST__*/")) return null;
|
|
1249
|
+
const regs = [...this.dollar_hoists.entries()].map(([tag, src]) => `globalThis.__og_reg_fn(${JSON.stringify(tag)}, (${src}));`).join("\n");
|
|
1250
|
+
return {
|
|
1251
|
+
code: code.replace("/*__OGYGIA_FN_MANIFEST__*/", () => regs),
|
|
1252
|
+
map: null
|
|
1253
|
+
};
|
|
1254
|
+
}
|
|
1255
|
+
/**
|
|
1256
|
+
* Patch the server manifest's page-data placeholder: per server island (a hole), does its SERVER
|
|
1257
|
+
* tree — the component and everything it imports, statically or dynamically (a registry's blocks)
|
|
1258
|
+
* — read `page.data`? The transform recorded each module's reads (`page_keys`, seed shaping); by
|
|
1259
|
+
* renderChunk the graph is complete. A hole that never reads it never pays the page lookup
|
|
1260
|
+
* (server/render-page.ts). One walk per hole, sharing what earlier walks proved: a walk that ends
|
|
1261
|
+
* with no reader proves every module it visited reads nothing. `graph` is the bundler's module info.
|
|
1262
|
+
*/
|
|
1263
|
+
patch_page_data_reads(code, graph, module_ids) {
|
|
1264
|
+
const at = code.indexOf(PAGE_DATA_READS_TOKEN);
|
|
1265
|
+
if (at === -1) return null;
|
|
1266
|
+
const { page_keys, page_pending, by_id, registry } = this.program;
|
|
1267
|
+
const clean = (id) => id.split("?")[0].split("\\").join("/");
|
|
1268
|
+
const reads_itself = (id) => {
|
|
1269
|
+
const c = clean(id);
|
|
1270
|
+
const k = page_keys.get(c);
|
|
1271
|
+
return k !== void 0 && (k === "all" || k.size > 0) || page_pending.has(c);
|
|
1272
|
+
};
|
|
1273
|
+
const ids_by_path = /* @__PURE__ */ new Map();
|
|
1274
|
+
for (const id of module_ids()) if (!id.startsWith("\0")) ids_by_path.set(clean(id), id);
|
|
1275
|
+
const proven_clean = /* @__PURE__ */ new Set();
|
|
1276
|
+
const reads = (root) => {
|
|
1277
|
+
const seen = /* @__PURE__ */ new Set([root]);
|
|
1278
|
+
const queue = [root];
|
|
1279
|
+
for (let i = 0; i < queue.length; i++) {
|
|
1280
|
+
const id = queue[i];
|
|
1281
|
+
if (proven_clean.has(id)) continue;
|
|
1282
|
+
if (reads_itself(id)) return true;
|
|
1283
|
+
const info = graph(id);
|
|
1284
|
+
if (!info) continue;
|
|
1285
|
+
for (const next of info.importedIds) if (!seen.has(next)) {
|
|
1286
|
+
seen.add(next);
|
|
1287
|
+
queue.push(next);
|
|
1288
|
+
}
|
|
1289
|
+
for (const next of info.dynamicallyImportedIds) if (!seen.has(next)) {
|
|
1290
|
+
seen.add(next);
|
|
1291
|
+
queue.push(next);
|
|
1292
|
+
}
|
|
1293
|
+
}
|
|
1294
|
+
for (const id of seen) proven_clean.add(id);
|
|
1295
|
+
return false;
|
|
1296
|
+
};
|
|
1297
|
+
const out = {};
|
|
1298
|
+
for (const [iid, virtual_path] of by_id) {
|
|
1299
|
+
const reg = registry.get(virtual_path);
|
|
1300
|
+
if (!reg?.server) continue;
|
|
1301
|
+
const root = reg.componentPath ? ids_by_path.get(clean(reg.componentPath)) : void 0;
|
|
1302
|
+
out[iid] = root === void 0 ? true : reads(root);
|
|
1303
|
+
}
|
|
1304
|
+
const json = JSON.stringify(out);
|
|
1305
|
+
const literal = code[at - 1] === "\"" ? json.split("\"").join("\\\"") : json;
|
|
1306
|
+
return {
|
|
1307
|
+
code: code.slice(0, at) + literal + code.slice(at + PAGE_DATA_READS_TOKEN.length),
|
|
1308
|
+
map: null
|
|
1309
|
+
};
|
|
1310
|
+
}
|
|
1311
|
+
/** True when `file` is a registered island HOST (a component that declares islands). */
|
|
1312
|
+
is_registered_host(file) {
|
|
1313
|
+
const { host_index, registry } = this.program;
|
|
1314
|
+
return host_index.has(host_key(file)) || [...registry.values()].some((e) => same_module_path(e.hostPath, file));
|
|
1315
|
+
}
|
|
1316
|
+
/**
|
|
1317
|
+
* Drop the cached virtual island modules + the registry rows for `file` — call when a HOST changes
|
|
1318
|
+
* (an import-target rename keeps the same island id) or an ENTRY component is deleted (NOT on ordinary
|
|
1319
|
+
* entry-component content edits — those are soft HMR). Mutates the Program; `invalidate` is the
|
|
1320
|
+
* bundler's module-invalidation (Vite's moduleGraph), threaded in. Returns whether anything changed.
|
|
1321
|
+
*/
|
|
1322
|
+
invalidate_for_file(file, { deleted = false, invalidate }) {
|
|
1323
|
+
const { registry, island_graph, by_id, region_kinds, host_index } = this.program;
|
|
1324
|
+
const affected = /* @__PURE__ */ new Set();
|
|
1325
|
+
if (this.is_registered_host(file)) {
|
|
1326
|
+
for (const vpath of island_vpaths_affected_by_file(file, registry.entries())) affected.add(vpath);
|
|
1327
|
+
const prev = host_index.get(host_key(file));
|
|
1328
|
+
if (prev) for (const vpath of prev.vpaths) affected.add(vpath);
|
|
1329
|
+
this.program.unregister_host(file);
|
|
1330
|
+
}
|
|
1331
|
+
if (deleted) for (const [vpath, entry] of Array.from(registry.entries())) {
|
|
1332
|
+
if (!same_module_path(entry.componentPath, file)) continue;
|
|
1333
|
+
affected.add(vpath);
|
|
1334
|
+
registry.delete(vpath);
|
|
1335
|
+
island_graph.delete(vpath);
|
|
1336
|
+
by_id.delete(entry.id);
|
|
1337
|
+
region_kinds.delete(entry.id);
|
|
1338
|
+
const idx = host_index.get(host_key(entry.hostPath ?? ""));
|
|
1339
|
+
if (idx) {
|
|
1340
|
+
idx.vpaths.delete(vpath);
|
|
1341
|
+
idx.ids.delete(entry.id);
|
|
1342
|
+
}
|
|
1343
|
+
}
|
|
1344
|
+
if (affected.size === 0) return false;
|
|
1345
|
+
for (const vpath of affected) invalidate(vpath);
|
|
1346
|
+
invalidate(RESOLVED(V_SERVER_MANIFEST));
|
|
1347
|
+
invalidate(RESOLVED(V_SERVER_ISLANDS));
|
|
1348
|
+
invalidate(RESOLVED(V_MANIFEST));
|
|
1349
|
+
return true;
|
|
1350
|
+
}
|
|
1351
|
+
};
|
|
1352
|
+
export { Compiler, app_shim_for };
|