@lwrjs/view-registry 0.9.0-alpha.9 → 0.9.0

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,21 +1,32 @@
1
- import { kebabCaseToModuleSpecifer, getModuleGraphs, GraphDepth, getModuleUriPrefix, logger, } from '@lwrjs/shared-utils';
1
+ import { kebabCaseToModuleSpecifier, getModuleGraphs, GraphDepth, getModuleUriPrefix, logger, explodeSpecifier, isBundler, } from '@lwrjs/shared-utils';
2
2
  import { AppResourceEnum, getAppSpecifier } from '@lwrjs/app-service/identity';
3
- import { generateHtmlTag, getModuleResource, getModuleResourceByUri } from '../utils.js';
4
- import { flattenCustomElements, getViewBootstrapConfigurationResource, getViewHmrConfigurationResource, } from './utils.js';
3
+ import { generateHtmlTag, getModuleResourceByUri } from '../utils.js';
4
+ import { flattenCustomElements, getViewBootstrapConfigurationResource, getViewHmrConfigurationResource, getPreloadModulesMeta, } from './utils.js';
5
5
  export async function getHtmlResources(view, viewParams, resourceContext) {
6
6
  const { runtimeEnvironment, runtimeParams, moduleRegistry, moduleBundler, resourceRegistry, viewMetadata, } = resourceContext;
7
- const { id: appName, bootstrap: { services } = { services: [] } } = view;
7
+ const { bundleConfig } = resourceContext;
8
+ const { external = {} } = bundleConfig;
9
+ const isExternal = function (rawSpecifier) {
10
+ const { specifier } = explodeSpecifier(rawSpecifier);
11
+ return Object.keys(external).some((e) => specifier === e);
12
+ };
13
+ const { id: appName, bootstrap: { services, module: bootstrapModule, preloadModules = [] } = {
14
+ services: [],
15
+ preloadModules: [],
16
+ }, } = view;
8
17
  const { lwrVersion, format, hmrEnabled, bundle, debug, minify } = runtimeEnvironment;
9
18
  const { customElements } = viewMetadata;
10
19
  const version = lwrVersion;
11
20
  const isAMD = format === 'amd';
12
- // Application Bootstrap (ABS) module resource: "@lwrjs/app-service/{appName}/module/{format}"
21
+ // The Application Bootstrap (ABS) module resource is EITHER
22
+ // - configured as routes[x].bootstrap.module OR
23
+ // - defaulted as "@lwrjs/app-service/{appName}/module/{format}"
13
24
  const appIdentity = {
14
25
  appName,
15
26
  format: runtimeEnvironment.format,
16
27
  resourceType: AppResourceEnum.MODULE,
17
28
  };
18
- const bootstrapSpecifier = getAppSpecifier(appIdentity);
29
+ const bootstrapSpecifier = bootstrapModule || getAppSpecifier(appIdentity);
19
30
  /*
20
31
  Internal module and module dependency related resources used by the view to render view related components.
21
32
  */
@@ -37,25 +48,34 @@ 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
41
- const preloadAmdModules = [];
51
+ // Collection of modules that will be preloaded. For AMD, it will be part of
52
+ // the preloadModules client bootstrap config
53
+ const preloadModulesMeta = new Map();
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 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';
52
- const def = (await resourceRegistry.getResource({ specifier: shimBundle, version }, runtimeEnvironment, runtimeParams));
59
+ const shimBundle = debug || minify === false
60
+ ? 'lwr-loader-shim-legacy.bundle.js'
61
+ : 'lwr-loader-shim-legacy.bundle.min.js';
62
+ let def = (await resourceRegistry.getResource({ specifier: shimBundle, version }, runtimeEnvironment, runtimeParams));
53
63
  if (!def) {
54
- throw Error('Failed to find definition of resource: ' + shimBundle);
55
- }
56
- // HACK: preemptively closing the stream because it is never read
57
- if (def.stream) {
58
- def.stream.destroy();
64
+ // HACK: fallback to looking for the other shim.
65
+ // TODO: remove this once we solve debug mode in MRT
66
+ let fallbackShimBundle;
67
+ if (shimBundle === 'lwr-loader-shim-legacy.bundle.js') {
68
+ fallbackShimBundle = 'lwr-loader-shim-legacy.bundle.min.js';
69
+ def = (await resourceRegistry.getResource({ specifier: fallbackShimBundle, version }, runtimeEnvironment, runtimeParams));
70
+ }
71
+ else {
72
+ fallbackShimBundle = 'lwr-loader-shim-legacy.bundle.js';
73
+ def = (await resourceRegistry.getResource({ specifier: fallbackShimBundle, version }, runtimeEnvironment, runtimeParams));
74
+ }
75
+ // throw if we still can't find it
76
+ if (!def) {
77
+ throw Error('Failed to find definition of resource: ' + shimBundle);
78
+ }
59
79
  }
60
80
  requiredResources.push(def);
61
81
  // Always inline the error shim script after the shim
@@ -64,30 +84,34 @@ export async function getHtmlResources(view, viewParams, resourceContext) {
64
84
  throw Error('Failed to find definition of resource: lwr-error-shim.js');
65
85
  }
66
86
  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
87
  }
79
88
  // ------- Application Bootstrap module
80
89
  // 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.
90
+ // Reasoning: This is to avoid unnecessary HTTP 302's during initial application module fetching.
82
91
  // Scope: ESM currently only exposes immutable URI references, optimize for AMD formats
83
92
  const depth = isAMD
84
93
  ? { static: GraphDepth.ALL, dynamic: 1 }
85
94
  : { static: GraphDepth.NONE, dynamic: 0 };
86
- const bootstrapModuleGraph = await getModuleGraphs(bootstrapSpecifier, { includeUris: true, includeLinkedDefinitions: true, depth }, moduleRegistry, bundle ? moduleBundler : moduleRegistry, runtimeEnvironment, runtimeParams, visitedCache);
95
+ const defRegistry = bundle ? moduleBundler : moduleRegistry;
96
+ const bootstrapModuleGraph = await getModuleGraphs(bootstrapSpecifier, { includeUris: true, includeLinkedDefinitions: true, depth }, moduleRegistry, defRegistry, runtimeEnvironment, runtimeParams, visitedCache);
87
97
  // ADD bootstrap module uri as a script resource
88
98
  const versionedSpecifier = bootstrapModuleGraph.graphs[0].specifier;
89
99
  const uri = bootstrapModuleGraph.uriMap[versionedSpecifier];
90
100
  moduleResources.push(getModuleResourceByUri(uri, runtimeEnvironment, { isPreload: false, isSSR }));
101
+ // PRELOAD the bootstrap module static dependencies as preloaded script resources
102
+ for (const depSpecifier of bootstrapModuleGraph.graphs[0].static) {
103
+ if (!isExternal(depSpecifier)) {
104
+ const uri = bootstrapModuleGraph.uriMap[depSpecifier];
105
+ preloadModulesMeta.set(depSpecifier, uri);
106
+ }
107
+ }
108
+ // PRELOAD configured preloadModules as preloaded script resources
109
+ if (isBundler(defRegistry)) {
110
+ for (const specifier of preloadModules) {
111
+ // eslint-disable-next-line no-await-in-loop
112
+ await getPreloadModulesMeta(specifier, preloadModulesMeta, bundleConfig, moduleRegistry, defRegistry, runtimeEnvironment, runtimeParams);
113
+ }
114
+ }
91
115
  if (isAMD) {
92
116
  // ADD bootstrap module as required
93
117
  requiredAmdModules.push(versionedSpecifier);
@@ -100,8 +124,6 @@ export async function getHtmlResources(view, viewParams, resourceContext) {
100
124
  imports[staticDep] = uri;
101
125
  // ADD bootstrap module static deps to requiredAmdModules if services, otherwise preloadModules
102
126
  if (services && services.length) {
103
- // get the graphs for the bs static deps
104
- moduleResources.push(getModuleResourceByUri(uri, runtimeEnvironment, { isPreload: true, isSSR }));
105
127
  requiredAmdModules.push(staticDep);
106
128
  }
107
129
  }
@@ -120,18 +142,26 @@ export async function getHtmlResources(view, viewParams, resourceContext) {
120
142
  const customElementsRecords = [];
121
143
  const flattenedElements = flattenCustomElements(customElements, isSSR);
122
144
  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);
145
+ const graph = await getModuleGraphs(kebabCaseToModuleSpecifier(element), { includeUris: true, includeLinkedDefinitions: true, depth }, moduleRegistry, defRegistry, runtimeEnvironment, runtimeParams ? runtimeParams : {}, visitedCache);
124
146
  // add to the viewRecord
125
147
  customElementsRecords.push({ elementName: element, flatGraph: graph });
126
- // PRELOAD custom element static deps as link resource
148
+ // PRELOAD the custom element module as a link resource
127
149
  const specifier = graph.graphs[0].specifier;
128
150
  const uri = graph.uriMap[specifier];
129
- moduleResources.push(getModuleResourceByUri(uri, runtimeEnvironment, { isPreload: true, isSSR }));
151
+ preloadModulesMeta.set(specifier, uri);
152
+ // PRELOAD custom element static deps as link resources when bundling is ON
153
+ if (bundle) {
154
+ for (const depSpecifier of graph.graphs[0].static) {
155
+ if (!isExternal(depSpecifier)) {
156
+ const uri = graph.uriMap[depSpecifier];
157
+ preloadModulesMeta.set(depSpecifier, uri);
158
+ }
159
+ }
160
+ }
130
161
  // ADD register custom elements as a uri addressable rootComponents
131
162
  rootComponents.push(specifier);
132
163
  imports[specifier] = uri;
133
164
  if (isAMD) {
134
- preloadAmdModules.push(specifier);
135
165
  for (const staticDep of graph.graphs[0].static) {
136
166
  const uri = graph.uriMap[staticDep];
137
167
  // AMD ADD static module dep uri addressability
@@ -159,11 +189,16 @@ export async function getHtmlResources(view, viewParams, resourceContext) {
159
189
  },
160
190
  rootComponents,
161
191
  ...(isAMD && { requiredModules: requiredAmdModules }),
162
- ...(isAMD && { preloadModules: preloadAmdModules }),
192
+ // in AMD we need to tell the loader what modules we are preloading
193
+ ...(isAMD && { preloadModules: Array.from(preloadModulesMeta.keys()) }),
163
194
  }, runtimeEnvironment, runtimeParams));
164
195
  if (!isAMD && hmrEnabled) {
165
196
  configResources.unshift(await getViewHmrConfigurationResource(view, viewMetadata));
166
197
  }
198
+ // PRELOAD script resources for preload module URIs after the bootstrap module
199
+ for (const [, preloadUri] of preloadModulesMeta) {
200
+ moduleResources.push(getModuleResourceByUri(preloadUri, runtimeEnvironment, { isPreload: true, isSSR }));
201
+ }
167
202
  // generate html partial
168
203
  const htmlResources = await Promise.all([...configResources, ...requiredResources, ...moduleResources].map(generateHtmlTag));
169
204
  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>;
@@ -1,6 +1,12 @@
1
- import { ClientBootstrapConfig, RuntimeEnvironment, RuntimeParams, ResourceDefinition, RenderedViewMetadata, CustomElementReference } from '@lwrjs/types';
1
+ import { ClientBootstrapConfig, RuntimeEnvironment, RuntimeParams, ResourceDefinition, RenderedViewMetadata, CustomElementReference, BundleConfig, ModuleBundler, ModuleRegistry } from '@lwrjs/types';
2
2
  import { View, ViewInfo } from '@lwrjs/types';
3
3
  export declare function getViewBootstrapConfigurationResource(viewInfo: ViewInfo, config: ClientBootstrapConfig, runtimeEnvironment: RuntimeEnvironment, runtimeParams?: RuntimeParams): ResourceDefinition;
4
4
  export declare function getViewHmrConfigurationResource(view: View, viewMetadata: RenderedViewMetadata): ResourceDefinition;
5
5
  export declare function flattenCustomElements(arr: CustomElementReference[], isSSR?: boolean): CustomElementReference[];
6
+ /**
7
+ * Recursively gets preloadModules metadata starting with a specifer
8
+ * Note: don't call me unless you got bundles
9
+ */
10
+ export declare function getPreloadModulesMeta(specifier: string, // unversioned specifier
11
+ preloadModulesMeta: Map<string, string>, bundleConfig: BundleConfig, moduleRegistry: ModuleRegistry, defRegistry: ModuleBundler, runtimeEnvironment: RuntimeEnvironment, runtimeParams?: RuntimeParams, pending?: Map<string, boolean>): Promise<void>;
6
12
  //# sourceMappingURL=utils.d.ts.map
@@ -1,4 +1,4 @@
1
- import { getMappingUriPrefix, getModuleUriPrefix, getClientBootstrapConfigurationUri, hashContent, } from '@lwrjs/shared-utils';
1
+ import { getMappingUriPrefix, getModuleUriPrefix, getClientBootstrapConfigurationUri, hashContent, getVersionedModuleId, normalizeVersionToUri, logger, VERSION_NOT_PROVIDED, explodeSpecifier, getSpecifier, } from '@lwrjs/shared-utils';
2
2
  const CONTENT_TYPE = 'application/javascript';
3
3
  export function getViewBootstrapConfigurationResource(viewInfo, config, runtimeEnvironment, runtimeParams) {
4
4
  const { compat, debug, hmrEnabled, apiVersion, format } = runtimeEnvironment;
@@ -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)
@@ -99,4 +100,54 @@ export function flattenCustomElements(arr, isSSR = false) {
99
100
  flatten(arr);
100
101
  return ret;
101
102
  }
103
+ /**
104
+ * Recursively gets preloadModules metadata starting with a specifer
105
+ * Note: don't call me unless you got bundles
106
+ */
107
+ export async function getPreloadModulesMeta(specifier, // unversioned specifier
108
+ preloadModulesMeta, bundleConfig, moduleRegistry, defRegistry, runtimeEnvironment, runtimeParams, pending) {
109
+ const { exclude = [], external = {} } = bundleConfig;
110
+ const isExternal = function (rawSpecifier) {
111
+ const { specifier } = explodeSpecifier(rawSpecifier);
112
+ return Object.keys(external).includes(specifier);
113
+ };
114
+ const isExclude = function (specifier) {
115
+ return exclude.includes(specifier);
116
+ };
117
+ if (isExternal(specifier)) {
118
+ logger.warn(`"${specifier}" is configured in both bundleConfig.externals and bootstrap.preloadModules. We are treating it as external.`);
119
+ }
120
+ else {
121
+ // eslint-disable-next-line no-await-in-loop
122
+ const versionedModuleId = await getVersionedModuleId(specifier, moduleRegistry); // TODO replace moduleRegistry with defRegistry
123
+ const versionedModuleSpecifier = getSpecifier({
124
+ specifier,
125
+ version: normalizeVersionToUri(versionedModuleId.version),
126
+ });
127
+ const uri =
128
+ // eslint-disable-next-line no-await-in-loop
129
+ await defRegistry.resolveModuleUri(versionedModuleId, runtimeEnvironment, runtimeParams);
130
+ // fallback to unversioned specifier if needed
131
+ const normalizedSpecifier = versionedModuleId.version === VERSION_NOT_PROVIDED ? specifier : versionedModuleSpecifier;
132
+ preloadModulesMeta.set(normalizedSpecifier, uri);
133
+ if (exclude.length) {
134
+ // check if we need to also preload any excluded dependencies of this preload module
135
+ const preloadModuleRecord = await defRegistry.getModuleBundle(versionedModuleId, runtimeEnvironment, runtimeParams);
136
+ const { imports } = preloadModuleRecord.bundleRecord;
137
+ if (imports) {
138
+ if (!pending) {
139
+ pending = new Map();
140
+ }
141
+ for (let i = 0; i < imports.length; i++) {
142
+ const imp = imports[i];
143
+ if (!pending.has(imp.specifier) && isExclude(imp.specifier)) {
144
+ pending.set(imp.specifier, true); // prevent dupe calls
145
+ // eslint-disable-next-line no-await-in-loop
146
+ await getPreloadModulesMeta(imp.specifier, preloadModulesMeta, bundleConfig, moduleRegistry, defRegistry, runtimeEnvironment, runtimeParams, pending);
147
+ }
148
+ }
149
+ }
150
+ }
151
+ }
152
+ }
102
153
  //# sourceMappingURL=utils.js.map
@@ -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,21 +1,33 @@
1
- import { kebabCaseToModuleSpecifer, toImportMetadata, getModuleGraphs, getMappingUriPrefix, GraphDepth, logger, } from '@lwrjs/shared-utils';
1
+ import { kebabCaseToModuleSpecifier, toImportMetadata, getModuleGraphs, getMappingUriPrefix, GraphDepth, logger, explodeSpecifier, isBundler, } from '@lwrjs/shared-utils';
2
2
  import { AppResourceEnum, getAppSpecifier } from '@lwrjs/app-service/identity';
3
- import { generateHtmlTag, getModuleResource, getModuleResourceByUri } from '../utils.js';
4
- import { flattenCustomElements, getViewBootstrapConfigurationResource, getViewHmrConfigurationResource, } from './utils.js';
3
+ import { generateHtmlTag, getModuleResourceByUri } from '../utils.js';
4
+ import { flattenCustomElements, getViewBootstrapConfigurationResource, getViewHmrConfigurationResource, getPreloadModulesMeta, } from './utils.js';
5
5
  export async function getHtmlResources(view, viewParams, resourceContext) {
6
6
  const { runtimeEnvironment, runtimeParams, moduleRegistry, moduleBundler, resourceRegistry, viewMetadata, } = resourceContext;
7
- const { id: appName, bootstrap: { services } = { services: [] } } = view;
7
+ const { bundleConfig } = resourceContext;
8
+ const { external = {} } = bundleConfig;
9
+ const isExternal = function (rawSpecifier) {
10
+ const { specifier } = explodeSpecifier(rawSpecifier);
11
+ return Object.keys(external).some((e) => specifier === e);
12
+ };
13
+ const { id: appName, bootstrap: { services, module: bootstrapModule, preloadModules = [] } = {
14
+ services: [],
15
+ preloadModules: [],
16
+ }, } = view;
8
17
  const { lwrVersion, format, hmrEnabled, bundle, debug, minify } = runtimeEnvironment;
9
18
  const { customElements } = viewMetadata;
19
+ const defRegistry = bundle ? moduleBundler : moduleRegistry;
10
20
  const version = lwrVersion;
11
21
  const isAMD = format === 'amd';
12
- // Application Bootstrap (ABS) module resource: "@lwrjs/app-service/{appName}/module/{format}"
22
+ // The Application Bootstrap (ABS) module resource is EITHER
23
+ // - configured as routes[x].bootstrap.module OR
24
+ // - defaulted as "@lwrjs/app-service/{appName}/module/{format}"
13
25
  const appIdentity = {
14
26
  appName,
15
27
  format: runtimeEnvironment.format,
16
28
  resourceType: AppResourceEnum.MODULE,
17
29
  };
18
- const bootstrapSpecifier = getAppSpecifier(appIdentity);
30
+ const bootstrapSpecifier = bootstrapModule || getAppSpecifier(appIdentity);
19
31
  /*
20
32
  Internal module and module dependency related resources used by the view to render view related components.
21
33
  */
@@ -37,26 +49,19 @@ export async function getHtmlResources(view, viewParams, resourceContext) {
37
49
  const rootComponents = [];
38
50
  // Collection of modules specifiers that MUST be loaded in the view
39
51
  const requiredAmdModules = [];
40
- // Collection of modules that will be loaded in the view
41
- const preloadAmdModules = [];
52
+ // Collection of modules that will be preloaded. For AMD, it will be part of
53
+ // the preloadModules client bootstrap config
54
+ const preloadModulesMeta = new Map();
42
55
  // Determine if server side rendering view modules
43
56
  const isSSR = view.bootstrap?.ssr;
44
57
  // ------ AMD Required module resources
45
58
  if (isAMD) {
46
59
  // 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';
60
+ const shimBundle = debug || minify === false ? 'lwr-loader-shim.bundle.js' : 'lwr-loader-shim.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,16 +69,6 @@ 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/loader',
72
- version,
73
- }, runtimeEnvironment, {
74
- isSSR,
75
- }, moduleRegistry, runtimeParams));
76
- }
77
72
  }
78
73
  // ------- Application Bootstrap module
79
74
  // Traversal of the Bootstrap Module Graph is done to get all the URLS for discoverable static dependencies.
@@ -81,11 +76,25 @@ export async function getHtmlResources(view, viewParams, resourceContext) {
81
76
  const depth = isAMD
82
77
  ? { static: GraphDepth.ALL, dynamic: 1 }
83
78
  : { static: GraphDepth.NONE, dynamic: 1 };
84
- const bootstrapModuleGraph = await getModuleGraphs(bootstrapSpecifier, { includeUris: true, includeLinkedDefinitions: true, depth }, moduleRegistry, bundle ? moduleBundler : moduleRegistry, runtimeEnvironment, runtimeParams, visitedCache);
79
+ const bootstrapModuleGraph = await getModuleGraphs(bootstrapSpecifier, { includeUris: true, includeLinkedDefinitions: true, depth }, moduleRegistry, defRegistry, runtimeEnvironment, runtimeParams, visitedCache);
85
80
  // ADD bootstrap module uri as a script resource
86
81
  const versionedSpecifier = bootstrapModuleGraph.graphs[0].specifier;
87
82
  const uri = bootstrapModuleGraph.uriMap[versionedSpecifier];
88
83
  moduleResources.push(getModuleResourceByUri(uri, runtimeEnvironment, { isPreload: false, isSSR }));
84
+ // PRELOAD the bootstrap module static dependencies as preloaded script resources
85
+ for (const depSpecifier of bootstrapModuleGraph.graphs[0].static) {
86
+ if (!isExternal(depSpecifier)) {
87
+ const uri = bootstrapModuleGraph.uriMap[depSpecifier];
88
+ preloadModulesMeta.set(depSpecifier, uri);
89
+ }
90
+ }
91
+ // PRELOAD configured preloadModules as preloaded script resources
92
+ if (isBundler(defRegistry)) {
93
+ for (const specifier of preloadModules) {
94
+ // eslint-disable-next-line no-await-in-loop
95
+ await getPreloadModulesMeta(specifier, preloadModulesMeta, bundleConfig, moduleRegistry, defRegistry, runtimeEnvironment, runtimeParams);
96
+ }
97
+ }
89
98
  if (isAMD) {
90
99
  // ADD bootstrap module as required
91
100
  requiredAmdModules.push(versionedSpecifier);
@@ -98,8 +107,6 @@ export async function getHtmlResources(view, viewParams, resourceContext) {
98
107
  imports[staticDep] = uri;
99
108
  // ADD bootstrap module static deps to requiredAmdModules if services, otherwise preloadModules
100
109
  if (services && services.length) {
101
- // get the graphs for the bs static deps
102
- moduleResources.push(getModuleResourceByUri(uri, runtimeEnvironment, { isPreload: true, isSSR }));
103
110
  requiredAmdModules.push(staticDep);
104
111
  }
105
112
  }
@@ -120,18 +127,26 @@ export async function getHtmlResources(view, viewParams, resourceContext) {
120
127
  const flattenedElements = flattenCustomElements(customElements, isSSR);
121
128
  for (const { tagName: element } of flattenedElements) {
122
129
  // eslint-disable-next-line no-await-in-loop
123
- const graph = await getModuleGraphs(kebabCaseToModuleSpecifer(element), { includeUris: true, includeLinkedDefinitions: true, depth }, moduleRegistry, bundle ? moduleBundler : moduleRegistry, runtimeEnvironment, runtimeParams ? runtimeParams : {}, visitedCache);
130
+ const graph = await getModuleGraphs(kebabCaseToModuleSpecifier(element), { includeUris: true, includeLinkedDefinitions: true, depth }, moduleRegistry, defRegistry, runtimeEnvironment, runtimeParams ? runtimeParams : {}, visitedCache);
124
131
  // add to the viewRecord
125
132
  customElementsRecords.push({ elementName: element, flatGraph: graph });
126
- // PRELOAD custom element static deps as link resource
133
+ // PRELOAD the custom element module as a link resource
127
134
  const specifier = graph.graphs[0].specifier;
128
135
  const uri = graph.uriMap[specifier];
129
- moduleResources.push(getModuleResourceByUri(uri, runtimeEnvironment, { isPreload: true, isSSR }));
136
+ preloadModulesMeta.set(specifier, uri);
137
+ // PRELOAD custom element static deps as link resources when bundling is ON
138
+ if (bundle) {
139
+ for (const depSpecifier of graph.graphs[0].static) {
140
+ if (!isExternal(depSpecifier)) {
141
+ const uri = graph.uriMap[depSpecifier];
142
+ preloadModulesMeta.set(depSpecifier, uri);
143
+ }
144
+ }
145
+ }
130
146
  // ADD register custom elements as a uri addressable rootComponents
131
147
  rootComponents.push(specifier);
132
148
  imports[specifier] = uri;
133
149
  if (isAMD) {
134
- preloadAmdModules.push(specifier);
135
150
  for (const staticDep of graph.graphs[0].static) {
136
151
  const uri = graph.uriMap[staticDep];
137
152
  // AMD ADD static module dep uri addressability
@@ -159,11 +174,16 @@ export async function getHtmlResources(view, viewParams, resourceContext) {
159
174
  index: importMetadata?.index,
160
175
  rootComponents,
161
176
  ...(isAMD && { requiredModules: requiredAmdModules }),
162
- ...(isAMD && { preloadModules: preloadAmdModules }),
177
+ // in AMD we need to tell the loader what modules we are preloading
178
+ ...(isAMD && { preloadModules: Array.from(preloadModulesMeta.keys()) }),
163
179
  }, runtimeEnvironment, runtimeParams));
164
180
  if (!isAMD && hmrEnabled) {
165
181
  configResources.unshift(await getViewHmrConfigurationResource(view, viewMetadata));
166
182
  }
183
+ // PRELOAD script resources for preload module URIs after the bootstrap module
184
+ for (const [, preloadUri] of preloadModulesMeta) {
185
+ moduleResources.push(getModuleResourceByUri(preloadUri, runtimeEnvironment, { isPreload: true, isSSR }));
186
+ }
167
187
  // generate html partial
168
188
  const htmlResources = await Promise.all([...configResources, ...requiredResources, ...moduleResources].map(generateHtmlTag));
169
189
  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>;