@emkodev/emroute 1.8.0 → 1.8.2-beta.2
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 +1 -1
- package/core/renderer/html.renderer.ts +1 -1
- package/core/renderer/md.renderer.ts +1 -1
- package/core/renderer/ssr.renderer.ts +21 -1
- package/core/server/emroute.server.ts +45 -52
- package/core/util/widget-resolve.util.ts +2 -2
- package/core/widget/widget.registry.ts +29 -2
- package/dist/core/renderer/html.renderer.js +1 -1
- package/dist/core/renderer/html.renderer.js.map +1 -1
- package/dist/core/renderer/md.renderer.js +1 -1
- package/dist/core/renderer/md.renderer.js.map +1 -1
- package/dist/core/renderer/ssr.renderer.d.ts +4 -1
- package/dist/core/renderer/ssr.renderer.js +20 -0
- package/dist/core/renderer/ssr.renderer.js.map +1 -1
- package/dist/core/server/emroute.server.d.ts +0 -2
- package/dist/core/server/emroute.server.js +36 -47
- package/dist/core/server/emroute.server.js.map +1 -1
- package/dist/core/util/widget-resolve.util.d.ts +1 -3
- package/dist/core/util/widget-resolve.util.js +2 -2
- package/dist/core/util/widget-resolve.util.js.map +1 -1
- package/dist/core/widget/widget.registry.d.ts +8 -0
- package/dist/core/widget/widget.registry.js +28 -2
- package/dist/core/widget/widget.registry.js.map +1 -1
- package/dist/emroute.js +227 -66
- package/dist/emroute.js.map +13 -13
- package/dist/runtime/abstract.runtime.js +7 -3
- package/dist/runtime/abstract.runtime.js.map +1 -1
- package/dist/runtime/fetch.runtime.js +7 -1
- package/dist/runtime/fetch.runtime.js.map +1 -1
- package/dist/server/build.util.d.ts +1 -1
- package/dist/server/build.util.js +10 -28
- package/dist/server/build.util.js.map +1 -1
- package/dist/src/element/component.element.d.ts +4 -1
- package/dist/src/element/component.element.js +4 -1
- package/dist/src/element/component.element.js.map +1 -1
- package/dist/src/overlay/mod.d.ts +1 -1
- package/dist/src/overlay/overlay.service.js +136 -6
- package/dist/src/overlay/overlay.service.js.map +1 -1
- package/dist/src/overlay/overlay.type.d.ts +28 -4
- package/dist/src/renderer/spa/emroute.app.d.ts +3 -0
- package/dist/src/renderer/spa/emroute.app.js +18 -3
- package/dist/src/renderer/spa/emroute.app.js.map +1 -1
- package/package.json +2 -2
- package/runtime/abstract.runtime.ts +11 -5
- package/runtime/fetch.runtime.ts +6 -1
- package/server/build.util.ts +10 -30
- package/src/element/component.element.ts +4 -1
- package/src/overlay/mod.ts +1 -1
- package/src/overlay/overlay.service.ts +158 -8
- package/src/overlay/overlay.type.ts +27 -2
- package/src/renderer/spa/emroute.app.ts +20 -3
package/README.md
CHANGED
|
@@ -114,7 +114,7 @@ export default new ProjectPage();
|
|
|
114
114
|
- **Configurable base paths** — `/html/` and `/md/` prefixes are configurable via `BasePath`
|
|
115
115
|
- **SPA modes** — `'root'` (default), `'leaf'`, `'none'`, or `'only'` to control how the server handles non-file requests and SSR endpoints
|
|
116
116
|
- **Sitemap generation** — opt-in `sitemap.xml` from the routes manifest with support for dynamic route enumerators
|
|
117
|
-
- **Dev server** — zero-config: auto-generates `main.ts
|
|
117
|
+
- **Dev server** — zero-config: auto-generates `main.ts` and route/widget manifests. File watcher with hot reload and bundle serving
|
|
118
118
|
|
|
119
119
|
## Runtimes
|
|
120
120
|
|
|
@@ -68,7 +68,7 @@ export class SsrHtmlRenderer extends SsrRenderer {
|
|
|
68
68
|
if (this.widgets) {
|
|
69
69
|
content = await resolveWidgetTags(
|
|
70
70
|
content,
|
|
71
|
-
this.
|
|
71
|
+
(name) => this.resolveWidget(name),
|
|
72
72
|
routeInfo,
|
|
73
73
|
async (name) => {
|
|
74
74
|
const modulePath = this.widgets!.getModulePath(name);
|
|
@@ -95,7 +95,7 @@ export class SsrMdRenderer extends SsrRenderer {
|
|
|
95
95
|
return `> **Error** (\`${block.widgetName}\`): ${block.parseError}`;
|
|
96
96
|
}
|
|
97
97
|
|
|
98
|
-
const widget = this.
|
|
98
|
+
const widget = await this.resolveWidget(block.widgetName);
|
|
99
99
|
if (!widget) {
|
|
100
100
|
return `> **Error**: Unknown widget \`${block.widgetName}\``;
|
|
101
101
|
}
|
|
@@ -15,7 +15,8 @@ import type { Logger } from '../type/logger.type.ts';
|
|
|
15
15
|
import defaultPageComponent, { type PageComponent } from '../component/page.component.ts';
|
|
16
16
|
import { DEFAULT_ROOT_ROUTE, type Pipeline } from '../pipeline/pipeline.ts';
|
|
17
17
|
import { assertSafeRedirect } from '../util/html.util.ts';
|
|
18
|
-
import type
|
|
18
|
+
import { type WidgetRegistry, extractWidgetExport } from '../widget/widget.registry.ts';
|
|
19
|
+
import type { WidgetComponent } from '../component/widget.component.ts';
|
|
19
20
|
|
|
20
21
|
/** Options for SSR renderers. */
|
|
21
22
|
export interface SsrRendererOptions {
|
|
@@ -38,6 +39,25 @@ export abstract class SsrRenderer {
|
|
|
38
39
|
this.widgets = options.widgets ?? null;
|
|
39
40
|
}
|
|
40
41
|
|
|
42
|
+
/** Resolve a widget by name — eager lookup, then lazy load via Pipeline → Runtime. */
|
|
43
|
+
protected async resolveWidget(name: string): Promise<WidgetComponent | undefined> {
|
|
44
|
+
if (!this.widgets) return undefined;
|
|
45
|
+
const widget = this.widgets.get(name);
|
|
46
|
+
if (widget) return widget;
|
|
47
|
+
const path = this.widgets.getModulePath(name);
|
|
48
|
+
if (!path) return undefined;
|
|
49
|
+
try {
|
|
50
|
+
const mod = await this.pipeline.loadModule<Record<string, unknown>>(path);
|
|
51
|
+
return extractWidgetExport(mod) ?? undefined;
|
|
52
|
+
} catch (e) {
|
|
53
|
+
this.logger.error(
|
|
54
|
+
`[${this.label}] Failed to load widget "${name}"`,
|
|
55
|
+
e instanceof Error ? e : undefined,
|
|
56
|
+
);
|
|
57
|
+
return undefined;
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
|
|
41
61
|
/**
|
|
42
62
|
* Render a URL to a content string.
|
|
43
63
|
*/
|
|
@@ -6,7 +6,6 @@
|
|
|
6
6
|
*/
|
|
7
7
|
|
|
8
8
|
import type { WidgetManifestEntry } from '../type/widget.type.ts';
|
|
9
|
-
import type { WidgetComponent } from '../component/widget.component.ts';
|
|
10
9
|
import type { Runtime } from '../runtime/abstract.runtime.ts';
|
|
11
10
|
import { Pipeline } from '../pipeline/pipeline.ts';
|
|
12
11
|
import { SsrHtmlRenderer } from '../renderer/html.renderer.ts';
|
|
@@ -88,16 +87,22 @@ export class Emroute {
|
|
|
88
87
|
|
|
89
88
|
// ── Widgets ───────────────────────────────────────────────────────
|
|
90
89
|
|
|
91
|
-
let widgets: WidgetRegistry | undefined
|
|
90
|
+
let widgets: WidgetRegistry | undefined;
|
|
92
91
|
|
|
93
92
|
const widgetsResponse = await runtime.query(WIDGETS_MANIFEST_PATH);
|
|
94
93
|
if (widgetsResponse.status !== 404) {
|
|
95
94
|
const entries: WidgetManifestEntry[] = await widgetsResponse.json();
|
|
96
|
-
|
|
97
|
-
|
|
95
|
+
widgets = new WidgetRegistry();
|
|
96
|
+
for (const entry of entries) {
|
|
97
|
+
widgets.addLazy(entry.name, entry.modulePath);
|
|
98
98
|
}
|
|
99
99
|
}
|
|
100
100
|
|
|
101
|
+
if (config.widgets) {
|
|
102
|
+
if (!widgets) widgets = new WidgetRegistry();
|
|
103
|
+
for (const w of config.widgets) widgets.add(w);
|
|
104
|
+
}
|
|
105
|
+
|
|
101
106
|
// ── Renderers ─────────────────────────────────────────────────────
|
|
102
107
|
|
|
103
108
|
let ssrHtmlRenderer: SsrHtmlRenderer | null = null;
|
|
@@ -118,11 +123,7 @@ export class Emroute {
|
|
|
118
123
|
|
|
119
124
|
const title = config.title ?? 'emroute';
|
|
120
125
|
const shellBase = (spa === 'root' || spa === 'only') ? appBase : htmlBase;
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
if ((await runtime.query('/main.css')).status !== 404) {
|
|
124
|
-
shell = shell.replace('</head>', ' <link rel="stylesheet" href="/main.css">\n</head>');
|
|
125
|
-
}
|
|
126
|
+
const shell = await Emroute.resolveShell(runtime, title, shellBase, spa);
|
|
126
127
|
|
|
127
128
|
return new Emroute(
|
|
128
129
|
ssrHtmlRenderer,
|
|
@@ -211,15 +212,18 @@ export class Emroute {
|
|
|
211
212
|
});
|
|
212
213
|
}
|
|
213
214
|
|
|
214
|
-
// Unhandled SSR paths in 'only' mode —
|
|
215
|
+
// Unhandled SSR paths in 'only' mode — redirect to /app/
|
|
215
216
|
if (
|
|
216
217
|
pathname.startsWith(htmlPrefix) || pathname === this.htmlBase ||
|
|
217
218
|
pathname.startsWith(mdPrefix) || pathname === this.mdBase
|
|
218
219
|
) {
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
220
|
+
const routePath = pathname.startsWith(htmlPrefix) ? pathname.slice(this.htmlBase.length)
|
|
221
|
+
: pathname.startsWith(mdPrefix) ? pathname.slice(this.mdBase.length)
|
|
222
|
+
: '/';
|
|
223
|
+
return Response.redirect(
|
|
224
|
+
new URL(this.appBase + routePath + (url.search || ''), url.origin),
|
|
225
|
+
302,
|
|
226
|
+
);
|
|
223
227
|
}
|
|
224
228
|
|
|
225
229
|
// Static files
|
|
@@ -238,57 +242,45 @@ export class Emroute {
|
|
|
238
242
|
|
|
239
243
|
// ── Private static helpers ────────────────────────────────────────
|
|
240
244
|
|
|
241
|
-
private static
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
245
|
+
private static async buildHtmlShell(
|
|
246
|
+
runtime: Runtime,
|
|
247
|
+
title: string,
|
|
248
|
+
basePath: string,
|
|
249
|
+
spa: SpaMode,
|
|
250
|
+
): Promise<string> {
|
|
251
|
+
const baseTag = basePath ? `\n <base href="${escapeHtml(basePath)}/">` : '';
|
|
252
|
+
|
|
253
|
+
let cssTag = '';
|
|
254
|
+
if ((await runtime.query('/main.css')).status !== 404) {
|
|
255
|
+
cssTag = '\n <link rel="stylesheet" href="/main.css">';
|
|
252
256
|
}
|
|
253
|
-
return null;
|
|
254
|
-
}
|
|
255
257
|
|
|
256
|
-
|
|
257
|
-
entries: WidgetManifestEntry[],
|
|
258
|
-
runtime: Runtime,
|
|
259
|
-
): Promise<WidgetRegistry> {
|
|
260
|
-
const registry = new WidgetRegistry();
|
|
258
|
+
const needsJs = spa !== 'none';
|
|
261
259
|
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
const mod = await runtime.loadModule(runtimePath) as Record<string, unknown>;
|
|
269
|
-
const instance = Emroute.extractWidgetExport(mod);
|
|
270
|
-
if (!instance) continue;
|
|
271
|
-
registry.add(instance, runtimePath);
|
|
272
|
-
} catch (e) {
|
|
273
|
-
console.error(`[emroute] Failed to load widget ${entry.modulePath}:`, e);
|
|
260
|
+
let importMapHtml = '';
|
|
261
|
+
if (needsJs) {
|
|
262
|
+
const mapResponse = await runtime.query('/importmap.json');
|
|
263
|
+
if (mapResponse.status !== 404) {
|
|
264
|
+
const importMap = await mapResponse.text();
|
|
265
|
+
importMapHtml = `\n <script type="importmap">\n${importMap}\n </script>`;
|
|
274
266
|
}
|
|
275
267
|
}
|
|
276
268
|
|
|
277
|
-
|
|
278
|
-
|
|
269
|
+
let scriptHtml = '';
|
|
270
|
+
if (needsJs && (await runtime.query('/app.js')).status !== 404) {
|
|
271
|
+
scriptHtml = '\n <script type="module" src="/app.js"></script>';
|
|
272
|
+
}
|
|
279
273
|
|
|
280
|
-
private static buildHtmlShell(title: string, htmlBase: string): string {
|
|
281
|
-
const baseTag = htmlBase ? `\n <base href="${escapeHtml(htmlBase)}/">` : '';
|
|
282
274
|
return `<!DOCTYPE html>
|
|
283
275
|
<html>
|
|
284
276
|
<head>${baseTag}
|
|
285
277
|
<meta charset="utf-8">
|
|
286
278
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
|
287
279
|
<title>${escapeHtml(title)}</title>
|
|
288
|
-
<style>@view-transition { navigation: auto; } router-slot { display: contents; }</style
|
|
280
|
+
<style>@view-transition { navigation: auto; } router-slot { display: contents; }</style>${cssTag}
|
|
289
281
|
</head>
|
|
290
282
|
<body>
|
|
291
|
-
<router-slot></router-slot
|
|
283
|
+
<router-slot></router-slot>${importMapHtml}${scriptHtml}
|
|
292
284
|
</body>
|
|
293
285
|
</html>`;
|
|
294
286
|
}
|
|
@@ -315,10 +307,11 @@ export class Emroute {
|
|
|
315
307
|
private static async resolveShell(
|
|
316
308
|
runtime: Runtime,
|
|
317
309
|
title: string,
|
|
318
|
-
|
|
310
|
+
basePath: string,
|
|
311
|
+
spa: SpaMode,
|
|
319
312
|
): Promise<string> {
|
|
320
313
|
const response = await runtime.query('/index.html');
|
|
321
314
|
if (response.status !== 404) return await response.text();
|
|
322
|
-
return Emroute.buildHtmlShell(title,
|
|
315
|
+
return Emroute.buildHtmlShell(runtime, title, basePath, spa);
|
|
323
316
|
}
|
|
324
317
|
}
|
|
@@ -53,7 +53,7 @@ export async function resolveRecursively<T>(
|
|
|
53
53
|
*/
|
|
54
54
|
export function resolveWidgetTags(
|
|
55
55
|
html: string,
|
|
56
|
-
|
|
56
|
+
getWidget: (name: string) => Promise<Component | undefined>,
|
|
57
57
|
routeInfo: RouteInfo,
|
|
58
58
|
loadFiles?: (
|
|
59
59
|
widgetName: string,
|
|
@@ -78,7 +78,7 @@ export function resolveWidgetTags(
|
|
|
78
78
|
const resolve = async (match: RegExpExecArray): Promise<string> => {
|
|
79
79
|
const widgetName = match.groups!.name!;
|
|
80
80
|
const attrsString = match.groups!.attrs?.trim() ?? '';
|
|
81
|
-
const widget =
|
|
81
|
+
const widget = await getWidget(widgetName);
|
|
82
82
|
|
|
83
83
|
if (!widget) return match[0];
|
|
84
84
|
|
|
@@ -3,22 +3,33 @@
|
|
|
3
3
|
*
|
|
4
4
|
* Name → Component lookup. Used by all renderers.
|
|
5
5
|
* Pages are NOT in this registry — they live in the routes manifest.
|
|
6
|
+
*
|
|
7
|
+
* Supports eager entries (widget instance) and lazy entries (module path only).
|
|
8
|
+
* Lazy entries are resolved on demand by the renderer via Pipeline → Runtime.
|
|
6
9
|
*/
|
|
7
10
|
|
|
8
11
|
import type { WidgetComponent } from '../component/widget.component.ts';
|
|
9
12
|
|
|
10
13
|
interface RegistryEntry {
|
|
11
|
-
widget
|
|
14
|
+
widget?: WidgetComponent;
|
|
12
15
|
modulePath?: string | undefined;
|
|
13
16
|
}
|
|
14
17
|
|
|
15
18
|
export class WidgetRegistry {
|
|
16
19
|
private entries = new Map<string, RegistryEntry>();
|
|
17
20
|
|
|
21
|
+
/** Register a widget instance (eager). */
|
|
18
22
|
add(widget: WidgetComponent, modulePath?: string): void {
|
|
19
23
|
this.entries.set(widget.name, { widget, modulePath });
|
|
20
24
|
}
|
|
21
25
|
|
|
26
|
+
/** Register a widget by name and module path (lazy — resolved on demand by renderer). */
|
|
27
|
+
addLazy(name: string, modulePath: string): void {
|
|
28
|
+
if (!this.entries.has(name)) {
|
|
29
|
+
this.entries.set(name, { modulePath });
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
|
|
22
33
|
get(name: string): WidgetComponent | undefined {
|
|
23
34
|
return this.entries.get(name)?.widget;
|
|
24
35
|
}
|
|
@@ -30,7 +41,23 @@ export class WidgetRegistry {
|
|
|
30
41
|
[Symbol.iterator](): IterableIterator<WidgetComponent> {
|
|
31
42
|
const entries = this.entries.values();
|
|
32
43
|
return (function* () {
|
|
33
|
-
for (const entry of entries)
|
|
44
|
+
for (const entry of entries) {
|
|
45
|
+
if (entry.widget) yield entry.widget;
|
|
46
|
+
}
|
|
34
47
|
})();
|
|
35
48
|
}
|
|
36
49
|
}
|
|
50
|
+
|
|
51
|
+
/** Extract a WidgetComponent from a loaded module's exports. */
|
|
52
|
+
export function extractWidgetExport(mod: Record<string, unknown>): WidgetComponent | null {
|
|
53
|
+
for (const value of Object.values(mod)) {
|
|
54
|
+
if (!value) continue;
|
|
55
|
+
if (typeof value === 'object' && 'getData' in value) {
|
|
56
|
+
return value as WidgetComponent;
|
|
57
|
+
}
|
|
58
|
+
if (typeof value === 'function' && value.prototype?.getData) {
|
|
59
|
+
return new (value as new () => WidgetComponent)();
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
return null;
|
|
63
|
+
}
|
|
@@ -38,7 +38,7 @@ export class SsrHtmlRenderer extends SsrRenderer {
|
|
|
38
38
|
content = this.attributeSlots(content, route.pattern);
|
|
39
39
|
// Resolve <widget-*> tags
|
|
40
40
|
if (this.widgets) {
|
|
41
|
-
content = await resolveWidgetTags(content, this.
|
|
41
|
+
content = await resolveWidgetTags(content, (name) => this.resolveWidget(name), routeInfo, async (name) => {
|
|
42
42
|
const modulePath = this.widgets.getModulePath(name);
|
|
43
43
|
if (modulePath) {
|
|
44
44
|
const mod = await this.pipeline.loadModule(modulePath);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"html.renderer.js","sourceRoot":"","sources":["../../../core/renderer/html.renderer.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAMH,OAAO,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAC;AAC7D,OAAO,EAAE,UAAU,EAAE,eAAe,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AACjF,OAAO,EAAE,iBAAiB,EAAE,MAAM,gCAAgC,CAAC;AACnE,OAAO,EAAE,WAAW,EAA2B,MAAM,mBAAmB,CAAC;AAOzE,MAAM,OAAO,eAAgB,SAAQ,WAAW;IAClB,KAAK,GAAG,UAAU,CAAC;IACvC,gBAAgB,CAA0B;IAC1C,aAAa,GAAyB,IAAI,CAAC;IAEnD,YAAY,QAAkB,EAAE,UAAkC,EAAE;QAClE,KAAK,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;QACzB,IAAI,CAAC,gBAAgB,GAAG,OAAO,CAAC,gBAAgB,IAAI,IAAI,CAAC;QAEzD,IAAI,IAAI,CAAC,gBAAgB,EAAE,IAAI,EAAE,CAAC;YAChC,IAAI,CAAC,aAAa,GAAG,IAAI,CAAC,gBAAgB,CAAC,IAAI,EAAE,CAAC;QACpD,CAAC;IACH,CAAC;IAEkB,UAAU,CAAC,MAAc,EAAE,KAAa,EAAE,aAAqB;QAChF,MAAM,OAAO,GAAG,aAAa,CAAC,OAAO,CAAC,qBAAqB,EAAE,MAAM,CAAC,CAAC;QACrE,OAAO,MAAM,CAAC,OAAO,CACnB,IAAI,MAAM,CAAC,mCAAmC,OAAO,uBAAuB,CAAC,EAC7E,KAAK,CACN,CAAC;IACJ,CAAC;IAEkB,UAAU,CAAC,MAAc;QAC1C,OAAO,MAAM,CAAC,OAAO,CAAC,oCAAoC,EAAE,EAAE,CAAC,CAAC;IAClE,CAAC;IAEkB,KAAK,CAAC,kBAAkB,CACzC,SAAoB,EACpB,KAAkB,EAClB,MAAgB,EAChB,MAAoB;QAEpB,IAAI,KAAK,CAAC,UAAU,KAAK,kBAAkB,CAAC,UAAU,EAAE,CAAC;YACvD,OAAO,EAAE,OAAO,EAAE,yBAAyB,KAAK,CAAC,OAAO,kBAAkB,EAAE,CAAC;QAC/E,CAAC;QAED,MAAM,EAAE,OAAO,EAAE,UAAU,EAAE,KAAK,EAAE,GAAG,MAAM,IAAI,CAAC,gBAAgB,CAAC,SAAS,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC;QACrG,IAAI,OAAO,GAAG,UAAU,CAAC;QAEzB,OAAO,GAAG,MAAM,IAAI,CAAC,cAAc,CAAC,OAAO,CAAC,CAAC;QAE7C,8DAA8D;QAC9D,OAAO,GAAG,IAAI,CAAC,cAAc,CAAC,OAAO,EAAE,KAAK,CAAC,OAAO,CAAC,CAAC;QAEtD,0BAA0B;QAC1B,IAAI,IAAI,CAAC,OAAO,EAAE,CAAC;YACjB,OAAO,GAAG,MAAM,iBAAiB,CAC/B,OAAO,EACP,IAAI,CAAC,
|
|
1
|
+
{"version":3,"file":"html.renderer.js","sourceRoot":"","sources":["../../../core/renderer/html.renderer.ts"],"names":[],"mappings":"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"}
|
|
@@ -57,7 +57,7 @@ export class SsrMdRenderer extends SsrRenderer {
|
|
|
57
57
|
if (block.parseError || !block.params) {
|
|
58
58
|
return `> **Error** (\`${block.widgetName}\`): ${block.parseError}`;
|
|
59
59
|
}
|
|
60
|
-
const widget = this.
|
|
60
|
+
const widget = await this.resolveWidget(block.widgetName);
|
|
61
61
|
if (!widget) {
|
|
62
62
|
return `> **Error**: Unknown widget \`${block.widgetName}\``;
|
|
63
63
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"md.renderer.js","sourceRoot":"","sources":["../../../core/renderer/md.renderer.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"md.renderer.js","sourceRoot":"","sources":["../../../core/renderer/md.renderer.ts"],"names":[],"mappings":"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"}
|
|
@@ -9,7 +9,8 @@ import type { ComponentContext } from '../type/component.type.ts';
|
|
|
9
9
|
import type { Logger } from '../type/logger.type.ts';
|
|
10
10
|
import { type PageComponent } from '../component/page.component.ts';
|
|
11
11
|
import { type Pipeline } from '../pipeline/pipeline.ts';
|
|
12
|
-
import type
|
|
12
|
+
import { type WidgetRegistry } from '../widget/widget.registry.ts';
|
|
13
|
+
import type { WidgetComponent } from '../component/widget.component.ts';
|
|
13
14
|
/** Options for SSR renderers. */
|
|
14
15
|
export interface SsrRendererOptions {
|
|
15
16
|
widgets?: WidgetRegistry;
|
|
@@ -23,6 +24,8 @@ export declare abstract class SsrRenderer {
|
|
|
23
24
|
protected abstract readonly label: string;
|
|
24
25
|
protected readonly logger: Logger;
|
|
25
26
|
constructor(pipeline: Pipeline, options?: SsrRendererOptions);
|
|
27
|
+
/** Resolve a widget by name — eager lookup, then lazy load via Pipeline → Runtime. */
|
|
28
|
+
protected resolveWidget(name: string): Promise<WidgetComponent | undefined>;
|
|
26
29
|
/**
|
|
27
30
|
* Render a URL to a content string.
|
|
28
31
|
*/
|
|
@@ -7,6 +7,7 @@
|
|
|
7
7
|
import defaultPageComponent from "../component/page.component.js";
|
|
8
8
|
import { DEFAULT_ROOT_ROUTE } from "../pipeline/pipeline.js";
|
|
9
9
|
import { assertSafeRedirect } from "../util/html.util.js";
|
|
10
|
+
import { extractWidgetExport } from "../widget/widget.registry.js";
|
|
10
11
|
/**
|
|
11
12
|
* Abstract SSR renderer with shared routing pipeline.
|
|
12
13
|
*/
|
|
@@ -19,6 +20,25 @@ export class SsrRenderer {
|
|
|
19
20
|
this.logger = pipeline.logger;
|
|
20
21
|
this.widgets = options.widgets ?? null;
|
|
21
22
|
}
|
|
23
|
+
/** Resolve a widget by name — eager lookup, then lazy load via Pipeline → Runtime. */
|
|
24
|
+
async resolveWidget(name) {
|
|
25
|
+
if (!this.widgets)
|
|
26
|
+
return undefined;
|
|
27
|
+
const widget = this.widgets.get(name);
|
|
28
|
+
if (widget)
|
|
29
|
+
return widget;
|
|
30
|
+
const path = this.widgets.getModulePath(name);
|
|
31
|
+
if (!path)
|
|
32
|
+
return undefined;
|
|
33
|
+
try {
|
|
34
|
+
const mod = await this.pipeline.loadModule(path);
|
|
35
|
+
return extractWidgetExport(mod) ?? undefined;
|
|
36
|
+
}
|
|
37
|
+
catch (e) {
|
|
38
|
+
this.logger.error(`[${this.label}] Failed to load widget "${name}"`, e instanceof Error ? e : undefined);
|
|
39
|
+
return undefined;
|
|
40
|
+
}
|
|
41
|
+
}
|
|
22
42
|
/**
|
|
23
43
|
* Render a URL to a content string.
|
|
24
44
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ssr.renderer.js","sourceRoot":"","sources":["../../../core/renderer/ssr.renderer.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AASH,OAAO,oBAA4C,MAAM,gCAAgC,CAAC;AAC1F,OAAO,EAAE,kBAAkB,EAAiB,MAAM,yBAAyB,CAAC;AAC5E,OAAO,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAC;
|
|
1
|
+
{"version":3,"file":"ssr.renderer.js","sourceRoot":"","sources":["../../../core/renderer/ssr.renderer.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AASH,OAAO,oBAA4C,MAAM,gCAAgC,CAAC;AAC1F,OAAO,EAAE,kBAAkB,EAAiB,MAAM,yBAAyB,CAAC;AAC5E,OAAO,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAC;AAC1D,OAAO,EAAuB,mBAAmB,EAAE,MAAM,8BAA8B,CAAC;AAQxF;;GAEG;AACH,MAAM,OAAgB,WAAW;IACZ,QAAQ,CAAW;IAC5B,OAAO,CAAwB;IAGtB,MAAM,CAAS;IAElC,YAAY,QAAkB,EAAE,UAA8B,EAAE;QAC9D,IAAI,CAAC,QAAQ,GAAG,QAAQ,CAAC;QACzB,IAAI,CAAC,MAAM,GAAG,QAAQ,CAAC,MAAM,CAAC;QAC9B,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC,OAAO,IAAI,IAAI,CAAC;IACzC,CAAC;IAED,sFAAsF;IAC5E,KAAK,CAAC,aAAa,CAAC,IAAY;QACxC,IAAI,CAAC,IAAI,CAAC,OAAO;YAAE,OAAO,SAAS,CAAC;QACpC,MAAM,MAAM,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;QACtC,IAAI,MAAM;YAAE,OAAO,MAAM,CAAC;QAC1B,MAAM,IAAI,GAAG,IAAI,CAAC,OAAO,CAAC,aAAa,CAAC,IAAI,CAAC,CAAC;QAC9C,IAAI,CAAC,IAAI;YAAE,OAAO,SAAS,CAAC;QAC5B,IAAI,CAAC;YACH,MAAM,GAAG,GAAG,MAAM,IAAI,CAAC,QAAQ,CAAC,UAAU,CAA0B,IAAI,CAAC,CAAC;YAC1E,OAAO,mBAAmB,CAAC,GAAG,CAAC,IAAI,SAAS,CAAC;QAC/C,CAAC;QAAC,OAAO,CAAC,EAAE,CAAC;YACX,IAAI,CAAC,MAAM,CAAC,KAAK,CACf,IAAI,IAAI,CAAC,KAAK,4BAA4B,IAAI,GAAG,EACjD,CAAC,YAAY,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CACnC,CAAC;YACF,OAAO,SAAS,CAAC;QACnB,CAAC;IACH,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,MAAM,CACV,GAAQ,EACR,MAAoB;QAEpB,MAAM,OAAO,GAAG,MAAM,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;QAE/C,IAAI,CAAC,OAAO,EAAE,CAAC;YACb,MAAM,UAAU,GAAG,MAAM,IAAI,CAAC,QAAQ,CAAC,aAAa,CAAC,GAAG,CAAC,CAAC;YAC1D,IAAI,UAAU,EAAE,CAAC;gBACf,IAAI,CAAC;oBACH,MAAM,EAAE,GAAc,EAAE,GAAG,EAAE,MAAM,EAAE,EAAE,EAAE,CAAC;oBAC1C,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,kBAAkB,CAAC,EAAE,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,CAAC,CAAC;oBAChF,OAAO,EAAE,OAAO,EAAE,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC,OAAO,CAAC,EAAE,MAAM,EAAE,GAAG,EAAE,GAAG,CAAC,MAAM,CAAC,KAAK,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,MAAM,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC;gBACnI,CAAC;gBAAC,OAAO,CAAC,EAAE,CAAC;oBACX,IAAI,CAAC,MAAM,CAAC,KAAK,CACf,IAAI,IAAI,CAAC,KAAK,0CAA0C,GAAG,CAAC,QAAQ,EAAE,EACtE,CAAC,YAAY,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CACnC,CAAC;gBACJ,CAAC;YACH,CAAC;YACD,OAAO,EAAE,OAAO,EAAE,IAAI,CAAC,gBAAgB,CAAC,GAAG,EAAE,GAAG,CAAC,EAAE,MAAM,EAAE,GAAG,EAAE,CAAC;QACnE,CAAC;QAED,kBAAkB;QAClB,IAAI,OAAO,CAAC,KAAK,CAAC,IAAI,KAAK,UAAU,EAAE,CAAC;YACtC,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,QAAQ,CAAC,UAAU,CAC3C,OAAO,CAAC,KAAK,CAAC,UAAU,CACzB,CAAC;YACF,MAAM,cAAc,GAAG,MAAM,CAAC,OAAO,CAAC;YACtC,kBAAkB,CAAC,cAAc,CAAC,EAAE,CAAC,CAAC;YACtC,OAAO;gBACL,OAAO,EAAE,IAAI,CAAC,cAAc,CAAC,cAAc,CAAC,EAAE,CAAC;gBAC/C,MAAM,EAAE,cAAc,CAAC,MAAM,IAAI,GAAG;gBACpC,QAAQ,EAAE,cAAc,CAAC,EAAE;aAC5B,CAAC;QACJ,CAAC;QAED,MAAM,SAAS,GAAG,IAAI,CAAC,QAAQ,CAAC,WAAW,CAAC,OAAO,EAAE,GAAG,CAAC,CAAC;QAE1D,IAAI,CAAC;YACH,MAAM,EAAE,OAAO,EAAE,KAAK,EAAE,GAAG,MAAM,IAAI,CAAC,UAAU,CAAC,SAAS,EAAE,OAAO,EAAE,MAAM,CAAC,CAAC;YAC7E,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,GAAG,EAAE,GAAG,CAAC,KAAK,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC;QAC7E,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,IAAI,KAAK,YAAY,QAAQ,EAAE,CAAC;gBAC9B,MAAM,UAAU,GAAG,MAAM,IAAI,CAAC,QAAQ,CAAC,aAAa,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;gBACnE,IAAI,UAAU,EAAE,CAAC;oBACf,IAAI,CAAC;wBACH,MAAM,EAAE,GAAc,EAAE,GAAG,EAAE,MAAM,EAAE,EAAE,EAAE,CAAC;wBAC1C,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,kBAAkB,CAAC,EAAE,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,CAAC,CAAC;wBAChF,OAAO;4BACL,OAAO,EAAE,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC,OAAO,CAAC;4BACxC,MAAM,EAAE,KAAK,CAAC,MAAM;4BACpB,GAAG,CAAC,MAAM,CAAC,KAAK,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,MAAM,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;yBAC/D,CAAC;oBACJ,CAAC;oBAAC,OAAO,CAAC,EAAE,CAAC;wBACX,IAAI,CAAC,MAAM,CAAC,KAAK,CACf,IAAI,IAAI,CAAC,KAAK,sBAAsB,KAAK,CAAC,MAAM,oBAAoB,GAAG,CAAC,QAAQ,EAAE,EAClF,CAAC,YAAY,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CACnC,CAAC;oBACJ,CAAC;gBACH,CAAC;gBACD,OAAO,EAAE,OAAO,EAAE,IAAI,CAAC,gBAAgB,CAAC,KAAK,CAAC,MAAM,EAAE,GAAG,CAAC,EAAE,MAAM,EAAE,KAAK,CAAC,MAAM,EAAE,CAAC;YACrF,CAAC;YACD,IAAI,CAAC,MAAM,CAAC,KAAK,CACf,IAAI,IAAI,CAAC,KAAK,qBAAqB,GAAG,CAAC,QAAQ,GAAG,EAClD,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,SAAS,CAC3C,CAAC;YAEF,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,QAAQ,CAAC,iBAAiB,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;YACrE,IAAI,QAAQ,EAAE,CAAC;gBACb,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,oBAAoB,CAAC,QAAQ,CAAC,UAAU,EAAE,GAAG,EAAE,UAAU,CAAC,CAAC;gBACrF,IAAI,MAAM;oBAAE,OAAO,MAAM,CAAC;YAC5B,CAAC;YAED,MAAM,YAAY,GAAG,MAAM,IAAI,CAAC,QAAQ,CAAC,eAAe,EAAE,CAAC;YAC3D,IAAI,YAAY,EAAE,CAAC;gBACjB,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,oBAAoB,CAAC,YAAY,CAAC,UAAU,EAAE,GAAG,EAAE,SAAS,CAAC,CAAC;gBACxF,IAAI,MAAM;oBAAE,OAAO,MAAM,CAAC;YAC5B,CAAC;YAED,OAAO,EAAE,OAAO,EAAE,IAAI,CAAC,eAAe,CAAC,KAAK,EAAE,GAAG,CAAC,EAAE,MAAM,EAAE,GAAG,EAAE,CAAC;QACpE,CAAC;IACH,CAAC;IAED;;OAEG;IACO,KAAK,CAAC,UAAU,CACxB,SAAoB,EACpB,OAAqB,EACrB,MAAoB;QAEpB,MAAM,SAAS,GAAG,IAAI,CAAC,QAAQ,CAAC,mBAAmB,CAAC,OAAO,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;QAE3E,MAAM,QAAQ,GAA8C,EAAE,CAAC;QAC/D,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,SAAS,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;YAC1C,MAAM,YAAY,GAAG,SAAS,CAAC,CAAC,CAAE,CAAC;YACnC,IAAI,KAAK,GAAG,MAAM,IAAI,CAAC,QAAQ,CAAC,SAAS,CAAC,YAAY,CAAC,CAAC;YAExD,IAAI,CAAC,KAAK,IAAI,YAAY,KAAK,GAAG,EAAE,CAAC;gBACnC,KAAK,GAAG,kBAAkB,CAAC;YAC7B,CAAC;YAED,IAAI,CAAC,KAAK;gBAAE,SAAS;YACrB,IAAI,KAAK,KAAK,OAAO,CAAC,KAAK,IAAI,YAAY,KAAK,OAAO,CAAC,KAAK,CAAC,OAAO;gBAAE,SAAS;YAEhF,QAAQ,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC,KAAK,SAAS,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC,CAAC;QAC/D,CAAC;QAED,MAAM,OAAO,GAAG,MAAM,OAAO,CAAC,GAAG,CAC/B,QAAQ,CAAC,GAAG,CAAC,CAAC,EAAE,KAAK,EAAE,MAAM,EAAE,EAAE,EAAE,CACjC,IAAI,CAAC,kBAAkB,CAAC,SAAS,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,CAAC,CAC1D,CACF,CAAC;QAEF,IAAI,MAAM,GAAG,EAAE,CAAC;QAChB,IAAI,SAA6B,CAAC;QAClC,IAAI,mBAAmB,GAAG,EAAE,CAAC;QAE7B,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,QAAQ,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;YACzC,MAAM,EAAE,OAAO,EAAE,KAAK,EAAE,GAAG,OAAO,CAAC,CAAC,CAAE,CAAC;YAEvC,IAAI,KAAK,EAAE,CAAC;gBACV,SAAS,GAAG,KAAK,CAAC;YACpB,CAAC;YAED,IAAI,MAAM,KAAK,EAAE,EAAE,CAAC;gBAClB,MAAM,GAAG,OAAO,CAAC;YACnB,CAAC;iBAAM,CAAC;gBACN,MAAM,QAAQ,GAAG,IAAI,CAAC,UAAU,CAAC,MAAM,EAAE,OAAO,EAAE,mBAAmB,CAAC,CAAC;gBACvE,IAAI,QAAQ,KAAK,MAAM,EAAE,CAAC;oBACxB,IAAI,CAAC,MAAM,CAAC,IAAI,CACd,IAAI,IAAI,CAAC,KAAK,YAAY,mBAAmB,yBAAyB;wBACpE,oBAAoB,SAAS,CAAC,CAAC,CAAC,oBAAoB;wBACpD,yDAAyD,CAC5D,CAAC;gBACJ,CAAC;gBACD,MAAM,GAAG,QAAQ,CAAC;YACpB,CAAC;YAED,mBAAmB,GAAG,QAAQ,CAAC,CAAC,CAAE,CAAC,KAAK,CAAC,OAAO,CAAC;QACnD,CAAC;QAED,MAAM,GAAG,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC;QAEjC,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,GAAG,CAAC,SAAS,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,SAAS,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC;IACvF,CAAC;IASD,0EAA0E;IAChE,KAAK,CAAC,gBAAgB,CAC9B,SAAoB,EACpB,KAAkB,EAClB,MAAgB,EAChB,MAAoB;QAEpB,MAAM,KAAK,GAAG,KAAK,CAAC,KAAK,IAAI,EAAE,CAAC;QAEhC,MAAM,QAAQ,GAAG,KAAK,CAAC,EAAE,IAAI,KAAK,CAAC,EAAE,CAAC;QACtC,MAAM,YAAY,GAAG,QAAQ;YAC3B,CAAC,CAAC,MAAM,IAAI,CAAC,QAAQ,CAAC,UAAU,CAA6B,QAAQ,CAAC;YACtE,CAAC,CAAC,SAAS,CAAC;QACd,MAAM,SAAS,GAAkB,YAAY,EAAE,OAAO,IAAI,oBAAoB,CAAC;QAE/E,MAAM,OAAO,GAAG,MAAM,IAAI,CAAC,QAAQ,CAAC,YAAY,CAAC,SAAS,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,YAAY,CAAC,CAAC;QACjG,MAAM,IAAI,GAAG,MAAM,SAAS,CAAC,OAAO,CAAC,EAAE,MAAM,EAAE,SAAS,CAAC,MAAM,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,OAAO,EAAE,CAAC,CAAC;QAC3G,MAAM,OAAO,GAAG,IAAI,CAAC,aAAa,CAAC,SAAS,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,SAAS,CAAC,MAAM,EAAE,OAAO,EAAE,CAAC,CAAC;QAC3F,MAAM,KAAK,GAAG,SAAS,CAAC,QAAQ,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,SAAS,CAAC,MAAM,EAAE,OAAO,EAAE,CAAC,CAAC;QAE9E,OAAO,EAAE,OAAO,EAAE,GAAG,CAAC,KAAK,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC;IAChE,CAAC;IAOS,eAAe,CACvB,SAAwB,EACxB,IAAa,EACb,OAAyB;QAEzB,OAAO,IAAI,CAAC,aAAa,CAAC,SAAS,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,OAAO,EAAE,CAAC,CAAC;IACtE,CAAC;IAEO,MAAM,CAAU,SAAS,GAAG,IAAI,GAAG,CAAC,cAAc,CAAC,CAAC;IAEpD,KAAK,CAAC,oBAAoB,CAChC,UAAkB,EAClB,GAAQ,EACR,IAA4B;QAE5B,IAAI,CAAC;YACH,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,QAAQ,CAAC,UAAU,CAA6B,UAAU,CAAC,CAAC;YACtF,MAAM,SAAS,GAAG,MAAM,CAAC,OAAO,CAAC;YACjC,MAAM,MAAM,GAAqB;gBAC/B,GAAG,EAAE,WAAW,CAAC,SAAS;gBAC1B,MAAM,EAAE,EAAE;gBACV,QAAQ,EAAE,EAAE;gBACZ,YAAY,EAAE,IAAI,eAAe,EAAE;aACpC,CAAC;YACF,MAAM,IAAI,GAAG,MAAM,SAAS,CAAC,OAAO,CAAC,EAAE,MAAM,EAAE,EAAE,EAAE,OAAO,EAAE,MAAM,EAAE,CAAC,CAAC;YACtE,MAAM,OAAO,GAAG,IAAI,CAAC,eAAe,CAAC,SAAS,EAAE,IAAI,EAAE,MAAM,CAAC,CAAC;YAC9D,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,GAAG,EAAE,CAAC;QAClC,CAAC;QAAC,OAAO,CAAC,EAAE,CAAC;YACX,IAAI,CAAC,MAAM,CAAC,KAAK,CACf,IAAI,IAAI,CAAC,KAAK,WAAW,IAAI,eAAe,GAAG,CAAC,QAAQ,EAAE,EAC1D,CAAC,YAAY,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CACnC,CAAC;YACF,OAAO,IAAI,CAAC;QACd,CAAC;IACH,CAAC"}
|
|
@@ -40,8 +40,6 @@ export declare class Emroute {
|
|
|
40
40
|
moduleLoaders?: Record<string, () => Promise<unknown>>;
|
|
41
41
|
}, runtime: Runtime): Promise<Emroute>;
|
|
42
42
|
handleRequest(req: Request): Promise<Response | null>;
|
|
43
|
-
private static extractWidgetExport;
|
|
44
|
-
private static importWidgets;
|
|
45
43
|
private static buildHtmlShell;
|
|
46
44
|
private static injectSsrContent;
|
|
47
45
|
private static resolveShell;
|
|
@@ -54,14 +54,21 @@ export class Emroute {
|
|
|
54
54
|
...(config.moduleLoaders ? { moduleLoaders: config.moduleLoaders } : {}),
|
|
55
55
|
});
|
|
56
56
|
// ── Widgets ───────────────────────────────────────────────────────
|
|
57
|
-
let widgets
|
|
57
|
+
let widgets;
|
|
58
58
|
const widgetsResponse = await runtime.query(WIDGETS_MANIFEST_PATH);
|
|
59
59
|
if (widgetsResponse.status !== 404) {
|
|
60
60
|
const entries = await widgetsResponse.json();
|
|
61
|
-
|
|
62
|
-
|
|
61
|
+
widgets = new WidgetRegistry();
|
|
62
|
+
for (const entry of entries) {
|
|
63
|
+
widgets.addLazy(entry.name, entry.modulePath);
|
|
63
64
|
}
|
|
64
65
|
}
|
|
66
|
+
if (config.widgets) {
|
|
67
|
+
if (!widgets)
|
|
68
|
+
widgets = new WidgetRegistry();
|
|
69
|
+
for (const w of config.widgets)
|
|
70
|
+
widgets.add(w);
|
|
71
|
+
}
|
|
65
72
|
// ── Renderers ─────────────────────────────────────────────────────
|
|
66
73
|
let ssrHtmlRenderer = null;
|
|
67
74
|
let ssrMdRenderer = null;
|
|
@@ -77,10 +84,7 @@ export class Emroute {
|
|
|
77
84
|
// ── HTML shell ────────────────────────────────────────────────────
|
|
78
85
|
const title = config.title ?? 'emroute';
|
|
79
86
|
const shellBase = (spa === 'root' || spa === 'only') ? appBase : htmlBase;
|
|
80
|
-
|
|
81
|
-
if ((await runtime.query('/main.css')).status !== 404) {
|
|
82
|
-
shell = shell.replace('</head>', ' <link rel="stylesheet" href="/main.css">\n</head>');
|
|
83
|
-
}
|
|
87
|
+
const shell = await Emroute.resolveShell(runtime, title, shellBase, spa);
|
|
84
88
|
return new Emroute(ssrHtmlRenderer, ssrMdRenderer, shell, runtime, htmlBase, mdBase, appBase, spa, title);
|
|
85
89
|
}
|
|
86
90
|
// ── handleRequest ─────────────────────────────────────────────────
|
|
@@ -149,13 +153,13 @@ export class Emroute {
|
|
|
149
153
|
headers: { 'Content-Type': 'text/html; charset=utf-8' },
|
|
150
154
|
});
|
|
151
155
|
}
|
|
152
|
-
// Unhandled SSR paths in 'only' mode —
|
|
156
|
+
// Unhandled SSR paths in 'only' mode — redirect to /app/
|
|
153
157
|
if (pathname.startsWith(htmlPrefix) || pathname === this.htmlBase ||
|
|
154
158
|
pathname.startsWith(mdPrefix) || pathname === this.mdBase) {
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
+
const routePath = pathname.startsWith(htmlPrefix) ? pathname.slice(this.htmlBase.length)
|
|
160
|
+
: pathname.startsWith(mdPrefix) ? pathname.slice(this.mdBase.length)
|
|
161
|
+
: '/';
|
|
162
|
+
return Response.redirect(new URL(this.appBase + routePath + (url.search || ''), url.origin), 302);
|
|
159
163
|
}
|
|
160
164
|
// Static files
|
|
161
165
|
const lastSegment = pathname.split('/').pop() ?? '';
|
|
@@ -171,50 +175,35 @@ export class Emroute {
|
|
|
171
175
|
return Response.redirect(new URL(`${base}/${bare}`, url.origin), 302);
|
|
172
176
|
}
|
|
173
177
|
// ── Private static helpers ────────────────────────────────────────
|
|
174
|
-
static
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
return value;
|
|
180
|
-
}
|
|
181
|
-
if (typeof value === 'function' && value.prototype?.getData) {
|
|
182
|
-
return new value();
|
|
183
|
-
}
|
|
178
|
+
static async buildHtmlShell(runtime, title, basePath, spa) {
|
|
179
|
+
const baseTag = basePath ? `\n <base href="${escapeHtml(basePath)}/">` : '';
|
|
180
|
+
let cssTag = '';
|
|
181
|
+
if ((await runtime.query('/main.css')).status !== 404) {
|
|
182
|
+
cssTag = '\n <link rel="stylesheet" href="/main.css">';
|
|
184
183
|
}
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
? entry.modulePath
|
|
193
|
-
: `/${entry.modulePath}`;
|
|
194
|
-
const mod = await runtime.loadModule(runtimePath);
|
|
195
|
-
const instance = Emroute.extractWidgetExport(mod);
|
|
196
|
-
if (!instance)
|
|
197
|
-
continue;
|
|
198
|
-
registry.add(instance, runtimePath);
|
|
199
|
-
}
|
|
200
|
-
catch (e) {
|
|
201
|
-
console.error(`[emroute] Failed to load widget ${entry.modulePath}:`, e);
|
|
184
|
+
const needsJs = spa !== 'none';
|
|
185
|
+
let importMapHtml = '';
|
|
186
|
+
if (needsJs) {
|
|
187
|
+
const mapResponse = await runtime.query('/importmap.json');
|
|
188
|
+
if (mapResponse.status !== 404) {
|
|
189
|
+
const importMap = await mapResponse.text();
|
|
190
|
+
importMapHtml = `\n <script type="importmap">\n${importMap}\n </script>`;
|
|
202
191
|
}
|
|
203
192
|
}
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
193
|
+
let scriptHtml = '';
|
|
194
|
+
if (needsJs && (await runtime.query('/app.js')).status !== 404) {
|
|
195
|
+
scriptHtml = '\n <script type="module" src="/app.js"></script>';
|
|
196
|
+
}
|
|
208
197
|
return `<!DOCTYPE html>
|
|
209
198
|
<html>
|
|
210
199
|
<head>${baseTag}
|
|
211
200
|
<meta charset="utf-8">
|
|
212
201
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
|
213
202
|
<title>${escapeHtml(title)}</title>
|
|
214
|
-
<style>@view-transition { navigation: auto; } router-slot { display: contents; }</style
|
|
203
|
+
<style>@view-transition { navigation: auto; } router-slot { display: contents; }</style>${cssTag}
|
|
215
204
|
</head>
|
|
216
205
|
<body>
|
|
217
|
-
<router-slot></router-slot
|
|
206
|
+
<router-slot></router-slot>${importMapHtml}${scriptHtml}
|
|
218
207
|
</body>
|
|
219
208
|
</html>`;
|
|
220
209
|
}
|
|
@@ -229,11 +218,11 @@ export class Emroute {
|
|
|
229
218
|
}
|
|
230
219
|
return html;
|
|
231
220
|
}
|
|
232
|
-
static async resolveShell(runtime, title,
|
|
221
|
+
static async resolveShell(runtime, title, basePath, spa) {
|
|
233
222
|
const response = await runtime.query('/index.html');
|
|
234
223
|
if (response.status !== 404)
|
|
235
224
|
return await response.text();
|
|
236
|
-
return Emroute.buildHtmlShell(title,
|
|
225
|
+
return Emroute.buildHtmlShell(runtime, title, basePath, spa);
|
|
237
226
|
}
|
|
238
227
|
}
|
|
239
228
|
//# sourceMappingURL=emroute.server.js.map
|