@emkodev/emroute 1.6.6-beta.2 → 1.6.6-beta.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/dist/emroute.js +2757 -0
- package/dist/emroute.js.map +7 -0
- package/dist/runtime/abstract.runtime.d.ts +0 -28
- package/dist/runtime/abstract.runtime.js +10 -58
- package/dist/runtime/abstract.runtime.js.map +1 -1
- package/dist/runtime/bun/esbuild-runtime-loader.plugin.js +3 -0
- package/dist/runtime/bun/esbuild-runtime-loader.plugin.js.map +1 -1
- package/dist/runtime/bun/fs/bun-fs.runtime.d.ts +0 -5
- package/dist/runtime/bun/fs/bun-fs.runtime.js +1 -95
- package/dist/runtime/bun/fs/bun-fs.runtime.js.map +1 -1
- package/dist/runtime/bun/sqlite/bun-sqlite.runtime.d.ts +0 -5
- package/dist/runtime/bun/sqlite/bun-sqlite.runtime.js +2 -96
- package/dist/runtime/bun/sqlite/bun-sqlite.runtime.js.map +1 -1
- package/dist/runtime/fetch.runtime.d.ts +26 -0
- package/dist/runtime/fetch.runtime.js +55 -0
- package/dist/runtime/fetch.runtime.js.map +1 -0
- package/dist/runtime/sitemap.generator.d.ts +4 -4
- package/dist/runtime/sitemap.generator.js +32 -11
- package/dist/runtime/sitemap.generator.js.map +1 -1
- package/dist/runtime/universal/fs/universal-fs.runtime.d.ts +0 -5
- package/dist/runtime/universal/fs/universal-fs.runtime.js +1 -95
- package/dist/runtime/universal/fs/universal-fs.runtime.js.map +1 -1
- package/dist/server/build.util.d.ts +38 -0
- package/dist/server/build.util.js +133 -0
- package/dist/server/build.util.js.map +1 -0
- package/dist/server/codegen.util.d.ts +3 -0
- package/dist/server/codegen.util.js +28 -10
- package/dist/server/codegen.util.js.map +1 -1
- package/dist/server/emroute.server.js +53 -29
- package/dist/server/emroute.server.js.map +1 -1
- package/dist/server/esbuild-manifest.plugin.js +6 -4
- package/dist/server/esbuild-manifest.plugin.js.map +1 -1
- package/dist/server/server-api.type.d.ts +6 -0
- package/dist/src/component/abstract.component.d.ts +5 -3
- package/dist/src/component/abstract.component.js.map +1 -1
- package/dist/src/element/component.element.js +5 -4
- package/dist/src/element/component.element.js.map +1 -1
- package/dist/src/renderer/spa/mod.d.ts +2 -3
- package/dist/src/renderer/spa/mod.js +2 -3
- package/dist/src/renderer/spa/mod.js.map +1 -1
- package/dist/src/renderer/spa/thin-client.d.ts +34 -0
- package/dist/src/renderer/spa/thin-client.js +138 -0
- package/dist/src/renderer/spa/thin-client.js.map +1 -0
- package/dist/src/renderer/ssr/html.renderer.d.ts +3 -3
- package/dist/src/renderer/ssr/html.renderer.js +6 -6
- package/dist/src/renderer/ssr/html.renderer.js.map +1 -1
- package/dist/src/renderer/ssr/md.renderer.d.ts +3 -3
- package/dist/src/renderer/ssr/md.renderer.js +12 -7
- package/dist/src/renderer/ssr/md.renderer.js.map +1 -1
- package/dist/src/renderer/ssr/ssr.renderer.d.ts +7 -6
- package/dist/src/renderer/ssr/ssr.renderer.js +42 -44
- package/dist/src/renderer/ssr/ssr.renderer.js.map +1 -1
- package/dist/src/route/route.core.d.ts +16 -6
- package/dist/src/route/route.core.js +44 -23
- package/dist/src/route/route.core.js.map +1 -1
- package/dist/src/type/route-tree.type.d.ts +2 -0
- package/dist/src/type/route.type.d.ts +6 -24
- package/dist/src/util/md.util.d.ts +8 -0
- package/dist/src/util/md.util.js +28 -0
- package/dist/src/util/md.util.js.map +1 -0
- package/dist/src/util/widget-resolve.util.js +6 -1
- package/dist/src/util/widget-resolve.util.js.map +1 -1
- package/dist/src/widget/breadcrumb.widget.d.ts +0 -1
- package/dist/src/widget/breadcrumb.widget.js +4 -15
- package/dist/src/widget/breadcrumb.widget.js.map +1 -1
- package/package.json +13 -2
- package/runtime/abstract.runtime.ts +9 -82
- package/runtime/bun/esbuild-runtime-loader.plugin.ts +2 -0
- package/runtime/bun/fs/bun-fs.runtime.ts +0 -109
- package/runtime/bun/sqlite/bun-sqlite.runtime.ts +1 -112
- package/runtime/fetch.runtime.ts +70 -0
- package/runtime/sitemap.generator.ts +37 -12
- package/runtime/universal/fs/universal-fs.runtime.ts +0 -109
- package/server/build.util.ts +168 -0
- package/server/codegen.util.ts +29 -11
- package/server/emroute.server.ts +50 -30
- package/server/esbuild-manifest.plugin.ts +5 -3
- package/server/server-api.type.ts +7 -0
- package/src/component/abstract.component.ts +5 -3
- package/src/element/component.element.ts +5 -4
- package/src/renderer/spa/mod.ts +2 -8
- package/src/renderer/spa/thin-client.ts +165 -0
- package/src/renderer/ssr/html.renderer.ts +6 -5
- package/src/renderer/ssr/md.renderer.ts +12 -6
- package/src/renderer/ssr/ssr.renderer.ts +54 -48
- package/src/route/route.core.ts +49 -28
- package/src/type/route-tree.type.ts +2 -0
- package/src/type/route.type.ts +7 -32
- package/src/util/md.util.ts +31 -0
- package/src/util/widget-resolve.util.ts +6 -1
- package/src/widget/breadcrumb.widget.ts +4 -16
- package/server/scanner.util.ts +0 -243
- package/src/renderer/spa/base.renderer.ts +0 -186
- package/src/renderer/spa/hash.renderer.ts +0 -238
- package/src/renderer/spa/html.renderer.ts +0 -399
- package/src/route/route.matcher.ts +0 -260
- package/src/web-doc/index.md +0 -15
|
@@ -1,260 +0,0 @@
|
|
|
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
|
-
|
|
12
|
-
/** Parse a URL path string into a URL object. Passes through URL objects unchanged. */
|
|
13
|
-
export function toUrl(url: string | URL): URL {
|
|
14
|
-
return typeof url === 'string' ? new URL(url, 'http://url-parse') : url;
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
import type {
|
|
18
|
-
ErrorBoundary,
|
|
19
|
-
MatchedRoute,
|
|
20
|
-
RouteConfig,
|
|
21
|
-
RouteParams,
|
|
22
|
-
RoutesManifest,
|
|
23
|
-
} from '../type/route.type.ts';
|
|
24
|
-
|
|
25
|
-
/** Compiled route with URLPattern instance */
|
|
26
|
-
interface CompiledRoute {
|
|
27
|
-
route: RouteConfig;
|
|
28
|
-
pattern: URLPattern;
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
/**
|
|
32
|
-
* Route matcher using native URLPattern API.
|
|
33
|
-
*
|
|
34
|
-
* Routes are matched in order of specificity:
|
|
35
|
-
* 1. Exact static matches first
|
|
36
|
-
* 2. Dynamic segment matches
|
|
37
|
-
* 3. More specific patterns before less specific
|
|
38
|
-
*/
|
|
39
|
-
export class RouteMatcher {
|
|
40
|
-
private compiledRoutes: CompiledRoute[] = [];
|
|
41
|
-
private errorBoundaries: ErrorBoundary[] = [];
|
|
42
|
-
private statusPages = new Map<number, RouteConfig>();
|
|
43
|
-
private errorHandler?: RouteConfig;
|
|
44
|
-
|
|
45
|
-
/**
|
|
46
|
-
* Initialize matcher with routes manifest.
|
|
47
|
-
* Routes should be pre-sorted by specificity in the manifest.
|
|
48
|
-
*/
|
|
49
|
-
constructor(manifest: RoutesManifest) {
|
|
50
|
-
this.errorBoundaries = manifest.errorBoundaries.toSorted(
|
|
51
|
-
(a, b) => b.pattern.length - a.pattern.length,
|
|
52
|
-
);
|
|
53
|
-
this.statusPages = manifest.statusPages;
|
|
54
|
-
this.errorHandler = manifest.errorHandler;
|
|
55
|
-
|
|
56
|
-
// Compile URLPatterns for all routes
|
|
57
|
-
for (const route of manifest.routes) {
|
|
58
|
-
try {
|
|
59
|
-
const pattern = new URLPattern({ pathname: route.pattern });
|
|
60
|
-
this.compiledRoutes.push({ route, pattern });
|
|
61
|
-
} catch (e) {
|
|
62
|
-
console.error(`[Router] Invalid pattern: ${route.pattern}`, e);
|
|
63
|
-
}
|
|
64
|
-
}
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
/**
|
|
68
|
-
* Match a URL against registered routes.
|
|
69
|
-
* Returns the first matching route or undefined.
|
|
70
|
-
*/
|
|
71
|
-
match(url: URL | string): MatchedRoute | undefined {
|
|
72
|
-
const urlObj = toUrl(url);
|
|
73
|
-
|
|
74
|
-
const searchParams = urlObj.searchParams;
|
|
75
|
-
|
|
76
|
-
for (const { route, pattern } of this.compiledRoutes) {
|
|
77
|
-
const result = pattern.exec(urlObj);
|
|
78
|
-
if (result) {
|
|
79
|
-
return {
|
|
80
|
-
route,
|
|
81
|
-
params: this.extractParams(result),
|
|
82
|
-
searchParams,
|
|
83
|
-
patternResult: result,
|
|
84
|
-
};
|
|
85
|
-
}
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
return undefined;
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
/**
|
|
92
|
-
* Find error boundary for a given pathname.
|
|
93
|
-
* Searches from most specific to least specific.
|
|
94
|
-
*/
|
|
95
|
-
findErrorBoundary(pathname: string): ErrorBoundary | undefined {
|
|
96
|
-
for (const boundary of this.errorBoundaries) {
|
|
97
|
-
const prefix = boundary.pattern.endsWith('/') ? boundary.pattern : boundary.pattern + '/';
|
|
98
|
-
if (pathname === boundary.pattern || pathname.startsWith(prefix)) {
|
|
99
|
-
return boundary;
|
|
100
|
-
}
|
|
101
|
-
}
|
|
102
|
-
|
|
103
|
-
return undefined;
|
|
104
|
-
}
|
|
105
|
-
|
|
106
|
-
/**
|
|
107
|
-
* Get status-specific page (404, 401, 403).
|
|
108
|
-
*/
|
|
109
|
-
getStatusPage(status: number): RouteConfig | undefined {
|
|
110
|
-
return this.statusPages.get(status);
|
|
111
|
-
}
|
|
112
|
-
|
|
113
|
-
/**
|
|
114
|
-
* Get generic error handler.
|
|
115
|
-
*/
|
|
116
|
-
getErrorHandler(): RouteConfig | undefined {
|
|
117
|
-
return this.errorHandler;
|
|
118
|
-
}
|
|
119
|
-
|
|
120
|
-
/**
|
|
121
|
-
* Find a route by its exact pattern or by matching a pathname.
|
|
122
|
-
* Used for building route hierarchy.
|
|
123
|
-
*/
|
|
124
|
-
findRoute(patternOrPath: string): RouteConfig | undefined {
|
|
125
|
-
// First try exact pattern match
|
|
126
|
-
for (const { route } of this.compiledRoutes) {
|
|
127
|
-
if (route.pattern === patternOrPath) {
|
|
128
|
-
return route;
|
|
129
|
-
}
|
|
130
|
-
}
|
|
131
|
-
|
|
132
|
-
// Then try to match as a URL path
|
|
133
|
-
const matched = this.match(toUrl(patternOrPath));
|
|
134
|
-
return matched?.route;
|
|
135
|
-
}
|
|
136
|
-
|
|
137
|
-
/**
|
|
138
|
-
* Extract params from URLPatternResult.
|
|
139
|
-
*/
|
|
140
|
-
private extractParams(result: URLPatternResult): RouteParams {
|
|
141
|
-
const groups = result.pathname.groups;
|
|
142
|
-
const params: Record<string, string> = {};
|
|
143
|
-
for (const [key, value] of Object.entries(groups)) {
|
|
144
|
-
if (value !== undefined) {
|
|
145
|
-
params[key] = value;
|
|
146
|
-
}
|
|
147
|
-
}
|
|
148
|
-
return params;
|
|
149
|
-
}
|
|
150
|
-
}
|
|
151
|
-
|
|
152
|
-
/**
|
|
153
|
-
* Convert file-based route path to URLPattern.
|
|
154
|
-
*
|
|
155
|
-
* Examples:
|
|
156
|
-
* - index.page.ts → /
|
|
157
|
-
* - about.page.ts → /about
|
|
158
|
-
* - projects/index.page.ts → /projects/:rest*
|
|
159
|
-
* - projects/[id].page.ts → /projects/:id
|
|
160
|
-
* - projects/[id]/tasks.page.ts → /projects/:id/tasks
|
|
161
|
-
*
|
|
162
|
-
* Directory index files (non-root) become wildcard catch-all routes.
|
|
163
|
-
* See ADR-0002: Wildcard Routes via Directory Index Convention.
|
|
164
|
-
*/
|
|
165
|
-
export function filePathToPattern(filePath: string): string {
|
|
166
|
-
// Remove routes/ prefix and file extension
|
|
167
|
-
let pattern = filePath
|
|
168
|
-
.replace(/^routes\//, '')
|
|
169
|
-
.replace(/\.(page|error|redirect)\.(ts|html|md|css)$/, '');
|
|
170
|
-
|
|
171
|
-
// Detect non-root directory index before stripping
|
|
172
|
-
const isDirectoryIndex = pattern.endsWith('/index') && pattern !== 'index';
|
|
173
|
-
|
|
174
|
-
// Handle index files
|
|
175
|
-
pattern = pattern.replace(/\/index$/, '').replace(/^index$/, '');
|
|
176
|
-
|
|
177
|
-
// Convert [param] to :param
|
|
178
|
-
pattern = pattern.replace(/\[(?<param>[^\]]+)\]/g, ':$<param>');
|
|
179
|
-
|
|
180
|
-
// Ensure leading slash
|
|
181
|
-
pattern = '/' + pattern;
|
|
182
|
-
|
|
183
|
-
// Non-root directory index becomes wildcard catch-all
|
|
184
|
-
if (isDirectoryIndex) {
|
|
185
|
-
pattern += '/:rest*';
|
|
186
|
-
}
|
|
187
|
-
|
|
188
|
-
return pattern;
|
|
189
|
-
}
|
|
190
|
-
|
|
191
|
-
/**
|
|
192
|
-
* Determine route type from filename.
|
|
193
|
-
*/
|
|
194
|
-
export function getRouteType(
|
|
195
|
-
filename: string,
|
|
196
|
-
): 'page' | 'error' | 'redirect' | null {
|
|
197
|
-
if (
|
|
198
|
-
filename.endsWith('.page.ts') ||
|
|
199
|
-
filename.endsWith('.page.html') ||
|
|
200
|
-
filename.endsWith('.page.md')
|
|
201
|
-
) {
|
|
202
|
-
return 'page';
|
|
203
|
-
}
|
|
204
|
-
if (filename.endsWith('.error.ts')) {
|
|
205
|
-
return 'error';
|
|
206
|
-
}
|
|
207
|
-
if (filename.endsWith('.redirect.ts')) {
|
|
208
|
-
return 'redirect';
|
|
209
|
-
}
|
|
210
|
-
return null;
|
|
211
|
-
}
|
|
212
|
-
|
|
213
|
-
/**
|
|
214
|
-
* Get the file extension type from a page filename.
|
|
215
|
-
*/
|
|
216
|
-
export function getPageFileType(
|
|
217
|
-
filename: string,
|
|
218
|
-
): 'ts' | 'html' | 'md' | 'css' | null {
|
|
219
|
-
if (filename.endsWith('.page.ts')) return 'ts';
|
|
220
|
-
if (filename.endsWith('.page.html')) return 'html';
|
|
221
|
-
if (filename.endsWith('.page.md')) return 'md';
|
|
222
|
-
if (filename.endsWith('.page.css')) return 'css';
|
|
223
|
-
return null;
|
|
224
|
-
}
|
|
225
|
-
|
|
226
|
-
/**
|
|
227
|
-
* Sort routes by specificity.
|
|
228
|
-
* Non-wildcards before wildcards, static before dynamic, longer paths first.
|
|
229
|
-
*/
|
|
230
|
-
export function sortRoutesBySpecificity(routes: RouteConfig[]): RouteConfig[] {
|
|
231
|
-
return routes.toSorted((a, b) => {
|
|
232
|
-
const aSegments = a.pattern.split('/').filter(Boolean);
|
|
233
|
-
const bSegments = b.pattern.split('/').filter(Boolean);
|
|
234
|
-
|
|
235
|
-
// Wildcards always sort last
|
|
236
|
-
const aIsWildcard = aSegments.some((s) => s.endsWith('*') || s.endsWith('+'));
|
|
237
|
-
const bIsWildcard = bSegments.some((s) => s.endsWith('*') || s.endsWith('+'));
|
|
238
|
-
if (aIsWildcard !== bIsWildcard) {
|
|
239
|
-
return aIsWildcard ? 1 : -1;
|
|
240
|
-
}
|
|
241
|
-
|
|
242
|
-
// More segments = more specific
|
|
243
|
-
if (aSegments.length !== bSegments.length) {
|
|
244
|
-
return bSegments.length - aSegments.length;
|
|
245
|
-
}
|
|
246
|
-
|
|
247
|
-
// Compare segment by segment
|
|
248
|
-
for (let i = 0; i < aSegments.length; i++) {
|
|
249
|
-
const aIsDynamic = aSegments[i].startsWith(':');
|
|
250
|
-
const bIsDynamic = bSegments[i].startsWith(':');
|
|
251
|
-
|
|
252
|
-
// Static segments are more specific than dynamic
|
|
253
|
-
if (aIsDynamic !== bIsDynamic) {
|
|
254
|
-
return aIsDynamic ? 1 : -1;
|
|
255
|
-
}
|
|
256
|
-
}
|
|
257
|
-
|
|
258
|
-
return 0;
|
|
259
|
-
});
|
|
260
|
-
}
|
package/src/web-doc/index.md
DELETED
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
https://developer.mozilla.org/en-US/docs/Web/API/ShadowRoot/setHTMLUnsafe
|
|
2
|
-
|
|
3
|
-
https://developer.mozilla.org/en-US/docs/Web/API/ShadowRoot
|
|
4
|
-
|
|
5
|
-
https://developer.mozilla.org/en-US/docs/Web/API/SanitizerConfig
|
|
6
|
-
|
|
7
|
-
https://developer.mozilla.org/en-US/docs/Web/API/Invoker_Commands_API - MUST SEE! We might rework popover service completely.
|
|
8
|
-
|
|
9
|
-
https://developer.mozilla.org/en-US/docs/Web/HTML/Reference/Elements/template - must see. Must use. Especially for listst (/article fixture route).
|
|
10
|
-
|
|
11
|
-
https://developer.mozilla.org/en-US/docs/Web/API/Navigation_API - appears to be the newer solution over history api.
|
|
12
|
-
|
|
13
|
-
https://developer.mozilla.org/en-US/docs/Web/API/Houdini_APIs - probably very useful.
|
|
14
|
-
|
|
15
|
-
https://developer.mozilla.org/en-US/docs/Web/API/Prioritized_Task_Scheduling_API - might be beneficial to manage loading widgets/pages in spa mode.
|