@async/framework 0.11.0 → 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 +22 -1
- 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/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,26 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 0.11.2 - 2026-06-18
|
|
4
|
+
|
|
5
|
+
- Published the post-`0.11.1` feedback-regression hardening now on `main`,
|
|
6
|
+
including scheduler scope revival, server error envelopes, async-signal SSR
|
|
7
|
+
snapshot restore, lazy component error handling, router prefetch context,
|
|
8
|
+
server proxy transport validation, and package export smoke coverage.
|
|
9
|
+
- Refreshed the generated Async Pipeline workflow and lock metadata to
|
|
10
|
+
`@async/pipeline` `0.9.1`.
|
|
11
|
+
- Ignored local `docs/goals/` GoalBuddy planning bundles.
|
|
12
|
+
|
|
13
|
+
## 0.11.1 - 2026-06-17
|
|
14
|
+
|
|
15
|
+
- Removed the literal old global fetch identifier from published release notes
|
|
16
|
+
so package-wide text scans stay focused on runtime artifacts.
|
|
17
|
+
- Hardened scheduler scope revival, server error envelopes, async-signal SSR
|
|
18
|
+
snapshot restore, lazy component sync-rendering errors, router prefetch
|
|
19
|
+
context, server proxy transport validation, and package export smoke tests.
|
|
20
|
+
- Bundle size from bundled TypeScript source: `browser.ts` 177,243 B raw /
|
|
21
|
+
33,354 B gzip -> `browser.min.js` 75,517 B raw / 22,516 B gzip
|
|
22
|
+
(-101,726 B raw, -10,838 B gzip).
|
|
23
|
+
|
|
3
24
|
## 0.11.0 - 2026-06-17
|
|
4
25
|
|
|
5
26
|
- Removed the networked `ssr-spa` router mode and route-fragment fetching so
|
|
@@ -8,7 +29,7 @@
|
|
|
8
29
|
- Changed browser navigation to render registered SPA partials locally in
|
|
9
30
|
`spa` and `csr` modes while leaving same-origin document navigation alone in
|
|
10
31
|
`ssr` and `mpa` modes.
|
|
11
|
-
- Replaced the server proxy's implicit
|
|
32
|
+
- Replaced the server proxy's implicit global fetch default with an
|
|
12
33
|
explicit `transport` callback supplied by application code.
|
|
13
34
|
- Published only generated runtime artifacts and declarations:
|
|
14
35
|
`browser.*`, `server.js`, `framework.ts`, and `framework.d.ts`; source,
|
package/browser.js
CHANGED
|
@@ -185,6 +185,24 @@ const __asyncSignalModule = (() => {
|
|
|
185
185
|
};
|
|
186
186
|
},
|
|
187
187
|
|
|
188
|
+
_restore(snapshot = {}) {
|
|
189
|
+
if (!isAsyncSignalSnapshot(snapshot)) {
|
|
190
|
+
return state.set(snapshot);
|
|
191
|
+
}
|
|
192
|
+
if (activeAbort && !activeAbort.aborted) {
|
|
193
|
+
activeAbort.cancel(new Error(`Async signal "${registeredId}" restored from snapshot.`));
|
|
194
|
+
}
|
|
195
|
+
value = snapshot.value;
|
|
196
|
+
loading = Boolean(snapshot.loading);
|
|
197
|
+
error = snapshot.error ?? null;
|
|
198
|
+
status = typeof snapshot.status === "string" ? snapshot.status : inferStatus({ value, loading, error });
|
|
199
|
+
if (Number.isFinite(snapshot.version)) {
|
|
200
|
+
version = snapshot.version;
|
|
201
|
+
}
|
|
202
|
+
notify();
|
|
203
|
+
return state;
|
|
204
|
+
},
|
|
205
|
+
|
|
188
206
|
_bindRegistry(nextRegistry, nextId) {
|
|
189
207
|
registry = nextRegistry;
|
|
190
208
|
registeredId = nextId;
|
|
@@ -270,6 +288,27 @@ const __asyncSignalModule = (() => {
|
|
|
270
288
|
return Boolean(value?.[asyncSignalKind]);
|
|
271
289
|
}
|
|
272
290
|
|
|
291
|
+
function isAsyncSignalSnapshot(value) {
|
|
292
|
+
if (!value || typeof value !== "object" || Array.isArray(value)) {
|
|
293
|
+
return false;
|
|
294
|
+
}
|
|
295
|
+
return Object.hasOwn(value, "value")
|
|
296
|
+
&& (Object.hasOwn(value, "loading")
|
|
297
|
+
|| Object.hasOwn(value, "error")
|
|
298
|
+
|| Object.hasOwn(value, "status")
|
|
299
|
+
|| Object.hasOwn(value, "version"));
|
|
300
|
+
}
|
|
301
|
+
|
|
302
|
+
function inferStatus({ value, loading, error }) {
|
|
303
|
+
if (loading) {
|
|
304
|
+
return "loading";
|
|
305
|
+
}
|
|
306
|
+
if (error) {
|
|
307
|
+
return "error";
|
|
308
|
+
}
|
|
309
|
+
return value === undefined ? "idle" : "ready";
|
|
310
|
+
}
|
|
311
|
+
|
|
273
312
|
function attachCancel(signal, controller) {
|
|
274
313
|
Object.defineProperty(signal, "cancel", {
|
|
275
314
|
configurable: true,
|
|
@@ -1908,12 +1947,16 @@ const __componentModule = (() => {
|
|
|
1908
1947
|
});
|
|
1909
1948
|
|
|
1910
1949
|
const output = Component.call(context, props);
|
|
1950
|
+
if (output && typeof output.then === "function") {
|
|
1951
|
+
throw new TypeError(`Component "${componentName(Component)}" returned a Promise. Async components are not supported by synchronous renderComponent(). Use an async partial or handler instead.`);
|
|
1952
|
+
}
|
|
1911
1953
|
const html = renderScopedTemplate(output);
|
|
1912
1954
|
|
|
1913
1955
|
return {
|
|
1914
1956
|
html,
|
|
1915
1957
|
attach(target) {
|
|
1916
|
-
for (
|
|
1958
|
+
for (let index = 0; index < attachHooks.length; index += 1) {
|
|
1959
|
+
const hook = attachHooks[index];
|
|
1917
1960
|
runtime.scheduler?.enqueue("lifecycle", () => {
|
|
1918
1961
|
const cleanup = hook(target);
|
|
1919
1962
|
if (typeof cleanup === "function") {
|
|
@@ -1921,7 +1964,7 @@ const __componentModule = (() => {
|
|
|
1921
1964
|
}
|
|
1922
1965
|
}, {
|
|
1923
1966
|
scope,
|
|
1924
|
-
key: `attach:${
|
|
1967
|
+
key: `attach:${index}`
|
|
1925
1968
|
}) ?? runAttachHook(hook, target);
|
|
1926
1969
|
}
|
|
1927
1970
|
},
|
|
@@ -1929,8 +1972,12 @@ const __componentModule = (() => {
|
|
|
1929
1972
|
this.attach(target);
|
|
1930
1973
|
},
|
|
1931
1974
|
visible(target, observeVisible) {
|
|
1932
|
-
|
|
1933
|
-
|
|
1975
|
+
if (visibleHooks.length === 0) {
|
|
1976
|
+
return;
|
|
1977
|
+
}
|
|
1978
|
+
const cleanup = observeVisible(target, () => {
|
|
1979
|
+
for (let index = 0; index < visibleHooks.length; index += 1) {
|
|
1980
|
+
const hook = visibleHooks[index];
|
|
1934
1981
|
runtime.scheduler?.enqueue("lifecycle", () => {
|
|
1935
1982
|
const hookCleanup = hook(target);
|
|
1936
1983
|
if (typeof hookCleanup === "function") {
|
|
@@ -1938,12 +1985,12 @@ const __componentModule = (() => {
|
|
|
1938
1985
|
}
|
|
1939
1986
|
}, {
|
|
1940
1987
|
scope,
|
|
1941
|
-
key: `visible:${
|
|
1988
|
+
key: `visible:${index}`
|
|
1942
1989
|
}) ?? runVisibleHook(hook, target);
|
|
1943
|
-
});
|
|
1944
|
-
if (typeof cleanup === "function") {
|
|
1945
|
-
cleanups.push(cleanup);
|
|
1946
1990
|
}
|
|
1991
|
+
});
|
|
1992
|
+
if (typeof cleanup === "function") {
|
|
1993
|
+
cleanups.push(cleanup);
|
|
1947
1994
|
}
|
|
1948
1995
|
},
|
|
1949
1996
|
cleanup() {
|
|
@@ -2199,11 +2246,12 @@ const __serverModule = (() => {
|
|
|
2199
2246
|
signal: context.abort
|
|
2200
2247
|
});
|
|
2201
2248
|
|
|
2249
|
+
assertTransportResponse(id, response);
|
|
2202
2250
|
if (!response.ok) {
|
|
2203
2251
|
throw new Error(`Server function "${id}" failed with ${response.status}.`);
|
|
2204
2252
|
}
|
|
2205
2253
|
|
|
2206
|
-
const result = await readServerResponse(response);
|
|
2254
|
+
const result = await readServerResponse(id, response);
|
|
2207
2255
|
await applyServerResult(result, runContext);
|
|
2208
2256
|
return markAppliedServerValue(unwrapServerResult(result));
|
|
2209
2257
|
}
|
|
@@ -2244,6 +2292,11 @@ const __serverModule = (() => {
|
|
|
2244
2292
|
return result;
|
|
2245
2293
|
}
|
|
2246
2294
|
|
|
2295
|
+
if (result.error) {
|
|
2296
|
+
markAppliedServerResult(result);
|
|
2297
|
+
throw toError(result.error);
|
|
2298
|
+
}
|
|
2299
|
+
|
|
2247
2300
|
if (result.signals && context.signals) {
|
|
2248
2301
|
for (const [path, value] of Object.entries(result.signals)) {
|
|
2249
2302
|
context.signals.set?.(path, value);
|
|
@@ -2262,15 +2315,7 @@ const __serverModule = (() => {
|
|
|
2262
2315
|
await context.router?.navigate?.(result.redirect);
|
|
2263
2316
|
}
|
|
2264
2317
|
|
|
2265
|
-
|
|
2266
|
-
throw toError(result.error);
|
|
2267
|
-
}
|
|
2268
|
-
|
|
2269
|
-
Object.defineProperty(result, appliedServerResult, {
|
|
2270
|
-
configurable: true,
|
|
2271
|
-
enumerable: false,
|
|
2272
|
-
value: true
|
|
2273
|
-
});
|
|
2318
|
+
markAppliedServerResult(result);
|
|
2274
2319
|
|
|
2275
2320
|
return result;
|
|
2276
2321
|
}
|
|
@@ -2289,6 +2334,15 @@ const __serverModule = (() => {
|
|
|
2289
2334
|
return value;
|
|
2290
2335
|
}
|
|
2291
2336
|
|
|
2337
|
+
function markAppliedServerResult(result) {
|
|
2338
|
+
Object.defineProperty(result, appliedServerResult, {
|
|
2339
|
+
configurable: true,
|
|
2340
|
+
enumerable: false,
|
|
2341
|
+
value: true
|
|
2342
|
+
});
|
|
2343
|
+
return result;
|
|
2344
|
+
}
|
|
2345
|
+
|
|
2292
2346
|
function defaultInput(context = {}) {
|
|
2293
2347
|
const form = findForm(context);
|
|
2294
2348
|
if (form) {
|
|
@@ -2366,10 +2420,37 @@ const __serverModule = (() => {
|
|
|
2366
2420
|
return namespace([]);
|
|
2367
2421
|
}
|
|
2368
2422
|
|
|
2369
|
-
|
|
2423
|
+
function assertTransportResponse(id, response) {
|
|
2424
|
+
if (!response || typeof response !== "object") {
|
|
2425
|
+
throw new Error(`Server function "${id}" transport returned an invalid response: expected a fetch Response-like object.`);
|
|
2426
|
+
}
|
|
2427
|
+
if (typeof response.ok !== "boolean") {
|
|
2428
|
+
throw new Error(`Server function "${id}" transport returned an invalid response: missing boolean ok.`);
|
|
2429
|
+
}
|
|
2430
|
+
if (!response.headers || typeof response.headers.get !== "function") {
|
|
2431
|
+
throw new Error(`Server function "${id}" transport returned an invalid response: missing headers.get(name).`);
|
|
2432
|
+
}
|
|
2433
|
+
}
|
|
2434
|
+
|
|
2435
|
+
async function readServerResponse(id, response) {
|
|
2436
|
+
if (response.status === 204) {
|
|
2437
|
+
return { value: undefined };
|
|
2438
|
+
}
|
|
2370
2439
|
const type = response.headers.get("content-type") ?? "";
|
|
2371
2440
|
if (type.includes("application/json")) {
|
|
2372
|
-
|
|
2441
|
+
if (typeof response.json !== "function") {
|
|
2442
|
+
throw new Error(`Server function "${id}" transport returned an invalid response: missing json().`);
|
|
2443
|
+
}
|
|
2444
|
+
try {
|
|
2445
|
+
return await response.json();
|
|
2446
|
+
} catch (cause) {
|
|
2447
|
+
throw new Error(`Server function "${id}" returned invalid JSON: ${errorMessage(cause)}`, {
|
|
2448
|
+
cause
|
|
2449
|
+
});
|
|
2450
|
+
}
|
|
2451
|
+
}
|
|
2452
|
+
if (typeof response.text !== "function") {
|
|
2453
|
+
throw new Error(`Server function "${id}" transport returned an invalid response: missing text().`);
|
|
2373
2454
|
}
|
|
2374
2455
|
return { value: await response.text() };
|
|
2375
2456
|
}
|
|
@@ -2482,6 +2563,9 @@ const __serverModule = (() => {
|
|
|
2482
2563
|
if (tag === "[object File]" || tag === "[object Blob]" || tag === "[object FormData]") {
|
|
2483
2564
|
throw new Error("Server proxy JSON transport does not support File, Blob, or FormData values yet.");
|
|
2484
2565
|
}
|
|
2566
|
+
if (isUnsupportedJsonTransportObject(value, tag)) {
|
|
2567
|
+
throw new Error("Server proxy JSON transport does not support URLSearchParams, Headers, Request, Response, ReadableStream, ArrayBuffer, or typed array values yet.");
|
|
2568
|
+
}
|
|
2485
2569
|
if (Array.isArray(value)) {
|
|
2486
2570
|
for (const item of value) {
|
|
2487
2571
|
assertJsonTransportable(item, stack);
|
|
@@ -2495,6 +2579,16 @@ const __serverModule = (() => {
|
|
|
2495
2579
|
stack.delete(value);
|
|
2496
2580
|
}
|
|
2497
2581
|
|
|
2582
|
+
function isUnsupportedJsonTransportObject(value, tag = Object.prototype.toString.call(value)) {
|
|
2583
|
+
return tag === "[object URLSearchParams]"
|
|
2584
|
+
|| tag === "[object Headers]"
|
|
2585
|
+
|| tag === "[object Request]"
|
|
2586
|
+
|| tag === "[object Response]"
|
|
2587
|
+
|| tag === "[object ReadableStream]"
|
|
2588
|
+
|| tag === "[object ArrayBuffer]"
|
|
2589
|
+
|| ArrayBuffer.isView(value);
|
|
2590
|
+
}
|
|
2591
|
+
|
|
2498
2592
|
function joinEndpoint(endpoint, id) {
|
|
2499
2593
|
return `${String(endpoint).replace(/\/$/, "")}/${encodeURIComponent(id)}`;
|
|
2500
2594
|
}
|
|
@@ -2516,6 +2610,10 @@ const __serverModule = (() => {
|
|
|
2516
2610
|
return new Error(String(value));
|
|
2517
2611
|
}
|
|
2518
2612
|
|
|
2613
|
+
function errorMessage(error) {
|
|
2614
|
+
return error instanceof Error ? error.message : String(error);
|
|
2615
|
+
}
|
|
2616
|
+
|
|
2519
2617
|
function assertServerId(id) {
|
|
2520
2618
|
if (typeof id !== "string" || id.length === 0) {
|
|
2521
2619
|
throw new TypeError("Server function id must be a non-empty string.");
|
|
@@ -2748,7 +2846,8 @@ const __schedulerModule = (() => {
|
|
|
2748
2846
|
const phases = [...(options.phases ?? defaultPhases)];
|
|
2749
2847
|
const queues = new Map(phases.map((phase) => [phase, []]));
|
|
2750
2848
|
const keyedJobs = new Map();
|
|
2751
|
-
const
|
|
2849
|
+
const destroyedObjectScopes = new WeakSet();
|
|
2850
|
+
const destroyedPrimitiveScopes = new Set();
|
|
2752
2851
|
const objectScopeIds = new WeakMap();
|
|
2753
2852
|
const onError = typeof options.onError === "function" ? options.onError : undefined;
|
|
2754
2853
|
const maxDepth = options.maxDepth ?? 100;
|
|
@@ -2796,7 +2895,7 @@ const __schedulerModule = (() => {
|
|
|
2796
2895
|
throw new TypeError("scheduler.enqueue(phase, fn) requires a function.");
|
|
2797
2896
|
}
|
|
2798
2897
|
const scope = options.scope;
|
|
2799
|
-
if (
|
|
2898
|
+
if (isScopeDestroyed(scope)) {
|
|
2800
2899
|
return noop;
|
|
2801
2900
|
}
|
|
2802
2901
|
|
|
@@ -2900,14 +2999,29 @@ const __schedulerModule = (() => {
|
|
|
2900
2999
|
|
|
2901
3000
|
markScopeDestroyed(scope) {
|
|
2902
3001
|
if (scope !== undefined) {
|
|
2903
|
-
|
|
3002
|
+
if (isObjectScope(scope)) {
|
|
3003
|
+
destroyedObjectScopes.add(scope);
|
|
3004
|
+
} else {
|
|
3005
|
+
destroyedPrimitiveScopes.add(scope);
|
|
3006
|
+
}
|
|
2904
3007
|
api.cancelScope(scope);
|
|
2905
3008
|
}
|
|
2906
3009
|
return api;
|
|
2907
3010
|
},
|
|
2908
3011
|
|
|
3012
|
+
reviveScope(scope) {
|
|
3013
|
+
if (scope !== undefined) {
|
|
3014
|
+
if (isObjectScope(scope)) {
|
|
3015
|
+
destroyedObjectScopes.delete(scope);
|
|
3016
|
+
} else {
|
|
3017
|
+
destroyedPrimitiveScopes.delete(scope);
|
|
3018
|
+
}
|
|
3019
|
+
}
|
|
3020
|
+
return api;
|
|
3021
|
+
},
|
|
3022
|
+
|
|
2909
3023
|
isScopeDestroyed(scope) {
|
|
2910
|
-
return
|
|
3024
|
+
return isScopeDestroyed(scope);
|
|
2911
3025
|
},
|
|
2912
3026
|
|
|
2913
3027
|
inspect() {
|
|
@@ -2919,7 +3033,7 @@ const __schedulerModule = (() => {
|
|
|
2919
3033
|
strategy,
|
|
2920
3034
|
phases: [...phases],
|
|
2921
3035
|
pending: counts,
|
|
2922
|
-
scopesDestroyed:
|
|
3036
|
+
scopesDestroyed: destroyedPrimitiveScopes.size,
|
|
2923
3037
|
flushing,
|
|
2924
3038
|
scheduled
|
|
2925
3039
|
};
|
|
@@ -2934,7 +3048,7 @@ const __schedulerModule = (() => {
|
|
|
2934
3048
|
queue.length = 0;
|
|
2935
3049
|
}
|
|
2936
3050
|
keyedJobs.clear();
|
|
2937
|
-
|
|
3051
|
+
destroyedPrimitiveScopes.clear();
|
|
2938
3052
|
}
|
|
2939
3053
|
};
|
|
2940
3054
|
|
|
@@ -2974,7 +3088,7 @@ const __schedulerModule = (() => {
|
|
|
2974
3088
|
if (job.key) {
|
|
2975
3089
|
keyedJobs.delete(job.key);
|
|
2976
3090
|
}
|
|
2977
|
-
if (job.canceled || (job.scope
|
|
3091
|
+
if (job.canceled || isScopeDestroyed(job.scope)) {
|
|
2978
3092
|
continue;
|
|
2979
3093
|
}
|
|
2980
3094
|
try {
|
|
@@ -3031,6 +3145,20 @@ const __schedulerModule = (() => {
|
|
|
3031
3145
|
}
|
|
3032
3146
|
return String(scope);
|
|
3033
3147
|
}
|
|
3148
|
+
|
|
3149
|
+
function isScopeDestroyed(scope) {
|
|
3150
|
+
if (scope === undefined) {
|
|
3151
|
+
return false;
|
|
3152
|
+
}
|
|
3153
|
+
if (isObjectScope(scope)) {
|
|
3154
|
+
return destroyedObjectScopes.has(scope);
|
|
3155
|
+
}
|
|
3156
|
+
return destroyedPrimitiveScopes.has(scope);
|
|
3157
|
+
}
|
|
3158
|
+
}
|
|
3159
|
+
|
|
3160
|
+
function isObjectScope(scope) {
|
|
3161
|
+
return (typeof scope === "object" && scope !== null) || typeof scope === "function";
|
|
3034
3162
|
}
|
|
3035
3163
|
|
|
3036
3164
|
function scheduleMicrotask(fn) {
|
|
@@ -3091,6 +3219,7 @@ const __loaderModule = (() => {
|
|
|
3091
3219
|
|
|
3092
3220
|
scan(rootOrFragment = rootNode) {
|
|
3093
3221
|
assertActive();
|
|
3222
|
+
reviveScopes(rootOrFragment);
|
|
3094
3223
|
bindSignalAttributes(rootOrFragment);
|
|
3095
3224
|
bindClassAttributes(rootOrFragment);
|
|
3096
3225
|
bindEventAttributes(rootOrFragment);
|
|
@@ -3594,6 +3723,12 @@ const __loaderModule = (() => {
|
|
|
3594
3723
|
}
|
|
3595
3724
|
}
|
|
3596
3725
|
|
|
3726
|
+
function reviveScopes(scope) {
|
|
3727
|
+
for (const element of elementsIn(scope)) {
|
|
3728
|
+
schedulerInstance.reviveScope?.(element);
|
|
3729
|
+
}
|
|
3730
|
+
}
|
|
3731
|
+
|
|
3597
3732
|
return api;
|
|
3598
3733
|
}
|
|
3599
3734
|
|
|
@@ -4157,7 +4292,10 @@ const __routerModule = (() => {
|
|
|
4157
4292
|
}
|
|
4158
4293
|
const matched = api.match(url);
|
|
4159
4294
|
if (matched?.route?.partial && partials?.resolve?.(matched.route.partial)) {
|
|
4160
|
-
return partials.render(matched.route.partial, matched.params,
|
|
4295
|
+
return partials.render(matched.route.partial, matched.params, {
|
|
4296
|
+
...contextFor(matched),
|
|
4297
|
+
prefetch: true
|
|
4298
|
+
});
|
|
4161
4299
|
}
|
|
4162
4300
|
return Promise.resolve(null);
|
|
4163
4301
|
},
|
|
@@ -5193,6 +5331,13 @@ const __appModule = (() => {
|
|
|
5193
5331
|
function setOrRegisterSignal(signals, path, value) {
|
|
5194
5332
|
const id = String(path).split(".")[0];
|
|
5195
5333
|
if (signals.has?.(id)) {
|
|
5334
|
+
if (path === id) {
|
|
5335
|
+
const entry = signals._entry?.(id);
|
|
5336
|
+
if (typeof entry?._restore === "function" && isAsyncSignalSnapshot(value)) {
|
|
5337
|
+
entry._restore(value);
|
|
5338
|
+
return;
|
|
5339
|
+
}
|
|
5340
|
+
}
|
|
5196
5341
|
signals.set(path, value);
|
|
5197
5342
|
return;
|
|
5198
5343
|
}
|
|
@@ -5202,6 +5347,17 @@ const __appModule = (() => {
|
|
|
5202
5347
|
}
|
|
5203
5348
|
}
|
|
5204
5349
|
|
|
5350
|
+
function isAsyncSignalSnapshot(value) {
|
|
5351
|
+
if (!value || typeof value !== "object" || Array.isArray(value)) {
|
|
5352
|
+
return false;
|
|
5353
|
+
}
|
|
5354
|
+
return Object.hasOwn(value, "value")
|
|
5355
|
+
&& (Object.hasOwn(value, "loading")
|
|
5356
|
+
|| Object.hasOwn(value, "error")
|
|
5357
|
+
|| Object.hasOwn(value, "status")
|
|
5358
|
+
|| Object.hasOwn(value, "version"));
|
|
5359
|
+
}
|
|
5360
|
+
|
|
5205
5361
|
function attachServerCache(server, cache) {
|
|
5206
5362
|
try {
|
|
5207
5363
|
server.cache = cache;
|