@lwrjs/view-registry 0.9.0-alpha.3 → 0.9.0-alpha.31

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.
@@ -1,24 +1,34 @@
1
- import { kebabCaseToModuleSpecifer, getModuleGraphs, GraphDepth, getModuleUriPrefix, logger, } from '@lwrjs/shared-utils';
1
+ import { kebabCaseToModuleSpecifier, getModuleGraphs, GraphDepth, getModuleUriPrefix, logger, getVersionedModuleId, explodeSpecifier, getSpecifier, normalizeVersionToUri, VERSION_NOT_PROVIDED, } from '@lwrjs/shared-utils';
2
2
  import { AppResourceEnum, getAppSpecifier } from '@lwrjs/app-service/identity';
3
- import { generateHtmlTag, getModuleResource, getModuleResourceByUri } from '../utils.js';
3
+ import { generateHtmlTag, getModuleResourceByUri } from '../utils.js';
4
4
  import { flattenCustomElements, getViewBootstrapConfigurationResource, getViewHmrConfigurationResource, } from './utils.js';
5
5
  export async function getHtmlResources(view, viewParams, resourceContext) {
6
- const { runtimeEnvironment, runtimeParams, moduleRegistry, moduleBundler, resourceRegistry, viewMetadata, } = resourceContext;
7
- const { id: appName, bootstrap: { services } = { services: [] } } = view;
6
+ const { runtimeEnvironment, runtimeParams, moduleRegistry, moduleBundler, resourceRegistry, viewMetadata, bundleConfig: { external = {} }, } = resourceContext;
7
+ const isExternal = function (rawSpecifier) {
8
+ const { specifier } = explodeSpecifier(rawSpecifier);
9
+ return Object.keys(external).some((e) => specifier === e);
10
+ };
11
+ const { id: appName, bootstrap: { services, module: bootstrapModule, preloadModules = [] } = {
12
+ services: [],
13
+ preloadModules: [],
14
+ }, } = view;
8
15
  const { lwrVersion, format, hmrEnabled, bundle, debug, minify } = runtimeEnvironment;
9
16
  const { customElements } = viewMetadata;
10
17
  const version = lwrVersion;
11
18
  const isAMD = format === 'amd';
12
- // Application Bootstrap (ABS) module resource: "@lwrjs/app-service/{appName}/module/{format}"
19
+ // The Application Bootstrap (ABS) module resource is EITHER
20
+ // - configured as routes[x].bootstrap.module OR
21
+ // - defaulted as "@lwrjs/app-service/{appName}/module/{format}"
13
22
  const appIdentity = {
14
23
  appName,
15
24
  format: runtimeEnvironment.format,
16
25
  resourceType: AppResourceEnum.MODULE,
17
26
  };
18
- const bootstrapSpecifier = getAppSpecifier(appIdentity);
27
+ const bootstrapSpecifier = bootstrapModule || getAppSpecifier(appIdentity);
19
28
  /*
20
29
  Internal module and module dependency related resources used by the view to render view related components.
21
30
  */
31
+ const preloadModuleUris = new Set();
22
32
  const moduleResources = [];
23
33
  /*
24
34
  External resources that the view depends. These resources include ones that an ViewDefinition client are required to load
@@ -37,26 +47,21 @@ export async function getHtmlResources(view, viewParams, resourceContext) {
37
47
  const rootComponents = [];
38
48
  // Collection of modules specifiers that MUST be loaded in the view
39
49
  const requiredAmdModules = [];
40
- // Collection of modules that will be loaded in the view
50
+ // Collection of modules that will be preloaded. For AMD, it will be part of
51
+ // the preloadModules client bootstrap config
41
52
  const preloadAmdModules = [];
42
53
  // Determine if server side rendering view modules
43
54
  const isSSR = view.bootstrap?.ssr;
44
55
  // ------ AMD Required module resources
45
56
  if (isAMD) {
46
57
  // Keep shim format in sync with view_bootstrap.ts
47
- const shimBundle = !bundle
48
- ? 'lwr-loader-shim-legacy.js'
49
- : debug || minify === false
50
- ? 'lwr-loader-shim-legacy.bundle.js'
51
- : 'lwr-loader-shim-legacy.bundle.min.js';
58
+ const shimBundle = debug || minify === false
59
+ ? 'lwr-loader-shim-legacy.bundle.js'
60
+ : 'lwr-loader-shim-legacy.bundle.min.js';
52
61
  const def = (await resourceRegistry.getResource({ specifier: shimBundle, version }, runtimeEnvironment, runtimeParams));
53
62
  if (!def) {
54
63
  throw Error('Failed to find definition of resource: ' + shimBundle);
55
64
  }
56
- // HACK: preemptively closing the stream because it is never read
57
- if (def.stream) {
58
- def.stream.destroy();
59
- }
60
65
  requiredResources.push(def);
61
66
  // Always inline the error shim script after the shim
62
67
  const errorShimDef = (await resourceRegistry.getResource({ specifier: 'lwr-error-shim.js', version }, runtimeEnvironment, runtimeParams));
@@ -64,30 +69,55 @@ export async function getHtmlResources(view, viewParams, resourceContext) {
64
69
  throw Error('Failed to find definition of resource: lwr-error-shim.js');
65
70
  }
66
71
  requiredResources.push(errorShimDef);
67
- // Add loader, if not already bundled with the shim
68
- if (!bundle) {
69
- // needed because we're resolving against fully-linked modules
70
- requiredResources.push(await getModuleResource({
71
- specifier: 'lwr/loaderLegacy',
72
- version,
73
- }, runtimeEnvironment, {
74
- isPreload: false,
75
- isSSR,
76
- }, moduleRegistry, runtimeParams));
77
- }
78
72
  }
79
73
  // ------- Application Bootstrap module
80
74
  // Traversal of the Bootstrap Module Graph is done to get all the URLS for discoverable static dependencies.
81
- // Reasoning: This is to avoid unecessary HTTP 302's during initial application module fetching.
75
+ // Reasoning: This is to avoid unnecessary HTTP 302's during initial application module fetching.
82
76
  // Scope: ESM currently only exposes immutable URI references, optimize for AMD formats
83
77
  const depth = isAMD
84
78
  ? { static: GraphDepth.ALL, dynamic: 1 }
85
79
  : { static: GraphDepth.NONE, dynamic: 0 };
86
- const bootstrapModuleGraph = await getModuleGraphs(bootstrapSpecifier, { includeUris: true, includeLinkedDefinitions: true, depth }, moduleRegistry, bundle ? moduleBundler : moduleRegistry, runtimeEnvironment, runtimeParams, visitedCache);
80
+ const defRegistry = bundle ? moduleBundler : moduleRegistry;
81
+ const bootstrapModuleGraph = await getModuleGraphs(bootstrapSpecifier, { includeUris: true, includeLinkedDefinitions: true, depth }, moduleRegistry, defRegistry, runtimeEnvironment, runtimeParams, visitedCache);
87
82
  // ADD bootstrap module uri as a script resource
88
83
  const versionedSpecifier = bootstrapModuleGraph.graphs[0].specifier;
89
84
  const uri = bootstrapModuleGraph.uriMap[versionedSpecifier];
90
85
  moduleResources.push(getModuleResourceByUri(uri, runtimeEnvironment, { isPreload: false, isSSR }));
86
+ // PRELOAD the bootstrap module static dependencies as preloaded script resources
87
+ for (const depSpecifier of bootstrapModuleGraph.graphs[0].static) {
88
+ if (!isExternal(depSpecifier)) {
89
+ preloadModuleUris.add(bootstrapModuleGraph.uriMap[depSpecifier]);
90
+ // in AMD, we also need to tell the loader it's being preloaded
91
+ preloadAmdModules.push(depSpecifier);
92
+ }
93
+ }
94
+ // PRELOAD configured preloadModules as preloaded script resources
95
+ for (let i = 0; i < preloadModules.length; i++) {
96
+ const specifier = preloadModules[i];
97
+ if (isExternal(specifier)) {
98
+ logger.warn(`"${specifier}" is configured in both bundleConfig.externals and bootstrap.preloadModules. We are treating it as external.`);
99
+ }
100
+ else {
101
+ // eslint-disable-next-line no-await-in-loop
102
+ const versionedModuleId = await getVersionedModuleId(specifier, moduleRegistry);
103
+ const versionedModuleSpecifier = getSpecifier({
104
+ specifier,
105
+ version: normalizeVersionToUri(versionedModuleId.version),
106
+ });
107
+ const uri = bootstrapModuleGraph.uriMap[versionedModuleSpecifier] ||
108
+ // eslint-disable-next-line no-await-in-loop
109
+ (await defRegistry.resolveModuleUri(versionedModuleId, runtimeEnvironment, runtimeParams));
110
+ preloadModuleUris.add(uri);
111
+ // in AMD, we also need to tell the loader it's being preloaded
112
+ if (versionedModuleId.version == VERSION_NOT_PROVIDED) {
113
+ // If this is explicitly a non versioned specifier from static metadata key off the non versioned specifier
114
+ preloadAmdModules.push(specifier);
115
+ }
116
+ else {
117
+ preloadAmdModules.push(versionedModuleSpecifier);
118
+ }
119
+ }
120
+ }
91
121
  if (isAMD) {
92
122
  // ADD bootstrap module as required
93
123
  requiredAmdModules.push(versionedSpecifier);
@@ -100,8 +130,6 @@ export async function getHtmlResources(view, viewParams, resourceContext) {
100
130
  imports[staticDep] = uri;
101
131
  // ADD bootstrap module static deps to requiredAmdModules if services, otherwise preloadModules
102
132
  if (services && services.length) {
103
- // get the graphs for the bs static deps
104
- moduleResources.push(getModuleResourceByUri(uri, runtimeEnvironment, { isPreload: true, isSSR }));
105
133
  requiredAmdModules.push(staticDep);
106
134
  }
107
135
  }
@@ -120,13 +148,23 @@ export async function getHtmlResources(view, viewParams, resourceContext) {
120
148
  const customElementsRecords = [];
121
149
  const flattenedElements = flattenCustomElements(customElements, isSSR);
122
150
  await Promise.all(flattenedElements.map(async ({ tagName: element, props }) => {
123
- const graph = await getModuleGraphs(kebabCaseToModuleSpecifer(element), { includeUris: true, includeLinkedDefinitions: true, depth }, moduleRegistry, bundle ? moduleBundler : moduleRegistry, runtimeEnvironment, runtimeParams ? runtimeParams : {}, visitedCache);
151
+ const graph = await getModuleGraphs(kebabCaseToModuleSpecifier(element), { includeUris: true, includeLinkedDefinitions: true, depth }, moduleRegistry, defRegistry, runtimeEnvironment, runtimeParams ? runtimeParams : {}, visitedCache);
124
152
  // add to the viewRecord
125
153
  customElementsRecords.push({ elementName: element, flatGraph: graph });
126
- // PRELOAD custom element static deps as link resource
154
+ // PRELOAD the custom element module as a link resource
127
155
  const specifier = graph.graphs[0].specifier;
128
156
  const uri = graph.uriMap[specifier];
129
157
  moduleResources.push(getModuleResourceByUri(uri, runtimeEnvironment, { isPreload: true, isSSR }));
158
+ // PRELOAD custom element static deps as link resources when bundling is ON
159
+ if (bundle) {
160
+ for (const depSpecifier of graph.graphs[0].static) {
161
+ if (!isExternal(depSpecifier)) {
162
+ preloadModuleUris.add(graph.uriMap[depSpecifier]);
163
+ // in AMD, we also need to tell the loader it's being preloaded
164
+ preloadAmdModules.push(depSpecifier);
165
+ }
166
+ }
167
+ }
130
168
  // ADD register custom elements as a uri addressable rootComponents
131
169
  rootComponents.push(specifier);
132
170
  imports[specifier] = uri;
@@ -144,6 +182,7 @@ export async function getHtmlResources(view, viewParams, resourceContext) {
144
182
  }
145
183
  }
146
184
  }));
185
+ const dedupedPreloadAmdModules = [...new Set(preloadAmdModules)];
147
186
  // ADD configuration of the bootstrapModule
148
187
  configResources.unshift(await getViewBootstrapConfigurationResource({
149
188
  id: view.id,
@@ -159,11 +198,15 @@ export async function getHtmlResources(view, viewParams, resourceContext) {
159
198
  },
160
199
  rootComponents,
161
200
  ...(isAMD && { requiredModules: requiredAmdModules }),
162
- ...(isAMD && { preloadModules: preloadAmdModules }),
201
+ ...(isAMD && { preloadModules: dedupedPreloadAmdModules }),
163
202
  }, runtimeEnvironment, runtimeParams));
164
203
  if (!isAMD && hmrEnabled) {
165
204
  configResources.unshift(await getViewHmrConfigurationResource(view, viewMetadata));
166
205
  }
206
+ // PRELOAD script resources for preload module URIs at the top (ie: bootstrap and root component static dependencies)
207
+ for (const preloadUri of preloadModuleUris) {
208
+ moduleResources.unshift(getModuleResourceByUri(preloadUri, runtimeEnvironment, { isPreload: true, isSSR }));
209
+ }
167
210
  // generate html partial
168
211
  const htmlResources = await Promise.all([...configResources, ...requiredResources, ...moduleResources].map(generateHtmlTag));
169
212
  return {
@@ -1,4 +1,4 @@
1
- import { ModuleRegistry, LinkedViewDefinition, RenderedViewMetadata, ResourceRegistry, RuntimeEnvironment, RuntimeParams, View, ModuleBundler, ViewParams } from '@lwrjs/types';
1
+ import { ModuleRegistry, LinkedViewDefinition, RenderedViewMetadata, ResourceRegistry, RuntimeEnvironment, RuntimeParams, View, ModuleBundler, ViewParams, BundleConfig } from '@lwrjs/types';
2
2
  export interface LwrResourcesLinkedContext extends ResourceContext {
3
3
  lwrResourcesId: string;
4
4
  }
@@ -9,6 +9,7 @@ interface ResourceContext {
9
9
  moduleRegistry: ModuleRegistry;
10
10
  moduleBundler: ModuleBundler;
11
11
  resourceRegistry: ResourceRegistry;
12
+ bundleConfig: BundleConfig;
12
13
  }
13
14
  declare type LinkedResourcesViewDefinition = Pick<LinkedViewDefinition, 'renderedView' | 'viewRecord'>;
14
15
  export declare function linkLwrResources(source: string, view: View, viewParams: ViewParams, cxt: LwrResourcesLinkedContext): Promise<LinkedResourcesViewDefinition>;
@@ -25,6 +25,7 @@ export function getViewBootstrapConfigurationResource(viewInfo, config, runtimeE
25
25
  ...config,
26
26
  endpoints,
27
27
  })});`,
28
+ // TODO: W-12639529 change after addressing downstream customers
28
29
  `globalThis.process = { env: { NODE_ENV: "${runtimeEnvironment.serverMode}" } };`,
29
30
  ]
30
31
  .filter(Boolean)
@@ -1,4 +1,4 @@
1
- import { ModuleRegistry, RenderedViewMetadata, RenderedViewRecord, ResourceRegistry, RuntimeEnvironment, RuntimeParams, View, ModuleBundler, ViewParams } from '@lwrjs/types';
1
+ import { BundleConfig, ModuleRegistry, RenderedViewMetadata, RenderedViewRecord, ResourceRegistry, RuntimeEnvironment, RuntimeParams, View, ModuleBundler, ViewParams } from '@lwrjs/types';
2
2
  export interface LwrResourcesLinkedContext extends ResourceContext {
3
3
  lwrResourcesId: string;
4
4
  }
@@ -9,6 +9,7 @@ interface ResourceContext {
9
9
  moduleRegistry: ModuleRegistry;
10
10
  moduleBundler: ModuleBundler;
11
11
  resourceRegistry: ResourceRegistry;
12
+ bundleConfig: BundleConfig;
12
13
  }
13
14
  export declare function getHtmlResources(view: View, viewParams: ViewParams, resourceContext: ResourceContext): Promise<{
14
15
  partial: string;
@@ -1,24 +1,35 @@
1
- import { kebabCaseToModuleSpecifer, toImportMetadata, getModuleGraphs, getMappingUriPrefix, GraphDepth, logger, } from '@lwrjs/shared-utils';
1
+ import { kebabCaseToModuleSpecifier, toImportMetadata, getModuleGraphs, getMappingUriPrefix, GraphDepth, logger, getVersionedModuleId, explodeSpecifier, getSpecifier, normalizeVersionToUri, VERSION_NOT_PROVIDED, } from '@lwrjs/shared-utils';
2
2
  import { AppResourceEnum, getAppSpecifier } from '@lwrjs/app-service/identity';
3
- import { generateHtmlTag, getModuleResource, getModuleResourceByUri } from '../utils.js';
3
+ import { generateHtmlTag, getModuleResourceByUri } from '../utils.js';
4
4
  import { flattenCustomElements, getViewBootstrapConfigurationResource, getViewHmrConfigurationResource, } from './utils.js';
5
5
  export async function getHtmlResources(view, viewParams, resourceContext) {
6
- const { runtimeEnvironment, runtimeParams, moduleRegistry, moduleBundler, resourceRegistry, viewMetadata, } = resourceContext;
7
- const { id: appName, bootstrap: { services } = { services: [] } } = view;
6
+ const { runtimeEnvironment, runtimeParams, moduleRegistry, moduleBundler, resourceRegistry, viewMetadata, bundleConfig: { external = {} }, } = resourceContext;
7
+ const isExternal = function (rawSpecifier) {
8
+ const { specifier } = explodeSpecifier(rawSpecifier);
9
+ return Object.keys(external).some((e) => specifier === e);
10
+ };
11
+ const { id: appName, bootstrap: { services, module: bootstrapModule, preloadModules = [] } = {
12
+ services: [],
13
+ preloadModules: [],
14
+ }, } = view;
8
15
  const { lwrVersion, format, hmrEnabled, bundle, debug, minify } = runtimeEnvironment;
9
16
  const { customElements } = viewMetadata;
17
+ const defRegistry = bundle ? moduleBundler : moduleRegistry;
10
18
  const version = lwrVersion;
11
19
  const isAMD = format === 'amd';
12
- // Application Bootstrap (ABS) module resource: "@lwrjs/app-service/{appName}/module/{format}"
20
+ // The Application Bootstrap (ABS) module resource is EITHER
21
+ // - configured as routes[x].bootstrap.module OR
22
+ // - defaulted as "@lwrjs/app-service/{appName}/module/{format}"
13
23
  const appIdentity = {
14
24
  appName,
15
25
  format: runtimeEnvironment.format,
16
26
  resourceType: AppResourceEnum.MODULE,
17
27
  };
18
- const bootstrapSpecifier = getAppSpecifier(appIdentity);
28
+ const bootstrapSpecifier = bootstrapModule || getAppSpecifier(appIdentity);
19
29
  /*
20
30
  Internal module and module dependency related resources used by the view to render view related components.
21
31
  */
32
+ const preloadModuleUris = new Set();
22
33
  const moduleResources = [];
23
34
  /*
24
35
  External resources that the view depends. These resources include ones that an ViewDefinition client are required to load
@@ -37,26 +48,19 @@ export async function getHtmlResources(view, viewParams, resourceContext) {
37
48
  const rootComponents = [];
38
49
  // Collection of modules specifiers that MUST be loaded in the view
39
50
  const requiredAmdModules = [];
40
- // Collection of modules that will be loaded in the view
51
+ // Collection of modules that will be preloaded. For AMD, it will be part of
52
+ // the preloadModules client bootstrap config
41
53
  const preloadAmdModules = [];
42
54
  // Determine if server side rendering view modules
43
55
  const isSSR = view.bootstrap?.ssr;
44
56
  // ------ AMD Required module resources
45
57
  if (isAMD) {
46
58
  // Keep shim format in sync with legacy_view_bootstrap.ts
47
- const shimBundle = !bundle
48
- ? 'lwr-loader-shim.js'
49
- : debug || minify === false
50
- ? 'lwr-loader-shim.bundle.js'
51
- : 'lwr-loader-shim.bundle.min.js';
59
+ const shimBundle = debug || minify === false ? 'lwr-loader-shim.bundle.js' : 'lwr-loader-shim.bundle.min.js';
52
60
  const def = (await resourceRegistry.getResource({ specifier: shimBundle, version }, runtimeEnvironment, runtimeParams));
53
61
  if (!def) {
54
62
  throw Error('Failed to find definition of resource: ' + shimBundle);
55
63
  }
56
- // HACK: preemptively closing the stream because it is never read
57
- if (def.stream) {
58
- def.stream.destroy();
59
- }
60
64
  requiredResources.push(def);
61
65
  // Always inline the error shim script after the shim
62
66
  const errorShimDef = (await resourceRegistry.getResource({ specifier: 'lwr-error-shim.js', version }, runtimeEnvironment, runtimeParams));
@@ -64,16 +68,6 @@ export async function getHtmlResources(view, viewParams, resourceContext) {
64
68
  throw Error('Failed to find definition of resource: lwr-error-shim.js');
65
69
  }
66
70
  requiredResources.push(errorShimDef);
67
- // Add loader, if not already bundled with the shim
68
- if (!bundle) {
69
- // needed because we're resolving against fully-linked modules
70
- requiredResources.push(await getModuleResource({
71
- specifier: 'lwr/loader',
72
- version,
73
- }, runtimeEnvironment, {
74
- isSSR,
75
- }, moduleRegistry, runtimeParams));
76
- }
77
71
  }
78
72
  // ------- Application Bootstrap module
79
73
  // Traversal of the Bootstrap Module Graph is done to get all the URLS for discoverable static dependencies.
@@ -81,11 +75,46 @@ export async function getHtmlResources(view, viewParams, resourceContext) {
81
75
  const depth = isAMD
82
76
  ? { static: GraphDepth.ALL, dynamic: 1 }
83
77
  : { static: GraphDepth.NONE, dynamic: 1 };
84
- const bootstrapModuleGraph = await getModuleGraphs(bootstrapSpecifier, { includeUris: true, includeLinkedDefinitions: true, depth }, moduleRegistry, bundle ? moduleBundler : moduleRegistry, runtimeEnvironment, runtimeParams, visitedCache);
78
+ const bootstrapModuleGraph = await getModuleGraphs(bootstrapSpecifier, { includeUris: true, includeLinkedDefinitions: true, depth }, moduleRegistry, defRegistry, runtimeEnvironment, runtimeParams, visitedCache);
85
79
  // ADD bootstrap module uri as a script resource
86
80
  const versionedSpecifier = bootstrapModuleGraph.graphs[0].specifier;
87
81
  const uri = bootstrapModuleGraph.uriMap[versionedSpecifier];
88
82
  moduleResources.push(getModuleResourceByUri(uri, runtimeEnvironment, { isPreload: false, isSSR }));
83
+ // PRELOAD the bootstrap module static dependencies as preloaded script resources
84
+ for (const depSpecifier of bootstrapModuleGraph.graphs[0].static) {
85
+ if (!isExternal(depSpecifier)) {
86
+ preloadModuleUris.add(bootstrapModuleGraph.uriMap[depSpecifier]);
87
+ // in AMD, we also need to tell the loader it's being preloaded
88
+ preloadAmdModules.push(depSpecifier);
89
+ }
90
+ }
91
+ // PRELOAD configured preloadModules as preloaded script resources
92
+ for (let i = 0; i < preloadModules.length; i++) {
93
+ const specifier = preloadModules[i];
94
+ if (isExternal(specifier)) {
95
+ logger.warn(`"${specifier}" is configured in both bundleConfig.externals and bootstrap.preloadModules. We are treating it as external.`);
96
+ }
97
+ else {
98
+ // eslint-disable-next-line no-await-in-loop
99
+ const versionedModuleId = await getVersionedModuleId(specifier, moduleRegistry);
100
+ const versionedModuleSpecifier = getSpecifier({
101
+ specifier,
102
+ version: normalizeVersionToUri(versionedModuleId.version),
103
+ });
104
+ const uri = bootstrapModuleGraph.uriMap[versionedModuleSpecifier] ||
105
+ // eslint-disable-next-line no-await-in-loop
106
+ (await defRegistry.resolveModuleUri(versionedModuleId, runtimeEnvironment, runtimeParams));
107
+ preloadModuleUris.add(uri);
108
+ // in AMD, we also need to tell the loader it's being preloaded
109
+ if (versionedModuleId.version == VERSION_NOT_PROVIDED) {
110
+ // If this is explicitly a non versioned specifier from static metadata key off the non versioned specifier
111
+ preloadAmdModules.push(specifier);
112
+ }
113
+ else {
114
+ preloadAmdModules.push(versionedModuleSpecifier);
115
+ }
116
+ }
117
+ }
89
118
  if (isAMD) {
90
119
  // ADD bootstrap module as required
91
120
  requiredAmdModules.push(versionedSpecifier);
@@ -98,8 +127,6 @@ export async function getHtmlResources(view, viewParams, resourceContext) {
98
127
  imports[staticDep] = uri;
99
128
  // ADD bootstrap module static deps to requiredAmdModules if services, otherwise preloadModules
100
129
  if (services && services.length) {
101
- // get the graphs for the bs static deps
102
- moduleResources.push(getModuleResourceByUri(uri, runtimeEnvironment, { isPreload: true, isSSR }));
103
130
  requiredAmdModules.push(staticDep);
104
131
  }
105
132
  }
@@ -118,14 +145,25 @@ export async function getHtmlResources(view, viewParams, resourceContext) {
118
145
  // ------- View related custom element moduleResources
119
146
  const customElementsRecords = [];
120
147
  const flattenedElements = flattenCustomElements(customElements, isSSR);
121
- await Promise.all(flattenedElements.map(async ({ tagName: element, props }) => {
122
- const graph = await getModuleGraphs(kebabCaseToModuleSpecifer(element), { includeUris: true, includeLinkedDefinitions: true, depth }, moduleRegistry, bundle ? moduleBundler : moduleRegistry, runtimeEnvironment, runtimeParams ? runtimeParams : {}, visitedCache);
148
+ for (const { tagName: element } of flattenedElements) {
149
+ // eslint-disable-next-line no-await-in-loop
150
+ const graph = await getModuleGraphs(kebabCaseToModuleSpecifier(element), { includeUris: true, includeLinkedDefinitions: true, depth }, moduleRegistry, defRegistry, runtimeEnvironment, runtimeParams ? runtimeParams : {}, visitedCache);
123
151
  // add to the viewRecord
124
152
  customElementsRecords.push({ elementName: element, flatGraph: graph });
125
- // PRELOAD custom element static deps as link resource
153
+ // PRELOAD the custom element module as a link resource
126
154
  const specifier = graph.graphs[0].specifier;
127
155
  const uri = graph.uriMap[specifier];
128
156
  moduleResources.push(getModuleResourceByUri(uri, runtimeEnvironment, { isPreload: true, isSSR }));
157
+ // PRELOAD custom element static deps as link resources when bundling is ON
158
+ if (bundle) {
159
+ for (const depSpecifier of graph.graphs[0].static) {
160
+ if (!isExternal(depSpecifier)) {
161
+ preloadModuleUris.add(graph.uriMap[depSpecifier]);
162
+ // in AMD, we also need to tell the loader it's being preloaded
163
+ preloadAmdModules.push(depSpecifier);
164
+ }
165
+ }
166
+ }
129
167
  // ADD register custom elements as a uri addressable rootComponents
130
168
  rootComponents.push(specifier);
131
169
  imports[specifier] = uri;
@@ -142,8 +180,10 @@ export async function getHtmlResources(view, viewParams, resourceContext) {
142
180
  imports[dynamicDep] = uri;
143
181
  }
144
182
  }
183
+ // eslint-disable-next-line no-await-in-loop
145
184
  importMetadata = await toImportMetadata(graph, importMetadata, moduleRegistry, runtimeEnvironment, runtimeParams);
146
- }));
185
+ }
186
+ const dedupedPreloadAmdModules = [...new Set(preloadAmdModules)];
147
187
  // ADD configuration of the bootstrapModule
148
188
  configResources.unshift(await getViewBootstrapConfigurationResource({
149
189
  id: view.id,
@@ -157,11 +197,15 @@ export async function getHtmlResources(view, viewParams, resourceContext) {
157
197
  index: importMetadata?.index,
158
198
  rootComponents,
159
199
  ...(isAMD && { requiredModules: requiredAmdModules }),
160
- ...(isAMD && { preloadModules: preloadAmdModules }),
200
+ ...(isAMD && { preloadModules: dedupedPreloadAmdModules }),
161
201
  }, runtimeEnvironment, runtimeParams));
162
202
  if (!isAMD && hmrEnabled) {
163
203
  configResources.unshift(await getViewHmrConfigurationResource(view, viewMetadata));
164
204
  }
205
+ // PRELOAD script resources for preload module URIs at the top (ie: bootstrap and root component static dependencies)
206
+ for (const preloadUri of preloadModuleUris) {
207
+ moduleResources.unshift(getModuleResourceByUri(preloadUri, runtimeEnvironment, { isPreload: true, isSSR }));
208
+ }
165
209
  // generate html partial
166
210
  const htmlResources = await Promise.all([...configResources, ...requiredResources, ...moduleResources].map(generateHtmlTag));
167
211
  const mapping = getMappingUriPrefix(runtimeEnvironment, runtimeParams);
@@ -1,5 +1,4 @@
1
- import { NormalizedRenderingResult, RenderingResult, ResourceDefinition, AssetReference, RenderedAssetReference, RenderOptions, ModuleId, ViewModuleResourceContext, ViewPageContext, JsonCompatible } from '@lwrjs/types';
2
- import { PublicModuleRegistry, RuntimeEnvironment, RuntimeParams, ModuleJson, RouteHandlerViewResponse, ViewResponse, RouteHandlerFunction, LwrRoute, LwrErrorRoute, ViewRequest, LinkedViewDefinition, ModuleRegistry } from 'packages/@lwrjs/types/src';
1
+ import type { AssetReference, JsonCompatible, LinkedViewDefinition, LwrErrorRoute, LwrRoute, ModuleBundler, ModuleId, ModuleJson, ModuleRegistry, NormalizedRenderingResult, PublicModuleRegistry, RenderOptions, RenderedAssetReference, RenderingResult, ResourceDefinition, RouteHandlerViewResponse, RuntimeEnvironment, RuntimeParams, ViewModuleResourceContext, ViewPageContext, ViewRequest, ViewResponse } from '@lwrjs/types';
3
2
  export declare type HTMLResource = Partial<ResourceDefinition>;
4
3
  export declare function generateHtmlTag(definition: HTMLResource): Promise<string>;
5
4
  export declare function normalizeRenderedResult({ renderedView, metadata, options, }: RenderingResult): NormalizedRenderingResult;
@@ -7,19 +6,8 @@ export declare function reduceSourceAssetReferences(assets: AssetReference[]): R
7
6
  export declare function normalizeRenderOptions(runtimeEnvironment: RuntimeEnvironment, overrideRenderOptions?: RenderOptions, baseRenderOptions?: RenderOptions): Required<RenderOptions>;
8
7
  export declare function generatePageContext({ requestPath: url }: ViewRequest, { id, contentTemplate, properties }: LwrRoute | LwrErrorRoute): JsonCompatible<ViewPageContext>;
9
8
  export declare function isViewResponse(response: RouteHandlerViewResponse): response is ViewResponse;
10
- interface RouteHandlerContext {
11
- cacheDir: string;
12
- rootDir: string;
13
- }
14
- /**
15
- * Load and cache a route handler function (for a view) from the fs
16
- * @param path - path to the route handle code on the fs
17
- * @param param1 - directories
18
- */
19
- export declare function getRouteHandler(path: string, { cacheDir, rootDir }: RouteHandlerContext): Promise<RouteHandlerFunction>;
20
9
  export declare function toJsonFormat(viewRequest: ViewRequest, viewDefinition: LinkedViewDefinition, route: LwrRoute | LwrErrorRoute, runtimeEnvironment: RuntimeEnvironment, runtimeParams: RuntimeParams, moduleRegistry: ModuleRegistry): Promise<ViewResponse>;
21
- export declare function getModuleResource(moduleId: Pick<ModuleId, 'specifier' | 'version'>, runtimeEnvironment: RuntimeEnvironment, moduleResouceMeta: ViewModuleResourceContext, moduleRegistry: ModuleRegistry, runtimeParams?: RuntimeParams): Promise<ResourceDefinition>;
10
+ export declare function getModuleResource(moduleId: Pick<ModuleId, 'specifier' | 'version'>, runtimeEnvironment: RuntimeEnvironment, moduleResouceMeta: ViewModuleResourceContext, defRegistry: ModuleRegistry | ModuleBundler, runtimeParams?: RuntimeParams): Promise<ResourceDefinition>;
22
11
  export declare function getModuleResourceByUri(uri: string, runtimeEnvironment: RuntimeEnvironment, moduleResouceMeta: ViewModuleResourceContext): ResourceDefinition;
23
12
  export declare function createJsonModule(specifier: string, moduleRegistry: PublicModuleRegistry, environment: RuntimeEnvironment, params?: RuntimeParams): Promise<ModuleJson>;
24
- export {};
25
13
  //# sourceMappingURL=utils.d.ts.map
package/build/es/utils.js CHANGED
@@ -1,9 +1,6 @@
1
- import { explodeSpecifier, getMappingUriPrefix, getSpecifier, resolveFileExtension, transpileTs, DEFAULT_TITLE, } from '@lwrjs/shared-utils';
2
- import libPath from 'path';
3
1
  import { basename, extname } from 'path';
4
- import { mimeLookup } from '@lwrjs/shared-utils';
2
+ import { explodeSpecifier, getMappingUriPrefix, getSpecifier, getClientBootstrapConfigurationUri, mimeLookup, DEFAULT_TITLE, } from '@lwrjs/shared-utils';
5
3
  import { AppResourceEnum, getAppSpecifier, ResourceIdentityTypes, } from '@lwrjs/app-service/identity';
6
- import { getClientBootstrapConfigurationUri } from '@lwrjs/shared-utils';
7
4
  function streamToString(stream) {
8
5
  const chunks = [];
9
6
  return new Promise((resolve, reject) => {
@@ -51,7 +48,7 @@ async function generateInlineTag({ specifier, type, content, stream, nonce }) {
51
48
  if (!content && !stream) {
52
49
  throw new Error(`Invalid inline Resource Definition: must have either "content" or "stream": "${specifier}"`);
53
50
  }
54
- const code = content ? content : await streamToString(stream);
51
+ const code = stream ? await streamToString(stream()) : content;
55
52
  return `<${tag}${typeStr}${nonceStr}>${code}</${tag}>`;
56
53
  }
57
54
  export async function generateHtmlTag(definition) {
@@ -110,25 +107,6 @@ export function generatePageContext({ requestPath: url }, { id, contentTemplate,
110
107
  export function isViewResponse(response) {
111
108
  return response.body !== undefined;
112
109
  }
113
- /**
114
- * Load and cache a route handler function (for a view) from the fs
115
- * @param path - path to the route handle code on the fs
116
- * @param param1 - directories
117
- */
118
- export async function getRouteHandler(path, { cacheDir, rootDir }) {
119
- try {
120
- const fullPath = resolveFileExtension(path);
121
- if (fullPath.endsWith('.ts')) {
122
- path = await transpileTs(path, { rootDir, cacheDir: libPath.join(cacheDir, 'routeHandlers') });
123
- }
124
- const moduleEntry = await import(path);
125
- return moduleEntry.default || moduleEntry;
126
- }
127
- catch (err) {
128
- console.log(err);
129
- throw new Error(`Unable to get routeHandler: ${path}`);
130
- }
131
- }
132
110
  export async function toJsonFormat(viewRequest, viewDefinition, route, runtimeEnvironment, runtimeParams, moduleRegistry) {
133
111
  const { viewRecord } = viewDefinition;
134
112
  const { bootstrap, id: appName } = route;
@@ -213,10 +191,10 @@ export async function toJsonFormat(viewRequest, viewDefinition, route, runtimeEn
213
191
  },
214
192
  };
215
193
  }
216
- export async function getModuleResource(moduleId, runtimeEnvironment, moduleResouceMeta, moduleRegistry, runtimeParams) {
194
+ export async function getModuleResource(moduleId, runtimeEnvironment, moduleResouceMeta, defRegistry, runtimeParams) {
217
195
  const { format } = runtimeEnvironment;
218
196
  const { isSSR = false, isPreload = false } = moduleResouceMeta;
219
- const moduleUri = await moduleRegistry.resolveModuleUri(moduleId, runtimeEnvironment, runtimeParams);
197
+ const moduleUri = await defRegistry.resolveModuleUri(moduleId, runtimeEnvironment, runtimeParams);
220
198
  return {
221
199
  src: moduleUri,
222
200
  type: format === 'amd' ? 'application/javascript' : 'module',
@@ -257,7 +235,7 @@ export async function createJsonModule(specifier, moduleRegistry, environment, p
257
235
  version,
258
236
  ownHash,
259
237
  links: {
260
- self: moduleRegistry.resolveModuleUri(moduleIdentifier, environment, params, ownHash),
238
+ self: await moduleRegistry.resolveModuleUri(moduleIdentifier, environment, params, ownHash),
261
239
  },
262
240
  };
263
241
  }
@@ -1,14 +1,14 @@
1
- import { ViewRegistry, RuntimeEnvironment, NormalizedLwrGlobalConfig, ViewRequest, RuntimeParams, ViewResponse, LwrErrorRoute, LwrRoute, ModuleRegistry, RouteHandlerFunction } from '@lwrjs/types';
1
+ import { ViewRegistry, RuntimeEnvironment, NormalizedLwrGlobalConfig, ViewRequest, RuntimeParams, ViewResponse, LwrRoute, LwrErrorRoute, ModuleRegistry, ViewHandler, RouteHandlers } from '@lwrjs/types';
2
2
  export interface ViewHandlerContext {
3
3
  viewRegistry: ViewRegistry;
4
4
  moduleRegistry: ModuleRegistry;
5
+ routeHandlers: RouteHandlers;
5
6
  }
6
- export declare class LwrViewHandler {
7
+ export declare class LwrViewHandler implements ViewHandler {
8
+ globalConfig: NormalizedLwrGlobalConfig;
9
+ routeHandlers: RouteHandlers;
7
10
  viewRegistry: ViewRegistry;
8
11
  moduleRegistry: ModuleRegistry;
9
- globalConfig: NormalizedLwrGlobalConfig;
10
- inflightRouteHandlerEvalMap: Map<string, Promise<RouteHandlerFunction>>;
11
- routeHandlerFunctionMap: Map<string, RouteHandlerFunction>;
12
12
  constructor(context: ViewHandlerContext, globalConfig: NormalizedLwrGlobalConfig);
13
13
  getViewContent(viewRequest: ViewRequest, route: LwrRoute | LwrErrorRoute, runtimeEnvironment: RuntimeEnvironment, runtimeParams?: RuntimeParams): Promise<ViewResponse>;
14
14
  getViewJson(viewRequest: ViewRequest, route: LwrRoute | LwrErrorRoute, runtimeEnvironment: RuntimeEnvironment, runtimeParams?: RuntimeParams): Promise<ViewResponse>;