@async/framework 0.11.3 → 0.11.5

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/server.js CHANGED
@@ -1220,10 +1220,16 @@ const __signalsModule = (() => {
1220
1220
  let subscriptionCounter = 0;
1221
1221
  let effectCounter = 0;
1222
1222
 
1223
+ for (const id of entries.keys()) {
1224
+ if (asyncDescriptors.has(id)) {
1225
+ throw new Error(`Signal "${id}" is already registered.`);
1226
+ }
1227
+ }
1228
+
1223
1229
  const registry = attachRegistryInspection({
1224
1230
  register(id, signalLike) {
1225
1231
  assertId(id);
1226
- if (entries.has(id)) {
1232
+ if (entries.has(id) || asyncDescriptors.has(id)) {
1227
1233
  throw new Error(`Signal "${id}" is already registered.`);
1228
1234
  }
1229
1235
  const entry = normalizeSignal(signalLike);
@@ -1241,14 +1247,19 @@ const __signalsModule = (() => {
1241
1247
 
1242
1248
  unregister(id) {
1243
1249
  assertId(id);
1244
- if (!entries.has(id)) {
1250
+ const hadEntry = entries.has(id);
1251
+ const hadDescriptor = asyncDescriptors.has(id);
1252
+ if (!hadEntry && !hadDescriptor) {
1245
1253
  return false;
1246
1254
  }
1247
- registryCleanups.get(id)?.();
1248
- registryCleanups.delete(id);
1249
- entries.get(id)?._dispose?.();
1250
- entries.delete(id);
1251
- boundEntries.delete(id);
1255
+ if (hadEntry) {
1256
+ registryCleanups.get(id)?.();
1257
+ registryCleanups.delete(id);
1258
+ entries.get(id)?._dispose?.();
1259
+ entries.delete(id);
1260
+ boundEntries.delete(id);
1261
+ }
1262
+ asyncDescriptors.delete(id);
1252
1263
  return true;
1253
1264
  },
1254
1265
 
@@ -1410,6 +1421,24 @@ const __signalsModule = (() => {
1410
1421
  return requireEntry(entries, id);
1411
1422
  },
1412
1423
 
1424
+ _setPath(path, value) {
1425
+ const parsed = parseRootPath(path);
1426
+ if (!entries.has(parsed.id)) {
1427
+ if (asyncDescriptors.has(parsed.id)) {
1428
+ materializeAsyncSignal(parsed.id);
1429
+ } else {
1430
+ registry.register(parsed.id, createSignal(parsed.parts.length === 0 ? value : {}));
1431
+ }
1432
+ }
1433
+ const entry = requireEntry(entries, parsed.id);
1434
+ if (parsed.parts.length === 0) {
1435
+ return entry.set(value);
1436
+ }
1437
+ const nextValue = setPath(entry.value, parsed.parts, value);
1438
+ entry.set(nextValue);
1439
+ return value;
1440
+ },
1441
+
1413
1442
  _setContext(context = {}) {
1414
1443
  Object.assign(runtimeContext, context);
1415
1444
  return registry;
@@ -1422,6 +1451,9 @@ const __signalsModule = (() => {
1422
1451
  _adoptMany(map = {}) {
1423
1452
  for (const [id, signalLike] of Object.entries(map ?? {})) {
1424
1453
  if (!entries.has(id)) {
1454
+ if (asyncDescriptors.has(id)) {
1455
+ throw new Error(`Signal "${id}" is already registered.`);
1456
+ }
1425
1457
  const entry = cloneSignalDeclaration(signalLike);
1426
1458
  entries.set(id, entry);
1427
1459
  bindEntry(id, entry);
@@ -1466,6 +1498,14 @@ const __signalsModule = (() => {
1466
1498
  return { id, parts, path };
1467
1499
  }
1468
1500
 
1501
+ function parseRootPath(path) {
1502
+ if (typeof path !== "string" || path.length === 0) {
1503
+ throw new TypeError("Signal path must be a non-empty string.");
1504
+ }
1505
+ const [id, ...parts] = path.split(".");
1506
+ return { id, parts, path };
1507
+ }
1508
+
1469
1509
  function materializeAsyncSignal(id) {
1470
1510
  if (entries.has(id) || !asyncDescriptors.has(id)) {
1471
1511
  return;
@@ -5006,7 +5046,7 @@ const __appModule = (() => {
5006
5046
 
5007
5047
  if (result.signals) {
5008
5048
  for (const [path, value] of Object.entries(result.signals)) {
5009
- setOrRegisterSignal(signals, path, value);
5049
+ applySignalPatch(signals, path, value);
5010
5050
  }
5011
5051
  }
5012
5052
  if (result.cache?.browser) {
@@ -5284,8 +5324,9 @@ const __appModule = (() => {
5284
5324
 
5285
5325
  function applySnapshotToRuntime(runtime, snapshot = {}, options = {}) {
5286
5326
  const normalized = normalizeSnapshot(snapshot);
5287
- for (const [path, value] of Object.entries(normalized.signal)) {
5288
- setOrRegisterSignal(runtime.signals, path, value);
5327
+ mergeRegistryEntries(runtime, "asyncSignal", normalized.asyncSignal, null, options);
5328
+ for (const [id, value] of Object.entries(normalized.signal)) {
5329
+ restoreSignalEntry(runtime.signals, id, value);
5289
5330
  }
5290
5331
  runtime.browser.cache.restore(normalized.cache.browser);
5291
5332
  mergeRegistryEntries(runtime, "handler", normalized.handler, runtime.handlers, options);
@@ -5293,7 +5334,6 @@ const __appModule = (() => {
5293
5334
  mergeRegistryEntries(runtime, "partial", normalized.partial, runtime.partials, options);
5294
5335
  mergeRegistryEntries(runtime, "route", normalized.route, runtime.routes, options);
5295
5336
  mergeRegistryEntries(runtime, "component", normalized.component, runtime.components, options);
5296
- mergeRegistryEntries(runtime, "asyncSignal", normalized.asyncSignal, null, options);
5297
5337
  return runtime;
5298
5338
  }
5299
5339
 
@@ -5314,6 +5354,9 @@ const __appModule = (() => {
5314
5354
  return;
5315
5355
  }
5316
5356
  for (const [id, value] of Object.entries(entries)) {
5357
+ if (type === "asyncSignal" && runtime.signals?.has?.(id) && !runtime.registry.has(type, id)) {
5358
+ throw new Error(`Signal "${id}" is already registered.`);
5359
+ }
5317
5360
  registerSnapshotEntry(runtime.registry, type, id, value, options);
5318
5361
  }
5319
5362
  concreteRegistry?._adoptMany?.(entries);
@@ -5399,16 +5442,26 @@ const __appModule = (() => {
5399
5442
  }
5400
5443
  }
5401
5444
 
5402
- function setOrRegisterSignal(signals, path, value) {
5403
- const id = String(path).split(".")[0];
5445
+ function restoreSignalEntry(signals, id, value) {
5404
5446
  if (signals.has?.(id)) {
5405
- if (path === id) {
5406
- const entry = signals._entry?.(id);
5407
- if (typeof entry?._restore === "function" && isAsyncSignalSnapshot(value)) {
5408
- entry._restore(value);
5409
- return;
5410
- }
5447
+ const entry = signals._entry?.(id);
5448
+ if (typeof entry?._restore === "function" && isAsyncSignalSnapshot(value)) {
5449
+ entry._restore(value);
5450
+ return;
5411
5451
  }
5452
+ signals.set(id, value);
5453
+ return;
5454
+ }
5455
+ signals.register(id, createSignal(value));
5456
+ }
5457
+
5458
+ function applySignalPatch(signals, path, value) {
5459
+ if (typeof signals._setPath === "function") {
5460
+ signals._setPath(path, value);
5461
+ return;
5462
+ }
5463
+ const id = String(path).split(".")[0];
5464
+ if (signals.has?.(id)) {
5412
5465
  signals.set(path, value);
5413
5466
  return;
5414
5467
  }