@async/framework 0.11.1 → 0.11.2
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 +16 -0
- package/browser.js +184 -28
- package/browser.min.js +1 -1
- package/browser.ts +184 -28
- package/browser.umd.js +184 -28
- package/browser.umd.min.js +1 -1
- package/framework.ts +184 -28
- package/package.json +4 -3
- package/server.js +184 -28
package/server.js
CHANGED
|
@@ -187,6 +187,24 @@ const __asyncSignalModule = (() => {
|
|
|
187
187
|
};
|
|
188
188
|
},
|
|
189
189
|
|
|
190
|
+
_restore(snapshot = {}) {
|
|
191
|
+
if (!isAsyncSignalSnapshot(snapshot)) {
|
|
192
|
+
return state.set(snapshot);
|
|
193
|
+
}
|
|
194
|
+
if (activeAbort && !activeAbort.aborted) {
|
|
195
|
+
activeAbort.cancel(new Error(`Async signal "${registeredId}" restored from snapshot.`));
|
|
196
|
+
}
|
|
197
|
+
value = snapshot.value;
|
|
198
|
+
loading = Boolean(snapshot.loading);
|
|
199
|
+
error = snapshot.error ?? null;
|
|
200
|
+
status = typeof snapshot.status === "string" ? snapshot.status : inferStatus({ value, loading, error });
|
|
201
|
+
if (Number.isFinite(snapshot.version)) {
|
|
202
|
+
version = snapshot.version;
|
|
203
|
+
}
|
|
204
|
+
notify();
|
|
205
|
+
return state;
|
|
206
|
+
},
|
|
207
|
+
|
|
190
208
|
_bindRegistry(nextRegistry, nextId) {
|
|
191
209
|
registry = nextRegistry;
|
|
192
210
|
registeredId = nextId;
|
|
@@ -272,6 +290,27 @@ const __asyncSignalModule = (() => {
|
|
|
272
290
|
return Boolean(value?.[asyncSignalKind]);
|
|
273
291
|
}
|
|
274
292
|
|
|
293
|
+
function isAsyncSignalSnapshot(value) {
|
|
294
|
+
if (!value || typeof value !== "object" || Array.isArray(value)) {
|
|
295
|
+
return false;
|
|
296
|
+
}
|
|
297
|
+
return Object.hasOwn(value, "value")
|
|
298
|
+
&& (Object.hasOwn(value, "loading")
|
|
299
|
+
|| Object.hasOwn(value, "error")
|
|
300
|
+
|| Object.hasOwn(value, "status")
|
|
301
|
+
|| Object.hasOwn(value, "version"));
|
|
302
|
+
}
|
|
303
|
+
|
|
304
|
+
function inferStatus({ value, loading, error }) {
|
|
305
|
+
if (loading) {
|
|
306
|
+
return "loading";
|
|
307
|
+
}
|
|
308
|
+
if (error) {
|
|
309
|
+
return "error";
|
|
310
|
+
}
|
|
311
|
+
return value === undefined ? "idle" : "ready";
|
|
312
|
+
}
|
|
313
|
+
|
|
275
314
|
function attachCancel(signal, controller) {
|
|
276
315
|
Object.defineProperty(signal, "cancel", {
|
|
277
316
|
configurable: true,
|
|
@@ -1910,12 +1949,16 @@ const __componentModule = (() => {
|
|
|
1910
1949
|
});
|
|
1911
1950
|
|
|
1912
1951
|
const output = Component.call(context, props);
|
|
1952
|
+
if (output && typeof output.then === "function") {
|
|
1953
|
+
throw new TypeError(`Component "${componentName(Component)}" returned a Promise. Async components are not supported by synchronous renderComponent(). Use an async partial or handler instead.`);
|
|
1954
|
+
}
|
|
1913
1955
|
const html = renderScopedTemplate(output);
|
|
1914
1956
|
|
|
1915
1957
|
return {
|
|
1916
1958
|
html,
|
|
1917
1959
|
attach(target) {
|
|
1918
|
-
for (
|
|
1960
|
+
for (let index = 0; index < attachHooks.length; index += 1) {
|
|
1961
|
+
const hook = attachHooks[index];
|
|
1919
1962
|
runtime.scheduler?.enqueue("lifecycle", () => {
|
|
1920
1963
|
const cleanup = hook(target);
|
|
1921
1964
|
if (typeof cleanup === "function") {
|
|
@@ -1923,7 +1966,7 @@ const __componentModule = (() => {
|
|
|
1923
1966
|
}
|
|
1924
1967
|
}, {
|
|
1925
1968
|
scope,
|
|
1926
|
-
key: `attach:${
|
|
1969
|
+
key: `attach:${index}`
|
|
1927
1970
|
}) ?? runAttachHook(hook, target);
|
|
1928
1971
|
}
|
|
1929
1972
|
},
|
|
@@ -1931,8 +1974,12 @@ const __componentModule = (() => {
|
|
|
1931
1974
|
this.attach(target);
|
|
1932
1975
|
},
|
|
1933
1976
|
visible(target, observeVisible) {
|
|
1934
|
-
|
|
1935
|
-
|
|
1977
|
+
if (visibleHooks.length === 0) {
|
|
1978
|
+
return;
|
|
1979
|
+
}
|
|
1980
|
+
const cleanup = observeVisible(target, () => {
|
|
1981
|
+
for (let index = 0; index < visibleHooks.length; index += 1) {
|
|
1982
|
+
const hook = visibleHooks[index];
|
|
1936
1983
|
runtime.scheduler?.enqueue("lifecycle", () => {
|
|
1937
1984
|
const hookCleanup = hook(target);
|
|
1938
1985
|
if (typeof hookCleanup === "function") {
|
|
@@ -1940,12 +1987,12 @@ const __componentModule = (() => {
|
|
|
1940
1987
|
}
|
|
1941
1988
|
}, {
|
|
1942
1989
|
scope,
|
|
1943
|
-
key: `visible:${
|
|
1990
|
+
key: `visible:${index}`
|
|
1944
1991
|
}) ?? runVisibleHook(hook, target);
|
|
1945
|
-
});
|
|
1946
|
-
if (typeof cleanup === "function") {
|
|
1947
|
-
cleanups.push(cleanup);
|
|
1948
1992
|
}
|
|
1993
|
+
});
|
|
1994
|
+
if (typeof cleanup === "function") {
|
|
1995
|
+
cleanups.push(cleanup);
|
|
1949
1996
|
}
|
|
1950
1997
|
},
|
|
1951
1998
|
cleanup() {
|
|
@@ -2201,11 +2248,12 @@ const __serverModule = (() => {
|
|
|
2201
2248
|
signal: context.abort
|
|
2202
2249
|
});
|
|
2203
2250
|
|
|
2251
|
+
assertTransportResponse(id, response);
|
|
2204
2252
|
if (!response.ok) {
|
|
2205
2253
|
throw new Error(`Server function "${id}" failed with ${response.status}.`);
|
|
2206
2254
|
}
|
|
2207
2255
|
|
|
2208
|
-
const result = await readServerResponse(response);
|
|
2256
|
+
const result = await readServerResponse(id, response);
|
|
2209
2257
|
await applyServerResult(result, runContext);
|
|
2210
2258
|
return markAppliedServerValue(unwrapServerResult(result));
|
|
2211
2259
|
}
|
|
@@ -2246,6 +2294,11 @@ const __serverModule = (() => {
|
|
|
2246
2294
|
return result;
|
|
2247
2295
|
}
|
|
2248
2296
|
|
|
2297
|
+
if (result.error) {
|
|
2298
|
+
markAppliedServerResult(result);
|
|
2299
|
+
throw toError(result.error);
|
|
2300
|
+
}
|
|
2301
|
+
|
|
2249
2302
|
if (result.signals && context.signals) {
|
|
2250
2303
|
for (const [path, value] of Object.entries(result.signals)) {
|
|
2251
2304
|
context.signals.set?.(path, value);
|
|
@@ -2264,15 +2317,7 @@ const __serverModule = (() => {
|
|
|
2264
2317
|
await context.router?.navigate?.(result.redirect);
|
|
2265
2318
|
}
|
|
2266
2319
|
|
|
2267
|
-
|
|
2268
|
-
throw toError(result.error);
|
|
2269
|
-
}
|
|
2270
|
-
|
|
2271
|
-
Object.defineProperty(result, appliedServerResult, {
|
|
2272
|
-
configurable: true,
|
|
2273
|
-
enumerable: false,
|
|
2274
|
-
value: true
|
|
2275
|
-
});
|
|
2320
|
+
markAppliedServerResult(result);
|
|
2276
2321
|
|
|
2277
2322
|
return result;
|
|
2278
2323
|
}
|
|
@@ -2291,6 +2336,15 @@ const __serverModule = (() => {
|
|
|
2291
2336
|
return value;
|
|
2292
2337
|
}
|
|
2293
2338
|
|
|
2339
|
+
function markAppliedServerResult(result) {
|
|
2340
|
+
Object.defineProperty(result, appliedServerResult, {
|
|
2341
|
+
configurable: true,
|
|
2342
|
+
enumerable: false,
|
|
2343
|
+
value: true
|
|
2344
|
+
});
|
|
2345
|
+
return result;
|
|
2346
|
+
}
|
|
2347
|
+
|
|
2294
2348
|
function defaultInput(context = {}) {
|
|
2295
2349
|
const form = findForm(context);
|
|
2296
2350
|
if (form) {
|
|
@@ -2368,10 +2422,37 @@ const __serverModule = (() => {
|
|
|
2368
2422
|
return namespace([]);
|
|
2369
2423
|
}
|
|
2370
2424
|
|
|
2371
|
-
|
|
2425
|
+
function assertTransportResponse(id, response) {
|
|
2426
|
+
if (!response || typeof response !== "object") {
|
|
2427
|
+
throw new Error(`Server function "${id}" transport returned an invalid response: expected a fetch Response-like object.`);
|
|
2428
|
+
}
|
|
2429
|
+
if (typeof response.ok !== "boolean") {
|
|
2430
|
+
throw new Error(`Server function "${id}" transport returned an invalid response: missing boolean ok.`);
|
|
2431
|
+
}
|
|
2432
|
+
if (!response.headers || typeof response.headers.get !== "function") {
|
|
2433
|
+
throw new Error(`Server function "${id}" transport returned an invalid response: missing headers.get(name).`);
|
|
2434
|
+
}
|
|
2435
|
+
}
|
|
2436
|
+
|
|
2437
|
+
async function readServerResponse(id, response) {
|
|
2438
|
+
if (response.status === 204) {
|
|
2439
|
+
return { value: undefined };
|
|
2440
|
+
}
|
|
2372
2441
|
const type = response.headers.get("content-type") ?? "";
|
|
2373
2442
|
if (type.includes("application/json")) {
|
|
2374
|
-
|
|
2443
|
+
if (typeof response.json !== "function") {
|
|
2444
|
+
throw new Error(`Server function "${id}" transport returned an invalid response: missing json().`);
|
|
2445
|
+
}
|
|
2446
|
+
try {
|
|
2447
|
+
return await response.json();
|
|
2448
|
+
} catch (cause) {
|
|
2449
|
+
throw new Error(`Server function "${id}" returned invalid JSON: ${errorMessage(cause)}`, {
|
|
2450
|
+
cause
|
|
2451
|
+
});
|
|
2452
|
+
}
|
|
2453
|
+
}
|
|
2454
|
+
if (typeof response.text !== "function") {
|
|
2455
|
+
throw new Error(`Server function "${id}" transport returned an invalid response: missing text().`);
|
|
2375
2456
|
}
|
|
2376
2457
|
return { value: await response.text() };
|
|
2377
2458
|
}
|
|
@@ -2484,6 +2565,9 @@ const __serverModule = (() => {
|
|
|
2484
2565
|
if (tag === "[object File]" || tag === "[object Blob]" || tag === "[object FormData]") {
|
|
2485
2566
|
throw new Error("Server proxy JSON transport does not support File, Blob, or FormData values yet.");
|
|
2486
2567
|
}
|
|
2568
|
+
if (isUnsupportedJsonTransportObject(value, tag)) {
|
|
2569
|
+
throw new Error("Server proxy JSON transport does not support URLSearchParams, Headers, Request, Response, ReadableStream, ArrayBuffer, or typed array values yet.");
|
|
2570
|
+
}
|
|
2487
2571
|
if (Array.isArray(value)) {
|
|
2488
2572
|
for (const item of value) {
|
|
2489
2573
|
assertJsonTransportable(item, stack);
|
|
@@ -2497,6 +2581,16 @@ const __serverModule = (() => {
|
|
|
2497
2581
|
stack.delete(value);
|
|
2498
2582
|
}
|
|
2499
2583
|
|
|
2584
|
+
function isUnsupportedJsonTransportObject(value, tag = Object.prototype.toString.call(value)) {
|
|
2585
|
+
return tag === "[object URLSearchParams]"
|
|
2586
|
+
|| tag === "[object Headers]"
|
|
2587
|
+
|| tag === "[object Request]"
|
|
2588
|
+
|| tag === "[object Response]"
|
|
2589
|
+
|| tag === "[object ReadableStream]"
|
|
2590
|
+
|| tag === "[object ArrayBuffer]"
|
|
2591
|
+
|| ArrayBuffer.isView(value);
|
|
2592
|
+
}
|
|
2593
|
+
|
|
2500
2594
|
function joinEndpoint(endpoint, id) {
|
|
2501
2595
|
return `${String(endpoint).replace(/\/$/, "")}/${encodeURIComponent(id)}`;
|
|
2502
2596
|
}
|
|
@@ -2518,6 +2612,10 @@ const __serverModule = (() => {
|
|
|
2518
2612
|
return new Error(String(value));
|
|
2519
2613
|
}
|
|
2520
2614
|
|
|
2615
|
+
function errorMessage(error) {
|
|
2616
|
+
return error instanceof Error ? error.message : String(error);
|
|
2617
|
+
}
|
|
2618
|
+
|
|
2521
2619
|
function assertServerId(id) {
|
|
2522
2620
|
if (typeof id !== "string" || id.length === 0) {
|
|
2523
2621
|
throw new TypeError("Server function id must be a non-empty string.");
|
|
@@ -2750,7 +2848,8 @@ const __schedulerModule = (() => {
|
|
|
2750
2848
|
const phases = [...(options.phases ?? defaultPhases)];
|
|
2751
2849
|
const queues = new Map(phases.map((phase) => [phase, []]));
|
|
2752
2850
|
const keyedJobs = new Map();
|
|
2753
|
-
const
|
|
2851
|
+
const destroyedObjectScopes = new WeakSet();
|
|
2852
|
+
const destroyedPrimitiveScopes = new Set();
|
|
2754
2853
|
const objectScopeIds = new WeakMap();
|
|
2755
2854
|
const onError = typeof options.onError === "function" ? options.onError : undefined;
|
|
2756
2855
|
const maxDepth = options.maxDepth ?? 100;
|
|
@@ -2798,7 +2897,7 @@ const __schedulerModule = (() => {
|
|
|
2798
2897
|
throw new TypeError("scheduler.enqueue(phase, fn) requires a function.");
|
|
2799
2898
|
}
|
|
2800
2899
|
const scope = options.scope;
|
|
2801
|
-
if (
|
|
2900
|
+
if (isScopeDestroyed(scope)) {
|
|
2802
2901
|
return noop;
|
|
2803
2902
|
}
|
|
2804
2903
|
|
|
@@ -2902,14 +3001,29 @@ const __schedulerModule = (() => {
|
|
|
2902
3001
|
|
|
2903
3002
|
markScopeDestroyed(scope) {
|
|
2904
3003
|
if (scope !== undefined) {
|
|
2905
|
-
|
|
3004
|
+
if (isObjectScope(scope)) {
|
|
3005
|
+
destroyedObjectScopes.add(scope);
|
|
3006
|
+
} else {
|
|
3007
|
+
destroyedPrimitiveScopes.add(scope);
|
|
3008
|
+
}
|
|
2906
3009
|
api.cancelScope(scope);
|
|
2907
3010
|
}
|
|
2908
3011
|
return api;
|
|
2909
3012
|
},
|
|
2910
3013
|
|
|
3014
|
+
reviveScope(scope) {
|
|
3015
|
+
if (scope !== undefined) {
|
|
3016
|
+
if (isObjectScope(scope)) {
|
|
3017
|
+
destroyedObjectScopes.delete(scope);
|
|
3018
|
+
} else {
|
|
3019
|
+
destroyedPrimitiveScopes.delete(scope);
|
|
3020
|
+
}
|
|
3021
|
+
}
|
|
3022
|
+
return api;
|
|
3023
|
+
},
|
|
3024
|
+
|
|
2911
3025
|
isScopeDestroyed(scope) {
|
|
2912
|
-
return
|
|
3026
|
+
return isScopeDestroyed(scope);
|
|
2913
3027
|
},
|
|
2914
3028
|
|
|
2915
3029
|
inspect() {
|
|
@@ -2921,7 +3035,7 @@ const __schedulerModule = (() => {
|
|
|
2921
3035
|
strategy,
|
|
2922
3036
|
phases: [...phases],
|
|
2923
3037
|
pending: counts,
|
|
2924
|
-
scopesDestroyed:
|
|
3038
|
+
scopesDestroyed: destroyedPrimitiveScopes.size,
|
|
2925
3039
|
flushing,
|
|
2926
3040
|
scheduled
|
|
2927
3041
|
};
|
|
@@ -2936,7 +3050,7 @@ const __schedulerModule = (() => {
|
|
|
2936
3050
|
queue.length = 0;
|
|
2937
3051
|
}
|
|
2938
3052
|
keyedJobs.clear();
|
|
2939
|
-
|
|
3053
|
+
destroyedPrimitiveScopes.clear();
|
|
2940
3054
|
}
|
|
2941
3055
|
};
|
|
2942
3056
|
|
|
@@ -2976,7 +3090,7 @@ const __schedulerModule = (() => {
|
|
|
2976
3090
|
if (job.key) {
|
|
2977
3091
|
keyedJobs.delete(job.key);
|
|
2978
3092
|
}
|
|
2979
|
-
if (job.canceled || (job.scope
|
|
3093
|
+
if (job.canceled || isScopeDestroyed(job.scope)) {
|
|
2980
3094
|
continue;
|
|
2981
3095
|
}
|
|
2982
3096
|
try {
|
|
@@ -3033,6 +3147,20 @@ const __schedulerModule = (() => {
|
|
|
3033
3147
|
}
|
|
3034
3148
|
return String(scope);
|
|
3035
3149
|
}
|
|
3150
|
+
|
|
3151
|
+
function isScopeDestroyed(scope) {
|
|
3152
|
+
if (scope === undefined) {
|
|
3153
|
+
return false;
|
|
3154
|
+
}
|
|
3155
|
+
if (isObjectScope(scope)) {
|
|
3156
|
+
return destroyedObjectScopes.has(scope);
|
|
3157
|
+
}
|
|
3158
|
+
return destroyedPrimitiveScopes.has(scope);
|
|
3159
|
+
}
|
|
3160
|
+
}
|
|
3161
|
+
|
|
3162
|
+
function isObjectScope(scope) {
|
|
3163
|
+
return (typeof scope === "object" && scope !== null) || typeof scope === "function";
|
|
3036
3164
|
}
|
|
3037
3165
|
|
|
3038
3166
|
function scheduleMicrotask(fn) {
|
|
@@ -3093,6 +3221,7 @@ const __loaderModule = (() => {
|
|
|
3093
3221
|
|
|
3094
3222
|
scan(rootOrFragment = rootNode) {
|
|
3095
3223
|
assertActive();
|
|
3224
|
+
reviveScopes(rootOrFragment);
|
|
3096
3225
|
bindSignalAttributes(rootOrFragment);
|
|
3097
3226
|
bindClassAttributes(rootOrFragment);
|
|
3098
3227
|
bindEventAttributes(rootOrFragment);
|
|
@@ -3596,6 +3725,12 @@ const __loaderModule = (() => {
|
|
|
3596
3725
|
}
|
|
3597
3726
|
}
|
|
3598
3727
|
|
|
3728
|
+
function reviveScopes(scope) {
|
|
3729
|
+
for (const element of elementsIn(scope)) {
|
|
3730
|
+
schedulerInstance.reviveScope?.(element);
|
|
3731
|
+
}
|
|
3732
|
+
}
|
|
3733
|
+
|
|
3599
3734
|
return api;
|
|
3600
3735
|
}
|
|
3601
3736
|
|
|
@@ -4159,7 +4294,10 @@ const __routerModule = (() => {
|
|
|
4159
4294
|
}
|
|
4160
4295
|
const matched = api.match(url);
|
|
4161
4296
|
if (matched?.route?.partial && partials?.resolve?.(matched.route.partial)) {
|
|
4162
|
-
return partials.render(matched.route.partial, matched.params,
|
|
4297
|
+
return partials.render(matched.route.partial, matched.params, {
|
|
4298
|
+
...contextFor(matched),
|
|
4299
|
+
prefetch: true
|
|
4300
|
+
});
|
|
4163
4301
|
}
|
|
4164
4302
|
return Promise.resolve(null);
|
|
4165
4303
|
},
|
|
@@ -5195,6 +5333,13 @@ const __appModule = (() => {
|
|
|
5195
5333
|
function setOrRegisterSignal(signals, path, value) {
|
|
5196
5334
|
const id = String(path).split(".")[0];
|
|
5197
5335
|
if (signals.has?.(id)) {
|
|
5336
|
+
if (path === id) {
|
|
5337
|
+
const entry = signals._entry?.(id);
|
|
5338
|
+
if (typeof entry?._restore === "function" && isAsyncSignalSnapshot(value)) {
|
|
5339
|
+
entry._restore(value);
|
|
5340
|
+
return;
|
|
5341
|
+
}
|
|
5342
|
+
}
|
|
5198
5343
|
signals.set(path, value);
|
|
5199
5344
|
return;
|
|
5200
5345
|
}
|
|
@@ -5204,6 +5349,17 @@ const __appModule = (() => {
|
|
|
5204
5349
|
}
|
|
5205
5350
|
}
|
|
5206
5351
|
|
|
5352
|
+
function isAsyncSignalSnapshot(value) {
|
|
5353
|
+
if (!value || typeof value !== "object" || Array.isArray(value)) {
|
|
5354
|
+
return false;
|
|
5355
|
+
}
|
|
5356
|
+
return Object.hasOwn(value, "value")
|
|
5357
|
+
&& (Object.hasOwn(value, "loading")
|
|
5358
|
+
|| Object.hasOwn(value, "error")
|
|
5359
|
+
|| Object.hasOwn(value, "status")
|
|
5360
|
+
|| Object.hasOwn(value, "version"));
|
|
5361
|
+
}
|
|
5362
|
+
|
|
5207
5363
|
function attachServerCache(server, cache) {
|
|
5208
5364
|
try {
|
|
5209
5365
|
server.cache = cache;
|