@async/framework 0.11.2 → 0.11.4
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 +28 -0
- package/README.md +3 -1
- package/browser.js +128 -23
- package/browser.min.js +1 -1
- package/browser.ts +128 -23
- package/browser.umd.js +128 -23
- package/browser.umd.min.js +1 -1
- package/framework.ts +134 -24
- package/package.json +1 -1
- package/server.js +134 -24
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,33 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 0.11.4 - 2026-06-18
|
|
4
|
+
|
|
5
|
+
- Restored snapshot signal keys as exact IDs so dotted plain, async, and
|
|
6
|
+
component-scoped signal IDs such as `product.load` survive SSR activation
|
|
7
|
+
without becoming nested properties under their first segment.
|
|
8
|
+
- Adopted async-signal descriptors before restoring matching snapshot state so
|
|
9
|
+
dotted async signals preserve `$value`, `$status`, and `$version` without an
|
|
10
|
+
immediate client refresh.
|
|
11
|
+
- Kept server-result signal patches on nested first-segment path semantics for
|
|
12
|
+
updates such as `product.title`.
|
|
13
|
+
- Bundle size from bundled TypeScript source: `browser.ts` 180,585 B raw /
|
|
14
|
+
33,742 B gzip -> `browser.min.js` 76,946 B raw / 22,793 B gzip
|
|
15
|
+
(-103,639 B raw, -10,949 B gzip).
|
|
16
|
+
|
|
17
|
+
## 0.11.3 - 2026-06-18
|
|
18
|
+
|
|
19
|
+
- Isolated runtime-owned signal, async-signal, scheduler, request, and cache
|
|
20
|
+
state so each `createApp(...)` call materializes fresh mutable state from
|
|
21
|
+
reusable app declarations.
|
|
22
|
+
- Preserved reusable app declarations across runtime destroy/recreate cycles,
|
|
23
|
+
late `app.use(...)` adoption, server render repetition, and peer async-signal
|
|
24
|
+
subscribers.
|
|
25
|
+
- Added direct runtime-isolation regression coverage and regenerated the
|
|
26
|
+
published browser/server artifacts.
|
|
27
|
+
- Bundle size from bundled TypeScript source: `browser.ts` 179,469 B raw /
|
|
28
|
+
33,612 B gzip -> `browser.min.js` 76,458 B raw / 22,690 B gzip
|
|
29
|
+
(-103,011 B raw, -10,922 B gzip).
|
|
30
|
+
|
|
3
31
|
## 0.11.2 - 2026-06-18
|
|
4
32
|
|
|
5
33
|
- Published the post-`0.11.1` feedback-regression hardening now on `main`,
|
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,10 @@ const __asyncSignalModule = (() => {
|
|
|
185
185
|
};
|
|
186
186
|
},
|
|
187
187
|
|
|
188
|
+
_cloneSignalDeclaration() {
|
|
189
|
+
return asyncSignal(id, fn);
|
|
190
|
+
},
|
|
191
|
+
|
|
188
192
|
_restore(snapshot = {}) {
|
|
189
193
|
if (!isAsyncSignalSnapshot(snapshot)) {
|
|
190
194
|
return state.set(snapshot);
|
|
@@ -956,7 +960,12 @@ const __cacheModule = (() => {
|
|
|
956
960
|
return registryStore.entries(`${type}.entries`);
|
|
957
961
|
},
|
|
958
962
|
|
|
959
|
-
_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
|
+
}
|
|
960
969
|
return registryApi;
|
|
961
970
|
}
|
|
962
971
|
}, registryStore, type);
|
|
@@ -1114,6 +1123,10 @@ const __signalsModule = (() => {
|
|
|
1114
1123
|
|
|
1115
1124
|
snapshot() {
|
|
1116
1125
|
return value;
|
|
1126
|
+
},
|
|
1127
|
+
|
|
1128
|
+
_cloneSignalDeclaration() {
|
|
1129
|
+
return createSignal(value);
|
|
1117
1130
|
}
|
|
1118
1131
|
};
|
|
1119
1132
|
|
|
@@ -1156,6 +1169,10 @@ const __signalsModule = (() => {
|
|
|
1156
1169
|
return backing.snapshot();
|
|
1157
1170
|
},
|
|
1158
1171
|
|
|
1172
|
+
_cloneSignalDeclaration() {
|
|
1173
|
+
return computed(fn);
|
|
1174
|
+
},
|
|
1175
|
+
|
|
1159
1176
|
_bindRegistry(registry, id) {
|
|
1160
1177
|
return registry.effect(() => {
|
|
1161
1178
|
backing.set(fn.call({
|
|
@@ -1180,6 +1197,9 @@ const __signalsModule = (() => {
|
|
|
1180
1197
|
[effectKind]: true,
|
|
1181
1198
|
kind: "effect",
|
|
1182
1199
|
fn,
|
|
1200
|
+
_cloneSignalDeclaration() {
|
|
1201
|
+
return effect(fn);
|
|
1202
|
+
},
|
|
1183
1203
|
_bindRegistry(registry) {
|
|
1184
1204
|
return registry.effect(fn);
|
|
1185
1205
|
}
|
|
@@ -1388,6 +1408,24 @@ const __signalsModule = (() => {
|
|
|
1388
1408
|
return requireEntry(entries, id);
|
|
1389
1409
|
},
|
|
1390
1410
|
|
|
1411
|
+
_setPath(path, value) {
|
|
1412
|
+
const parsed = parseRootPath(path);
|
|
1413
|
+
if (!entries.has(parsed.id)) {
|
|
1414
|
+
if (asyncDescriptors.has(parsed.id)) {
|
|
1415
|
+
materializeAsyncSignal(parsed.id);
|
|
1416
|
+
} else {
|
|
1417
|
+
registry.register(parsed.id, createSignal(parsed.parts.length === 0 ? value : {}));
|
|
1418
|
+
}
|
|
1419
|
+
}
|
|
1420
|
+
const entry = requireEntry(entries, parsed.id);
|
|
1421
|
+
if (parsed.parts.length === 0) {
|
|
1422
|
+
return entry.set(value);
|
|
1423
|
+
}
|
|
1424
|
+
const nextValue = setPath(entry.value, parsed.parts, value);
|
|
1425
|
+
entry.set(nextValue);
|
|
1426
|
+
return value;
|
|
1427
|
+
},
|
|
1428
|
+
|
|
1391
1429
|
_setContext(context = {}) {
|
|
1392
1430
|
Object.assign(runtimeContext, context);
|
|
1393
1431
|
return registry;
|
|
@@ -1398,10 +1436,14 @@ const __signalsModule = (() => {
|
|
|
1398
1436
|
},
|
|
1399
1437
|
|
|
1400
1438
|
_adoptMany(map = {}) {
|
|
1401
|
-
for (const id of Object.
|
|
1402
|
-
if (entries.has(id)) {
|
|
1403
|
-
|
|
1439
|
+
for (const [id, signalLike] of Object.entries(map ?? {})) {
|
|
1440
|
+
if (!entries.has(id)) {
|
|
1441
|
+
const entry = cloneSignalDeclaration(signalLike);
|
|
1442
|
+
entries.set(id, entry);
|
|
1443
|
+
bindEntry(id, entry);
|
|
1444
|
+
continue;
|
|
1404
1445
|
}
|
|
1446
|
+
bindEntry(id, entries.get(id));
|
|
1405
1447
|
}
|
|
1406
1448
|
return registry;
|
|
1407
1449
|
}
|
|
@@ -1440,6 +1482,14 @@ const __signalsModule = (() => {
|
|
|
1440
1482
|
return { id, parts, path };
|
|
1441
1483
|
}
|
|
1442
1484
|
|
|
1485
|
+
function parseRootPath(path) {
|
|
1486
|
+
if (typeof path !== "string" || path.length === 0) {
|
|
1487
|
+
throw new TypeError("Signal path must be a non-empty string.");
|
|
1488
|
+
}
|
|
1489
|
+
const [id, ...parts] = path.split(".");
|
|
1490
|
+
return { id, parts, path };
|
|
1491
|
+
}
|
|
1492
|
+
|
|
1443
1493
|
function materializeAsyncSignal(id) {
|
|
1444
1494
|
if (entries.has(id) || !asyncDescriptors.has(id)) {
|
|
1445
1495
|
return;
|
|
@@ -1479,6 +1529,16 @@ const __signalsModule = (() => {
|
|
|
1479
1529
|
return createSignal(signalLike);
|
|
1480
1530
|
}
|
|
1481
1531
|
|
|
1532
|
+
function cloneSignalDeclaration(signalLike) {
|
|
1533
|
+
if (typeof signalLike?._cloneSignalDeclaration === "function") {
|
|
1534
|
+
return signalLike._cloneSignalDeclaration();
|
|
1535
|
+
}
|
|
1536
|
+
if (isSignalLike(signalLike)) {
|
|
1537
|
+
return createSignal(typeof signalLike.snapshot === "function" ? signalLike.snapshot() : signalLike.value);
|
|
1538
|
+
}
|
|
1539
|
+
return createSignal(signalLike);
|
|
1540
|
+
}
|
|
1541
|
+
|
|
1482
1542
|
function isSignalLike(value) {
|
|
1483
1543
|
return Boolean(value && typeof value === "object" && typeof value.subscribe === "function");
|
|
1484
1544
|
}
|
|
@@ -1657,7 +1717,7 @@ const __signalsModule = (() => {
|
|
|
1657
1717
|
frame.add(path);
|
|
1658
1718
|
}
|
|
1659
1719
|
}
|
|
1660
|
-
return { createSignal, computed, effect, createSignalRegistry, isSignalRef, signal };
|
|
1720
|
+
return { createSignal, computed, effect, createSignalRegistry, cloneSignalDeclaration, isSignalRef, signal };
|
|
1661
1721
|
})();
|
|
1662
1722
|
|
|
1663
1723
|
const __htmlModule = (() => {
|
|
@@ -1899,7 +1959,12 @@ const __componentModule = (() => {
|
|
|
1899
1959
|
return lazyComponents.get(id);
|
|
1900
1960
|
},
|
|
1901
1961
|
|
|
1902
|
-
_adoptMany() {
|
|
1962
|
+
_adoptMany(map = {}) {
|
|
1963
|
+
for (const [id, Component] of Object.entries(map ?? {})) {
|
|
1964
|
+
if (!entries.has(id)) {
|
|
1965
|
+
registry.register(id, Component);
|
|
1966
|
+
}
|
|
1967
|
+
}
|
|
1903
1968
|
return registry;
|
|
1904
1969
|
}
|
|
1905
1970
|
}, registryStore, type);
|
|
@@ -2739,7 +2804,12 @@ const __handlersModule = (() => {
|
|
|
2739
2804
|
return results;
|
|
2740
2805
|
},
|
|
2741
2806
|
|
|
2742
|
-
_adoptMany() {
|
|
2807
|
+
_adoptMany(map = {}) {
|
|
2808
|
+
for (const [id, fn] of Object.entries(map ?? {})) {
|
|
2809
|
+
if (!handlers.has(id)) {
|
|
2810
|
+
registry.register(id, fn);
|
|
2811
|
+
}
|
|
2812
|
+
}
|
|
2743
2813
|
return registry;
|
|
2744
2814
|
}
|
|
2745
2815
|
}, registryStore, type);
|
|
@@ -4028,7 +4098,12 @@ const __partialsModule = (() => {
|
|
|
4028
4098
|
return normalizePartialResult(result, partialContext);
|
|
4029
4099
|
},
|
|
4030
4100
|
|
|
4031
|
-
_adoptMany() {
|
|
4101
|
+
_adoptMany(map = {}) {
|
|
4102
|
+
for (const [id, fn] of Object.entries(map ?? {})) {
|
|
4103
|
+
if (!entries.has(id)) {
|
|
4104
|
+
registry.register(id, fn);
|
|
4105
|
+
}
|
|
4106
|
+
}
|
|
4032
4107
|
return registry;
|
|
4033
4108
|
}
|
|
4034
4109
|
}, registryStore, type);
|
|
@@ -4180,7 +4255,11 @@ const __routerModule = (() => {
|
|
|
4180
4255
|
},
|
|
4181
4256
|
|
|
4182
4257
|
_adoptMany(map = {}) {
|
|
4183
|
-
for (const pattern of Object.
|
|
4258
|
+
for (const [pattern, definition] of Object.entries(map ?? {})) {
|
|
4259
|
+
if (!entries.has(pattern)) {
|
|
4260
|
+
registry.register(pattern, definition);
|
|
4261
|
+
continue;
|
|
4262
|
+
}
|
|
4184
4263
|
adoptRoute(pattern, entries.get(pattern));
|
|
4185
4264
|
}
|
|
4186
4265
|
return registry;
|
|
@@ -4676,7 +4755,7 @@ const __appModule = (() => {
|
|
|
4676
4755
|
const { createRouteRegistry, createRouter } = __routerModule;
|
|
4677
4756
|
const { createScheduler } = __schedulerModule;
|
|
4678
4757
|
const { createServerNamespace } = __serverModule;
|
|
4679
|
-
const { createSignal, createSignalRegistry } = __signalsModule;
|
|
4758
|
+
const { cloneSignalDeclaration, createSignal, createSignalRegistry } = __signalsModule;
|
|
4680
4759
|
const { createRegistryStore } = __registryStoreModule;
|
|
4681
4760
|
const { attributeName, normalizeAttributeConfig } = __attributesModule;
|
|
4682
4761
|
const { createLazyRegistry, defineRegistrySnapshot, sameRegistryValue } = __lazyRegistryModule;
|
|
@@ -4759,7 +4838,7 @@ const __appModule = (() => {
|
|
|
4759
4838
|
registryAssets: options.registryAssets,
|
|
4760
4839
|
importModule: options.importModule
|
|
4761
4840
|
});
|
|
4762
|
-
const registry = options.registry ?? app.registry
|
|
4841
|
+
const registry = options.registry ?? createRuntimeRegistry(app.registry, { target });
|
|
4763
4842
|
const signals = options.signals ?? createSignalRegistry(undefined, { registry, type: "signal", lazyRegistry });
|
|
4764
4843
|
const handlers = options.handlers ?? createHandlerRegistry(undefined, { registry, type: "handler", lazyRegistry });
|
|
4765
4844
|
const serverCache = createCacheRegistry(undefined, { registry, type: "cache.server" });
|
|
@@ -4951,7 +5030,7 @@ const __appModule = (() => {
|
|
|
4951
5030
|
|
|
4952
5031
|
if (result.signals) {
|
|
4953
5032
|
for (const [path, value] of Object.entries(result.signals)) {
|
|
4954
|
-
|
|
5033
|
+
applySignalPatch(signals, path, value);
|
|
4955
5034
|
}
|
|
4956
5035
|
}
|
|
4957
5036
|
if (result.cache?.browser) {
|
|
@@ -5140,6 +5219,22 @@ const __appModule = (() => {
|
|
|
5140
5219
|
registry?.registerMany?.(entries);
|
|
5141
5220
|
}
|
|
5142
5221
|
|
|
5222
|
+
function createRuntimeRegistry(appRegistry, { target } = {}) {
|
|
5223
|
+
const declarations = appRegistry.rawSnapshot();
|
|
5224
|
+
return createRegistryStore({
|
|
5225
|
+
...declarations,
|
|
5226
|
+
signal: cloneSignalDeclarations(declarations.signal)
|
|
5227
|
+
}, { target });
|
|
5228
|
+
}
|
|
5229
|
+
|
|
5230
|
+
function cloneSignalDeclarations(signals = {}) {
|
|
5231
|
+
const cloned = {};
|
|
5232
|
+
for (const [id, signalLike] of Object.entries(signals ?? {})) {
|
|
5233
|
+
cloned[id] = cloneSignalDeclaration(signalLike);
|
|
5234
|
+
}
|
|
5235
|
+
return cloned;
|
|
5236
|
+
}
|
|
5237
|
+
|
|
5143
5238
|
function emptyDeclarations() {
|
|
5144
5239
|
return {
|
|
5145
5240
|
signal: {},
|
|
@@ -5213,8 +5308,9 @@ const __appModule = (() => {
|
|
|
5213
5308
|
|
|
5214
5309
|
function applySnapshotToRuntime(runtime, snapshot = {}, options = {}) {
|
|
5215
5310
|
const normalized = normalizeSnapshot(snapshot);
|
|
5216
|
-
|
|
5217
|
-
|
|
5311
|
+
mergeRegistryEntries(runtime, "asyncSignal", normalized.asyncSignal, null, options);
|
|
5312
|
+
for (const [id, value] of Object.entries(normalized.signal)) {
|
|
5313
|
+
restoreSignalEntry(runtime.signals, id, value);
|
|
5218
5314
|
}
|
|
5219
5315
|
runtime.browser.cache.restore(normalized.cache.browser);
|
|
5220
5316
|
mergeRegistryEntries(runtime, "handler", normalized.handler, runtime.handlers, options);
|
|
@@ -5222,7 +5318,6 @@ const __appModule = (() => {
|
|
|
5222
5318
|
mergeRegistryEntries(runtime, "partial", normalized.partial, runtime.partials, options);
|
|
5223
5319
|
mergeRegistryEntries(runtime, "route", normalized.route, runtime.routes, options);
|
|
5224
5320
|
mergeRegistryEntries(runtime, "component", normalized.component, runtime.components, options);
|
|
5225
|
-
mergeRegistryEntries(runtime, "asyncSignal", normalized.asyncSignal, null, options);
|
|
5226
5321
|
return runtime;
|
|
5227
5322
|
}
|
|
5228
5323
|
|
|
@@ -5328,16 +5423,26 @@ const __appModule = (() => {
|
|
|
5328
5423
|
}
|
|
5329
5424
|
}
|
|
5330
5425
|
|
|
5331
|
-
function
|
|
5332
|
-
const id = String(path).split(".")[0];
|
|
5426
|
+
function restoreSignalEntry(signals, id, value) {
|
|
5333
5427
|
if (signals.has?.(id)) {
|
|
5334
|
-
|
|
5335
|
-
|
|
5336
|
-
|
|
5337
|
-
|
|
5338
|
-
return;
|
|
5339
|
-
}
|
|
5428
|
+
const entry = signals._entry?.(id);
|
|
5429
|
+
if (typeof entry?._restore === "function" && isAsyncSignalSnapshot(value)) {
|
|
5430
|
+
entry._restore(value);
|
|
5431
|
+
return;
|
|
5340
5432
|
}
|
|
5433
|
+
signals.set(id, value);
|
|
5434
|
+
return;
|
|
5435
|
+
}
|
|
5436
|
+
signals.register(id, createSignal(value));
|
|
5437
|
+
}
|
|
5438
|
+
|
|
5439
|
+
function applySignalPatch(signals, path, value) {
|
|
5440
|
+
if (typeof signals._setPath === "function") {
|
|
5441
|
+
signals._setPath(path, value);
|
|
5442
|
+
return;
|
|
5443
|
+
}
|
|
5444
|
+
const id = String(path).split(".")[0];
|
|
5445
|
+
if (signals.has?.(id)) {
|
|
5341
5446
|
signals.set(path, value);
|
|
5342
5447
|
return;
|
|
5343
5448
|
}
|