@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.
Files changed (37) hide show
  1. package/core/component/abstract.component.ts +1 -1
  2. package/core/component/page.component.ts +0 -6
  3. package/core/pipeline/pipeline.ts +30 -0
  4. package/core/renderer/html.renderer.ts +13 -10
  5. package/core/renderer/md.renderer.ts +18 -9
  6. package/core/renderer/ssr.renderer.ts +0 -19
  7. package/core/util/html.util.ts +3 -0
  8. package/core/util/widget-resolve.util.ts +9 -16
  9. package/dist/core/component/abstract.component.d.ts +1 -1
  10. package/dist/core/component/abstract.component.js +1 -0
  11. package/dist/core/component/abstract.component.js.map +1 -1
  12. package/dist/core/component/page.component.d.ts +0 -1
  13. package/dist/core/component/page.component.js +0 -3
  14. package/dist/core/component/page.component.js.map +1 -1
  15. package/dist/core/pipeline/pipeline.d.ts +10 -0
  16. package/dist/core/pipeline/pipeline.js +29 -0
  17. package/dist/core/pipeline/pipeline.js.map +1 -1
  18. package/dist/core/renderer/html.renderer.js +10 -10
  19. package/dist/core/renderer/html.renderer.js.map +1 -1
  20. package/dist/core/renderer/md.renderer.js +13 -8
  21. package/dist/core/renderer/md.renderer.js.map +1 -1
  22. package/dist/core/renderer/ssr.renderer.d.ts +0 -3
  23. package/dist/core/renderer/ssr.renderer.js +0 -15
  24. package/dist/core/renderer/ssr.renderer.js.map +1 -1
  25. package/dist/core/util/html.util.d.ts +2 -0
  26. package/dist/core/util/html.util.js +2 -0
  27. package/dist/core/util/html.util.js.map +1 -1
  28. package/dist/core/util/widget-resolve.util.d.ts +5 -6
  29. package/dist/core/util/widget-resolve.util.js +8 -11
  30. package/dist/core/util/widget-resolve.util.js.map +1 -1
  31. package/dist/emroute.js +62 -60
  32. package/dist/emroute.js.map +12 -13
  33. package/dist/src/element/component.element.js +2 -2
  34. package/dist/src/element/component.element.js.map +1 -1
  35. package/package.json +1 -1
  36. package/src/element/component.element.ts +2 -2
  37. 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<Component | undefined>, routeInfo: RouteInfo, loadFiles?: (widgetName: string) => Promise<{
21
- html?: string;
22
- md?: string;
23
- css?: string;
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 { LAZY_ATTR, SSR_ATTR } from "./html.util.js";
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, loadFiles, contextProvider, logger = defaultLogger) {
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
- let files;
54
- if (loadFiles) {
55
- files = await loadFiles(widgetName);
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 === SSR_ATTR || attrName === LAZY_ATTR)
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":"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"}
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 (attr.name === SSR_ATTR || attr.name === LAZY_ATTR)
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, loadFiles, contextProvider, logger = defaultLogger) {
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
- let files;
815
- if (loadFiles) {
816
- files = await loadFiles(widgetName);
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 === SSR_ATTR || attrName === LAZY_ATTR)
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
- content = await resolveWidgetTags(content, (name) => this.resolveWidget(name), routeInfo, async (name) => {
1205
- const modulePath = await this.pipeline.findWidgetModulePath(name);
1206
- if (modulePath) {
1207
- const mod = await this.pipeline.loadModule(modulePath);
1208
- const inlined = this.pipeline.getModuleFiles(mod);
1209
- if (inlined)
1210
- return inlined;
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 widget = await this.resolveWidget(block.widgetName);
1350
- if (!widget) {
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=FB9DE7997217939864756E2164756E21
3470
+ //# debugId=422168580B2E75DD64756E2164756E21
3469
3471
  //# sourceMappingURL=emroute.js.map