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

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -27,6 +27,7 @@ __export(exports, {
27
27
  LwrViewHandler: () => import_view_handler.LwrViewHandler,
28
28
  LwrViewRegistry: () => LwrViewRegistry
29
29
  });
30
+ var import_config = __toModule(require("@lwrjs/config"));
30
31
  var import_shared_utils = __toModule(require("@lwrjs/shared-utils"));
31
32
  var import_instrumentation = __toModule(require("@lwrjs/instrumentation"));
32
33
  var import_utils = __toModule(require("./utils.cjs"));
@@ -41,7 +42,6 @@ var LwrViewRegistry = class {
41
42
  this.compiledViews = new Map();
42
43
  this.immutableAssets = new Map();
43
44
  this.pendingViewDefinitions = new import_shared_utils.InflightTasks();
44
- this.metadataCache = new Map();
45
45
  this.name = "lwr-view-registry";
46
46
  this.resourceRegistry = context.resourceRegistry;
47
47
  this.runtimeEnvironment = context.runtimeEnvironment;
@@ -59,6 +59,12 @@ var LwrViewRegistry = class {
59
59
  import_diagnostics.logger.verbose(`View evicted from cache ${key}`);
60
60
  }
61
61
  });
62
+ this.metadataCache = new import_lru_cache.LRUCache({
63
+ max: parseInt(process.env.VIEW_METADATA_CACHE_SIZE ?? "500", 10),
64
+ dispose: (_value, key) => {
65
+ import_diagnostics.logger.verbose(`Metadata evicted from cache ${key}`);
66
+ }
67
+ });
62
68
  observer.onViewSourceChange(({payload}) => this.onViewSourceChange(payload));
63
69
  observer.onModuleDefinitionChange(({payload}) => this.onModuleDefinitionChange(payload));
64
70
  observer.onAssetSourceChange(({payload}) => this.onAssetSourceChange(payload));
@@ -220,9 +226,14 @@ var LwrViewRegistry = class {
220
226
  throw new import_diagnostics.LwrServerError(import_diagnostics.descriptions.SERVER.UNEXPECTED_ERROR(message));
221
227
  }
222
228
  }
229
+ getLwrResourcesPlaceHolder(view, runtimeEnvironment, runtimeParams) {
230
+ const resourcesCacheKey = (0, import_utils.getViewDefCacheKey)(view, runtimeEnvironment, true, runtimeParams);
231
+ const resourcesCacheKeyHashed = (0, import_crypto.createHash)("md5").update(resourcesCacheKey).digest("hex");
232
+ return `__LWR_RESOURCES__${view.id}${resourcesCacheKeyHashed}`;
233
+ }
223
234
  async renderView(view, viewParams, runtimeEnvironment, runtimeParams, viewCacheKey, renderOptions) {
224
235
  const {id, contentTemplate, rootComponent, layoutTemplate} = view;
225
- const lwrResourcesId = `__LWR_RESOURCES__${viewCacheKey}`;
236
+ const lwrResourcesId = this.getLwrResourcesPlaceHolder(view, runtimeEnvironment, runtimeParams);
226
237
  const renderedContent = await this.render({id, contentTemplate, rootComponent}, {...viewParams, lwr_resources: lwrResourcesId}, runtimeParams, runtimeEnvironment);
227
238
  let normalizedRenderOptions = (0, import_utils.normalizeRenderOptions)(this.runtimeEnvironment, renderedContent.options, renderOptions);
228
239
  const layout = layoutTemplate || renderedContent.compiledView.layoutTemplate;
@@ -317,32 +328,59 @@ var LwrViewRegistry = class {
317
328
  const {lwrResourcesId} = contentIds;
318
329
  const {moduleRegistry, resourceRegistry, moduleBundler} = this;
319
330
  const runtimeEnvironment = {...runtimeEnv, immutableAssets: freezeAssets};
331
+ const isSSR = view.bootstrap?.ssr === true;
320
332
  const {
321
333
  renderedView: renderedViewContent,
322
334
  metadata: renderedViewMetadata,
323
335
  compiledView: {immutable = true}
324
336
  } = renderedView;
337
+ let traceId;
325
338
  const {linkedMetadata, stringBuilder} = (0, import_instrumentation.getTracer)().trace({
326
339
  name: import_instrumentation.ViewSpan.ParseView,
327
340
  attributes: {
328
341
  view: view.id,
329
- ssr: view.bootstrap?.ssr === true
330
- }
331
- }, () => {
332
- let linkedMetadata2 = renderedViewMetadata;
333
- if (!skipMetadataCollection) {
334
- const contentHash = (0, import_crypto.createHash)("md5").update(renderedViewContent).digest("hex");
335
- const cacheKey = `${view.id}:${contentHash}`;
336
- if (this.metadataCache.has(cacheKey)) {
337
- linkedMetadata2 = this.metadataCache.get(cacheKey);
338
- } else {
339
- linkedMetadata2 = (0, import_shared_utils.extractMetadataFromHtml)(renderedViewContent, renderedViewMetadata, this.globalConfig);
340
- this.metadataCache.set(cacheKey, linkedMetadata2);
341
- }
342
+ ssr: isSSR
342
343
  }
344
+ }, (span) => {
345
+ traceId = span.traceId;
343
346
  const stringBuilder2 = (0, import_shared_utils.createStringBuilder)(renderedViewContent);
344
- return {linkedMetadata: linkedMetadata2, stringBuilder: stringBuilder2};
347
+ if (skipMetadataCollection) {
348
+ return {linkedMetadata: renderedViewMetadata, stringBuilder: stringBuilder2};
349
+ }
350
+ const contentHash = (0, import_crypto.createHash)("md5").update(renderedViewContent).digest("hex");
351
+ const cacheKey = `${view.id}:${contentHash}`;
352
+ let metadata;
353
+ if (this.metadataCache.has(cacheKey)) {
354
+ metadata = this.metadataCache.get(cacheKey);
355
+ } else {
356
+ metadata = (0, import_shared_utils.extractMetadataFromHtml)(renderedViewContent, renderedViewMetadata, this.globalConfig);
357
+ this.metadataCache.set(cacheKey, metadata);
358
+ }
359
+ return {
360
+ linkedMetadata: {
361
+ ...renderedViewMetadata,
362
+ customElements: metadata.customElements,
363
+ assetReferences: metadata.assetReferences
364
+ },
365
+ stringBuilder: stringBuilder2
366
+ };
345
367
  });
368
+ if (!(0, import_shared_utils.getFeatureFlags)().DISABLE_B3_TRACING && traceId && runtimeParams.viewSpanID) {
369
+ const content = `00-${traceId}-${runtimeParams.viewSpanID}-01`;
370
+ (0, import_shared_utils.addHeadMarkup)([{meta: [{name: "traceparent", content}]}], stringBuilder);
371
+ }
372
+ if (isSSR && (0, import_shared_utils.getFeatureFlags)().SSR_COMPILER_ENABLED) {
373
+ const ssrUtils = await resourceRegistry.getResource({specifier: "register-lwc-style.js", version: import_config.LWC_VERSION}, runtimeEnvironment, runtimeParams);
374
+ if (!ssrUtils?.src) {
375
+ } else {
376
+ (0, import_shared_utils.addToHead)(await (0, import_utils.generateHtmlTag)(ssrUtils), stringBuilder);
377
+ linkedMetadata.assetReferences.push({
378
+ url: ssrUtils.src,
379
+ relative: (0, import_shared_utils.isRelative)(ssrUtils.src),
380
+ integrity: ssrUtils.integrity
381
+ });
382
+ }
383
+ }
346
384
  const mergedViewContext = {
347
385
  ...viewContext,
348
386
  config: this.globalConfig,
@@ -374,23 +412,24 @@ var LwrViewRegistry = class {
374
412
  unsafeEnableViewLinkCaching: this.globalConfig.unsafeEnableViewLinkCaching,
375
413
  viewLinkCacheKey: viewCacheKey
376
414
  });
415
+ const assetReferences = [...linkedMetadata.assetReferences];
377
416
  if (viewRecord.resources?.length) {
378
- linkedMetadata.assetReferences.push(...viewRecord.resources.reduce((res, asset) => {
379
- if (!asset.src)
380
- return res;
381
- res.push({
382
- url: asset.src,
383
- relative: (0, import_shared_utils.isRelative)(asset.src),
384
- integrity: asset.integrity
417
+ for (const resource of viewRecord.resources) {
418
+ if (!resource.src) {
419
+ continue;
420
+ }
421
+ assetReferences.push({
422
+ url: resource.src,
423
+ relative: (0, import_shared_utils.isRelative)(resource.src),
424
+ integrity: resource.integrity
385
425
  });
386
- return res;
387
- }, []));
426
+ }
388
427
  }
389
428
  return {
390
429
  renderedView: linkedView,
391
430
  immutable,
392
431
  viewRecord: {
393
- assetReferences: (0, import_utils.reduceSourceAssetReferences)(linkedMetadata.assetReferences),
432
+ assetReferences: (0, import_utils.reduceSourceAssetReferences)(assetReferences),
394
433
  ...viewRecord,
395
434
  serverBundles: linkedMetadata.serverBundles
396
435
  },
@@ -110,6 +110,7 @@ async function getHtmlResources(view, viewParams, resourceContext) {
110
110
  const viewPreloads = {
111
111
  uris: [],
112
112
  specifiers: [],
113
+ includedModules: [],
113
114
  groups: new Map(),
114
115
  integrities: new Map()
115
116
  };
@@ -157,6 +158,10 @@ async function getHtmlResources(view, viewParams, resourceContext) {
157
158
  if (enableModuleGraphsCache && moduleGraphsCache.has(bootstrapModuleGraphCacheKey)) {
158
159
  bootstrapModuleGraph = moduleGraphsCache.get(bootstrapModuleGraphCacheKey);
159
160
  } else {
161
+ import_diagnostics.logger.info({
162
+ label: "view-registry",
163
+ message: `Cache miss for ServerGenerate, cache key: ${bootstrapModuleGraphCacheKey}`
164
+ });
160
165
  bootstrapModuleGraph = await (0, import_shared_utils.getModuleGraphs)(bootstrapSpecifier, {includeUris: true, includeLinkedDefinitions: true, depth}, moduleRegistry, defRegistry, runtimeEnvironment, runtimeParams, visitedCache);
161
166
  enableModuleGraphsCache && moduleGraphsCache.set(bootstrapModuleGraphCacheKey, bootstrapModuleGraph);
162
167
  }
@@ -227,7 +232,9 @@ async function getHtmlResources(view, viewParams, resourceContext) {
227
232
  const specifier = graph.graphs[0].specifier;
228
233
  const uri = graph.uriMap[specifier];
229
234
  const integrity = (0, import_utils2.getBundleIntegrity)(graph, specifier);
230
- (0, import_preload_utils.setPreloadModulesMeta)(specifier, uri, integrity, groups, viewPreloads);
235
+ const bundleDef = graph.linkedDefinitions[specifier];
236
+ const includedModules = bundleDef?.bundleRecord ? bundleDef.bundleRecord.includedModules : [];
237
+ (0, import_preload_utils.setPreloadModulesMeta)(specifier, uri, integrity, groups, viewPreloads, includedModules);
231
238
  if (bundle) {
232
239
  for (const depSpecifier of graph.graphs[0].static) {
233
240
  const depUri = getPreloadUri(depSpecifier, graph.uriMap);
@@ -277,7 +284,7 @@ async function getHtmlResources(view, viewParams, resourceContext) {
277
284
  rootComponents,
278
285
  serverData,
279
286
  ...isAMD && {requiredModules: requiredAmdModules},
280
- ...isAMD && {preloadModules: viewPreloads.specifiers}
287
+ ...isAMD && {preloadModules: (0, import_preload_utils.getPreloadModuleList)(viewPreloads)}
281
288
  }, runtimeEnvironment, runtimeParams, serverDebug?.warnings));
282
289
  }
283
290
  if (!isAMD && hmrEnabled) {
@@ -24,12 +24,13 @@ var __toModule = (module2) => {
24
24
  // packages/@lwrjs/view-registry/src/linkers/preload-utils.ts
25
25
  __markAsModule(exports);
26
26
  __export(exports, {
27
+ getPreloadModuleList: () => getPreloadModuleList,
27
28
  getPreloadModulesMeta: () => getPreloadModulesMeta,
28
29
  setPreloadModulesMeta: () => setPreloadModulesMeta
29
30
  });
30
31
  var import_diagnostics = __toModule(require("@lwrjs/diagnostics"));
31
32
  var import_shared_utils = __toModule(require("@lwrjs/shared-utils"));
32
- function setPreloadModulesMeta(specifier, uri, integrity, groups, preloads) {
33
+ function setPreloadModulesMeta(specifier, uri, integrity, groups, preloads, includedModules = []) {
33
34
  if (!uri) {
34
35
  throw new import_diagnostics.LwrInvalidError(import_diagnostics.descriptions.INVALID.PRELOAD_MODULE(specifier));
35
36
  }
@@ -40,6 +41,7 @@ function setPreloadModulesMeta(specifier, uri, integrity, groups, preloads) {
40
41
  const preloadBundleGroupsMap = preloads.groups;
41
42
  const preloadModulesURIs = preloads.uris;
42
43
  const preloadModuleIntegrities = preloads.integrities;
44
+ const preloadModuleIncludedModules = preloads.includedModules;
43
45
  preloadModulesSpecifiers.push(specifier);
44
46
  const {specifier: unversionedSpecifier} = (0, import_shared_utils.explodeSpecifier)(specifier);
45
47
  const groupName = (0, import_shared_utils.getGroupName)(unversionedSpecifier, groups);
@@ -49,6 +51,7 @@ function setPreloadModulesMeta(specifier, uri, integrity, groups, preloads) {
49
51
  preloadModulesURIs.push(uri);
50
52
  groupName && preloadBundleGroupsMap.set(groupName, true);
51
53
  preloadModuleIntegrities.set(uri, integrity);
54
+ preloadModuleIncludedModules.push(...includedModules);
52
55
  }
53
56
  async function getPreloadModulesMeta(specifier, viewPreloads, bundleConfig, moduleRegistry, defRegistry, runtimeEnvironment, runtimeParams, pending) {
54
57
  const {exclude = [], external = {}, groups = {}} = bundleConfig;
@@ -92,3 +95,8 @@ async function getPreloadModulesMeta(specifier, viewPreloads, bundleConfig, modu
92
95
  }
93
96
  }
94
97
  }
98
+ function getPreloadModuleList(viewPreloads) {
99
+ if (process.env.PRELOAD_INCLUDED_MODULES === "true")
100
+ return [...new Set(viewPreloads.specifiers), ...new Set(viewPreloads.includedModules)];
101
+ return [...new Set(viewPreloads.specifiers)];
102
+ }
@@ -52,6 +52,7 @@ function getViewBootstrapConfigurationResource(viewInfo, config, runtimeEnvironm
52
52
  };
53
53
  const lwrEnv = {
54
54
  SSR: false,
55
+ SSREnabled: !!viewInfo.ssr,
55
56
  ...(0, import_shared_utils.buildEnvironmentContext)(runtimeParams)
56
57
  };
57
58
  let warnMessages = `console.group('Server-side rendering warnings:');`;
@@ -100,6 +100,7 @@ async function getHtmlResources(view, viewParams, resourceContext) {
100
100
  const viewPreloads = {
101
101
  uris: [],
102
102
  specifiers: [],
103
+ includedModules: [],
103
104
  groups: new Map(),
104
105
  integrities: new Map()
105
106
  };
@@ -209,7 +210,9 @@ async function getHtmlResources(view, viewParams, resourceContext) {
209
210
  const specifier = graph.graphs[0].specifier;
210
211
  const uri = graph.uriMap[specifier];
211
212
  const integrity = (0, import_utils2.getBundleIntegrity)(graph, specifier);
212
- (0, import_preload_utils.setPreloadModulesMeta)(specifier, uri, integrity, groups, viewPreloads);
213
+ const bundleDef = graph.linkedDefinitions[specifier];
214
+ const includedModules = bundleDef?.bundleRecord ? bundleDef.bundleRecord.includedModules : [];
215
+ (0, import_preload_utils.setPreloadModulesMeta)(specifier, uri, integrity, groups, viewPreloads, includedModules);
213
216
  if (bundle) {
214
217
  for (const depSpecifier of graph.graphs[0].static) {
215
218
  const depUri = getPreloadUri(depSpecifier, graph.uriMap);
@@ -251,7 +254,7 @@ async function getHtmlResources(view, viewParams, resourceContext) {
251
254
  rootComponents,
252
255
  serverData,
253
256
  ...isAMD && {requiredModules: requiredAmdModules},
254
- ...isAMD && {preloadModules: viewPreloads.specifiers}
257
+ ...isAMD && {preloadModules: (0, import_preload_utils.getPreloadModuleList)(viewPreloads)}
255
258
  }, runtimeEnvironment, runtimeParams, serverDebug?.warnings));
256
259
  }
257
260
  if (!isAMD && hmrEnabled) {
@@ -45,6 +45,7 @@ export declare class LwrViewRegistry implements ViewRegistry {
45
45
  getView(viewId: ViewIdentity): Promise<CompiledView>;
46
46
  hasViewDefinition(view: View, viewParams: ViewParams, runtimeEnvironment: RuntimeEnvironment, runtimeParams?: RuntimeParams, renderOptions?: RenderOptions): boolean;
47
47
  getViewDefinition(view: View, viewParams: ViewParams, runtimeEnvironment: RuntimeEnvironment, runtimeParams?: RuntimeParams, renderOptions?: RenderOptions): Promise<LinkedViewDefinition>;
48
+ private getLwrResourcesPlaceHolder;
48
49
  private renderView;
49
50
  private render;
50
51
  private metadataCache;
package/build/es/index.js CHANGED
@@ -1,6 +1,7 @@
1
- import { InflightTasks, createStringBuilder, extractMetadataFromHtml, getCacheKeyFromJson, getFeatureFlags, getSpecifier, isLocalDev, normalizeResourcePath, shortestTtl, isRelative, } from '@lwrjs/shared-utils';
1
+ import { LWC_VERSION } from '@lwrjs/config';
2
+ import { InflightTasks, addHeadMarkup, addToHead, createStringBuilder, extractMetadataFromHtml, getCacheKeyFromJson, getFeatureFlags, getSpecifier, isLocalDev, isRelative, normalizeResourcePath, shortestTtl, } from '@lwrjs/shared-utils';
2
3
  import { getTracer, ViewSpan } from '@lwrjs/instrumentation';
3
- import { generateViewNonce, getViewNonce, normalizeRenderOptions, normalizeRenderedResult, reduceSourceAssetReferences, getViewDefCacheKey, } from './utils.js';
4
+ import { generateHtmlTag, generateViewNonce, getViewDefCacheKey, getViewNonce, normalizeRenderOptions, normalizeRenderedResult, reduceSourceAssetReferences, } from './utils.js';
4
5
  import { linkLwrResources } from './linkers/link-lwr-resources.js';
5
6
  // TODO: investigate perf impact W-16056356
6
7
  import { LRUCache } from 'lru-cache';
@@ -8,19 +9,31 @@ import { createHash } from 'crypto';
8
9
  import { LwrError, LwrServerError, descriptions, logger } from '@lwrjs/diagnostics';
9
10
  export { LwrViewHandler } from './view-handler.js';
10
11
  export class LwrViewRegistry {
12
+ name;
13
+ viewProviders = [];
14
+ // Cache of compiled views retrieved from the viewProviders
15
+ // Cache key: ViewIdentity
16
+ compiledViews = new Map();
17
+ // Cache of linked view definitions, keyed by the View
18
+ // Cache key: View
19
+ viewDefinitions;
20
+ resourceRegistry;
21
+ moduleRegistry;
22
+ moduleBundler;
23
+ assetRegistry;
24
+ globalConfig;
25
+ appEmitter;
26
+ globalData;
27
+ runtimeEnvironment;
28
+ immutableAssets = new Map();
29
+ viewTransformers;
30
+ // Cache of unresolved view definitions
31
+ // Cache key: View + View Params
32
+ //
33
+ // Pending view definitions are tracked to prevent concurrent resolution of the same view.
34
+ // Subsequent requests for the same view will await the original promise.
35
+ pendingViewDefinitions = new InflightTasks();
11
36
  constructor(context, globalConfig) {
12
- this.viewProviders = [];
13
- // Cache of compiled views retrieved from the viewProviders
14
- // Cache key: ViewIdentity
15
- this.compiledViews = new Map();
16
- this.immutableAssets = new Map();
17
- // Cache of unresolved view definitions
18
- // Cache key: View + View Params
19
- //
20
- // Pending view definitions are tracked to prevent concurrent resolution of the same view.
21
- // Subsequent requests for the same view will await the original promise.
22
- this.pendingViewDefinitions = new InflightTasks();
23
- this.metadataCache = new Map();
24
37
  this.name = 'lwr-view-registry';
25
38
  this.resourceRegistry = context.resourceRegistry;
26
39
  this.runtimeEnvironment = context.runtimeEnvironment;
@@ -39,6 +52,12 @@ export class LwrViewRegistry {
39
52
  logger.verbose(`View evicted from cache ${key}`);
40
53
  },
41
54
  });
55
+ this.metadataCache = new LRUCache({
56
+ max: parseInt(process.env.VIEW_METADATA_CACHE_SIZE ?? '500', 10),
57
+ dispose: (_value, key) => {
58
+ logger.verbose(`Metadata evicted from cache ${key}`);
59
+ },
60
+ });
42
61
  // Observers for cached entries external dependencies -- view templates, modules, and assets
43
62
  observer.onViewSourceChange(({ payload }) => this.onViewSourceChange(payload));
44
63
  observer.onModuleDefinitionChange(({ payload }) => this.onModuleDefinitionChange(payload));
@@ -239,9 +258,17 @@ export class LwrViewRegistry {
239
258
  throw new LwrServerError(descriptions.SERVER.UNEXPECTED_ERROR(message));
240
259
  }
241
260
  }
261
+ getLwrResourcesPlaceHolder(view, runtimeEnvironment, runtimeParams) {
262
+ // Unlike the view definiton cache key which is a lot more open ended, we only
263
+ // need this cache key to vary for critical items like ?debug, locale, basePath, etc
264
+ // Note: hardcoding freeze assets here because it shouldn't matter for this key.
265
+ const resourcesCacheKey = getViewDefCacheKey(view, runtimeEnvironment, true, runtimeParams);
266
+ const resourcesCacheKeyHashed = createHash('md5').update(resourcesCacheKey).digest('hex');
267
+ return `__LWR_RESOURCES__${view.id}${resourcesCacheKeyHashed}`;
268
+ }
242
269
  async renderView(view, viewParams, runtimeEnvironment, runtimeParams, viewCacheKey, renderOptions) {
243
270
  const { id, contentTemplate, rootComponent, layoutTemplate } = view;
244
- const lwrResourcesId = `__LWR_RESOURCES__${viewCacheKey}`;
271
+ const lwrResourcesId = this.getLwrResourcesPlaceHolder(view, runtimeEnvironment, runtimeParams);
245
272
  const renderedContent = await this.render({ id, contentTemplate, rootComponent }, { ...viewParams, lwr_resources: lwrResourcesId }, runtimeParams, runtimeEnvironment);
246
273
  // normalize the renderOptions provided by the CompiledView content with the request options.
247
274
  let normalizedRenderOptions = normalizeRenderOptions(this.runtimeEnvironment, renderedContent.options, renderOptions);
@@ -342,37 +369,71 @@ export class LwrViewRegistry {
342
369
  ...normalizedResult,
343
370
  };
344
371
  }
372
+ metadataCache;
345
373
  async link(renderedView, viewContext) {
346
374
  const { view, viewParams, runtimeEnvironment: runtimeEnv, runtimeParams, renderOptions, contentIds, importer, viewCacheKey, } = viewContext;
347
375
  const { skipMetadataCollection, freezeAssets } = renderOptions;
348
376
  const { lwrResourcesId } = contentIds;
349
377
  const { moduleRegistry, resourceRegistry, moduleBundler } = this;
350
378
  const runtimeEnvironment = { ...runtimeEnv, immutableAssets: freezeAssets };
379
+ const isSSR = view.bootstrap?.ssr === true;
351
380
  // normalize/extract metadata
352
381
  const { renderedView: renderedViewContent, metadata: renderedViewMetadata, compiledView: { immutable = true }, } = renderedView;
382
+ let traceId;
353
383
  const { linkedMetadata, stringBuilder } = getTracer().trace({
354
384
  name: ViewSpan.ParseView,
355
385
  attributes: {
356
386
  view: view.id,
357
- ssr: view.bootstrap?.ssr === true,
387
+ ssr: isSSR,
358
388
  },
359
- }, () => {
360
- let linkedMetadata = renderedViewMetadata;
361
- if (!skipMetadataCollection) {
362
- // Create a unique key based on view ID and content hash
363
- const contentHash = createHash('md5').update(renderedViewContent).digest('hex');
364
- const cacheKey = `${view.id}:${contentHash}`;
365
- if (this.metadataCache.has(cacheKey)) {
366
- linkedMetadata = this.metadataCache.get(cacheKey);
367
- }
368
- else {
369
- linkedMetadata = extractMetadataFromHtml(renderedViewContent, renderedViewMetadata, this.globalConfig);
370
- this.metadataCache.set(cacheKey, linkedMetadata);
371
- }
372
- }
389
+ }, (span) => {
390
+ traceId = span.traceId;
373
391
  const stringBuilder = createStringBuilder(renderedViewContent);
374
- return { linkedMetadata, stringBuilder };
392
+ if (skipMetadataCollection) {
393
+ return { linkedMetadata: renderedViewMetadata, stringBuilder };
394
+ }
395
+ // Create a unique key based on view ID and content hash
396
+ const contentHash = createHash('md5').update(renderedViewContent).digest('hex');
397
+ const cacheKey = `${view.id}:${contentHash}`;
398
+ let metadata;
399
+ if (this.metadataCache.has(cacheKey)) {
400
+ metadata = this.metadataCache.get(cacheKey);
401
+ }
402
+ else {
403
+ metadata = extractMetadataFromHtml(renderedViewContent, renderedViewMetadata, this.globalConfig);
404
+ this.metadataCache.set(cacheKey, metadata);
405
+ }
406
+ return {
407
+ linkedMetadata: {
408
+ ...renderedViewMetadata,
409
+ customElements: metadata.customElements,
410
+ assetReferences: metadata.assetReferences,
411
+ },
412
+ stringBuilder,
413
+ };
375
414
  });
415
+ // Add distributed tracing meta tag to pass tracing info to the client
416
+ // {version}-{traceId}-{spanId}-{sampleDecision} and version is always 00
417
+ if (!getFeatureFlags().DISABLE_B3_TRACING && traceId && runtimeParams.viewSpanID) {
418
+ const content = `00-${traceId}-${runtimeParams.viewSpanID}-01`;
419
+ addHeadMarkup([{ meta: [{ name: 'traceparent', content }] }], stringBuilder);
420
+ }
421
+ // If the SSR compiler is enabled then inline the @lwc/ssr-client-utils/register-lwc-style script for style de-duplication
422
+ // re-enable logger.error below with W-18004123 after the app has integrated the register-lwc-style resource
423
+ if (isSSR && getFeatureFlags().SSR_COMPILER_ENABLED) {
424
+ const ssrUtils = await resourceRegistry.getResource({ specifier: 'register-lwc-style.js', version: LWC_VERSION }, runtimeEnvironment, runtimeParams);
425
+ if (!ssrUtils?.src) {
426
+ // logger.error('Failed to find script: register-lwc-style.js');
427
+ }
428
+ else {
429
+ addToHead(await generateHtmlTag(ssrUtils), stringBuilder);
430
+ linkedMetadata.assetReferences.push({
431
+ url: ssrUtils.src,
432
+ relative: isRelative(ssrUtils.src),
433
+ integrity: ssrUtils.integrity,
434
+ });
435
+ }
436
+ }
376
437
  const mergedViewContext = {
377
438
  ...viewContext,
378
439
  config: this.globalConfig,
@@ -411,24 +472,25 @@ export class LwrViewRegistry {
411
472
  // Use the same cache key for the link stage
412
473
  viewLinkCacheKey: viewCacheKey,
413
474
  });
475
+ const assetReferences = [...linkedMetadata.assetReferences];
414
476
  if (viewRecord.resources?.length) {
415
- linkedMetadata.assetReferences.push(...viewRecord.resources.reduce((res, asset) => {
416
- if (!asset.src)
417
- return res;
418
- res.push({
419
- url: asset.src,
420
- relative: isRelative(asset.src),
421
- integrity: asset.integrity,
477
+ for (const resource of viewRecord.resources) {
478
+ if (!resource.src) {
479
+ continue;
480
+ }
481
+ assetReferences.push({
482
+ url: resource.src,
483
+ relative: isRelative(resource.src),
484
+ integrity: resource.integrity,
422
485
  });
423
- return res;
424
- }, []));
486
+ }
425
487
  }
426
488
  return {
427
489
  // ...viewDefinition,
428
490
  renderedView: linkedView,
429
491
  immutable,
430
492
  viewRecord: {
431
- assetReferences: reduceSourceAssetReferences(linkedMetadata.assetReferences),
493
+ assetReferences: reduceSourceAssetReferences(assetReferences),
432
494
  ...viewRecord,
433
495
  serverBundles: linkedMetadata.serverBundles,
434
496
  },
@@ -3,7 +3,7 @@ import { kebabCaseToModuleSpecifier, getModuleGraphs, GraphDepth, getModuleUriPr
3
3
  import { AppResourceEnum, getAppSpecifier } from '@lwrjs/app-service/identity';
4
4
  import { addExternalScriptNonce, generateHtmlTag, getModuleResource, getModuleResourceByUri, getViewNonce, getModuleGraphCacheKey, } from '../utils.js';
5
5
  import { flattenCustomElements, getBundleIntegrity, getViewBootstrapConfigurationResource, getViewHmrConfigurationResource, } from './utils.js';
6
- import { setPreloadModulesMeta, getPreloadModulesMeta } from './preload-utils.js';
6
+ import { setPreloadModulesMeta, getPreloadModulesMeta, getPreloadModuleList, } from './preload-utils.js';
7
7
  import { LRUCache } from 'lru-cache';
8
8
  function includeIdFactory(bundleConfig) {
9
9
  return (moduleRef) => {
@@ -103,6 +103,7 @@ export async function getHtmlResources(view, viewParams, resourceContext) {
103
103
  const viewPreloads = {
104
104
  uris: [],
105
105
  specifiers: [],
106
+ includedModules: [],
106
107
  groups: new Map(),
107
108
  integrities: new Map(),
108
109
  };
@@ -174,6 +175,10 @@ export async function getHtmlResources(view, viewParams, resourceContext) {
174
175
  bootstrapModuleGraph = moduleGraphsCache.get(bootstrapModuleGraphCacheKey);
175
176
  }
176
177
  else {
178
+ logger.info({
179
+ label: 'view-registry',
180
+ message: `Cache miss for ServerGenerate, cache key: ${bootstrapModuleGraphCacheKey}`,
181
+ });
177
182
  bootstrapModuleGraph = await getModuleGraphs(bootstrapSpecifier, { includeUris: true, includeLinkedDefinitions: true, depth }, moduleRegistry, defRegistry, runtimeEnvironment, runtimeParams, visitedCache);
178
183
  enableModuleGraphsCache &&
179
184
  moduleGraphsCache.set(bootstrapModuleGraphCacheKey, bootstrapModuleGraph);
@@ -262,7 +267,9 @@ export async function getHtmlResources(view, viewParams, resourceContext) {
262
267
  const specifier = graph.graphs[0].specifier;
263
268
  const uri = graph.uriMap[specifier];
264
269
  const integrity = getBundleIntegrity(graph, specifier);
265
- setPreloadModulesMeta(specifier, uri, integrity, groups, viewPreloads);
270
+ const bundleDef = graph.linkedDefinitions[specifier];
271
+ const includedModules = bundleDef?.bundleRecord ? bundleDef.bundleRecord.includedModules : [];
272
+ setPreloadModulesMeta(specifier, uri, integrity, groups, viewPreloads, includedModules);
266
273
  // PRELOAD custom element static deps as link resources when bundling is ON
267
274
  if (bundle) {
268
275
  for (const depSpecifier of graph.graphs[0].static) {
@@ -319,7 +326,7 @@ export async function getHtmlResources(view, viewParams, resourceContext) {
319
326
  serverData,
320
327
  ...(isAMD && { requiredModules: requiredAmdModules }),
321
328
  // in AMD we need to tell the loader what modules we are preloading
322
- ...(isAMD && { preloadModules: viewPreloads.specifiers }),
329
+ ...(isAMD && { preloadModules: getPreloadModuleList(viewPreloads) }),
323
330
  }, runtimeEnvironment, runtimeParams, serverDebug?.warnings));
324
331
  }
325
332
  if (!isAMD && hmrEnabled) {
@@ -4,15 +4,17 @@ export type ViewPreloads = {
4
4
  uris: string[];
5
5
  specifiers: string[];
6
6
  integrities: Map<string, string | undefined>;
7
+ includedModules: string[];
7
8
  };
8
9
  /**
9
10
  * keeps track of preloadModules metadata
10
11
  */
11
- export declare function setPreloadModulesMeta(specifier: string, uri: string, integrity: string | undefined, groups: BundleGroups, preloads: ViewPreloads): void;
12
+ export declare function setPreloadModulesMeta(specifier: string, uri: string, integrity: string | undefined, groups: BundleGroups, preloads: ViewPreloads, includedModules?: string[]): void;
12
13
  /**
13
14
  * Recursively gets preloadModules metadata starting with a specifier
14
15
  * Note: don't call me unless you got bundles
15
16
  */
16
17
  export declare function getPreloadModulesMeta(specifier: string, // un-versioned specifier
17
18
  viewPreloads: ViewPreloads, bundleConfig: BundleConfig, moduleRegistry: ModuleRegistry, defRegistry: ModuleBundler, runtimeEnvironment: RuntimeEnvironment, runtimeParams: RuntimeParams, pending?: Map<string, boolean>): Promise<void>;
19
+ export declare function getPreloadModuleList(viewPreloads: ViewPreloads): string[];
18
20
  //# sourceMappingURL=preload-utils.d.ts.map
@@ -3,7 +3,7 @@ import { explodeSpecifier, getGroupName, getVersionedModuleId, normalizeVersionT
3
3
  /**
4
4
  * keeps track of preloadModules metadata
5
5
  */
6
- export function setPreloadModulesMeta(specifier, uri, integrity, groups, preloads) {
6
+ export function setPreloadModulesMeta(specifier, uri, integrity, groups, preloads, includedModules = []) {
7
7
  // Throw a very specific error if we get this back and the uri property is not set
8
8
  if (!uri) {
9
9
  throw new LwrInvalidError(descriptions.INVALID.PRELOAD_MODULE(specifier));
@@ -19,6 +19,7 @@ export function setPreloadModulesMeta(specifier, uri, integrity, groups, preload
19
19
  const preloadBundleGroupsMap = preloads.groups;
20
20
  const preloadModulesURIs = preloads.uris;
21
21
  const preloadModuleIntegrities = preloads.integrities;
22
+ const preloadModuleIncludedModules = preloads.includedModules;
22
23
  preloadModulesSpecifiers.push(specifier);
23
24
  const { specifier: unversionedSpecifier } = explodeSpecifier(specifier);
24
25
  const groupName = getGroupName(unversionedSpecifier, groups);
@@ -29,6 +30,7 @@ export function setPreloadModulesMeta(specifier, uri, integrity, groups, preload
29
30
  preloadModulesURIs.push(uri);
30
31
  groupName && preloadBundleGroupsMap.set(groupName, true);
31
32
  preloadModuleIntegrities.set(uri, integrity);
33
+ preloadModuleIncludedModules.push(...includedModules);
32
34
  }
33
35
  /**
34
36
  * Recursively gets preloadModules metadata starting with a specifier
@@ -85,4 +87,9 @@ viewPreloads, bundleConfig, moduleRegistry, defRegistry, runtimeEnvironment, run
85
87
  }
86
88
  }
87
89
  }
90
+ export function getPreloadModuleList(viewPreloads) {
91
+ if (process.env.PRELOAD_INCLUDED_MODULES === 'true')
92
+ return [...new Set(viewPreloads.specifiers), ...new Set(viewPreloads.includedModules)];
93
+ return [...new Set(viewPreloads.specifiers)];
94
+ }
88
95
  //# sourceMappingURL=preload-utils.js.map
@@ -25,6 +25,7 @@ export function getViewBootstrapConfigurationResource(viewInfo, config, runtimeE
25
25
  const lwrEnv = {
26
26
  // Note: SSR is always false because this script is executed on the client
27
27
  SSR: false,
28
+ SSREnabled: !!viewInfo.ssr,
28
29
  // Used by `lwr/environment`
29
30
  ...buildEnvironmentContext(runtimeParams),
30
31
  };
@@ -5,7 +5,7 @@ import { AppResourceEnum, getAppSpecifier } from '@lwrjs/app-service/identity';
5
5
  import { addExternalScriptNonce, generateHtmlTag, getModuleResourceByUri, getViewNonce } from '../utils.js';
6
6
  import { flattenCustomElements, getBundleIntegrity, getViewBootstrapConfigurationResource, getViewHmrConfigurationResource, } from './utils.js';
7
7
  import { getModuleGraphCacheKey } from '../utils.js';
8
- import { setPreloadModulesMeta, getPreloadModulesMeta } from './preload-utils.js';
8
+ import { setPreloadModulesMeta, getPreloadModulesMeta, getPreloadModuleList, } from './preload-utils.js';
9
9
  // `getModuleGraphs` is very expensive and does not need to be recomputed every time.
10
10
  // Note: we use the same cache key passed in from the top level view-registry for consistency
11
11
  const moduleGraphsCache = new LRUCache({
@@ -87,6 +87,7 @@ export async function getHtmlResources(view, viewParams, resourceContext) {
87
87
  const viewPreloads = {
88
88
  uris: [],
89
89
  specifiers: [],
90
+ includedModules: [],
90
91
  groups: new Map(),
91
92
  integrities: new Map(),
92
93
  };
@@ -232,7 +233,9 @@ export async function getHtmlResources(view, viewParams, resourceContext) {
232
233
  const specifier = graph.graphs[0].specifier;
233
234
  const uri = graph.uriMap[specifier];
234
235
  const integrity = getBundleIntegrity(graph, specifier);
235
- setPreloadModulesMeta(specifier, uri, integrity, groups, viewPreloads);
236
+ const bundleDef = graph.linkedDefinitions[specifier];
237
+ const includedModules = bundleDef?.bundleRecord ? bundleDef.bundleRecord.includedModules : [];
238
+ setPreloadModulesMeta(specifier, uri, integrity, groups, viewPreloads, includedModules);
236
239
  // PRELOAD custom element static deps as link resources when bundling is ON
237
240
  if (bundle) {
238
241
  for (const depSpecifier of graph.graphs[0].static) {
@@ -281,7 +284,7 @@ export async function getHtmlResources(view, viewParams, resourceContext) {
281
284
  serverData,
282
285
  ...(isAMD && { requiredModules: requiredAmdModules }),
283
286
  // in AMD we need to tell the loader what modules we are preloading
284
- ...(isAMD && { preloadModules: viewPreloads.specifiers }),
287
+ ...(isAMD && { preloadModules: getPreloadModuleList(viewPreloads) }),
285
288
  }, runtimeEnvironment, runtimeParams, serverDebug?.warnings));
286
289
  }
287
290
  if (!isAMD && hmrEnabled) {
@@ -4,6 +4,10 @@ import { getTracer, ViewSpan } from '@lwrjs/instrumentation';
4
4
  import { generateHtmlTag, generateLinkHeaders, generatePageContext, isViewResponse, isViewDefinitionResponse, toJsonFormat, } from './utils.js';
5
5
  import { LwrApplicationError, LwrError, descriptions } from '@lwrjs/diagnostics';
6
6
  export class LwrViewHandler {
7
+ globalConfig;
8
+ routeHandlers;
9
+ viewRegistry;
10
+ moduleRegistry;
7
11
  constructor(context, globalConfig) {
8
12
  this.globalConfig = globalConfig;
9
13
  this.routeHandlers = context.routeHandlers;
package/package.json CHANGED
@@ -4,7 +4,7 @@
4
4
  "publishConfig": {
5
5
  "access": "public"
6
6
  },
7
- "version": "0.17.2-alpha.9",
7
+ "version": "0.17.2",
8
8
  "homepage": "https://developer.salesforce.com/docs/platform/lwr/overview",
9
9
  "repository": {
10
10
  "type": "git",
@@ -33,20 +33,21 @@
33
33
  "build": "tsc -b"
34
34
  },
35
35
  "dependencies": {
36
- "@lwrjs/app-service": "0.17.2-alpha.9",
37
- "@lwrjs/diagnostics": "0.17.2-alpha.9",
38
- "@lwrjs/instrumentation": "0.17.2-alpha.9",
39
- "@lwrjs/shared-utils": "0.17.2-alpha.9",
36
+ "@lwrjs/app-service": "0.17.2",
37
+ "@lwrjs/config": "0.17.2",
38
+ "@lwrjs/diagnostics": "0.17.2",
39
+ "@lwrjs/instrumentation": "0.17.2",
40
+ "@lwrjs/shared-utils": "0.17.2",
40
41
  "lru-cache": "^10.4.3"
41
42
  },
42
43
  "devDependencies": {
43
- "@lwrjs/types": "0.17.2-alpha.9"
44
+ "@lwrjs/types": "0.17.2"
44
45
  },
45
46
  "engines": {
46
- "node": ">=18.0.0"
47
+ "node": ">=20.0.0"
47
48
  },
48
49
  "volta": {
49
50
  "extends": "../../../package.json"
50
51
  },
51
- "gitHead": "7ede5d04a97513b9869b13e66155bc4f3920bb99"
52
+ "gitHead": "d64d8888a28da36c05e3d8d9baf51416551863a9"
52
53
  }