@async/framework 0.11.1 → 0.11.3
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/CHANGELOG.md +30 -0
- package/README.md +3 -1
- package/browser.js +264 -39
- package/browser.min.js +1 -1
- package/browser.ts +264 -39
- package/browser.umd.js +264 -39
- package/browser.umd.min.js +1 -1
- package/framework.ts +270 -40
- package/package.json +4 -3
- package/server.js +270 -40
package/CHANGELOG.md
CHANGED
|
@@ -1,9 +1,39 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 0.11.3 - 2026-06-18
|
|
4
|
+
|
|
5
|
+
- Isolated runtime-owned signal, async-signal, scheduler, request, and cache
|
|
6
|
+
state so each `createApp(...)` call materializes fresh mutable state from
|
|
7
|
+
reusable app declarations.
|
|
8
|
+
- Preserved reusable app declarations across runtime destroy/recreate cycles,
|
|
9
|
+
late `app.use(...)` adoption, server render repetition, and peer async-signal
|
|
10
|
+
subscribers.
|
|
11
|
+
- Added direct runtime-isolation regression coverage and regenerated the
|
|
12
|
+
published browser/server artifacts.
|
|
13
|
+
- Bundle size from bundled TypeScript source: `browser.ts` 179,469 B raw /
|
|
14
|
+
33,612 B gzip -> `browser.min.js` 76,458 B raw / 22,690 B gzip
|
|
15
|
+
(-103,011 B raw, -10,922 B gzip).
|
|
16
|
+
|
|
17
|
+
## 0.11.2 - 2026-06-18
|
|
18
|
+
|
|
19
|
+
- Published the post-`0.11.1` feedback-regression hardening now on `main`,
|
|
20
|
+
including scheduler scope revival, server error envelopes, async-signal SSR
|
|
21
|
+
snapshot restore, lazy component error handling, router prefetch context,
|
|
22
|
+
server proxy transport validation, and package export smoke coverage.
|
|
23
|
+
- Refreshed the generated Async Pipeline workflow and lock metadata to
|
|
24
|
+
`@async/pipeline` `0.9.1`.
|
|
25
|
+
- Ignored local `docs/goals/` GoalBuddy planning bundles.
|
|
26
|
+
|
|
3
27
|
## 0.11.1 - 2026-06-17
|
|
4
28
|
|
|
5
29
|
- Removed the literal old global fetch identifier from published release notes
|
|
6
30
|
so package-wide text scans stay focused on runtime artifacts.
|
|
31
|
+
- Hardened scheduler scope revival, server error envelopes, async-signal SSR
|
|
32
|
+
snapshot restore, lazy component sync-rendering errors, router prefetch
|
|
33
|
+
context, server proxy transport validation, and package export smoke tests.
|
|
34
|
+
- Bundle size from bundled TypeScript source: `browser.ts` 177,243 B raw /
|
|
35
|
+
33,354 B gzip -> `browser.min.js` 75,517 B raw / 22,516 B gzip
|
|
36
|
+
(-101,726 B raw, -10,838 B gzip).
|
|
7
37
|
|
|
8
38
|
## 0.11.0 - 2026-06-17
|
|
9
39
|
|
package/README.md
CHANGED
|
@@ -430,7 +430,9 @@ Singular registry keys are canonical: `signal`, `handler`, `server`,
|
|
|
430
430
|
### Registry Inspection
|
|
431
431
|
|
|
432
432
|
`Async.registry` is the global inspection surface for registered app pieces.
|
|
433
|
-
Every runtime
|
|
433
|
+
Every runtime owns fresh mutable signal and cache state materialized from the
|
|
434
|
+
app declaration store. Concrete registries inside one runtime share that
|
|
435
|
+
runtime's registry view:
|
|
434
436
|
|
|
435
437
|
```js
|
|
436
438
|
Async.registry.keys("signal");
|
package/browser.js
CHANGED
|
@@ -185,6 +185,28 @@ const __asyncSignalModule = (() => {
|
|
|
185
185
|
};
|
|
186
186
|
},
|
|
187
187
|
|
|
188
|
+
_cloneSignalDeclaration() {
|
|
189
|
+
return asyncSignal(id, fn);
|
|
190
|
+
},
|
|
191
|
+
|
|
192
|
+
_restore(snapshot = {}) {
|
|
193
|
+
if (!isAsyncSignalSnapshot(snapshot)) {
|
|
194
|
+
return state.set(snapshot);
|
|
195
|
+
}
|
|
196
|
+
if (activeAbort && !activeAbort.aborted) {
|
|
197
|
+
activeAbort.cancel(new Error(`Async signal "${registeredId}" restored from snapshot.`));
|
|
198
|
+
}
|
|
199
|
+
value = snapshot.value;
|
|
200
|
+
loading = Boolean(snapshot.loading);
|
|
201
|
+
error = snapshot.error ?? null;
|
|
202
|
+
status = typeof snapshot.status === "string" ? snapshot.status : inferStatus({ value, loading, error });
|
|
203
|
+
if (Number.isFinite(snapshot.version)) {
|
|
204
|
+
version = snapshot.version;
|
|
205
|
+
}
|
|
206
|
+
notify();
|
|
207
|
+
return state;
|
|
208
|
+
},
|
|
209
|
+
|
|
188
210
|
_bindRegistry(nextRegistry, nextId) {
|
|
189
211
|
registry = nextRegistry;
|
|
190
212
|
registeredId = nextId;
|
|
@@ -270,6 +292,27 @@ const __asyncSignalModule = (() => {
|
|
|
270
292
|
return Boolean(value?.[asyncSignalKind]);
|
|
271
293
|
}
|
|
272
294
|
|
|
295
|
+
function isAsyncSignalSnapshot(value) {
|
|
296
|
+
if (!value || typeof value !== "object" || Array.isArray(value)) {
|
|
297
|
+
return false;
|
|
298
|
+
}
|
|
299
|
+
return Object.hasOwn(value, "value")
|
|
300
|
+
&& (Object.hasOwn(value, "loading")
|
|
301
|
+
|| Object.hasOwn(value, "error")
|
|
302
|
+
|| Object.hasOwn(value, "status")
|
|
303
|
+
|| Object.hasOwn(value, "version"));
|
|
304
|
+
}
|
|
305
|
+
|
|
306
|
+
function inferStatus({ value, loading, error }) {
|
|
307
|
+
if (loading) {
|
|
308
|
+
return "loading";
|
|
309
|
+
}
|
|
310
|
+
if (error) {
|
|
311
|
+
return "error";
|
|
312
|
+
}
|
|
313
|
+
return value === undefined ? "idle" : "ready";
|
|
314
|
+
}
|
|
315
|
+
|
|
273
316
|
function attachCancel(signal, controller) {
|
|
274
317
|
Object.defineProperty(signal, "cancel", {
|
|
275
318
|
configurable: true,
|
|
@@ -917,7 +960,12 @@ const __cacheModule = (() => {
|
|
|
917
960
|
return registryStore.entries(`${type}.entries`);
|
|
918
961
|
},
|
|
919
962
|
|
|
920
|
-
_adoptMany() {
|
|
963
|
+
_adoptMany(map = {}) {
|
|
964
|
+
for (const [id, definition] of Object.entries(map ?? {})) {
|
|
965
|
+
if (!definitions.has(id)) {
|
|
966
|
+
registryApi.register(id, definition);
|
|
967
|
+
}
|
|
968
|
+
}
|
|
921
969
|
return registryApi;
|
|
922
970
|
}
|
|
923
971
|
}, registryStore, type);
|
|
@@ -1075,6 +1123,10 @@ const __signalsModule = (() => {
|
|
|
1075
1123
|
|
|
1076
1124
|
snapshot() {
|
|
1077
1125
|
return value;
|
|
1126
|
+
},
|
|
1127
|
+
|
|
1128
|
+
_cloneSignalDeclaration() {
|
|
1129
|
+
return createSignal(value);
|
|
1078
1130
|
}
|
|
1079
1131
|
};
|
|
1080
1132
|
|
|
@@ -1117,6 +1169,10 @@ const __signalsModule = (() => {
|
|
|
1117
1169
|
return backing.snapshot();
|
|
1118
1170
|
},
|
|
1119
1171
|
|
|
1172
|
+
_cloneSignalDeclaration() {
|
|
1173
|
+
return computed(fn);
|
|
1174
|
+
},
|
|
1175
|
+
|
|
1120
1176
|
_bindRegistry(registry, id) {
|
|
1121
1177
|
return registry.effect(() => {
|
|
1122
1178
|
backing.set(fn.call({
|
|
@@ -1141,6 +1197,9 @@ const __signalsModule = (() => {
|
|
|
1141
1197
|
[effectKind]: true,
|
|
1142
1198
|
kind: "effect",
|
|
1143
1199
|
fn,
|
|
1200
|
+
_cloneSignalDeclaration() {
|
|
1201
|
+
return effect(fn);
|
|
1202
|
+
},
|
|
1144
1203
|
_bindRegistry(registry) {
|
|
1145
1204
|
return registry.effect(fn);
|
|
1146
1205
|
}
|
|
@@ -1359,10 +1418,14 @@ const __signalsModule = (() => {
|
|
|
1359
1418
|
},
|
|
1360
1419
|
|
|
1361
1420
|
_adoptMany(map = {}) {
|
|
1362
|
-
for (const id of Object.
|
|
1363
|
-
if (entries.has(id)) {
|
|
1364
|
-
|
|
1421
|
+
for (const [id, signalLike] of Object.entries(map ?? {})) {
|
|
1422
|
+
if (!entries.has(id)) {
|
|
1423
|
+
const entry = cloneSignalDeclaration(signalLike);
|
|
1424
|
+
entries.set(id, entry);
|
|
1425
|
+
bindEntry(id, entry);
|
|
1426
|
+
continue;
|
|
1365
1427
|
}
|
|
1428
|
+
bindEntry(id, entries.get(id));
|
|
1366
1429
|
}
|
|
1367
1430
|
return registry;
|
|
1368
1431
|
}
|
|
@@ -1440,6 +1503,16 @@ const __signalsModule = (() => {
|
|
|
1440
1503
|
return createSignal(signalLike);
|
|
1441
1504
|
}
|
|
1442
1505
|
|
|
1506
|
+
function cloneSignalDeclaration(signalLike) {
|
|
1507
|
+
if (typeof signalLike?._cloneSignalDeclaration === "function") {
|
|
1508
|
+
return signalLike._cloneSignalDeclaration();
|
|
1509
|
+
}
|
|
1510
|
+
if (isSignalLike(signalLike)) {
|
|
1511
|
+
return createSignal(typeof signalLike.snapshot === "function" ? signalLike.snapshot() : signalLike.value);
|
|
1512
|
+
}
|
|
1513
|
+
return createSignal(signalLike);
|
|
1514
|
+
}
|
|
1515
|
+
|
|
1443
1516
|
function isSignalLike(value) {
|
|
1444
1517
|
return Boolean(value && typeof value === "object" && typeof value.subscribe === "function");
|
|
1445
1518
|
}
|
|
@@ -1618,7 +1691,7 @@ const __signalsModule = (() => {
|
|
|
1618
1691
|
frame.add(path);
|
|
1619
1692
|
}
|
|
1620
1693
|
}
|
|
1621
|
-
return { createSignal, computed, effect, createSignalRegistry, isSignalRef, signal };
|
|
1694
|
+
return { createSignal, computed, effect, createSignalRegistry, cloneSignalDeclaration, isSignalRef, signal };
|
|
1622
1695
|
})();
|
|
1623
1696
|
|
|
1624
1697
|
const __htmlModule = (() => {
|
|
@@ -1860,7 +1933,12 @@ const __componentModule = (() => {
|
|
|
1860
1933
|
return lazyComponents.get(id);
|
|
1861
1934
|
},
|
|
1862
1935
|
|
|
1863
|
-
_adoptMany() {
|
|
1936
|
+
_adoptMany(map = {}) {
|
|
1937
|
+
for (const [id, Component] of Object.entries(map ?? {})) {
|
|
1938
|
+
if (!entries.has(id)) {
|
|
1939
|
+
registry.register(id, Component);
|
|
1940
|
+
}
|
|
1941
|
+
}
|
|
1864
1942
|
return registry;
|
|
1865
1943
|
}
|
|
1866
1944
|
}, registryStore, type);
|
|
@@ -1908,12 +1986,16 @@ const __componentModule = (() => {
|
|
|
1908
1986
|
});
|
|
1909
1987
|
|
|
1910
1988
|
const output = Component.call(context, props);
|
|
1989
|
+
if (output && typeof output.then === "function") {
|
|
1990
|
+
throw new TypeError(`Component "${componentName(Component)}" returned a Promise. Async components are not supported by synchronous renderComponent(). Use an async partial or handler instead.`);
|
|
1991
|
+
}
|
|
1911
1992
|
const html = renderScopedTemplate(output);
|
|
1912
1993
|
|
|
1913
1994
|
return {
|
|
1914
1995
|
html,
|
|
1915
1996
|
attach(target) {
|
|
1916
|
-
for (
|
|
1997
|
+
for (let index = 0; index < attachHooks.length; index += 1) {
|
|
1998
|
+
const hook = attachHooks[index];
|
|
1917
1999
|
runtime.scheduler?.enqueue("lifecycle", () => {
|
|
1918
2000
|
const cleanup = hook(target);
|
|
1919
2001
|
if (typeof cleanup === "function") {
|
|
@@ -1921,7 +2003,7 @@ const __componentModule = (() => {
|
|
|
1921
2003
|
}
|
|
1922
2004
|
}, {
|
|
1923
2005
|
scope,
|
|
1924
|
-
key: `attach:${
|
|
2006
|
+
key: `attach:${index}`
|
|
1925
2007
|
}) ?? runAttachHook(hook, target);
|
|
1926
2008
|
}
|
|
1927
2009
|
},
|
|
@@ -1929,8 +2011,12 @@ const __componentModule = (() => {
|
|
|
1929
2011
|
this.attach(target);
|
|
1930
2012
|
},
|
|
1931
2013
|
visible(target, observeVisible) {
|
|
1932
|
-
|
|
1933
|
-
|
|
2014
|
+
if (visibleHooks.length === 0) {
|
|
2015
|
+
return;
|
|
2016
|
+
}
|
|
2017
|
+
const cleanup = observeVisible(target, () => {
|
|
2018
|
+
for (let index = 0; index < visibleHooks.length; index += 1) {
|
|
2019
|
+
const hook = visibleHooks[index];
|
|
1934
2020
|
runtime.scheduler?.enqueue("lifecycle", () => {
|
|
1935
2021
|
const hookCleanup = hook(target);
|
|
1936
2022
|
if (typeof hookCleanup === "function") {
|
|
@@ -1938,12 +2024,12 @@ const __componentModule = (() => {
|
|
|
1938
2024
|
}
|
|
1939
2025
|
}, {
|
|
1940
2026
|
scope,
|
|
1941
|
-
key: `visible:${
|
|
2027
|
+
key: `visible:${index}`
|
|
1942
2028
|
}) ?? runVisibleHook(hook, target);
|
|
1943
|
-
});
|
|
1944
|
-
if (typeof cleanup === "function") {
|
|
1945
|
-
cleanups.push(cleanup);
|
|
1946
2029
|
}
|
|
2030
|
+
});
|
|
2031
|
+
if (typeof cleanup === "function") {
|
|
2032
|
+
cleanups.push(cleanup);
|
|
1947
2033
|
}
|
|
1948
2034
|
},
|
|
1949
2035
|
cleanup() {
|
|
@@ -2199,11 +2285,12 @@ const __serverModule = (() => {
|
|
|
2199
2285
|
signal: context.abort
|
|
2200
2286
|
});
|
|
2201
2287
|
|
|
2288
|
+
assertTransportResponse(id, response);
|
|
2202
2289
|
if (!response.ok) {
|
|
2203
2290
|
throw new Error(`Server function "${id}" failed with ${response.status}.`);
|
|
2204
2291
|
}
|
|
2205
2292
|
|
|
2206
|
-
const result = await readServerResponse(response);
|
|
2293
|
+
const result = await readServerResponse(id, response);
|
|
2207
2294
|
await applyServerResult(result, runContext);
|
|
2208
2295
|
return markAppliedServerValue(unwrapServerResult(result));
|
|
2209
2296
|
}
|
|
@@ -2244,6 +2331,11 @@ const __serverModule = (() => {
|
|
|
2244
2331
|
return result;
|
|
2245
2332
|
}
|
|
2246
2333
|
|
|
2334
|
+
if (result.error) {
|
|
2335
|
+
markAppliedServerResult(result);
|
|
2336
|
+
throw toError(result.error);
|
|
2337
|
+
}
|
|
2338
|
+
|
|
2247
2339
|
if (result.signals && context.signals) {
|
|
2248
2340
|
for (const [path, value] of Object.entries(result.signals)) {
|
|
2249
2341
|
context.signals.set?.(path, value);
|
|
@@ -2262,15 +2354,7 @@ const __serverModule = (() => {
|
|
|
2262
2354
|
await context.router?.navigate?.(result.redirect);
|
|
2263
2355
|
}
|
|
2264
2356
|
|
|
2265
|
-
|
|
2266
|
-
throw toError(result.error);
|
|
2267
|
-
}
|
|
2268
|
-
|
|
2269
|
-
Object.defineProperty(result, appliedServerResult, {
|
|
2270
|
-
configurable: true,
|
|
2271
|
-
enumerable: false,
|
|
2272
|
-
value: true
|
|
2273
|
-
});
|
|
2357
|
+
markAppliedServerResult(result);
|
|
2274
2358
|
|
|
2275
2359
|
return result;
|
|
2276
2360
|
}
|
|
@@ -2289,6 +2373,15 @@ const __serverModule = (() => {
|
|
|
2289
2373
|
return value;
|
|
2290
2374
|
}
|
|
2291
2375
|
|
|
2376
|
+
function markAppliedServerResult(result) {
|
|
2377
|
+
Object.defineProperty(result, appliedServerResult, {
|
|
2378
|
+
configurable: true,
|
|
2379
|
+
enumerable: false,
|
|
2380
|
+
value: true
|
|
2381
|
+
});
|
|
2382
|
+
return result;
|
|
2383
|
+
}
|
|
2384
|
+
|
|
2292
2385
|
function defaultInput(context = {}) {
|
|
2293
2386
|
const form = findForm(context);
|
|
2294
2387
|
if (form) {
|
|
@@ -2366,10 +2459,37 @@ const __serverModule = (() => {
|
|
|
2366
2459
|
return namespace([]);
|
|
2367
2460
|
}
|
|
2368
2461
|
|
|
2369
|
-
|
|
2462
|
+
function assertTransportResponse(id, response) {
|
|
2463
|
+
if (!response || typeof response !== "object") {
|
|
2464
|
+
throw new Error(`Server function "${id}" transport returned an invalid response: expected a fetch Response-like object.`);
|
|
2465
|
+
}
|
|
2466
|
+
if (typeof response.ok !== "boolean") {
|
|
2467
|
+
throw new Error(`Server function "${id}" transport returned an invalid response: missing boolean ok.`);
|
|
2468
|
+
}
|
|
2469
|
+
if (!response.headers || typeof response.headers.get !== "function") {
|
|
2470
|
+
throw new Error(`Server function "${id}" transport returned an invalid response: missing headers.get(name).`);
|
|
2471
|
+
}
|
|
2472
|
+
}
|
|
2473
|
+
|
|
2474
|
+
async function readServerResponse(id, response) {
|
|
2475
|
+
if (response.status === 204) {
|
|
2476
|
+
return { value: undefined };
|
|
2477
|
+
}
|
|
2370
2478
|
const type = response.headers.get("content-type") ?? "";
|
|
2371
2479
|
if (type.includes("application/json")) {
|
|
2372
|
-
|
|
2480
|
+
if (typeof response.json !== "function") {
|
|
2481
|
+
throw new Error(`Server function "${id}" transport returned an invalid response: missing json().`);
|
|
2482
|
+
}
|
|
2483
|
+
try {
|
|
2484
|
+
return await response.json();
|
|
2485
|
+
} catch (cause) {
|
|
2486
|
+
throw new Error(`Server function "${id}" returned invalid JSON: ${errorMessage(cause)}`, {
|
|
2487
|
+
cause
|
|
2488
|
+
});
|
|
2489
|
+
}
|
|
2490
|
+
}
|
|
2491
|
+
if (typeof response.text !== "function") {
|
|
2492
|
+
throw new Error(`Server function "${id}" transport returned an invalid response: missing text().`);
|
|
2373
2493
|
}
|
|
2374
2494
|
return { value: await response.text() };
|
|
2375
2495
|
}
|
|
@@ -2482,6 +2602,9 @@ const __serverModule = (() => {
|
|
|
2482
2602
|
if (tag === "[object File]" || tag === "[object Blob]" || tag === "[object FormData]") {
|
|
2483
2603
|
throw new Error("Server proxy JSON transport does not support File, Blob, or FormData values yet.");
|
|
2484
2604
|
}
|
|
2605
|
+
if (isUnsupportedJsonTransportObject(value, tag)) {
|
|
2606
|
+
throw new Error("Server proxy JSON transport does not support URLSearchParams, Headers, Request, Response, ReadableStream, ArrayBuffer, or typed array values yet.");
|
|
2607
|
+
}
|
|
2485
2608
|
if (Array.isArray(value)) {
|
|
2486
2609
|
for (const item of value) {
|
|
2487
2610
|
assertJsonTransportable(item, stack);
|
|
@@ -2495,6 +2618,16 @@ const __serverModule = (() => {
|
|
|
2495
2618
|
stack.delete(value);
|
|
2496
2619
|
}
|
|
2497
2620
|
|
|
2621
|
+
function isUnsupportedJsonTransportObject(value, tag = Object.prototype.toString.call(value)) {
|
|
2622
|
+
return tag === "[object URLSearchParams]"
|
|
2623
|
+
|| tag === "[object Headers]"
|
|
2624
|
+
|| tag === "[object Request]"
|
|
2625
|
+
|| tag === "[object Response]"
|
|
2626
|
+
|| tag === "[object ReadableStream]"
|
|
2627
|
+
|| tag === "[object ArrayBuffer]"
|
|
2628
|
+
|| ArrayBuffer.isView(value);
|
|
2629
|
+
}
|
|
2630
|
+
|
|
2498
2631
|
function joinEndpoint(endpoint, id) {
|
|
2499
2632
|
return `${String(endpoint).replace(/\/$/, "")}/${encodeURIComponent(id)}`;
|
|
2500
2633
|
}
|
|
@@ -2516,6 +2649,10 @@ const __serverModule = (() => {
|
|
|
2516
2649
|
return new Error(String(value));
|
|
2517
2650
|
}
|
|
2518
2651
|
|
|
2652
|
+
function errorMessage(error) {
|
|
2653
|
+
return error instanceof Error ? error.message : String(error);
|
|
2654
|
+
}
|
|
2655
|
+
|
|
2519
2656
|
function assertServerId(id) {
|
|
2520
2657
|
if (typeof id !== "string" || id.length === 0) {
|
|
2521
2658
|
throw new TypeError("Server function id must be a non-empty string.");
|
|
@@ -2641,7 +2778,12 @@ const __handlersModule = (() => {
|
|
|
2641
2778
|
return results;
|
|
2642
2779
|
},
|
|
2643
2780
|
|
|
2644
|
-
_adoptMany() {
|
|
2781
|
+
_adoptMany(map = {}) {
|
|
2782
|
+
for (const [id, fn] of Object.entries(map ?? {})) {
|
|
2783
|
+
if (!handlers.has(id)) {
|
|
2784
|
+
registry.register(id, fn);
|
|
2785
|
+
}
|
|
2786
|
+
}
|
|
2645
2787
|
return registry;
|
|
2646
2788
|
}
|
|
2647
2789
|
}, registryStore, type);
|
|
@@ -2748,7 +2890,8 @@ const __schedulerModule = (() => {
|
|
|
2748
2890
|
const phases = [...(options.phases ?? defaultPhases)];
|
|
2749
2891
|
const queues = new Map(phases.map((phase) => [phase, []]));
|
|
2750
2892
|
const keyedJobs = new Map();
|
|
2751
|
-
const
|
|
2893
|
+
const destroyedObjectScopes = new WeakSet();
|
|
2894
|
+
const destroyedPrimitiveScopes = new Set();
|
|
2752
2895
|
const objectScopeIds = new WeakMap();
|
|
2753
2896
|
const onError = typeof options.onError === "function" ? options.onError : undefined;
|
|
2754
2897
|
const maxDepth = options.maxDepth ?? 100;
|
|
@@ -2796,7 +2939,7 @@ const __schedulerModule = (() => {
|
|
|
2796
2939
|
throw new TypeError("scheduler.enqueue(phase, fn) requires a function.");
|
|
2797
2940
|
}
|
|
2798
2941
|
const scope = options.scope;
|
|
2799
|
-
if (
|
|
2942
|
+
if (isScopeDestroyed(scope)) {
|
|
2800
2943
|
return noop;
|
|
2801
2944
|
}
|
|
2802
2945
|
|
|
@@ -2900,14 +3043,29 @@ const __schedulerModule = (() => {
|
|
|
2900
3043
|
|
|
2901
3044
|
markScopeDestroyed(scope) {
|
|
2902
3045
|
if (scope !== undefined) {
|
|
2903
|
-
|
|
3046
|
+
if (isObjectScope(scope)) {
|
|
3047
|
+
destroyedObjectScopes.add(scope);
|
|
3048
|
+
} else {
|
|
3049
|
+
destroyedPrimitiveScopes.add(scope);
|
|
3050
|
+
}
|
|
2904
3051
|
api.cancelScope(scope);
|
|
2905
3052
|
}
|
|
2906
3053
|
return api;
|
|
2907
3054
|
},
|
|
2908
3055
|
|
|
3056
|
+
reviveScope(scope) {
|
|
3057
|
+
if (scope !== undefined) {
|
|
3058
|
+
if (isObjectScope(scope)) {
|
|
3059
|
+
destroyedObjectScopes.delete(scope);
|
|
3060
|
+
} else {
|
|
3061
|
+
destroyedPrimitiveScopes.delete(scope);
|
|
3062
|
+
}
|
|
3063
|
+
}
|
|
3064
|
+
return api;
|
|
3065
|
+
},
|
|
3066
|
+
|
|
2909
3067
|
isScopeDestroyed(scope) {
|
|
2910
|
-
return
|
|
3068
|
+
return isScopeDestroyed(scope);
|
|
2911
3069
|
},
|
|
2912
3070
|
|
|
2913
3071
|
inspect() {
|
|
@@ -2919,7 +3077,7 @@ const __schedulerModule = (() => {
|
|
|
2919
3077
|
strategy,
|
|
2920
3078
|
phases: [...phases],
|
|
2921
3079
|
pending: counts,
|
|
2922
|
-
scopesDestroyed:
|
|
3080
|
+
scopesDestroyed: destroyedPrimitiveScopes.size,
|
|
2923
3081
|
flushing,
|
|
2924
3082
|
scheduled
|
|
2925
3083
|
};
|
|
@@ -2934,7 +3092,7 @@ const __schedulerModule = (() => {
|
|
|
2934
3092
|
queue.length = 0;
|
|
2935
3093
|
}
|
|
2936
3094
|
keyedJobs.clear();
|
|
2937
|
-
|
|
3095
|
+
destroyedPrimitiveScopes.clear();
|
|
2938
3096
|
}
|
|
2939
3097
|
};
|
|
2940
3098
|
|
|
@@ -2974,7 +3132,7 @@ const __schedulerModule = (() => {
|
|
|
2974
3132
|
if (job.key) {
|
|
2975
3133
|
keyedJobs.delete(job.key);
|
|
2976
3134
|
}
|
|
2977
|
-
if (job.canceled || (job.scope
|
|
3135
|
+
if (job.canceled || isScopeDestroyed(job.scope)) {
|
|
2978
3136
|
continue;
|
|
2979
3137
|
}
|
|
2980
3138
|
try {
|
|
@@ -3031,6 +3189,20 @@ const __schedulerModule = (() => {
|
|
|
3031
3189
|
}
|
|
3032
3190
|
return String(scope);
|
|
3033
3191
|
}
|
|
3192
|
+
|
|
3193
|
+
function isScopeDestroyed(scope) {
|
|
3194
|
+
if (scope === undefined) {
|
|
3195
|
+
return false;
|
|
3196
|
+
}
|
|
3197
|
+
if (isObjectScope(scope)) {
|
|
3198
|
+
return destroyedObjectScopes.has(scope);
|
|
3199
|
+
}
|
|
3200
|
+
return destroyedPrimitiveScopes.has(scope);
|
|
3201
|
+
}
|
|
3202
|
+
}
|
|
3203
|
+
|
|
3204
|
+
function isObjectScope(scope) {
|
|
3205
|
+
return (typeof scope === "object" && scope !== null) || typeof scope === "function";
|
|
3034
3206
|
}
|
|
3035
3207
|
|
|
3036
3208
|
function scheduleMicrotask(fn) {
|
|
@@ -3091,6 +3263,7 @@ const __loaderModule = (() => {
|
|
|
3091
3263
|
|
|
3092
3264
|
scan(rootOrFragment = rootNode) {
|
|
3093
3265
|
assertActive();
|
|
3266
|
+
reviveScopes(rootOrFragment);
|
|
3094
3267
|
bindSignalAttributes(rootOrFragment);
|
|
3095
3268
|
bindClassAttributes(rootOrFragment);
|
|
3096
3269
|
bindEventAttributes(rootOrFragment);
|
|
@@ -3594,6 +3767,12 @@ const __loaderModule = (() => {
|
|
|
3594
3767
|
}
|
|
3595
3768
|
}
|
|
3596
3769
|
|
|
3770
|
+
function reviveScopes(scope) {
|
|
3771
|
+
for (const element of elementsIn(scope)) {
|
|
3772
|
+
schedulerInstance.reviveScope?.(element);
|
|
3773
|
+
}
|
|
3774
|
+
}
|
|
3775
|
+
|
|
3597
3776
|
return api;
|
|
3598
3777
|
}
|
|
3599
3778
|
|
|
@@ -3893,7 +4072,12 @@ const __partialsModule = (() => {
|
|
|
3893
4072
|
return normalizePartialResult(result, partialContext);
|
|
3894
4073
|
},
|
|
3895
4074
|
|
|
3896
|
-
_adoptMany() {
|
|
4075
|
+
_adoptMany(map = {}) {
|
|
4076
|
+
for (const [id, fn] of Object.entries(map ?? {})) {
|
|
4077
|
+
if (!entries.has(id)) {
|
|
4078
|
+
registry.register(id, fn);
|
|
4079
|
+
}
|
|
4080
|
+
}
|
|
3897
4081
|
return registry;
|
|
3898
4082
|
}
|
|
3899
4083
|
}, registryStore, type);
|
|
@@ -4045,7 +4229,11 @@ const __routerModule = (() => {
|
|
|
4045
4229
|
},
|
|
4046
4230
|
|
|
4047
4231
|
_adoptMany(map = {}) {
|
|
4048
|
-
for (const pattern of Object.
|
|
4232
|
+
for (const [pattern, definition] of Object.entries(map ?? {})) {
|
|
4233
|
+
if (!entries.has(pattern)) {
|
|
4234
|
+
registry.register(pattern, definition);
|
|
4235
|
+
continue;
|
|
4236
|
+
}
|
|
4049
4237
|
adoptRoute(pattern, entries.get(pattern));
|
|
4050
4238
|
}
|
|
4051
4239
|
return registry;
|
|
@@ -4157,7 +4345,10 @@ const __routerModule = (() => {
|
|
|
4157
4345
|
}
|
|
4158
4346
|
const matched = api.match(url);
|
|
4159
4347
|
if (matched?.route?.partial && partials?.resolve?.(matched.route.partial)) {
|
|
4160
|
-
return partials.render(matched.route.partial, matched.params,
|
|
4348
|
+
return partials.render(matched.route.partial, matched.params, {
|
|
4349
|
+
...contextFor(matched),
|
|
4350
|
+
prefetch: true
|
|
4351
|
+
});
|
|
4161
4352
|
}
|
|
4162
4353
|
return Promise.resolve(null);
|
|
4163
4354
|
},
|
|
@@ -4538,7 +4729,7 @@ const __appModule = (() => {
|
|
|
4538
4729
|
const { createRouteRegistry, createRouter } = __routerModule;
|
|
4539
4730
|
const { createScheduler } = __schedulerModule;
|
|
4540
4731
|
const { createServerNamespace } = __serverModule;
|
|
4541
|
-
const { createSignal, createSignalRegistry } = __signalsModule;
|
|
4732
|
+
const { cloneSignalDeclaration, createSignal, createSignalRegistry } = __signalsModule;
|
|
4542
4733
|
const { createRegistryStore } = __registryStoreModule;
|
|
4543
4734
|
const { attributeName, normalizeAttributeConfig } = __attributesModule;
|
|
4544
4735
|
const { createLazyRegistry, defineRegistrySnapshot, sameRegistryValue } = __lazyRegistryModule;
|
|
@@ -4621,7 +4812,7 @@ const __appModule = (() => {
|
|
|
4621
4812
|
registryAssets: options.registryAssets,
|
|
4622
4813
|
importModule: options.importModule
|
|
4623
4814
|
});
|
|
4624
|
-
const registry = options.registry ?? app.registry
|
|
4815
|
+
const registry = options.registry ?? createRuntimeRegistry(app.registry, { target });
|
|
4625
4816
|
const signals = options.signals ?? createSignalRegistry(undefined, { registry, type: "signal", lazyRegistry });
|
|
4626
4817
|
const handlers = options.handlers ?? createHandlerRegistry(undefined, { registry, type: "handler", lazyRegistry });
|
|
4627
4818
|
const serverCache = createCacheRegistry(undefined, { registry, type: "cache.server" });
|
|
@@ -5002,6 +5193,22 @@ const __appModule = (() => {
|
|
|
5002
5193
|
registry?.registerMany?.(entries);
|
|
5003
5194
|
}
|
|
5004
5195
|
|
|
5196
|
+
function createRuntimeRegistry(appRegistry, { target } = {}) {
|
|
5197
|
+
const declarations = appRegistry.rawSnapshot();
|
|
5198
|
+
return createRegistryStore({
|
|
5199
|
+
...declarations,
|
|
5200
|
+
signal: cloneSignalDeclarations(declarations.signal)
|
|
5201
|
+
}, { target });
|
|
5202
|
+
}
|
|
5203
|
+
|
|
5204
|
+
function cloneSignalDeclarations(signals = {}) {
|
|
5205
|
+
const cloned = {};
|
|
5206
|
+
for (const [id, signalLike] of Object.entries(signals ?? {})) {
|
|
5207
|
+
cloned[id] = cloneSignalDeclaration(signalLike);
|
|
5208
|
+
}
|
|
5209
|
+
return cloned;
|
|
5210
|
+
}
|
|
5211
|
+
|
|
5005
5212
|
function emptyDeclarations() {
|
|
5006
5213
|
return {
|
|
5007
5214
|
signal: {},
|
|
@@ -5193,6 +5400,13 @@ const __appModule = (() => {
|
|
|
5193
5400
|
function setOrRegisterSignal(signals, path, value) {
|
|
5194
5401
|
const id = String(path).split(".")[0];
|
|
5195
5402
|
if (signals.has?.(id)) {
|
|
5403
|
+
if (path === id) {
|
|
5404
|
+
const entry = signals._entry?.(id);
|
|
5405
|
+
if (typeof entry?._restore === "function" && isAsyncSignalSnapshot(value)) {
|
|
5406
|
+
entry._restore(value);
|
|
5407
|
+
return;
|
|
5408
|
+
}
|
|
5409
|
+
}
|
|
5196
5410
|
signals.set(path, value);
|
|
5197
5411
|
return;
|
|
5198
5412
|
}
|
|
@@ -5202,6 +5416,17 @@ const __appModule = (() => {
|
|
|
5202
5416
|
}
|
|
5203
5417
|
}
|
|
5204
5418
|
|
|
5419
|
+
function isAsyncSignalSnapshot(value) {
|
|
5420
|
+
if (!value || typeof value !== "object" || Array.isArray(value)) {
|
|
5421
|
+
return false;
|
|
5422
|
+
}
|
|
5423
|
+
return Object.hasOwn(value, "value")
|
|
5424
|
+
&& (Object.hasOwn(value, "loading")
|
|
5425
|
+
|| Object.hasOwn(value, "error")
|
|
5426
|
+
|| Object.hasOwn(value, "status")
|
|
5427
|
+
|| Object.hasOwn(value, "version"));
|
|
5428
|
+
}
|
|
5429
|
+
|
|
5205
5430
|
function attachServerCache(server, cache) {
|
|
5206
5431
|
try {
|
|
5207
5432
|
server.cache = cache;
|