@emkodev/emroute 1.7.3 → 1.8.0-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/component/abstract.component.ts +74 -0
- package/{src → core}/component/page.component.ts +3 -61
- package/core/component/widget.component.ts +54 -0
- package/core/pipeline/pipeline.ts +224 -0
- package/{src/renderer/ssr → core/renderer}/html.renderer.ts +26 -47
- package/{src/renderer/ssr → core/renderer}/md.renderer.ts +22 -41
- package/{src/renderer/ssr → core/renderer}/ssr.renderer.ts +44 -58
- package/{src/route → core/router}/route.resolver.ts +1 -10
- package/core/router/route.trie.ts +175 -0
- package/core/runtime/abstract.runtime.ts +47 -0
- package/core/server/emroute.server.ts +324 -0
- package/core/type/component.type.ts +39 -0
- package/core/type/element.type.ts +10 -0
- package/core/type/logger.type.ts +20 -0
- package/core/type/markdown.type.ts +8 -0
- package/core/type/route-tree.type.ts +28 -0
- package/core/type/route.type.ts +75 -0
- package/core/type/widget.type.ts +27 -0
- package/core/util/html.util.ts +50 -0
- package/{src → core}/util/md.util.ts +3 -5
- package/{src/route → core/util}/route-tree.util.ts +0 -2
- package/{src → core}/util/widget-resolve.util.ts +15 -46
- package/{src → core}/widget/widget.parser.ts +2 -23
- package/core/widget/widget.registry.ts +36 -0
- package/dist/core/component/abstract.component.d.ts +48 -0
- package/dist/core/component/abstract.component.js +42 -0
- package/dist/core/component/abstract.component.js.map +1 -0
- package/dist/core/component/page.component.d.ts +23 -0
- package/dist/core/component/page.component.js +49 -0
- package/dist/core/component/page.component.js.map +1 -0
- package/dist/core/component/widget.component.d.ts +17 -0
- package/dist/core/component/widget.component.js +37 -0
- package/dist/core/component/widget.component.js.map +1 -0
- package/dist/core/pipeline/pipeline.d.ts +61 -0
- package/dist/core/pipeline/pipeline.js +189 -0
- package/dist/core/pipeline/pipeline.js.map +1 -0
- package/dist/{src/renderer/ssr → core/renderer}/html.renderer.d.ts +8 -24
- package/dist/{src/renderer/ssr → core/renderer}/html.renderer.js +20 -35
- package/dist/core/renderer/html.renderer.js.map +1 -0
- package/dist/{src/renderer/ssr → core/renderer}/md.renderer.d.ts +6 -21
- package/dist/{src/renderer/ssr → core/renderer}/md.renderer.js +16 -32
- package/dist/core/renderer/md.renderer.js.map +1 -0
- package/dist/{src/renderer/ssr → core/renderer}/ssr.renderer.d.ts +11 -27
- package/dist/{src/renderer/ssr → core/renderer}/ssr.renderer.js +33 -37
- package/dist/core/renderer/ssr.renderer.js.map +1 -0
- package/dist/{src/route → core/router}/route.resolver.d.ts +1 -8
- package/dist/{src/route → core/router}/route.resolver.js +0 -1
- package/dist/core/router/route.resolver.js.map +1 -0
- package/dist/core/router/route.trie.d.ts +32 -0
- package/dist/core/router/route.trie.js +152 -0
- package/dist/core/router/route.trie.js.map +1 -0
- package/dist/core/runtime/abstract.runtime.d.ts +32 -0
- package/dist/core/runtime/abstract.runtime.js +26 -0
- package/dist/core/runtime/abstract.runtime.js.map +1 -0
- package/dist/core/server/emroute.server.d.ts +48 -0
- package/dist/core/server/emroute.server.js +239 -0
- package/dist/core/server/emroute.server.js.map +1 -0
- package/dist/core/server/server.type.d.ts +45 -0
- package/dist/core/server/server.type.js +11 -0
- package/dist/core/server/server.type.js.map +1 -0
- package/dist/core/type/component.type.d.ts +37 -0
- package/dist/core/type/component.type.js +7 -0
- package/dist/core/type/component.type.js.map +1 -0
- package/dist/core/type/element.type.d.ts +9 -0
- package/dist/core/type/element.type.js +5 -0
- package/dist/core/type/element.type.js.map +1 -0
- package/dist/core/type/logger.type.d.ts +14 -0
- package/dist/core/type/logger.type.js +8 -0
- package/dist/core/type/logger.type.js.map +1 -0
- package/dist/core/type/markdown.type.d.ts +7 -0
- package/dist/core/type/markdown.type.js +5 -0
- package/dist/core/type/markdown.type.js.map +1 -0
- package/dist/{src → core}/type/route-tree.type.d.ts +0 -12
- package/dist/{src → core}/type/route-tree.type.js +0 -1
- package/dist/core/type/route-tree.type.js.map +1 -0
- package/dist/core/type/route.type.d.ts +62 -0
- package/dist/core/type/route.type.js +7 -0
- package/dist/core/type/route.type.js.map +1 -0
- package/dist/core/type/widget.type.d.ts +27 -0
- package/dist/core/type/widget.type.js +5 -0
- package/dist/core/type/widget.type.js.map +1 -0
- package/dist/core/util/html.util.d.ts +14 -0
- package/dist/core/util/html.util.js +43 -0
- package/dist/core/util/html.util.js.map +1 -0
- package/dist/{src → core}/util/md.util.d.ts +0 -1
- package/dist/{src → core}/util/md.util.js +0 -2
- package/dist/core/util/md.util.js.map +1 -0
- package/dist/{src/route → core/util}/route-tree.util.js +0 -2
- package/dist/core/util/route-tree.util.js.map +1 -0
- package/dist/core/util/widget-resolve.util.d.ts +28 -0
- package/dist/{src → core}/util/widget-resolve.util.js +12 -42
- package/dist/core/util/widget-resolve.util.js.map +1 -0
- package/dist/{src → core}/widget/widget.parser.d.ts +0 -13
- package/dist/{src → core}/widget/widget.parser.js +1 -22
- package/dist/core/widget/widget.parser.js.map +1 -0
- package/dist/core/widget/widget.registry.d.ts +14 -0
- package/dist/core/widget/widget.registry.js +26 -0
- package/dist/core/widget/widget.registry.js.map +1 -0
- package/dist/emroute.js +1092 -1220
- package/dist/emroute.js.map +36 -5
- package/dist/runtime/abstract.runtime.d.ts +41 -7
- package/dist/runtime/abstract.runtime.js +404 -9
- package/dist/runtime/abstract.runtime.js.map +1 -1
- package/dist/runtime/bun/fs/bun-fs.runtime.d.ts +1 -0
- package/dist/runtime/bun/fs/bun-fs.runtime.js +15 -1
- package/dist/runtime/bun/fs/bun-fs.runtime.js.map +1 -1
- package/dist/runtime/bun/sqlite/bun-sqlite.runtime.d.ts +2 -0
- package/dist/runtime/bun/sqlite/bun-sqlite.runtime.js +8 -0
- package/dist/runtime/bun/sqlite/bun-sqlite.runtime.js.map +1 -1
- package/dist/runtime/fetch.runtime.d.ts +3 -3
- package/dist/runtime/fetch.runtime.js +3 -3
- package/dist/runtime/sitemap.generator.d.ts +1 -1
- package/dist/runtime/sitemap.generator.js +1 -1
- package/dist/runtime/sitemap.generator.js.map +1 -1
- package/dist/runtime/universal/fs/universal-fs.runtime.d.ts +1 -0
- package/dist/runtime/universal/fs/universal-fs.runtime.js +15 -1
- package/dist/runtime/universal/fs/universal-fs.runtime.js.map +1 -1
- package/dist/server/build.util.d.ts +9 -10
- package/dist/server/build.util.js +11 -31
- package/dist/server/build.util.js.map +1 -1
- package/dist/server/codegen.util.d.ts +1 -1
- package/dist/server/emroute.server.d.ts +8 -35
- package/dist/server/emroute.server.js +7 -351
- package/dist/server/emroute.server.js.map +1 -1
- package/dist/server/esbuild-manifest.plugin.js +1 -1
- package/dist/server/esbuild-manifest.plugin.js.map +1 -1
- package/dist/server/server-api.type.d.ts +3 -71
- package/dist/server/server-api.type.js +1 -8
- package/dist/server/server-api.type.js.map +1 -1
- package/dist/src/element/component.element.d.ts +6 -14
- package/dist/src/element/component.element.js +13 -40
- package/dist/src/element/component.element.js.map +1 -1
- package/dist/src/element/markdown.element.d.ts +2 -2
- package/dist/src/element/markdown.element.js +3 -2
- package/dist/src/element/markdown.element.js.map +1 -1
- package/dist/src/index.d.ts +15 -14
- package/dist/src/index.js +8 -8
- package/dist/src/index.js.map +1 -1
- package/dist/src/renderer/spa/emroute.app.d.ts +50 -0
- package/dist/src/renderer/spa/emroute.app.js +246 -0
- package/dist/src/renderer/spa/emroute.app.js.map +1 -0
- package/dist/src/renderer/spa/mod.d.ts +17 -16
- package/dist/src/renderer/spa/mod.js +9 -9
- package/dist/src/renderer/spa/mod.js.map +1 -1
- package/dist/src/renderer/spa/thin-client.d.ts +3 -3
- package/dist/src/renderer/spa/thin-client.js +7 -7
- package/dist/src/renderer/spa/thin-client.js.map +1 -1
- package/dist/src/route/route.core.d.ts +3 -3
- package/dist/src/util/html.util.d.ts +5 -22
- package/dist/src/util/html.util.js +8 -56
- package/dist/src/util/html.util.js.map +1 -1
- package/dist/src/widget/breadcrumb.widget.d.ts +2 -2
- package/dist/src/widget/breadcrumb.widget.js +2 -2
- package/dist/src/widget/breadcrumb.widget.js.map +1 -1
- package/dist/src/widget/page-title.widget.d.ts +1 -1
- package/dist/src/widget/page-title.widget.js +1 -1
- package/dist/src/widget/page-title.widget.js.map +1 -1
- package/package.json +8 -8
- package/runtime/abstract.runtime.ts +433 -17
- package/runtime/bun/fs/bun-fs.runtime.ts +15 -1
- package/runtime/bun/sqlite/bun-sqlite.runtime.ts +9 -0
- package/runtime/fetch.runtime.ts +3 -3
- package/runtime/sitemap.generator.ts +2 -2
- package/runtime/universal/fs/universal-fs.runtime.ts +15 -1
- package/server/build.util.ts +17 -43
- package/server/codegen.util.ts +1 -1
- package/server/emroute.server.ts +12 -426
- package/src/element/component.element.ts +14 -54
- package/src/element/markdown.element.ts +4 -3
- package/src/index.ts +22 -19
- package/src/renderer/spa/{thin-client.ts → emroute.app.ts} +19 -20
- package/src/renderer/spa/mod.ts +22 -22
- package/src/util/html.util.ts +16 -61
- package/src/widget/breadcrumb.widget.ts +3 -3
- package/src/widget/page-title.widget.ts +1 -1
- package/dist/src/component/abstract.component.d.ts +0 -199
- package/dist/src/component/abstract.component.js +0 -84
- package/dist/src/component/abstract.component.js.map +0 -1
- package/dist/src/component/page.component.d.ts +0 -74
- package/dist/src/component/page.component.js +0 -107
- package/dist/src/component/page.component.js.map +0 -1
- package/dist/src/component/widget.component.d.ts +0 -47
- package/dist/src/component/widget.component.js +0 -69
- package/dist/src/component/widget.component.js.map +0 -1
- package/dist/src/renderer/ssr/html.renderer.js.map +0 -1
- package/dist/src/renderer/ssr/md.renderer.js.map +0 -1
- package/dist/src/renderer/ssr/ssr.renderer.js.map +0 -1
- package/dist/src/route/route-tree.util.js.map +0 -1
- package/dist/src/route/route.matcher.d.ts +0 -86
- package/dist/src/route/route.matcher.js +0 -214
- package/dist/src/route/route.matcher.js.map +0 -1
- package/dist/src/route/route.resolver.js.map +0 -1
- package/dist/src/route/route.trie.d.ts +0 -38
- package/dist/src/route/route.trie.js +0 -206
- package/dist/src/route/route.trie.js.map +0 -1
- package/dist/src/type/element.type.d.ts +0 -19
- package/dist/src/type/element.type.js +0 -9
- package/dist/src/type/element.type.js.map +0 -1
- package/dist/src/type/logger.type.d.ts +0 -17
- package/dist/src/type/logger.type.js +0 -9
- package/dist/src/type/logger.type.js.map +0 -1
- package/dist/src/type/markdown.type.d.ts +0 -20
- package/dist/src/type/markdown.type.js +0 -2
- package/dist/src/type/markdown.type.js.map +0 -1
- package/dist/src/type/route-tree.type.js.map +0 -1
- package/dist/src/type/route.type.d.ts +0 -94
- package/dist/src/type/route.type.js +0 -8
- package/dist/src/type/route.type.js.map +0 -1
- package/dist/src/type/widget.type.d.ts +0 -55
- package/dist/src/type/widget.type.js +0 -10
- package/dist/src/type/widget.type.js.map +0 -1
- package/dist/src/util/logger.util.d.ts +0 -26
- package/dist/src/util/logger.util.js +0 -80
- package/dist/src/util/logger.util.js.map +0 -1
- package/dist/src/util/md.util.js.map +0 -1
- package/dist/src/util/widget-resolve.util.d.ts +0 -52
- package/dist/src/util/widget-resolve.util.js.map +0 -1
- package/dist/src/widget/widget.parser.js.map +0 -1
- package/dist/src/widget/widget.registry.d.ts +0 -23
- package/dist/src/widget/widget.registry.js +0 -42
- package/dist/src/widget/widget.registry.js.map +0 -1
- package/runtime/bun/esbuild-runtime-loader.plugin.ts +0 -112
- package/server/esbuild-manifest.plugin.ts +0 -209
- package/server/server-api.type.ts +0 -101
- package/src/component/abstract.component.ts +0 -231
- package/src/component/widget.component.ts +0 -85
- package/src/route/route.core.ts +0 -371
- package/src/route/route.trie.ts +0 -265
- package/src/type/element.type.ts +0 -22
- package/src/type/logger.type.ts +0 -24
- package/src/type/markdown.type.ts +0 -21
- package/src/type/route-tree.type.ts +0 -51
- package/src/type/route.type.ts +0 -124
- package/src/type/widget.type.ts +0 -65
- package/src/util/logger.util.ts +0 -83
- package/src/widget/widget.registry.ts +0 -51
- /package/dist/{src/route → core/util}/route-tree.util.d.ts +0 -0
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Pure HTML utilities. No DOM, no browser APIs.
|
|
3
|
+
*/
|
|
4
|
+
/** HTML attribute name marking a widget as server-rendered. */
|
|
5
|
+
export const SSR_ATTR = 'ssr';
|
|
6
|
+
/** HTML attribute name for lazy-loading widgets. */
|
|
7
|
+
export const LAZY_ATTR = 'lazy';
|
|
8
|
+
const BLOCKED_PROTOCOLS = /^(javascript|data|vbscript):/i;
|
|
9
|
+
/** Throw if a redirect URL uses a dangerous protocol. */
|
|
10
|
+
export function assertSafeRedirect(url) {
|
|
11
|
+
if (BLOCKED_PROTOCOLS.test(url.trim())) {
|
|
12
|
+
throw new Error(`Unsafe redirect URL blocked: ${url}`);
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
export function escapeHtml(text) {
|
|
16
|
+
return text
|
|
17
|
+
.replaceAll('&', '&')
|
|
18
|
+
.replaceAll('<', '<')
|
|
19
|
+
.replaceAll('>', '>')
|
|
20
|
+
.replaceAll('"', '"')
|
|
21
|
+
.replaceAll("'", ''')
|
|
22
|
+
.replaceAll('`', '`');
|
|
23
|
+
}
|
|
24
|
+
export function unescapeHtml(text) {
|
|
25
|
+
return text
|
|
26
|
+
.replaceAll('`', '`')
|
|
27
|
+
.replaceAll(''', "'")
|
|
28
|
+
.replaceAll('"', '"')
|
|
29
|
+
.replaceAll('>', '>')
|
|
30
|
+
.replaceAll('<', '<')
|
|
31
|
+
.replaceAll('&', '&');
|
|
32
|
+
}
|
|
33
|
+
export function scopeWidgetCss(css, widgetName) {
|
|
34
|
+
return `@scope (widget-${widgetName}) {\n${css}\n}`;
|
|
35
|
+
}
|
|
36
|
+
/** Status code to message mapping. */
|
|
37
|
+
export const STATUS_MESSAGES = {
|
|
38
|
+
401: 'Unauthorized',
|
|
39
|
+
403: 'Forbidden',
|
|
40
|
+
404: 'Not Found',
|
|
41
|
+
500: 'Internal Server Error',
|
|
42
|
+
};
|
|
43
|
+
//# sourceMappingURL=html.util.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"html.util.js","sourceRoot":"","sources":["../../../core/util/html.util.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,+DAA+D;AAC/D,MAAM,CAAC,MAAM,QAAQ,GAAG,KAAK,CAAC;AAE9B,oDAAoD;AACpD,MAAM,CAAC,MAAM,SAAS,GAAG,MAAM,CAAC;AAEhC,MAAM,iBAAiB,GAAG,+BAA+B,CAAC;AAE1D,yDAAyD;AACzD,MAAM,UAAU,kBAAkB,CAAC,GAAW;IAC5C,IAAI,iBAAiB,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,EAAE,CAAC,EAAE,CAAC;QACvC,MAAM,IAAI,KAAK,CAAC,gCAAgC,GAAG,EAAE,CAAC,CAAC;IACzD,CAAC;AACH,CAAC;AAED,MAAM,UAAU,UAAU,CAAC,IAAY;IACrC,OAAO,IAAI;SACR,UAAU,CAAC,GAAG,EAAE,OAAO,CAAC;SACxB,UAAU,CAAC,GAAG,EAAE,MAAM,CAAC;SACvB,UAAU,CAAC,GAAG,EAAE,MAAM,CAAC;SACvB,UAAU,CAAC,GAAG,EAAE,QAAQ,CAAC;SACzB,UAAU,CAAC,GAAG,EAAE,OAAO,CAAC;SACxB,UAAU,CAAC,GAAG,EAAE,OAAO,CAAC,CAAC;AAC9B,CAAC;AAED,MAAM,UAAU,YAAY,CAAC,IAAY;IACvC,OAAO,IAAI;SACR,UAAU,CAAC,OAAO,EAAE,GAAG,CAAC;SACxB,UAAU,CAAC,OAAO,EAAE,GAAG,CAAC;SACxB,UAAU,CAAC,QAAQ,EAAE,GAAG,CAAC;SACzB,UAAU,CAAC,MAAM,EAAE,GAAG,CAAC;SACvB,UAAU,CAAC,MAAM,EAAE,GAAG,CAAC;SACvB,UAAU,CAAC,OAAO,EAAE,GAAG,CAAC,CAAC;AAC9B,CAAC;AAED,MAAM,UAAU,cAAc,CAAC,GAAW,EAAE,UAAkB;IAC5D,OAAO,kBAAkB,UAAU,QAAQ,GAAG,KAAK,CAAC;AACtD,CAAC;AAED,sCAAsC;AACtC,MAAM,CAAC,MAAM,eAAe,GAA2B;IACrD,GAAG,EAAE,cAAc;IACnB,GAAG,EAAE,WAAW;IAChB,GAAG,EAAE,WAAW;IAChB,GAAG,EAAE,uBAAuB;CAC7B,CAAC"}
|
|
@@ -4,5 +4,4 @@
|
|
|
4
4
|
* Rewrites internal absolute links in markdown to include a base path prefix.
|
|
5
5
|
* Skips fenced code blocks and links already under a known base path.
|
|
6
6
|
*/
|
|
7
|
-
/** Rewrite internal absolute links in markdown to include the base path prefix. */
|
|
8
7
|
export declare function rewriteMdLinks(markdown: string, base: string, skipPrefixes: string[]): string;
|
|
@@ -4,10 +4,8 @@
|
|
|
4
4
|
* Rewrites internal absolute links in markdown to include a base path prefix.
|
|
5
5
|
* Skips fenced code blocks and links already under a known base path.
|
|
6
6
|
*/
|
|
7
|
-
/** Rewrite internal absolute links in markdown to include the base path prefix. */
|
|
8
7
|
export function rewriteMdLinks(markdown, base, skipPrefixes) {
|
|
9
8
|
const prefix = base + '/';
|
|
10
|
-
// Negative lookahead: skip links already under a known base path
|
|
11
9
|
const skip = skipPrefixes.map((p) => p.slice(1) + '/').join('|');
|
|
12
10
|
const inlineRe = new RegExp(`\\]\\(\\/(?!${skip})`, 'g');
|
|
13
11
|
const refRe = new RegExp(`^(\\[[^\\]]+\\]:\\s+)\\/(?!${skip})`, 'g');
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"md.util.js","sourceRoot":"","sources":["../../../core/util/md.util.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,MAAM,UAAU,cAAc,CAAC,QAAgB,EAAE,IAAY,EAAE,YAAsB;IACnF,MAAM,MAAM,GAAG,IAAI,GAAG,GAAG,CAAC;IAC1B,MAAM,IAAI,GAAG,YAAY,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,GAAG,GAAG,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IACjE,MAAM,QAAQ,GAAG,IAAI,MAAM,CAAC,eAAe,IAAI,GAAG,EAAE,GAAG,CAAC,CAAC;IACzD,MAAM,KAAK,GAAG,IAAI,MAAM,CAAC,8BAA8B,IAAI,GAAG,EAAE,GAAG,CAAC,CAAC;IAErE,MAAM,KAAK,GAAG,QAAQ,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IACnC,IAAI,WAAW,GAAG,KAAK,CAAC;IAExB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QACtC,IAAI,KAAK,CAAC,CAAC,CAAE,CAAC,UAAU,CAAC,KAAK,CAAC,EAAE,CAAC;YAChC,WAAW,GAAG,CAAC,WAAW,CAAC;YAC3B,SAAS;QACX,CAAC;QACD,IAAI,WAAW;YAAE,SAAS;QAE1B,KAAK,CAAC,CAAC,CAAC,GAAG,KAAK,CAAC,CAAC,CAAE,CAAC,UAAU,CAAC,QAAQ,EAAE,KAAK,MAAM,EAAE,CAAC,CAAC;QACzD,KAAK,CAAC,CAAC,CAAC,GAAG,KAAK,CAAC,CAAC,CAAE,CAAC,UAAU,CAAC,KAAK,EAAE,KAAK,MAAM,EAAE,CAAC,CAAC;IACxD,CAAC;IAED,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAC1B,CAAC"}
|
|
@@ -15,7 +15,6 @@ export function resolveTargetNode(node, name, isRoot) {
|
|
|
15
15
|
if (name === 'index') {
|
|
16
16
|
if (isRoot)
|
|
17
17
|
return node;
|
|
18
|
-
// Non-root index → wildcard catch-all
|
|
19
18
|
node.wildcard ??= { param: 'rest', child: {} };
|
|
20
19
|
return node.wildcard.child;
|
|
21
20
|
}
|
|
@@ -24,7 +23,6 @@ export function resolveTargetNode(node, name, isRoot) {
|
|
|
24
23
|
node.dynamic ??= { param, child: {} };
|
|
25
24
|
return node.dynamic.child;
|
|
26
25
|
}
|
|
27
|
-
// Static segment
|
|
28
26
|
node.children ??= {};
|
|
29
27
|
node.children[name] ??= {};
|
|
30
28
|
return node.children[name];
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"route-tree.util.js","sourceRoot":"","sources":["../../../core/util/route-tree.util.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAIH;;;;;;;GAOG;AACH,MAAM,UAAU,iBAAiB,CAAC,IAAe,EAAE,IAAY,EAAE,MAAe;IAC9E,IAAI,IAAI,KAAK,OAAO,EAAE,CAAC;QACrB,IAAI,MAAM;YAAE,OAAO,IAAI,CAAC;QACxB,IAAI,CAAC,QAAQ,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,EAAE,EAAE,CAAC;QAC/C,OAAO,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC;IAC7B,CAAC;IAED,IAAI,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC;QAC/C,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;QAChC,IAAI,CAAC,OAAO,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,EAAE,EAAE,CAAC;QACtC,OAAO,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC;IAC5B,CAAC;IAED,IAAI,CAAC,QAAQ,KAAK,EAAE,CAAC;IACrB,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,KAAK,EAAE,CAAC;IAC3B,OAAO,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;AAC7B,CAAC"}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Widget Resolve Utilities
|
|
3
|
+
*
|
|
4
|
+
* Server-side resolution of <widget-*> tags in HTML.
|
|
5
|
+
* Calls getData() + renderHTML() on widgets and injects SSR hydration data.
|
|
6
|
+
*/
|
|
7
|
+
import type { Component } from '../component/abstract.component.ts';
|
|
8
|
+
import type { ContextProvider } from '../type/component.type.ts';
|
|
9
|
+
import { type Logger } from '../type/logger.type.ts';
|
|
10
|
+
import type { RouteInfo } from '../type/route.type.ts';
|
|
11
|
+
/** Maximum nesting depth for widgets to prevent infinite loops */
|
|
12
|
+
export declare const MAX_WIDGET_DEPTH = 10;
|
|
13
|
+
/**
|
|
14
|
+
* Recursively resolve widgets in content with depth limit.
|
|
15
|
+
*/
|
|
16
|
+
export declare function resolveRecursively<T>(content: string, parse: (content: string) => T[], resolve: (widget: T) => Promise<string>, replace: (content: string, replacements: Map<T, string>) => string, depth?: number, logger?: Logger): Promise<string>;
|
|
17
|
+
/**
|
|
18
|
+
* Resolve <widget-*> tags in HTML by calling getData() + renderHTML().
|
|
19
|
+
*/
|
|
20
|
+
export declare function resolveWidgetTags(html: string, registry: {
|
|
21
|
+
get(name: string): Component | undefined;
|
|
22
|
+
}, routeInfo: RouteInfo, loadFiles?: (widgetName: string) => Promise<{
|
|
23
|
+
html?: string;
|
|
24
|
+
md?: string;
|
|
25
|
+
css?: string;
|
|
26
|
+
}>, contextProvider?: ContextProvider, logger?: Logger): Promise<string>;
|
|
27
|
+
/** Parse HTML attribute string into params object. */
|
|
28
|
+
export declare function parseAttrsToParams(attrsString: string): Record<string, unknown>;
|
|
@@ -4,25 +4,14 @@
|
|
|
4
4
|
* Server-side resolution of <widget-*> tags in HTML.
|
|
5
5
|
* Calls getData() + renderHTML() on widgets and injects SSR hydration data.
|
|
6
6
|
*/
|
|
7
|
-
import {
|
|
7
|
+
import { defaultLogger } from "../type/logger.type.js";
|
|
8
8
|
import { LAZY_ATTR, SSR_ATTR } from "./html.util.js";
|
|
9
9
|
/** Maximum nesting depth for widgets to prevent infinite loops */
|
|
10
10
|
export const MAX_WIDGET_DEPTH = 10;
|
|
11
11
|
/**
|
|
12
12
|
* Recursively resolve widgets in content with depth limit.
|
|
13
|
-
*
|
|
14
|
-
* Generic utility used by both HTML and Markdown widget resolution.
|
|
15
|
-
* Each depth level processes all widgets concurrently, then recurses
|
|
16
|
-
* into each rendered result to resolve nested widgets.
|
|
17
|
-
*
|
|
18
|
-
* @param content - Content containing widgets
|
|
19
|
-
* @param parse - Find widgets in content
|
|
20
|
-
* @param resolve - Resolve a single widget to rendered output
|
|
21
|
-
* @param replace - Replace widgets with resolved content
|
|
22
|
-
* @param depth - Current recursion depth (internal)
|
|
23
|
-
* @returns Content with all widgets recursively resolved
|
|
24
13
|
*/
|
|
25
|
-
export async function resolveRecursively(content, parse, resolve, replace, depth = 0) {
|
|
14
|
+
export async function resolveRecursively(content, parse, resolve, replace, depth = 0, logger = defaultLogger) {
|
|
26
15
|
if (depth >= MAX_WIDGET_DEPTH) {
|
|
27
16
|
logger.warn(`Widget nesting depth limit reached (${MAX_WIDGET_DEPTH}). ` +
|
|
28
17
|
'Possible circular dependency or excessive nesting.');
|
|
@@ -34,33 +23,18 @@ export async function resolveRecursively(content, parse, resolve, replace, depth
|
|
|
34
23
|
const replacements = new Map();
|
|
35
24
|
await Promise.all(widgets.map(async (widget) => {
|
|
36
25
|
let rendered = await resolve(widget);
|
|
37
|
-
|
|
38
|
-
rendered = await resolveRecursively(rendered, parse, resolve, replace, depth + 1);
|
|
26
|
+
rendered = await resolveRecursively(rendered, parse, resolve, replace, depth + 1, logger);
|
|
39
27
|
replacements.set(widget, rendered);
|
|
40
28
|
}));
|
|
41
29
|
return replace(content, replacements);
|
|
42
30
|
}
|
|
43
31
|
/**
|
|
44
|
-
* Resolve <widget-*> tags in HTML by calling getData() + renderHTML()
|
|
45
|
-
* via the widget registry. Injects rendered content and boolean ssr attribute.
|
|
46
|
-
*
|
|
47
|
-
* Supports nested widgets: if a widget's renderHTML() returns HTML containing
|
|
48
|
-
* other <widget-*> tags, those will be resolved recursively up to MAX_WIDGET_DEPTH.
|
|
49
|
-
*
|
|
50
|
-
* Before: <widget-crypto-price coin="bitcoin"></widget-crypto-price>
|
|
51
|
-
* After: <widget-crypto-price coin="bitcoin" ssr><template shadowrootmode="open"><span>$42,000</span></template></widget-crypto-price>
|
|
52
|
-
*
|
|
53
|
-
* When a widget has `exposeSsrData = true`, the getData() result is serialized
|
|
54
|
-
* as JSON text in the light DOM (alongside the shadow root template):
|
|
55
|
-
* After: <widget-crypto-price coin="bitcoin" ssr><template shadowrootmode="open"><span>$42,000</span></template>{"price":42000}</widget-crypto-price>
|
|
32
|
+
* Resolve <widget-*> tags in HTML by calling getData() + renderHTML().
|
|
56
33
|
*/
|
|
57
|
-
export function resolveWidgetTags(html, registry, routeInfo, loadFiles, contextProvider) {
|
|
34
|
+
export function resolveWidgetTags(html, registry, routeInfo, loadFiles, contextProvider, logger = defaultLogger) {
|
|
58
35
|
const tagPattern = /<widget-(?<name>[a-z][a-z0-9-]*)(?<attrs>\s[^>]*)?>(?<content>.*?)<\/widget-\k<name>>/gis;
|
|
59
|
-
// Wrapping info stored per-match so replace() can apply it after recursion
|
|
60
36
|
const wrappers = new Map();
|
|
61
|
-
// Matches standalone ssr attribute (boolean or with value), not as substring of another value
|
|
62
37
|
const ssrAttrPattern = new RegExp(`\\s${SSR_ATTR}(?:\\s|=|$)`);
|
|
63
|
-
// Parse: find unprocessed widget tags
|
|
64
38
|
const parse = (content) => {
|
|
65
39
|
const matches = content.matchAll(tagPattern).toArray();
|
|
66
40
|
return matches.filter((match) => {
|
|
@@ -68,18 +42,17 @@ export function resolveWidgetTags(html, registry, routeInfo, loadFiles, contextP
|
|
|
68
42
|
return !ssrAttrPattern.test(attrsString);
|
|
69
43
|
});
|
|
70
44
|
};
|
|
71
|
-
// Resolve: render a single widget's inner content (no outer tag wrapping — that's in replace)
|
|
72
45
|
const resolve = async (match) => {
|
|
73
46
|
const widgetName = match.groups.name;
|
|
74
47
|
const attrsString = match.groups.attrs?.trim() ?? '';
|
|
75
48
|
const widget = registry.get(widgetName);
|
|
76
49
|
if (!widget)
|
|
77
|
-
return match[0];
|
|
50
|
+
return match[0];
|
|
78
51
|
const params = parseAttrsToParams(attrsString);
|
|
79
52
|
try {
|
|
80
53
|
let files;
|
|
81
54
|
if (loadFiles) {
|
|
82
|
-
files = await loadFiles(widgetName
|
|
55
|
+
files = await loadFiles(widgetName);
|
|
83
56
|
}
|
|
84
57
|
const baseContext = {
|
|
85
58
|
...routeInfo,
|
|
@@ -90,7 +63,6 @@ export function resolveWidgetTags(html, registry, routeInfo, loadFiles, contextP
|
|
|
90
63
|
const context = contextProvider ? contextProvider(baseContext) : baseContext;
|
|
91
64
|
const data = await widget.getData({ params, context });
|
|
92
65
|
const rendered = widget.renderHTML({ data, params, context });
|
|
93
|
-
// Store wrapping info — applied in replace() after recursion resolves nested widgets
|
|
94
66
|
wrappers.set(match, {
|
|
95
67
|
tagName: `widget-${widgetName}`,
|
|
96
68
|
attrs: attrsString ? ` ${attrsString}` : '',
|
|
@@ -100,10 +72,9 @@ export function resolveWidgetTags(html, registry, routeInfo, loadFiles, contextP
|
|
|
100
72
|
}
|
|
101
73
|
catch (e) {
|
|
102
74
|
logger.error(`[SSR HTML] Widget "${widgetName}" render failed`, e instanceof Error ? e : undefined);
|
|
103
|
-
return match[0];
|
|
75
|
+
return match[0];
|
|
104
76
|
}
|
|
105
77
|
};
|
|
106
|
-
// Replace: wrap resolved content in outer tag + DSD template, then substitute by index
|
|
107
78
|
const replace = (content, replacements) => {
|
|
108
79
|
let result = content;
|
|
109
80
|
const entries = [...replacements.entries()].sort((a, b) => b[0].index - a[0].index);
|
|
@@ -114,14 +85,14 @@ export function resolveWidgetTags(html, registry, routeInfo, loadFiles, contextP
|
|
|
114
85
|
const lightDomData = wrap?.ssrData ? wrap.ssrData : '';
|
|
115
86
|
const replacement = wrap
|
|
116
87
|
? `<${wrap.tagName}${wrap.attrs} ${SSR_ATTR}><template shadowrootmode="open">${innerHtml}</template>${lightDomData}</${wrap.tagName}>`
|
|
117
|
-
: innerHtml;
|
|
88
|
+
: innerHtml;
|
|
118
89
|
result = result.slice(0, start) + replacement + result.slice(end);
|
|
119
90
|
}
|
|
120
91
|
return result;
|
|
121
92
|
};
|
|
122
|
-
return resolveRecursively(html, parse, resolve, replace);
|
|
93
|
+
return resolveRecursively(html, parse, resolve, replace, 0, logger);
|
|
123
94
|
}
|
|
124
|
-
/** Parse HTML attribute string into params object
|
|
95
|
+
/** Parse HTML attribute string into params object. */
|
|
125
96
|
export function parseAttrsToParams(attrsString) {
|
|
126
97
|
const params = {};
|
|
127
98
|
if (!attrsString)
|
|
@@ -129,7 +100,7 @@ export function parseAttrsToParams(attrsString) {
|
|
|
129
100
|
const attrPattern = /(?<attr>[a-z][a-z0-9-]*)(?:="(?<dq>[^"]*)"|='(?<sq>[^']*)'|=(?<uq>[^\s>]+))?/gi;
|
|
130
101
|
for (const match of attrsString.matchAll(attrPattern)) {
|
|
131
102
|
const { attr: attrName, dq, sq, uq } = match.groups;
|
|
132
|
-
if (attrName === SSR_ATTR || attrName === LAZY_ATTR)
|
|
103
|
+
if (!attrName || attrName === SSR_ATTR || attrName === LAZY_ATTR)
|
|
133
104
|
continue;
|
|
134
105
|
const key = attrName.replace(/-([a-z])/g, (_, c) => c.toUpperCase());
|
|
135
106
|
const rawValue = dq ?? sq ?? uq;
|
|
@@ -147,7 +118,6 @@ export function parseAttrsToParams(attrsString) {
|
|
|
147
118
|
}
|
|
148
119
|
return params;
|
|
149
120
|
}
|
|
150
|
-
/** Escape a value for use in a single-quoted HTML attribute. */
|
|
151
121
|
function escapeAttr(value) {
|
|
152
122
|
return value.replaceAll('&', '&').replaceAll("'", ''');
|
|
153
123
|
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"widget-resolve.util.js","sourceRoot":"","sources":["../../../core/util/widget-resolve.util.ts"],"names":[],"mappings":"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"}
|
|
@@ -9,18 +9,5 @@
|
|
|
9
9
|
* ```
|
|
10
10
|
*/
|
|
11
11
|
import type { ParsedWidgetBlock } from '../type/widget.type.ts';
|
|
12
|
-
/**
|
|
13
|
-
* Parse all widget blocks from markdown content.
|
|
14
|
-
*
|
|
15
|
-
* @param markdown - Markdown content to parse
|
|
16
|
-
* @returns Array of parsed widget blocks with positions
|
|
17
|
-
*/
|
|
18
12
|
export declare function parseWidgetBlocks(markdown: string): ParsedWidgetBlock[];
|
|
19
|
-
/**
|
|
20
|
-
* Replace widget blocks in markdown with rendered content.
|
|
21
|
-
*
|
|
22
|
-
* @param markdown - Original markdown content
|
|
23
|
-
* @param replacements - Map of parsed blocks to replacement strings
|
|
24
|
-
* @returns Markdown with widget blocks replaced
|
|
25
|
-
*/
|
|
26
13
|
export declare function replaceWidgetBlocks(markdown: string, replacements: Map<ParsedWidgetBlock, string>): string;
|
|
@@ -8,17 +8,7 @@
|
|
|
8
8
|
* {"key": "value"}
|
|
9
9
|
* ```
|
|
10
10
|
*/
|
|
11
|
-
/**
|
|
12
|
-
* Pattern to match widget fenced code blocks.
|
|
13
|
-
* Captures: widget name, params content
|
|
14
|
-
*/
|
|
15
11
|
const WIDGET_PATTERN = /```widget:(?<name>[a-z][a-z0-9-]*)\n(?<params>.*?)```/gs;
|
|
16
|
-
/**
|
|
17
|
-
* Parse all widget blocks from markdown content.
|
|
18
|
-
*
|
|
19
|
-
* @param markdown - Markdown content to parse
|
|
20
|
-
* @returns Array of parsed widget blocks with positions
|
|
21
|
-
*/
|
|
22
12
|
export function parseWidgetBlocks(markdown) {
|
|
23
13
|
const blocks = [];
|
|
24
14
|
for (const match of markdown.matchAll(WIDGET_PATTERN)) {
|
|
@@ -28,12 +18,11 @@ export function parseWidgetBlocks(markdown) {
|
|
|
28
18
|
const startIndex = match.index;
|
|
29
19
|
const block = {
|
|
30
20
|
fullMatch,
|
|
31
|
-
widgetName,
|
|
21
|
+
widgetName: widgetName,
|
|
32
22
|
params: null,
|
|
33
23
|
startIndex,
|
|
34
24
|
endIndex: startIndex + fullMatch.length,
|
|
35
25
|
};
|
|
36
|
-
// Parse JSON params if present
|
|
37
26
|
if (paramsJson) {
|
|
38
27
|
try {
|
|
39
28
|
const parsed = JSON.parse(paramsJson);
|
|
@@ -49,23 +38,13 @@ export function parseWidgetBlocks(markdown) {
|
|
|
49
38
|
}
|
|
50
39
|
}
|
|
51
40
|
else {
|
|
52
|
-
// Empty params is valid - use empty object
|
|
53
41
|
block.params = {};
|
|
54
42
|
}
|
|
55
43
|
blocks.push(block);
|
|
56
44
|
}
|
|
57
45
|
return blocks;
|
|
58
46
|
}
|
|
59
|
-
/**
|
|
60
|
-
* Replace widget blocks in markdown with rendered content.
|
|
61
|
-
*
|
|
62
|
-
* @param markdown - Original markdown content
|
|
63
|
-
* @param replacements - Map of parsed blocks to replacement strings
|
|
64
|
-
* @returns Markdown with widget blocks replaced
|
|
65
|
-
*/
|
|
66
47
|
export function replaceWidgetBlocks(markdown, replacements) {
|
|
67
|
-
// Sort blocks by position descending to replace from end first
|
|
68
|
-
// This preserves indices during replacement
|
|
69
48
|
const sortedBlocks = [...replacements.entries()].sort(([a], [b]) => b.startIndex - a.startIndex);
|
|
70
49
|
let result = markdown;
|
|
71
50
|
for (const [block, replacement] of sortedBlocks) {
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"widget.parser.js","sourceRoot":"","sources":["../../../core/widget/widget.parser.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAIH,MAAM,cAAc,GAAG,yDAAyD,CAAC;AAEjF,MAAM,UAAU,iBAAiB,CAAC,QAAgB;IAChD,MAAM,MAAM,GAAwB,EAAE,CAAC;IAEvC,KAAK,MAAM,KAAK,IAAI,QAAQ,CAAC,QAAQ,CAAC,cAAc,CAAC,EAAE,CAAC;QACtD,MAAM,SAAS,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC;QAC3B,MAAM,EAAE,IAAI,EAAE,UAAU,EAAE,MAAM,EAAE,SAAS,EAAE,GAAG,KAAK,CAAC,MAAO,CAAC;QAC9D,MAAM,UAAU,GAAG,SAAU,CAAC,IAAI,EAAE,CAAC;QACrC,MAAM,UAAU,GAAG,KAAK,CAAC,KAAK,CAAC;QAE/B,MAAM,KAAK,GAAsB;YAC/B,SAAS;YACT,UAAU,EAAE,UAAW;YACvB,MAAM,EAAE,IAAI;YACZ,UAAU;YACV,QAAQ,EAAE,UAAU,GAAG,SAAS,CAAC,MAAM;SACxC,CAAC;QAEF,IAAI,UAAU,EAAE,CAAC;YACf,IAAI,CAAC;gBACH,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC;gBACtC,IAAI,OAAO,MAAM,KAAK,QAAQ,IAAI,MAAM,KAAK,IAAI,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC;oBAC5E,KAAK,CAAC,MAAM,GAAG,MAAM,CAAC;gBACxB,CAAC;qBAAM,CAAC;oBACN,KAAK,CAAC,UAAU,GAAG,8BAA8B,CAAC;gBACpD,CAAC;YACH,CAAC;YAAC,OAAO,CAAC,EAAE,CAAC;gBACX,KAAK,CAAC,UAAU,GAAG,iBAAiB,CAAC,YAAY,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC;YACnF,CAAC;QACH,CAAC;aAAM,CAAC;YACN,KAAK,CAAC,MAAM,GAAG,EAAE,CAAC;QACpB,CAAC;QAED,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IACrB,CAAC;IAED,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,MAAM,UAAU,mBAAmB,CACjC,QAAgB,EAChB,YAA4C;IAE5C,MAAM,YAAY,GAAG,CAAC,GAAG,YAAY,CAAC,OAAO,EAAE,CAAC,CAAC,IAAI,CACnD,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,UAAU,GAAG,CAAC,CAAC,UAAU,CAC1C,CAAC;IAEF,IAAI,MAAM,GAAG,QAAQ,CAAC;IACtB,KAAK,MAAM,CAAC,KAAK,EAAE,WAAW,CAAC,IAAI,YAAY,EAAE,CAAC;QAChD,MAAM,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC,EAAE,KAAK,CAAC,UAAU,CAAC,GAAG,WAAW,GAAG,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC;IAC1F,CAAC;IAED,OAAO,MAAM,CAAC;AAChB,CAAC"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Widget Registry
|
|
3
|
+
*
|
|
4
|
+
* Name → Component lookup. Used by all renderers.
|
|
5
|
+
* Pages are NOT in this registry — they live in the routes manifest.
|
|
6
|
+
*/
|
|
7
|
+
import type { WidgetComponent } from '../component/widget.component.ts';
|
|
8
|
+
export declare class WidgetRegistry {
|
|
9
|
+
private entries;
|
|
10
|
+
add(widget: WidgetComponent, modulePath?: string): void;
|
|
11
|
+
get(name: string): WidgetComponent | undefined;
|
|
12
|
+
getModulePath(name: string): string | undefined;
|
|
13
|
+
[Symbol.iterator](): IterableIterator<WidgetComponent>;
|
|
14
|
+
}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Widget Registry
|
|
3
|
+
*
|
|
4
|
+
* Name → Component lookup. Used by all renderers.
|
|
5
|
+
* Pages are NOT in this registry — they live in the routes manifest.
|
|
6
|
+
*/
|
|
7
|
+
export class WidgetRegistry {
|
|
8
|
+
entries = new Map();
|
|
9
|
+
add(widget, modulePath) {
|
|
10
|
+
this.entries.set(widget.name, { widget, modulePath });
|
|
11
|
+
}
|
|
12
|
+
get(name) {
|
|
13
|
+
return this.entries.get(name)?.widget;
|
|
14
|
+
}
|
|
15
|
+
getModulePath(name) {
|
|
16
|
+
return this.entries.get(name)?.modulePath;
|
|
17
|
+
}
|
|
18
|
+
[Symbol.iterator]() {
|
|
19
|
+
const entries = this.entries.values();
|
|
20
|
+
return (function* () {
|
|
21
|
+
for (const entry of entries)
|
|
22
|
+
yield entry.widget;
|
|
23
|
+
})();
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
//# sourceMappingURL=widget.registry.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"widget.registry.js","sourceRoot":"","sources":["../../../core/widget/widget.registry.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AASH,MAAM,OAAO,cAAc;IACjB,OAAO,GAAG,IAAI,GAAG,EAAyB,CAAC;IAEnD,GAAG,CAAC,MAAuB,EAAE,UAAmB;QAC9C,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,EAAE,EAAE,MAAM,EAAE,UAAU,EAAE,CAAC,CAAC;IACxD,CAAC;IAED,GAAG,CAAC,IAAY;QACd,OAAO,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC;IACxC,CAAC;IAED,aAAa,CAAC,IAAY;QACxB,OAAO,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,UAAU,CAAC;IAC5C,CAAC;IAED,CAAC,MAAM,CAAC,QAAQ,CAAC;QACf,MAAM,OAAO,GAAG,IAAI,CAAC,OAAO,CAAC,MAAM,EAAE,CAAC;QACtC,OAAO,CAAC,QAAQ,CAAC;YACf,KAAK,MAAM,KAAK,IAAI,OAAO;gBAAE,MAAM,KAAK,CAAC,MAAM,CAAC;QAClD,CAAC,CAAC,EAAE,CAAC;IACP,CAAC;CACF"}
|