@ogygia/core 0.12.2 → 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.
- package/dist/LateIsland.svelte +3 -2
- package/dist/LateIslandAwait.svelte +6 -2
- package/dist/Region.svelte +22 -33
- package/dist/boundary.d.ts +0 -2
- package/dist/boundary.js +8 -6
- package/dist/compiler/debarrel/barrel.d.ts +15 -8
- package/dist/compiler/debarrel/barrel.js +92 -45
- package/dist/compiler/debarrel/plugin.js +41 -17
- package/dist/compiler/dev/dev-hmr.d.ts +3 -0
- package/dist/compiler/dev/dev-hmr.js +3 -0
- package/dist/compiler/driver.js +11 -4
- package/dist/compiler/flags.js +21 -7
- package/dist/compiler/fouc-css.js +5 -1
- package/dist/compiler/kit.js +5 -1
- package/dist/compiler/link/build-output.js +12 -3
- package/dist/compiler/macros/bake.js +18 -4
- package/dist/compiler/macros/dollar.js +6 -1
- package/dist/compiler/macros/source.js +6 -1
- package/dist/compiler/macros/store.js +10 -2
- package/dist/compiler/macros/wire.js +6 -1
- package/dist/compiler/parse/scan.js +10 -3
- package/dist/compiler/region/transform.js +188 -74
- package/dist/context-bridge.js +13 -5
- package/dist/context.d.ts +9 -0
- package/dist/context.js +30 -1
- package/dist/document.d.ts +1 -1
- package/dist/document.js +7 -1
- package/dist/early-holes-head.d.ts +5 -0
- package/dist/early-holes-head.js +20 -0
- package/dist/early-holes.d.ts +34 -0
- package/dist/early-holes.js +51 -0
- package/dist/entry-hydrate.js +9 -12
- package/dist/events/bus.js +7 -2
- package/dist/events/schema.d.ts +2 -2
- package/dist/fn-transport.js +4 -3
- package/dist/hooks.js +94 -163
- package/dist/insights/page-assets.js +11 -3
- package/dist/insights/page-insights.d.ts +0 -2
- package/dist/insights/page-insights.js +14 -10
- package/dist/insights/session-insights.js +2 -2
- package/dist/internal-instruments.d.ts +3 -1
- package/dist/internal-instruments.js +3 -1
- package/dist/internal-server.d.ts +3 -2
- package/dist/internal-server.js +3 -2
- package/dist/internal.d.ts +1 -2
- package/dist/internal.js +1 -2
- package/dist/keep-fallback.d.ts +0 -2
- package/dist/keep-fallback.js +4 -5
- package/dist/live-transport.js +3 -2
- package/dist/messages/build.d.ts +585 -0
- package/dist/messages/build.js +800 -0
- package/dist/messages/core.d.ts +464 -0
- package/dist/messages/core.js +843 -0
- package/dist/messages/define.d.ts +62 -0
- package/dist/messages/define.js +49 -0
- package/dist/messages/index.d.ts +6 -0
- package/dist/messages/index.js +6 -0
- package/dist/messages/island.d.ts +4 -0
- package/dist/messages/island.js +34 -0
- package/dist/messages/lazy.d.ts +3 -0
- package/dist/messages/lazy.js +22 -0
- package/dist/messages/prose.d.ts +15 -0
- package/dist/messages/prose.js +43 -0
- package/dist/messages/server.d.ts +142 -0
- package/dist/messages/server.js +246 -0
- package/dist/nested.d.ts +3 -0
- package/dist/nested.js +8 -1
- package/dist/plugin/css.js +14 -13
- package/dist/plugin/facts.d.ts +2 -0
- package/dist/plugin/facts.js +10 -6
- package/dist/plugin/hooks.d.ts +7 -17
- package/dist/plugin/hooks.js +32 -4
- package/dist/plugin/index.d.ts +9 -2
- package/dist/plugin/request-scope.d.ts +20 -0
- package/dist/plugin/request-scope.js +149 -0
- package/dist/plugin/server.d.ts +20 -2
- package/dist/plugin/server.js +98 -28
- package/dist/plugin/testing.d.ts +6 -0
- package/dist/plugin/testing.js +14 -2
- package/dist/policies.d.ts +21 -0
- package/dist/policies.js +66 -0
- package/dist/preference.js +6 -1
- package/dist/preload.js +6 -9
- package/dist/ref-watch.d.ts +0 -10
- package/dist/ref-watch.js +14 -1
- package/dist/ref.js +17 -5
- package/dist/region-snippet.js +9 -3
- package/dist/region.js +2 -1
- package/dist/report-thrown.d.ts +9 -0
- package/dist/report-thrown.js +15 -0
- package/dist/rules.d.ts +17 -0
- package/dist/rules.js +57 -0
- package/dist/runtime/beacon.d.ts +0 -4
- package/dist/runtime/beacon.js +58 -43
- package/dist/runtime/boot-link.js +19 -2
- package/dist/runtime/client-hooks.js +2 -1
- package/dist/runtime/concurrency.d.ts +16 -5
- package/dist/runtime/concurrency.js +123 -7
- package/dist/runtime/core.d.ts +3 -1
- package/dist/runtime/core.js +718 -384
- package/dist/runtime/devalue-lane.d.ts +13 -0
- package/dist/runtime/devalue-lane.js +49 -0
- package/dist/runtime/disclose-version.d.ts +1 -0
- package/dist/runtime/disclose-version.js +14 -0
- package/dist/runtime/early-holes.d.ts +4 -0
- package/dist/runtime/early-holes.js +40 -0
- package/dist/runtime/entry-locations.js +40 -49
- package/dist/runtime/foreign-props.d.ts +0 -7
- package/dist/runtime/foreign-props.js +2 -1
- package/dist/runtime/form-continuity.d.ts +2 -2
- package/dist/runtime/form-continuity.js +30 -8
- package/dist/runtime/frame-nav.d.ts +7 -1
- package/dist/runtime/frame-nav.js +84 -18
- package/dist/runtime/frame-store.d.ts +25 -16
- package/dist/runtime/frame-store.js +124 -98
- package/dist/runtime/frames.js +8 -4
- package/dist/runtime/hole-facts.js +6 -7
- package/dist/runtime/hole-fetch.d.ts +17 -0
- package/dist/runtime/hole-fetch.js +47 -0
- package/dist/runtime/hydrate-core.d.ts +4 -4
- package/dist/runtime/hydrate-core.js +80 -64
- package/dist/runtime/import-again.d.ts +33 -0
- package/dist/runtime/import-again.js +217 -0
- package/dist/runtime/interaction-replay.d.ts +5 -3
- package/dist/runtime/interaction-replay.js +6 -6
- package/dist/runtime/interaction.d.ts +14 -3
- package/dist/runtime/interaction.js +46 -23
- package/dist/runtime/kit-page-thread.svelte.d.ts +2 -1
- package/dist/runtime/kit-page-thread.svelte.js +44 -20
- package/dist/runtime/lakes.d.ts +1 -1
- package/dist/runtime/lakes.js +18 -5
- package/dist/runtime/live.d.ts +1 -2
- package/dist/runtime/live.js +6 -8
- package/dist/runtime/load-scheduler.d.ts +29 -18
- package/dist/runtime/load-scheduler.js +236 -136
- package/dist/runtime/nav-handle.js +25 -6
- package/dist/runtime/navigation.d.ts +24 -0
- package/dist/runtime/navigation.js +24 -0
- package/dist/runtime/ownership.d.ts +1 -1
- package/dist/runtime/page-defer.js +3 -3
- package/dist/runtime/parse-html.d.ts +15 -4
- package/dist/runtime/parse-html.js +24 -5
- package/dist/runtime/pushable-props.svelte.d.ts +21 -0
- package/dist/runtime/pushable-props.svelte.js +37 -0
- package/dist/runtime/region-endpoint-url.js +4 -6
- package/dist/runtime/region-machines.d.ts +111 -0
- package/dist/runtime/region-machines.js +97 -0
- package/dist/runtime/region-sheets.d.ts +31 -0
- package/dist/runtime/region-sheets.js +49 -0
- package/dist/runtime/restore-report.d.ts +1 -0
- package/dist/runtime/restore-report.js +36 -0
- package/dist/runtime/restore.d.ts +5 -2
- package/dist/runtime/restore.js +33 -14
- package/dist/runtime/router-nav.d.ts +32 -12
- package/dist/runtime/router-nav.js +320 -228
- package/dist/runtime/router.d.ts +83 -19
- package/dist/runtime/router.js +297 -129
- package/dist/runtime/rules.d.ts +35 -0
- package/dist/runtime/rules.js +137 -0
- package/dist/runtime/schedule.d.ts +6 -3
- package/dist/runtime/schedule.js +172 -57
- package/dist/runtime/seeds.d.ts +5 -1
- package/dist/runtime/seeds.js +11 -5
- package/dist/runtime/session.d.ts +46 -7
- package/dist/runtime/session.js +78 -10
- package/dist/runtime/slots.d.ts +53 -20
- package/dist/runtime/slots.js +2 -3
- package/dist/runtime/soft-refresh.d.ts +16 -0
- package/dist/runtime/soft-refresh.js +14 -0
- package/dist/runtime/svelte-warnings.d.ts +4 -10
- package/dist/runtime/svelte-warnings.js +7 -4
- package/dist/runtime/wire-classes.js +21 -8
- package/dist/runtime/wire-format.js +6 -3
- package/dist/script.js +8 -7
- package/dist/seed-ref-reviver.d.ts +0 -9
- package/dist/seed-ref-reviver.js +2 -1
- package/dist/seed-refs.d.ts +46 -36
- package/dist/seed-refs.js +131 -92
- package/dist/server/document-tail.d.ts +6 -0
- package/dist/server/document-tail.js +7 -1
- package/dist/server/early-holes-csp.d.ts +14 -0
- package/dist/server/early-holes-csp.js +73 -0
- package/dist/server/page-facts.d.ts +4 -1
- package/dist/server/page-facts.js +4 -1
- package/dist/server/page-seed.d.ts +2 -2
- package/dist/server/page-seed.js +104 -11
- package/dist/server/page-stream.d.ts +14 -1
- package/dist/server/page-stream.js +119 -2
- package/dist/server/personal-response.d.ts +0 -5
- package/dist/server/personal-response.js +6 -2
- package/dist/server/props-wire.js +5 -1
- package/dist/server/region-endpoint.js +10 -2
- package/dist/server/render-cache.d.ts +24 -20
- package/dist/server/render-cache.js +99 -40
- package/dist/server/render-page.js +46 -15
- package/dist/server/request-stats.d.ts +10 -8
- package/dist/server/request-stats.js +20 -12
- package/dist/server/rules.d.ts +11 -0
- package/dist/server/rules.js +64 -0
- package/dist/server/signing-key.js +31 -18
- package/dist/server/stream-regions.d.ts +14 -1
- package/dist/server/stream-regions.js +38 -2
- package/dist/shared-state.js +5 -1
- package/dist/shims/app-navigation.js +3 -2
- package/dist/shims/page-store.svelte.js +16 -2
- package/dist/source.js +7 -2
- package/dist/store-transport.js +12 -5
- package/dist/transport.js +3 -2
- package/dist/vite/index.js +83 -74
- package/dist/vite/kit-dirs.js +7 -1
- package/dist/vite/options.d.ts +2 -1
- package/dist/vite/options.js +11 -20
- package/dist/vite/package-files.js +13 -3
- package/dist/vite/paths.d.ts +2 -0
- package/dist/vite/paths.js +4 -4
- package/dist/vite/plugin-api.d.ts +6 -5
- package/dist/vite/plugin-api.js +42 -14
- package/dist/vite/style-preprocess.js +10 -3
- package/package.json +8 -1
- package/dist/KeepHost.svelte +0 -19
- package/dist/KeepHost.svelte.d.ts +0 -10
- package/dist/LiveHost.svelte +0 -19
- package/dist/LiveHost.svelte.d.ts +0 -10
- package/dist/NestedProvider.svelte +0 -13
- package/dist/NestedProvider.svelte.d.ts +0 -8
- package/dist/runtime/page-cache.d.ts +0 -23
- package/dist/runtime/page-cache.js +0 -74
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
import { Rules } from "../rules.js";
|
|
2
|
+
import { warn } from "../messages/server.js";
|
|
3
|
+
import { observe } from "@ogygia/machine";
|
|
4
|
+
// src/server/rules.ts
|
|
5
|
+
/**
|
|
6
|
+
* THE SERVER'S RULES (#313, ../rules.ts): what is always true of the server, checked a task after
|
|
7
|
+
* each response ends (in dev, and in a build made with `OGYGIA_RULES=1`), printed with its code.
|
|
8
|
+
*
|
|
9
|
+
* - `rule_request_scope_open`: a request's scope (its timers, streams, fetches) is closed once its
|
|
10
|
+
* response has ended.
|
|
11
|
+
* - `rule_flight_kept_failure`: no flight keeps a failure: an answer kept is never an error.
|
|
12
|
+
*
|
|
13
|
+
* Each area tells this module what it holds (`note_response_end`) only when rules are on: every call
|
|
14
|
+
* site folds out of a build without them.
|
|
15
|
+
*/
|
|
16
|
+
/** The server's rules. */
|
|
17
|
+
const server_rules = /* @__PURE__ */ new Rules();
|
|
18
|
+
/** Request scopes whose response has ended, until a check sees them closed. */
|
|
19
|
+
const ended = /* @__PURE__ */ new Set();
|
|
20
|
+
/** A response ended (its body read to the end, cancelled, or none): its request's scope must be
|
|
21
|
+
* closed by the time the next check runs. */
|
|
22
|
+
function note_response_end(owner) {
|
|
23
|
+
if (!installed) return;
|
|
24
|
+
ended.add(owner);
|
|
25
|
+
check_soon();
|
|
26
|
+
}
|
|
27
|
+
function request_scopes_closed() {
|
|
28
|
+
let open = 0;
|
|
29
|
+
for (const owner of ended) if (owner.closed) ended.delete(owner);
|
|
30
|
+
else open++;
|
|
31
|
+
return open === 0 ? null : `${open} request scope(s) still open after their response ended`;
|
|
32
|
+
}
|
|
33
|
+
/** The flights' entries that keep an error as their answer now, each with what it keeps. An entry
|
|
34
|
+
* leaves when it moves on (dropped, or a fresh answer kept): the rule is about what is kept now, so
|
|
35
|
+
* a check (a simulated run, the next response in dev) sees its own breaks, not an earlier one's. */
|
|
36
|
+
const kept_failures = /* @__PURE__ */ new Map();
|
|
37
|
+
function no_kept_failure() {
|
|
38
|
+
if (kept_failures.size === 0) return null;
|
|
39
|
+
return [...kept_failures.values()].slice(0, 10).join("; ");
|
|
40
|
+
}
|
|
41
|
+
let installed = false;
|
|
42
|
+
let pending = false;
|
|
43
|
+
/** Checks every rule a task from now (once, however many responses ask), and says what broke. */
|
|
44
|
+
function check_soon() {
|
|
45
|
+
if (pending) return;
|
|
46
|
+
pending = true;
|
|
47
|
+
setTimeout(() => {
|
|
48
|
+
pending = false;
|
|
49
|
+
server_rules.say((code, detail) => warn(code, { detail }));
|
|
50
|
+
}, 0);
|
|
51
|
+
}
|
|
52
|
+
/** Rules on: checked after each response, and what broke is said with its code. */
|
|
53
|
+
function install_server_rules() {
|
|
54
|
+
if (installed) return;
|
|
55
|
+
installed = true;
|
|
56
|
+
server_rules.add("rule_request_scope_open", request_scopes_closed);
|
|
57
|
+
server_rules.add("rule_flight_kept_failure", no_kept_failure);
|
|
58
|
+
observe((name, _from, to, machine) => {
|
|
59
|
+
const answer = to?.kind === "kept" ? to.answer : void 0;
|
|
60
|
+
if (answer instanceof Error) kept_failures.set(machine, `"${name}" kept ${answer.name}: ${answer.message.slice(0, 120)}`);
|
|
61
|
+
else if (kept_failures.size !== 0) kept_failures.delete(machine);
|
|
62
|
+
});
|
|
63
|
+
}
|
|
64
|
+
export { install_server_rules, note_response_end, server_rules };
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { OgygiaError, warn } from "../messages/server.js";
|
|
1
2
|
import { buildHadSecret, buildKey } from "virtual:ogygia/secret";
|
|
2
3
|
import { sign } from "virtual:ogygia/sign";
|
|
3
4
|
import { building } from "$app/env";
|
|
@@ -24,23 +25,27 @@ const SOURCE_NAME = {
|
|
|
24
25
|
env: "OGYGIA_SECRET",
|
|
25
26
|
build: "this build's random key"
|
|
26
27
|
};
|
|
28
|
+
const slots = globalThis;
|
|
27
29
|
function slot() {
|
|
28
|
-
|
|
29
|
-
return g[SLOT] ??= {};
|
|
30
|
+
return slots[SLOT] ?? { kind: "undecided" };
|
|
30
31
|
}
|
|
31
32
|
function signing_key() {
|
|
32
33
|
const s = slot();
|
|
33
|
-
if (s.
|
|
34
|
+
if (s.kind === "decided") return s.key;
|
|
34
35
|
const from_env = typeof process !== "undefined" && process.env?.OGYGIA_SECRET || "";
|
|
35
|
-
const [secret, source] = s.
|
|
36
|
-
|
|
36
|
+
const [secret, source] = s.kind === "secret" ? [s.option, "option"] : from_env ? [from_env, "env"] : [buildKey, "build"];
|
|
37
|
+
const key = {
|
|
37
38
|
secret,
|
|
38
39
|
stable: source !== "build",
|
|
39
40
|
fp: key_fingerprint(secret),
|
|
40
41
|
source
|
|
41
42
|
};
|
|
42
|
-
|
|
43
|
-
|
|
43
|
+
slots[SLOT] = {
|
|
44
|
+
kind: "decided",
|
|
45
|
+
key
|
|
46
|
+
};
|
|
47
|
+
if (!key.stable && !import.meta.env.DEV) warn_build_key();
|
|
48
|
+
return key;
|
|
44
49
|
}
|
|
45
50
|
/**
|
|
46
51
|
* Record the app's `handle({ secret })`. A blank one counts as none (an app can pass a value that may
|
|
@@ -50,15 +55,23 @@ function signing_key() {
|
|
|
50
55
|
function configure_signing_secret(secret) {
|
|
51
56
|
if (!secret?.trim()) return;
|
|
52
57
|
const s = slot();
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
58
|
+
if (s.kind === "undecided") {
|
|
59
|
+
slots[SLOT] = {
|
|
60
|
+
kind: "secret",
|
|
61
|
+
option: secret
|
|
62
|
+
};
|
|
56
63
|
return;
|
|
57
64
|
}
|
|
58
|
-
const
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
65
|
+
const decided = s.kind === "decided" ? s.key.secret : s.option;
|
|
66
|
+
if (decided === secret) return;
|
|
67
|
+
const from = s.kind === "decided" ? `${SOURCE_NAME[s.key.source]}, decided by an earlier mint or verify` : "another handle({ secret })";
|
|
68
|
+
const error = new OgygiaError("secret_conflict", {
|
|
69
|
+
key: key_fingerprint(secret),
|
|
70
|
+
decided: key_fingerprint(decided),
|
|
71
|
+
from
|
|
72
|
+
});
|
|
73
|
+
if (import.meta.env.DEV) throw error;
|
|
74
|
+
console.error(error);
|
|
62
75
|
}
|
|
63
76
|
function key_fingerprint(secret) {
|
|
64
77
|
return sign(secret, "ogygia:key-fp").slice(0, 8);
|
|
@@ -70,12 +83,12 @@ function warn_build_key() {
|
|
|
70
83
|
const K = Symbol.for("ogygia.build-key-warned");
|
|
71
84
|
if (g[K]) return;
|
|
72
85
|
g[K] = true;
|
|
73
|
-
if (building)
|
|
74
|
-
else if (buildHadSecret) console.error(
|
|
75
|
-
else
|
|
86
|
+
if (building) warn("build_key_prerender");
|
|
87
|
+
else if (buildHadSecret) console.error(new OgygiaError("secret_missing_at_runtime"));
|
|
88
|
+
else warn("secret_missing");
|
|
76
89
|
}
|
|
77
90
|
/** Tests: forget the decided key and the app's secret. */
|
|
78
91
|
function reset_signing_key() {
|
|
79
|
-
delete
|
|
92
|
+
delete slots[SLOT];
|
|
80
93
|
}
|
|
81
94
|
export { configure_signing_secret, key_fingerprint, reset_signing_key, signing_key };
|
|
@@ -1,5 +1,18 @@
|
|
|
1
|
+
import { Scope } from "@ogygia/machine";
|
|
1
2
|
/** Build a parcel `<template data-ogygia-slot="…">…rendered html…</template>` (length-framed when
|
|
2
3
|
* the html carries a `</template` of its own). */
|
|
3
4
|
export declare function build_parcel(slot: string, html: string): string;
|
|
4
5
|
/** The done-sentinel parcel (empty template) the client watches to end the batch. */
|
|
5
|
-
export declare function done_parcel(): string;
|
|
6
|
+
export declare function done_parcel(): string;
|
|
7
|
+
/** One region call's answer in a batch: its slot (the capability signature) and its HTML. Null:
|
|
8
|
+
* the call is left out (the client fetches it on its own). */
|
|
9
|
+
export type BatchAnswer = {
|
|
10
|
+
slot: string;
|
|
11
|
+
html: string;
|
|
12
|
+
} | null;
|
|
13
|
+
/**
|
|
14
|
+
* The batch's frame stream: every call renders at once, and each answer goes out as its parcel the
|
|
15
|
+
* moment it settles, whatever the order; the done sentinel ends it. `render` is handed the batch's
|
|
16
|
+
* signal: it aborts when the stream is cancelled, or when `owner` (the request's) ends first.
|
|
17
|
+
*/
|
|
18
|
+
export declare function batch_stream(calls: readonly string[], render: (endpoint: string, signal: AbortSignal) => Promise<BatchAnswer>, owner?: Scope): ReadableStream<Uint8Array>;
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { STALE, machine } from "@ogygia/machine";
|
|
1
2
|
// src/server/stream-regions.ts
|
|
2
3
|
/**
|
|
3
4
|
* Region parcels for the batch endpoint (single-flight navigation, a page's first-load holes, OOO).
|
|
@@ -11,7 +12,7 @@
|
|
|
11
12
|
* decoded string counts in — so its content can never close the box or forge a parcel for another
|
|
12
13
|
* slot, and it no longer falls back to a second request.
|
|
13
14
|
*
|
|
14
|
-
*
|
|
15
|
+
* No I/O and no Kit (the batch stream is handed its render), so it stays unit-testable.
|
|
15
16
|
*/
|
|
16
17
|
/** Sentinel slot appended once a batch finishes, so waiting regions know it is complete. */
|
|
17
18
|
const STREAM_DONE_SLOT = "__ogygia_done__";
|
|
@@ -33,4 +34,39 @@ function build_parcel(slot, html) {
|
|
|
33
34
|
function done_parcel() {
|
|
34
35
|
return `<template data-ogygia-slot="${STREAM_DONE_SLOT}"></template>`;
|
|
35
36
|
}
|
|
36
|
-
|
|
37
|
+
const batch_def = machine()({
|
|
38
|
+
name: "batch stream",
|
|
39
|
+
initial: "streaming",
|
|
40
|
+
steps: {
|
|
41
|
+
streaming: ["ended", "cancelled"],
|
|
42
|
+
ended: [],
|
|
43
|
+
cancelled: []
|
|
44
|
+
}
|
|
45
|
+
});
|
|
46
|
+
/**
|
|
47
|
+
* The batch's frame stream: every call renders at once, and each answer goes out as its parcel the
|
|
48
|
+
* moment it settles, whatever the order; the done sentinel ends it. `render` is handed the batch's
|
|
49
|
+
* signal: it aborts when the stream is cancelled, or when `owner` (the request's) ends first.
|
|
50
|
+
*/
|
|
51
|
+
function batch_stream(calls, render, owner) {
|
|
52
|
+
const encoder = new TextEncoder();
|
|
53
|
+
const batch = batch_def.create();
|
|
54
|
+
owner?.defer(() => {
|
|
55
|
+
batch.move("streaming", "cancelled");
|
|
56
|
+
});
|
|
57
|
+
return new ReadableStream({
|
|
58
|
+
async start(controller) {
|
|
59
|
+
const streaming = batch.now;
|
|
60
|
+
if (await batch.scope.task((signal) => Promise.all(calls.map(async (endpoint) => {
|
|
61
|
+
const out = await render(endpoint, signal).catch(() => null);
|
|
62
|
+
if (out && batch.now === streaming) controller.enqueue(encoder.encode(build_parcel(out.slot, out.html)));
|
|
63
|
+
}))) === STALE || !batch.move("streaming", "ended")) return;
|
|
64
|
+
controller.enqueue(encoder.encode(done_parcel()));
|
|
65
|
+
controller.close();
|
|
66
|
+
},
|
|
67
|
+
cancel() {
|
|
68
|
+
batch.move("streaming", "cancelled");
|
|
69
|
+
}
|
|
70
|
+
});
|
|
71
|
+
}
|
|
72
|
+
export { batch_stream, build_parcel, done_parcel };
|
package/dist/shared-state.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { OgygiaError } from "./messages/island.js";
|
|
1
2
|
import { parse, stringify } from "devalue";
|
|
2
3
|
import { createSubscriber } from "svelte/reactivity";
|
|
3
4
|
// src/shared-state.ts
|
|
@@ -46,7 +47,10 @@ function snapshot(name, value) {
|
|
|
46
47
|
try {
|
|
47
48
|
return parse(stringify(value));
|
|
48
49
|
} catch (e) {
|
|
49
|
-
throw new
|
|
50
|
+
throw new OgygiaError("shared_state_not_plain", {
|
|
51
|
+
name,
|
|
52
|
+
reason: e instanceof Error ? e.message : String(e)
|
|
53
|
+
});
|
|
50
54
|
}
|
|
51
55
|
}
|
|
52
56
|
var SharedState = class {
|
|
@@ -1,14 +1,15 @@
|
|
|
1
1
|
import { kit_bridge } from "./kit-bridge.js";
|
|
2
2
|
import { refresh_remote_instances } from "./kit-remote/remote-cache.js";
|
|
3
3
|
import { bind_to_component } from "../runtime/nav-hooks.js";
|
|
4
|
+
import { OgygiaError } from "../messages/island.js";
|
|
4
5
|
// src/shims/app-navigation.ts
|
|
5
6
|
const kit = () => kit_bridge()?.navigation ?? null;
|
|
6
7
|
const og = () => globalThis[Symbol.for("ogygia.nav")] ?? null;
|
|
7
8
|
/** No runtime on this document at all (neither Kit's nor ogygia's): the browser navigates. */
|
|
8
9
|
function browser_goto(url, opts = {}) {
|
|
9
10
|
const target = new URL(url, location.href);
|
|
10
|
-
if (target.protocol !== "http:" && target.protocol !== "https:") throw new
|
|
11
|
-
if (target.origin !== location.origin && !opts.external) throw new
|
|
11
|
+
if (target.protocol !== "http:" && target.protocol !== "https:") throw new OgygiaError("goto_not_http");
|
|
12
|
+
if (target.origin !== location.origin && !opts.external) throw new OgygiaError("goto_cross_origin");
|
|
12
13
|
if (opts.replaceState) location.replace(target.href);
|
|
13
14
|
else location.assign(target.href);
|
|
14
15
|
return Promise.resolve();
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { foreign_hydrate } from "../current-region.js";
|
|
2
|
+
import { warn } from "../messages/island.js";
|
|
2
3
|
// src/shims/page-store.svelte.ts
|
|
3
4
|
const FALLBACK = {
|
|
4
5
|
url: typeof location !== "undefined" ? new URL(location.href) : new URL("http://localhost/"),
|
|
@@ -32,7 +33,9 @@ var PageState = class {
|
|
|
32
33
|
this.state = s.state ?? {};
|
|
33
34
|
for (const fn of this.#subscribers) try {
|
|
34
35
|
fn();
|
|
35
|
-
} catch {
|
|
36
|
+
} catch (error) {
|
|
37
|
+
report_thrown(error);
|
|
38
|
+
}
|
|
36
39
|
}
|
|
37
40
|
reset() {
|
|
38
41
|
this.set({
|
|
@@ -51,6 +54,13 @@ var PageState = class {
|
|
|
51
54
|
return () => this.#subscribers.delete(fn);
|
|
52
55
|
}
|
|
53
56
|
};
|
|
57
|
+
/** report-thrown.ts's `report_thrown`, here in full: island-side code never imports a module the
|
|
58
|
+
* runtime's boot imports (runtime-boot-svelte-free.test.ts), and the boot's ref watchers use it. */
|
|
59
|
+
function report_thrown(error) {
|
|
60
|
+
const report = globalThis.reportError;
|
|
61
|
+
if (typeof report === "function") report(error);
|
|
62
|
+
else console.error(error);
|
|
63
|
+
}
|
|
54
64
|
const PAGE_STATE_KEY = Symbol.for("ogygia.page-state");
|
|
55
65
|
const global_scope = globalThis;
|
|
56
66
|
const page_state = global_scope[PAGE_STATE_KEY] ??= new PageState();
|
|
@@ -72,6 +82,10 @@ function warn_foreign_page_read(expr) {
|
|
|
72
82
|
const f = foreign_hydrate();
|
|
73
83
|
if (!f || warned_foreign_entries.has(f.entry)) return;
|
|
74
84
|
warned_foreign_entries.add(f.entry);
|
|
75
|
-
|
|
85
|
+
warn("foreign_page_read", {
|
|
86
|
+
expr,
|
|
87
|
+
entry: f.entry,
|
|
88
|
+
origin: f.origin
|
|
89
|
+
});
|
|
76
90
|
}
|
|
77
91
|
export { PageState, page_state, reset_page, set_page, subscribe_page, warn_foreign_page_read };
|
package/dist/source.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { fnv1a } from "./runtime/hash.js";
|
|
2
|
+
import { report_thrown } from "./report-thrown.js";
|
|
2
3
|
// src/source.ts
|
|
3
4
|
/**
|
|
4
5
|
* DATA SOURCES — `import.meta.og.source(fn)`, the RUNTIME half (the compiler rewrites the macro to
|
|
@@ -29,10 +30,14 @@ function set_source_observer(fn) {
|
|
|
29
30
|
function record_source_read(tag) {
|
|
30
31
|
try {
|
|
31
32
|
slots.recorder?.(tag);
|
|
32
|
-
} catch {
|
|
33
|
+
} catch (error) {
|
|
34
|
+
report_thrown(error);
|
|
35
|
+
}
|
|
33
36
|
try {
|
|
34
37
|
slots.observer?.(tag);
|
|
35
|
-
} catch {
|
|
38
|
+
} catch (error) {
|
|
39
|
+
report_thrown(error);
|
|
40
|
+
}
|
|
36
41
|
}
|
|
37
42
|
/** The identity stamp — read by `postrender.invalidate(fn, args)`. */
|
|
38
43
|
const SOURCE_ID = Symbol.for("ogygia.source.id");
|
package/dist/store-transport.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { wire } from "./live-transport.js";
|
|
2
2
|
import { mint, register_kind, resolve } from "./ref.js";
|
|
3
|
+
import { OgygiaError, warn } from "./messages/island.js";
|
|
3
4
|
import { derived, get, writable } from "svelte/store";
|
|
4
5
|
// src/store-transport.ts
|
|
5
6
|
/**
|
|
@@ -81,7 +82,7 @@ function mark_store(store, tag) {
|
|
|
81
82
|
enumerable: false
|
|
82
83
|
});
|
|
83
84
|
} catch {
|
|
84
|
-
if (typeof console !== "undefined")
|
|
85
|
+
if (typeof console !== "undefined") warn("store_not_extensible", { tag });
|
|
85
86
|
}
|
|
86
87
|
return store;
|
|
87
88
|
}
|
|
@@ -100,12 +101,15 @@ function register_store_kind() {
|
|
|
100
101
|
const t = ref.t ?? GENERIC_TAG;
|
|
101
102
|
const factory = t === GENERIC_TAG ? void 0 : store_registry().factories.get(t);
|
|
102
103
|
if (t !== GENERIC_TAG && factory === void 0) {
|
|
103
|
-
if (typeof console !== "undefined")
|
|
104
|
+
if (typeof console !== "undefined") warn("store_factory_missing", { tag: t });
|
|
104
105
|
return writable(ref.d);
|
|
105
106
|
}
|
|
106
107
|
const built = factory ? factory(ref.d) : writable(ref.d);
|
|
107
108
|
if (built === null || typeof built !== "object") {
|
|
108
|
-
if (typeof console !== "undefined")
|
|
109
|
+
if (typeof console !== "undefined") warn("store_factory_bad_rebuild", {
|
|
110
|
+
tag: t,
|
|
111
|
+
got: type_of(built)
|
|
112
|
+
});
|
|
109
113
|
return writable(ref.d);
|
|
110
114
|
}
|
|
111
115
|
return built;
|
|
@@ -160,7 +164,10 @@ function __og_store(tag, factory) {
|
|
|
160
164
|
if (product === null || typeof product !== "object") {
|
|
161
165
|
if (!warned_unbranded.has(tag) && typeof console !== "undefined") {
|
|
162
166
|
warned_unbranded.add(tag);
|
|
163
|
-
|
|
167
|
+
warn("store_factory_unbranded", {
|
|
168
|
+
tag,
|
|
169
|
+
got: type_of(product)
|
|
170
|
+
});
|
|
164
171
|
}
|
|
165
172
|
return product;
|
|
166
173
|
}
|
|
@@ -221,7 +228,7 @@ function register_derived_kind() {
|
|
|
221
228
|
},
|
|
222
229
|
decode(ref) {
|
|
223
230
|
const d = ref.d;
|
|
224
|
-
if (typeof d.f !== "function") throw new
|
|
231
|
+
if (typeof d.f !== "function") throw new OgygiaError("og_derived_formula_missing");
|
|
225
232
|
return og_derived(d.single ? d.s[0] : d.s, d.f, d.seed);
|
|
226
233
|
}
|
|
227
234
|
});
|
package/dist/transport.js
CHANGED
|
@@ -6,6 +6,7 @@ import { register_wire_kind } from "./live-transport.js";
|
|
|
6
6
|
import { register_derived_kind, register_store_kind } from "./store-transport.js";
|
|
7
7
|
import { register_snippet_kind } from "./region-snippet.js";
|
|
8
8
|
import { register_fn_kind } from "./fn-transport.js";
|
|
9
|
+
import { OgygiaError } from "./messages/island.js";
|
|
9
10
|
// src/transport.ts
|
|
10
11
|
/**
|
|
11
12
|
* `ogygiaTransport` — the SvelteKit `transport` entry that lets a held region cross the wire.
|
|
@@ -38,7 +39,7 @@ function encode_region(value) {
|
|
|
38
39
|
return pack(f.id, props, sign(f.id, props), f.module, f.hydrate, f.hydrateMargin, f.html);
|
|
39
40
|
}
|
|
40
41
|
if (typeof f.html === "string") return pack("", f.props ?? {}, "", "", void 0, void 0, f.html);
|
|
41
|
-
throw new
|
|
42
|
+
throw new OgygiaError("held_region_plain_import");
|
|
42
43
|
}
|
|
43
44
|
}
|
|
44
45
|
/** The region DECODE law (single-flight frame write for baked HTML + deferred rebuild),
|
|
@@ -88,7 +89,7 @@ function register_region_kind() {
|
|
|
88
89
|
},
|
|
89
90
|
encode(value) {
|
|
90
91
|
const packed = encode_region(value);
|
|
91
|
-
if (packed === false) throw new
|
|
92
|
+
if (packed === false) throw new OgygiaError("region_kind_mismatch");
|
|
92
93
|
return { d: packed };
|
|
93
94
|
},
|
|
94
95
|
decode(ref) {
|