@async/framework 0.4.0 → 0.6.0
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 +32 -0
- package/README.md +124 -7
- package/examples/cache/index.html +1 -1
- package/examples/components/index.html +1 -1
- package/examples/components/main.js +2 -2
- package/examples/counter/index.html +1 -1
- package/examples/partials/index.html +1 -1
- package/examples/product/index.html +1 -1
- package/examples/product/main.js +2 -2
- package/examples/router/index.html +1 -1
- package/examples/server-call/index.html +1 -1
- package/examples/ssr/index.html +1 -1
- package/examples/streaming/index.html +1 -1
- package/framework.d.ts +569 -0
- package/framework.js +325 -101
- package/framework.min.js +3648 -0
- package/framework.ts +3 -0
- package/framework.umd.js +4158 -0
- package/framework.umd.min.js +3671 -0
- package/package.json +34 -5
- package/src/app.js +2 -2
- package/src/async-signal.js +12 -1
- package/src/cache.js +5 -0
- package/src/component.js +80 -16
- package/src/handlers.js +12 -4
- package/src/index.js +1 -1
- package/src/loader.js +93 -9
- package/src/partials.js +5 -0
- package/src/registry-store.js +4 -0
- package/src/router.js +11 -2
- package/src/server.js +26 -6
- package/src/signals.js +16 -3
package/framework.js
CHANGED
|
@@ -86,7 +86,18 @@ const __asyncSignalModule = (() => {
|
|
|
86
86
|
signals: registry,
|
|
87
87
|
id: registeredId,
|
|
88
88
|
get server() {
|
|
89
|
-
|
|
89
|
+
const context = registry._context?.() ?? {};
|
|
90
|
+
const server = context.server;
|
|
91
|
+
if (typeof server?._withContext === "function") {
|
|
92
|
+
return server._withContext({
|
|
93
|
+
signals: registry,
|
|
94
|
+
router: context.router,
|
|
95
|
+
loader: context.loader,
|
|
96
|
+
cache: context.cache,
|
|
97
|
+
abort: activeAbort
|
|
98
|
+
});
|
|
99
|
+
}
|
|
100
|
+
return server;
|
|
90
101
|
},
|
|
91
102
|
get router() {
|
|
92
103
|
return registry._context?.().router;
|
|
@@ -280,6 +291,10 @@ const __registryStoreModule = (() => {
|
|
|
280
291
|
return value;
|
|
281
292
|
},
|
|
282
293
|
|
|
294
|
+
unregister(type, id) {
|
|
295
|
+
return registry.delete(type, id);
|
|
296
|
+
},
|
|
297
|
+
|
|
283
298
|
delete(type, id) {
|
|
284
299
|
return registry._map(type).delete(id);
|
|
285
300
|
},
|
|
@@ -540,6 +555,11 @@ const __cacheModule = (() => {
|
|
|
540
555
|
return registryApi;
|
|
541
556
|
},
|
|
542
557
|
|
|
558
|
+
unregister(id) {
|
|
559
|
+
assertId(id);
|
|
560
|
+
return definitions.delete(id);
|
|
561
|
+
},
|
|
562
|
+
|
|
543
563
|
resolve(id) {
|
|
544
564
|
assertId(id);
|
|
545
565
|
return definitions.get(id);
|
|
@@ -667,6 +687,62 @@ const __cacheModule = (() => {
|
|
|
667
687
|
return { defineCache, createCacheRegistry };
|
|
668
688
|
})();
|
|
669
689
|
|
|
690
|
+
const __attributesModule = (() => {
|
|
691
|
+
const defaultPrefixes = Object.freeze({
|
|
692
|
+
async: ["async:"],
|
|
693
|
+
class: ["class:"],
|
|
694
|
+
signal: ["signal:"],
|
|
695
|
+
on: ["on:"]
|
|
696
|
+
});
|
|
697
|
+
|
|
698
|
+
function defineAttributeConfig(config = {}) {
|
|
699
|
+
return normalizeAttributeConfig(config);
|
|
700
|
+
}
|
|
701
|
+
|
|
702
|
+
function normalizeAttributeConfig(config = {}) {
|
|
703
|
+
return {
|
|
704
|
+
async: normalizePrefixes(config.async, defaultPrefixes.async),
|
|
705
|
+
class: normalizePrefixes(config.class, defaultPrefixes.class),
|
|
706
|
+
signal: normalizePrefixes(config.signal, defaultPrefixes.signal),
|
|
707
|
+
on: normalizePrefixes(config.on, defaultPrefixes.on)
|
|
708
|
+
};
|
|
709
|
+
}
|
|
710
|
+
|
|
711
|
+
function attributeName(attributes, type, name) {
|
|
712
|
+
return normalizeAttributeConfig(attributes)[type][0] + name;
|
|
713
|
+
}
|
|
714
|
+
|
|
715
|
+
function readAttribute(element, attributes, type, name) {
|
|
716
|
+
for (const prefix of normalizeAttributeConfig(attributes)[type]) {
|
|
717
|
+
const attr = `${prefix}${name}`;
|
|
718
|
+
if (element.hasAttribute?.(attr)) {
|
|
719
|
+
return element.getAttribute(attr);
|
|
720
|
+
}
|
|
721
|
+
}
|
|
722
|
+
return null;
|
|
723
|
+
}
|
|
724
|
+
|
|
725
|
+
function matchAttribute(name, attributes, type) {
|
|
726
|
+
for (const prefix of normalizeAttributeConfig(attributes)[type]) {
|
|
727
|
+
if (name.startsWith(prefix)) {
|
|
728
|
+
return name.slice(prefix.length);
|
|
729
|
+
}
|
|
730
|
+
}
|
|
731
|
+
return null;
|
|
732
|
+
}
|
|
733
|
+
|
|
734
|
+
function normalizePrefixes(value, fallback) {
|
|
735
|
+
const prefixes = value == null ? fallback : Array.isArray(value) ? value : [value];
|
|
736
|
+
return prefixes.map((prefix) => {
|
|
737
|
+
if (typeof prefix !== "string" || prefix.length === 0) {
|
|
738
|
+
throw new TypeError("Attribute prefixes must be non-empty strings.");
|
|
739
|
+
}
|
|
740
|
+
return prefix;
|
|
741
|
+
});
|
|
742
|
+
}
|
|
743
|
+
return { defineAttributeConfig, normalizeAttributeConfig, attributeName, readAttribute, matchAttribute };
|
|
744
|
+
})();
|
|
745
|
+
|
|
670
746
|
const __signalsModule = (() => {
|
|
671
747
|
const { asyncSignal: createAsyncSignal, isAsyncSignal } = __asyncSignalModule;
|
|
672
748
|
const { attachRegistryInspection, createRegistryStore } = __registryStoreModule;
|
|
@@ -790,7 +866,7 @@ const __signalsModule = (() => {
|
|
|
790
866
|
const registryStore = options.registry ?? createRegistryStore();
|
|
791
867
|
const type = options.type ?? "signal";
|
|
792
868
|
const entries = registryStore._map(type);
|
|
793
|
-
const registryCleanups = new
|
|
869
|
+
const registryCleanups = new Map();
|
|
794
870
|
const runtimeContext = {};
|
|
795
871
|
const boundEntries = new Set();
|
|
796
872
|
|
|
@@ -813,6 +889,19 @@ const __signalsModule = (() => {
|
|
|
813
889
|
return registry;
|
|
814
890
|
},
|
|
815
891
|
|
|
892
|
+
unregister(id) {
|
|
893
|
+
assertId(id);
|
|
894
|
+
if (!entries.has(id)) {
|
|
895
|
+
return false;
|
|
896
|
+
}
|
|
897
|
+
registryCleanups.get(id)?.();
|
|
898
|
+
registryCleanups.delete(id);
|
|
899
|
+
entries.get(id)?._dispose?.();
|
|
900
|
+
entries.delete(id);
|
|
901
|
+
boundEntries.delete(id);
|
|
902
|
+
return true;
|
|
903
|
+
},
|
|
904
|
+
|
|
816
905
|
ensure(id, initial) {
|
|
817
906
|
assertId(id);
|
|
818
907
|
if (!entries.has(id)) {
|
|
@@ -925,7 +1014,7 @@ const __signalsModule = (() => {
|
|
|
925
1014
|
},
|
|
926
1015
|
|
|
927
1016
|
destroy() {
|
|
928
|
-
for (const cleanup of registryCleanups) {
|
|
1017
|
+
for (const cleanup of registryCleanups.values()) {
|
|
929
1018
|
cleanup();
|
|
930
1019
|
}
|
|
931
1020
|
registryCleanups.clear();
|
|
@@ -982,7 +1071,7 @@ const __signalsModule = (() => {
|
|
|
982
1071
|
boundEntries.add(id);
|
|
983
1072
|
const cleanup = entry._bindRegistry(registry, id);
|
|
984
1073
|
if (typeof cleanup === "function") {
|
|
985
|
-
registryCleanups.
|
|
1074
|
+
registryCleanups.set(id, cleanup);
|
|
986
1075
|
}
|
|
987
1076
|
}
|
|
988
1077
|
}
|
|
@@ -1175,62 +1264,6 @@ const __signalsModule = (() => {
|
|
|
1175
1264
|
return { createSignal, computed, effect, createSignalRegistry, isSignalRef, signal };
|
|
1176
1265
|
})();
|
|
1177
1266
|
|
|
1178
|
-
const __attributesModule = (() => {
|
|
1179
|
-
const defaultPrefixes = Object.freeze({
|
|
1180
|
-
async: ["async:"],
|
|
1181
|
-
class: ["class:"],
|
|
1182
|
-
signal: ["signal:"],
|
|
1183
|
-
on: ["on:"]
|
|
1184
|
-
});
|
|
1185
|
-
|
|
1186
|
-
function defineAttributeConfig(config = {}) {
|
|
1187
|
-
return normalizeAttributeConfig(config);
|
|
1188
|
-
}
|
|
1189
|
-
|
|
1190
|
-
function normalizeAttributeConfig(config = {}) {
|
|
1191
|
-
return {
|
|
1192
|
-
async: normalizePrefixes(config.async, defaultPrefixes.async),
|
|
1193
|
-
class: normalizePrefixes(config.class, defaultPrefixes.class),
|
|
1194
|
-
signal: normalizePrefixes(config.signal, defaultPrefixes.signal),
|
|
1195
|
-
on: normalizePrefixes(config.on, defaultPrefixes.on)
|
|
1196
|
-
};
|
|
1197
|
-
}
|
|
1198
|
-
|
|
1199
|
-
function attributeName(attributes, type, name) {
|
|
1200
|
-
return normalizeAttributeConfig(attributes)[type][0] + name;
|
|
1201
|
-
}
|
|
1202
|
-
|
|
1203
|
-
function readAttribute(element, attributes, type, name) {
|
|
1204
|
-
for (const prefix of normalizeAttributeConfig(attributes)[type]) {
|
|
1205
|
-
const attr = `${prefix}${name}`;
|
|
1206
|
-
if (element.hasAttribute?.(attr)) {
|
|
1207
|
-
return element.getAttribute(attr);
|
|
1208
|
-
}
|
|
1209
|
-
}
|
|
1210
|
-
return null;
|
|
1211
|
-
}
|
|
1212
|
-
|
|
1213
|
-
function matchAttribute(name, attributes, type) {
|
|
1214
|
-
for (const prefix of normalizeAttributeConfig(attributes)[type]) {
|
|
1215
|
-
if (name.startsWith(prefix)) {
|
|
1216
|
-
return name.slice(prefix.length);
|
|
1217
|
-
}
|
|
1218
|
-
}
|
|
1219
|
-
return null;
|
|
1220
|
-
}
|
|
1221
|
-
|
|
1222
|
-
function normalizePrefixes(value, fallback) {
|
|
1223
|
-
const prefixes = value == null ? fallback : Array.isArray(value) ? value : [value];
|
|
1224
|
-
return prefixes.map((prefix) => {
|
|
1225
|
-
if (typeof prefix !== "string" || prefix.length === 0) {
|
|
1226
|
-
throw new TypeError("Attribute prefixes must be non-empty strings.");
|
|
1227
|
-
}
|
|
1228
|
-
return prefix;
|
|
1229
|
-
});
|
|
1230
|
-
}
|
|
1231
|
-
return { defineAttributeConfig, normalizeAttributeConfig, attributeName, readAttribute, matchAttribute };
|
|
1232
|
-
})();
|
|
1233
|
-
|
|
1234
1267
|
const __htmlModule = (() => {
|
|
1235
1268
|
const { isSignalRef } = __signalsModule;
|
|
1236
1269
|
const { attributeName, matchAttribute, normalizeAttributeConfig } = __attributesModule;
|
|
@@ -1393,7 +1426,8 @@ const __htmlModule = (() => {
|
|
|
1393
1426
|
})();
|
|
1394
1427
|
|
|
1395
1428
|
const __componentModule = (() => {
|
|
1396
|
-
const {
|
|
1429
|
+
const { attributeName } = __attributesModule;
|
|
1430
|
+
const { escapeHtml, rawHtml, renderTemplate } = __htmlModule;
|
|
1397
1431
|
const { attachRegistryInspection, createRegistryStore } = __registryStoreModule;
|
|
1398
1432
|
const componentKind = Symbol.for("@async/framework.component");
|
|
1399
1433
|
let componentCounter = 0;
|
|
@@ -1438,6 +1472,13 @@ const __componentModule = (() => {
|
|
|
1438
1472
|
return registry;
|
|
1439
1473
|
},
|
|
1440
1474
|
|
|
1475
|
+
unregister(id) {
|
|
1476
|
+
if (typeof id !== "string" || id.length === 0) {
|
|
1477
|
+
throw new TypeError("Component id must be a non-empty string.");
|
|
1478
|
+
}
|
|
1479
|
+
return entries.delete(id);
|
|
1480
|
+
},
|
|
1481
|
+
|
|
1441
1482
|
resolve(id) {
|
|
1442
1483
|
if (typeof id !== "string" || id.length === 0) {
|
|
1443
1484
|
throw new TypeError("Component id must be a non-empty string.");
|
|
@@ -1469,29 +1510,32 @@ const __componentModule = (() => {
|
|
|
1469
1510
|
const visibleHooks = [];
|
|
1470
1511
|
const destroyHooks = [];
|
|
1471
1512
|
const bindingIds = [];
|
|
1472
|
-
const
|
|
1473
|
-
runtime,
|
|
1474
|
-
scope,
|
|
1475
|
-
cleanups,
|
|
1476
|
-
attachHooks,
|
|
1477
|
-
visibleHooks,
|
|
1478
|
-
destroyHooks
|
|
1479
|
-
});
|
|
1480
|
-
|
|
1481
|
-
const output = Component.call(context, props);
|
|
1482
|
-
const html = renderTemplate(output, {
|
|
1513
|
+
const templateOptions = {
|
|
1483
1514
|
attributes: runtime.attributes,
|
|
1484
1515
|
signals: runtime.signals,
|
|
1485
1516
|
bind(value) {
|
|
1486
1517
|
const id = runtime.loader?._registerBinding?.(value);
|
|
1487
1518
|
if (!id) {
|
|
1488
|
-
throw new Error("Inline template bindings require
|
|
1519
|
+
throw new Error("Inline template bindings require a Loader.");
|
|
1489
1520
|
}
|
|
1490
1521
|
bindingIds.push(id);
|
|
1491
1522
|
return id;
|
|
1492
1523
|
}
|
|
1524
|
+
};
|
|
1525
|
+
const renderScopedTemplate = (value) => renderTemplate(value, templateOptions);
|
|
1526
|
+
const context = createComponentContext({
|
|
1527
|
+
runtime,
|
|
1528
|
+
scope,
|
|
1529
|
+
cleanups,
|
|
1530
|
+
attachHooks,
|
|
1531
|
+
visibleHooks,
|
|
1532
|
+
destroyHooks,
|
|
1533
|
+
renderScopedTemplate
|
|
1493
1534
|
});
|
|
1494
1535
|
|
|
1536
|
+
const output = Component.call(context, props);
|
|
1537
|
+
const html = renderScopedTemplate(output);
|
|
1538
|
+
|
|
1495
1539
|
return {
|
|
1496
1540
|
html,
|
|
1497
1541
|
attach(target) {
|
|
@@ -1527,7 +1571,7 @@ const __componentModule = (() => {
|
|
|
1527
1571
|
};
|
|
1528
1572
|
}
|
|
1529
1573
|
|
|
1530
|
-
function createComponentContext({ runtime, scope, cleanups, attachHooks, visibleHooks, destroyHooks }) {
|
|
1574
|
+
function createComponentContext({ runtime, scope, cleanups, attachHooks, visibleHooks, destroyHooks, renderScopedTemplate }) {
|
|
1531
1575
|
const { signals, handlers, loader, server, router, cache } = runtime;
|
|
1532
1576
|
const generatedHandlers = new WeakMap();
|
|
1533
1577
|
let generatedHandlerCounter = 0;
|
|
@@ -1543,14 +1587,27 @@ const __componentModule = (() => {
|
|
|
1543
1587
|
|
|
1544
1588
|
signal(name, initial) {
|
|
1545
1589
|
if (arguments.length === 1) {
|
|
1546
|
-
|
|
1590
|
+
const id = scoped(scope, `signal.${++generatedSignalCounter}`);
|
|
1591
|
+
const ref = signals.ensure(id, name);
|
|
1592
|
+
cleanups.push(() => signals.unregister?.(id));
|
|
1593
|
+
return ref;
|
|
1594
|
+
}
|
|
1595
|
+
const id = scoped(scope, name);
|
|
1596
|
+
const created = !signals.has(id);
|
|
1597
|
+
const ref = signals.ensure(id, initial);
|
|
1598
|
+
if (created) {
|
|
1599
|
+
cleanups.push(() => signals.unregister?.(id));
|
|
1547
1600
|
}
|
|
1548
|
-
return
|
|
1601
|
+
return ref;
|
|
1549
1602
|
},
|
|
1550
1603
|
|
|
1551
1604
|
computed(name, fn) {
|
|
1552
1605
|
const id = scoped(scope, name);
|
|
1606
|
+
const created = !signals.has(id);
|
|
1553
1607
|
const ref = signals.ensure(id, undefined);
|
|
1608
|
+
if (created) {
|
|
1609
|
+
cleanups.push(() => signals.unregister?.(id));
|
|
1610
|
+
}
|
|
1554
1611
|
const cleanup = signals.effect(() => {
|
|
1555
1612
|
signals.set(id, fn.call(context));
|
|
1556
1613
|
});
|
|
@@ -1560,9 +1617,13 @@ const __componentModule = (() => {
|
|
|
1560
1617
|
|
|
1561
1618
|
asyncSignal(name, fn) {
|
|
1562
1619
|
const id = scoped(scope, name);
|
|
1620
|
+
const created = !signals.has(id);
|
|
1563
1621
|
if (!signals.has(id)) {
|
|
1564
1622
|
signals.asyncSignal(id, fn);
|
|
1565
1623
|
}
|
|
1624
|
+
if (created) {
|
|
1625
|
+
cleanups.push(() => signals.unregister?.(id));
|
|
1626
|
+
}
|
|
1566
1627
|
return signals.ref(id);
|
|
1567
1628
|
},
|
|
1568
1629
|
|
|
@@ -1596,6 +1657,26 @@ const __componentModule = (() => {
|
|
|
1596
1657
|
return rawHtml(child.html);
|
|
1597
1658
|
},
|
|
1598
1659
|
|
|
1660
|
+
suspense(signalRef, views) {
|
|
1661
|
+
const id = signalRef?.id;
|
|
1662
|
+
if (!id) {
|
|
1663
|
+
throw new TypeError("this.suspense(signalRef, views) requires a signal ref.");
|
|
1664
|
+
}
|
|
1665
|
+
|
|
1666
|
+
const normalized = normalizeSuspenseViews(views);
|
|
1667
|
+
const chunks = [];
|
|
1668
|
+
for (const state of ["loading", "ready", "error"]) {
|
|
1669
|
+
const view = normalized[state];
|
|
1670
|
+
if (!view) {
|
|
1671
|
+
continue;
|
|
1672
|
+
}
|
|
1673
|
+
const attr = attributeName(runtime.attributes, "async", state);
|
|
1674
|
+
const body = renderScopedTemplate(view.call(context, signalRef));
|
|
1675
|
+
chunks.push(`<template ${attr}="${escapeHtml(id)}">${body}</template>`);
|
|
1676
|
+
}
|
|
1677
|
+
return rawHtml(chunks.join(""));
|
|
1678
|
+
},
|
|
1679
|
+
|
|
1599
1680
|
on(eventName, fn) {
|
|
1600
1681
|
if (typeof eventName !== "string" || eventName.length === 0) {
|
|
1601
1682
|
throw new TypeError("Component lifecycle event must be a non-empty string.");
|
|
@@ -1635,6 +1716,7 @@ const __componentModule = (() => {
|
|
|
1635
1716
|
handlers.register(id, function runComponentHandler(handlerContext) {
|
|
1636
1717
|
return fn.call({ ...context, ...handlerContext }, handlerContext);
|
|
1637
1718
|
});
|
|
1719
|
+
cleanups.push(() => handlers.unregister?.(id));
|
|
1638
1720
|
return id;
|
|
1639
1721
|
}
|
|
1640
1722
|
}
|
|
@@ -1646,6 +1728,21 @@ const __componentModule = (() => {
|
|
|
1646
1728
|
return `${scope}.${name}`;
|
|
1647
1729
|
}
|
|
1648
1730
|
|
|
1731
|
+
function normalizeSuspenseViews(views) {
|
|
1732
|
+
const normalized = typeof views === "function" ? { ready: views } : views;
|
|
1733
|
+
if (!normalized || typeof normalized !== "object" || Array.isArray(normalized)) {
|
|
1734
|
+
throw new TypeError("this.suspense(signalRef, views) requires views to be a function or object.");
|
|
1735
|
+
}
|
|
1736
|
+
|
|
1737
|
+
for (const state of ["loading", "ready", "error"]) {
|
|
1738
|
+
if (Object.hasOwn(normalized, state) && normalized[state] !== undefined && typeof normalized[state] !== "function") {
|
|
1739
|
+
throw new TypeError(`this.suspense(signalRef, views) view "${state}" must be a function.`);
|
|
1740
|
+
}
|
|
1741
|
+
}
|
|
1742
|
+
|
|
1743
|
+
return normalized;
|
|
1744
|
+
}
|
|
1745
|
+
|
|
1649
1746
|
function componentName(Component) {
|
|
1650
1747
|
return Component.displayName || Component.name || "anonymous";
|
|
1651
1748
|
}
|
|
@@ -1682,6 +1779,11 @@ const __serverModule = (() => {
|
|
|
1682
1779
|
return registry;
|
|
1683
1780
|
},
|
|
1684
1781
|
|
|
1782
|
+
unregister(id) {
|
|
1783
|
+
assertServerId(id);
|
|
1784
|
+
return entries.delete(id);
|
|
1785
|
+
},
|
|
1786
|
+
|
|
1685
1787
|
resolve(id) {
|
|
1686
1788
|
assertServerId(id);
|
|
1687
1789
|
return entries.get(id);
|
|
@@ -1697,7 +1799,7 @@ const __serverModule = (() => {
|
|
|
1697
1799
|
let runContext;
|
|
1698
1800
|
const server = createServerNamespace((childId, childArgs, childContext = {}) => {
|
|
1699
1801
|
return registry.run(childId, childArgs, { ...runContext, ...childContext });
|
|
1700
|
-
});
|
|
1802
|
+
}, {}, () => runContext);
|
|
1701
1803
|
|
|
1702
1804
|
const mergedContext = {
|
|
1703
1805
|
...defaults,
|
|
@@ -1730,7 +1832,7 @@ const __serverModule = (() => {
|
|
|
1730
1832
|
}, registryStore, type);
|
|
1731
1833
|
|
|
1732
1834
|
registry.registerMany(initialMap);
|
|
1733
|
-
return createServerNamespace((id, args, context) => registry.run(id, args, context), registry);
|
|
1835
|
+
return createServerNamespace((id, args, context) => registry.run(id, args, context), registry, () => defaults);
|
|
1734
1836
|
}
|
|
1735
1837
|
|
|
1736
1838
|
function createServerProxy({
|
|
@@ -1781,7 +1883,7 @@ const __serverModule = (() => {
|
|
|
1781
1883
|
_setContext(context = {}) {
|
|
1782
1884
|
Object.assign(defaults, context);
|
|
1783
1885
|
}
|
|
1784
|
-
});
|
|
1886
|
+
}, () => defaults);
|
|
1785
1887
|
}
|
|
1786
1888
|
|
|
1787
1889
|
function resolveServerCommandArguments(args, context = {}) {
|
|
@@ -1859,7 +1961,7 @@ const __serverModule = (() => {
|
|
|
1859
1961
|
};
|
|
1860
1962
|
}
|
|
1861
1963
|
|
|
1862
|
-
function createServerNamespace(run, root = {}) {
|
|
1964
|
+
function createServerNamespace(run, root = {}, contextProvider = () => ({})) {
|
|
1863
1965
|
const cache = new Map();
|
|
1864
1966
|
|
|
1865
1967
|
function namespace(parts) {
|
|
@@ -1868,11 +1970,14 @@ const __serverModule = (() => {
|
|
|
1868
1970
|
return cache.get(cacheKey);
|
|
1869
1971
|
}
|
|
1870
1972
|
|
|
1871
|
-
const callable = (...args) => {
|
|
1973
|
+
const callable = async (...args) => {
|
|
1872
1974
|
if (parts.length === 0) {
|
|
1873
1975
|
throw new Error("Server namespace is not directly callable.");
|
|
1874
1976
|
}
|
|
1875
|
-
|
|
1977
|
+
const context = contextProvider() ?? {};
|
|
1978
|
+
const result = await run(parts.join("."), args, context);
|
|
1979
|
+
await applyServerResult(result, context);
|
|
1980
|
+
return unwrapServerResult(result);
|
|
1876
1981
|
};
|
|
1877
1982
|
|
|
1878
1983
|
const proxy = new Proxy(callable, {
|
|
@@ -1883,6 +1988,18 @@ const __serverModule = (() => {
|
|
|
1883
1988
|
if (prop in _target) {
|
|
1884
1989
|
return _target[prop];
|
|
1885
1990
|
}
|
|
1991
|
+
if (parts.length === 0 && prop === "_withContext") {
|
|
1992
|
+
return (context = {}) => createServerNamespace(run, root, () => ({
|
|
1993
|
+
...(contextProvider() ?? {}),
|
|
1994
|
+
...context
|
|
1995
|
+
}));
|
|
1996
|
+
}
|
|
1997
|
+
if (parts.length === 0 && prop === "run" && typeof root.run === "function") {
|
|
1998
|
+
return (id, args = [], context = {}) => root.run(id, args, {
|
|
1999
|
+
...(contextProvider() ?? {}),
|
|
2000
|
+
...context
|
|
2001
|
+
});
|
|
2002
|
+
}
|
|
1886
2003
|
if (parts.length === 0 && Object.hasOwn(root, prop)) {
|
|
1887
2004
|
return root[prop];
|
|
1888
2005
|
}
|
|
@@ -2035,11 +2152,10 @@ const __serverModule = (() => {
|
|
|
2035
2152
|
const __handlersModule = (() => {
|
|
2036
2153
|
const { applyServerResult, defaultInput, resolveServerCommandArguments, unwrapServerResult } = __serverModule;
|
|
2037
2154
|
const { attachRegistryInspection, createRegistryStore } = __registryStoreModule;
|
|
2038
|
-
const builtInTokens = new Set(["preventDefault", "stopPropagation", "stopImmediatePropagation"]);
|
|
2155
|
+
const builtInTokens = new Set(["prevent", "preventDefault", "stopPropagation", "stopImmediatePropagation"]);
|
|
2039
2156
|
const builtInHandlers = {
|
|
2040
|
-
preventDefault
|
|
2041
|
-
|
|
2042
|
-
},
|
|
2157
|
+
prevent: preventDefault,
|
|
2158
|
+
preventDefault,
|
|
2043
2159
|
stopPropagation() {
|
|
2044
2160
|
this.event?.stopPropagation?.();
|
|
2045
2161
|
},
|
|
@@ -2048,6 +2164,10 @@ const __handlersModule = (() => {
|
|
|
2048
2164
|
}
|
|
2049
2165
|
};
|
|
2050
2166
|
|
|
2167
|
+
function preventDefault() {
|
|
2168
|
+
this.event?.preventDefault?.();
|
|
2169
|
+
}
|
|
2170
|
+
|
|
2051
2171
|
function createHandlerRegistry(initialMap = {}, options = {}) {
|
|
2052
2172
|
const registryStore = options.registry ?? createRegistryStore();
|
|
2053
2173
|
const type = options.type ?? "handler";
|
|
@@ -2073,6 +2193,11 @@ const __handlersModule = (() => {
|
|
|
2073
2193
|
return registry;
|
|
2074
2194
|
},
|
|
2075
2195
|
|
|
2196
|
+
unregister(id) {
|
|
2197
|
+
assertId(id);
|
|
2198
|
+
return handlers.delete(id);
|
|
2199
|
+
},
|
|
2200
|
+
|
|
2076
2201
|
resolve(id) {
|
|
2077
2202
|
assertId(id);
|
|
2078
2203
|
return handlers.get(id);
|
|
@@ -2231,7 +2356,7 @@ const __loaderModule = (() => {
|
|
|
2231
2356
|
const { matchAttribute, normalizeAttributeConfig, readAttribute } = __attributesModule;
|
|
2232
2357
|
const inlineBindingPrefix = "__async:inline:";
|
|
2233
2358
|
|
|
2234
|
-
function
|
|
2359
|
+
function Loader({ root, signals, handlers, server, router, cache, attributes } = {}) {
|
|
2235
2360
|
const documentRef = root?.ownerDocument ?? root ?? globalThis.document;
|
|
2236
2361
|
const rootNode = root ?? documentRef;
|
|
2237
2362
|
const signalRegistry = signals ?? createSignalRegistry();
|
|
@@ -2245,6 +2370,7 @@ const __loaderModule = (() => {
|
|
|
2245
2370
|
const boundaryState = new WeakMap();
|
|
2246
2371
|
const renderingBoundaries = new WeakSet();
|
|
2247
2372
|
const inlineBindings = new Map();
|
|
2373
|
+
const scopedCleanups = new WeakMap();
|
|
2248
2374
|
let inlineBindingCounter = 0;
|
|
2249
2375
|
let destroyed = false;
|
|
2250
2376
|
|
|
@@ -2279,6 +2405,7 @@ const __loaderModule = (() => {
|
|
|
2279
2405
|
if (!boundary) {
|
|
2280
2406
|
throw new Error(`Boundary "${boundaryId}" was not found.`);
|
|
2281
2407
|
}
|
|
2408
|
+
cleanupChildren(boundary);
|
|
2282
2409
|
boundary.replaceChildren(toFragment(fragmentOrTemplate, documentRef));
|
|
2283
2410
|
api.scan(boundary);
|
|
2284
2411
|
return boundary;
|
|
@@ -2295,11 +2422,12 @@ const __loaderModule = (() => {
|
|
|
2295
2422
|
cache: api.cache,
|
|
2296
2423
|
attributes: attributeConfig
|
|
2297
2424
|
});
|
|
2425
|
+
cleanupChildren(target);
|
|
2298
2426
|
target.replaceChildren(toFragment(rendered.html, target.ownerDocument));
|
|
2299
2427
|
api.scan(target);
|
|
2300
2428
|
rendered.mount(target);
|
|
2301
2429
|
rendered.visible(target, api._observeVisible);
|
|
2302
|
-
|
|
2430
|
+
addCleanup(rendered.cleanup, target, "children");
|
|
2303
2431
|
return rendered;
|
|
2304
2432
|
},
|
|
2305
2433
|
|
|
@@ -2309,7 +2437,7 @@ const __loaderModule = (() => {
|
|
|
2309
2437
|
}
|
|
2310
2438
|
destroyed = true;
|
|
2311
2439
|
for (const cleanup of [...cleanups]) {
|
|
2312
|
-
cleanup
|
|
2440
|
+
runCleanup(cleanup);
|
|
2313
2441
|
}
|
|
2314
2442
|
cleanups.clear();
|
|
2315
2443
|
},
|
|
@@ -2330,6 +2458,13 @@ const __loaderModule = (() => {
|
|
|
2330
2458
|
};
|
|
2331
2459
|
|
|
2332
2460
|
signalRegistry._setContext?.({ server: api.server, router: api.router, loader: api, cache: api.cache });
|
|
2461
|
+
api.server?._setContext?.({
|
|
2462
|
+
signals: signalRegistry,
|
|
2463
|
+
handlers: handlerRegistry,
|
|
2464
|
+
loader: api,
|
|
2465
|
+
router: api.router,
|
|
2466
|
+
cache: api.cache
|
|
2467
|
+
});
|
|
2333
2468
|
|
|
2334
2469
|
function bindEventAttributes(scope) {
|
|
2335
2470
|
for (const element of elementsIn(scope)) {
|
|
@@ -2378,7 +2513,7 @@ const __loaderModule = (() => {
|
|
|
2378
2513
|
};
|
|
2379
2514
|
|
|
2380
2515
|
element.addEventListener(eventName, listener);
|
|
2381
|
-
|
|
2516
|
+
addCleanup(() => element.removeEventListener(eventName, listener), element);
|
|
2382
2517
|
}
|
|
2383
2518
|
|
|
2384
2519
|
function bindSignalAttributes(scope) {
|
|
@@ -2413,6 +2548,12 @@ const __loaderModule = (() => {
|
|
|
2413
2548
|
bindSignal(element, `attr:${attr}:${path}`, path, (value) => updateAttribute(element, attr, value));
|
|
2414
2549
|
continue;
|
|
2415
2550
|
}
|
|
2551
|
+
if (signalName.startsWith("prop:")) {
|
|
2552
|
+
const prop = signalName.slice("prop:".length);
|
|
2553
|
+
const path = element.getAttribute(name);
|
|
2554
|
+
bindSignal(element, `prop:${prop}:${path}`, path, (value) => updateProperty(element, prop, value));
|
|
2555
|
+
continue;
|
|
2556
|
+
}
|
|
2416
2557
|
if (signalName.startsWith("class:")) {
|
|
2417
2558
|
const className = signalName.slice("class:".length);
|
|
2418
2559
|
const path = element.getAttribute(name);
|
|
@@ -2481,7 +2622,7 @@ const __loaderModule = (() => {
|
|
|
2481
2622
|
|
|
2482
2623
|
const read = () => readBinding(path, options);
|
|
2483
2624
|
apply(read());
|
|
2484
|
-
|
|
2625
|
+
addCleanup(subscribeBinding(path, () => apply(read())), element);
|
|
2485
2626
|
}
|
|
2486
2627
|
|
|
2487
2628
|
function bindValueWriter(element, path) {
|
|
@@ -2545,7 +2686,7 @@ const __loaderModule = (() => {
|
|
|
2545
2686
|
cleanup: signalRegistry.subscribe(`${id}.$status`, () => renderBoundary(boundary))
|
|
2546
2687
|
};
|
|
2547
2688
|
boundaryState.set(boundary, state);
|
|
2548
|
-
|
|
2689
|
+
addCleanup(state.cleanup, boundary);
|
|
2549
2690
|
}
|
|
2550
2691
|
renderBoundary(boundary);
|
|
2551
2692
|
}
|
|
@@ -2561,6 +2702,7 @@ const __loaderModule = (() => {
|
|
|
2561
2702
|
if (!template) {
|
|
2562
2703
|
return;
|
|
2563
2704
|
}
|
|
2705
|
+
cleanupChildren(boundary);
|
|
2564
2706
|
boundary.replaceChildren(template.content.cloneNode(true));
|
|
2565
2707
|
renderingBoundaries.add(boundary);
|
|
2566
2708
|
try {
|
|
@@ -2594,7 +2736,7 @@ const __loaderModule = (() => {
|
|
|
2594
2736
|
continue;
|
|
2595
2737
|
}
|
|
2596
2738
|
visibleElements.add(element);
|
|
2597
|
-
|
|
2739
|
+
addCleanup(observeVisible(element, () => runPseudo(element, ref)), element);
|
|
2598
2740
|
}
|
|
2599
2741
|
}
|
|
2600
2742
|
|
|
@@ -2624,7 +2766,7 @@ const __loaderModule = (() => {
|
|
|
2624
2766
|
});
|
|
2625
2767
|
for (const result of results) {
|
|
2626
2768
|
if (typeof result === "function") {
|
|
2627
|
-
|
|
2769
|
+
addCleanup(result, element);
|
|
2628
2770
|
}
|
|
2629
2771
|
}
|
|
2630
2772
|
} catch (error) {
|
|
@@ -2656,13 +2798,72 @@ const __loaderModule = (() => {
|
|
|
2656
2798
|
|
|
2657
2799
|
function assertActive() {
|
|
2658
2800
|
if (destroyed) {
|
|
2659
|
-
throw new Error("
|
|
2801
|
+
throw new Error("Loader has been destroyed.");
|
|
2802
|
+
}
|
|
2803
|
+
}
|
|
2804
|
+
|
|
2805
|
+
function addCleanup(cleanup, owner, mode = "self") {
|
|
2806
|
+
if (typeof cleanup !== "function") {
|
|
2807
|
+
return cleanup;
|
|
2808
|
+
}
|
|
2809
|
+
cleanups.add(cleanup);
|
|
2810
|
+
if (owner) {
|
|
2811
|
+
const records = scopedCleanups.get(owner) ?? [];
|
|
2812
|
+
records.push({ cleanup, mode });
|
|
2813
|
+
scopedCleanups.set(owner, records);
|
|
2814
|
+
}
|
|
2815
|
+
return cleanup;
|
|
2816
|
+
}
|
|
2817
|
+
|
|
2818
|
+
function runCleanup(cleanup) {
|
|
2819
|
+
if (typeof cleanup !== "function" || !cleanups.has(cleanup)) {
|
|
2820
|
+
return;
|
|
2821
|
+
}
|
|
2822
|
+
cleanups.delete(cleanup);
|
|
2823
|
+
cleanup();
|
|
2824
|
+
}
|
|
2825
|
+
|
|
2826
|
+
function cleanupChildren(container) {
|
|
2827
|
+
runScopedCleanups(container, "children");
|
|
2828
|
+
for (const child of [...(container.childNodes ?? [])]) {
|
|
2829
|
+
cleanupNode(child);
|
|
2830
|
+
}
|
|
2831
|
+
}
|
|
2832
|
+
|
|
2833
|
+
function cleanupNode(node) {
|
|
2834
|
+
if (node.nodeType !== 1) {
|
|
2835
|
+
return;
|
|
2836
|
+
}
|
|
2837
|
+
for (const element of elementsIn(node)) {
|
|
2838
|
+
runScopedCleanups(element);
|
|
2839
|
+
}
|
|
2840
|
+
}
|
|
2841
|
+
|
|
2842
|
+
function runScopedCleanups(element, mode) {
|
|
2843
|
+
const records = scopedCleanups.get(element);
|
|
2844
|
+
if (!records) {
|
|
2845
|
+
return;
|
|
2846
|
+
}
|
|
2847
|
+
const remaining = [];
|
|
2848
|
+
for (const record of records) {
|
|
2849
|
+
if (mode && record.mode !== mode) {
|
|
2850
|
+
remaining.push(record);
|
|
2851
|
+
continue;
|
|
2852
|
+
}
|
|
2853
|
+
runCleanup(record.cleanup);
|
|
2854
|
+
}
|
|
2855
|
+
if (remaining.length > 0) {
|
|
2856
|
+
scopedCleanups.set(element, remaining);
|
|
2857
|
+
} else {
|
|
2858
|
+
scopedCleanups.delete(element);
|
|
2660
2859
|
}
|
|
2661
2860
|
}
|
|
2662
2861
|
|
|
2663
2862
|
return api;
|
|
2664
2863
|
}
|
|
2665
2864
|
|
|
2865
|
+
const AsyncLoader = Loader;
|
|
2866
|
+
|
|
2666
2867
|
function normalizeClassTokens(value, tokens = new Set()) {
|
|
2667
2868
|
if (value == null || value === false) {
|
|
2668
2869
|
return tokens;
|
|
@@ -2807,6 +3008,14 @@ const __loaderModule = (() => {
|
|
|
2807
3008
|
}
|
|
2808
3009
|
}
|
|
2809
3010
|
|
|
3011
|
+
function updateProperty(element, prop, value) {
|
|
3012
|
+
if (value == null) {
|
|
3013
|
+
element[prop] = "";
|
|
3014
|
+
return;
|
|
3015
|
+
}
|
|
3016
|
+
element[prop] = value;
|
|
3017
|
+
}
|
|
3018
|
+
|
|
2810
3019
|
function selectAll(scope, selector) {
|
|
2811
3020
|
const elements = [];
|
|
2812
3021
|
if (scope?.nodeType === 1 && scope.matches?.(selector)) {
|
|
@@ -2855,7 +3064,7 @@ const __loaderModule = (() => {
|
|
|
2855
3064
|
})
|
|
2856
3065
|
);
|
|
2857
3066
|
}
|
|
2858
|
-
return { AsyncLoader };
|
|
3067
|
+
return { Loader, AsyncLoader };
|
|
2859
3068
|
})();
|
|
2860
3069
|
|
|
2861
3070
|
const __partialsModule = (() => {
|
|
@@ -2886,6 +3095,11 @@ const __partialsModule = (() => {
|
|
|
2886
3095
|
return registry;
|
|
2887
3096
|
},
|
|
2888
3097
|
|
|
3098
|
+
unregister(id) {
|
|
3099
|
+
assertId(id);
|
|
3100
|
+
return entries.delete(id);
|
|
3101
|
+
},
|
|
3102
|
+
|
|
2889
3103
|
resolve(id) {
|
|
2890
3104
|
assertId(id);
|
|
2891
3105
|
return entries.get(id);
|
|
@@ -2973,7 +3187,7 @@ const __partialsModule = (() => {
|
|
|
2973
3187
|
})();
|
|
2974
3188
|
|
|
2975
3189
|
const __routerModule = (() => {
|
|
2976
|
-
const {
|
|
3190
|
+
const { Loader } = __loaderModule;
|
|
2977
3191
|
const { createHandlerRegistry } = __handlersModule;
|
|
2978
3192
|
const { createSignalRegistry } = __signalsModule;
|
|
2979
3193
|
const { applyServerResult } = __serverModule;
|
|
@@ -3015,6 +3229,15 @@ const __routerModule = (() => {
|
|
|
3015
3229
|
return registry;
|
|
3016
3230
|
},
|
|
3017
3231
|
|
|
3232
|
+
unregister(pattern) {
|
|
3233
|
+
assertPattern(pattern);
|
|
3234
|
+
const index = routes.findIndex((candidate) => candidate.pattern === pattern);
|
|
3235
|
+
if (index !== -1) {
|
|
3236
|
+
routes.splice(index, 1);
|
|
3237
|
+
}
|
|
3238
|
+
return entries.delete(pattern);
|
|
3239
|
+
},
|
|
3240
|
+
|
|
3018
3241
|
match(url) {
|
|
3019
3242
|
const path = toUrl(url).pathname;
|
|
3020
3243
|
for (const candidate of routes) {
|
|
@@ -3093,7 +3316,7 @@ const __routerModule = (() => {
|
|
|
3093
3316
|
const attributeConfig = normalizeAttributeConfig(attributes ?? loader?.attributes);
|
|
3094
3317
|
const loaderInstance =
|
|
3095
3318
|
loader ??
|
|
3096
|
-
|
|
3319
|
+
Loader({
|
|
3097
3320
|
root: rootNode,
|
|
3098
3321
|
signals: signalRegistry,
|
|
3099
3322
|
handlers: handlerRegistry,
|
|
@@ -3444,7 +3667,7 @@ const __appModule = (() => {
|
|
|
3444
3667
|
const { createCacheRegistry } = __cacheModule;
|
|
3445
3668
|
const { createComponentRegistry } = __componentModule;
|
|
3446
3669
|
const { createHandlerRegistry } = __handlersModule;
|
|
3447
|
-
const {
|
|
3670
|
+
const { Loader } = __loaderModule;
|
|
3448
3671
|
const { createPartialRegistry } = __partialsModule;
|
|
3449
3672
|
const { createRouteRegistry, createRouter } = __routerModule;
|
|
3450
3673
|
const { createServerRegistry } = __serverModule;
|
|
@@ -3543,7 +3766,7 @@ const __appModule = (() => {
|
|
|
3543
3766
|
started = true;
|
|
3544
3767
|
|
|
3545
3768
|
if (target !== "server") {
|
|
3546
|
-
loader = loader ??
|
|
3769
|
+
loader = loader ?? Loader({
|
|
3547
3770
|
root: options.root,
|
|
3548
3771
|
signals,
|
|
3549
3772
|
handlers,
|
|
@@ -3894,6 +4117,7 @@ const { defineComponent: defineComponent } = __componentModule;
|
|
|
3894
4117
|
const { delay: delay } = __delayModule;
|
|
3895
4118
|
const { createHandlerRegistry: createHandlerRegistry } = __handlersModule;
|
|
3896
4119
|
const { html: html } = __htmlModule;
|
|
4120
|
+
const { Loader: Loader } = __loaderModule;
|
|
3897
4121
|
const { AsyncLoader: AsyncLoader } = __loaderModule;
|
|
3898
4122
|
const { createPartialRegistry: createPartialRegistry } = __partialsModule;
|
|
3899
4123
|
const { createRegistryStore: createRegistryStore } = __registryStoreModule;
|
|
@@ -3909,4 +4133,4 @@ const { createSignalRegistry: createSignalRegistry } = __signalsModule;
|
|
|
3909
4133
|
const { effect: effect } = __signalsModule;
|
|
3910
4134
|
const { signal: signal } = __signalsModule;
|
|
3911
4135
|
|
|
3912
|
-
export { asyncSignal, Async, createApp, defineApp, attributeName, defineAttributeConfig, createCacheRegistry, defineCache, component, createComponentRegistry, defineComponent, delay, createHandlerRegistry, html, AsyncLoader, createPartialRegistry, createRegistryStore, createRouteRegistry, createRouter, defineRoute, route, createServerProxy, createServerRegistry, computed, createSignal, createSignalRegistry, effect, signal };
|
|
4136
|
+
export { asyncSignal, Async, createApp, defineApp, attributeName, defineAttributeConfig, createCacheRegistry, defineCache, component, createComponentRegistry, defineComponent, delay, createHandlerRegistry, html, Loader, AsyncLoader, createPartialRegistry, createRegistryStore, createRouteRegistry, createRouter, defineRoute, route, createServerProxy, createServerRegistry, computed, createSignal, createSignalRegistry, effect, signal };
|