white-label-router 6.1.0 → 6.1.1
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/README.md +19 -9
- package/dist/index.d.ts +4 -0
- package/dist/index.js +94 -59
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -67,7 +67,7 @@ router.initialize();
|
|
|
67
67
|
|
|
68
68
|
### Server
|
|
69
69
|
|
|
70
|
-
Pass
|
|
70
|
+
Pass a fully qualified request URL when possible. No `window` or `document` is required:
|
|
71
71
|
|
|
72
72
|
```js
|
|
73
73
|
const router = new Router();
|
|
@@ -75,10 +75,10 @@ router.routes = {
|
|
|
75
75
|
'/products': (_scope, location) => console.log(location.data.url),
|
|
76
76
|
defaultRoute: () => true
|
|
77
77
|
};
|
|
78
|
-
router.initialize('/products/42?color=blue');
|
|
78
|
+
router.initialize('https://example.com/products/42?color=blue');
|
|
79
79
|
```
|
|
80
80
|
|
|
81
|
-
Browser-only history, click interception, focus, and document-title effects are skipped on the server. Scope mutable routing state per request when appropriate.
|
|
81
|
+
Browser-only history, click interception, focus, and document-title effects are skipped on the server. Scope mutable routing state per request when appropriate. If a host exposes only a raw relative HTTP request target, preserve that target's path semantics at the adapter boundary before handing Router an absolute URL; see [Serverless and function runtimes](#serverless-and-function-runtimes).
|
|
82
82
|
|
|
83
83
|
## Progressive enhancement first
|
|
84
84
|
|
|
@@ -190,9 +190,9 @@ const result = router.navigate('/products/42', {
|
|
|
190
190
|
|
|
191
191
|
In browsers, successful navigation updates history unless the call represents `popstate`. On servers it dispatches without History API effects.
|
|
192
192
|
|
|
193
|
-
Rejected navigation is atomic from Router's perspective: cross-origin browser URLs, failed guards, and routes without runnable view behavior return `false` without destroying the current route, pushing browser history, or replacing the last successful URL, selected route, or location payload.
|
|
193
|
+
Rejected navigation is atomic from Router's perspective: malformed or wrong-type URL candidates, cross-origin browser URLs, failed guards, and routes without runnable view behavior return `false` without destroying the current route, pushing browser history, or replacing the last successful URL, selected route, or location payload.
|
|
194
194
|
|
|
195
|
-
Calling `navigate()` without a URL dispatches the current browser URL. In a non-browser runtime the safe default is `/`; server applications should normally supply
|
|
195
|
+
Calling `navigate()` without a URL dispatches the current browser URL. In a non-browser runtime the safe default is `/`; server applications should normally supply a fully qualified request URL explicitly.
|
|
196
196
|
|
|
197
197
|
## Mediator integration
|
|
198
198
|
|
|
@@ -220,15 +220,25 @@ Router does not import or require `white-label-mediator`; the integration is str
|
|
|
220
220
|
|
|
221
221
|
## Serverless and function runtimes
|
|
222
222
|
|
|
223
|
-
Pass the incoming request URL explicitly when Router runs inside a serverless function.
|
|
223
|
+
Pass the incoming request URL explicitly when Router runs inside a serverless function. A Web `Request` already supplies a fully qualified URL, so preserve it directly:
|
|
224
224
|
|
|
225
225
|
```js
|
|
226
|
-
const requestUrl = new URL(request.url);
|
|
227
226
|
const router = new Router();
|
|
228
227
|
router.routes = routes;
|
|
229
|
-
router.initialize(
|
|
228
|
+
router.initialize(request.url);
|
|
230
229
|
```
|
|
231
230
|
|
|
231
|
+
Do not parse that absolute URL and rebuild it from `pathname + search`; a pathname beginning `//` can change meaning when reparsed.
|
|
232
|
+
|
|
233
|
+
Some Node HTTP frameworks expose only a raw origin-form request target such as `/products/42?color=blue`. Prefix that raw target with the application's configured origin without feeding the target through `new URL(raw, origin)` first:
|
|
234
|
+
|
|
235
|
+
```js
|
|
236
|
+
const applicationOrigin = 'https://example.com';
|
|
237
|
+
router.initialize(`${applicationOrigin}${req.originalUrl}`);
|
|
238
|
+
```
|
|
239
|
+
|
|
240
|
+
This assumes the adapter's raw request target begins with `/`. If a host can also supply absolute-form request targets, detect and preserve those separately. A raw target beginning `//` is a path in HTTP origin-form but a network-path reference to WHATWG `URL`; handing `//...` directly to Router as a relative URL changes its meaning.
|
|
241
|
+
|
|
232
242
|
Create a request-scoped Router when its location state, mediator, route lifecycle, or other mutable configuration belongs to one invocation. Warm function processes may serve sequential or overlapping requests, so sharing one mutable Router can mix location/lifecycle state unless that process-wide lifetime is intentional.
|
|
233
243
|
|
|
234
244
|
Router handles **application routing inside the invocation**. It does not replace API Gateway routes, CDN routing, Vercel/Netlify/Cloudflare route configuration, load balancing, authentication infrastructure, or other cloud request plumbing.
|
|
@@ -264,7 +274,7 @@ Initialization dispatches the current URL without adding a duplicate history ent
|
|
|
264
274
|
| `navigationRoot` | Optional browser `Document`/`Element` that owns `data-pushstate` click interception; `null` uses `document`. Active listeners move when reassigned. | Configuration property. |
|
|
265
275
|
| `mediator` | Optional EventTarget-compatible source for `router:navigate`; active subscriptions move when this property changes. | Configuration property. |
|
|
266
276
|
| `initialize(url?)` | Dispatch the browser URL or an explicit server URL and attach applicable listeners. | The same `Router` instance. |
|
|
267
|
-
| `navigate(url?, data?, isPopState?)` | Match and run a route; update browser history when appropriate.
|
|
277
|
+
| `navigate(url?, data?, isPopState?)` | Match and run a route; update browser history when appropriate. Invalid/malformed URL candidates and other rejected navigation preserve current route state. | The same Router on success; `false` for rejected navigation. |
|
|
268
278
|
| `addListeners()` | Attach browser and optional mediator listeners once. | The same `Router` instance. |
|
|
269
279
|
| `removeListeners()` | Release listeners owned by this router. | The same `Router` instance. |
|
|
270
280
|
| `destroy()` | Release routing listeners. | The same `Router` instance after cleanup. |
|
package/dist/index.d.ts
CHANGED
|
@@ -60,10 +60,14 @@ declare class Router {
|
|
|
60
60
|
private getOrigin;
|
|
61
61
|
/** Read the authoritative browser URL, or retain the supplied server URL. */
|
|
62
62
|
private getCurrentUrl;
|
|
63
|
+
/** Parse a navigation candidate without changing Router state. */
|
|
64
|
+
private parseNavigationUrl;
|
|
63
65
|
/** Normalize browser navigation to a same-origin path, query, and hash. */
|
|
64
66
|
private normalizeBrowserUrl;
|
|
65
67
|
/** Return whether a selected route has runnable view behavior. */
|
|
66
68
|
private isRunnableRoute;
|
|
69
|
+
/** Build decoded path, query, and mediator data for a navigation candidate. */
|
|
70
|
+
private buildLocationData;
|
|
67
71
|
/**
|
|
68
72
|
* Start this instance and return it for lifecycle chaining.
|
|
69
73
|
* In a browser the URL is optional and defaults to window.location. On a server pass the request URL.
|
package/dist/index.js
CHANGED
|
@@ -34,7 +34,15 @@ class Router {
|
|
|
34
34
|
this.boundPushStateClick = this.eventPushStateClick.bind(this);
|
|
35
35
|
this.boundPopState = this.eventPopState.bind(this);
|
|
36
36
|
this.boundMediatorNavigate = (event) => {
|
|
37
|
-
const
|
|
37
|
+
const detail = event.detail;
|
|
38
|
+
if (detail === undefined || detail === null) {
|
|
39
|
+
this.navigate(undefined, {}, false);
|
|
40
|
+
return;
|
|
41
|
+
}
|
|
42
|
+
if (typeof detail !== 'object' || Array.isArray(detail)) {
|
|
43
|
+
return;
|
|
44
|
+
}
|
|
45
|
+
const data = detail;
|
|
38
46
|
this.navigate(data.url, data, false);
|
|
39
47
|
};
|
|
40
48
|
this.listenersInitialized = false;
|
|
@@ -86,13 +94,23 @@ class Router {
|
|
|
86
94
|
}
|
|
87
95
|
return window.location.pathname + window.location.search + (window.location.hash || '');
|
|
88
96
|
}
|
|
97
|
+
/** Parse a navigation candidate without changing Router state. */
|
|
98
|
+
parseNavigationUrl(url) {
|
|
99
|
+
try {
|
|
100
|
+
const base = this.isBrowserRuntime() ? window.location.href || `${window.location.origin}/` : this.getOrigin();
|
|
101
|
+
return new URL(url || '/', base);
|
|
102
|
+
}
|
|
103
|
+
catch (_error) {
|
|
104
|
+
return null;
|
|
105
|
+
}
|
|
106
|
+
}
|
|
89
107
|
/** Normalize browser navigation to a same-origin path, query, and hash. */
|
|
90
108
|
normalizeBrowserUrl(url) {
|
|
91
109
|
if (!this.isBrowserRuntime()) {
|
|
92
110
|
return url;
|
|
93
111
|
}
|
|
94
|
-
const parsedUrl =
|
|
95
|
-
if (parsedUrl.origin !== window.location.origin) {
|
|
112
|
+
const parsedUrl = this.parseNavigationUrl(url);
|
|
113
|
+
if (!parsedUrl || parsedUrl.origin !== window.location.origin) {
|
|
96
114
|
return null;
|
|
97
115
|
}
|
|
98
116
|
return `${parsedUrl.pathname}${parsedUrl.search}${parsedUrl.hash}`;
|
|
@@ -102,14 +120,36 @@ class Router {
|
|
|
102
120
|
return typeof route === 'function' || typeof route.view === 'function' ||
|
|
103
121
|
Boolean(route.view && typeof route.view.initialize === 'function');
|
|
104
122
|
}
|
|
123
|
+
/** Build decoded path, query, and mediator data for a navigation candidate. */
|
|
124
|
+
buildLocationData(url, route, mediatorData, parsedUrl) {
|
|
125
|
+
const matchedRoute = route && route !== 'defaultRoute' ? route : '';
|
|
126
|
+
return {
|
|
127
|
+
url,
|
|
128
|
+
data: {
|
|
129
|
+
url: parsedUrl.pathname
|
|
130
|
+
.slice(matchedRoute.length)
|
|
131
|
+
.split('/')
|
|
132
|
+
.filter(Boolean)
|
|
133
|
+
.map((fragment) => {
|
|
134
|
+
try {
|
|
135
|
+
return decodeURIComponent(fragment);
|
|
136
|
+
}
|
|
137
|
+
catch (_error) {
|
|
138
|
+
return fragment;
|
|
139
|
+
}
|
|
140
|
+
}),
|
|
141
|
+
mediator: mediatorData,
|
|
142
|
+
query: this.parseQueryString(parsedUrl.search)
|
|
143
|
+
}
|
|
144
|
+
};
|
|
145
|
+
}
|
|
105
146
|
/**
|
|
106
147
|
* Start this instance and return it for lifecycle chaining.
|
|
107
148
|
* In a browser the URL is optional and defaults to window.location. On a server pass the request URL.
|
|
108
149
|
*/
|
|
109
150
|
initialize(url) {
|
|
110
|
-
this.url = url ?? this.getCurrentUrl();
|
|
111
151
|
this.addListeners();
|
|
112
|
-
this.navigate(
|
|
152
|
+
this.navigate(url ?? this.getCurrentUrl(), {}, true);
|
|
113
153
|
return this;
|
|
114
154
|
}
|
|
115
155
|
/** Register browser and optional mediator handlers once. */
|
|
@@ -170,7 +210,11 @@ class Router {
|
|
|
170
210
|
if (anchor.hasAttribute('download') || (target && target.toLowerCase() !== '_self')) {
|
|
171
211
|
return true;
|
|
172
212
|
}
|
|
173
|
-
const
|
|
213
|
+
const href = anchor.href || anchor.getAttribute('href') || '';
|
|
214
|
+
const baseUrl = typeof document !== 'undefined' && document.baseURI
|
|
215
|
+
? document.baseURI
|
|
216
|
+
: window.location.href || `${window.location.origin}/`;
|
|
217
|
+
const location = new URL(href, baseUrl);
|
|
174
218
|
if (location.origin !== window.location.origin) {
|
|
175
219
|
return true;
|
|
176
220
|
}
|
|
@@ -183,8 +227,7 @@ class Router {
|
|
|
183
227
|
if (typeof window === 'undefined') {
|
|
184
228
|
return this;
|
|
185
229
|
}
|
|
186
|
-
this.
|
|
187
|
-
this.navigate(undefined, {}, true);
|
|
230
|
+
this.navigate(this.getCurrentUrl(), {}, true);
|
|
188
231
|
return this;
|
|
189
232
|
}
|
|
190
233
|
/** Decode URL query parameters, keeping the last value for duplicate keys. */
|
|
@@ -193,25 +236,16 @@ class Router {
|
|
|
193
236
|
}
|
|
194
237
|
/** Build decoded path, query, and mediator data for the selected route. */
|
|
195
238
|
setLocationData(mediatorData) {
|
|
196
|
-
const
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
}
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
.map((fragment) => {
|
|
207
|
-
try {
|
|
208
|
-
return decodeURIComponent(fragment);
|
|
209
|
-
}
|
|
210
|
-
catch (_error) {
|
|
211
|
-
return fragment;
|
|
212
|
-
}
|
|
213
|
-
});
|
|
214
|
-
this.locationData.data.query = this.parseQueryString(parsedUrl.search);
|
|
239
|
+
const url = this.url || '/';
|
|
240
|
+
let parsedUrl;
|
|
241
|
+
try {
|
|
242
|
+
const value = this.isBrowserRuntime() ? `${window.location.origin}${url}` : url;
|
|
243
|
+
parsedUrl = new URL(value, this.getOrigin());
|
|
244
|
+
}
|
|
245
|
+
catch (_error) {
|
|
246
|
+
return;
|
|
247
|
+
}
|
|
248
|
+
this.locationData = this.buildLocationData(this.url, this.route, mediatorData, parsedUrl);
|
|
215
249
|
}
|
|
216
250
|
/** Update page context after a route renders. DOM effects are browser-only. */
|
|
217
251
|
applyPageContext(route) {
|
|
@@ -239,44 +273,45 @@ class Router {
|
|
|
239
273
|
}
|
|
240
274
|
/** Select a route, enforce its guard, transition view lifecycles, and update browser history when available. */
|
|
241
275
|
navigate(url, mediatorData, isPopState = false) {
|
|
242
|
-
|
|
243
|
-
const previousSelectedRoute = this.route;
|
|
244
|
-
const previousLocationData = this.locationData;
|
|
245
|
-
if (url !== undefined) {
|
|
246
|
-
this.url = url;
|
|
247
|
-
}
|
|
248
|
-
if (!this.url) {
|
|
249
|
-
this.url = this.getCurrentUrl();
|
|
250
|
-
}
|
|
251
|
-
const normalizedUrl = this.normalizeBrowserUrl(this.url);
|
|
252
|
-
if (normalizedUrl === null) {
|
|
253
|
-
this.url = previousUrl;
|
|
276
|
+
if (url !== undefined && typeof url !== 'string') {
|
|
254
277
|
return false;
|
|
255
278
|
}
|
|
256
|
-
this.url
|
|
257
|
-
|
|
258
|
-
|
|
279
|
+
let candidateInput = url !== undefined ? url : this.url;
|
|
280
|
+
if (!candidateInput) {
|
|
281
|
+
candidateInput = this.getCurrentUrl();
|
|
282
|
+
}
|
|
283
|
+
const parsedUrl = this.parseNavigationUrl(candidateInput);
|
|
284
|
+
if (!parsedUrl) {
|
|
285
|
+
return false;
|
|
286
|
+
}
|
|
287
|
+
if (this.isBrowserRuntime() && parsedUrl.origin !== window.location.origin) {
|
|
288
|
+
return false;
|
|
289
|
+
}
|
|
290
|
+
const candidateUrl = this.isBrowserRuntime()
|
|
291
|
+
? `${parsedUrl.pathname}${parsedUrl.search}${parsedUrl.hash}`
|
|
292
|
+
: candidateInput;
|
|
293
|
+
let candidateRoute = null;
|
|
259
294
|
for (const route of Object.keys(this.routes)) {
|
|
260
|
-
if (route === 'defaultRoute' || (pathname !== route && !pathname.startsWith(`${route}/`))) {
|
|
295
|
+
if (route === 'defaultRoute' || (parsedUrl.pathname !== route && !parsedUrl.pathname.startsWith(`${route}/`))) {
|
|
261
296
|
continue;
|
|
262
297
|
}
|
|
263
|
-
if (!
|
|
264
|
-
|
|
298
|
+
if (!candidateRoute || route.length > candidateRoute.length) {
|
|
299
|
+
candidateRoute = route;
|
|
265
300
|
}
|
|
266
301
|
}
|
|
267
|
-
this.
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
302
|
+
if (!candidateRoute && Object.prototype.hasOwnProperty.call(this.routes, 'defaultRoute') && this.routes.defaultRoute) {
|
|
303
|
+
candidateRoute = 'defaultRoute';
|
|
304
|
+
}
|
|
305
|
+
const candidateLocationData = this.buildLocationData(candidateUrl, candidateRoute, mediatorData, parsedUrl);
|
|
306
|
+
const selected = candidateRoute ? this.routes[candidateRoute] : undefined;
|
|
307
|
+
if (selected && ((typeof selected !== 'function' && selected.secure && selected.secure(this.scope, candidateLocationData) !== true) ||
|
|
308
|
+
!this.isRunnableRoute(selected))) {
|
|
309
|
+
return false;
|
|
310
|
+
}
|
|
311
|
+
this.url = candidateUrl;
|
|
312
|
+
this.route = candidateRoute;
|
|
313
|
+
this.locationData = candidateLocationData;
|
|
314
|
+
if (selected) {
|
|
280
315
|
const previous = this.previousRoute ? this.routes[this.previousRoute] : undefined;
|
|
281
316
|
if (previous && typeof previous !== 'function' && typeof previous.view === 'object' && previous.view.destroy) {
|
|
282
317
|
previous.view.destroy(this.scope, this.locationData);
|
|
@@ -294,7 +329,7 @@ class Router {
|
|
|
294
329
|
this.previousRoute = this.route;
|
|
295
330
|
}
|
|
296
331
|
if (!isPopState && this.isBrowserRuntime()) {
|
|
297
|
-
window.history.pushState(this.url, this.pageTitle || '',
|
|
332
|
+
window.history.pushState(this.url, this.pageTitle || '', parsedUrl.href);
|
|
298
333
|
}
|
|
299
334
|
return this;
|
|
300
335
|
}
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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","sourcesContent":["/** Navigation payload, including caller-defined metadata. */\ninterface NavigationData {url?: string; [key: string]: unknown}\n/** URL-derived values supplied to route handlers. */\ninterface LocationData {url: string; data: {url: string[]; mediator: NavigationData | undefined; query: Record<string, string>}}\ntype RouteHandler = (scope: Element | null, location: LocationData) => unknown;\n/** An object route can own a function or a view lifecycle. */\ninterface RouteObject {title?: string; focus?: string | false; secure?: RouteHandler; view?: RouteHandler | {initialize?: RouteHandler; destroy?: RouteHandler}}\ntype Route = RouteHandler | RouteObject;\n/** Minimal standards-based event target contract required by the router. */\ninterface NavigationMediator {\n addEventListener(type: string, callback: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void;\n removeEventListener(type: string, callback: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void;\n}\n/** History API router that also dispatches request URLs in non-browser runtimes. */\nclass Router {\n routes: Record<string, Route>;\n url: string;\n route: string | null;\n scope: Element | null;\n previousRoute: string | null;\n pageTitle: string | null;\n boundPushStateClick: (event: MouseEvent) => unknown;\n boundPopState: (event: PopStateEvent) => unknown;\n boundMediatorNavigate: EventListener;\n listenersInitialized: boolean;\n locationData: LocationData = {url: '', data: {url: [], mediator: undefined, query: {}}};\n private currentMediator: NavigationMediator | false = false;\n private boundMediator: NavigationMediator | false = false;\n private currentNavigationRoot: Document | Element | null = null;\n private boundNavigationRoot: Document | Element | null = null;\n\n /** Create an instance with its own state and listener references. */\n constructor() {\n this.routes = {\n defaultRoute: {\n view: {\n initialize: () => true,\n destroy: () => true\n }\n }\n };\n this.url = '';\n this.route = null;\n this.scope = null;\n this.previousRoute = null;\n this.pageTitle = null;\n this.boundPushStateClick = this.eventPushStateClick.bind(this);\n this.boundPopState = this.eventPopState.bind(this);\n this.boundMediatorNavigate = (event: Event) => {\n const data = (event as CustomEvent<NavigationData | undefined>).detail ?? {};\n this.navigate(data.url, data, false);\n };\n this.listenersInitialized = false;\n }\n\n get mediator(): NavigationMediator | false {return this.currentMediator;}\n\n /** Move an active router:navigate subscription when the mediator changes. */\n set mediator(value: NavigationMediator | false) {\n if (value === this.currentMediator) {return;}\n if (this.listenersInitialized && this.boundMediator) {\n this.boundMediator.removeEventListener('router:navigate', this.boundMediatorNavigate);\n this.boundMediator = false;\n }\n this.currentMediator = value;\n if (this.listenersInitialized && value) {\n value.addEventListener('router:navigate', this.boundMediatorNavigate);\n this.boundMediator = value;\n }\n }\n\n get navigationRoot(): Document | Element | null {return this.currentNavigationRoot;}\n\n /** Scope progressive link interception and move an active click listener when the root changes. */\n set navigationRoot(value: Document | Element | null) {\n if (value === this.currentNavigationRoot) {return;}\n if (this.listenersInitialized && this.isBrowserRuntime()) {\n this.boundNavigationRoot?.removeEventListener('click', this.boundPushStateClick as EventListener);\n this.currentNavigationRoot = value;\n const nextRoot = value || document;\n nextRoot.addEventListener('click', this.boundPushStateClick as EventListener);\n this.boundNavigationRoot = nextRoot;\n return;\n }\n this.currentNavigationRoot = value;\n }\n\n /** True when browser navigation APIs are available. */\n private isBrowserRuntime() {\n return typeof window !== 'undefined' && typeof document !== 'undefined';\n }\n\n /** Stable base URL for WHATWG URL parsing in browser and server runtimes. */\n private getOrigin() {\n return this.isBrowserRuntime() ? window.location.origin : 'http://white-label.invalid';\n }\n\n /** Read the authoritative browser URL, or retain the supplied server URL. */\n private getCurrentUrl() {\n if (!this.isBrowserRuntime()) {return this.url || '/';}\n return window.location.pathname + window.location.search + (window.location.hash || '');\n }\n\n /** Normalize browser navigation to a same-origin path, query, and hash. */\n private normalizeBrowserUrl(url: string) {\n if (!this.isBrowserRuntime()) {return url;}\n const parsedUrl = new URL(url || '/', window.location.href || `${window.location.origin}/`);\n if (parsedUrl.origin !== window.location.origin) {return null;}\n return `${parsedUrl.pathname}${parsedUrl.search}${parsedUrl.hash}`;\n }\n\n /** Return whether a selected route has runnable view behavior. */\n private isRunnableRoute(route: Route): boolean {\n return typeof route === 'function' || typeof route.view === 'function' ||\n Boolean(route.view && typeof route.view.initialize === 'function');\n }\n\n /**\n * Start this instance and return it for lifecycle chaining.\n * In a browser the URL is optional and defaults to window.location. On a server pass the request URL.\n */\n initialize(url?: string) {\n this.url = url ?? this.getCurrentUrl();\n this.addListeners();\n this.navigate(undefined, {}, true);\n return this;\n }\n\n /** Register browser and optional mediator handlers once. */\n addListeners() {\n if (this.listenersInitialized) {return this;}\n if (this.isBrowserRuntime()) {\n const navigationRoot = this.currentNavigationRoot || document;\n navigationRoot.addEventListener('click', this.boundPushStateClick as EventListener);\n this.boundNavigationRoot = navigationRoot;\n window.addEventListener('popstate', this.boundPopState);\n }\n if (this.currentMediator) {\n this.currentMediator.addEventListener('router:navigate', this.boundMediatorNavigate);\n this.boundMediator = this.currentMediator;\n }\n this.listenersInitialized = true;\n return this;\n }\n\n /** Release owned state and listeners so the instance can leave the application lifecycle. */\n destroy() {\n this.removeListeners();\n return this;\n }\n\n /** Release listeners owned by this instance; subclasses may extend the lifecycle hook. */\n removeListeners() {\n if (!this.listenersInitialized) {return this;}\n if (this.isBrowserRuntime()) {\n this.boundNavigationRoot?.removeEventListener('click', this.boundPushStateClick as EventListener);\n this.boundNavigationRoot = null;\n window.removeEventListener('popstate', this.boundPopState);\n }\n if (this.boundMediator) {\n this.boundMediator.removeEventListener('router:navigate', this.boundMediatorNavigate);\n this.boundMediator = false;\n }\n this.listenersInitialized = false;\n return this;\n }\n\n /** Intercept eligible same-origin push-state links while preserving normal browser actions. */\n eventPushStateClick(e: MouseEvent) {\n if (typeof window === 'undefined') {return true;}\n if (e.defaultPrevented || (e.button !== undefined && e.button !== 0) || e.metaKey || e.ctrlKey || e.shiftKey || e.altKey) {\n return true;\n }\n const eventTarget = e.target as Element | null;\n const source = eventTarget && (typeof eventTarget.closest === 'function' ? eventTarget : eventTarget.parentElement);\n const anchor = source && typeof source.closest === 'function' ? source.closest('a[href][data-pushstate]') : null;\n if (!anchor) {return true;}\n const target = anchor.getAttribute('target');\n if (anchor.hasAttribute('download') || (target && target.toLowerCase() !== '_self')) {return true;}\n const location = new URL(anchor.getAttribute('href') || '', window.location.href || `${window.location.origin}/`);\n if (location.origin !== window.location.origin) {return true;}\n e.preventDefault();\n this.navigate(`${location.pathname}${location.search}${location.hash}`, {}, false);\n return this;\n }\n\n /** Restore browser history state without adding a new history entry. */\n eventPopState() {\n if (typeof window === 'undefined') {return this;}\n this.url = this.getCurrentUrl();\n this.navigate(undefined, {}, true);\n return this;\n }\n\n /** Decode URL query parameters, keeping the last value for duplicate keys. */\n parseQueryString(queryString: string) {\n return Object.fromEntries(new URLSearchParams(queryString));\n }\n\n /** Build decoded path, query, and mediator data for the selected route. */\n setLocationData(mediatorData?: NavigationData) {\n const parsedUrl = new URL(this.url || '/', this.getOrigin());\n const matchedRoute = this.route && this.route !== 'defaultRoute' ? this.route : '';\n this.locationData = {\n url: this.url,\n data: {url: [], mediator: mediatorData, query: {}}\n };\n this.locationData.data.url = parsedUrl.pathname\n .slice(matchedRoute.length)\n .split('/')\n .filter(Boolean)\n .map((fragment) => {\n try {return decodeURIComponent(fragment);} catch (_error) {return fragment;}\n });\n this.locationData.data.query = this.parseQueryString(parsedUrl.search);\n }\n\n /** Update page context after a route renders. DOM effects are browser-only. */\n applyPageContext(route: Route) {\n if (typeof route === 'function') {\n this.pageTitle = null;\n return this;\n }\n this.pageTitle = typeof route.title === 'string' ? route.title : null;\n if (!this.isBrowserRuntime()) {return this;}\n if (this.pageTitle) {document.title = this.pageTitle;}\n if (route.focus !== false) {\n const target = document.querySelector<HTMLElement>(route.focus || 'main h1');\n if (target) {\n if (!target.hasAttribute('tabindex')) {target.setAttribute('tabindex', '-1');}\n target.focus();\n }\n }\n return this;\n }\n\n /** Select a route, enforce its guard, transition view lifecycles, and update browser history when available. */\n navigate(url?: string, mediatorData?: NavigationData, isPopState = false) {\n const previousUrl = this.url;\n const previousSelectedRoute = this.route;\n const previousLocationData = this.locationData;\n if (url !== undefined) {this.url = url;}\n if (!this.url) {this.url = this.getCurrentUrl();}\n const normalizedUrl = this.normalizeBrowserUrl(this.url);\n if (normalizedUrl === null) {\n this.url = previousUrl;\n return false;\n }\n this.url = normalizedUrl;\n this.route = null;\n const pathname = new URL(this.url, this.getOrigin()).pathname;\n for (const route of Object.keys(this.routes)) {\n if (route === 'defaultRoute' || (pathname !== route && !pathname.startsWith(`${route}/`))) {continue;}\n if (!this.route || route.length > this.route.length) {this.route = route;}\n }\n this.setLocationData(mediatorData);\n if (!this.route && this.routes.defaultRoute) {this.route = 'defaultRoute';}\n if (this.route) {\n const selected = this.routes[this.route]!;\n if ((typeof selected !== 'function' && selected.secure && selected.secure(this.scope, this.locationData) !== true) ||\n !this.isRunnableRoute(selected)) {\n this.url = previousUrl;\n this.route = previousSelectedRoute;\n this.locationData = previousLocationData;\n return false;\n }\n const previous = this.previousRoute ? this.routes[this.previousRoute] : undefined;\n if (previous && typeof previous !== 'function' && typeof previous.view === 'object' && previous.view.destroy) {\n previous.view.destroy(this.scope, this.locationData);\n }\n if (typeof selected === 'function') {\n selected(this.scope, this.locationData);\n } else if (typeof selected.view === 'function') {\n selected.view(this.scope, this.locationData);\n } else {\n selected.view!.initialize!(this.scope, this.locationData);\n }\n this.applyPageContext(selected);\n this.previousRoute = this.route;\n }\n if (!isPopState && this.isBrowserRuntime()) {\n window.history.pushState(this.url, this.pageTitle || '', this.url);\n }\n return this;\n }\n}\n\n/** Public route configuration and navigation payload types. */\nnamespace Router {\n export type Handler = RouteHandler;\n export type Route = RouteHandler | RouteObject;\n export type Location = LocationData;\n export type Navigation = NavigationData;\n}\nexport = Router;\n"]}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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","sourcesContent":["/** Navigation payload, including caller-defined metadata. */\ninterface NavigationData {url?: string; [key: string]: unknown}\n/** URL-derived values supplied to route handlers. */\ninterface LocationData {url: string; data: {url: string[]; mediator: NavigationData | undefined; query: Record<string, string>}}\ntype RouteHandler = (scope: Element | null, location: LocationData) => unknown;\n/** An object route can own a function or a view lifecycle. */\ninterface RouteObject {title?: string; focus?: string | false; secure?: RouteHandler; view?: RouteHandler | {initialize?: RouteHandler; destroy?: RouteHandler}}\ntype Route = RouteHandler | RouteObject;\n/** Minimal standards-based event target contract required by the router. */\ninterface NavigationMediator {\n addEventListener(type: string, callback: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void;\n removeEventListener(type: string, callback: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void;\n}\n/** History API router that also dispatches request URLs in non-browser runtimes. */\nclass Router {\n routes: Record<string, Route>;\n url: string;\n route: string | null;\n scope: Element | null;\n previousRoute: string | null;\n pageTitle: string | null;\n boundPushStateClick: (event: MouseEvent) => unknown;\n boundPopState: (event: PopStateEvent) => unknown;\n boundMediatorNavigate: EventListener;\n listenersInitialized: boolean;\n locationData: LocationData = {url: '', data: {url: [], mediator: undefined, query: {}}};\n private currentMediator: NavigationMediator | false = false;\n private boundMediator: NavigationMediator | false = false;\n private currentNavigationRoot: Document | Element | null = null;\n private boundNavigationRoot: Document | Element | null = null;\n\n /** Create an instance with its own state and listener references. */\n constructor() {\n this.routes = {\n defaultRoute: {\n view: {\n initialize: () => true,\n destroy: () => true\n }\n }\n };\n this.url = '';\n this.route = null;\n this.scope = null;\n this.previousRoute = null;\n this.pageTitle = null;\n this.boundPushStateClick = this.eventPushStateClick.bind(this);\n this.boundPopState = this.eventPopState.bind(this);\n this.boundMediatorNavigate = (event: Event) => {\n const detail = (event as CustomEvent<unknown>).detail;\n if (detail === undefined || detail === null) {\n this.navigate(undefined, {}, false);\n return;\n }\n if (typeof detail !== 'object' || Array.isArray(detail)) {return;}\n const data = detail as NavigationData;\n this.navigate(data.url, data, false);\n };\n this.listenersInitialized = false;\n }\n\n get mediator(): NavigationMediator | false {return this.currentMediator;}\n\n /** Move an active router:navigate subscription when the mediator changes. */\n set mediator(value: NavigationMediator | false) {\n if (value === this.currentMediator) {return;}\n if (this.listenersInitialized && this.boundMediator) {\n this.boundMediator.removeEventListener('router:navigate', this.boundMediatorNavigate);\n this.boundMediator = false;\n }\n this.currentMediator = value;\n if (this.listenersInitialized && value) {\n value.addEventListener('router:navigate', this.boundMediatorNavigate);\n this.boundMediator = value;\n }\n }\n\n get navigationRoot(): Document | Element | null {return this.currentNavigationRoot;}\n\n /** Scope progressive link interception and move an active click listener when the root changes. */\n set navigationRoot(value: Document | Element | null) {\n if (value === this.currentNavigationRoot) {return;}\n if (this.listenersInitialized && this.isBrowserRuntime()) {\n this.boundNavigationRoot?.removeEventListener('click', this.boundPushStateClick as EventListener);\n this.currentNavigationRoot = value;\n const nextRoot = value || document;\n nextRoot.addEventListener('click', this.boundPushStateClick as EventListener);\n this.boundNavigationRoot = nextRoot;\n return;\n }\n this.currentNavigationRoot = value;\n }\n\n /** True when browser navigation APIs are available. */\n private isBrowserRuntime() {\n return typeof window !== 'undefined' && typeof document !== 'undefined';\n }\n\n /** Stable base URL for WHATWG URL parsing in browser and server runtimes. */\n private getOrigin() {\n return this.isBrowserRuntime() ? window.location.origin : 'http://white-label.invalid';\n }\n\n /** Read the authoritative browser URL, or retain the supplied server URL. */\n private getCurrentUrl() {\n if (!this.isBrowserRuntime()) {return this.url || '/';}\n return window.location.pathname + window.location.search + (window.location.hash || '');\n }\n\n /** Parse a navigation candidate without changing Router state. */\n private parseNavigationUrl(url: string) {\n try {\n const base = this.isBrowserRuntime() ? window.location.href || `${window.location.origin}/` : this.getOrigin();\n return new URL(url || '/', base);\n } catch (_error) {\n return null;\n }\n }\n\n /** Normalize browser navigation to a same-origin path, query, and hash. */\n private normalizeBrowserUrl(url: string) {\n if (!this.isBrowserRuntime()) {return url;}\n const parsedUrl = this.parseNavigationUrl(url);\n if (!parsedUrl || parsedUrl.origin !== window.location.origin) {return null;}\n return `${parsedUrl.pathname}${parsedUrl.search}${parsedUrl.hash}`;\n }\n\n /** Return whether a selected route has runnable view behavior. */\n private isRunnableRoute(route: Route): boolean {\n return typeof route === 'function' || typeof route.view === 'function' ||\n Boolean(route.view && typeof route.view.initialize === 'function');\n }\n\n /** Build decoded path, query, and mediator data for a navigation candidate. */\n private buildLocationData(url: string, route: string | null, mediatorData: NavigationData | undefined, parsedUrl: URL): LocationData {\n const matchedRoute = route && route !== 'defaultRoute' ? route : '';\n return {\n url,\n data: {\n url: parsedUrl.pathname\n .slice(matchedRoute.length)\n .split('/')\n .filter(Boolean)\n .map((fragment) => {\n try {return decodeURIComponent(fragment);} catch (_error) {return fragment;}\n }),\n mediator: mediatorData,\n query: this.parseQueryString(parsedUrl.search)\n }\n };\n }\n\n /**\n * Start this instance and return it for lifecycle chaining.\n * In a browser the URL is optional and defaults to window.location. On a server pass the request URL.\n */\n initialize(url?: string) {\n this.addListeners();\n this.navigate(url ?? this.getCurrentUrl(), {}, true);\n return this;\n }\n\n /** Register browser and optional mediator handlers once. */\n addListeners() {\n if (this.listenersInitialized) {return this;}\n if (this.isBrowserRuntime()) {\n const navigationRoot = this.currentNavigationRoot || document;\n navigationRoot.addEventListener('click', this.boundPushStateClick as EventListener);\n this.boundNavigationRoot = navigationRoot;\n window.addEventListener('popstate', this.boundPopState);\n }\n if (this.currentMediator) {\n this.currentMediator.addEventListener('router:navigate', this.boundMediatorNavigate);\n this.boundMediator = this.currentMediator;\n }\n this.listenersInitialized = true;\n return this;\n }\n\n /** Release owned state and listeners so the instance can leave the application lifecycle. */\n destroy() {\n this.removeListeners();\n return this;\n }\n\n /** Release listeners owned by this instance; subclasses may extend the lifecycle hook. */\n removeListeners() {\n if (!this.listenersInitialized) {return this;}\n if (this.isBrowserRuntime()) {\n this.boundNavigationRoot?.removeEventListener('click', this.boundPushStateClick as EventListener);\n this.boundNavigationRoot = null;\n window.removeEventListener('popstate', this.boundPopState);\n }\n if (this.boundMediator) {\n this.boundMediator.removeEventListener('router:navigate', this.boundMediatorNavigate);\n this.boundMediator = false;\n }\n this.listenersInitialized = false;\n return this;\n }\n\n /** Intercept eligible same-origin push-state links while preserving normal browser actions. */\n eventPushStateClick(e: MouseEvent) {\n if (typeof window === 'undefined') {return true;}\n if (e.defaultPrevented || (e.button !== undefined && e.button !== 0) || e.metaKey || e.ctrlKey || e.shiftKey || e.altKey) {\n return true;\n }\n const eventTarget = e.target as Element | null;\n const source = eventTarget && (typeof eventTarget.closest === 'function' ? eventTarget : eventTarget.parentElement);\n const anchor = source && typeof source.closest === 'function' ? source.closest('a[href][data-pushstate]') : null;\n if (!anchor) {return true;}\n const target = anchor.getAttribute('target');\n if (anchor.hasAttribute('download') || (target && target.toLowerCase() !== '_self')) {return true;}\n const href = (anchor as HTMLAnchorElement).href || anchor.getAttribute('href') || '';\n const baseUrl = typeof document !== 'undefined' && document.baseURI\n ? document.baseURI\n : window.location.href || `${window.location.origin}/`;\n const location = new URL(href, baseUrl);\n if (location.origin !== window.location.origin) {return true;}\n e.preventDefault();\n this.navigate(`${location.pathname}${location.search}${location.hash}`, {}, false);\n return this;\n }\n\n /** Restore browser history state without adding a new history entry. */\n eventPopState() {\n if (typeof window === 'undefined') {return this;}\n this.navigate(this.getCurrentUrl(), {}, true);\n return this;\n }\n\n /** Decode URL query parameters, keeping the last value for duplicate keys. */\n parseQueryString(queryString: string) {\n return Object.fromEntries(new URLSearchParams(queryString));\n }\n\n /** Build decoded path, query, and mediator data for the selected route. */\n setLocationData(mediatorData?: NavigationData) {\n const url = this.url || '/';\n let parsedUrl: URL;\n try {\n const value = this.isBrowserRuntime() ? `${window.location.origin}${url}` : url;\n parsedUrl = new URL(value, this.getOrigin());\n } catch (_error) {\n return;\n }\n this.locationData = this.buildLocationData(this.url, this.route, mediatorData, parsedUrl);\n }\n\n /** Update page context after a route renders. DOM effects are browser-only. */\n applyPageContext(route: Route) {\n if (typeof route === 'function') {\n this.pageTitle = null;\n return this;\n }\n this.pageTitle = typeof route.title === 'string' ? route.title : null;\n if (!this.isBrowserRuntime()) {return this;}\n if (this.pageTitle) {document.title = this.pageTitle;}\n if (route.focus !== false) {\n const target = document.querySelector<HTMLElement>(route.focus || 'main h1');\n if (target) {\n if (!target.hasAttribute('tabindex')) {target.setAttribute('tabindex', '-1');}\n target.focus();\n }\n }\n return this;\n }\n\n /** Select a route, enforce its guard, transition view lifecycles, and update browser history when available. */\n navigate(url?: string, mediatorData?: NavigationData, isPopState = false) {\n if (url !== undefined && typeof url !== 'string') {return false;}\n\n let candidateInput = url !== undefined ? url : this.url;\n if (!candidateInput) {candidateInput = this.getCurrentUrl();}\n const parsedUrl = this.parseNavigationUrl(candidateInput);\n if (!parsedUrl) {return false;}\n if (this.isBrowserRuntime() && parsedUrl.origin !== window.location.origin) {return false;}\n\n const candidateUrl = this.isBrowserRuntime()\n ? `${parsedUrl.pathname}${parsedUrl.search}${parsedUrl.hash}`\n : candidateInput;\n let candidateRoute: string | null = null;\n for (const route of Object.keys(this.routes)) {\n if (route === 'defaultRoute' || (parsedUrl.pathname !== route && !parsedUrl.pathname.startsWith(`${route}/`))) {continue;}\n if (!candidateRoute || route.length > candidateRoute.length) {candidateRoute = route;}\n }\n if (!candidateRoute && Object.prototype.hasOwnProperty.call(this.routes, 'defaultRoute') && this.routes.defaultRoute) {\n candidateRoute = 'defaultRoute';\n }\n\n const candidateLocationData = this.buildLocationData(candidateUrl, candidateRoute, mediatorData, parsedUrl);\n const selected = candidateRoute ? this.routes[candidateRoute] : undefined;\n if (selected && ((typeof selected !== 'function' && selected.secure && selected.secure(this.scope, candidateLocationData) !== true) ||\n !this.isRunnableRoute(selected))) {\n return false;\n }\n\n this.url = candidateUrl;\n this.route = candidateRoute;\n this.locationData = candidateLocationData;\n if (selected) {\n const previous = this.previousRoute ? this.routes[this.previousRoute] : undefined;\n if (previous && typeof previous !== 'function' && typeof previous.view === 'object' && previous.view.destroy) {\n previous.view.destroy(this.scope, this.locationData);\n }\n if (typeof selected === 'function') {\n selected(this.scope, this.locationData);\n } else if (typeof selected.view === 'function') {\n selected.view(this.scope, this.locationData);\n } else {\n selected.view!.initialize!(this.scope, this.locationData);\n }\n this.applyPageContext(selected);\n this.previousRoute = this.route;\n }\n if (!isPopState && this.isBrowserRuntime()) {\n window.history.pushState(this.url, this.pageTitle || '', parsedUrl.href);\n }\n return this;\n }\n}\n\n/** Public route configuration and navigation payload types. */\nnamespace Router {\n export type Handler = RouteHandler;\n export type Route = RouteHandler | RouteObject;\n export type Location = LocationData;\n export type Navigation = NavigationData;\n}\nexport = Router;\n"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "white-label-router",
|
|
3
|
-
"version": "6.1.
|
|
3
|
+
"version": "6.1.1",
|
|
4
4
|
"description": "Framework-independent TypeScript router for progressive enhancement in browser, server-rendered, and Node.js applications, with scoped links, guards, and accessible navigation.",
|
|
5
5
|
"sideEffects": false,
|
|
6
6
|
"main": "dist/index.js",
|