anentrypoint-design 0.0.242 → 0.0.244
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/dist/247420.js +14 -14
- package/package.json +1 -1
- package/src/index.js +4 -1
- package/src/router.js +89 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "anentrypoint-design",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.244",
|
|
4
4
|
"description": "247420 design system SDK — webjsx + modified ripple-ui, single-file ESM bundle for reproducible use of the AnEntrypoint design.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/247420.js",
|
package/src/index.js
CHANGED
|
@@ -5,6 +5,7 @@
|
|
|
5
5
|
import * as webjsx from '../vendor/webjsx/index.js';
|
|
6
6
|
import { loadCss, scope } from './styles.js';
|
|
7
7
|
import { registerDeckStage, getDeckStage } from './deck-stage.js';
|
|
8
|
+
import { Router, createRouter } from './router.js';
|
|
8
9
|
import * as components from './components.js';
|
|
9
10
|
import * as motion from './motion.js';
|
|
10
11
|
import * as debug from './debug.js';
|
|
@@ -61,6 +62,7 @@ if (typeof window !== 'undefined' && typeof customElements !== 'undefined') {
|
|
|
61
62
|
export {
|
|
62
63
|
webjsx, loadCss, scope,
|
|
63
64
|
registerDeckStage, getDeckStage,
|
|
65
|
+
Router, createRouter,
|
|
64
66
|
components, motion, debug, mountKit,
|
|
65
67
|
renderMarkdown, ensureMarkdownReady,
|
|
66
68
|
ensurePrism, highlightAllUnder,
|
|
@@ -90,6 +92,7 @@ export {
|
|
|
90
92
|
|
|
91
93
|
export default {
|
|
92
94
|
webjsx, loadCss, scope, installStyles, mount, h, applyDiff,
|
|
93
|
-
registerDeckStage, getDeckStage,
|
|
95
|
+
registerDeckStage, getDeckStage, Router, createRouter,
|
|
96
|
+
components, motion, debug, mountKit,
|
|
94
97
|
renderMarkdown, ensurePrism, registerChatElement, renderPageHtml
|
|
95
98
|
};
|
package/src/router.js
ADDED
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
// Hash-based SPA router over webjsx applyDiff. Registers named page
|
|
2
|
+
// components, dispatches on '#/<name>/<params...>', re-renders on
|
|
3
|
+
// popstate/hashchange. No framework-specific routing lib — direct
|
|
4
|
+
// history/hash manipulation, matching how every ui_kit already drives
|
|
5
|
+
// itself off window.ds.applyDiff.
|
|
6
|
+
|
|
7
|
+
import * as webjsx from '../vendor/webjsx/index.js';
|
|
8
|
+
import { register as registerDebug } from './debug.js';
|
|
9
|
+
|
|
10
|
+
const MAX_SDK_WAIT_FRAMES = 120; // ~2s at 60fps before giving up
|
|
11
|
+
|
|
12
|
+
export class Router {
|
|
13
|
+
constructor({ fallback } = {}) {
|
|
14
|
+
this.routes = new Map();
|
|
15
|
+
this.fallback = fallback || null;
|
|
16
|
+
this.currentRoute = null;
|
|
17
|
+
this.state = { page: null, params: [], sdkWaitFrames: 0, lastError: null };
|
|
18
|
+
registerDebug('router', () => ({
|
|
19
|
+
currentRoute: this.currentRoute,
|
|
20
|
+
registeredRoutes: [...this.routes.keys()],
|
|
21
|
+
params: this.state.params,
|
|
22
|
+
lastError: this.state.lastError,
|
|
23
|
+
}));
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
parseHash() {
|
|
27
|
+
const raw = (window.location.hash.slice(2) || '').split('?')[0];
|
|
28
|
+
const parts = raw.split('/').filter(Boolean);
|
|
29
|
+
return { name: parts[0] || '', params: parts.slice(1) };
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
register(name, component) {
|
|
33
|
+
this.routes.set(name, component);
|
|
34
|
+
return this;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
async navigate(name, ...params) {
|
|
38
|
+
if (!this.routes.has(name) && !this.fallback) return;
|
|
39
|
+
this.currentRoute = this.routes.has(name) ? name : null;
|
|
40
|
+
this.state.page = name;
|
|
41
|
+
this.state.params = params;
|
|
42
|
+
window.history.pushState({ page: name }, '', '#/' + [name, ...params].filter(Boolean).join('/'));
|
|
43
|
+
this.render();
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
render() {
|
|
47
|
+
const root = document.getElementById('app');
|
|
48
|
+
if (!root) throw new Error('Router: #app root element not found');
|
|
49
|
+
const component = this.routes.get(this.currentRoute) || this.fallback;
|
|
50
|
+
if (!component) {
|
|
51
|
+
this.state.lastError = 'no route registered for "' + this.currentRoute + '" and no fallback set';
|
|
52
|
+
return;
|
|
53
|
+
}
|
|
54
|
+
if (window.ds && window.ds.applyDiff) {
|
|
55
|
+
this.state.sdkWaitFrames = 0;
|
|
56
|
+
this.state.lastError = null;
|
|
57
|
+
const tree = component(this.state);
|
|
58
|
+
window.ds.applyDiff(root, tree);
|
|
59
|
+
} else if (this.state.sdkWaitFrames < MAX_SDK_WAIT_FRAMES) {
|
|
60
|
+
this.state.sdkWaitFrames += 1;
|
|
61
|
+
requestAnimationFrame(() => this.render());
|
|
62
|
+
} else {
|
|
63
|
+
this.state.lastError = 'window.ds.applyDiff never became available after ' + MAX_SDK_WAIT_FRAMES + ' frames';
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
handlePopState() {
|
|
68
|
+
const { name, params } = this.parseHash();
|
|
69
|
+
this.currentRoute = this.routes.has(name) ? name : null;
|
|
70
|
+
this.state.page = name;
|
|
71
|
+
this.state.params = params;
|
|
72
|
+
this.render();
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
start() {
|
|
76
|
+
window.addEventListener('popstate', () => this.handlePopState());
|
|
77
|
+
window.addEventListener('hashchange', () => this.handlePopState());
|
|
78
|
+
const { name, params } = this.parseHash();
|
|
79
|
+
this.currentRoute = this.routes.has(name) ? name : null;
|
|
80
|
+
this.state.page = name;
|
|
81
|
+
this.state.params = params;
|
|
82
|
+
this.render();
|
|
83
|
+
return this;
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
export function createRouter(opts) {
|
|
88
|
+
return new Router(opts);
|
|
89
|
+
}
|