@emkodev/emroute 1.10.0-beta.1 → 1.10.0-beta.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/core/component/abstract.component.ts +1 -1
- package/core/component/page.component.ts +0 -6
- package/core/pipeline/pipeline.ts +30 -0
- package/core/renderer/html.renderer.ts +13 -10
- package/core/renderer/md.renderer.ts +18 -9
- package/core/renderer/ssr.renderer.ts +0 -19
- package/core/util/html.util.ts +3 -0
- package/core/util/widget-resolve.util.ts +9 -16
- package/dist/core/component/abstract.component.d.ts +1 -1
- package/dist/core/component/abstract.component.js +1 -0
- package/dist/core/component/abstract.component.js.map +1 -1
- package/dist/core/component/page.component.d.ts +0 -1
- package/dist/core/component/page.component.js +0 -3
- package/dist/core/component/page.component.js.map +1 -1
- package/dist/core/pipeline/pipeline.d.ts +10 -0
- package/dist/core/pipeline/pipeline.js +29 -0
- package/dist/core/pipeline/pipeline.js.map +1 -1
- package/dist/core/renderer/html.renderer.js +10 -10
- package/dist/core/renderer/html.renderer.js.map +1 -1
- package/dist/core/renderer/md.renderer.js +13 -8
- package/dist/core/renderer/md.renderer.js.map +1 -1
- package/dist/core/renderer/ssr.renderer.d.ts +0 -3
- package/dist/core/renderer/ssr.renderer.js +0 -15
- package/dist/core/renderer/ssr.renderer.js.map +1 -1
- package/dist/core/util/html.util.d.ts +2 -0
- package/dist/core/util/html.util.js +2 -0
- package/dist/core/util/html.util.js.map +1 -1
- package/dist/core/util/widget-resolve.util.d.ts +5 -6
- package/dist/core/util/widget-resolve.util.js +8 -11
- package/dist/core/util/widget-resolve.util.js.map +1 -1
- package/dist/emroute.js +62 -60
- package/dist/emroute.js.map +12 -13
- package/dist/src/element/component.element.js +2 -2
- package/dist/src/element/component.element.js.map +1 -1
- package/package.json +1 -1
- package/src/element/component.element.ts +2 -2
- package/core/widget/widget.registry.ts +0 -22
|
@@ -5,6 +5,8 @@
|
|
|
5
5
|
export const SSR_ATTR = 'ssr';
|
|
6
6
|
/** HTML attribute name for lazy-loading widgets. */
|
|
7
7
|
export const LAZY_ATTR = 'lazy';
|
|
8
|
+
/** Attribute names to skip when parsing widget params (not user-supplied data). */
|
|
9
|
+
export const RESERVED_ATTRS = new Set([SSR_ATTR, LAZY_ATTR, 'style', 'class', 'id', 'slot', 'part']);
|
|
8
10
|
const BLOCKED_PROTOCOLS = /^(javascript|data|vbscript):/i;
|
|
9
11
|
/** Throw if a redirect URL uses a dangerous protocol. */
|
|
10
12
|
export function assertSafeRedirect(url) {
|
|
@@ -1 +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"}
|
|
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,mFAAmF;AACnF,MAAM,CAAC,MAAM,cAAc,GAAG,IAAI,GAAG,CAAC,CAAC,QAAQ,EAAE,SAAS,EAAE,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;AAErG,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"}
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
* Calls getData() + renderHTML() on widgets and injects SSR hydration data.
|
|
6
6
|
*/
|
|
7
7
|
import type { Component } from '../component/abstract.component.ts';
|
|
8
|
-
import type { ContextProvider } from '../type/component.type.ts';
|
|
8
|
+
import type { ContextProvider, FileContents } from '../type/component.type.ts';
|
|
9
9
|
import { type Logger } from '../type/logger.type.ts';
|
|
10
10
|
import type { RouteInfo } from '../type/route.type.ts';
|
|
11
11
|
/** Maximum nesting depth for widgets to prevent infinite loops */
|
|
@@ -17,10 +17,9 @@ export declare function resolveRecursively<T>(content: string, parse: (content:
|
|
|
17
17
|
/**
|
|
18
18
|
* Resolve <widget-*> tags in HTML by calling getData() + renderHTML().
|
|
19
19
|
*/
|
|
20
|
-
export declare function resolveWidgetTags(html: string, getWidget: (name: string) => Promise<
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
}>, contextProvider?: ContextProvider, logger?: Logger): Promise<string>;
|
|
20
|
+
export declare function resolveWidgetTags(html: string, getWidget: (name: string) => Promise<{
|
|
21
|
+
component: Component;
|
|
22
|
+
files?: FileContents;
|
|
23
|
+
} | undefined>, routeInfo: RouteInfo, contextProvider?: ContextProvider, logger?: Logger): Promise<string>;
|
|
25
24
|
/** Parse HTML attribute string into params object. */
|
|
26
25
|
export declare function parseAttrsToParams(attrsString: string): Record<string, unknown>;
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
* Calls getData() + renderHTML() on widgets and injects SSR hydration data.
|
|
6
6
|
*/
|
|
7
7
|
import { defaultLogger } from "../type/logger.type.js";
|
|
8
|
-
import {
|
|
8
|
+
import { RESERVED_ATTRS, 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
|
/**
|
|
@@ -31,7 +31,7 @@ export async function resolveRecursively(content, parse, resolve, replace, depth
|
|
|
31
31
|
/**
|
|
32
32
|
* Resolve <widget-*> tags in HTML by calling getData() + renderHTML().
|
|
33
33
|
*/
|
|
34
|
-
export function resolveWidgetTags(html, getWidget, routeInfo,
|
|
34
|
+
export function resolveWidgetTags(html, getWidget, routeInfo, contextProvider, logger = defaultLogger) {
|
|
35
35
|
const tagPattern = /<widget-(?<name>[a-z][a-z0-9-]*)(?<attrs>\s[^>]*)?>(?<content>.*?)<\/widget-\k<name>>/gis;
|
|
36
36
|
const wrappers = new Map();
|
|
37
37
|
const ssrAttrPattern = new RegExp(`\\s${SSR_ATTR}(?:\\s|=|$)`);
|
|
@@ -45,15 +45,12 @@ export function resolveWidgetTags(html, getWidget, routeInfo, loadFiles, context
|
|
|
45
45
|
const resolve = async (match) => {
|
|
46
46
|
const widgetName = match.groups.name;
|
|
47
47
|
const attrsString = match.groups.attrs?.trim() ?? '';
|
|
48
|
-
const widget = await getWidget(widgetName);
|
|
49
|
-
if (!widget)
|
|
50
|
-
return match[0];
|
|
51
|
-
const params = parseAttrsToParams(attrsString);
|
|
52
48
|
try {
|
|
53
|
-
|
|
54
|
-
if (
|
|
55
|
-
|
|
56
|
-
}
|
|
49
|
+
const result = await getWidget(widgetName);
|
|
50
|
+
if (!result)
|
|
51
|
+
return match[0];
|
|
52
|
+
const { component: widget, files } = result;
|
|
53
|
+
const params = parseAttrsToParams(attrsString);
|
|
57
54
|
const baseContext = {
|
|
58
55
|
...routeInfo,
|
|
59
56
|
pathname: routeInfo.url.pathname,
|
|
@@ -100,7 +97,7 @@ export function parseAttrsToParams(attrsString) {
|
|
|
100
97
|
const attrPattern = /(?<attr>[a-z][a-z0-9-]*)(?:="(?<dq>[^"]*)"|='(?<sq>[^']*)'|=(?<uq>[^\s>]+))?/gi;
|
|
101
98
|
for (const match of attrsString.matchAll(attrPattern)) {
|
|
102
99
|
const { attr: attrName, dq, sq, uq } = match.groups;
|
|
103
|
-
if (!attrName || attrName
|
|
100
|
+
if (!attrName || RESERVED_ATTRS.has(attrName))
|
|
104
101
|
continue;
|
|
105
102
|
const key = attrName.replace(/-([a-z])/g, (_, c) => c.toUpperCase());
|
|
106
103
|
const rawValue = dq ?? sq ?? uq;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"widget-resolve.util.js","sourceRoot":"","sources":["../../../core/util/widget-resolve.util.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAIH,OAAO,EAAe,aAAa,EAAE,MAAM,wBAAwB,CAAC;AAEpE,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"widget-resolve.util.js","sourceRoot":"","sources":["../../../core/util/widget-resolve.util.ts"],"names":[],"mappings":"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"}
|
package/dist/emroute.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
// dist/core/util/html.util.js
|
|
2
2
|
var SSR_ATTR = "ssr";
|
|
3
3
|
var LAZY_ATTR = "lazy";
|
|
4
|
+
var RESERVED_ATTRS = new Set([SSR_ATTR, LAZY_ATTR, "style", "class", "id", "slot", "part"]);
|
|
4
5
|
var BLOCKED_PROTOCOLS = /^(javascript|data|vbscript):/i;
|
|
5
6
|
function assertSafeRedirect(url) {
|
|
6
7
|
if (BLOCKED_PROTOCOLS.test(url.trim())) {
|
|
@@ -320,7 +321,7 @@ class ComponentElement extends HTMLElementBase {
|
|
|
320
321
|
const signal = this.abortController.signal;
|
|
321
322
|
const params = {};
|
|
322
323
|
for (const attr of this.attributes) {
|
|
323
|
-
if (
|
|
324
|
+
if (RESERVED_ATTRS.has(attr.name))
|
|
324
325
|
continue;
|
|
325
326
|
const key = attr.name.replace(/-([a-z])/g, (_, c) => c.toUpperCase());
|
|
326
327
|
try {
|
|
@@ -701,6 +702,32 @@ class Pipeline {
|
|
|
701
702
|
const entries = await response.json();
|
|
702
703
|
return entries.find((e) => e.name === name)?.modulePath;
|
|
703
704
|
}
|
|
705
|
+
async loadWidgetModule(name) {
|
|
706
|
+
const path = await this.findWidgetModulePath(name);
|
|
707
|
+
if (!path)
|
|
708
|
+
return;
|
|
709
|
+
const mod = await this.loadModule(path);
|
|
710
|
+
const component = this.extractWidgetComponent(mod);
|
|
711
|
+
if (!component)
|
|
712
|
+
return;
|
|
713
|
+
return { component, files: this.getModuleFiles(mod) ?? {} };
|
|
714
|
+
}
|
|
715
|
+
async loadWidget(name) {
|
|
716
|
+
return (await this.loadWidgetModule(name))?.component;
|
|
717
|
+
}
|
|
718
|
+
extractWidgetComponent(mod) {
|
|
719
|
+
for (const value of Object.values(mod)) {
|
|
720
|
+
if (!value)
|
|
721
|
+
continue;
|
|
722
|
+
if (typeof value === "object" && "getData" in value) {
|
|
723
|
+
return value;
|
|
724
|
+
}
|
|
725
|
+
if (typeof value === "function" && value.prototype?.getData) {
|
|
726
|
+
return new value;
|
|
727
|
+
}
|
|
728
|
+
}
|
|
729
|
+
return;
|
|
730
|
+
}
|
|
704
731
|
async loadModule(modulePath) {
|
|
705
732
|
const loader = this.moduleLoaders[modulePath];
|
|
706
733
|
if (loader) {
|
|
@@ -792,7 +819,7 @@ async function resolveRecursively(content, parse, resolve, replace, depth = 0, l
|
|
|
792
819
|
}));
|
|
793
820
|
return replace(content, replacements);
|
|
794
821
|
}
|
|
795
|
-
function resolveWidgetTags(html, getWidget, routeInfo,
|
|
822
|
+
function resolveWidgetTags(html, getWidget, routeInfo, contextProvider, logger = defaultLogger) {
|
|
796
823
|
const tagPattern = /<widget-(?<name>[a-z][a-z0-9-]*)(?<attrs>\s[^>]*)?>(?<content>.*?)<\/widget-\k<name>>/gis;
|
|
797
824
|
const wrappers = new Map;
|
|
798
825
|
const ssrAttrPattern = new RegExp(`\\s${SSR_ATTR}(?:\\s|=|$)`);
|
|
@@ -806,15 +833,12 @@ function resolveWidgetTags(html, getWidget, routeInfo, loadFiles, contextProvide
|
|
|
806
833
|
const resolve = async (match) => {
|
|
807
834
|
const widgetName = match.groups.name;
|
|
808
835
|
const attrsString = match.groups.attrs?.trim() ?? "";
|
|
809
|
-
const widget = await getWidget(widgetName);
|
|
810
|
-
if (!widget)
|
|
811
|
-
return match[0];
|
|
812
|
-
const params = parseAttrsToParams(attrsString);
|
|
813
836
|
try {
|
|
814
|
-
|
|
815
|
-
if (
|
|
816
|
-
|
|
817
|
-
}
|
|
837
|
+
const result = await getWidget(widgetName);
|
|
838
|
+
if (!result)
|
|
839
|
+
return match[0];
|
|
840
|
+
const { component: widget, files } = result;
|
|
841
|
+
const params = parseAttrsToParams(attrsString);
|
|
818
842
|
const baseContext = {
|
|
819
843
|
...routeInfo,
|
|
820
844
|
pathname: routeInfo.url.pathname,
|
|
@@ -857,7 +881,7 @@ function parseAttrsToParams(attrsString) {
|
|
|
857
881
|
const attrPattern = /(?<attr>[a-z][a-z0-9-]*)(?:="(?<dq>[^"]*)"|='(?<sq>[^']*)'|=(?<uq>[^\s>]+))?/gi;
|
|
858
882
|
for (const match of attrsString.matchAll(attrPattern)) {
|
|
859
883
|
const { attr: attrName, dq, sq, uq } = match.groups;
|
|
860
|
-
if (!attrName || attrName
|
|
884
|
+
if (!attrName || RESERVED_ATTRS.has(attrName))
|
|
861
885
|
continue;
|
|
862
886
|
const key = attrName.replace(/-([a-z])/g, (_, c) => c.toUpperCase());
|
|
863
887
|
const rawValue = dq ?? sq ?? uq;
|
|
@@ -883,6 +907,9 @@ class Component {
|
|
|
883
907
|
element;
|
|
884
908
|
files;
|
|
885
909
|
exposeSsrData;
|
|
910
|
+
getData(_args) {
|
|
911
|
+
return Promise.resolve(null);
|
|
912
|
+
}
|
|
886
913
|
renderHTML(args) {
|
|
887
914
|
if (args.data === null) {
|
|
888
915
|
return `<div data-component="${this.name}">Loading...</div>`;
|
|
@@ -968,9 +995,6 @@ class Component {
|
|
|
968
995
|
class PageComponent extends Component {
|
|
969
996
|
name = "page";
|
|
970
997
|
pattern;
|
|
971
|
-
getData(_args) {
|
|
972
|
-
return Promise.resolve(null);
|
|
973
|
-
}
|
|
974
998
|
renderHTML(args) {
|
|
975
999
|
const files = args.context.files;
|
|
976
1000
|
const style = files?.css ? `<style>${files.css}</style>
|
|
@@ -1003,21 +1027,6 @@ class PageComponent extends Component {
|
|
|
1003
1027
|
}
|
|
1004
1028
|
var page_component_default = new PageComponent;
|
|
1005
1029
|
|
|
1006
|
-
// dist/core/widget/widget.registry.js
|
|
1007
|
-
function extractWidgetExport(mod) {
|
|
1008
|
-
for (const value of Object.values(mod)) {
|
|
1009
|
-
if (!value)
|
|
1010
|
-
continue;
|
|
1011
|
-
if (typeof value === "object" && "getData" in value) {
|
|
1012
|
-
return value;
|
|
1013
|
-
}
|
|
1014
|
-
if (typeof value === "function" && value.prototype?.getData) {
|
|
1015
|
-
return new value;
|
|
1016
|
-
}
|
|
1017
|
-
}
|
|
1018
|
-
return null;
|
|
1019
|
-
}
|
|
1020
|
-
|
|
1021
1030
|
// dist/core/renderer/ssr.renderer.js
|
|
1022
1031
|
class SsrRenderer {
|
|
1023
1032
|
pipeline;
|
|
@@ -1026,18 +1035,6 @@ class SsrRenderer {
|
|
|
1026
1035
|
this.pipeline = pipeline;
|
|
1027
1036
|
this.logger = pipeline.logger;
|
|
1028
1037
|
}
|
|
1029
|
-
async resolveWidget(name) {
|
|
1030
|
-
const path = await this.pipeline.findWidgetModulePath(name);
|
|
1031
|
-
if (!path)
|
|
1032
|
-
return;
|
|
1033
|
-
try {
|
|
1034
|
-
const mod = await this.pipeline.loadModule(path);
|
|
1035
|
-
return extractWidgetExport(mod) ?? undefined;
|
|
1036
|
-
} catch (e) {
|
|
1037
|
-
this.logger.error(`[${this.label}] Failed to load widget "${name}"`, e instanceof Error ? e : undefined);
|
|
1038
|
-
return;
|
|
1039
|
-
}
|
|
1040
|
-
}
|
|
1041
1038
|
async render(url, signal) {
|
|
1042
1039
|
const matched = await this.pipeline.match(url);
|
|
1043
1040
|
if (!matched) {
|
|
@@ -1201,16 +1198,16 @@ class SsrHtmlRenderer extends SsrRenderer {
|
|
|
1201
1198
|
let content = rawContent;
|
|
1202
1199
|
content = await this.expandMarkdown(content);
|
|
1203
1200
|
content = this.attributeSlots(content, route.pattern);
|
|
1204
|
-
|
|
1205
|
-
|
|
1206
|
-
if (
|
|
1207
|
-
|
|
1208
|
-
|
|
1209
|
-
|
|
1210
|
-
|
|
1211
|
-
}
|
|
1212
|
-
return
|
|
1213
|
-
}, this.pipeline.contextProvider, this.logger);
|
|
1201
|
+
const widgetCache = new Map;
|
|
1202
|
+
content = await resolveWidgetTags(content, (name) => {
|
|
1203
|
+
if (!widgetCache.has(name)) {
|
|
1204
|
+
widgetCache.set(name, this.pipeline.loadWidgetModule(name).catch((e) => {
|
|
1205
|
+
this.logger.error(`[${this.label}] Failed to load widget "${name}"`, e instanceof Error ? e : undefined);
|
|
1206
|
+
return;
|
|
1207
|
+
}));
|
|
1208
|
+
}
|
|
1209
|
+
return widgetCache.get(name);
|
|
1210
|
+
}, routeInfo, this.pipeline.contextProvider, this.logger);
|
|
1214
1211
|
return { content, ...title !== undefined ? { title } : {} };
|
|
1215
1212
|
}
|
|
1216
1213
|
renderContent(component, args) {
|
|
@@ -1342,21 +1339,26 @@ Path: \`${url.pathname}\``;
|
|
|
1342
1339
|
Path: \`${url.pathname}\``;
|
|
1343
1340
|
}
|
|
1344
1341
|
resolveWidgets(content, routeInfo) {
|
|
1342
|
+
const widgetCache = new Map;
|
|
1343
|
+
const loadWidget = (name) => {
|
|
1344
|
+
if (!widgetCache.has(name)) {
|
|
1345
|
+
widgetCache.set(name, this.pipeline.loadWidgetModule(name).catch((e) => {
|
|
1346
|
+
this.logger.error(`[${this.label}] Failed to load widget "${name}"`, e instanceof Error ? e : undefined);
|
|
1347
|
+
return;
|
|
1348
|
+
}));
|
|
1349
|
+
}
|
|
1350
|
+
return widgetCache.get(name);
|
|
1351
|
+
};
|
|
1345
1352
|
return resolveRecursively(content, parseWidgetBlocks, async (block) => {
|
|
1346
1353
|
if (block.parseError || !block.params) {
|
|
1347
1354
|
return `> **Error** (\`${block.widgetName}\`): ${block.parseError}`;
|
|
1348
1355
|
}
|
|
1349
|
-
const
|
|
1350
|
-
if (!
|
|
1356
|
+
const result = await loadWidget(block.widgetName);
|
|
1357
|
+
if (!result) {
|
|
1351
1358
|
return `> **Error**: Unknown widget \`${block.widgetName}\``;
|
|
1352
1359
|
}
|
|
1360
|
+
const { component: widget, files } = result;
|
|
1353
1361
|
try {
|
|
1354
|
-
let files;
|
|
1355
|
-
const modulePath = await this.pipeline.findWidgetModulePath(block.widgetName);
|
|
1356
|
-
if (modulePath) {
|
|
1357
|
-
const mod = await this.pipeline.loadModule(modulePath);
|
|
1358
|
-
files = this.pipeline.getModuleFiles(mod);
|
|
1359
|
-
}
|
|
1360
1362
|
const baseContext = {
|
|
1361
1363
|
...routeInfo,
|
|
1362
1364
|
pathname: routeInfo.url.pathname,
|
|
@@ -3465,5 +3467,5 @@ export {
|
|
|
3465
3467
|
BreadcrumbWidget
|
|
3466
3468
|
};
|
|
3467
3469
|
|
|
3468
|
-
//# debugId=
|
|
3470
|
+
//# debugId=422168580B2E75DD64756E2164756E21
|
|
3469
3471
|
//# sourceMappingURL=emroute.js.map
|