@emkodev/emroute 1.6.2 → 1.6.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +6 -6
- package/dist/runtime/abstract.runtime.d.ts +94 -0
- package/dist/runtime/abstract.runtime.js +339 -0
- package/dist/runtime/abstract.runtime.js.map +1 -0
- package/dist/runtime/bun/esbuild-runtime-loader.plugin.d.ts +25 -0
- package/dist/runtime/bun/esbuild-runtime-loader.plugin.js +72 -0
- package/dist/runtime/bun/esbuild-runtime-loader.plugin.js.map +1 -0
- package/dist/runtime/bun/fs/bun-fs.runtime.d.ts +21 -0
- package/dist/runtime/bun/fs/bun-fs.runtime.js +205 -0
- package/dist/runtime/bun/fs/bun-fs.runtime.js.map +1 -0
- package/dist/runtime/bun/sqlite/bun-sqlite.runtime.d.ts +27 -0
- package/dist/runtime/bun/sqlite/bun-sqlite.runtime.js +234 -0
- package/dist/runtime/bun/sqlite/bun-sqlite.runtime.js.map +1 -0
- package/dist/runtime/sitemap.generator.d.ts +58 -0
- package/dist/runtime/sitemap.generator.js +107 -0
- package/dist/runtime/sitemap.generator.js.map +1 -0
- package/dist/runtime/universal/fs/universal-fs.runtime.d.ts +29 -0
- package/dist/runtime/universal/fs/universal-fs.runtime.js +213 -0
- package/dist/runtime/universal/fs/universal-fs.runtime.js.map +1 -0
- package/dist/server/codegen.util.d.ts +16 -0
- package/dist/server/codegen.util.js +46 -0
- package/dist/server/codegen.util.js.map +1 -0
- package/dist/server/emroute.server.d.ts +37 -0
- package/dist/server/emroute.server.js +314 -0
- package/dist/server/emroute.server.js.map +1 -0
- package/dist/server/esbuild-manifest.plugin.d.ts +26 -0
- package/dist/server/esbuild-manifest.plugin.js +187 -0
- package/dist/server/esbuild-manifest.plugin.js.map +1 -0
- package/dist/server/scanner.util.d.ts +22 -0
- package/dist/server/scanner.util.js +194 -0
- package/dist/server/scanner.util.js.map +1 -0
- package/dist/server/server-api.type.d.ts +71 -0
- package/dist/server/server-api.type.js +9 -0
- package/dist/server/server-api.type.js.map +1 -0
- package/dist/src/component/abstract.component.d.ts +197 -0
- package/dist/src/component/abstract.component.js +84 -0
- package/dist/src/component/abstract.component.js.map +1 -0
- package/dist/src/component/page.component.d.ts +74 -0
- package/dist/src/component/page.component.js +107 -0
- package/dist/src/component/page.component.js.map +1 -0
- package/dist/src/component/widget.component.d.ts +47 -0
- package/dist/src/component/widget.component.js +69 -0
- package/dist/src/component/widget.component.js.map +1 -0
- package/dist/src/element/component.element.d.ts +79 -0
- package/dist/src/element/component.element.js +293 -0
- package/dist/src/element/component.element.js.map +1 -0
- package/dist/src/element/markdown.element.d.ts +36 -0
- package/dist/src/element/markdown.element.js +93 -0
- package/dist/src/element/markdown.element.js.map +1 -0
- package/dist/src/element/slot.element.d.ts +30 -0
- package/dist/src/element/slot.element.js +31 -0
- package/dist/src/element/slot.element.js.map +1 -0
- package/dist/src/index.d.ts +23 -0
- package/dist/src/index.js +24 -0
- package/dist/src/index.js.map +1 -0
- package/dist/src/overlay/mod.d.ts +9 -0
- package/dist/src/overlay/mod.js +9 -0
- package/dist/src/overlay/mod.js.map +1 -0
- package/dist/src/overlay/overlay.css.d.ts +8 -0
- package/dist/src/overlay/overlay.css.js +170 -0
- package/dist/src/overlay/overlay.css.js.map +1 -0
- package/dist/src/overlay/overlay.service.d.ts +14 -0
- package/dist/src/overlay/overlay.service.js +307 -0
- package/dist/src/overlay/overlay.service.js.map +1 -0
- package/dist/src/overlay/overlay.type.d.ts +33 -0
- package/dist/src/overlay/overlay.type.js +11 -0
- package/dist/src/overlay/overlay.type.js.map +1 -0
- package/dist/src/renderer/spa/base.renderer.d.ts +39 -0
- package/dist/src/renderer/spa/base.renderer.js +149 -0
- package/dist/src/renderer/spa/base.renderer.js.map +1 -0
- package/dist/src/renderer/spa/hash.renderer.d.ts +78 -0
- package/dist/src/renderer/spa/hash.renderer.js +162 -0
- package/dist/src/renderer/spa/hash.renderer.js.map +1 -0
- package/dist/src/renderer/spa/html.renderer.d.ts +81 -0
- package/dist/src/renderer/spa/html.renderer.js +304 -0
- package/dist/src/renderer/spa/html.renderer.js.map +1 -0
- package/dist/src/renderer/spa/mod.d.ts +30 -0
- package/dist/src/renderer/spa/mod.js +35 -0
- package/dist/src/renderer/spa/mod.js.map +1 -0
- package/dist/src/renderer/ssr/html.renderer.d.ts +49 -0
- package/dist/src/renderer/ssr/html.renderer.js +108 -0
- package/dist/src/renderer/ssr/html.renderer.js.map +1 -0
- package/dist/src/renderer/ssr/md.renderer.d.ts +40 -0
- package/dist/src/renderer/ssr/md.renderer.js +100 -0
- package/dist/src/renderer/ssr/md.renderer.js.map +1 -0
- package/dist/src/renderer/ssr/ssr.renderer.d.ts +74 -0
- package/dist/src/renderer/ssr/ssr.renderer.js +185 -0
- package/dist/src/renderer/ssr/ssr.renderer.js.map +1 -0
- package/dist/src/route/route.core.d.ts +129 -0
- package/dist/src/route/route.core.js +255 -0
- package/dist/src/route/route.core.js.map +1 -0
- package/dist/src/route/route.matcher.d.ts +86 -0
- package/dist/src/route/route.matcher.js +214 -0
- package/dist/src/route/route.matcher.js.map +1 -0
- package/dist/src/type/logger.type.d.ts +17 -0
- package/dist/src/type/logger.type.js +9 -0
- package/dist/src/type/logger.type.js.map +1 -0
- package/dist/src/type/markdown.type.d.ts +20 -0
- package/dist/src/type/markdown.type.js +2 -0
- package/dist/src/type/markdown.type.js.map +1 -0
- package/dist/src/type/route.type.d.ts +112 -0
- package/dist/src/type/route.type.js +8 -0
- package/dist/src/type/route.type.js.map +1 -0
- package/dist/src/type/widget.type.d.ts +55 -0
- package/dist/src/type/widget.type.js +10 -0
- package/dist/src/type/widget.type.js.map +1 -0
- package/dist/src/util/html.util.d.ts +29 -0
- package/dist/src/util/html.util.js +158 -0
- package/dist/src/util/html.util.js.map +1 -0
- package/dist/src/util/logger.util.d.ts +26 -0
- package/dist/src/util/logger.util.js +80 -0
- package/dist/src/util/logger.util.js.map +1 -0
- package/dist/src/util/widget-resolve.util.d.ts +52 -0
- package/dist/src/util/widget-resolve.util.js +149 -0
- package/dist/src/util/widget-resolve.util.js.map +1 -0
- package/dist/src/widget/breadcrumb.widget.d.ts +48 -0
- package/dist/src/widget/breadcrumb.widget.js +72 -0
- package/dist/src/widget/breadcrumb.widget.js.map +1 -0
- package/dist/src/widget/page-title.widget.d.ts +33 -0
- package/dist/src/widget/page-title.widget.js +33 -0
- package/dist/src/widget/page-title.widget.js.map +1 -0
- package/dist/src/widget/widget.parser.d.ts +26 -0
- package/dist/src/widget/widget.parser.js +76 -0
- package/dist/src/widget/widget.parser.js.map +1 -0
- package/dist/src/widget/widget.registry.d.ts +23 -0
- package/dist/src/widget/widget.registry.js +42 -0
- package/dist/src/widget/widget.registry.js.map +1 -0
- package/package.json +63 -13
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Route Core
|
|
3
|
+
*
|
|
4
|
+
* Shared routing logic used by all renderers:
|
|
5
|
+
* - Route matching and hierarchy building
|
|
6
|
+
* - Module loading and caching
|
|
7
|
+
* - Event emission
|
|
8
|
+
* - URL normalization
|
|
9
|
+
*/
|
|
10
|
+
import type { MatchedRoute, RouteConfig, RouteInfo, RouteParams, RouterEvent, RouterEventListener, RoutesManifest } from '../type/route.type.ts';
|
|
11
|
+
import type { ComponentContext, ContextProvider } from '../component/abstract.component.ts';
|
|
12
|
+
import { RouteMatcher } from './route.matcher.ts';
|
|
13
|
+
/** Base paths for the two SSR rendering endpoints. */
|
|
14
|
+
export interface BasePath {
|
|
15
|
+
/** Base path for SSR HTML rendering (default: '/html') */
|
|
16
|
+
html: string;
|
|
17
|
+
/** Base path for SSR Markdown rendering (default: '/md') */
|
|
18
|
+
md: string;
|
|
19
|
+
}
|
|
20
|
+
/** Default base paths — backward compatible with existing /html/ and /md/ prefixes. */
|
|
21
|
+
export declare const DEFAULT_BASE_PATH: BasePath;
|
|
22
|
+
/**
|
|
23
|
+
* Create a copy of a manifest with basePath prepended to all patterns.
|
|
24
|
+
* Used by the server to prefix bare in-memory manifests before passing to routers.
|
|
25
|
+
*/
|
|
26
|
+
export declare function prefixManifest(manifest: RoutesManifest, basePath: string): RoutesManifest;
|
|
27
|
+
/** Throw if a redirect URL uses a dangerous protocol. */
|
|
28
|
+
export declare function assertSafeRedirect(url: string): void;
|
|
29
|
+
/** Default root route - renders a slot for child routes */
|
|
30
|
+
export declare const DEFAULT_ROOT_ROUTE: RouteConfig;
|
|
31
|
+
/** Options for RouteCore */
|
|
32
|
+
export interface RouteCoreOptions {
|
|
33
|
+
/**
|
|
34
|
+
* Read a companion file (.html, .md, .css) by path — returns its text content.
|
|
35
|
+
* SSR: `(path) => runtime.query(path, { as: 'text' })`.
|
|
36
|
+
* SPA default: `fetch(path, { headers: { Accept: 'text/plain' } }).then(r => r.text())`.
|
|
37
|
+
*/
|
|
38
|
+
fileReader?: (path: string) => Promise<string>;
|
|
39
|
+
/** Enriches every ComponentContext with app-level services before it reaches components. */
|
|
40
|
+
extendContext?: ContextProvider;
|
|
41
|
+
/** Base path prepended to route patterns for URL matching (e.g. '/html'). No trailing slash. */
|
|
42
|
+
basePath?: string;
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Core router functionality shared across all rendering contexts.
|
|
46
|
+
*/
|
|
47
|
+
export declare class RouteCore {
|
|
48
|
+
readonly matcher: RouteMatcher;
|
|
49
|
+
/** Registered context provider (if any). Exposed so renderers can apply it to inline contexts. */
|
|
50
|
+
readonly contextProvider: ContextProvider | undefined;
|
|
51
|
+
/** Base path for URL matching (e.g. '/html'). Empty string when no basePath. */
|
|
52
|
+
readonly basePath: string;
|
|
53
|
+
/** The root pattern — basePath when set, '/' otherwise. */
|
|
54
|
+
get root(): string;
|
|
55
|
+
private listeners;
|
|
56
|
+
private moduleCache;
|
|
57
|
+
private widgetFileCache;
|
|
58
|
+
private moduleLoaders;
|
|
59
|
+
currentRoute: MatchedRoute | null;
|
|
60
|
+
private readFile;
|
|
61
|
+
constructor(manifest: RoutesManifest, options?: RouteCoreOptions);
|
|
62
|
+
/**
|
|
63
|
+
* Get current route parameters.
|
|
64
|
+
*/
|
|
65
|
+
getParams(): RouteParams;
|
|
66
|
+
/**
|
|
67
|
+
* Add event listener for router events.
|
|
68
|
+
*/
|
|
69
|
+
addEventListener(listener: RouterEventListener): () => void;
|
|
70
|
+
/**
|
|
71
|
+
* Emit router event to listeners.
|
|
72
|
+
*/
|
|
73
|
+
emit(event: RouterEvent): void;
|
|
74
|
+
/**
|
|
75
|
+
* Match a URL to a route.
|
|
76
|
+
* Falls back to the default root route for the basePath root (or '/' when no basePath).
|
|
77
|
+
*/
|
|
78
|
+
match(url: URL | string): MatchedRoute | undefined;
|
|
79
|
+
/**
|
|
80
|
+
* Build route hierarchy from a pattern.
|
|
81
|
+
*
|
|
82
|
+
* When basePath is set, the root is the basePath itself and only
|
|
83
|
+
* segments after it are split into ancestors.
|
|
84
|
+
*
|
|
85
|
+
* e.g., basePath='/html', pattern='/html/projects/:id/tasks'
|
|
86
|
+
* → ['/html', '/html/projects', '/html/projects/:id', '/html/projects/:id/tasks']
|
|
87
|
+
*
|
|
88
|
+
* Without basePath: '/projects/:id/tasks'
|
|
89
|
+
* → ['/', '/projects', '/projects/:id', '/projects/:id/tasks']
|
|
90
|
+
*/
|
|
91
|
+
buildRouteHierarchy(pattern: string): string[];
|
|
92
|
+
/**
|
|
93
|
+
* Normalize URL by removing trailing slashes (except bare '/').
|
|
94
|
+
*/
|
|
95
|
+
normalizeUrl(url: string): string;
|
|
96
|
+
/**
|
|
97
|
+
* Convert relative path to absolute path.
|
|
98
|
+
*/
|
|
99
|
+
toAbsolutePath(path: string): string;
|
|
100
|
+
/**
|
|
101
|
+
* Load a module with caching.
|
|
102
|
+
* Uses pre-bundled loaders when available, falls back to dynamic import.
|
|
103
|
+
*/
|
|
104
|
+
loadModule<T>(modulePath: string): Promise<T>;
|
|
105
|
+
/**
|
|
106
|
+
* Load widget file contents with caching.
|
|
107
|
+
* Returns an object with loaded file contents.
|
|
108
|
+
*/
|
|
109
|
+
loadWidgetFiles(widgetFiles: {
|
|
110
|
+
html?: string;
|
|
111
|
+
md?: string;
|
|
112
|
+
css?: string;
|
|
113
|
+
}): Promise<{
|
|
114
|
+
html?: string;
|
|
115
|
+
md?: string;
|
|
116
|
+
css?: string;
|
|
117
|
+
}>;
|
|
118
|
+
/**
|
|
119
|
+
* Build a RouteInfo from a matched route and the resolved URL pathname.
|
|
120
|
+
* Called once per navigation; the result is reused across the route hierarchy.
|
|
121
|
+
*/
|
|
122
|
+
toRouteInfo(matched: MatchedRoute, pathname: string): RouteInfo;
|
|
123
|
+
/**
|
|
124
|
+
* Build a ComponentContext by extending RouteInfo with loaded file contents.
|
|
125
|
+
* When a signal is provided it is forwarded to fetch() calls and included
|
|
126
|
+
* in the returned context so that getData() can observe cancellation.
|
|
127
|
+
*/
|
|
128
|
+
buildComponentContext(routeInfo: RouteInfo, route: RouteConfig, signal?: AbortSignal, isLeaf?: boolean): Promise<ComponentContext>;
|
|
129
|
+
}
|
|
@@ -0,0 +1,255 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Route Core
|
|
3
|
+
*
|
|
4
|
+
* Shared routing logic used by all renderers:
|
|
5
|
+
* - Route matching and hierarchy building
|
|
6
|
+
* - Module loading and caching
|
|
7
|
+
* - Event emission
|
|
8
|
+
* - URL normalization
|
|
9
|
+
*/
|
|
10
|
+
var __rewriteRelativeImportExtension = (this && this.__rewriteRelativeImportExtension) || function (path, preserveJsx) {
|
|
11
|
+
if (typeof path === "string" && /^\.\.?\//.test(path)) {
|
|
12
|
+
return path.replace(/\.(tsx)$|((?:\.d)?)((?:\.[^./]+?)?)\.([cm]?)ts$/i, function (m, tsx, d, ext, cm) {
|
|
13
|
+
return tsx ? preserveJsx ? ".jsx" : ".js" : d && (!ext || !cm) ? m : (d + ext + "." + cm.toLowerCase() + "js");
|
|
14
|
+
});
|
|
15
|
+
}
|
|
16
|
+
return path;
|
|
17
|
+
};
|
|
18
|
+
import { RouteMatcher, toUrl } from "./route.matcher.js";
|
|
19
|
+
/** Default base paths — backward compatible with existing /html/ and /md/ prefixes. */
|
|
20
|
+
export const DEFAULT_BASE_PATH = { html: '/html', md: '/md' };
|
|
21
|
+
/**
|
|
22
|
+
* Create a copy of a manifest with basePath prepended to all patterns.
|
|
23
|
+
* Used by the server to prefix bare in-memory manifests before passing to routers.
|
|
24
|
+
*/
|
|
25
|
+
export function prefixManifest(manifest, basePath) {
|
|
26
|
+
if (!basePath)
|
|
27
|
+
return manifest;
|
|
28
|
+
return {
|
|
29
|
+
routes: manifest.routes.map((r) => ({
|
|
30
|
+
...r,
|
|
31
|
+
// Root pattern '/' becomes basePath itself (e.g. '/html'), not '/html/'
|
|
32
|
+
pattern: r.pattern === '/' ? basePath : basePath + r.pattern,
|
|
33
|
+
parent: r.parent ? (r.parent === '/' ? basePath : basePath + r.parent) : undefined,
|
|
34
|
+
})),
|
|
35
|
+
errorBoundaries: manifest.errorBoundaries.map((e) => ({
|
|
36
|
+
...e,
|
|
37
|
+
pattern: e.pattern === '/' ? basePath : basePath + e.pattern,
|
|
38
|
+
})),
|
|
39
|
+
statusPages: new Map([...manifest.statusPages].map(([status, route]) => [
|
|
40
|
+
status,
|
|
41
|
+
{ ...route, pattern: basePath + route.pattern },
|
|
42
|
+
])),
|
|
43
|
+
errorHandler: manifest.errorHandler,
|
|
44
|
+
moduleLoaders: manifest.moduleLoaders,
|
|
45
|
+
};
|
|
46
|
+
}
|
|
47
|
+
const BLOCKED_PROTOCOLS = /^(javascript|data|vbscript):/i;
|
|
48
|
+
/** Throw if a redirect URL uses a dangerous protocol. */
|
|
49
|
+
export function assertSafeRedirect(url) {
|
|
50
|
+
if (BLOCKED_PROTOCOLS.test(url.trim())) {
|
|
51
|
+
throw new Error(`Unsafe redirect URL blocked: ${url}`);
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
/** Default root route - renders a slot for child routes */
|
|
55
|
+
export const DEFAULT_ROOT_ROUTE = {
|
|
56
|
+
pattern: '/',
|
|
57
|
+
type: 'page',
|
|
58
|
+
modulePath: '__default_root__',
|
|
59
|
+
};
|
|
60
|
+
/**
|
|
61
|
+
* Core router functionality shared across all rendering contexts.
|
|
62
|
+
*/
|
|
63
|
+
export class RouteCore {
|
|
64
|
+
matcher;
|
|
65
|
+
/** Registered context provider (if any). Exposed so renderers can apply it to inline contexts. */
|
|
66
|
+
contextProvider;
|
|
67
|
+
/** Base path for URL matching (e.g. '/html'). Empty string when no basePath. */
|
|
68
|
+
basePath;
|
|
69
|
+
/** The root pattern — basePath when set, '/' otherwise. */
|
|
70
|
+
get root() {
|
|
71
|
+
return this.basePath || '/';
|
|
72
|
+
}
|
|
73
|
+
listeners = new Set();
|
|
74
|
+
moduleCache = new Map();
|
|
75
|
+
widgetFileCache = new Map();
|
|
76
|
+
moduleLoaders;
|
|
77
|
+
currentRoute = null;
|
|
78
|
+
readFile;
|
|
79
|
+
constructor(manifest, options = {}) {
|
|
80
|
+
this.basePath = options.basePath ?? '';
|
|
81
|
+
this.matcher = new RouteMatcher(manifest);
|
|
82
|
+
this.readFile = options.fileReader ??
|
|
83
|
+
((path) => fetch(path, { headers: { Accept: 'text/plain' } }).then((r) => r.text()));
|
|
84
|
+
this.contextProvider = options.extendContext;
|
|
85
|
+
this.moduleLoaders = manifest.moduleLoaders ?? {};
|
|
86
|
+
}
|
|
87
|
+
/**
|
|
88
|
+
* Get current route parameters.
|
|
89
|
+
*/
|
|
90
|
+
getParams() {
|
|
91
|
+
return this.currentRoute?.params ?? {};
|
|
92
|
+
}
|
|
93
|
+
/**
|
|
94
|
+
* Add event listener for router events.
|
|
95
|
+
*/
|
|
96
|
+
addEventListener(listener) {
|
|
97
|
+
this.listeners.add(listener);
|
|
98
|
+
return () => this.listeners.delete(listener);
|
|
99
|
+
}
|
|
100
|
+
/**
|
|
101
|
+
* Emit router event to listeners.
|
|
102
|
+
*/
|
|
103
|
+
emit(event) {
|
|
104
|
+
for (const listener of this.listeners) {
|
|
105
|
+
try {
|
|
106
|
+
listener(event);
|
|
107
|
+
}
|
|
108
|
+
catch (e) {
|
|
109
|
+
console.error('[Router] Event listener error:', e);
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
/**
|
|
114
|
+
* Match a URL to a route.
|
|
115
|
+
* Falls back to the default root route for the basePath root (or '/' when no basePath).
|
|
116
|
+
*/
|
|
117
|
+
match(url) {
|
|
118
|
+
const matched = this.matcher.match(url);
|
|
119
|
+
if (matched)
|
|
120
|
+
return matched;
|
|
121
|
+
const urlObj = toUrl(url);
|
|
122
|
+
if (urlObj.pathname === this.root || urlObj.pathname === this.root + '/') {
|
|
123
|
+
return {
|
|
124
|
+
route: { ...DEFAULT_ROOT_ROUTE, pattern: this.root },
|
|
125
|
+
params: {},
|
|
126
|
+
searchParams: urlObj.searchParams,
|
|
127
|
+
};
|
|
128
|
+
}
|
|
129
|
+
return undefined;
|
|
130
|
+
}
|
|
131
|
+
/**
|
|
132
|
+
* Build route hierarchy from a pattern.
|
|
133
|
+
*
|
|
134
|
+
* When basePath is set, the root is the basePath itself and only
|
|
135
|
+
* segments after it are split into ancestors.
|
|
136
|
+
*
|
|
137
|
+
* e.g., basePath='/html', pattern='/html/projects/:id/tasks'
|
|
138
|
+
* → ['/html', '/html/projects', '/html/projects/:id', '/html/projects/:id/tasks']
|
|
139
|
+
*
|
|
140
|
+
* Without basePath: '/projects/:id/tasks'
|
|
141
|
+
* → ['/', '/projects', '/projects/:id', '/projects/:id/tasks']
|
|
142
|
+
*/
|
|
143
|
+
buildRouteHierarchy(pattern) {
|
|
144
|
+
if (pattern === this.root || pattern === this.root + '/') {
|
|
145
|
+
return [this.root];
|
|
146
|
+
}
|
|
147
|
+
// Extract the part after basePath
|
|
148
|
+
const tail = this.basePath ? pattern.slice(this.basePath.length) : pattern;
|
|
149
|
+
const segments = tail.split('/').filter(Boolean);
|
|
150
|
+
const hierarchy = [this.root];
|
|
151
|
+
let current = this.basePath || '';
|
|
152
|
+
for (const segment of segments) {
|
|
153
|
+
current += '/' + segment;
|
|
154
|
+
hierarchy.push(current);
|
|
155
|
+
}
|
|
156
|
+
return hierarchy;
|
|
157
|
+
}
|
|
158
|
+
/**
|
|
159
|
+
* Normalize URL by removing trailing slashes (except bare '/').
|
|
160
|
+
*/
|
|
161
|
+
normalizeUrl(url) {
|
|
162
|
+
if (url.length > 1 && url.endsWith('/')) {
|
|
163
|
+
return url.slice(0, -1);
|
|
164
|
+
}
|
|
165
|
+
return url;
|
|
166
|
+
}
|
|
167
|
+
/**
|
|
168
|
+
* Convert relative path to absolute path.
|
|
169
|
+
*/
|
|
170
|
+
toAbsolutePath(path) {
|
|
171
|
+
return path.startsWith('/') ? path : '/' + path;
|
|
172
|
+
}
|
|
173
|
+
/**
|
|
174
|
+
* Load a module with caching.
|
|
175
|
+
* Uses pre-bundled loaders when available, falls back to dynamic import.
|
|
176
|
+
*/
|
|
177
|
+
async loadModule(modulePath) {
|
|
178
|
+
if (this.moduleCache.has(modulePath)) {
|
|
179
|
+
return this.moduleCache.get(modulePath);
|
|
180
|
+
}
|
|
181
|
+
let module;
|
|
182
|
+
const loader = this.moduleLoaders[modulePath];
|
|
183
|
+
if (loader) {
|
|
184
|
+
module = await loader();
|
|
185
|
+
}
|
|
186
|
+
else {
|
|
187
|
+
const absolutePath = this.toAbsolutePath(modulePath);
|
|
188
|
+
module = await import(__rewriteRelativeImportExtension(absolutePath));
|
|
189
|
+
}
|
|
190
|
+
this.moduleCache.set(modulePath, module);
|
|
191
|
+
return module;
|
|
192
|
+
}
|
|
193
|
+
/**
|
|
194
|
+
* Load widget file contents with caching.
|
|
195
|
+
* Returns an object with loaded file contents.
|
|
196
|
+
*/
|
|
197
|
+
async loadWidgetFiles(widgetFiles) {
|
|
198
|
+
const load = async (path) => {
|
|
199
|
+
const absPath = this.toAbsolutePath(path);
|
|
200
|
+
const cached = this.widgetFileCache.get(absPath);
|
|
201
|
+
if (cached !== undefined)
|
|
202
|
+
return cached;
|
|
203
|
+
try {
|
|
204
|
+
const content = await this.readFile(absPath);
|
|
205
|
+
this.widgetFileCache.set(absPath, content);
|
|
206
|
+
return content;
|
|
207
|
+
}
|
|
208
|
+
catch (e) {
|
|
209
|
+
console.warn(`[RouteCore] Failed to load widget file ${path}:`, e instanceof Error ? e.message : e);
|
|
210
|
+
return undefined;
|
|
211
|
+
}
|
|
212
|
+
};
|
|
213
|
+
const [html, md, css] = await Promise.all([
|
|
214
|
+
widgetFiles.html ? load(widgetFiles.html) : undefined,
|
|
215
|
+
widgetFiles.md ? load(widgetFiles.md) : undefined,
|
|
216
|
+
widgetFiles.css ? load(widgetFiles.css) : undefined,
|
|
217
|
+
]);
|
|
218
|
+
return { html, md, css };
|
|
219
|
+
}
|
|
220
|
+
/**
|
|
221
|
+
* Build a RouteInfo from a matched route and the resolved URL pathname.
|
|
222
|
+
* Called once per navigation; the result is reused across the route hierarchy.
|
|
223
|
+
*/
|
|
224
|
+
toRouteInfo(matched, pathname) {
|
|
225
|
+
return {
|
|
226
|
+
pathname,
|
|
227
|
+
pattern: matched.route.pattern,
|
|
228
|
+
params: matched.params,
|
|
229
|
+
searchParams: matched.searchParams ?? new URLSearchParams(),
|
|
230
|
+
};
|
|
231
|
+
}
|
|
232
|
+
/**
|
|
233
|
+
* Build a ComponentContext by extending RouteInfo with loaded file contents.
|
|
234
|
+
* When a signal is provided it is forwarded to fetch() calls and included
|
|
235
|
+
* in the returned context so that getData() can observe cancellation.
|
|
236
|
+
*/
|
|
237
|
+
async buildComponentContext(routeInfo, route, signal, isLeaf) {
|
|
238
|
+
const fetchFile = (filePath) => this.readFile(this.toAbsolutePath(filePath));
|
|
239
|
+
const rf = route.files;
|
|
240
|
+
const [html, md, css] = await Promise.all([
|
|
241
|
+
rf?.html ? fetchFile(rf.html) : undefined,
|
|
242
|
+
rf?.md ? fetchFile(rf.md) : undefined,
|
|
243
|
+
rf?.css ? fetchFile(rf.css) : undefined,
|
|
244
|
+
]);
|
|
245
|
+
const base = {
|
|
246
|
+
...routeInfo,
|
|
247
|
+
files: { html, md, css },
|
|
248
|
+
signal,
|
|
249
|
+
isLeaf,
|
|
250
|
+
basePath: this.basePath || undefined,
|
|
251
|
+
};
|
|
252
|
+
return this.contextProvider ? this.contextProvider(base) : base;
|
|
253
|
+
}
|
|
254
|
+
}
|
|
255
|
+
//# sourceMappingURL=route.core.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"route.core.js","sourceRoot":"","sources":["../../../src/route/route.core.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Route Matcher
|
|
3
|
+
*
|
|
4
|
+
* URLPattern-based route matching with support for:
|
|
5
|
+
* - Static routes (/about)
|
|
6
|
+
* - Dynamic segments (/projects/:id)
|
|
7
|
+
* - Wildcard/catch-all (future)
|
|
8
|
+
*
|
|
9
|
+
* Uses native URLPattern API (supported in all major browsers).
|
|
10
|
+
*/
|
|
11
|
+
/** Parse a URL path string into a URL object. Passes through URL objects unchanged. */
|
|
12
|
+
export declare function toUrl(url: string | URL): URL;
|
|
13
|
+
import type { ErrorBoundary, MatchedRoute, RouteConfig, RoutesManifest } from '../type/route.type.ts';
|
|
14
|
+
/**
|
|
15
|
+
* Route matcher using native URLPattern API.
|
|
16
|
+
*
|
|
17
|
+
* Routes are matched in order of specificity:
|
|
18
|
+
* 1. Exact static matches first
|
|
19
|
+
* 2. Dynamic segment matches
|
|
20
|
+
* 3. More specific patterns before less specific
|
|
21
|
+
*/
|
|
22
|
+
export declare class RouteMatcher {
|
|
23
|
+
private compiledRoutes;
|
|
24
|
+
private errorBoundaries;
|
|
25
|
+
private statusPages;
|
|
26
|
+
private errorHandler?;
|
|
27
|
+
/**
|
|
28
|
+
* Initialize matcher with routes manifest.
|
|
29
|
+
* Routes should be pre-sorted by specificity in the manifest.
|
|
30
|
+
*/
|
|
31
|
+
constructor(manifest: RoutesManifest);
|
|
32
|
+
/**
|
|
33
|
+
* Match a URL against registered routes.
|
|
34
|
+
* Returns the first matching route or undefined.
|
|
35
|
+
*/
|
|
36
|
+
match(url: URL | string): MatchedRoute | undefined;
|
|
37
|
+
/**
|
|
38
|
+
* Find error boundary for a given pathname.
|
|
39
|
+
* Searches from most specific to least specific.
|
|
40
|
+
*/
|
|
41
|
+
findErrorBoundary(pathname: string): ErrorBoundary | undefined;
|
|
42
|
+
/**
|
|
43
|
+
* Get status-specific page (404, 401, 403).
|
|
44
|
+
*/
|
|
45
|
+
getStatusPage(status: number): RouteConfig | undefined;
|
|
46
|
+
/**
|
|
47
|
+
* Get generic error handler.
|
|
48
|
+
*/
|
|
49
|
+
getErrorHandler(): RouteConfig | undefined;
|
|
50
|
+
/**
|
|
51
|
+
* Find a route by its exact pattern or by matching a pathname.
|
|
52
|
+
* Used for building route hierarchy.
|
|
53
|
+
*/
|
|
54
|
+
findRoute(patternOrPath: string): RouteConfig | undefined;
|
|
55
|
+
/**
|
|
56
|
+
* Extract params from URLPatternResult.
|
|
57
|
+
*/
|
|
58
|
+
private extractParams;
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* Convert file-based route path to URLPattern.
|
|
62
|
+
*
|
|
63
|
+
* Examples:
|
|
64
|
+
* - index.page.ts → /
|
|
65
|
+
* - about.page.ts → /about
|
|
66
|
+
* - projects/index.page.ts → /projects/:rest*
|
|
67
|
+
* - projects/[id].page.ts → /projects/:id
|
|
68
|
+
* - projects/[id]/tasks.page.ts → /projects/:id/tasks
|
|
69
|
+
*
|
|
70
|
+
* Directory index files (non-root) become wildcard catch-all routes.
|
|
71
|
+
* See ADR-0002: Wildcard Routes via Directory Index Convention.
|
|
72
|
+
*/
|
|
73
|
+
export declare function filePathToPattern(filePath: string): string;
|
|
74
|
+
/**
|
|
75
|
+
* Determine route type from filename.
|
|
76
|
+
*/
|
|
77
|
+
export declare function getRouteType(filename: string): 'page' | 'error' | 'redirect' | null;
|
|
78
|
+
/**
|
|
79
|
+
* Get the file extension type from a page filename.
|
|
80
|
+
*/
|
|
81
|
+
export declare function getPageFileType(filename: string): 'ts' | 'html' | 'md' | 'css' | null;
|
|
82
|
+
/**
|
|
83
|
+
* Sort routes by specificity.
|
|
84
|
+
* Non-wildcards before wildcards, static before dynamic, longer paths first.
|
|
85
|
+
*/
|
|
86
|
+
export declare function sortRoutesBySpecificity(routes: RouteConfig[]): RouteConfig[];
|