@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/browser.ts CHANGED
@@ -186,6 +186,28 @@ const __asyncSignalModule = (() => {
186
186
  };
187
187
  },
188
188
 
189
+ _cloneSignalDeclaration() {
190
+ return asyncSignal(id, fn);
191
+ },
192
+
193
+ _restore(snapshot = {}) {
194
+ if (!isAsyncSignalSnapshot(snapshot)) {
195
+ return state.set(snapshot);
196
+ }
197
+ if (activeAbort && !activeAbort.aborted) {
198
+ activeAbort.cancel(new Error(`Async signal "${registeredId}" restored from snapshot.`));
199
+ }
200
+ value = snapshot.value;
201
+ loading = Boolean(snapshot.loading);
202
+ error = snapshot.error ?? null;
203
+ status = typeof snapshot.status === "string" ? snapshot.status : inferStatus({ value, loading, error });
204
+ if (Number.isFinite(snapshot.version)) {
205
+ version = snapshot.version;
206
+ }
207
+ notify();
208
+ return state;
209
+ },
210
+
189
211
  _bindRegistry(nextRegistry, nextId) {
190
212
  registry = nextRegistry;
191
213
  registeredId = nextId;
@@ -271,6 +293,27 @@ const __asyncSignalModule = (() => {
271
293
  return Boolean(value?.[asyncSignalKind]);
272
294
  }
273
295
 
296
+ function isAsyncSignalSnapshot(value) {
297
+ if (!value || typeof value !== "object" || Array.isArray(value)) {
298
+ return false;
299
+ }
300
+ return Object.hasOwn(value, "value")
301
+ && (Object.hasOwn(value, "loading")
302
+ || Object.hasOwn(value, "error")
303
+ || Object.hasOwn(value, "status")
304
+ || Object.hasOwn(value, "version"));
305
+ }
306
+
307
+ function inferStatus({ value, loading, error }) {
308
+ if (loading) {
309
+ return "loading";
310
+ }
311
+ if (error) {
312
+ return "error";
313
+ }
314
+ return value === undefined ? "idle" : "ready";
315
+ }
316
+
274
317
  function attachCancel(signal, controller) {
275
318
  Object.defineProperty(signal, "cancel", {
276
319
  configurable: true,
@@ -918,7 +961,12 @@ const __cacheModule = (() => {
918
961
  return registryStore.entries(`${type}.entries`);
919
962
  },
920
963
 
921
- _adoptMany() {
964
+ _adoptMany(map = {}) {
965
+ for (const [id, definition] of Object.entries(map ?? {})) {
966
+ if (!definitions.has(id)) {
967
+ registryApi.register(id, definition);
968
+ }
969
+ }
922
970
  return registryApi;
923
971
  }
924
972
  }, registryStore, type);
@@ -1076,6 +1124,10 @@ const __signalsModule = (() => {
1076
1124
 
1077
1125
  snapshot() {
1078
1126
  return value;
1127
+ },
1128
+
1129
+ _cloneSignalDeclaration() {
1130
+ return createSignal(value);
1079
1131
  }
1080
1132
  };
1081
1133
 
@@ -1118,6 +1170,10 @@ const __signalsModule = (() => {
1118
1170
  return backing.snapshot();
1119
1171
  },
1120
1172
 
1173
+ _cloneSignalDeclaration() {
1174
+ return computed(fn);
1175
+ },
1176
+
1121
1177
  _bindRegistry(registry, id) {
1122
1178
  return registry.effect(() => {
1123
1179
  backing.set(fn.call({
@@ -1142,6 +1198,9 @@ const __signalsModule = (() => {
1142
1198
  [effectKind]: true,
1143
1199
  kind: "effect",
1144
1200
  fn,
1201
+ _cloneSignalDeclaration() {
1202
+ return effect(fn);
1203
+ },
1145
1204
  _bindRegistry(registry) {
1146
1205
  return registry.effect(fn);
1147
1206
  }
@@ -1360,10 +1419,14 @@ const __signalsModule = (() => {
1360
1419
  },
1361
1420
 
1362
1421
  _adoptMany(map = {}) {
1363
- for (const id of Object.keys(map ?? {})) {
1364
- if (entries.has(id)) {
1365
- bindEntry(id, entries.get(id));
1422
+ for (const [id, signalLike] of Object.entries(map ?? {})) {
1423
+ if (!entries.has(id)) {
1424
+ const entry = cloneSignalDeclaration(signalLike);
1425
+ entries.set(id, entry);
1426
+ bindEntry(id, entry);
1427
+ continue;
1366
1428
  }
1429
+ bindEntry(id, entries.get(id));
1367
1430
  }
1368
1431
  return registry;
1369
1432
  }
@@ -1441,6 +1504,16 @@ const __signalsModule = (() => {
1441
1504
  return createSignal(signalLike);
1442
1505
  }
1443
1506
 
1507
+ function cloneSignalDeclaration(signalLike) {
1508
+ if (typeof signalLike?._cloneSignalDeclaration === "function") {
1509
+ return signalLike._cloneSignalDeclaration();
1510
+ }
1511
+ if (isSignalLike(signalLike)) {
1512
+ return createSignal(typeof signalLike.snapshot === "function" ? signalLike.snapshot() : signalLike.value);
1513
+ }
1514
+ return createSignal(signalLike);
1515
+ }
1516
+
1444
1517
  function isSignalLike(value) {
1445
1518
  return Boolean(value && typeof value === "object" && typeof value.subscribe === "function");
1446
1519
  }
@@ -1619,7 +1692,7 @@ const __signalsModule = (() => {
1619
1692
  frame.add(path);
1620
1693
  }
1621
1694
  }
1622
- return { createSignal, computed, effect, createSignalRegistry, isSignalRef, signal };
1695
+ return { createSignal, computed, effect, createSignalRegistry, cloneSignalDeclaration, isSignalRef, signal };
1623
1696
  })();
1624
1697
 
1625
1698
  const __htmlModule = (() => {
@@ -1861,7 +1934,12 @@ const __componentModule = (() => {
1861
1934
  return lazyComponents.get(id);
1862
1935
  },
1863
1936
 
1864
- _adoptMany() {
1937
+ _adoptMany(map = {}) {
1938
+ for (const [id, Component] of Object.entries(map ?? {})) {
1939
+ if (!entries.has(id)) {
1940
+ registry.register(id, Component);
1941
+ }
1942
+ }
1865
1943
  return registry;
1866
1944
  }
1867
1945
  }, registryStore, type);
@@ -1909,12 +1987,16 @@ const __componentModule = (() => {
1909
1987
  });
1910
1988
 
1911
1989
  const output = Component.call(context, props);
1990
+ if (output && typeof output.then === "function") {
1991
+ throw new TypeError(`Component "${componentName(Component)}" returned a Promise. Async components are not supported by synchronous renderComponent(). Use an async partial or handler instead.`);
1992
+ }
1912
1993
  const html = renderScopedTemplate(output);
1913
1994
 
1914
1995
  return {
1915
1996
  html,
1916
1997
  attach(target) {
1917
- for (const hook of attachHooks) {
1998
+ for (let index = 0; index < attachHooks.length; index += 1) {
1999
+ const hook = attachHooks[index];
1918
2000
  runtime.scheduler?.enqueue("lifecycle", () => {
1919
2001
  const cleanup = hook(target);
1920
2002
  if (typeof cleanup === "function") {
@@ -1922,7 +2004,7 @@ const __componentModule = (() => {
1922
2004
  }
1923
2005
  }, {
1924
2006
  scope,
1925
- key: `attach:${attachHooks.indexOf(hook)}`
2007
+ key: `attach:${index}`
1926
2008
  }) ?? runAttachHook(hook, target);
1927
2009
  }
1928
2010
  },
@@ -1930,8 +2012,12 @@ const __componentModule = (() => {
1930
2012
  this.attach(target);
1931
2013
  },
1932
2014
  visible(target, observeVisible) {
1933
- for (const hook of visibleHooks) {
1934
- const cleanup = observeVisible(target, () => {
2015
+ if (visibleHooks.length === 0) {
2016
+ return;
2017
+ }
2018
+ const cleanup = observeVisible(target, () => {
2019
+ for (let index = 0; index < visibleHooks.length; index += 1) {
2020
+ const hook = visibleHooks[index];
1935
2021
  runtime.scheduler?.enqueue("lifecycle", () => {
1936
2022
  const hookCleanup = hook(target);
1937
2023
  if (typeof hookCleanup === "function") {
@@ -1939,12 +2025,12 @@ const __componentModule = (() => {
1939
2025
  }
1940
2026
  }, {
1941
2027
  scope,
1942
- key: `visible:${visibleHooks.indexOf(hook)}`
2028
+ key: `visible:${index}`
1943
2029
  }) ?? runVisibleHook(hook, target);
1944
- });
1945
- if (typeof cleanup === "function") {
1946
- cleanups.push(cleanup);
1947
2030
  }
2031
+ });
2032
+ if (typeof cleanup === "function") {
2033
+ cleanups.push(cleanup);
1948
2034
  }
1949
2035
  },
1950
2036
  cleanup() {
@@ -2200,11 +2286,12 @@ const __serverModule = (() => {
2200
2286
  signal: context.abort
2201
2287
  });
2202
2288
 
2289
+ assertTransportResponse(id, response);
2203
2290
  if (!response.ok) {
2204
2291
  throw new Error(`Server function "${id}" failed with ${response.status}.`);
2205
2292
  }
2206
2293
 
2207
- const result = await readServerResponse(response);
2294
+ const result = await readServerResponse(id, response);
2208
2295
  await applyServerResult(result, runContext);
2209
2296
  return markAppliedServerValue(unwrapServerResult(result));
2210
2297
  }
@@ -2245,6 +2332,11 @@ const __serverModule = (() => {
2245
2332
  return result;
2246
2333
  }
2247
2334
 
2335
+ if (result.error) {
2336
+ markAppliedServerResult(result);
2337
+ throw toError(result.error);
2338
+ }
2339
+
2248
2340
  if (result.signals && context.signals) {
2249
2341
  for (const [path, value] of Object.entries(result.signals)) {
2250
2342
  context.signals.set?.(path, value);
@@ -2263,15 +2355,7 @@ const __serverModule = (() => {
2263
2355
  await context.router?.navigate?.(result.redirect);
2264
2356
  }
2265
2357
 
2266
- if (result.error) {
2267
- throw toError(result.error);
2268
- }
2269
-
2270
- Object.defineProperty(result, appliedServerResult, {
2271
- configurable: true,
2272
- enumerable: false,
2273
- value: true
2274
- });
2358
+ markAppliedServerResult(result);
2275
2359
 
2276
2360
  return result;
2277
2361
  }
@@ -2290,6 +2374,15 @@ const __serverModule = (() => {
2290
2374
  return value;
2291
2375
  }
2292
2376
 
2377
+ function markAppliedServerResult(result) {
2378
+ Object.defineProperty(result, appliedServerResult, {
2379
+ configurable: true,
2380
+ enumerable: false,
2381
+ value: true
2382
+ });
2383
+ return result;
2384
+ }
2385
+
2293
2386
  function defaultInput(context = {}) {
2294
2387
  const form = findForm(context);
2295
2388
  if (form) {
@@ -2367,10 +2460,37 @@ const __serverModule = (() => {
2367
2460
  return namespace([]);
2368
2461
  }
2369
2462
 
2370
- async function readServerResponse(response) {
2463
+ function assertTransportResponse(id, response) {
2464
+ if (!response || typeof response !== "object") {
2465
+ throw new Error(`Server function "${id}" transport returned an invalid response: expected a fetch Response-like object.`);
2466
+ }
2467
+ if (typeof response.ok !== "boolean") {
2468
+ throw new Error(`Server function "${id}" transport returned an invalid response: missing boolean ok.`);
2469
+ }
2470
+ if (!response.headers || typeof response.headers.get !== "function") {
2471
+ throw new Error(`Server function "${id}" transport returned an invalid response: missing headers.get(name).`);
2472
+ }
2473
+ }
2474
+
2475
+ async function readServerResponse(id, response) {
2476
+ if (response.status === 204) {
2477
+ return { value: undefined };
2478
+ }
2371
2479
  const type = response.headers.get("content-type") ?? "";
2372
2480
  if (type.includes("application/json")) {
2373
- return response.json();
2481
+ if (typeof response.json !== "function") {
2482
+ throw new Error(`Server function "${id}" transport returned an invalid response: missing json().`);
2483
+ }
2484
+ try {
2485
+ return await response.json();
2486
+ } catch (cause) {
2487
+ throw new Error(`Server function "${id}" returned invalid JSON: ${errorMessage(cause)}`, {
2488
+ cause
2489
+ });
2490
+ }
2491
+ }
2492
+ if (typeof response.text !== "function") {
2493
+ throw new Error(`Server function "${id}" transport returned an invalid response: missing text().`);
2374
2494
  }
2375
2495
  return { value: await response.text() };
2376
2496
  }
@@ -2483,6 +2603,9 @@ const __serverModule = (() => {
2483
2603
  if (tag === "[object File]" || tag === "[object Blob]" || tag === "[object FormData]") {
2484
2604
  throw new Error("Server proxy JSON transport does not support File, Blob, or FormData values yet.");
2485
2605
  }
2606
+ if (isUnsupportedJsonTransportObject(value, tag)) {
2607
+ throw new Error("Server proxy JSON transport does not support URLSearchParams, Headers, Request, Response, ReadableStream, ArrayBuffer, or typed array values yet.");
2608
+ }
2486
2609
  if (Array.isArray(value)) {
2487
2610
  for (const item of value) {
2488
2611
  assertJsonTransportable(item, stack);
@@ -2496,6 +2619,16 @@ const __serverModule = (() => {
2496
2619
  stack.delete(value);
2497
2620
  }
2498
2621
 
2622
+ function isUnsupportedJsonTransportObject(value, tag = Object.prototype.toString.call(value)) {
2623
+ return tag === "[object URLSearchParams]"
2624
+ || tag === "[object Headers]"
2625
+ || tag === "[object Request]"
2626
+ || tag === "[object Response]"
2627
+ || tag === "[object ReadableStream]"
2628
+ || tag === "[object ArrayBuffer]"
2629
+ || ArrayBuffer.isView(value);
2630
+ }
2631
+
2499
2632
  function joinEndpoint(endpoint, id) {
2500
2633
  return `${String(endpoint).replace(/\/$/, "")}/${encodeURIComponent(id)}`;
2501
2634
  }
@@ -2517,6 +2650,10 @@ const __serverModule = (() => {
2517
2650
  return new Error(String(value));
2518
2651
  }
2519
2652
 
2653
+ function errorMessage(error) {
2654
+ return error instanceof Error ? error.message : String(error);
2655
+ }
2656
+
2520
2657
  function assertServerId(id) {
2521
2658
  if (typeof id !== "string" || id.length === 0) {
2522
2659
  throw new TypeError("Server function id must be a non-empty string.");
@@ -2642,7 +2779,12 @@ const __handlersModule = (() => {
2642
2779
  return results;
2643
2780
  },
2644
2781
 
2645
- _adoptMany() {
2782
+ _adoptMany(map = {}) {
2783
+ for (const [id, fn] of Object.entries(map ?? {})) {
2784
+ if (!handlers.has(id)) {
2785
+ registry.register(id, fn);
2786
+ }
2787
+ }
2646
2788
  return registry;
2647
2789
  }
2648
2790
  }, registryStore, type);
@@ -2749,7 +2891,8 @@ const __schedulerModule = (() => {
2749
2891
  const phases = [...(options.phases ?? defaultPhases)];
2750
2892
  const queues = new Map(phases.map((phase) => [phase, []]));
2751
2893
  const keyedJobs = new Map();
2752
- const destroyedScopes = new Set();
2894
+ const destroyedObjectScopes = new WeakSet();
2895
+ const destroyedPrimitiveScopes = new Set();
2753
2896
  const objectScopeIds = new WeakMap();
2754
2897
  const onError = typeof options.onError === "function" ? options.onError : undefined;
2755
2898
  const maxDepth = options.maxDepth ?? 100;
@@ -2797,7 +2940,7 @@ const __schedulerModule = (() => {
2797
2940
  throw new TypeError("scheduler.enqueue(phase, fn) requires a function.");
2798
2941
  }
2799
2942
  const scope = options.scope;
2800
- if (scope !== undefined && destroyedScopes.has(scope)) {
2943
+ if (isScopeDestroyed(scope)) {
2801
2944
  return noop;
2802
2945
  }
2803
2946
 
@@ -2901,14 +3044,29 @@ const __schedulerModule = (() => {
2901
3044
 
2902
3045
  markScopeDestroyed(scope) {
2903
3046
  if (scope !== undefined) {
2904
- destroyedScopes.add(scope);
3047
+ if (isObjectScope(scope)) {
3048
+ destroyedObjectScopes.add(scope);
3049
+ } else {
3050
+ destroyedPrimitiveScopes.add(scope);
3051
+ }
2905
3052
  api.cancelScope(scope);
2906
3053
  }
2907
3054
  return api;
2908
3055
  },
2909
3056
 
3057
+ reviveScope(scope) {
3058
+ if (scope !== undefined) {
3059
+ if (isObjectScope(scope)) {
3060
+ destroyedObjectScopes.delete(scope);
3061
+ } else {
3062
+ destroyedPrimitiveScopes.delete(scope);
3063
+ }
3064
+ }
3065
+ return api;
3066
+ },
3067
+
2910
3068
  isScopeDestroyed(scope) {
2911
- return scope !== undefined && destroyedScopes.has(scope);
3069
+ return isScopeDestroyed(scope);
2912
3070
  },
2913
3071
 
2914
3072
  inspect() {
@@ -2920,7 +3078,7 @@ const __schedulerModule = (() => {
2920
3078
  strategy,
2921
3079
  phases: [...phases],
2922
3080
  pending: counts,
2923
- scopesDestroyed: destroyedScopes.size,
3081
+ scopesDestroyed: destroyedPrimitiveScopes.size,
2924
3082
  flushing,
2925
3083
  scheduled
2926
3084
  };
@@ -2935,7 +3093,7 @@ const __schedulerModule = (() => {
2935
3093
  queue.length = 0;
2936
3094
  }
2937
3095
  keyedJobs.clear();
2938
- destroyedScopes.clear();
3096
+ destroyedPrimitiveScopes.clear();
2939
3097
  }
2940
3098
  };
2941
3099
 
@@ -2975,7 +3133,7 @@ const __schedulerModule = (() => {
2975
3133
  if (job.key) {
2976
3134
  keyedJobs.delete(job.key);
2977
3135
  }
2978
- if (job.canceled || (job.scope !== undefined && destroyedScopes.has(job.scope))) {
3136
+ if (job.canceled || isScopeDestroyed(job.scope)) {
2979
3137
  continue;
2980
3138
  }
2981
3139
  try {
@@ -3032,6 +3190,20 @@ const __schedulerModule = (() => {
3032
3190
  }
3033
3191
  return String(scope);
3034
3192
  }
3193
+
3194
+ function isScopeDestroyed(scope) {
3195
+ if (scope === undefined) {
3196
+ return false;
3197
+ }
3198
+ if (isObjectScope(scope)) {
3199
+ return destroyedObjectScopes.has(scope);
3200
+ }
3201
+ return destroyedPrimitiveScopes.has(scope);
3202
+ }
3203
+ }
3204
+
3205
+ function isObjectScope(scope) {
3206
+ return (typeof scope === "object" && scope !== null) || typeof scope === "function";
3035
3207
  }
3036
3208
 
3037
3209
  function scheduleMicrotask(fn) {
@@ -3092,6 +3264,7 @@ const __loaderModule = (() => {
3092
3264
 
3093
3265
  scan(rootOrFragment = rootNode) {
3094
3266
  assertActive();
3267
+ reviveScopes(rootOrFragment);
3095
3268
  bindSignalAttributes(rootOrFragment);
3096
3269
  bindClassAttributes(rootOrFragment);
3097
3270
  bindEventAttributes(rootOrFragment);
@@ -3595,6 +3768,12 @@ const __loaderModule = (() => {
3595
3768
  }
3596
3769
  }
3597
3770
 
3771
+ function reviveScopes(scope) {
3772
+ for (const element of elementsIn(scope)) {
3773
+ schedulerInstance.reviveScope?.(element);
3774
+ }
3775
+ }
3776
+
3598
3777
  return api;
3599
3778
  }
3600
3779
 
@@ -3894,7 +4073,12 @@ const __partialsModule = (() => {
3894
4073
  return normalizePartialResult(result, partialContext);
3895
4074
  },
3896
4075
 
3897
- _adoptMany() {
4076
+ _adoptMany(map = {}) {
4077
+ for (const [id, fn] of Object.entries(map ?? {})) {
4078
+ if (!entries.has(id)) {
4079
+ registry.register(id, fn);
4080
+ }
4081
+ }
3898
4082
  return registry;
3899
4083
  }
3900
4084
  }, registryStore, type);
@@ -4046,7 +4230,11 @@ const __routerModule = (() => {
4046
4230
  },
4047
4231
 
4048
4232
  _adoptMany(map = {}) {
4049
- for (const pattern of Object.keys(map ?? {})) {
4233
+ for (const [pattern, definition] of Object.entries(map ?? {})) {
4234
+ if (!entries.has(pattern)) {
4235
+ registry.register(pattern, definition);
4236
+ continue;
4237
+ }
4050
4238
  adoptRoute(pattern, entries.get(pattern));
4051
4239
  }
4052
4240
  return registry;
@@ -4158,7 +4346,10 @@ const __routerModule = (() => {
4158
4346
  }
4159
4347
  const matched = api.match(url);
4160
4348
  if (matched?.route?.partial && partials?.resolve?.(matched.route.partial)) {
4161
- return partials.render(matched.route.partial, matched.params, contextFor(matched));
4349
+ return partials.render(matched.route.partial, matched.params, {
4350
+ ...contextFor(matched),
4351
+ prefetch: true
4352
+ });
4162
4353
  }
4163
4354
  return Promise.resolve(null);
4164
4355
  },
@@ -4539,7 +4730,7 @@ const __appModule = (() => {
4539
4730
  const { createRouteRegistry, createRouter } = __routerModule;
4540
4731
  const { createScheduler } = __schedulerModule;
4541
4732
  const { createServerNamespace } = __serverModule;
4542
- const { createSignal, createSignalRegistry } = __signalsModule;
4733
+ const { cloneSignalDeclaration, createSignal, createSignalRegistry } = __signalsModule;
4543
4734
  const { createRegistryStore } = __registryStoreModule;
4544
4735
  const { attributeName, normalizeAttributeConfig } = __attributesModule;
4545
4736
  const { createLazyRegistry, defineRegistrySnapshot, sameRegistryValue } = __lazyRegistryModule;
@@ -4622,7 +4813,7 @@ const __appModule = (() => {
4622
4813
  registryAssets: options.registryAssets,
4623
4814
  importModule: options.importModule
4624
4815
  });
4625
- const registry = options.registry ?? app.registry.view({ target });
4816
+ const registry = options.registry ?? createRuntimeRegistry(app.registry, { target });
4626
4817
  const signals = options.signals ?? createSignalRegistry(undefined, { registry, type: "signal", lazyRegistry });
4627
4818
  const handlers = options.handlers ?? createHandlerRegistry(undefined, { registry, type: "handler", lazyRegistry });
4628
4819
  const serverCache = createCacheRegistry(undefined, { registry, type: "cache.server" });
@@ -5003,6 +5194,22 @@ const __appModule = (() => {
5003
5194
  registry?.registerMany?.(entries);
5004
5195
  }
5005
5196
 
5197
+ function createRuntimeRegistry(appRegistry, { target } = {}) {
5198
+ const declarations = appRegistry.rawSnapshot();
5199
+ return createRegistryStore({
5200
+ ...declarations,
5201
+ signal: cloneSignalDeclarations(declarations.signal)
5202
+ }, { target });
5203
+ }
5204
+
5205
+ function cloneSignalDeclarations(signals = {}) {
5206
+ const cloned = {};
5207
+ for (const [id, signalLike] of Object.entries(signals ?? {})) {
5208
+ cloned[id] = cloneSignalDeclaration(signalLike);
5209
+ }
5210
+ return cloned;
5211
+ }
5212
+
5006
5213
  function emptyDeclarations() {
5007
5214
  return {
5008
5215
  signal: {},
@@ -5194,6 +5401,13 @@ const __appModule = (() => {
5194
5401
  function setOrRegisterSignal(signals, path, value) {
5195
5402
  const id = String(path).split(".")[0];
5196
5403
  if (signals.has?.(id)) {
5404
+ if (path === id) {
5405
+ const entry = signals._entry?.(id);
5406
+ if (typeof entry?._restore === "function" && isAsyncSignalSnapshot(value)) {
5407
+ entry._restore(value);
5408
+ return;
5409
+ }
5410
+ }
5197
5411
  signals.set(path, value);
5198
5412
  return;
5199
5413
  }
@@ -5203,6 +5417,17 @@ const __appModule = (() => {
5203
5417
  }
5204
5418
  }
5205
5419
 
5420
+ function isAsyncSignalSnapshot(value) {
5421
+ if (!value || typeof value !== "object" || Array.isArray(value)) {
5422
+ return false;
5423
+ }
5424
+ return Object.hasOwn(value, "value")
5425
+ && (Object.hasOwn(value, "loading")
5426
+ || Object.hasOwn(value, "error")
5427
+ || Object.hasOwn(value, "status")
5428
+ || Object.hasOwn(value, "version"));
5429
+ }
5430
+
5206
5431
  function attachServerCache(server, cache) {
5207
5432
  try {
5208
5433
  server.cache = cache;