@ogygia/core 0.12.3 → 0.13.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 (226) hide show
  1. package/dist/LateIsland.svelte +3 -2
  2. package/dist/LateIslandAwait.svelte +6 -2
  3. package/dist/Region.svelte +22 -33
  4. package/dist/boundary.d.ts +0 -2
  5. package/dist/boundary.js +8 -6
  6. package/dist/compiler/debarrel/barrel.d.ts +15 -8
  7. package/dist/compiler/debarrel/barrel.js +92 -45
  8. package/dist/compiler/debarrel/plugin.js +41 -17
  9. package/dist/compiler/dev/dev-hmr.d.ts +3 -0
  10. package/dist/compiler/dev/dev-hmr.js +3 -0
  11. package/dist/compiler/driver.js +11 -4
  12. package/dist/compiler/flags.js +21 -7
  13. package/dist/compiler/fouc-css.js +5 -1
  14. package/dist/compiler/kit.js +5 -1
  15. package/dist/compiler/link/build-output.js +12 -3
  16. package/dist/compiler/macros/bake.js +18 -4
  17. package/dist/compiler/macros/dollar.js +6 -1
  18. package/dist/compiler/macros/source.js +6 -1
  19. package/dist/compiler/macros/store.js +10 -2
  20. package/dist/compiler/macros/wire.js +6 -1
  21. package/dist/compiler/parse/scan.js +10 -3
  22. package/dist/compiler/region/transform.js +188 -74
  23. package/dist/context-bridge.js +13 -5
  24. package/dist/context.d.ts +9 -0
  25. package/dist/context.js +30 -1
  26. package/dist/document.d.ts +1 -1
  27. package/dist/document.js +7 -1
  28. package/dist/early-holes-head.d.ts +5 -0
  29. package/dist/early-holes-head.js +20 -0
  30. package/dist/early-holes.d.ts +34 -0
  31. package/dist/early-holes.js +51 -0
  32. package/dist/entry-hydrate.js +9 -12
  33. package/dist/events/bus.js +7 -2
  34. package/dist/events/schema.d.ts +2 -2
  35. package/dist/fn-transport.js +4 -3
  36. package/dist/hooks.js +94 -163
  37. package/dist/insights/page-assets.js +11 -3
  38. package/dist/insights/page-insights.d.ts +0 -2
  39. package/dist/insights/page-insights.js +14 -10
  40. package/dist/insights/session-insights.js +2 -2
  41. package/dist/internal-instruments.d.ts +3 -1
  42. package/dist/internal-instruments.js +3 -1
  43. package/dist/internal-server.d.ts +3 -2
  44. package/dist/internal-server.js +3 -2
  45. package/dist/internal.d.ts +1 -2
  46. package/dist/internal.js +1 -2
  47. package/dist/keep-fallback.d.ts +0 -2
  48. package/dist/keep-fallback.js +4 -5
  49. package/dist/live-transport.js +3 -2
  50. package/dist/messages/build.d.ts +585 -0
  51. package/dist/messages/build.js +800 -0
  52. package/dist/messages/core.d.ts +464 -0
  53. package/dist/messages/core.js +843 -0
  54. package/dist/messages/define.d.ts +62 -0
  55. package/dist/messages/define.js +49 -0
  56. package/dist/messages/index.d.ts +6 -0
  57. package/dist/messages/index.js +6 -0
  58. package/dist/messages/island.d.ts +4 -0
  59. package/dist/messages/island.js +34 -0
  60. package/dist/messages/lazy.d.ts +3 -0
  61. package/dist/messages/lazy.js +22 -0
  62. package/dist/messages/prose.d.ts +15 -0
  63. package/dist/messages/prose.js +43 -0
  64. package/dist/messages/server.d.ts +142 -0
  65. package/dist/messages/server.js +246 -0
  66. package/dist/nested.d.ts +3 -0
  67. package/dist/nested.js +8 -1
  68. package/dist/plugin/css.js +14 -13
  69. package/dist/plugin/facts.d.ts +2 -0
  70. package/dist/plugin/facts.js +10 -6
  71. package/dist/plugin/hooks.d.ts +7 -17
  72. package/dist/plugin/hooks.js +32 -4
  73. package/dist/plugin/index.d.ts +9 -2
  74. package/dist/plugin/request-scope.d.ts +20 -0
  75. package/dist/plugin/request-scope.js +149 -0
  76. package/dist/plugin/server.d.ts +20 -2
  77. package/dist/plugin/server.js +98 -28
  78. package/dist/plugin/testing.d.ts +6 -0
  79. package/dist/plugin/testing.js +14 -2
  80. package/dist/policies.d.ts +21 -0
  81. package/dist/policies.js +66 -0
  82. package/dist/preference.js +6 -1
  83. package/dist/preload.js +6 -9
  84. package/dist/ref-watch.d.ts +0 -10
  85. package/dist/ref-watch.js +14 -1
  86. package/dist/ref.js +17 -5
  87. package/dist/region-snippet.js +9 -3
  88. package/dist/region.js +2 -1
  89. package/dist/report-thrown.d.ts +9 -0
  90. package/dist/report-thrown.js +15 -0
  91. package/dist/rules.d.ts +17 -0
  92. package/dist/rules.js +57 -0
  93. package/dist/runtime/beacon.d.ts +0 -4
  94. package/dist/runtime/beacon.js +58 -43
  95. package/dist/runtime/boot-link.js +19 -2
  96. package/dist/runtime/client-hooks.js +2 -1
  97. package/dist/runtime/concurrency.d.ts +16 -5
  98. package/dist/runtime/concurrency.js +123 -7
  99. package/dist/runtime/core.d.ts +3 -1
  100. package/dist/runtime/core.js +718 -384
  101. package/dist/runtime/devalue-lane.d.ts +13 -0
  102. package/dist/runtime/devalue-lane.js +49 -0
  103. package/dist/runtime/disclose-version.d.ts +1 -0
  104. package/dist/runtime/disclose-version.js +14 -0
  105. package/dist/runtime/early-holes.d.ts +4 -0
  106. package/dist/runtime/early-holes.js +40 -0
  107. package/dist/runtime/entry-locations.js +40 -49
  108. package/dist/runtime/foreign-props.d.ts +0 -7
  109. package/dist/runtime/foreign-props.js +2 -1
  110. package/dist/runtime/form-continuity.d.ts +2 -2
  111. package/dist/runtime/form-continuity.js +30 -8
  112. package/dist/runtime/frame-nav.d.ts +7 -1
  113. package/dist/runtime/frame-nav.js +84 -18
  114. package/dist/runtime/frame-store.d.ts +25 -16
  115. package/dist/runtime/frame-store.js +124 -98
  116. package/dist/runtime/frames.js +8 -4
  117. package/dist/runtime/hole-facts.js +6 -7
  118. package/dist/runtime/hole-fetch.d.ts +17 -0
  119. package/dist/runtime/hole-fetch.js +47 -0
  120. package/dist/runtime/hydrate-core.d.ts +4 -4
  121. package/dist/runtime/hydrate-core.js +80 -64
  122. package/dist/runtime/import-again.d.ts +33 -0
  123. package/dist/runtime/import-again.js +217 -0
  124. package/dist/runtime/interaction-replay.d.ts +5 -3
  125. package/dist/runtime/interaction-replay.js +6 -6
  126. package/dist/runtime/interaction.d.ts +14 -3
  127. package/dist/runtime/interaction.js +46 -23
  128. package/dist/runtime/kit-page-thread.svelte.d.ts +2 -1
  129. package/dist/runtime/kit-page-thread.svelte.js +44 -20
  130. package/dist/runtime/lakes.d.ts +1 -1
  131. package/dist/runtime/lakes.js +18 -5
  132. package/dist/runtime/live.d.ts +1 -2
  133. package/dist/runtime/live.js +6 -8
  134. package/dist/runtime/load-scheduler.d.ts +29 -18
  135. package/dist/runtime/load-scheduler.js +236 -136
  136. package/dist/runtime/nav-handle.js +25 -6
  137. package/dist/runtime/navigation.d.ts +24 -0
  138. package/dist/runtime/navigation.js +24 -0
  139. package/dist/runtime/ownership.d.ts +1 -1
  140. package/dist/runtime/page-defer.js +3 -3
  141. package/dist/runtime/parse-html.d.ts +15 -4
  142. package/dist/runtime/parse-html.js +24 -5
  143. package/dist/runtime/pushable-props.svelte.d.ts +21 -0
  144. package/dist/runtime/pushable-props.svelte.js +37 -0
  145. package/dist/runtime/region-endpoint-url.js +4 -6
  146. package/dist/runtime/region-machines.d.ts +111 -0
  147. package/dist/runtime/region-machines.js +97 -0
  148. package/dist/runtime/region-sheets.d.ts +31 -0
  149. package/dist/runtime/region-sheets.js +49 -0
  150. package/dist/runtime/restore-report.d.ts +1 -0
  151. package/dist/runtime/restore-report.js +36 -0
  152. package/dist/runtime/restore.d.ts +5 -2
  153. package/dist/runtime/restore.js +33 -14
  154. package/dist/runtime/router-nav.d.ts +32 -12
  155. package/dist/runtime/router-nav.js +320 -228
  156. package/dist/runtime/router.d.ts +83 -19
  157. package/dist/runtime/router.js +297 -129
  158. package/dist/runtime/rules.d.ts +35 -0
  159. package/dist/runtime/rules.js +137 -0
  160. package/dist/runtime/schedule.d.ts +6 -3
  161. package/dist/runtime/schedule.js +172 -57
  162. package/dist/runtime/seeds.d.ts +5 -1
  163. package/dist/runtime/seeds.js +11 -5
  164. package/dist/runtime/session.d.ts +46 -7
  165. package/dist/runtime/session.js +78 -10
  166. package/dist/runtime/slots.d.ts +53 -20
  167. package/dist/runtime/slots.js +2 -3
  168. package/dist/runtime/soft-refresh.d.ts +16 -0
  169. package/dist/runtime/soft-refresh.js +14 -0
  170. package/dist/runtime/svelte-warnings.d.ts +4 -10
  171. package/dist/runtime/svelte-warnings.js +7 -4
  172. package/dist/runtime/wire-classes.js +21 -8
  173. package/dist/runtime/wire-format.js +6 -3
  174. package/dist/script.js +8 -7
  175. package/dist/seed-ref-reviver.d.ts +0 -9
  176. package/dist/seed-ref-reviver.js +2 -1
  177. package/dist/seed-refs.d.ts +46 -36
  178. package/dist/seed-refs.js +131 -92
  179. package/dist/server/document-tail.d.ts +6 -0
  180. package/dist/server/document-tail.js +7 -1
  181. package/dist/server/early-holes-csp.d.ts +14 -0
  182. package/dist/server/early-holes-csp.js +73 -0
  183. package/dist/server/page-facts.d.ts +4 -1
  184. package/dist/server/page-facts.js +4 -1
  185. package/dist/server/page-seed.d.ts +2 -2
  186. package/dist/server/page-seed.js +104 -11
  187. package/dist/server/page-stream.d.ts +14 -1
  188. package/dist/server/page-stream.js +119 -2
  189. package/dist/server/personal-response.d.ts +0 -5
  190. package/dist/server/personal-response.js +6 -2
  191. package/dist/server/props-wire.js +5 -1
  192. package/dist/server/region-endpoint.js +10 -2
  193. package/dist/server/render-cache.d.ts +24 -20
  194. package/dist/server/render-cache.js +99 -40
  195. package/dist/server/render-page.js +46 -15
  196. package/dist/server/request-stats.d.ts +10 -8
  197. package/dist/server/request-stats.js +20 -12
  198. package/dist/server/rules.d.ts +11 -0
  199. package/dist/server/rules.js +64 -0
  200. package/dist/server/signing-key.js +31 -18
  201. package/dist/server/stream-regions.d.ts +14 -1
  202. package/dist/server/stream-regions.js +38 -2
  203. package/dist/shared-state.js +5 -1
  204. package/dist/shims/app-navigation.js +3 -2
  205. package/dist/shims/page-store.svelte.js +16 -2
  206. package/dist/source.js +7 -2
  207. package/dist/store-transport.js +12 -5
  208. package/dist/transport.js +3 -2
  209. package/dist/vite/index.js +17 -10
  210. package/dist/vite/kit-dirs.js +7 -1
  211. package/dist/vite/options.d.ts +2 -1
  212. package/dist/vite/options.js +11 -20
  213. package/dist/vite/package-files.js +13 -3
  214. package/dist/vite/paths.d.ts +2 -0
  215. package/dist/vite/paths.js +4 -4
  216. package/dist/vite/plugin-api.js +42 -14
  217. package/dist/vite/style-preprocess.js +10 -3
  218. package/package.json +8 -1
  219. package/dist/KeepHost.svelte +0 -19
  220. package/dist/KeepHost.svelte.d.ts +0 -10
  221. package/dist/LiveHost.svelte +0 -19
  222. package/dist/LiveHost.svelte.d.ts +0 -10
  223. package/dist/NestedProvider.svelte +0 -13
  224. package/dist/NestedProvider.svelte.d.ts +0 -8
  225. package/dist/runtime/page-cache.d.ts +0 -23
  226. package/dist/runtime/page-cache.js +0 -74
@@ -1,4 +1,5 @@
1
1
  import { kit_hydrates_page } from "./kit-boot.js";
2
+ import { OgygiaError } from "../messages/core.js";
2
3
  // src/runtime/client-hooks.ts
3
4
  /**
4
5
  * Run the app's `hooks.client.ts` `init()` on a csr=false page.
@@ -17,6 +18,6 @@ import { kit_hydrates_page } from "./kit-boot.js";
17
18
  function run_app_client_hooks(loader) {
18
19
  if (typeof document === "undefined") return;
19
20
  if (kit_hydrates_page()) return;
20
- Promise.resolve().then(loader).then((m) => m.init?.()).catch((e) => console.error("[ogygia] hooks.client init failed:", e));
21
+ Promise.resolve().then(loader).then((m) => m.init?.()).catch((e) => console.error(new OgygiaError("client_hooks_init_failed"), e));
21
22
  }
22
23
  export { run_app_client_hooks };
@@ -1,12 +1,23 @@
1
- /**
2
- * Shared concurrency gate — client region fetches (SI-STORM) and server region SSR (M1).
3
- * Caps in-flight work; waiters queue FIFO. Does not cancel running work (see INVARIANTS.md).
4
- */
1
+ export interface GateOptions {
2
+ /** The call answers within this long: the wait for a slot and the run together. */
3
+ deadline_ms?: number;
4
+ /** Nobody waits on the call any more once it aborts (a batch whose visitor left, #245): still
5
+ * waiting, it leaves the queue at once and its body never runs (the call rejects with the
6
+ * signal's reason); already running, it runs on (a body cannot be cancelled). */
7
+ signal?: AbortSignal;
8
+ }
5
9
  export declare class ConcurrencyGate {
6
10
  #private;
7
11
  constructor(max: number);
8
- run<T>(fn: () => Promise<T>): Promise<T>;
12
+ run<T>(fn: () => Promise<T>, options?: GateOptions): Promise<T>;
13
+ /** Bodies running that someone waits on (the limit counts these). */
9
14
  get active(): number;
15
+ /** Bodies past their deadline still running: nobody waits on them, and they hold no slot. */
16
+ get abandoned(): number;
17
+ /** Calls waiting for a slot. */
18
+ get waiting(): number;
10
19
  }
20
+ /** Whether `error` is a call's run timeout: its body ran past the deadline and was abandoned. */
21
+ export declare function is_run_timeout(error: unknown): boolean;
11
22
  /** Max concurrent region SSR renders per process (CPU amp under valid MAC). */
12
23
  export declare const REGION_RENDER_CONCURRENCY = 4;
@@ -1,29 +1,145 @@
1
+ import { scope } from "@ogygia/machine";
1
2
  // src/runtime/concurrency.ts
2
3
  /**
3
4
  * Shared concurrency gate — client region fetches (SI-STORM) and server region SSR (M1).
4
5
  * Caps in-flight work; waiters queue FIFO. Does not cancel running work (see INVARIANTS.md).
6
+ *
7
+ * The promise: never more than `limit` bodies running that someone still waits on (#195), and a
8
+ * call with a deadline answers within it.
9
+ * - A freed slot is HANDED to the next waiter in the same step: it is never free in between, so a
10
+ * call arriving while the waiter resumes queues behind it instead of entering beside it.
11
+ * - `deadline_ms` covers the whole call, the wait for a slot and the run together. A waiter whose
12
+ * deadline passes gives up and never runs. A body still running at its deadline is ABANDONED: its
13
+ * caller gets the timeout and its slot goes to the next call at once. Svelte's `render()` cannot
14
+ * be cancelled, so the body runs on, counted in `abandoned` until it ends; it never blocks a slot,
15
+ * or a hung upstream (renders that never end) would hold every slot and take every hole down.
16
+ * - A call's `signal` aborting while it waits takes it out of the queue: a body nobody waits on any
17
+ * more never starts, and never holds a slot.
18
+ *
19
+ * Each call owns its timers and its listener on `signal` (a scope): they are let go the moment the
20
+ * call settles, whichever way.
5
21
  */
22
+ /** The caller's error when its body ran past the deadline (it was abandoned). */
23
+ const RUN_TIMEOUT = "region render timeout";
24
+ /** The caller's error when no slot came before the deadline (its body never ran). */
25
+ const WAIT_TIMEOUT = "region render queue timeout";
6
26
  var ConcurrencyGate = class {
7
27
  #limit;
8
28
  #active = 0;
29
+ #abandoned = 0;
9
30
  #wait = [];
10
31
  constructor(max) {
11
32
  this.#limit = Math.max(1, max);
12
33
  }
13
- async run(fn) {
14
- if (this.#active >= this.#limit) await new Promise((resolve) => this.#wait.push(resolve));
15
- this.#active++;
34
+ async run(fn, options = {}) {
35
+ const { deadline_ms, signal } = options;
36
+ if (signal?.aborted) throw signal.reason;
37
+ const deadline = deadline_ms === void 0 ? Infinity : Date.now() + deadline_ms;
38
+ const call = scope();
16
39
  try {
17
- return await fn();
40
+ await this.#enter(deadline, signal, call);
41
+ if (signal?.aborted) {
42
+ this.#leave();
43
+ throw signal.reason;
44
+ }
45
+ let body;
46
+ try {
47
+ body = fn();
48
+ } catch (error) {
49
+ body = Promise.reject(error);
50
+ }
51
+ let holds = true;
52
+ const end = () => {
53
+ if (holds) {
54
+ holds = false;
55
+ this.#leave();
56
+ } else this.#abandoned--;
57
+ };
58
+ body.then(end, end);
59
+ if (deadline === Infinity) return await body;
60
+ return await within(call, body, deadline - Date.now(), () => {
61
+ if (!holds) return;
62
+ holds = false;
63
+ this.#abandoned++;
64
+ this.#leave();
65
+ });
18
66
  } finally {
19
- this.#active--;
20
- this.#wait.shift()?.();
67
+ call.close();
21
68
  }
22
69
  }
70
+ /** Bodies running that someone waits on (the limit counts these). */
23
71
  get active() {
24
72
  return this.#active;
25
73
  }
74
+ /** Bodies past their deadline still running: nobody waits on them, and they hold no slot. */
75
+ get abandoned() {
76
+ return this.#abandoned;
77
+ }
78
+ /** Calls waiting for a slot. */
79
+ get waiting() {
80
+ return this.#wait.length;
81
+ }
82
+ /** A slot: at once when one is free, else in turn (or the deadline passes, or the signal aborts,
83
+ * first). */
84
+ #enter(deadline, signal, call) {
85
+ if (this.#active < this.#limit) {
86
+ this.#active++;
87
+ return Promise.resolve();
88
+ }
89
+ return new Promise((resolve, reject) => {
90
+ const wait = call.child();
91
+ const settle = () => wait.close();
92
+ const give_up = (error) => {
93
+ waiter.gave_up = true;
94
+ settle();
95
+ const at = this.#wait.indexOf(waiter);
96
+ if (at !== -1) this.#wait.splice(at, 1);
97
+ reject(error);
98
+ };
99
+ const waiter = {
100
+ gave_up: false,
101
+ deadline,
102
+ enter: () => {
103
+ settle();
104
+ resolve();
105
+ }
106
+ };
107
+ if (deadline !== Infinity) wait.timeout(() => give_up(/* @__PURE__ */ new Error(WAIT_TIMEOUT)), timer_ms(deadline - Date.now()));
108
+ if (signal) wait.on(signal, "abort", () => give_up(signal.reason));
109
+ this.#wait.push(waiter);
110
+ });
111
+ }
112
+ /** A slot is given back: it goes straight to the next waiter still waiting, else it is free. (A
113
+ * waiter whose deadline has come is passed over even before its timer runs: handed a slot, it
114
+ * would only start a body nobody waits on.) */
115
+ #leave() {
116
+ const now = Date.now();
117
+ let next = this.#wait.shift();
118
+ while (next && (next.gave_up || next.deadline <= now)) next = this.#wait.shift();
119
+ if (next) next.enter();
120
+ else this.#active--;
121
+ }
26
122
  };
123
+ /** Whether `error` is a call's run timeout: its body ran past the deadline and was abandoned. */
124
+ function is_run_timeout(error) {
125
+ return error instanceof Error && error.message === RUN_TIMEOUT;
126
+ }
127
+ /** `work`, or the run timeout after `ms` (`on_timeout` first). The timer is the call's: it goes
128
+ * when the call settles. */
129
+ function within(call, work, ms, on_timeout) {
130
+ return new Promise((resolve, reject) => {
131
+ call.timeout(() => {
132
+ on_timeout();
133
+ reject(/* @__PURE__ */ new Error(RUN_TIMEOUT));
134
+ }, timer_ms(ms));
135
+ work.then(resolve, reject);
136
+ });
137
+ }
138
+ /** A delay a timer can hold: a deadline already past is now, and one past the longest a timer
139
+ * holds (2^31 - 1 ms) waits that long. */
140
+ function timer_ms(ms) {
141
+ return Math.min(2147483647, Math.max(0, ms));
142
+ }
27
143
  /** Max concurrent region SSR renders per process (CPU amp under valid MAC). */
28
144
  const REGION_RENDER_CONCURRENCY = 4;
29
- export { ConcurrencyGate, REGION_RENDER_CONCURRENCY };
145
+ export { ConcurrencyGate, REGION_RENDER_CONCURRENCY, is_run_timeout };
@@ -4,11 +4,13 @@ import { ClientPlugin } from "../plugin/client.js";
4
4
  * inlined `<style data-ogygia-region-css="href">`) it carries into `<head>` (deduped by href). A held / server-picked region's component was never
5
5
  * imported by the page, so its scoped CSS is in no stylesheet the page loaded; the region response
6
6
  * ships the links and the runtime lifts them to the head — where they load once and stick. (A link
7
- * left in the body would also fail to load inside a `<template>` batch parcel.)
7
+ * left in the body would also fail to load inside a `<template>` batch parcel.) `sheets`: the head
8
+ * nodes the answer uses, for the region that paints it (./region-sheets.ts `use_sheets`).
8
9
  */
9
10
  export declare function region_fragment(html: string): {
10
11
  frag: DocumentFragment;
11
12
  ready: Promise<void>;
13
+ sheets: readonly Element[];
12
14
  };
13
15
  /** TEST: the pristine server markup {@link region_fragment} stashed on a nested island, if any. */
14
16
  export declare function pristine_ssr_of(el: Element): string | undefined;