@ogygia/core 0.11.5 → 0.12.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (53) hide show
  1. package/dist/Region.svelte +28 -21
  2. package/dist/Region.svelte.d.ts +0 -2
  3. package/dist/compiler/bom.js +1 -1
  4. package/dist/compiler/browser.d.ts +1 -1
  5. package/dist/compiler/browser.js +1 -1
  6. package/dist/compiler/ctx.d.ts +1 -1
  7. package/dist/compiler/ctx.js +3 -3
  8. package/dist/compiler/{macros/dedent.d.ts → dedent.d.ts} +12 -1
  9. package/dist/compiler/dedent.js +43 -0
  10. package/dist/compiler/driver.d.ts +9 -6
  11. package/dist/compiler/driver.js +16 -24
  12. package/dist/compiler/index.d.ts +2 -2
  13. package/dist/compiler/index.js +2 -2
  14. package/dist/compiler/link/caps.js +59 -9
  15. package/dist/compiler/link/island-deps.js +225 -22
  16. package/dist/compiler/link/location-map.d.ts +10 -0
  17. package/dist/compiler/link/location-map.js +53 -0
  18. package/dist/compiler/link/manifest.js +5 -1
  19. package/dist/compiler/link/server-manifest.js +43 -7
  20. package/dist/compiler/link/transport.js +39 -7
  21. package/dist/compiler/macros/source.js +2 -2
  22. package/dist/compiler/region/transform.d.ts +13 -4
  23. package/dist/compiler/region/transform.js +15 -6
  24. package/dist/hooks.d.ts +16 -0
  25. package/dist/hooks.js +4 -2
  26. package/dist/insights/page-insights.js +2 -2
  27. package/dist/runtime/beacon.js +1 -1
  28. package/dist/runtime/boot-link.js +4 -1
  29. package/dist/runtime/core.js +3 -2
  30. package/dist/runtime/entry-locations.d.ts +10 -3
  31. package/dist/runtime/entry-locations.js +132 -21
  32. package/dist/runtime/morph.d.ts +7 -0
  33. package/dist/runtime/morph.js +21 -15
  34. package/dist/runtime/ownership.d.ts +10 -1
  35. package/dist/runtime/ownership.js +19 -1
  36. package/dist/runtime/reconcile.d.ts +5 -2
  37. package/dist/runtime/reconcile.js +52 -16
  38. package/dist/runtime/region-endpoint-url.js +1 -0
  39. package/dist/runtime/router-nav.js +15 -0
  40. package/dist/runtime/router.js +3 -0
  41. package/dist/runtime/slots.d.ts +8 -2
  42. package/dist/server/document-tail.d.ts +3 -2
  43. package/dist/server/document-tail.js +4 -3
  44. package/dist/server/entry-location.js +11 -8
  45. package/dist/server/props-wire.js +2 -2
  46. package/dist/server/signing-key.d.ts +10 -2
  47. package/dist/server/signing-key.js +49 -15
  48. package/dist/vite/index.js +5 -4
  49. package/dist/vite/kit-dirs.js +1 -1
  50. package/package.json +1 -1
  51. package/dist/compiler/link/entry-shim.d.ts +0 -4
  52. package/dist/compiler/link/entry-shim.js +0 -29
  53. package/dist/compiler/macros/dedent.js +0 -36
@@ -104,7 +104,7 @@
104
104
  * children?: import('svelte').Snippet;
105
105
  * __mode?: 'island' | 'server' | 'lake'; __baked?: boolean;
106
106
  * visible?: string | boolean; idle?: boolean; media?: string; load?: boolean; interaction?: boolean;
107
- * __keep?: string; __entry?: string; __src?: string; __component?: import('svelte').Component; __css?: unknown;
107
+ * __keep?: string; __entry?: string; __component?: import('svelte').Component; __css?: unknown;
108
108
  * __load?: () => Promise<import('svelte').Component>;
109
109
  * __props?: Record<string, unknown>; __defer?: string; __margin?: string; __hydrate?: string;
110
110
  * __hydrateMargin?: string; __module?: string; __cacheTtl?: number; __stitch?: string; __prefetch?: string;
@@ -132,11 +132,9 @@
132
132
  load,
133
133
  interaction,
134
134
  __keep,
135
- // island + server shared. `__entry` is the island's IDENTITY (its stable URL); `__src` its
136
- // LOCATION — the content-hashed file to load — which only the client build knows (its wrapper
137
- // passes the bundler's own name for it). The server finds the location in the build handoff.
135
+ // island + server shared. `__entry` is the island's IDENTITY (its stable URL, a name); its
136
+ // LOCATION, the content-hashed file to load, the server finds in the build handoff.
138
137
  __entry = '',
139
- __src = '',
140
138
  __component,
141
139
  __css,
142
140
  // The client wrapper's on-demand component fetch (its lazy module answered `undefined`: a
@@ -497,13 +495,15 @@
497
495
  const island_module_url = $derived(nested || !island_entry ? '' : asset(island_entry));
498
496
  // IDENTITY vs LOCATION (server/entry-location.ts): `island_module_url` is the island's identity
499
497
  // (the `entry` attribute, the graph key, the fingerprint input); the file the runtime loads is its
500
- // location — content-hashed, so an `immutable` cache never serves a stale one. The client build's
501
- // wrapper passes it (`__src`); the server reads the build handoff. None → the identity is loaded.
498
+ // location — content-hashed, so an `immutable` cache never serves a stale one. The server reads it
499
+ // from the build handoff (in dev the identity is the location); a region the browser renders has
500
+ // none, and the runtime finds it in the build's location map (runtime/entry-locations.ts). Only a
501
+ // location is ever written as a URL to fetch: no location, no URL.
502
502
  const location_of = (/** @type {string} */ identity) => {
503
503
  const found = identity ? entryLocation(identity) : null;
504
504
  return found ? asset(found) : '';
505
505
  };
506
- const island_src = $derived(nested || !island_entry ? '' : __src || location_of(island_entry));
506
+ const island_src = $derived(nested || !island_entry ? '' : location_of(island_entry));
507
507
  // (written LAST on the element: every attribute before it keeps the order it had before
508
508
  // locations, so HTML rewriters and scans keyed on `entry="…" wake="…"` still match)
509
509
 
@@ -605,7 +605,7 @@
605
605
  for (const dep of deps) add(asset(dep));
606
606
  for (const m of live_entries) {
607
607
  // (the file the snippet's import fetches: its location, when the build named one)
608
- add(location_of(m) || asset(m));
608
+ add(location_of(m));
609
609
  for (const dep of islandDeps(m)) add(asset(dep));
610
610
  }
611
611
  return hrefs;
@@ -637,10 +637,8 @@
637
637
  // island only, at `fetchpriority="low"` (document-tail.ts `modulepreload_tag`): nothing it
638
638
  // downloads is needed for first paint, so it must never outrank the CSS and the LCP image.
639
639
  const island_kit_hint_hrefs = $derived(
640
- // (the entry's LOCATION: the file its import fetches, not the stable name)
641
- is_csr && hydrate_attr === 'load' && island_module_url
642
- ? [island_src || island_module_url, ...island_graph_hrefs]
643
- : []
640
+ // (the entry's LOCATION: the file its import fetches; an entry with none gets no hint)
641
+ is_csr && hydrate_attr === 'load' && island_src ? [island_src, ...island_graph_hrefs] : []
644
642
  );
645
643
  // Both ride the document tail on a Kit page (see `tail` above); the head everywhere else, so a
646
644
  // self-contained render root carries its own.
@@ -688,7 +686,7 @@
688
686
  // nav. The endpoint (which fetches the hole's HTML) is minted from `__entry` above, independently.
689
687
  const server_region_entry = $derived(!nested && __module ? asset(__module) : '');
690
688
  // …and its location, the file that import fetches (as for an island)
691
- const server_region_src = $derived(!nested && __module ? __src || location_of(__module) : '');
689
+ const server_region_src = $derived(!nested && __module ? location_of(__module) : '');
692
690
 
693
691
  // A hydrating hole's props: ADJACENT and self-contained (the hole's HTML is spliced by the
694
692
  // runtime), unkeyed, in whichever lane the props qualify for (props-wire.ts).
@@ -966,14 +964,23 @@
966
964
  return html;
967
965
  });
968
966
 
967
+ // THE HEAD IS SERVER OUTPUT. Every piece of it is a fact only the render knows (the build's
968
+ // handoff, the request's claims), and the browser knows none of them: a URL it built here would
969
+ // be a guess — an identity, a name with no file. Svelte keeps the server's nodes when it hydrates
970
+ // the head, but a Kit-hydrated document's head is often mounted afresh (the handle rewrote it),
971
+ // and a region Kit mounts on a client-side navigation has no server render at all: either way
972
+ // the client writes nothing. What a client-mounted region loads it loads through its own
973
+ // `import()`, which the bundler resolves to the file and preloads with its dependencies.
969
974
  const head_html = $derived(
970
- (is_island
971
- ? runtime_script + island_preload_head + island_css_html + kit_island_meta
972
- : is_server
973
- ? runtime_script + server_preload + hole_css_html
974
- : runtime_script) +
975
- region_css_html +
976
- content_css_html
975
+ typeof window !== 'undefined'
976
+ ? ''
977
+ : (is_island
978
+ ? runtime_script + island_preload_head + island_css_html + kit_island_meta
979
+ : is_server
980
+ ? runtime_script + server_preload + hole_css_html
981
+ : runtime_script) +
982
+ region_css_html +
983
+ content_css_html
977
984
  );
978
985
 
979
986
  // ────────────────────────────────────────────────────── held: live / deferred ──
@@ -14,7 +14,6 @@ type Region = {
14
14
  interaction?: boolean | undefined;
15
15
  __keep?: string | undefined;
16
16
  __entry?: string | undefined;
17
- __src?: string | undefined;
18
17
  __component?: Component<any, any, string> | undefined;
19
18
  __css?: unknown;
20
19
  __load?: (() => Promise<Component<any, any, string>>) | undefined;
@@ -47,7 +46,6 @@ declare const Region: import("svelte").Component<{
47
46
  interaction?: boolean;
48
47
  __keep?: string;
49
48
  __entry?: string;
50
- __src?: string;
51
49
  __component?: import("svelte").Component;
52
50
  __css?: unknown;
53
51
  __load?: () => Promise<import("svelte").Component>;
@@ -2,7 +2,7 @@
2
2
  /**
3
3
  * A leading UTF-8 byte-order mark is invisible text. Svelte's `parse` drops it, so every AST offset
4
4
  * it reports is one short of the raw source, and a pass that edits the raw source by those offsets
5
- * (MagicString) lands one character early — splitting a tag name (`<qds-butto data-og-opaquen`, a
5
+ * (MagicString) lands one character early — splitting a tag name (`<ds-butto data-og-opaquen`, a
6
6
  * field build). The compiler therefore takes the mark off at the doors where source comes in (the
7
7
  * per-file transform, the barrel rewrite, the file reader), so every pass sees exactly the text its
8
8
  * parser saw. Dropping it changes nothing a browser or a bundler reads.
@@ -6,6 +6,6 @@ import { JsRegion, OgCall, find_og_calls, is_js_module, og_js_regions, split_fir
6
6
  import { og_member } from "./macros/wire.js";
7
7
  import { BuildCache, __set_build_cache_root, configure_build_cache } from "../build-cache.js";
8
8
  import { contentCssKey as content_css_key } from "../plugin/utils.js";
9
- import { dedent } from "./macros/dedent.js";
9
+ import { dedent } from "./dedent.js";
10
10
  import { run_browser_macros } from "./macros/browser.js";
11
11
  export { BuildCache, CLIENT_BINDING_STUB, type CompilerHost, type JsRegion, type OgCall, type ParseResult, type RawParse, __set_build_cache_root, configure_build_cache, content_css_key, createHash, dedent, find_og_calls, fs, is_js_module, islandVirtualId, og_js_regions, og_member, parse_module, path, run_browser_macros, set_host, set_parser, split_first_string, transformHost, transformTsRegions, wrapperVirtualId };
@@ -6,6 +6,6 @@ import { find_og_calls, is_js_module, og_js_regions, split_first_string } from "
6
6
  import { og_member } from "./macros/wire.js";
7
7
  import { BuildCache, __set_build_cache_root, configure_build_cache } from "../build-cache.js";
8
8
  import { contentCssKey as content_css_key } from "../plugin/utils.js";
9
- import { dedent } from "./macros/dedent.js";
9
+ import { dedent } from "./dedent.js";
10
10
  import { run_browser_macros } from "./macros/browser.js";
11
11
  export { BuildCache, CLIENT_BINDING_STUB, __set_build_cache_root, configure_build_cache, content_css_key, createHash, dedent, find_og_calls, fs, is_js_module, islandVirtualId, og_js_regions, og_member, parse_module, path, run_browser_macros, set_host, set_parser, split_first_string, transformHost, transformTsRegions, wrapperVirtualId };
@@ -160,7 +160,7 @@ export declare class CompileCtx {
160
160
  * runs. Both the stable name and the content-hashed file carry it, so a name says which runtime. */
161
161
  runtime_features(program_feature_hash: string): string;
162
162
  /** The runtime's STABLE name (`RUNTIME_HASH` ⊕ its features): its identity — the key the handoff
163
- * maps to the content-hashed file the page loads — and the name of that file's shim. Computed here
163
+ * maps to the content-hashed file the page loads (a name, not a file). Computed here
164
164
  * (not the caller) so both build legs name it identically. `program_feature_hash` is
165
165
  * `Program.runtime_feature_hash`, threaded in by the caller so this stays a pure naming function. */
166
166
  runtime_chunk_filename(program_feature_hash: string): string;
@@ -2,7 +2,7 @@ import { fs } from "./host.js";
2
2
  import { strip_bom } from "./bom.js";
3
3
  import { islandVirtualId } from "./ids.js";
4
4
  import { parse_module } from "./parse/oxc.js";
5
- import { islandChunkFileName, islandPublicUrl, wrapperVirtualId } from "./region/transform.js";
5
+ import { STABLE_NAME_DIR, islandChunkFileName, islandPublicUrl, wrapperVirtualId } from "./region/transform.js";
6
6
  // src/compiler/ctx.ts
7
7
  /**
8
8
  * `CompileCtx` — the resolved compile context: the config the transform phase reads, plus its
@@ -156,12 +156,12 @@ var CompileCtx = class {
156
156
  return `${program_feature_hash}${this.client_hooks ? "h" : ""}`;
157
157
  }
158
158
  /** The runtime's STABLE name (`RUNTIME_HASH` ⊕ its features): its identity — the key the handoff
159
- * maps to the content-hashed file the page loads — and the name of that file's shim. Computed here
159
+ * maps to the content-hashed file the page loads (a name, not a file). Computed here
160
160
  * (not the caller) so both build legs name it identically. `program_feature_hash` is
161
161
  * `Program.runtime_feature_hash`, threaded in by the caller so this stays a pure naming function. */
162
162
  runtime_chunk_filename(program_feature_hash) {
163
163
  const feat = this.runtime_features(program_feature_hash);
164
- return `${this.app_dir}/immutable/og-runtime.${this.runtime_hash}${feat ? "-" + feat : ""}.js`;
164
+ return `${this.app_dir}/${STABLE_NAME_DIR}/og-runtime.${this.runtime_hash}${feat ? "-" + feat : ""}.js`;
165
165
  }
166
166
  /** App-internal URL of the runtime chunk (leading slash + appDir; NO base). SSR bakes it as the
167
167
  * `<script src>`, then `asset()` prepends base / the assets CDN at render time. */
@@ -8,5 +8,16 @@
8
8
  * their literal column contribution to the prefix (the common prefix is computed on raw characters,
9
9
  * so mixed tabs/spaces still de-indent correctly as long as the leading run is consistent — which it
10
10
  * is for machine-indented source).
11
+ *
12
+ * Also a TAG, for the code the compiler generates (its virtual modules), written as the code itself:
13
+ *
14
+ * dedent`
15
+ * export const dev = ${is_dev};
16
+ * `
17
+ *
18
+ * The template's own text is de-indented first and the values go in after, so a value spanning lines
19
+ * (a generated block) never decides the indent. Values are interpolated as a template literal would
20
+ * (cooked strings: `\\n` in the template is a newline).
11
21
  */
12
- export declare function dedent(text: string): string;
22
+ export declare function dedent(text: string): string;
23
+ export declare function dedent(strings: TemplateStringsArray, ...values: unknown[]): string;
@@ -0,0 +1,43 @@
1
+ // src/compiler/dedent.ts
2
+ const CRLF_G = /\r\n?/g;
3
+ const LEADING_INDENT_RE = /^[\t ]*/;
4
+ function dedent(first, ...values) {
5
+ if (typeof first === "string") return dedent_text(first);
6
+ let text = first[0];
7
+ for (let i = 1; i < first.length; i++) text += SLOT + (i - 1) + SLOT + first[i];
8
+ const flat = dedent_text(text);
9
+ if (values.length === 0) return flat;
10
+ let out = "";
11
+ let at = 0;
12
+ for (;;) {
13
+ const open = flat.indexOf(SLOT, at);
14
+ if (open === -1) return out + flat.slice(at);
15
+ const close = flat.indexOf(SLOT, open + 1);
16
+ out += flat.slice(at, open) + String(values[Number(flat.slice(open + 1, close))]);
17
+ at = close + 1;
18
+ }
19
+ }
20
+ /** The placeholder edge for a tag's value while its template is de-indented. */
21
+ const SLOT = "\0";
22
+ function dedent_text(text) {
23
+ const lines = text.replace(CRLF_G, "\n").split("\n");
24
+ while (lines.length && lines[0].trim() === "") lines.shift();
25
+ while (lines.length && lines[lines.length - 1].trim() === "") lines.pop();
26
+ if (!lines.length) return "";
27
+ let common = null;
28
+ for (const line of lines) {
29
+ if (line.trim() === "") continue;
30
+ const lead = LEADING_INDENT_RE.exec(line)[0];
31
+ if (common === null) common = lead;
32
+ else {
33
+ let i = 0;
34
+ const max = Math.min(common.length, lead.length);
35
+ while (i < max && common[i] === lead[i]) i++;
36
+ common = common.slice(0, i);
37
+ }
38
+ if (common === "") break;
39
+ }
40
+ const n = common?.length ?? 0;
41
+ return lines.map((line) => line.trim() === "" ? "" : line.slice(n)).join("\n");
42
+ }
43
+ export { dedent };
@@ -158,6 +158,9 @@ export declare class Compiler {
158
158
  * bundle end turns them into the hashed file names the handoff maps the stable names to. */
159
159
  readonly island_entry_refs: Map<string, string>;
160
160
  runtime_entry_ref: string | null;
161
+ /** The location map's served path (`/<appDir>/immutable/og-locations.<hash>.json`), once
162
+ * `location_map` wrote it: the handoff carries it to the server (`locations`). */
163
+ location_map_url: string | null;
161
164
  /**
162
165
  * At the bundle's end (the names are final): each entry's IDENTITY → its LOCATION. `islands` maps
163
166
  * an island entry's hashed file to its identity (the collector keys every map by identity);
@@ -170,8 +173,8 @@ export declare class Compiler {
170
173
  runtime_file: string | null;
171
174
  locations: Record<string, string>;
172
175
  };
173
- /** One hydrate island's entry, content-hashed by the bundler (its stable-name shim is written at
174
- * the bundle's end: `entry_shims`). */
176
+ /** One hydrate island's entry, content-hashed by the bundler (the location maps that name it are
177
+ * written at the bundle's end: `location_maps`). */
175
178
  emit_island_entry(emitFile: EmitChunk, rid: string, virtualPath: string): void;
176
179
  /**
177
180
  * The output file pattern for one of OUR entries (by the chunk name `emit_island_entry` / the
@@ -182,11 +185,11 @@ export declare class Compiler {
182
185
  */
183
186
  entry_file_pattern(chunk_name: string | undefined): string | null;
184
187
  /**
185
- * The stable-name shims (link/entry-shim.ts), for the bundle's end (the names are final): one per
186
- * island entry, plus the runtime's — each a plain file at the old stable name re-exporting the
187
- * hashed file. `get_file_name` is the bundler's `this.getFileName`.
188
+ * The build's location maps (link/location-map.ts), for the bundle's end (the names are final):
189
+ * every island entry's identity → its hashed file, content-hashed and at the one fixed name.
190
+ * `get_file_name` is the bundler's `this.getFileName`. Empty with no island.
188
191
  */
189
- entry_shims(get_file_name: (ref: string) => string): {
192
+ location_maps(get_file_name: (ref: string) => string): {
190
193
  fileName: string;
191
194
  source: string;
192
195
  }[];
@@ -9,7 +9,7 @@ import { resolveFoucImportSpec } from "./fouc-css.js";
9
9
  import { appendSvelteModuleRegistrations, appendTransportRegistrations, moduleHasTransportable, svelteModuleHasTransportable } from "./content/transportables.js";
10
10
  import { APP_SHIM_IMPORT, FOREIGN_HYDRATE_MARK, rewrite_lake_import_to_placeholder } from "./region/emit.js";
11
11
  import { island_deps_module } from "./link/island-deps.js";
12
- import { island_shim_source, runtime_shim_source } from "./link/entry-shim.js";
12
+ import { location_map_files } from "./link/location-map.js";
13
13
  import { context_string_keys, source_uses_ogygia_context } from "./link/context-detect.js";
14
14
  import { collect_flag_sites } from "./flags.js";
15
15
  import { router_css_module, router_css_roots } from "./link/router-css.js";
@@ -610,7 +610,7 @@ var Compiler = class {
610
610
  * `emitRuntime`), then one chunk per deduped HYDRATE region id. IDENTITY vs LOCATION: SSR bakes the
611
611
  * stable name (`island_public_url`) as the region's identity; the file the browser loads is named
612
612
  * by its content (the bundler hashes it), and the bundle end hands the stable → hashed map to the
613
- * server (the handoff's `entries`). The stable name is emitted too, as a shim of the hashed file.
613
+ * server (the handoff's `entries`) and to the browser (the location maps).
614
614
  * csr=false hosts omit wrapper imports so this emit owns the module. Idempotent per id.
615
615
  */
616
616
  #router_css_roots_cache = null;
@@ -695,6 +695,9 @@ var Compiler = class {
695
695
  * bundle end turns them into the hashed file names the handoff maps the stable names to. */
696
696
  island_entry_refs = /* @__PURE__ */ new Map();
697
697
  runtime_entry_ref = null;
698
+ /** The location map's served path (`/<appDir>/immutable/og-locations.<hash>.json`), once
699
+ * `location_map` wrote it: the handoff carries it to the server (`locations`). */
700
+ location_map_url = null;
698
701
  /**
699
702
  * At the bundle's end (the names are final): each entry's IDENTITY → its LOCATION. `islands` maps
700
703
  * an island entry's hashed file to its identity (the collector keys every map by identity);
@@ -725,8 +728,8 @@ var Compiler = class {
725
728
  locations
726
729
  };
727
730
  }
728
- /** One hydrate island's entry, content-hashed by the bundler (its stable-name shim is written at
729
- * the bundle's end: `entry_shims`). */
731
+ /** One hydrate island's entry, content-hashed by the bundler (the location maps that name it are
732
+ * written at the bundle's end: `location_maps`). */
730
733
  emit_island_entry(emitFile, rid, virtualPath) {
731
734
  this.program.emitted_island_chunks.add(rid);
732
735
  this.island_entry_refs.set(rid, emitFile({
@@ -748,28 +751,17 @@ var Compiler = class {
748
751
  return `${this.#ctx.app_dir}/immutable/[name].[hash].js`;
749
752
  }
750
753
  /**
751
- * The stable-name shims (link/entry-shim.ts), for the bundle's end (the names are final): one per
752
- * island entry, plus the runtime's — each a plain file at the old stable name re-exporting the
753
- * hashed file. `get_file_name` is the bundler's `this.getFileName`.
754
+ * The build's location maps (link/location-map.ts), for the bundle's end (the names are final):
755
+ * every island entry's identity → its hashed file, content-hashed and at the one fixed name.
756
+ * `get_file_name` is the bundler's `this.getFileName`. Empty with no island.
754
757
  */
755
- entry_shims(get_file_name) {
758
+ location_maps(get_file_name) {
756
759
  const ctx = this.#ctx;
757
- const out = [];
758
- for (const [rid, ref] of this.island_entry_refs) {
759
- const fileName = ctx.island_chunk_filename(rid);
760
- out.push({
761
- fileName,
762
- source: island_shim_source(fileName, get_file_name(ref))
763
- });
764
- }
765
- if (this.runtime_entry_ref) {
766
- const fileName = this.runtime_chunk_filename();
767
- out.push({
768
- fileName,
769
- source: runtime_shim_source(fileName, get_file_name(this.runtime_entry_ref))
770
- });
771
- }
772
- return out;
760
+ const pairs = [];
761
+ for (const [rid, ref] of this.island_entry_refs) pairs.push([ctx.island_chunk_filename(rid), get_file_name(ref)]);
762
+ const files = location_map_files(ctx.app_dir, pairs, (source) => createHash("sha256").update(source).digest("hex").slice(0, 12));
763
+ this.location_map_url = files.length ? "/" + files[0].fileName : null;
764
+ return files;
773
765
  }
774
766
  /**
775
767
  * Emit one ogygia VIRTUAL module's source: the config/capability virtuals (secret / sign / rate-limit
@@ -1,4 +1,4 @@
1
- import { CLIENT_BINDING_STUB, DEFAULT_IMPORT_KEYS, ISLAND_DIR, ImportKeys, asRegionLocals, import_keys_hint, is_island_path, islandChunkFileName, islandId, islandPublicUrl, normalize_hydrate_value, normalize_import_keys, normalize_region_value, transformHost, transformTsRegions, wrapperVirtualId } from "./region/transform.js";
1
+ import { CLIENT_BINDING_STUB, DEFAULT_IMPORT_KEYS, ISLAND_DIR, ImportKeys, STABLE_NAME_DIR, asRegionLocals, import_keys_hint, is_island_path, islandChunkFileName, islandId, islandPublicUrl, normalize_hydrate_value, normalize_import_keys, normalize_region_value, transformHost, transformTsRegions, wrapperVirtualId } from "./region/transform.js";
2
2
  import { RawParse, set_parser } from "./parse/oxc.js";
3
3
  import { CssReachOptions, FOUC_CSS_PREFIX, FOUC_SCOPED_PREFIX, FoucAlias, buildFoucCssModuleSource, collectFoucCssReachable, compileFoucScopedCss, foucCssVirtualId, foucRelFromId, foucScopedVirtualId, isFoucCssId, isFoucScopedId, listStaticImports, resolveFoucImportSpec, svelteHasStyle } from "./fouc-css.js";
4
4
  import { regionId, regionIdentity, strategyKey } from "./region/identity.js";
@@ -8,4 +8,4 @@ import { Program, host_key, strip_id } from "./program.js";
8
8
  import { CompileCtx, CompileCtxInit } from "./ctx.js";
9
9
  import { PROFILER_MAPS_GZ_PREFIX, 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_KIT_WIRE, 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_FLAGS, 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, islandVirtualId, lazyEntryVirtualId, regionBindingVirtualId } from "./ids.js";
10
10
  import { FLAGS_SPEC, FlagSite, collect_flag_sites, flags_manifest } from "./flags.js";
11
- export { CLIENT_BINDING_STUB, CompileCtx, type CompileCtxInit, Compiler, CssReachOptions, DEFAULT_IMPORT_KEYS, FLAGS_SPEC, FOUC_CSS_PREFIX, FOUC_SCOPED_PREFIX, type FlagSite, FoucAlias, ISLAND_DIR, ImportKeys, PROFILER_MAPS_GZ_PREFIX, PROFILER_MAPS_PLACEHOLDER, type Profiler, Program, RESOLVED, type RawParse, 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_KIT_WIRE, 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_FLAGS, 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, asRegionLocals, buildFoucCssModuleSource, collectCaptureInfo, collectFoucCssReachable, collectFreeIdentifiers, collectSnippetNames, collect_flag_sites, compileFoucScopedCss, flags_manifest, foucCssVirtualId, foucRelFromId, foucScopedVirtualId, host_key, import_keys_hint, isFoucCssId, isFoucScopedId, is_island_path, islandChunkFileName, islandId, islandPublicUrl, islandVirtualId, lazyEntryVirtualId, listStaticImports, normalize_hydrate_value, normalize_import_keys, normalize_region_value, regionBindingVirtualId, regionId, regionIdentity, resolveFoucImportSpec, set_parser, strategyKey, strip_id, svelteHasStyle, transformHost, transformTsRegions, wrapperVirtualId };
11
+ export { CLIENT_BINDING_STUB, CompileCtx, type CompileCtxInit, Compiler, CssReachOptions, DEFAULT_IMPORT_KEYS, FLAGS_SPEC, FOUC_CSS_PREFIX, FOUC_SCOPED_PREFIX, type FlagSite, FoucAlias, ISLAND_DIR, ImportKeys, PROFILER_MAPS_GZ_PREFIX, PROFILER_MAPS_PLACEHOLDER, type Profiler, Program, RESOLVED, type RawParse, STABLE_NAME_DIR, 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_KIT_WIRE, 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_FLAGS, 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, asRegionLocals, buildFoucCssModuleSource, collectCaptureInfo, collectFoucCssReachable, collectFreeIdentifiers, collectSnippetNames, collect_flag_sites, compileFoucScopedCss, flags_manifest, foucCssVirtualId, foucRelFromId, foucScopedVirtualId, host_key, import_keys_hint, isFoucCssId, isFoucScopedId, is_island_path, islandChunkFileName, islandId, islandPublicUrl, islandVirtualId, lazyEntryVirtualId, listStaticImports, normalize_hydrate_value, normalize_import_keys, normalize_region_value, regionBindingVirtualId, regionId, regionIdentity, resolveFoucImportSpec, set_parser, strategyKey, strip_id, svelteHasStyle, transformHost, transformTsRegions, wrapperVirtualId };
@@ -1,4 +1,4 @@
1
- import { CLIENT_BINDING_STUB, DEFAULT_IMPORT_KEYS, ISLAND_DIR, asRegionLocals, import_keys_hint, is_island_path, islandChunkFileName, islandId, islandPublicUrl, normalize_hydrate_value, normalize_import_keys, normalize_region_value, transformHost, transformTsRegions, wrapperVirtualId } from "./region/transform.js";
1
+ import { CLIENT_BINDING_STUB, DEFAULT_IMPORT_KEYS, ISLAND_DIR, STABLE_NAME_DIR, asRegionLocals, import_keys_hint, is_island_path, islandChunkFileName, islandId, islandPublicUrl, normalize_hydrate_value, normalize_import_keys, normalize_region_value, transformHost, transformTsRegions, wrapperVirtualId } from "./region/transform.js";
2
2
  import { set_parser } from "./parse/oxc.js";
3
3
  import { FOUC_CSS_PREFIX, FOUC_SCOPED_PREFIX, buildFoucCssModuleSource, collectFoucCssReachable, compileFoucScopedCss, foucCssVirtualId, foucRelFromId, foucScopedVirtualId, isFoucCssId, isFoucScopedId, listStaticImports, resolveFoucImportSpec, svelteHasStyle } from "./fouc-css.js";
4
4
  import { regionId, regionIdentity, strategyKey } from "./region/identity.js";
@@ -8,4 +8,4 @@ import { Program, host_key, strip_id } from "./program.js";
8
8
  import { CompileCtx } from "./ctx.js";
9
9
  import { PROFILER_MAPS_GZ_PREFIX, 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_KIT_WIRE, 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_FLAGS, 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, islandVirtualId, lazyEntryVirtualId, regionBindingVirtualId } from "./ids.js";
10
10
  import { FLAGS_SPEC, collect_flag_sites, flags_manifest } from "./flags.js";
11
- export { CLIENT_BINDING_STUB, CompileCtx, Compiler, DEFAULT_IMPORT_KEYS, FLAGS_SPEC, FOUC_CSS_PREFIX, FOUC_SCOPED_PREFIX, ISLAND_DIR, PROFILER_MAPS_GZ_PREFIX, PROFILER_MAPS_PLACEHOLDER, Program, 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_KIT_WIRE, 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_FLAGS, 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, asRegionLocals, buildFoucCssModuleSource, collectCaptureInfo, collectFoucCssReachable, collectFreeIdentifiers, collectSnippetNames, collect_flag_sites, compileFoucScopedCss, flags_manifest, foucCssVirtualId, foucRelFromId, foucScopedVirtualId, host_key, import_keys_hint, isFoucCssId, isFoucScopedId, is_island_path, islandChunkFileName, islandId, islandPublicUrl, islandVirtualId, lazyEntryVirtualId, listStaticImports, normalize_hydrate_value, normalize_import_keys, normalize_region_value, regionBindingVirtualId, regionId, regionIdentity, resolveFoucImportSpec, set_parser, strategyKey, strip_id, svelteHasStyle, transformHost, transformTsRegions, wrapperVirtualId };
11
+ export { CLIENT_BINDING_STUB, CompileCtx, Compiler, DEFAULT_IMPORT_KEYS, FLAGS_SPEC, FOUC_CSS_PREFIX, FOUC_SCOPED_PREFIX, ISLAND_DIR, PROFILER_MAPS_GZ_PREFIX, PROFILER_MAPS_PLACEHOLDER, Program, RESOLVED, STABLE_NAME_DIR, 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_KIT_WIRE, 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_FLAGS, 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, asRegionLocals, buildFoucCssModuleSource, collectCaptureInfo, collectFoucCssReachable, collectFreeIdentifiers, collectSnippetNames, collect_flag_sites, compileFoucScopedCss, flags_manifest, foucCssVirtualId, foucRelFromId, foucScopedVirtualId, host_key, import_keys_hint, isFoucCssId, isFoucScopedId, is_island_path, islandChunkFileName, islandId, islandPublicUrl, islandVirtualId, lazyEntryVirtualId, listStaticImports, normalize_hydrate_value, normalize_import_keys, normalize_region_value, regionBindingVirtualId, regionId, regionIdentity, resolveFoucImportSpec, set_parser, strategyKey, strip_id, svelteHasStyle, transformHost, transformTsRegions, wrapperVirtualId };
@@ -1,4 +1,5 @@
1
1
  import { csrTrueRouteIds, errorCsrTrueRouteIds, page_route_config, rootLayoutCsrTrue } from "../kit.js";
2
+ import { dedent } from "../dedent.js";
2
3
  // src/compiler/link/caps.ts
3
4
  /**
4
5
  * Capability virtual-module emitters — the leg-split sources for the signed-capability family:
@@ -14,8 +15,14 @@ import { csrTrueRouteIds, errorCsrTrueRouteIds, page_route_config, rootLayoutCsr
14
15
  * counts — else this build's key.
15
16
  */
16
17
  function secret_module(ssr, build_secret, build_had_secret) {
17
- if (!ssr) return `export const buildKey = '';\nexport const buildHadSecret = false;`;
18
- return `export const buildKey = ${JSON.stringify(build_secret)};\nexport const buildHadSecret = ${build_had_secret};`;
18
+ if (!ssr) return dedent`
19
+ export const buildKey = '';
20
+ export const buildHadSecret = false;
21
+ `;
22
+ return dedent`
23
+ export const buildKey = ${JSON.stringify(build_secret)};
24
+ export const buildHadSecret = ${build_had_secret};
25
+ `;
19
26
  }
20
27
  /**
21
28
  * `virtual:ogygia/sign` — same split as secret: SSR mints with node:crypto (re-exports the real
@@ -23,12 +30,37 @@ function secret_module(ssr, build_secret, build_had_secret) {
23
30
  * length-prefixed canonical form the runtime compares against.
24
31
  */
25
32
  function sign_module(ssr, hmac_module) {
26
- if (!ssr) return "export function sign(_secret, _message) { return ''; }\nexport function verify(_secret, _message, _sig) { return false; }\nexport function region_mac_message(id, exp, props, session = '', ttl = '', render = '') {\n const enc = new TextEncoder();\n const lp = (s) => enc.encode(String(s)).byteLength + ':' + String(s);\n const v1 = lp(id) + '|' + lp(exp) + '|' + lp(props) + '|' + lp(session) + '|' + lp(ttl);\n return render === '' ? 'v1|' + v1 : 'v2|' + v1 + '|' + lp(render);\n}\n";
27
- return `export { sign, verify, region_mac_message } from ${JSON.stringify(hmac_module)};`;
33
+ if (!ssr) return dedent`
34
+ export function sign(_secret, _message) {
35
+ return '';
36
+ }
37
+
38
+ export function verify(_secret, _message, _sig) {
39
+ return false;
40
+ }
41
+
42
+ export function region_mac_message(id, exp, props, session = '', ttl = '', render = '') {
43
+ const enc = new TextEncoder();
44
+ const lp = (s) => enc.encode(String(s)).byteLength + ':' + String(s);
45
+ const v1 = lp(id) + '|' + lp(exp) + '|' + lp(props) + '|' + lp(session) + '|' + lp(ttl);
46
+ return render === '' ? 'v1|' + v1 : 'v2|' + v1 + '|' + lp(render);
47
+ }
48
+ `;
49
+ return dedent`
50
+ export { sign, verify, region_mac_message } from ${JSON.stringify(hmac_module)};
51
+ `;
28
52
  }
29
53
  function server_plugins_module(ssr, realms) {
30
54
  if (!ssr || realms.length === 0) return `export const plugins = [];`;
31
- return `${realms.map((r, i) => `import p${i} from ${JSON.stringify(r.module)};`).join("\n")}\nexport const plugins = [\n\t${realms.map((r, i) => `{ name: ${JSON.stringify(r.name)}, options: ${JSON.stringify(r.options)}, server: p${i} }`).join(",\n ")}\n];`;
55
+ const imports = realms.map((r, i) => `import p${i} from ${JSON.stringify(r.module)};`).join("\n");
56
+ const list = realms.map((r, i) => `{ name: ${JSON.stringify(r.name)}, options: ${JSON.stringify(r.options)}, server: p${i} }`).join(",\n ");
57
+ return dedent`
58
+ ${imports}
59
+
60
+ export const plugins = [
61
+ ${list}
62
+ ];
63
+ `;
32
64
  }
33
65
  /** `virtual:ogygia/route-config` — SERVER only: every Kit page route id → the keys the plugins claim
34
66
  * inside Kit's `config` page option, merged the way Kit merges it (a key no level sets is absent).
@@ -50,15 +82,33 @@ function session_cookie_module(ssr, session_cookie) {
50
82
  /** `virtual:ogygia/region-ttl` — SERVER only; the capability expiry window for mint, and how long
51
83
  * after expiry an anonymous capability still renews. */
52
84
  function region_ttl_module(ssr, region_ttl, renew_window) {
53
- if (!ssr) return `export const regionTtl = 3600;\nexport const renewWindow = 0;`;
54
- return `export const regionTtl = ${region_ttl};\nexport const renewWindow = ${renew_window};`;
85
+ if (!ssr) return dedent`
86
+ export const regionTtl = 3600;
87
+ export const renewWindow = 0;
88
+ `;
89
+ return dedent`
90
+ export const regionTtl = ${region_ttl};
91
+ export const renewWindow = ${renew_window};
92
+ `;
55
93
  }
56
94
  /** `virtual:ogygia/route-csr` — SERVER only: the csr=true route ids, so a csr=false layout's islands
57
95
  * degrade to inline when the LEAF page is csr=true (Kit hydrates the whole document). The CLIENT leg
58
96
  * is an empty set — the client reads the identical signal from `kit_hydrates_page()`, and the route
59
97
  * list never ships to the browser. */
60
98
  function route_csr_module(ssr, routesDir) {
61
- if (!ssr) return "export const csr_true_routes = new Set();\nexport const error_csr_true_routes = new Set();\nexport const root_layout_csr_true = true;";
62
- return `export const csr_true_routes = new Set(${JSON.stringify(csrTrueRouteIds(routesDir))});\nexport const error_csr_true_routes = new Set(${JSON.stringify(errorCsrTrueRouteIds(routesDir))});\nexport const root_layout_csr_true = ${rootLayoutCsrTrue(routesDir)};`;
99
+ if (!ssr) return dedent`
100
+ export const csr_true_routes = new Set();
101
+ export const error_csr_true_routes = new Set();
102
+ export const root_layout_csr_true = true;
103
+ `;
104
+ return dedent`
105
+ export const csr_true_routes = new Set(${JSON.stringify(csrTrueRouteIds(routesDir))});
106
+
107
+ // The error-render map beside the page map: Kit renders a route's error page with its LAYOUT
108
+ // branch only, so a 404 under a csr=false page is hydrated whenever the layouts say so.
109
+ export const error_csr_true_routes = new Set(${JSON.stringify(errorCsrTrueRouteIds(routesDir))});
110
+
111
+ export const root_layout_csr_true = ${rootLayoutCsrTrue(routesDir)};
112
+ `;
63
113
  }
64
114
  export { rate_limit_module, region_ttl_module, route_config_module, route_csr_module, secret_module, server_plugins_module, session_cookie_module, sign_module };