@adukiorg/anza 0.2.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 +137 -0
- package/README.md +215 -0
- package/bin/anza.js +63 -0
- package/bin/create.js +150 -0
- package/importmap.json +72 -0
- package/package.json +100 -0
- package/src/core/animations/index.js +55 -0
- package/src/core/animations/play.js +111 -0
- package/src/core/animations/registry.js +54 -0
- package/src/core/animations/scroll.js +50 -0
- package/src/core/animations/tokens.js +58 -0
- package/src/core/animations/usage.md +301 -0
- package/src/core/animations/waapi.js +86 -0
- package/src/core/api/cache.js +120 -0
- package/src/core/api/caches/glob.js +24 -0
- package/src/core/api/caches/index.js +118 -0
- package/src/core/api/events/index.js +75 -0
- package/src/core/api/fetch.js +99 -0
- package/src/core/api/index.js +158 -0
- package/src/core/api/pipeline.js +98 -0
- package/src/core/api/plan.md +209 -0
- package/src/core/api/prefixes/index.js +66 -0
- package/src/core/api/retry.js +69 -0
- package/src/core/api/stream.js +127 -0
- package/src/core/api/upload.js +180 -0
- package/src/core/api/usage.md +206 -0
- package/src/core/events/bus.js +38 -0
- package/src/core/events/delegate.js +79 -0
- package/src/core/events/index.js +26 -0
- package/src/core/events/listen.js +50 -0
- package/src/core/events/missing.md +103 -0
- package/src/core/events/once.js +49 -0
- package/src/core/events/plan.md +177 -0
- package/src/core/events/types/index.js +34 -0
- package/src/core/events/usage.md +107 -0
- package/src/core/offline/bridge.js +51 -0
- package/src/core/offline/clock.js +100 -0
- package/src/core/offline/connectivity.js +116 -0
- package/src/core/offline/index.js +41 -0
- package/src/core/offline/missing.md +89 -0
- package/src/core/offline/plan.md +143 -0
- package/src/core/offline/queue.js +168 -0
- package/src/core/offline/state.js +18 -0
- package/src/core/offline/sync.js +106 -0
- package/src/core/offline/usage.md +273 -0
- package/src/core/platform/guard.js +104 -0
- package/src/core/platform/index.js +42 -0
- package/src/core/platform/missing.md +119 -0
- package/src/core/platform/platform.d.ts +88 -0
- package/src/core/platform/polyfills/anchor.js +79 -0
- package/src/core/platform/polyfills/navigation.js +142 -0
- package/src/core/platform/polyfills/popover.js +142 -0
- package/src/core/platform/polyfills/scheduler.js +194 -0
- package/src/core/platform/polyfills/shadow.js +35 -0
- package/src/core/platform/polyfills/urlpattern.js +119 -0
- package/src/core/platform/supports.js +186 -0
- package/src/core/platform/usage.md +287 -0
- package/src/core/router/cache.js +95 -0
- package/src/core/router/container.js +146 -0
- package/src/core/router/handler.js +52 -0
- package/src/core/router/history.js +120 -0
- package/src/core/router/index.js +158 -0
- package/src/core/router/intercept.js +376 -0
- package/src/core/router/match.js +145 -0
- package/src/core/router/missing.md +716 -0
- package/src/core/router/outlet.js +139 -0
- package/src/core/router/plan.md +370 -0
- package/src/core/router/sync/index.js +16 -0
- package/src/core/router/sync/tab.js +115 -0
- package/src/core/router/sync/transport.js +139 -0
- package/src/core/router/transitions.js +59 -0
- package/src/core/router/usage.md +773 -0
- package/src/core/security/crypto.js +159 -0
- package/src/core/security/index.js +49 -0
- package/src/core/security/missing.md +97 -0
- package/src/core/security/permissions.js +64 -0
- package/src/core/security/sanitize.js +100 -0
- package/src/core/security/usage.md +283 -0
- package/src/core/state/derived.js +117 -0
- package/src/core/state/index.js +23 -0
- package/src/core/state/missing.md +165 -0
- package/src/core/state/persist.js +284 -0
- package/src/core/state/store.js +308 -0
- package/src/core/state/sync.js +46 -0
- package/src/core/state/usage.md +440 -0
- package/src/core/storage/cache.js +83 -0
- package/src/core/storage/idb.js +196 -0
- package/src/core/storage/index.js +373 -0
- package/src/core/storage/lru.js +107 -0
- package/src/core/storage/missing.md +165 -0
- package/src/core/storage/opfs.js +190 -0
- package/src/core/storage/plan.md +69 -0
- package/src/core/storage/quota.js +69 -0
- package/src/core/storage/usage.md +226 -0
- package/src/core/ui/base.js +50 -0
- package/src/core/ui/define/container.js +82 -0
- package/src/core/ui/define/define.js +12 -0
- package/src/core/ui/define/element.js +390 -0
- package/src/core/ui/define/index.js +9 -0
- package/src/core/ui/define/orchestrator.js +105 -0
- package/src/core/ui/define/proxy.js +644 -0
- package/src/core/ui/define/state.js +6 -0
- package/src/core/ui/define/utils.js +134 -0
- package/src/core/ui/implementation.md +170 -0
- package/src/core/ui/index.js +41 -0
- package/src/core/ui/observe.js +117 -0
- package/src/core/ui/plan.md +510 -0
- package/src/core/ui/schedule.js +60 -0
- package/src/core/ui/template.js +37 -0
- package/src/core/ui/transitions.js +37 -0
- package/src/core/ui/ui.types.md +890 -0
- package/src/core/ui/usage.md +1124 -0
- package/src/core/ui/watch.md +346 -0
- package/src/core/workers/broadcast.js +138 -0
- package/src/core/workers/dedicated.js +153 -0
- package/src/core/workers/index.js +169 -0
- package/src/core/workers/locks.js +160 -0
- package/src/core/workers/offscreen.js +166 -0
- package/src/core/workers/plan.md +381 -0
- package/src/core/workers/pool.js +267 -0
- package/src/core/workers/shared.js +137 -0
- package/src/core/workers/usage.md +622 -0
- package/src/elements/base.js +12 -0
- package/src/elements/data/card/index.html +9 -0
- package/src/elements/data/card/index.js +19 -0
- package/src/elements/data/card/index.tags.json +1 -0
- package/src/elements/data/card/style.css +46 -0
- package/src/elements/data/chart/index.html +1 -0
- package/src/elements/data/chart/index.js +143 -0
- package/src/elements/data/chart/index.tags.json +1 -0
- package/src/elements/data/chart/style.css +13 -0
- package/src/elements/data/list/index.html +3 -0
- package/src/elements/data/list/index.js +19 -0
- package/src/elements/data/list/index.tags.json +1 -0
- package/src/elements/data/list/style.css +39 -0
- package/src/elements/data/stat/index.html +9 -0
- package/src/elements/data/stat/index.js +19 -0
- package/src/elements/data/stat/index.tags.json +1 -0
- package/src/elements/data/stat/style.css +50 -0
- package/src/elements/data/table/index.html +1 -0
- package/src/elements/data/table/index.js +16 -0
- package/src/elements/data/table/index.tags.json +1 -0
- package/src/elements/data/table/style.css +50 -0
- package/src/elements/feedback/alert/index.html +11 -0
- package/src/elements/feedback/alert/index.js +28 -0
- package/src/elements/feedback/alert/index.tags.json +1 -0
- package/src/elements/feedback/alert/style.css +75 -0
- package/src/elements/feedback/empty/index.html +13 -0
- package/src/elements/feedback/empty/index.js +34 -0
- package/src/elements/feedback/empty/index.tags.json +1 -0
- package/src/elements/feedback/empty/style.css +45 -0
- package/src/elements/feedback/progress/index.html +7 -0
- package/src/elements/feedback/progress/index.js +46 -0
- package/src/elements/feedback/progress/index.tags.json +1 -0
- package/src/elements/feedback/progress/style.css +36 -0
- package/src/elements/feedback/skeleton/index.html +1 -0
- package/src/elements/feedback/skeleton/index.js +78 -0
- package/src/elements/feedback/skeleton/index.tags.json +1 -0
- package/src/elements/feedback/skeleton/style.css +28 -0
- package/src/elements/feedback/toast/index.html +3 -0
- package/src/elements/feedback/toast/index.js +65 -0
- package/src/elements/feedback/toast/index.tags.json +1 -0
- package/src/elements/feedback/toast/style.css +36 -0
- package/src/elements/forms/checkbox/index.html +7 -0
- package/src/elements/forms/checkbox/index.js +104 -0
- package/src/elements/forms/checkbox/index.tags.json +1 -0
- package/src/elements/forms/checkbox/style.css +86 -0
- package/src/elements/forms/field/index.html +13 -0
- package/src/elements/forms/field/index.js +42 -0
- package/src/elements/forms/field/index.tags.json +1 -0
- package/src/elements/forms/field/style.css +42 -0
- package/src/elements/forms/form/index.html +3 -0
- package/src/elements/forms/form/index.js +122 -0
- package/src/elements/forms/form/index.tags.json +1 -0
- package/src/elements/forms/form/style.css +11 -0
- package/src/elements/forms/input/index.html +4 -0
- package/src/elements/forms/input/index.js +103 -0
- package/src/elements/forms/input/index.tags.json +1 -0
- package/src/elements/forms/input/style.css +39 -0
- package/src/elements/forms/radio/index.html +4 -0
- package/src/elements/forms/radio/index.js +109 -0
- package/src/elements/forms/radio/index.tags.json +1 -0
- package/src/elements/forms/radio/style.css +65 -0
- package/src/elements/forms/select/index.html +9 -0
- package/src/elements/forms/select/index.js +114 -0
- package/src/elements/forms/select/index.tags.json +1 -0
- package/src/elements/forms/select/style.css +95 -0
- package/src/elements/forms/textarea/index.html +4 -0
- package/src/elements/forms/textarea/index.js +115 -0
- package/src/elements/forms/textarea/index.tags.json +1 -0
- package/src/elements/forms/textarea/style.css +46 -0
- package/src/elements/forms/toggle/index.html +4 -0
- package/src/elements/forms/toggle/index.js +89 -0
- package/src/elements/forms/toggle/index.tags.json +1 -0
- package/src/elements/forms/toggle/style.css +63 -0
- package/src/elements/forms/upload/index.html +13 -0
- package/src/elements/forms/upload/index.js +120 -0
- package/src/elements/forms/upload/index.tags.json +1 -0
- package/src/elements/forms/upload/style.css +61 -0
- package/src/elements/index.js +71 -0
- package/src/elements/layout/app/index.html +7 -0
- package/src/elements/layout/app/index.js +16 -0
- package/src/elements/layout/app/index.tags.json +1 -0
- package/src/elements/layout/app/style.css +41 -0
- package/src/elements/layout/grid/index.html +3 -0
- package/src/elements/layout/grid/index.js +41 -0
- package/src/elements/layout/grid/index.tags.json +1 -0
- package/src/elements/layout/grid/style.css +12 -0
- package/src/elements/layout/header/index.html +8 -0
- package/src/elements/layout/header/index.js +16 -0
- package/src/elements/layout/header/index.tags.json +1 -0
- package/src/elements/layout/header/style.css +28 -0
- package/src/elements/layout/scroll/index.html +3 -0
- package/src/elements/layout/scroll/index.js +19 -0
- package/src/elements/layout/scroll/index.tags.json +1 -0
- package/src/elements/layout/scroll/style.css +24 -0
- package/src/elements/layout/sidebar/index.html +3 -0
- package/src/elements/layout/sidebar/index.js +24 -0
- package/src/elements/layout/sidebar/index.tags.json +1 -0
- package/src/elements/layout/sidebar/style.css +30 -0
- package/src/elements/layout/split/index.html +3 -0
- package/src/elements/layout/split/index.js +18 -0
- package/src/elements/layout/split/index.tags.json +1 -0
- package/src/elements/layout/split/style.css +28 -0
- package/src/elements/layout/stack/index.html +3 -0
- package/src/elements/layout/stack/index.js +31 -0
- package/src/elements/layout/stack/index.tags.json +1 -0
- package/src/elements/layout/stack/style.css +15 -0
- package/src/elements/layout/surface/index.html +3 -0
- package/src/elements/layout/surface/index.js +19 -0
- package/src/elements/layout/surface/index.tags.json +1 -0
- package/src/elements/layout/surface/style.css +29 -0
- package/src/elements/navigation/breadcrumb/index.html +5 -0
- package/src/elements/navigation/breadcrumb/index.js +16 -0
- package/src/elements/navigation/breadcrumb/index.tags.json +1 -0
- package/src/elements/navigation/breadcrumb/style.css +36 -0
- package/src/elements/navigation/nav/index.html +3 -0
- package/src/elements/navigation/nav/index.js +24 -0
- package/src/elements/navigation/nav/index.tags.json +1 -0
- package/src/elements/navigation/nav/style.css +38 -0
- package/src/elements/navigation/pagination/index.html +3 -0
- package/src/elements/navigation/pagination/index.js +94 -0
- package/src/elements/navigation/pagination/index.tags.json +1 -0
- package/src/elements/navigation/pagination/style.css +39 -0
- package/src/elements/navigation/steps/index.html +6 -0
- package/src/elements/navigation/steps/index.js +64 -0
- package/src/elements/navigation/steps/index.tags.json +1 -0
- package/src/elements/navigation/steps/style.css +78 -0
- package/src/elements/navigation/tabs/index.html +6 -0
- package/src/elements/navigation/tabs/index.js +132 -0
- package/src/elements/navigation/tabs/index.tags.json +1 -0
- package/src/elements/navigation/tabs/style.css +52 -0
- package/src/elements/overlay/dialog/index.html +5 -0
- package/src/elements/overlay/dialog/index.js +57 -0
- package/src/elements/overlay/dialog/index.tags.json +1 -0
- package/src/elements/overlay/dialog/style.css +31 -0
- package/src/elements/overlay/drawer/index.html +3 -0
- package/src/elements/overlay/drawer/index.js +56 -0
- package/src/elements/overlay/drawer/index.tags.json +1 -0
- package/src/elements/overlay/drawer/style.css +48 -0
- package/src/elements/overlay/menu/index.html +3 -0
- package/src/elements/overlay/menu/index.js +107 -0
- package/src/elements/overlay/menu/index.tags.json +1 -0
- package/src/elements/overlay/menu/style.css +43 -0
- package/src/elements/overlay/popover/index.html +3 -0
- package/src/elements/overlay/popover/index.js +44 -0
- package/src/elements/overlay/popover/index.tags.json +1 -0
- package/src/elements/overlay/popover/style.css +21 -0
- package/src/elements/overlay/sheet/index.html +8 -0
- package/src/elements/overlay/sheet/index.js +105 -0
- package/src/elements/overlay/sheet/index.tags.json +1 -0
- package/src/elements/overlay/sheet/style.css +64 -0
- package/src/elements/overlay/tooltip/index.html +6 -0
- package/src/elements/overlay/tooltip/index.js +16 -0
- package/src/elements/overlay/tooltip/index.tags.json +1 -0
- package/src/elements/overlay/tooltip/style.css +41 -0
- package/src/elements/primitives/avatar/index.html +2 -0
- package/src/elements/primitives/avatar/index.js +79 -0
- package/src/elements/primitives/avatar/index.tags.json +1 -0
- package/src/elements/primitives/avatar/style.css +36 -0
- package/src/elements/primitives/badge/index.html +3 -0
- package/src/elements/primitives/badge/index.js +20 -0
- package/src/elements/primitives/badge/index.tags.json +1 -0
- package/src/elements/primitives/badge/style.css +67 -0
- package/src/elements/primitives/button/index.html +3 -0
- package/src/elements/primitives/button/index.js +61 -0
- package/src/elements/primitives/button/index.tags.json +1 -0
- package/src/elements/primitives/button/style.css +66 -0
- package/src/elements/primitives/divider/index.html +1 -0
- package/src/elements/primitives/divider/index.js +43 -0
- package/src/elements/primitives/divider/index.tags.json +1 -0
- package/src/elements/primitives/divider/style.css +39 -0
- package/src/elements/primitives/icon/index.html +3 -0
- package/src/elements/primitives/icon/index.js +66 -0
- package/src/elements/primitives/icon/index.tags.json +1 -0
- package/src/elements/primitives/icon/style.css +20 -0
- package/src/elements/primitives/link/index.html +3 -0
- package/src/elements/primitives/link/index.js +129 -0
- package/src/elements/primitives/link/index.tags.json +1 -0
- package/src/elements/primitives/link/style.css +40 -0
- package/src/elements/primitives/spinner/index.html +1 -0
- package/src/elements/primitives/spinner/index.js +62 -0
- package/src/elements/primitives/spinner/index.tags.json +1 -0
- package/src/elements/primitives/spinner/style.css +20 -0
- package/src/elements/primitives/text/index.html +1 -0
- package/src/elements/primitives/text/index.js +79 -0
- package/src/elements/primitives/text/index.tags.json +1 -0
- package/src/elements/primitives/text/style.css +25 -0
- package/src/index.js +23 -0
- package/src/styles/base.css +66 -0
- package/src/styles/index.css +10 -0
- package/src/styles/layers.css +9 -0
- package/src/styles/reset.css +66 -0
- package/src/sw/activate.js +51 -0
- package/src/sw/expire.js +47 -0
- package/src/sw/index.js +28 -0
- package/src/sw/install.js +35 -0
- package/src/sw/push.js +58 -0
- package/src/sw/queue.js +60 -0
- package/src/sw/routes.js +71 -0
- package/src/sw/strategies.js +247 -0
- package/src/sw/sync.js +80 -0
- package/src/tokens/index.css +26 -0
- package/src/tokens/primitives/colors.css +54 -0
- package/src/tokens/primitives/motion.css +34 -0
- package/src/tokens/primitives/radius.css +16 -0
- package/src/tokens/primitives/shadow.css +34 -0
- package/src/tokens/primitives/spacing.css +27 -0
- package/src/tokens/primitives/typography.css +46 -0
- package/src/tokens/primitives/zindex.css +18 -0
- package/src/tokens/registered/colors.css +133 -0
- package/src/tokens/registered/dimensions.css +31 -0
- package/src/tokens/semantic/components.css +125 -0
- package/src/tokens/semantic/contrast.css +33 -0
- package/src/tokens/semantic/dark.css +61 -0
- package/src/tokens/semantic/light.css +64 -0
- package/types/core/animations/index.d.ts +52 -0
- package/types/core/api/index.d.ts +68 -0
- package/types/core/events/index.d.ts +50 -0
- package/types/core/offline/index.d.ts +68 -0
- package/types/core/platform/index.d.ts +60 -0
- package/types/core/router/index.d.ts +203 -0
- package/types/core/security/index.d.ts +33 -0
- package/types/core/state/index.d.ts +68 -0
- package/types/core/storage/index.d.ts +40 -0
- package/types/core/ui/index.d.ts +446 -0
- package/types/core/workers/index.d.ts +221 -0
- package/types/elements/index.d.ts +150 -0
- package/types/index.d.ts +18 -0
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* src/core/router/container.js
|
|
3
|
+
*
|
|
4
|
+
* Dynamic Container Registry for Advanced Topologies (v2).
|
|
5
|
+
* Maintains a real-time, non-blocking map of actively mounted DOM layout containers.
|
|
6
|
+
* Employs WeakRef and FinalizationRegistry for perfect GC safety, and idle
|
|
7
|
+
* MutationObservers for standard HTML fallback tracking.
|
|
8
|
+
*
|
|
9
|
+
* Source: advance2.md
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
// string -> WeakRef<HTMLElement>
|
|
13
|
+
const containerNodeMap = new Map();
|
|
14
|
+
|
|
15
|
+
// Passive safety net: prune stale map entries after GC
|
|
16
|
+
const cleanupRegistry = typeof FinalizationRegistry !== 'undefined'
|
|
17
|
+
? new FinalizationRegistry((name) => {
|
|
18
|
+
if (containerNodeMap.get(name)?.deref() === undefined) {
|
|
19
|
+
containerNodeMap.delete(name);
|
|
20
|
+
}
|
|
21
|
+
})
|
|
22
|
+
: { register() {}, unregister() {} };
|
|
23
|
+
|
|
24
|
+
let observer;
|
|
25
|
+
const observedSelectors = new Set();
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* Boots the MutationObserver at idle priority if standard selectors are tracked.
|
|
29
|
+
*/
|
|
30
|
+
function ensureObserver() {
|
|
31
|
+
if (observer || typeof window === 'undefined' || typeof requestIdleCallback === 'undefined') return;
|
|
32
|
+
|
|
33
|
+
requestIdleCallback(() => {
|
|
34
|
+
observer = new MutationObserver(() => {
|
|
35
|
+
let activeObservationNeeded = false;
|
|
36
|
+
for (const selector of observedSelectors) {
|
|
37
|
+
if (!containerNodeMap.get(selector)?.deref()) {
|
|
38
|
+
const el = document.querySelector(selector);
|
|
39
|
+
if (el) {
|
|
40
|
+
registerContainer(selector, el);
|
|
41
|
+
} else {
|
|
42
|
+
activeObservationNeeded = true;
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
// RT-06: Automatically disconnect MutationObserver if all observed selectors are resolved
|
|
48
|
+
if (!activeObservationNeeded && observer) {
|
|
49
|
+
observer.disconnect();
|
|
50
|
+
observer = null;
|
|
51
|
+
}
|
|
52
|
+
});
|
|
53
|
+
|
|
54
|
+
observer.observe(document.body, { childList: true, subtree: true });
|
|
55
|
+
});
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
/**
|
|
59
|
+
* Registers a layout container as actively mounted in the DOM.
|
|
60
|
+
* @param {string} name - The unique identifier/selector of the container.
|
|
61
|
+
* @param {HTMLElement} element - The DOM element instance.
|
|
62
|
+
*/
|
|
63
|
+
export function registerContainer(name, element) {
|
|
64
|
+
const existing = containerNodeMap.get(name)?.deref();
|
|
65
|
+
if (existing && existing !== element) {
|
|
66
|
+
throw new Error(`ContainerError: Singleton violation — '${name}' is already mounted. A second instance cannot register while the first is active.`);
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
containerNodeMap.set(name, new WeakRef(element));
|
|
70
|
+
cleanupRegistry.register(element, name);
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
/**
|
|
74
|
+
* Unregisters a layout container when it is removed from the DOM.
|
|
75
|
+
* @param {string} name - The unique identifier/selector of the container.
|
|
76
|
+
* @param {HTMLElement} element - The DOM element instance (used for safety check).
|
|
77
|
+
*/
|
|
78
|
+
export function unregisterContainer(name, element) {
|
|
79
|
+
const existing = containerNodeMap.get(name)?.deref();
|
|
80
|
+
if (!element || existing === element) {
|
|
81
|
+
containerNodeMap.delete(name);
|
|
82
|
+
if (existing) {
|
|
83
|
+
try { cleanupRegistry.unregister(existing); } catch(e) {}
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
/**
|
|
89
|
+
* Retrieves an active layout container by name.
|
|
90
|
+
* @param {string} name - The unique identifier of the container.
|
|
91
|
+
* @returns {HTMLElement|undefined} The active container element, or undefined if not mounted.
|
|
92
|
+
*/
|
|
93
|
+
export function getContainer(name) {
|
|
94
|
+
let el = containerNodeMap.get(name)?.deref();
|
|
95
|
+
|
|
96
|
+
// A plain registry key (e.g. 'main') is only ever looked up in the registry.
|
|
97
|
+
// A CSS selector (starts with '#', '.', '[', or contains a combinator) is
|
|
98
|
+
// resolved against the document. This removes the ambiguity where 'main'
|
|
99
|
+
// could mean a registry key or `querySelector('main')`.
|
|
100
|
+
if (!el && isSelector(name) && typeof document !== 'undefined') {
|
|
101
|
+
try {
|
|
102
|
+
el = document.querySelector(name);
|
|
103
|
+
if (el) {
|
|
104
|
+
registerContainer(name, el);
|
|
105
|
+
} else {
|
|
106
|
+
if (!observedSelectors.has(name)) {
|
|
107
|
+
observedSelectors.add(name);
|
|
108
|
+
}
|
|
109
|
+
ensureObserver();
|
|
110
|
+
}
|
|
111
|
+
} catch (err) {
|
|
112
|
+
// Invalid selector string, ignore.
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
// Warn on ambiguous names that look like they could be either a key or selector
|
|
117
|
+
if (!el && typeof name === 'string' && !isSelector(name) && typeof document !== 'undefined') {
|
|
118
|
+
const queryResult = document.querySelector(name);
|
|
119
|
+
if (queryResult) {
|
|
120
|
+
console.warn(
|
|
121
|
+
`[Router] Container name "${name}" is ambiguous: it exists in the DOM as a selector ` +
|
|
122
|
+
`but is being treated as a registry key. Use a selector prefix (e.g., "#${name}") ` +
|
|
123
|
+
`to explicitly target the DOM element, or ensure it is registered via registerContainer().`
|
|
124
|
+
);
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
return el;
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
/** Heuristic: does this string look like a CSS selector rather than a key? */
|
|
132
|
+
function isSelector(name) {
|
|
133
|
+
return typeof name === 'string' && /^[#.\[]|[\s>+~]/.test(name);
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
/**
|
|
137
|
+
* Clears the entire container registry.
|
|
138
|
+
*/
|
|
139
|
+
export function clearContainers() {
|
|
140
|
+
containerNodeMap.clear();
|
|
141
|
+
observedSelectors.clear();
|
|
142
|
+
if (observer) {
|
|
143
|
+
observer.disconnect();
|
|
144
|
+
observer = null;
|
|
145
|
+
}
|
|
146
|
+
}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* src/core/router/handler.js
|
|
3
|
+
*
|
|
4
|
+
* One clear contract for what a route handler can be. This removes the previous
|
|
5
|
+
* ambiguity where `match()` invoked every function handler as a lazy tag factory
|
|
6
|
+
* while `intercept()` separately treated functions with arguments as callbacks —
|
|
7
|
+
* which could run a callback twice (once during matching, once on navigation).
|
|
8
|
+
*
|
|
9
|
+
* A handler is exactly one of:
|
|
10
|
+
* - a string -> a custom element tag, e.g. 'page-home'
|
|
11
|
+
* - a zero-arg function -> a lazy tag factory, e.g. async () => 'page-home'
|
|
12
|
+
* - a function (params, event)-> a callback (arity > 0)
|
|
13
|
+
* - { tag: string } -> a static tag
|
|
14
|
+
* - { load: () => tag } -> a lazy tag factory
|
|
15
|
+
* - { handler: (params, ev) } -> a callback
|
|
16
|
+
*/
|
|
17
|
+
|
|
18
|
+
/** Does this handler render via a callback (rather than resolving to a tag)? */
|
|
19
|
+
export function isCallback(handler) {
|
|
20
|
+
if (typeof handler === 'function') return handler.length > 0;
|
|
21
|
+
if (handler && typeof handler === 'object') return typeof handler.handler === 'function';
|
|
22
|
+
return false;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* Resolve a handler to its element tag, or `null` when the handler is a callback.
|
|
27
|
+
* Never invokes callbacks (arity > 0 / `{ handler }`), so it is safe in `match()`.
|
|
28
|
+
*/
|
|
29
|
+
export async function resolveTag(handler) {
|
|
30
|
+
if (typeof handler === 'string') return handler;
|
|
31
|
+
|
|
32
|
+
if (typeof handler === 'function') {
|
|
33
|
+
return handler.length === 0 ? await handler() : null;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
if (handler && typeof handler === 'object') {
|
|
37
|
+
if (typeof handler.tag === 'string') return handler.tag;
|
|
38
|
+
if (typeof handler.load === 'function') return await handler.load();
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
return null;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
/** Run a callback handler. No-op for tag/lazy handlers. */
|
|
45
|
+
export async function runCallback(handler, params, event) {
|
|
46
|
+
if (typeof handler === 'function' && handler.length > 0) {
|
|
47
|
+
return handler(params, event);
|
|
48
|
+
}
|
|
49
|
+
if (handler && typeof handler === 'object' && typeof handler.handler === 'function') {
|
|
50
|
+
return handler.handler(params, event);
|
|
51
|
+
}
|
|
52
|
+
}
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* src/core/router/history.js
|
|
3
|
+
*
|
|
4
|
+
* Programmatic history navigation wrapper.
|
|
5
|
+
* Provides a clean interface for page-level traversals mapping directly
|
|
6
|
+
* to the Navigation API (native or polyfilled).
|
|
7
|
+
*
|
|
8
|
+
* Source: doc 09 — Routing §2, §10, §12
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
/** Normalized result shape for callers that await .finished. */
|
|
12
|
+
const resolved = { committed: Promise.resolve(), finished: Promise.resolve() };
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* Initiates a programmatic push navigation.
|
|
16
|
+
* Always returns { committed, finished } promises.
|
|
17
|
+
*/
|
|
18
|
+
export function navigate(url, options = {}) {
|
|
19
|
+
if (typeof window === 'undefined' || !window.navigation) return resolved;
|
|
20
|
+
const result = window.navigation.navigate(url, options);
|
|
21
|
+
return result ?? resolved;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* Initiates a programmatic replace navigation (replaces current history entry).
|
|
26
|
+
*/
|
|
27
|
+
export function replace(url, options = {}) {
|
|
28
|
+
if (typeof window === 'undefined' || !window.navigation) return resolved;
|
|
29
|
+
const result = window.navigation.navigate(url, { history: 'replace', ...options });
|
|
30
|
+
return result ?? resolved;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* Navigates back in history by one step.
|
|
35
|
+
*/
|
|
36
|
+
export function back() {
|
|
37
|
+
if (typeof window === 'undefined' || !window.navigation) return resolved;
|
|
38
|
+
return window.navigation.back() ?? resolved;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* Navigates forward in history by one step.
|
|
43
|
+
*/
|
|
44
|
+
export function forward() {
|
|
45
|
+
if (typeof window === 'undefined' || !window.navigation) return resolved;
|
|
46
|
+
return window.navigation.forward() ?? resolved;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* Traverses history by a numeric delta.
|
|
51
|
+
*/
|
|
52
|
+
export function go(delta) {
|
|
53
|
+
if (typeof window === 'undefined' || !window.navigation) return resolved;
|
|
54
|
+
return window.navigation.go(delta) ?? resolved;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* Returns a list of all active history entries.
|
|
59
|
+
*/
|
|
60
|
+
export function entries() {
|
|
61
|
+
if (typeof window === 'undefined' || !window.navigation) return [];
|
|
62
|
+
return typeof window.navigation.entries === 'function' ? window.navigation.entries() : [];
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
/**
|
|
66
|
+
* Returns the current active history entry.
|
|
67
|
+
*/
|
|
68
|
+
export function current() {
|
|
69
|
+
if (typeof window === 'undefined' || !window.navigation) return null;
|
|
70
|
+
return window.navigation.currentEntry || null;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
/**
|
|
74
|
+
* Checks if a backward navigation traversal is valid.
|
|
75
|
+
* Prefers native canGoBack property, falls back to entries inspection,
|
|
76
|
+
* and returns false (not true) when state is unknown.
|
|
77
|
+
*/
|
|
78
|
+
export function canBack() {
|
|
79
|
+
if (typeof window === 'undefined' || !window.navigation) return false;
|
|
80
|
+
|
|
81
|
+
// Use native canGoBack when available (Chrome 123+)
|
|
82
|
+
if (typeof window.navigation.canGoBack === 'boolean') {
|
|
83
|
+
return window.navigation.canGoBack;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
if (typeof window.navigation.entries === 'function') {
|
|
87
|
+
const list = window.navigation.entries();
|
|
88
|
+
const active = window.navigation.currentEntry;
|
|
89
|
+
if (active && list.length > 0) {
|
|
90
|
+
return list.indexOf(active) > 0;
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
return false;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
/**
|
|
98
|
+
* Checks if a forward navigation traversal is valid.
|
|
99
|
+
* Prefers native canGoForward property, falls back to entries inspection,
|
|
100
|
+
* and returns false (not true) when state is unknown.
|
|
101
|
+
*/
|
|
102
|
+
export function canForward() {
|
|
103
|
+
if (typeof window === 'undefined' || !window.navigation) return false;
|
|
104
|
+
|
|
105
|
+
// Use native canGoForward when available (Chrome 123+)
|
|
106
|
+
if (typeof window.navigation.canGoForward === 'boolean') {
|
|
107
|
+
return window.navigation.canGoForward;
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
if (typeof window.navigation.entries === 'function') {
|
|
111
|
+
const list = window.navigation.entries();
|
|
112
|
+
const active = window.navigation.currentEntry;
|
|
113
|
+
if (active && list.length > 0) {
|
|
114
|
+
const idx = list.indexOf(active);
|
|
115
|
+
return idx >= 0 && idx < list.length - 1;
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
return false;
|
|
120
|
+
}
|
|
@@ -0,0 +1,158 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* src/core/router/index.js
|
|
3
|
+
*
|
|
4
|
+
* Public client-side routing entry point.
|
|
5
|
+
* Aggregates route definition registry, guards, programmatic traversals,
|
|
6
|
+
* and mounts global onnavigate interception listeners.
|
|
7
|
+
*
|
|
8
|
+
* Source: doc 09 — Routing §1, §2
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
import { register, match, clear, getRoutes, load } from './match.js';
|
|
12
|
+
import {
|
|
13
|
+
setup, destroy,
|
|
14
|
+
addGuard, setNotFound,
|
|
15
|
+
guardsApi, missApi,
|
|
16
|
+
on, nav, registerNavigator
|
|
17
|
+
} from './intercept.js';
|
|
18
|
+
import {
|
|
19
|
+
navigate,
|
|
20
|
+
replace,
|
|
21
|
+
back,
|
|
22
|
+
forward,
|
|
23
|
+
go,
|
|
24
|
+
current,
|
|
25
|
+
entries,
|
|
26
|
+
canBack,
|
|
27
|
+
canForward
|
|
28
|
+
} from './history.js';
|
|
29
|
+
|
|
30
|
+
import {
|
|
31
|
+
setupTabSync,
|
|
32
|
+
start as syncStart,
|
|
33
|
+
stop as syncStop,
|
|
34
|
+
active as syncActive,
|
|
35
|
+
close as syncClose,
|
|
36
|
+
registerConnection,
|
|
37
|
+
getActiveConnections,
|
|
38
|
+
clearConnections,
|
|
39
|
+
links
|
|
40
|
+
} from './sync/index.js';
|
|
41
|
+
|
|
42
|
+
import {
|
|
43
|
+
registerContainer,
|
|
44
|
+
unregisterContainer,
|
|
45
|
+
getContainer,
|
|
46
|
+
clearContainers
|
|
47
|
+
} from './container.js';
|
|
48
|
+
|
|
49
|
+
import { cache, prefetch } from './cache.js';
|
|
50
|
+
|
|
51
|
+
import './outlet.js';
|
|
52
|
+
|
|
53
|
+
export const router = {
|
|
54
|
+
// Registration and boundary hooks
|
|
55
|
+
register,
|
|
56
|
+
load,
|
|
57
|
+
clear,
|
|
58
|
+
guard: addGuard,
|
|
59
|
+
notFound: setNotFound,
|
|
60
|
+
|
|
61
|
+
// Grouped APIs
|
|
62
|
+
guards: guardsApi,
|
|
63
|
+
miss: missApi,
|
|
64
|
+
links,
|
|
65
|
+
|
|
66
|
+
// Sync controls
|
|
67
|
+
sync: {
|
|
68
|
+
start: (r) => syncStart(r ?? router),
|
|
69
|
+
stop: syncStop,
|
|
70
|
+
active: syncActive,
|
|
71
|
+
close: syncClose
|
|
72
|
+
},
|
|
73
|
+
|
|
74
|
+
// Programmatic history API
|
|
75
|
+
navigate,
|
|
76
|
+
replace,
|
|
77
|
+
back,
|
|
78
|
+
forward,
|
|
79
|
+
go,
|
|
80
|
+
current,
|
|
81
|
+
entries,
|
|
82
|
+
canBack,
|
|
83
|
+
canForward,
|
|
84
|
+
|
|
85
|
+
match,
|
|
86
|
+
|
|
87
|
+
// Cache API integration (route/view asset caching)
|
|
88
|
+
cache,
|
|
89
|
+
prefetch,
|
|
90
|
+
|
|
91
|
+
// Event-driven subscription and navigation controllers
|
|
92
|
+
on,
|
|
93
|
+
nav,
|
|
94
|
+
|
|
95
|
+
// Synchronization and coordination hooks
|
|
96
|
+
registerConnection,
|
|
97
|
+
getActiveConnections,
|
|
98
|
+
clearConnections,
|
|
99
|
+
|
|
100
|
+
// Advanced Container Topology API
|
|
101
|
+
registerContainer,
|
|
102
|
+
unregisterContainer,
|
|
103
|
+
getContainer,
|
|
104
|
+
clearContainers,
|
|
105
|
+
|
|
106
|
+
// Lifecycle
|
|
107
|
+
setup,
|
|
108
|
+
destroy
|
|
109
|
+
};
|
|
110
|
+
|
|
111
|
+
// Auto-bootstrap client-side navigation listeners on client load
|
|
112
|
+
if (typeof window !== 'undefined') {
|
|
113
|
+
registerNavigator(navigate);
|
|
114
|
+
setup();
|
|
115
|
+
setupTabSync(router);
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
export {
|
|
119
|
+
navigate,
|
|
120
|
+
replace,
|
|
121
|
+
back,
|
|
122
|
+
forward,
|
|
123
|
+
go,
|
|
124
|
+
current,
|
|
125
|
+
entries,
|
|
126
|
+
canBack,
|
|
127
|
+
canForward,
|
|
128
|
+
|
|
129
|
+
// match sub-module
|
|
130
|
+
register,
|
|
131
|
+
load,
|
|
132
|
+
match,
|
|
133
|
+
clear,
|
|
134
|
+
getRoutes,
|
|
135
|
+
// intercept sub-module
|
|
136
|
+
addGuard,
|
|
137
|
+
setNotFound,
|
|
138
|
+
setup,
|
|
139
|
+
destroy,
|
|
140
|
+
on,
|
|
141
|
+
nav,
|
|
142
|
+
guardsApi,
|
|
143
|
+
missApi,
|
|
144
|
+
// sync sub-module
|
|
145
|
+
setupTabSync,
|
|
146
|
+
registerConnection,
|
|
147
|
+
getActiveConnections,
|
|
148
|
+
clearConnections,
|
|
149
|
+
links,
|
|
150
|
+
// container sub-module
|
|
151
|
+
registerContainer,
|
|
152
|
+
unregisterContainer,
|
|
153
|
+
getContainer,
|
|
154
|
+
clearContainers,
|
|
155
|
+
// cache sub-module
|
|
156
|
+
cache,
|
|
157
|
+
prefetch
|
|
158
|
+
};
|