@emkodev/emroute 1.6.2 → 1.6.3
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 +72 -13
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Page Component
|
|
3
|
+
*
|
|
4
|
+
* Page component — params come from URL, context carries file content.
|
|
5
|
+
*
|
|
6
|
+
* Default implementations follow the fallback table:
|
|
7
|
+
* - renderHTML: html file → md via <mark-down> → <router-slot /> (non-leaf only)
|
|
8
|
+
* - renderMarkdown: md file → ```router-slot\n``` (non-leaf only)
|
|
9
|
+
* - getData: no-op (returns null)
|
|
10
|
+
*/
|
|
11
|
+
import { Component } from "./abstract.component.js";
|
|
12
|
+
import { escapeHtml } from "../util/html.util.js";
|
|
13
|
+
export class PageComponent extends Component {
|
|
14
|
+
name = 'page';
|
|
15
|
+
/** Route pattern this page handles (optional — set by subclasses) */
|
|
16
|
+
pattern;
|
|
17
|
+
/**
|
|
18
|
+
* Fetch or compute page data. Override in subclasses.
|
|
19
|
+
* Default: returns null (no data needed).
|
|
20
|
+
*
|
|
21
|
+
* @example
|
|
22
|
+
* ```ts
|
|
23
|
+
* override getData({ params, context }: this['DataArgs']) {
|
|
24
|
+
* return fetch(`/api/${params.id}`, { signal: context?.signal });
|
|
25
|
+
* }
|
|
26
|
+
* ```
|
|
27
|
+
*/
|
|
28
|
+
getData(_args) {
|
|
29
|
+
return Promise.resolve(null);
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Render page as HTML.
|
|
33
|
+
*
|
|
34
|
+
* Fallback chain:
|
|
35
|
+
* 1. html file content from context
|
|
36
|
+
* 2. md file content wrapped in `<mark-down>`
|
|
37
|
+
* 3. `<router-slot />` (bare slot for child routes)
|
|
38
|
+
*
|
|
39
|
+
* @example
|
|
40
|
+
* ```ts
|
|
41
|
+
* override renderHTML({ data, params, context }: this['RenderArgs']) {
|
|
42
|
+
* return `<h1>${params.id}</h1><p>${context?.files?.html ?? ''}</p>`;
|
|
43
|
+
* }
|
|
44
|
+
* ```
|
|
45
|
+
*/
|
|
46
|
+
renderHTML(args) {
|
|
47
|
+
const files = args.context.files;
|
|
48
|
+
const style = files?.css ? `<style>${files.css}</style>\n` : '';
|
|
49
|
+
if (files?.html) {
|
|
50
|
+
let html = style + files.html;
|
|
51
|
+
if (files.md && html.includes('<mark-down></mark-down>')) {
|
|
52
|
+
html = html.replace('<mark-down></mark-down>', `<mark-down>${escapeHtml(files.md)}</mark-down>`);
|
|
53
|
+
}
|
|
54
|
+
return html;
|
|
55
|
+
}
|
|
56
|
+
if (files?.md) {
|
|
57
|
+
// HOTFIX: skip external <router-slot> when markdown already defines one
|
|
58
|
+
// via ```router-slot fenced block. Without this, SPA mode produces two
|
|
59
|
+
// slots with the same pattern — one inside <mark-down> (from the fenced
|
|
60
|
+
// block) and one outside (from this suffix). SSR strips empty duplicates
|
|
61
|
+
// via stripSlots, but SPA has no equivalent cleanup.
|
|
62
|
+
// See: issues/pending/spa-duplicate-router-slot.issue.md
|
|
63
|
+
const hasSlot = files.md.includes('```router-slot');
|
|
64
|
+
const slot = args.context.isLeaf || hasSlot ? '' : '\n<router-slot></router-slot>';
|
|
65
|
+
return `${style}<mark-down>${escapeHtml(files.md)}</mark-down>${slot}`;
|
|
66
|
+
}
|
|
67
|
+
return args.context.isLeaf ? '' : '<router-slot></router-slot>';
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* Render page as Markdown.
|
|
71
|
+
*
|
|
72
|
+
* Fallback chain:
|
|
73
|
+
* 1. md file content from context
|
|
74
|
+
* 2. `` ```router-slot\n``` `` (slot placeholder in markdown — newline required)
|
|
75
|
+
*
|
|
76
|
+
* @example
|
|
77
|
+
* ```ts
|
|
78
|
+
* override renderMarkdown({ data, params, context }: this['RenderArgs']) {
|
|
79
|
+
* return `# ${params.id}\n\n${context?.files?.md ?? ''}`;
|
|
80
|
+
* }
|
|
81
|
+
* ```
|
|
82
|
+
*/
|
|
83
|
+
renderMarkdown(args) {
|
|
84
|
+
const files = args.context.files;
|
|
85
|
+
if (files?.md) {
|
|
86
|
+
return files.md;
|
|
87
|
+
}
|
|
88
|
+
return args.context.isLeaf ? '' : '```router-slot\n```';
|
|
89
|
+
}
|
|
90
|
+
/**
|
|
91
|
+
* Page title. Override in subclasses.
|
|
92
|
+
* Default: undefined (no title).
|
|
93
|
+
*
|
|
94
|
+
* @example
|
|
95
|
+
* ```ts
|
|
96
|
+
* override getTitle({ data, params }: this['RenderArgs']) {
|
|
97
|
+
* return `Project ${params.id}`;
|
|
98
|
+
* }
|
|
99
|
+
* ```
|
|
100
|
+
*/
|
|
101
|
+
getTitle(_args) {
|
|
102
|
+
return undefined;
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
/** Shared default instance used by renderers when no custom .page.ts exists. */
|
|
106
|
+
export default new PageComponent();
|
|
107
|
+
//# sourceMappingURL=page.component.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"page.component.js","sourceRoot":"","sources":["../../../src/component/page.component.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,EAAE,SAAS,EAAyB,MAAM,yBAAyB,CAAC;AAC3E,OAAO,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAC;AAElD,MAAM,OAAO,aAIX,SAAQ,SAAmC;IACzB,IAAI,GAAW,MAAM,CAAC;IAExC,qEAAqE;IAC5D,OAAO,CAAU;IAE1B;;;;;;;;;;OAUG;IACM,OAAO,CACd,KAAuB;QAEvB,OAAO,OAAO,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;IAC/B,CAAC;IAED;;;;;;;;;;;;;;OAcG;IACM,UAAU,CACjB,IAAwB;QAExB,MAAM,KAAK,GAAG,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC;QACjC,MAAM,KAAK,GAAG,KAAK,EAAE,GAAG,CAAC,CAAC,CAAC,UAAU,KAAK,CAAC,GAAG,YAAY,CAAC,CAAC,CAAC,EAAE,CAAC;QAEhE,IAAI,KAAK,EAAE,IAAI,EAAE,CAAC;YAChB,IAAI,IAAI,GAAG,KAAK,GAAG,KAAK,CAAC,IAAI,CAAC;YAC9B,IAAI,KAAK,CAAC,EAAE,IAAI,IAAI,CAAC,QAAQ,CAAC,yBAAyB,CAAC,EAAE,CAAC;gBACzD,IAAI,GAAG,IAAI,CAAC,OAAO,CACjB,yBAAyB,EACzB,cAAc,UAAU,CAAC,KAAK,CAAC,EAAE,CAAC,cAAc,CACjD,CAAC;YACJ,CAAC;YACD,OAAO,IAAI,CAAC;QACd,CAAC;QAED,IAAI,KAAK,EAAE,EAAE,EAAE,CAAC;YACd,wEAAwE;YACxE,uEAAuE;YACvE,wEAAwE;YACxE,yEAAyE;YACzE,qDAAqD;YACrD,yDAAyD;YACzD,MAAM,OAAO,GAAG,KAAK,CAAC,EAAE,CAAC,QAAQ,CAAC,gBAAgB,CAAC,CAAC;YACpD,MAAM,IAAI,GAAG,IAAI,CAAC,OAAO,CAAC,MAAM,IAAI,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,+BAA+B,CAAC;YACnF,OAAO,GAAG,KAAK,cAAc,UAAU,CAAC,KAAK,CAAC,EAAE,CAAC,eAAe,IAAI,EAAE,CAAC;QACzE,CAAC;QAED,OAAO,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,6BAA6B,CAAC;IAClE,CAAC;IAED;;;;;;;;;;;;;OAaG;IACM,cAAc,CACrB,IAAwB;QAExB,MAAM,KAAK,GAAG,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC;QAEjC,IAAI,KAAK,EAAE,EAAE,EAAE,CAAC;YACd,OAAO,KAAK,CAAC,EAAE,CAAC;QAClB,CAAC;QAED,OAAO,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,qBAAqB,CAAC;IAC1D,CAAC;IAED;;;;;;;;;;OAUG;IACH,QAAQ,CACN,KAAyB;QAEzB,OAAO,SAAS,CAAC;IACnB,CAAC;CACF;AAED,gFAAgF;AAChF,eAAe,IAAI,aAAa,EAAE,CAAC"}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* WidgetComponent — embeddable unit within page content.
|
|
3
|
+
*
|
|
4
|
+
* Everything reusable that is not a page is a Widget.
|
|
5
|
+
* Widgets render across all contexts (HTML, Markdown, SPA) and are
|
|
6
|
+
* resolved by name via WidgetRegistry.
|
|
7
|
+
*
|
|
8
|
+
* Pages live in the routes manifest. Widgets live in the registry.
|
|
9
|
+
*
|
|
10
|
+
* Default rendering fallback chains (parallel to PageComponent):
|
|
11
|
+
* - renderHTML: html file → md file in <mark-down> → base Component default
|
|
12
|
+
* - renderMarkdown: md file → ''
|
|
13
|
+
*/
|
|
14
|
+
import { Component, type ComponentContext } from './abstract.component.ts';
|
|
15
|
+
export declare abstract class WidgetComponent<TParams = unknown, TData = unknown, TContext extends ComponentContext = ComponentContext> extends Component<TParams, TData, TContext> {
|
|
16
|
+
/**
|
|
17
|
+
* Render widget as HTML.
|
|
18
|
+
*
|
|
19
|
+
* Fallback chain:
|
|
20
|
+
* 1. html file content from context
|
|
21
|
+
* 2. md file content wrapped in `<mark-down>`
|
|
22
|
+
* 3. base Component default (markdown→HTML conversion)
|
|
23
|
+
*
|
|
24
|
+
* @example
|
|
25
|
+
* ```ts
|
|
26
|
+
* override renderHTML({ data, params }: this['RenderArgs']) {
|
|
27
|
+
* return `<span>${params.coin}: $${data?.price}</span>`;
|
|
28
|
+
* }
|
|
29
|
+
* ```
|
|
30
|
+
*/
|
|
31
|
+
renderHTML(args: this['RenderArgs']): string;
|
|
32
|
+
/**
|
|
33
|
+
* Render widget as Markdown.
|
|
34
|
+
*
|
|
35
|
+
* Fallback chain:
|
|
36
|
+
* 1. md file content from context
|
|
37
|
+
* 2. empty string
|
|
38
|
+
*
|
|
39
|
+
* @example
|
|
40
|
+
* ```ts
|
|
41
|
+
* override renderMarkdown({ data, params }: this['RenderArgs']) {
|
|
42
|
+
* return `**${params.coin}**: $${data?.price}`;
|
|
43
|
+
* }
|
|
44
|
+
* ```
|
|
45
|
+
*/
|
|
46
|
+
renderMarkdown(args: this['RenderArgs']): string;
|
|
47
|
+
}
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* WidgetComponent — embeddable unit within page content.
|
|
3
|
+
*
|
|
4
|
+
* Everything reusable that is not a page is a Widget.
|
|
5
|
+
* Widgets render across all contexts (HTML, Markdown, SPA) and are
|
|
6
|
+
* resolved by name via WidgetRegistry.
|
|
7
|
+
*
|
|
8
|
+
* Pages live in the routes manifest. Widgets live in the registry.
|
|
9
|
+
*
|
|
10
|
+
* Default rendering fallback chains (parallel to PageComponent):
|
|
11
|
+
* - renderHTML: html file → md file in <mark-down> → base Component default
|
|
12
|
+
* - renderMarkdown: md file → ''
|
|
13
|
+
*/
|
|
14
|
+
import { Component } from "./abstract.component.js";
|
|
15
|
+
import { escapeHtml, scopeWidgetCss } from "../util/html.util.js";
|
|
16
|
+
export class WidgetComponent extends Component {
|
|
17
|
+
/**
|
|
18
|
+
* Render widget as HTML.
|
|
19
|
+
*
|
|
20
|
+
* Fallback chain:
|
|
21
|
+
* 1. html file content from context
|
|
22
|
+
* 2. md file content wrapped in `<mark-down>`
|
|
23
|
+
* 3. base Component default (markdown→HTML conversion)
|
|
24
|
+
*
|
|
25
|
+
* @example
|
|
26
|
+
* ```ts
|
|
27
|
+
* override renderHTML({ data, params }: this['RenderArgs']) {
|
|
28
|
+
* return `<span>${params.coin}: $${data?.price}</span>`;
|
|
29
|
+
* }
|
|
30
|
+
* ```
|
|
31
|
+
*/
|
|
32
|
+
renderHTML(args) {
|
|
33
|
+
const files = args.context.files;
|
|
34
|
+
// @scope needed for SSR Light DOM output; redundant but harmless in SPA Shadow DOM
|
|
35
|
+
const style = files?.css ? `<style>${scopeWidgetCss(files.css, this.name)}</style>\n` : '';
|
|
36
|
+
if (files?.html) {
|
|
37
|
+
return style + files.html;
|
|
38
|
+
}
|
|
39
|
+
if (files?.md) {
|
|
40
|
+
return `${style}<mark-down>${escapeHtml(files.md)}</mark-down>`;
|
|
41
|
+
}
|
|
42
|
+
if (style) {
|
|
43
|
+
return style + super.renderHTML(args);
|
|
44
|
+
}
|
|
45
|
+
return super.renderHTML(args);
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* Render widget as Markdown.
|
|
49
|
+
*
|
|
50
|
+
* Fallback chain:
|
|
51
|
+
* 1. md file content from context
|
|
52
|
+
* 2. empty string
|
|
53
|
+
*
|
|
54
|
+
* @example
|
|
55
|
+
* ```ts
|
|
56
|
+
* override renderMarkdown({ data, params }: this['RenderArgs']) {
|
|
57
|
+
* return `**${params.coin}**: $${data?.price}`;
|
|
58
|
+
* }
|
|
59
|
+
* ```
|
|
60
|
+
*/
|
|
61
|
+
renderMarkdown(args) {
|
|
62
|
+
const files = args.context.files;
|
|
63
|
+
if (files?.md) {
|
|
64
|
+
return files.md;
|
|
65
|
+
}
|
|
66
|
+
return '';
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
//# sourceMappingURL=widget.component.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"widget.component.js","sourceRoot":"","sources":["../../../src/component/widget.component.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,OAAO,EAAE,SAAS,EAAyB,MAAM,yBAAyB,CAAC;AAC3E,OAAO,EAAE,UAAU,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAElE,MAAM,OAAgB,eAIpB,SAAQ,SAAmC;IAC3C;;;;;;;;;;;;;;OAcG;IACM,UAAU,CACjB,IAAwB;QAExB,MAAM,KAAK,GAAG,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC;QACjC,mFAAmF;QACnF,MAAM,KAAK,GAAG,KAAK,EAAE,GAAG,CAAC,CAAC,CAAC,UAAU,cAAc,CAAC,KAAK,CAAC,GAAG,EAAE,IAAI,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC,CAAC,EAAE,CAAC;QAE3F,IAAI,KAAK,EAAE,IAAI,EAAE,CAAC;YAChB,OAAO,KAAK,GAAG,KAAK,CAAC,IAAI,CAAC;QAC5B,CAAC;QAED,IAAI,KAAK,EAAE,EAAE,EAAE,CAAC;YACd,OAAO,GAAG,KAAK,cAAc,UAAU,CAAC,KAAK,CAAC,EAAE,CAAC,cAAc,CAAC;QAClE,CAAC;QAED,IAAI,KAAK,EAAE,CAAC;YACV,OAAO,KAAK,GAAG,KAAK,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC;QACxC,CAAC;QAED,OAAO,KAAK,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC;IAChC,CAAC;IAED;;;;;;;;;;;;;OAaG;IACM,cAAc,CACrB,IAAwB;QAExB,MAAM,KAAK,GAAG,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC;QAEjC,IAAI,KAAK,EAAE,EAAE,EAAE,CAAC;YACd,OAAO,KAAK,CAAC,EAAE,CAAC;QAClB,CAAC;QAED,OAAO,EAAE,CAAC;IACZ,CAAC;CACF"}
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Widget Element - Browser Custom Element
|
|
3
|
+
*
|
|
4
|
+
* Renders Widget instances in the browser as `widget-{name}` elements.
|
|
5
|
+
* Handles:
|
|
6
|
+
* - SSR hydration (ssr attribute)
|
|
7
|
+
* - Client-side data fetching with AbortSignal
|
|
8
|
+
* - Companion file loading (html, md, css) with caching
|
|
9
|
+
* - Loading/error states
|
|
10
|
+
*/
|
|
11
|
+
import type { Component, ContextProvider } from '../component/abstract.component.ts';
|
|
12
|
+
import { HTMLElementBase } from '../util/html.util.ts';
|
|
13
|
+
type WidgetFiles = {
|
|
14
|
+
html?: string;
|
|
15
|
+
md?: string;
|
|
16
|
+
css?: string;
|
|
17
|
+
};
|
|
18
|
+
/**
|
|
19
|
+
* Custom element that renders a Component in the browser.
|
|
20
|
+
*/
|
|
21
|
+
export declare class ComponentElement<TParams, TData> extends HTMLElementBase {
|
|
22
|
+
/** Shared file content cache — deduplicates fetches across all widget instances. */
|
|
23
|
+
private static fileCache;
|
|
24
|
+
/** App-level context provider set once during router initialization. */
|
|
25
|
+
private static extendContext;
|
|
26
|
+
/** Register (or clear) the context provider that enriches every widget's ComponentContext. */
|
|
27
|
+
static setContextProvider(provider: ContextProvider | undefined): void;
|
|
28
|
+
private component;
|
|
29
|
+
private effectiveFiles?;
|
|
30
|
+
private params;
|
|
31
|
+
private data;
|
|
32
|
+
private context;
|
|
33
|
+
private state;
|
|
34
|
+
private errorMessage;
|
|
35
|
+
private deferred;
|
|
36
|
+
private abortController;
|
|
37
|
+
private intersectionObserver;
|
|
38
|
+
/** Promise that resolves with fetched data (available after loadData starts) */
|
|
39
|
+
dataPromise: Promise<TData | null> | null;
|
|
40
|
+
constructor(component: Component<TParams, TData>, files?: WidgetFiles);
|
|
41
|
+
/**
|
|
42
|
+
* Register a widget as a custom element: `widget-{name}`.
|
|
43
|
+
* Creates a fresh widget instance per DOM element (per-element state).
|
|
44
|
+
* Optional `files` parameter provides discovered file paths without mutating
|
|
45
|
+
* the component instance.
|
|
46
|
+
*/
|
|
47
|
+
static register<TP, TD>(component: Component<TP, TD>, files?: WidgetFiles): void;
|
|
48
|
+
/**
|
|
49
|
+
* Register a widget class (not instance) as a custom element: `widget-{name}`.
|
|
50
|
+
* Used for manifest-based registration where classes are loaded dynamically.
|
|
51
|
+
*/
|
|
52
|
+
static registerClass<TP, TD>(WidgetClass: new () => Component<TP, TD>, name: string, files?: WidgetFiles): void;
|
|
53
|
+
/**
|
|
54
|
+
* Promise that resolves when component is ready (data loaded and rendered).
|
|
55
|
+
* Used by router to wait for async components.
|
|
56
|
+
*/
|
|
57
|
+
get ready(): Promise<void>;
|
|
58
|
+
connectedCallback(): Promise<void>;
|
|
59
|
+
disconnectedCallback(): void;
|
|
60
|
+
/**
|
|
61
|
+
* Reload component data. Aborts any in-flight request first.
|
|
62
|
+
*/
|
|
63
|
+
reload(): Promise<void>;
|
|
64
|
+
/**
|
|
65
|
+
* Fetch a single file by path, with caching.
|
|
66
|
+
* Absolute URLs (http/https) pass through; relative paths get '/' prefix.
|
|
67
|
+
*/
|
|
68
|
+
private static loadFile;
|
|
69
|
+
/**
|
|
70
|
+
* Load all companion files for this widget instance.
|
|
71
|
+
* Uses effectiveFiles (from registration) falling back to component.files.
|
|
72
|
+
*/
|
|
73
|
+
private loadFiles;
|
|
74
|
+
private loadData;
|
|
75
|
+
private setError;
|
|
76
|
+
private signalReady;
|
|
77
|
+
private render;
|
|
78
|
+
}
|
|
79
|
+
export {};
|
|
@@ -0,0 +1,293 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Widget Element - Browser Custom Element
|
|
3
|
+
*
|
|
4
|
+
* Renders Widget instances in the browser as `widget-{name}` elements.
|
|
5
|
+
* Handles:
|
|
6
|
+
* - SSR hydration (ssr attribute)
|
|
7
|
+
* - Client-side data fetching with AbortSignal
|
|
8
|
+
* - Companion file loading (html, md, css) with caching
|
|
9
|
+
* - Loading/error states
|
|
10
|
+
*/
|
|
11
|
+
import { HTMLElementBase, LAZY_ATTR, SSR_ATTR } from "../util/html.util.js";
|
|
12
|
+
/**
|
|
13
|
+
* Custom element that renders a Component in the browser.
|
|
14
|
+
*/
|
|
15
|
+
export class ComponentElement extends HTMLElementBase {
|
|
16
|
+
/** Shared file content cache — deduplicates fetches across all widget instances. */
|
|
17
|
+
static fileCache = new Map();
|
|
18
|
+
/** App-level context provider set once during router initialization. */
|
|
19
|
+
static extendContext;
|
|
20
|
+
/** Register (or clear) the context provider that enriches every widget's ComponentContext. */
|
|
21
|
+
static setContextProvider(provider) {
|
|
22
|
+
ComponentElement.extendContext = provider;
|
|
23
|
+
}
|
|
24
|
+
component;
|
|
25
|
+
effectiveFiles;
|
|
26
|
+
params = null;
|
|
27
|
+
data = null;
|
|
28
|
+
context;
|
|
29
|
+
state = 'idle';
|
|
30
|
+
errorMessage = '';
|
|
31
|
+
deferred = null;
|
|
32
|
+
abortController = null;
|
|
33
|
+
intersectionObserver = null;
|
|
34
|
+
/** Promise that resolves with fetched data (available after loadData starts) */
|
|
35
|
+
dataPromise = null;
|
|
36
|
+
constructor(component, files) {
|
|
37
|
+
super();
|
|
38
|
+
this.component = component;
|
|
39
|
+
this.effectiveFiles = files;
|
|
40
|
+
// Attach shadow root if not already present (Declarative Shadow DOM creates it from <template shadowrootmode="open">)
|
|
41
|
+
// This enables progressive enhancement: SSR with DSD works without JS, then hydrates when JS loads
|
|
42
|
+
if (!this.shadowRoot) {
|
|
43
|
+
this.attachShadow({ mode: 'open' });
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* Register a widget as a custom element: `widget-{name}`.
|
|
48
|
+
* Creates a fresh widget instance per DOM element (per-element state).
|
|
49
|
+
* Optional `files` parameter provides discovered file paths without mutating
|
|
50
|
+
* the component instance.
|
|
51
|
+
*/
|
|
52
|
+
static register(component, files) {
|
|
53
|
+
const tagName = `widget-${component.name}`;
|
|
54
|
+
if (!globalThis.customElements || customElements.get(tagName)) {
|
|
55
|
+
return;
|
|
56
|
+
}
|
|
57
|
+
const WidgetClass = component.constructor;
|
|
58
|
+
const BoundElement = class extends ComponentElement {
|
|
59
|
+
constructor() {
|
|
60
|
+
super(new WidgetClass(), files);
|
|
61
|
+
}
|
|
62
|
+
};
|
|
63
|
+
customElements.define(tagName, BoundElement);
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* Register a widget class (not instance) as a custom element: `widget-{name}`.
|
|
67
|
+
* Used for manifest-based registration where classes are loaded dynamically.
|
|
68
|
+
*/
|
|
69
|
+
static registerClass(WidgetClass, name, files) {
|
|
70
|
+
const tagName = `widget-${name}`;
|
|
71
|
+
if (!globalThis.customElements || customElements.get(tagName)) {
|
|
72
|
+
return;
|
|
73
|
+
}
|
|
74
|
+
const BoundElement = class extends ComponentElement {
|
|
75
|
+
constructor() {
|
|
76
|
+
super(new WidgetClass(), files);
|
|
77
|
+
}
|
|
78
|
+
};
|
|
79
|
+
customElements.define(tagName, BoundElement);
|
|
80
|
+
}
|
|
81
|
+
/**
|
|
82
|
+
* Promise that resolves when component is ready (data loaded and rendered).
|
|
83
|
+
* Used by router to wait for async components.
|
|
84
|
+
*/
|
|
85
|
+
get ready() {
|
|
86
|
+
if (this.state === 'ready') {
|
|
87
|
+
return Promise.resolve();
|
|
88
|
+
}
|
|
89
|
+
this.deferred ??= Promise.withResolvers();
|
|
90
|
+
return this.deferred.promise;
|
|
91
|
+
}
|
|
92
|
+
async connectedCallback() {
|
|
93
|
+
this.component.element = this;
|
|
94
|
+
this.style.contentVisibility = 'auto';
|
|
95
|
+
this.abortController = new AbortController();
|
|
96
|
+
const signal = this.abortController.signal;
|
|
97
|
+
// Parse params from element attributes
|
|
98
|
+
const params = {};
|
|
99
|
+
for (const attr of this.attributes) {
|
|
100
|
+
if (attr.name === SSR_ATTR || attr.name === LAZY_ATTR)
|
|
101
|
+
continue;
|
|
102
|
+
const key = attr.name.replace(/-([a-z])/g, (_, c) => c.toUpperCase());
|
|
103
|
+
try {
|
|
104
|
+
params[key] = JSON.parse(attr.value);
|
|
105
|
+
}
|
|
106
|
+
catch {
|
|
107
|
+
params[key] = attr.value;
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
this.params = params;
|
|
111
|
+
// Validate params
|
|
112
|
+
if (this.component.validateParams && this.params !== null) {
|
|
113
|
+
const error = this.component.validateParams(this.params);
|
|
114
|
+
if (error) {
|
|
115
|
+
this.setError(error);
|
|
116
|
+
return;
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
// Load companion files (html, md, css) if declared
|
|
120
|
+
const files = await this.loadFiles();
|
|
121
|
+
if (signal.aborted)
|
|
122
|
+
return;
|
|
123
|
+
const base = {
|
|
124
|
+
pathname: globalThis.location?.pathname ?? '/',
|
|
125
|
+
pattern: '',
|
|
126
|
+
params: {},
|
|
127
|
+
searchParams: new URLSearchParams(globalThis.location?.search ?? ''),
|
|
128
|
+
files: (files.html || files.md || files.css) ? files : undefined,
|
|
129
|
+
};
|
|
130
|
+
this.context = ComponentElement.extendContext ? ComponentElement.extendContext(base) : base;
|
|
131
|
+
// Hydrate from SSR: adopt content from Declarative Shadow DOM
|
|
132
|
+
if (this.hasAttribute(SSR_ATTR)) {
|
|
133
|
+
this.removeAttribute(SSR_ATTR);
|
|
134
|
+
// Read SSR data from light DOM (JSON text placed alongside shadow root)
|
|
135
|
+
const lightText = this.textContent?.trim();
|
|
136
|
+
if (lightText) {
|
|
137
|
+
try {
|
|
138
|
+
this.data = JSON.parse(lightText);
|
|
139
|
+
}
|
|
140
|
+
catch {
|
|
141
|
+
// Not valid JSON — proceed with data: null
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
// Clear light DOM content (JSON text)
|
|
145
|
+
this.textContent = '';
|
|
146
|
+
this.state = 'ready';
|
|
147
|
+
// Call hydrate() hook to attach event listeners
|
|
148
|
+
if (this.component.hydrate) {
|
|
149
|
+
const args = { data: this.data, params: this.params, context: this.context };
|
|
150
|
+
queueMicrotask(() => {
|
|
151
|
+
this.component.hydrate(args);
|
|
152
|
+
});
|
|
153
|
+
}
|
|
154
|
+
this.signalReady();
|
|
155
|
+
return;
|
|
156
|
+
}
|
|
157
|
+
// Lazy: defer loadData until element is visible
|
|
158
|
+
if (this.hasAttribute(LAZY_ATTR)) {
|
|
159
|
+
this.intersectionObserver = new IntersectionObserver(([entry]) => {
|
|
160
|
+
if (entry.isIntersecting) {
|
|
161
|
+
this.intersectionObserver?.disconnect();
|
|
162
|
+
this.intersectionObserver = null;
|
|
163
|
+
this.loadData();
|
|
164
|
+
}
|
|
165
|
+
});
|
|
166
|
+
this.intersectionObserver.observe(this);
|
|
167
|
+
return;
|
|
168
|
+
}
|
|
169
|
+
await this.loadData();
|
|
170
|
+
}
|
|
171
|
+
disconnectedCallback() {
|
|
172
|
+
this.component.destroy?.();
|
|
173
|
+
this.component.element = undefined;
|
|
174
|
+
this.intersectionObserver?.disconnect();
|
|
175
|
+
this.intersectionObserver = null;
|
|
176
|
+
this.abortController?.abort();
|
|
177
|
+
this.abortController = null;
|
|
178
|
+
this.state = 'idle';
|
|
179
|
+
this.data = null;
|
|
180
|
+
this.context = undefined;
|
|
181
|
+
this.dataPromise = null;
|
|
182
|
+
this.errorMessage = '';
|
|
183
|
+
this.signalReady();
|
|
184
|
+
this.deferred = null;
|
|
185
|
+
}
|
|
186
|
+
/**
|
|
187
|
+
* Reload component data. Aborts any in-flight request first.
|
|
188
|
+
*/
|
|
189
|
+
async reload() {
|
|
190
|
+
if (this.params === null)
|
|
191
|
+
return;
|
|
192
|
+
// Abort previous and create fresh controller
|
|
193
|
+
this.abortController?.abort();
|
|
194
|
+
this.abortController = new AbortController();
|
|
195
|
+
await this.loadData();
|
|
196
|
+
}
|
|
197
|
+
/**
|
|
198
|
+
* Fetch a single file by path, with caching.
|
|
199
|
+
* Absolute URLs (http/https) pass through; relative paths get '/' prefix.
|
|
200
|
+
*/
|
|
201
|
+
static loadFile(path) {
|
|
202
|
+
const cached = ComponentElement.fileCache.get(path);
|
|
203
|
+
if (cached)
|
|
204
|
+
return cached;
|
|
205
|
+
const url = path.startsWith('http://') || path.startsWith('https://')
|
|
206
|
+
? path
|
|
207
|
+
: (path.startsWith('/') ? path : '/' + path);
|
|
208
|
+
const promise = fetch(url).then((res) => res.ok ? res.text() : undefined, () => undefined);
|
|
209
|
+
ComponentElement.fileCache.set(path, promise);
|
|
210
|
+
return promise;
|
|
211
|
+
}
|
|
212
|
+
/**
|
|
213
|
+
* Load all companion files for this widget instance.
|
|
214
|
+
* Uses effectiveFiles (from registration) falling back to component.files.
|
|
215
|
+
*/
|
|
216
|
+
async loadFiles() {
|
|
217
|
+
const filePaths = this.effectiveFiles ?? this.component.files;
|
|
218
|
+
if (!filePaths)
|
|
219
|
+
return {};
|
|
220
|
+
const [html, md, css] = await Promise.all([
|
|
221
|
+
filePaths.html ? ComponentElement.loadFile(filePaths.html) : undefined,
|
|
222
|
+
filePaths.md ? ComponentElement.loadFile(filePaths.md) : undefined,
|
|
223
|
+
filePaths.css ? ComponentElement.loadFile(filePaths.css) : undefined,
|
|
224
|
+
]);
|
|
225
|
+
return { html, md, css };
|
|
226
|
+
}
|
|
227
|
+
async loadData() {
|
|
228
|
+
if (this.params === null)
|
|
229
|
+
return;
|
|
230
|
+
const signal = this.abortController?.signal;
|
|
231
|
+
this.state = 'loading';
|
|
232
|
+
this.render();
|
|
233
|
+
try {
|
|
234
|
+
const promise = this.component.getData({
|
|
235
|
+
params: this.params,
|
|
236
|
+
signal,
|
|
237
|
+
context: this.context,
|
|
238
|
+
});
|
|
239
|
+
this.dataPromise = promise;
|
|
240
|
+
this.data = await promise;
|
|
241
|
+
// Check abort after await — don't touch DOM if disconnected
|
|
242
|
+
if (signal?.aborted)
|
|
243
|
+
return;
|
|
244
|
+
this.state = 'ready';
|
|
245
|
+
}
|
|
246
|
+
catch (e) {
|
|
247
|
+
if (e instanceof DOMException && e.name === 'AbortError')
|
|
248
|
+
return;
|
|
249
|
+
if (signal?.aborted)
|
|
250
|
+
return;
|
|
251
|
+
this.setError(e instanceof Error ? e.message : String(e));
|
|
252
|
+
return;
|
|
253
|
+
}
|
|
254
|
+
this.render();
|
|
255
|
+
this.signalReady();
|
|
256
|
+
}
|
|
257
|
+
setError(message) {
|
|
258
|
+
this.state = 'error';
|
|
259
|
+
this.errorMessage = message;
|
|
260
|
+
this.render();
|
|
261
|
+
this.signalReady(); // Ready even on error (completed loading)
|
|
262
|
+
}
|
|
263
|
+
signalReady() {
|
|
264
|
+
this.deferred?.resolve();
|
|
265
|
+
this.deferred = null;
|
|
266
|
+
}
|
|
267
|
+
render() {
|
|
268
|
+
if (this.params === null) {
|
|
269
|
+
this.shadowRoot.setHTMLUnsafe('');
|
|
270
|
+
return;
|
|
271
|
+
}
|
|
272
|
+
if (this.state === 'error') {
|
|
273
|
+
this.shadowRoot.setHTMLUnsafe(this.component.renderError({
|
|
274
|
+
error: new Error(this.errorMessage),
|
|
275
|
+
params: this.params,
|
|
276
|
+
}));
|
|
277
|
+
return;
|
|
278
|
+
}
|
|
279
|
+
this.shadowRoot.setHTMLUnsafe(this.component.renderHTML({
|
|
280
|
+
data: this.state === 'ready' ? this.data : null,
|
|
281
|
+
params: this.params,
|
|
282
|
+
context: this.context,
|
|
283
|
+
}));
|
|
284
|
+
// Call hydrate() after rendering to attach event listeners
|
|
285
|
+
if (this.state === 'ready' && this.component.hydrate) {
|
|
286
|
+
const args = { data: this.data, params: this.params, context: this.context };
|
|
287
|
+
queueMicrotask(() => {
|
|
288
|
+
this.component.hydrate(args);
|
|
289
|
+
});
|
|
290
|
+
}
|
|
291
|
+
}
|
|
292
|
+
}
|
|
293
|
+
//# sourceMappingURL=component.element.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"component.element.js","sourceRoot":"","sources":["../../../src/element/component.element.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Markdown Element — <mark-down> custom element.
|
|
3
|
+
*
|
|
4
|
+
* Renders markdown content with pluggable renderer.
|
|
5
|
+
* Supports:
|
|
6
|
+
* - Inline content: <mark-down># Title</mark-down>
|
|
7
|
+
* - Source attribute: <mark-down src="/path/to.md"></mark-down>
|
|
8
|
+
*/
|
|
9
|
+
import { HTMLElementBase } from '../util/html.util.ts';
|
|
10
|
+
import type { MarkdownRenderer } from '../type/markdown.type.ts';
|
|
11
|
+
export declare class MarkdownElement extends HTMLElementBase {
|
|
12
|
+
private static renderer;
|
|
13
|
+
private static rendererInitPromise;
|
|
14
|
+
private abortController;
|
|
15
|
+
/**
|
|
16
|
+
* Set the markdown renderer.
|
|
17
|
+
* Must be called before any <mark-down> elements are connected.
|
|
18
|
+
*
|
|
19
|
+
* @example
|
|
20
|
+
* ```ts
|
|
21
|
+
* import { createEmkoRenderer } from './emko.renderer.ts';
|
|
22
|
+
* MarkdownElement.setRenderer(await createEmkoRenderer());
|
|
23
|
+
* ```
|
|
24
|
+
*/
|
|
25
|
+
static setRenderer(renderer: MarkdownRenderer): void;
|
|
26
|
+
/**
|
|
27
|
+
* Get the current renderer, waiting for init if needed.
|
|
28
|
+
*/
|
|
29
|
+
private static getRenderer;
|
|
30
|
+
connectedCallback(): Promise<void>;
|
|
31
|
+
disconnectedCallback(): void;
|
|
32
|
+
private loadContent;
|
|
33
|
+
private loadFromSrc;
|
|
34
|
+
private renderContent;
|
|
35
|
+
private showError;
|
|
36
|
+
}
|