@lwrjs/view-registry 0.15.0-alpha.3 → 0.15.0-alpha.30
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/build/cjs/index.cjs +64 -46
- package/build/cjs/linkers/legacy_view_bootstrap.cjs +27 -5
- package/build/cjs/linkers/link-lwr-resources.cjs +7 -7
- package/build/cjs/linkers/utils.cjs +1 -1
- package/build/cjs/linkers/view_bootstrap.cjs +28 -5
- package/build/cjs/utils.cjs +52 -3
- package/build/cjs/view-handler.cjs +21 -1
- package/build/es/index.js +70 -45
- package/build/es/linkers/legacy_view_bootstrap.d.ts +2 -14
- package/build/es/linkers/legacy_view_bootstrap.js +31 -5
- package/build/es/linkers/link-lwr-resources.d.ts +3 -1
- package/build/es/linkers/link-lwr-resources.js +11 -9
- package/build/es/linkers/utils.js +2 -1
- package/build/es/linkers/view_bootstrap.d.ts +2 -14
- package/build/es/linkers/view_bootstrap.js +33 -6
- package/build/es/utils.d.ts +6 -2
- package/build/es/utils.js +55 -3
- package/build/es/view-handler.js +27 -1
- package/package.json +10 -7
package/build/cjs/index.cjs
CHANGED
|
@@ -51,7 +51,12 @@ var LwrViewRegistry = class {
|
|
|
51
51
|
this.globalData = context.globalData;
|
|
52
52
|
this.appEmitter = context.appEmitter;
|
|
53
53
|
const observer = context.appObserver;
|
|
54
|
-
this.viewDefinitions = new import_lru_cache.LRUCache({
|
|
54
|
+
this.viewDefinitions = new import_lru_cache.LRUCache({
|
|
55
|
+
max: parseInt(process.env.VIEW_CACHE_SIZE ?? "500", 10),
|
|
56
|
+
dispose: (_value, key) => {
|
|
57
|
+
import_diagnostics.logger.verbose(`View evicted from cache ${key}`);
|
|
58
|
+
}
|
|
59
|
+
});
|
|
55
60
|
observer.onViewSourceChange(({payload}) => this.onViewSourceChange(payload));
|
|
56
61
|
observer.onModuleDefinitionChange(({payload}) => this.onModuleDefinitionChange(payload));
|
|
57
62
|
observer.onAssetSourceChange(({payload}) => this.onAssetSourceChange(payload));
|
|
@@ -140,28 +145,20 @@ var LwrViewRegistry = class {
|
|
|
140
145
|
const {contentTemplate, rootComponent} = viewId;
|
|
141
146
|
const compiledViewCacheKey = (0, import_shared_utils.getCacheKeyFromJson)({contentTemplate, rootComponent});
|
|
142
147
|
import_diagnostics.logger.debug(`[view-registry][getView] compiledViewCacheKey=${compiledViewCacheKey}`);
|
|
143
|
-
|
|
148
|
+
const route = this.globalConfig.routes.find((r) => r.id === viewId.id);
|
|
149
|
+
const skipCaching = route?.cache?.ttl === 0;
|
|
150
|
+
if (!skipCaching && this.compiledViews.has(compiledViewCacheKey)) {
|
|
144
151
|
return this.compiledViews.get(compiledViewCacheKey);
|
|
145
152
|
}
|
|
146
153
|
const compiledView = await this.delegateGetView(viewId);
|
|
147
|
-
|
|
154
|
+
if (!skipCaching) {
|
|
155
|
+
this.compiledViews.set(compiledViewCacheKey, compiledView);
|
|
156
|
+
}
|
|
148
157
|
return compiledView;
|
|
149
158
|
}
|
|
150
159
|
hasViewDefinition(view, viewParams, runtimeEnvironment, runtimeParams, renderOptions) {
|
|
151
|
-
const {id, bootstrap, rootComponent, contentTemplate, layoutTemplate} = view;
|
|
152
160
|
const {freezeAssets, viewParamCacheKey} = (0, import_utils.normalizeRenderOptions)(this.runtimeEnvironment, renderOptions);
|
|
153
|
-
const viewDefId = (0,
|
|
154
|
-
id,
|
|
155
|
-
bootstrap,
|
|
156
|
-
rootComponent,
|
|
157
|
-
contentTemplate,
|
|
158
|
-
layoutTemplate,
|
|
159
|
-
freezeAssets,
|
|
160
|
-
locale: runtimeParams?.locale,
|
|
161
|
-
basePath: runtimeParams?.basePath,
|
|
162
|
-
debug: runtimeEnvironment.debug,
|
|
163
|
-
nonceEnabled: (0, import_shared_utils.getFeatureFlags)().ENABLE_NONCE
|
|
164
|
-
});
|
|
161
|
+
const viewDefId = (0, import_utils.getViewDefCacheKey)(view, runtimeEnvironment, freezeAssets, runtimeParams);
|
|
165
162
|
import_diagnostics.logger.debug(`[view-registry][hasViewDefinition] viewDefId=${viewDefId}`);
|
|
166
163
|
const viewParamKey = viewParamCacheKey ? (0, import_shared_utils.getCacheKeyFromJson)(viewParamCacheKey) : (0, import_shared_utils.getCacheKeyFromJson)(viewParams);
|
|
167
164
|
import_diagnostics.logger.debug(`[view-registry][hasViewDefinition] viewParamKey=${viewParamKey}`);
|
|
@@ -173,22 +170,16 @@ var LwrViewRegistry = class {
|
|
|
173
170
|
}
|
|
174
171
|
return false;
|
|
175
172
|
}
|
|
176
|
-
async getViewDefinition(view, viewParams, runtimeEnvironment, runtimeParams, renderOptions) {
|
|
173
|
+
async getViewDefinition(view, viewParams, runtimeEnvironment, runtimeParams = {requestCache: {}}, renderOptions) {
|
|
174
|
+
runtimeParams.requestCache = runtimeParams.requestCache ?? {};
|
|
177
175
|
try {
|
|
178
176
|
const {freezeAssets, viewParamCacheKey} = (0, import_utils.normalizeRenderOptions)(this.runtimeEnvironment, renderOptions);
|
|
179
|
-
const viewDefCacheKey = (0,
|
|
180
|
-
...view,
|
|
181
|
-
freezeAssets,
|
|
182
|
-
locale: runtimeParams?.locale,
|
|
183
|
-
basePath: runtimeParams?.basePath,
|
|
184
|
-
debug: runtimeEnvironment.debug,
|
|
185
|
-
nonceEnabled: (0, import_shared_utils.getFeatureFlags)().ENABLE_NONCE
|
|
186
|
-
});
|
|
177
|
+
const viewDefCacheKey = (0, import_utils.getViewDefCacheKey)(view, runtimeEnvironment, freezeAssets, runtimeParams);
|
|
187
178
|
import_diagnostics.logger.debug(`[view-registry][getViewDefinition] viewDefCacheKey=${viewDefCacheKey}`);
|
|
188
179
|
const viewParamKey = viewParamCacheKey ? (0, import_shared_utils.getCacheKeyFromJson)(viewParamCacheKey) : (0, import_shared_utils.getCacheKeyFromJson)(viewParams);
|
|
189
180
|
import_diagnostics.logger.debug(`[view-registry][getViewDefinition] viewParamKey=${viewParamKey}`);
|
|
190
|
-
if (this.viewDefinitions.has(viewDefCacheKey)) {
|
|
191
|
-
const viewDefinition2 = this.viewDefinitions.get(viewDefCacheKey);
|
|
181
|
+
if (this.viewDefinitions.has(viewDefCacheKey) || runtimeParams.requestCache[viewDefCacheKey]) {
|
|
182
|
+
const viewDefinition2 = this.viewDefinitions.get(viewDefCacheKey) || runtimeParams.requestCache[viewDefCacheKey];
|
|
192
183
|
if (viewDefinition2 && viewDefinition2.paramKey === viewParamKey && viewDefinition2.viewDefinition.immutable) {
|
|
193
184
|
return viewDefinition2.viewDefinition;
|
|
194
185
|
}
|
|
@@ -202,18 +193,19 @@ var LwrViewRegistry = class {
|
|
|
202
193
|
view: view.id,
|
|
203
194
|
ssr: view.bootstrap?.ssr === true
|
|
204
195
|
}
|
|
205
|
-
}, () => this.renderView(view, updatableViewParams, runtimeEnvironment, runtimeParams, renderOptions)));
|
|
196
|
+
}, () => this.renderView(view, updatableViewParams, runtimeEnvironment, runtimeParams, pendingViewDefCacheKey, renderOptions)));
|
|
206
197
|
viewDefinition.nonce = (0, import_utils.getViewNonce)(updatableViewParams);
|
|
207
198
|
const route = this.globalConfig.routes.find((r) => r.id === view.id);
|
|
208
199
|
const maxViewCacheTtl = (0, import_shared_utils.getFeatureFlags)().MAX_VIEW_CACHE_TTL;
|
|
209
200
|
const maxTtl = maxViewCacheTtl && parseInt(maxViewCacheTtl, 10);
|
|
210
201
|
const leastTtl = (0, import_shared_utils.shortestTtl)(viewDefinition.cache?.ttl, route?.cache?.ttl, maxTtl);
|
|
211
202
|
const ttl = leastTtl !== void 0 ? leastTtl === 0 ? 10 : leastTtl * 1e3 : void 0;
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
203
|
+
const viewDefCacheEntry = {view, viewDefinition, paramKey: viewParamKey};
|
|
204
|
+
if (view.bootstrap?.includeCookiesForSSR) {
|
|
205
|
+
runtimeParams.requestCache[viewDefCacheKey] = viewDefCacheEntry;
|
|
206
|
+
} else {
|
|
207
|
+
this.viewDefinitions.set(viewDefCacheKey, viewDefCacheEntry, {ttl});
|
|
208
|
+
}
|
|
217
209
|
return viewDefinition;
|
|
218
210
|
} catch (err) {
|
|
219
211
|
if (err instanceof import_diagnostics.DiagnosticsError) {
|
|
@@ -225,10 +217,10 @@ var LwrViewRegistry = class {
|
|
|
225
217
|
throw (0, import_diagnostics.createSingleDiagnosticError)({description: import_diagnostics.descriptions.SERVER.UNEXPECTED_ERROR(message)}, import_diagnostics.LwrServerError);
|
|
226
218
|
}
|
|
227
219
|
}
|
|
228
|
-
async renderView(view, viewParams, runtimeEnvironment, runtimeParams
|
|
220
|
+
async renderView(view, viewParams, runtimeEnvironment, runtimeParams, viewCacheKey, renderOptions) {
|
|
229
221
|
const {id, contentTemplate, rootComponent, layoutTemplate} = view;
|
|
230
222
|
const lwrResourcesId = `__LWR_RESOURCES__${Date.now()}`;
|
|
231
|
-
const renderedContent = await this.render({id, contentTemplate, rootComponent}, {...viewParams, lwr_resources: lwrResourcesId}, runtimeParams, runtimeEnvironment
|
|
223
|
+
const renderedContent = await this.render({id, contentTemplate, rootComponent}, {...viewParams, lwr_resources: lwrResourcesId}, runtimeParams, runtimeEnvironment);
|
|
232
224
|
let normalizedRenderOptions = (0, import_utils.normalizeRenderOptions)(this.runtimeEnvironment, renderedContent.options, renderOptions);
|
|
233
225
|
const layout = layoutTemplate || renderedContent.compiledView.layoutTemplate;
|
|
234
226
|
if (!layout) {
|
|
@@ -238,7 +230,8 @@ var LwrViewRegistry = class {
|
|
|
238
230
|
runtimeEnvironment,
|
|
239
231
|
runtimeParams,
|
|
240
232
|
renderOptions: normalizedRenderOptions,
|
|
241
|
-
contentIds: {lwrResourcesId}
|
|
233
|
+
contentIds: {lwrResourcesId},
|
|
234
|
+
viewCacheKey
|
|
242
235
|
});
|
|
243
236
|
return renderedViewDef2;
|
|
244
237
|
}
|
|
@@ -274,7 +267,8 @@ var LwrViewRegistry = class {
|
|
|
274
267
|
...renderedLayout.metadata.serverDebug
|
|
275
268
|
}
|
|
276
269
|
},
|
|
277
|
-
cache: renderedContent.cache
|
|
270
|
+
cache: renderedContent.cache,
|
|
271
|
+
redirect: renderedContent.redirect
|
|
278
272
|
}, {
|
|
279
273
|
view: {...view, layoutTemplate: layoutTemplatePath},
|
|
280
274
|
viewParams,
|
|
@@ -282,11 +276,12 @@ var LwrViewRegistry = class {
|
|
|
282
276
|
runtimeParams,
|
|
283
277
|
renderOptions: normalizedRenderOptions,
|
|
284
278
|
contentIds: {lwrResourcesId},
|
|
285
|
-
importer: renderedContent.compiledView.filePath
|
|
279
|
+
importer: renderedContent.compiledView.filePath,
|
|
280
|
+
viewCacheKey
|
|
286
281
|
});
|
|
287
282
|
return renderedViewDef;
|
|
288
283
|
}
|
|
289
|
-
async render(viewId, viewParams, runtimeParams, runtimeEnvironment
|
|
284
|
+
async render(viewId, viewParams, runtimeParams, runtimeEnvironment) {
|
|
290
285
|
const globalContext = this.globalData;
|
|
291
286
|
const {id, rootComponent, contentTemplate} = viewId;
|
|
292
287
|
const compiledView = await this.getView({id, contentTemplate, rootComponent});
|
|
@@ -310,7 +305,8 @@ var LwrViewRegistry = class {
|
|
|
310
305
|
runtimeParams,
|
|
311
306
|
renderOptions,
|
|
312
307
|
contentIds,
|
|
313
|
-
importer
|
|
308
|
+
importer,
|
|
309
|
+
viewCacheKey
|
|
314
310
|
} = viewContext;
|
|
315
311
|
const {skipMetadataCollection, freezeAssets} = renderOptions;
|
|
316
312
|
const {lwrResourcesId} = contentIds;
|
|
@@ -321,19 +317,37 @@ var LwrViewRegistry = class {
|
|
|
321
317
|
metadata: renderedViewMetadata,
|
|
322
318
|
compiledView: {immutable = true}
|
|
323
319
|
} = renderedView;
|
|
324
|
-
const linkedMetadata =
|
|
320
|
+
const {linkedMetadata, stringBuilder} = await (0, import_instrumentation.getTracer)().trace({
|
|
321
|
+
name: import_instrumentation.ViewSpan.ParseView,
|
|
322
|
+
attributes: {
|
|
323
|
+
view: view.id,
|
|
324
|
+
ssr: view.bootstrap?.ssr === true
|
|
325
|
+
}
|
|
326
|
+
}, async () => {
|
|
327
|
+
const linkedMetadata2 = skipMetadataCollection ? renderedViewMetadata : await (0, import_shared_utils.extractMetadataFromHtml)(renderedViewContent, renderedViewMetadata, this.globalConfig);
|
|
328
|
+
const stringBuilder2 = (0, import_shared_utils.createStringBuilder)(renderedViewContent);
|
|
329
|
+
return {linkedMetadata: linkedMetadata2, stringBuilder: stringBuilder2};
|
|
330
|
+
});
|
|
325
331
|
const mergedViewContext = {
|
|
326
332
|
...viewContext,
|
|
327
333
|
config: this.globalConfig,
|
|
328
334
|
runtimeEnvironment,
|
|
329
335
|
importer: importer || renderedView.compiledView.filePath
|
|
330
336
|
};
|
|
331
|
-
const stringBuilder = (0, import_shared_utils.createStringBuilder)(renderedViewContent);
|
|
332
337
|
let pageTtl = renderedView.cache.ttl;
|
|
338
|
+
let pageRedirect = renderedView.redirect;
|
|
333
339
|
for (const viewTransformer of this.viewTransformers) {
|
|
334
|
-
const linkResults = await
|
|
340
|
+
const linkResults = await (0, import_instrumentation.getTracer)().trace({
|
|
341
|
+
name: import_instrumentation.ViewSpan.Transform,
|
|
342
|
+
attributes: {
|
|
343
|
+
name: viewTransformer.name
|
|
344
|
+
}
|
|
345
|
+
}, () => viewTransformer.link?.(stringBuilder, mergedViewContext, linkedMetadata));
|
|
335
346
|
const ttl = linkResults && linkResults.cache?.ttl;
|
|
336
347
|
pageTtl = (0, import_shared_utils.shortestTtl)(ttl || void 0, pageTtl);
|
|
348
|
+
if (!pageRedirect) {
|
|
349
|
+
pageRedirect = linkResults ? linkResults.redirect : void 0;
|
|
350
|
+
}
|
|
337
351
|
}
|
|
338
352
|
const linkedAssetContent = stringBuilder.toString();
|
|
339
353
|
if (linkedAssetContent.includes(lwrResourcesId)) {
|
|
@@ -345,7 +359,9 @@ var LwrViewRegistry = class {
|
|
|
345
359
|
resourceRegistry,
|
|
346
360
|
runtimeEnvironment,
|
|
347
361
|
runtimeParams,
|
|
348
|
-
bundleConfig: this.globalConfig.bundleConfig
|
|
362
|
+
bundleConfig: this.globalConfig.bundleConfig,
|
|
363
|
+
unsafeEnableViewLinkCaching: this.globalConfig.unsafeEnableViewLinkCaching,
|
|
364
|
+
viewLinkCacheKey: viewCacheKey
|
|
349
365
|
});
|
|
350
366
|
return {
|
|
351
367
|
renderedView: linkedView,
|
|
@@ -354,7 +370,8 @@ var LwrViewRegistry = class {
|
|
|
354
370
|
assetReferences: (0, import_utils.reduceSourceAssetReferences)(linkedMetadata.assetReferences),
|
|
355
371
|
...viewRecord
|
|
356
372
|
},
|
|
357
|
-
cache: {ttl: pageTtl}
|
|
373
|
+
cache: {ttl: pageTtl},
|
|
374
|
+
redirect: pageRedirect
|
|
358
375
|
};
|
|
359
376
|
}
|
|
360
377
|
return {
|
|
@@ -364,7 +381,8 @@ var LwrViewRegistry = class {
|
|
|
364
381
|
assetReferences: (0, import_utils.reduceSourceAssetReferences)(linkedMetadata.assetReferences),
|
|
365
382
|
moduleResources: []
|
|
366
383
|
},
|
|
367
|
-
cache: {ttl: pageTtl}
|
|
384
|
+
cache: {ttl: pageTtl},
|
|
385
|
+
redirect: pageRedirect
|
|
368
386
|
};
|
|
369
387
|
}
|
|
370
388
|
};
|
|
@@ -32,6 +32,7 @@ var import_identity = __toModule(require("@lwrjs/app-service/identity"));
|
|
|
32
32
|
var import_utils = __toModule(require("../utils.cjs"));
|
|
33
33
|
var import_utils2 = __toModule(require("./utils.cjs"));
|
|
34
34
|
var import_preload_utils = __toModule(require("./preload-utils.cjs"));
|
|
35
|
+
var import_lru_cache = __toModule(require("lru-cache"));
|
|
35
36
|
function includeIdFactory(bundleConfig) {
|
|
36
37
|
return (moduleRef) => {
|
|
37
38
|
if ((0, import_shared_utils.isExternalSpecifier)(moduleRef.specifier, bundleConfig)) {
|
|
@@ -40,6 +41,8 @@ function includeIdFactory(bundleConfig) {
|
|
|
40
41
|
return true;
|
|
41
42
|
};
|
|
42
43
|
}
|
|
44
|
+
var moduleGraphsCache = new import_lru_cache.LRUCache({max: 500});
|
|
45
|
+
var isRunningLocalDev = (0, import_shared_utils.isLocalDev)();
|
|
43
46
|
async function getHtmlResources(view, viewParams, resourceContext) {
|
|
44
47
|
const {
|
|
45
48
|
runtimeEnvironment,
|
|
@@ -47,14 +50,16 @@ async function getHtmlResources(view, viewParams, resourceContext) {
|
|
|
47
50
|
moduleRegistry,
|
|
48
51
|
moduleBundler,
|
|
49
52
|
resourceRegistry,
|
|
50
|
-
viewMetadata
|
|
53
|
+
viewMetadata,
|
|
54
|
+
viewLinkCacheKey
|
|
51
55
|
} = resourceContext;
|
|
52
56
|
const {format, hmrEnabled, bundle, debug, minify} = runtimeEnvironment;
|
|
53
57
|
const {customElements, serverData, serverDebug} = viewMetadata;
|
|
54
58
|
const isAMD = format === "amd";
|
|
55
|
-
const {bundleConfig} = resourceContext;
|
|
59
|
+
const {bundleConfig, unsafeEnableViewLinkCaching} = resourceContext;
|
|
56
60
|
const {external = {}, exclude = []} = bundleConfig;
|
|
57
61
|
const groups = isAMD ? bundleConfig.groups || {} : {};
|
|
62
|
+
const enableModuleGraphsCache = unsafeEnableViewLinkCaching && !isRunningLocalDev && !process.env.NOCACHE;
|
|
58
63
|
const getPreloadUri = function(rawSpecifier, uriMap) {
|
|
59
64
|
const {specifier} = (0, import_shared_utils.explodeSpecifier)(rawSpecifier);
|
|
60
65
|
if (Object.keys(external).some((e) => specifier === e))
|
|
@@ -139,7 +144,14 @@ async function getHtmlResources(view, viewParams, resourceContext) {
|
|
|
139
144
|
(0, import_utils.addExternalScriptNonce)(errorShimDef, nonce);
|
|
140
145
|
requiredResources.push(errorShimDef);
|
|
141
146
|
}
|
|
142
|
-
|
|
147
|
+
let bootstrapModuleGraph;
|
|
148
|
+
const bootstrapModuleGraphCacheKey = (0, import_utils.getModuleGraphCacheKey)(bootstrapSpecifier, viewLinkCacheKey);
|
|
149
|
+
if (enableModuleGraphsCache && moduleGraphsCache.has(bootstrapModuleGraphCacheKey)) {
|
|
150
|
+
bootstrapModuleGraph = moduleGraphsCache.get(bootstrapModuleGraphCacheKey);
|
|
151
|
+
} else {
|
|
152
|
+
bootstrapModuleGraph = await (0, import_shared_utils.getModuleGraphs)(bootstrapSpecifier, {includeUris: true, includeLinkedDefinitions: true, depth}, moduleRegistry, defRegistry, runtimeEnvironment, runtimeParams, visitedCache);
|
|
153
|
+
enableModuleGraphsCache && moduleGraphsCache.set(bootstrapModuleGraphCacheKey, bootstrapModuleGraph);
|
|
154
|
+
}
|
|
143
155
|
bootstrapModuleRef = {
|
|
144
156
|
specifier: bootstrapModuleGraph.graphs[0].specifier,
|
|
145
157
|
flatGraph: bootstrapModuleGraph,
|
|
@@ -188,7 +200,16 @@ async function getHtmlResources(view, viewParams, resourceContext) {
|
|
|
188
200
|
}
|
|
189
201
|
}
|
|
190
202
|
await Promise.all(flattenedElements.map(async ({tagName: element, props}) => {
|
|
191
|
-
const
|
|
203
|
+
const hydrateDirective = (0, import_shared_utils.getHydrateDirective)(props);
|
|
204
|
+
const isSsrOnly = isSSR && !hydrateDirective;
|
|
205
|
+
const moduleGraphCacheKey = (0, import_utils.getModuleGraphCacheKey)(element, viewLinkCacheKey);
|
|
206
|
+
let graph;
|
|
207
|
+
if (enableModuleGraphsCache && moduleGraphsCache.has(moduleGraphCacheKey)) {
|
|
208
|
+
graph = moduleGraphsCache.get(moduleGraphCacheKey);
|
|
209
|
+
} else {
|
|
210
|
+
graph = await (0, import_shared_utils.getModuleGraphs)((0, import_shared_utils.kebabCaseToModuleSpecifier)(element), {includeUris: true, includeLinkedDefinitions: true, depth}, moduleRegistry, defRegistry, runtimeEnvironment, {...runtimeParams, ssr: isSsrOnly}, visitedCache);
|
|
211
|
+
enableModuleGraphsCache && moduleGraphsCache.set(moduleGraphCacheKey, graph);
|
|
212
|
+
}
|
|
192
213
|
customElementsRecords.push({elementName: element, flatGraph: graph});
|
|
193
214
|
if (!isSSR || (0, import_shared_utils.getHydrateDirective)(props)) {
|
|
194
215
|
const specifier = graph.graphs[0].specifier;
|
|
@@ -231,7 +252,8 @@ async function getHtmlResources(view, viewParams, resourceContext) {
|
|
|
231
252
|
url: viewParams?.page?.url,
|
|
232
253
|
configAsSrc: view.bootstrap?.configAsSrc || false,
|
|
233
254
|
mixedMode: view.bootstrap?.mixedMode || false,
|
|
234
|
-
nonce: viewParams?.page?.nonce
|
|
255
|
+
nonce: viewParams?.page?.nonce,
|
|
256
|
+
ssr: view.bootstrap?.ssr || false
|
|
235
257
|
}, {
|
|
236
258
|
appId: appIdentity.appName,
|
|
237
259
|
bootstrapModule: versionedSpecifier,
|
|
@@ -32,16 +32,16 @@ var import_legacy_view_bootstrap = __toModule(require("./legacy_view_bootstrap.c
|
|
|
32
32
|
async function linkLwrResources(source, view, viewParams, cxt) {
|
|
33
33
|
const {lwrResourcesId, ...resourceContext} = cxt;
|
|
34
34
|
const LEGACY_LOADER = !!resourceContext.runtimeEnvironment.featureFlags.LEGACY_LOADER;
|
|
35
|
-
|
|
35
|
+
return await (0, import_instrumentation.getTracer)().trace({
|
|
36
36
|
name: import_instrumentation.ViewSpan.Generate,
|
|
37
37
|
attributes: {
|
|
38
38
|
legacyLoader: LEGACY_LOADER
|
|
39
39
|
}
|
|
40
|
-
}, () => {
|
|
41
|
-
|
|
40
|
+
}, async () => {
|
|
41
|
+
const {partial, viewRecord} = await (LEGACY_LOADER ? (0, import_legacy_view_bootstrap.getHtmlResources)(view, viewParams, resourceContext) : (0, import_view_bootstrap.getHtmlResources)(view, viewParams, resourceContext));
|
|
42
|
+
return {
|
|
43
|
+
renderedView: source.replace(lwrResourcesId, () => partial),
|
|
44
|
+
viewRecord
|
|
45
|
+
};
|
|
42
46
|
});
|
|
43
|
-
return {
|
|
44
|
-
renderedView: source.replace(lwrResourcesId, partial),
|
|
45
|
-
viewRecord
|
|
46
|
-
};
|
|
47
47
|
}
|
|
@@ -63,7 +63,7 @@ function getViewBootstrapConfigurationResource(viewInfo, config, runtimeEnvironm
|
|
|
63
63
|
})});`,
|
|
64
64
|
`globalThis.LWR = {...globalThis.LWR, env: ${JSON.stringify(lwrEnv)}};`,
|
|
65
65
|
`globalThis.process={...globalThis.process,env:{...globalThis.process?.env,...${JSON.stringify(nodeEnv)}}};`,
|
|
66
|
-
`globalThis.lwcRuntimeFlags = { ENABLE_MIXED_SHADOW_MODE: ${viewInfo.mixedMode} };`,
|
|
66
|
+
`globalThis.lwcRuntimeFlags = { ENABLE_MIXED_SHADOW_MODE: ${viewInfo.mixedMode}, ENABLE_WIRE_SYNC_EMIT: ${viewInfo.ssr} };`,
|
|
67
67
|
debug && debugMessage && `console.error(${JSON.stringify(debugMessage)});`
|
|
68
68
|
].filter(Boolean).join("\n");
|
|
69
69
|
if (viewInfo.configAsSrc) {
|
|
@@ -28,10 +28,14 @@ __export(exports, {
|
|
|
28
28
|
});
|
|
29
29
|
var import_diagnostics = __toModule(require("@lwrjs/diagnostics"));
|
|
30
30
|
var import_shared_utils = __toModule(require("@lwrjs/shared-utils"));
|
|
31
|
+
var import_lru_cache = __toModule(require("lru-cache"));
|
|
31
32
|
var import_identity = __toModule(require("@lwrjs/app-service/identity"));
|
|
32
33
|
var import_utils = __toModule(require("../utils.cjs"));
|
|
33
34
|
var import_utils2 = __toModule(require("./utils.cjs"));
|
|
35
|
+
var import_utils3 = __toModule(require("../utils.cjs"));
|
|
34
36
|
var import_preload_utils = __toModule(require("./preload-utils.cjs"));
|
|
37
|
+
var moduleGraphsCache = new import_lru_cache.LRUCache({max: 500});
|
|
38
|
+
var isRunningLocalDev = (0, import_shared_utils.isLocalDev)();
|
|
35
39
|
async function getHtmlResources(view, viewParams, resourceContext) {
|
|
36
40
|
const {
|
|
37
41
|
runtimeEnvironment,
|
|
@@ -39,16 +43,18 @@ async function getHtmlResources(view, viewParams, resourceContext) {
|
|
|
39
43
|
moduleRegistry,
|
|
40
44
|
moduleBundler,
|
|
41
45
|
resourceRegistry,
|
|
42
|
-
viewMetadata
|
|
46
|
+
viewMetadata,
|
|
47
|
+
viewLinkCacheKey
|
|
43
48
|
} = resourceContext;
|
|
44
49
|
const {format, hmrEnabled, bundle, debug, minify} = runtimeEnvironment;
|
|
45
50
|
const {customElements, serverData, serverDebug} = viewMetadata;
|
|
46
51
|
const defRegistry = bundle ? moduleBundler : moduleRegistry;
|
|
47
52
|
const isAMD = format === "amd";
|
|
48
53
|
const depth = isAMD ? {static: import_shared_utils.GraphDepth.ALL, dynamic: 1} : {static: import_shared_utils.GraphDepth.NONE, dynamic: 1};
|
|
49
|
-
const {bundleConfig} = resourceContext;
|
|
54
|
+
const {bundleConfig, unsafeEnableViewLinkCaching} = resourceContext;
|
|
50
55
|
const {external = {}, exclude = []} = bundleConfig;
|
|
51
56
|
const groups = isAMD ? bundleConfig.groups || {} : {};
|
|
57
|
+
const enableModuleGraphsCache = unsafeEnableViewLinkCaching && !isRunningLocalDev && !process.env.NOCACHE;
|
|
52
58
|
const getPreloadUri = function(rawSpecifier, uriMap) {
|
|
53
59
|
const {specifier} = (0, import_shared_utils.explodeSpecifier)(rawSpecifier);
|
|
54
60
|
if (Object.keys(external).some((e) => specifier === e))
|
|
@@ -119,7 +125,14 @@ async function getHtmlResources(view, viewParams, resourceContext) {
|
|
|
119
125
|
(0, import_utils.addExternalScriptNonce)(errorShimDef, nonce);
|
|
120
126
|
requiredResources.push(errorShimDef);
|
|
121
127
|
}
|
|
122
|
-
|
|
128
|
+
let bootstrapModuleGraph;
|
|
129
|
+
const bootstrapModuleGraphCacheKey = (0, import_utils3.getModuleGraphCacheKey)(bootstrapSpecifier, viewLinkCacheKey);
|
|
130
|
+
if (enableModuleGraphsCache && moduleGraphsCache.has(bootstrapModuleGraphCacheKey)) {
|
|
131
|
+
bootstrapModuleGraph = moduleGraphsCache.get(bootstrapModuleGraphCacheKey);
|
|
132
|
+
} else {
|
|
133
|
+
bootstrapModuleGraph = await (0, import_shared_utils.getModuleGraphs)(bootstrapSpecifier, {includeUris: true, includeLinkedDefinitions: true, depth}, moduleRegistry, defRegistry, runtimeEnvironment, runtimeParams, visitedCache);
|
|
134
|
+
enableModuleGraphsCache && moduleGraphsCache.set(bootstrapModuleGraphCacheKey, bootstrapModuleGraph);
|
|
135
|
+
}
|
|
123
136
|
bootstrapModuleRef = {
|
|
124
137
|
specifier: bootstrapModuleGraph.graphs[0].specifier,
|
|
125
138
|
flatGraph: bootstrapModuleGraph,
|
|
@@ -169,7 +182,16 @@ async function getHtmlResources(view, viewParams, resourceContext) {
|
|
|
169
182
|
importMetadata = await (0, import_shared_utils.toImportMetadata)(bootstrapModuleGraph, {imports: {}, index: {}}, moduleRegistry, runtimeEnvironment, runtimeParams);
|
|
170
183
|
}
|
|
171
184
|
for (const {tagName: element, props} of flattenedElements) {
|
|
172
|
-
const
|
|
185
|
+
const hydrateDirective = (0, import_shared_utils.getHydrateDirective)(props);
|
|
186
|
+
const isSsrOnly = isSSR && !hydrateDirective;
|
|
187
|
+
const moduleGraphCacheKey = (0, import_utils3.getModuleGraphCacheKey)(element, viewLinkCacheKey);
|
|
188
|
+
let graph;
|
|
189
|
+
if (enableModuleGraphsCache && moduleGraphsCache.has(moduleGraphCacheKey)) {
|
|
190
|
+
graph = moduleGraphsCache.get(moduleGraphCacheKey);
|
|
191
|
+
} else {
|
|
192
|
+
graph = await (0, import_shared_utils.getModuleGraphs)((0, import_shared_utils.kebabCaseToModuleSpecifier)(element), {includeUris: true, includeLinkedDefinitions: true, depth}, moduleRegistry, defRegistry, runtimeEnvironment, {...runtimeParams, ssr: isSsrOnly}, visitedCache);
|
|
193
|
+
enableModuleGraphsCache && moduleGraphsCache.set(moduleGraphCacheKey, graph);
|
|
194
|
+
}
|
|
173
195
|
customElementsRecords.push({elementName: element, flatGraph: graph});
|
|
174
196
|
if (!isSSR || (0, import_shared_utils.getHydrateDirective)(props)) {
|
|
175
197
|
const specifier = graph.graphs[0].specifier;
|
|
@@ -206,7 +228,8 @@ async function getHtmlResources(view, viewParams, resourceContext) {
|
|
|
206
228
|
url: viewParams?.page?.url,
|
|
207
229
|
configAsSrc: view.bootstrap?.configAsSrc || false,
|
|
208
230
|
mixedMode: view.bootstrap?.mixedMode || false,
|
|
209
|
-
nonce: viewParams?.page?.nonce
|
|
231
|
+
nonce: viewParams?.page?.nonce,
|
|
232
|
+
ssr: view.bootstrap?.ssr || false
|
|
210
233
|
}, {
|
|
211
234
|
appId: appIdentity.appName,
|
|
212
235
|
bootstrapModule: versionedSpecifier,
|
package/build/cjs/utils.cjs
CHANGED
|
@@ -27,11 +27,15 @@ __export(exports, {
|
|
|
27
27
|
addExternalScriptNonce: () => addExternalScriptNonce,
|
|
28
28
|
createJsonModule: () => createJsonModule,
|
|
29
29
|
generateHtmlTag: () => generateHtmlTag,
|
|
30
|
+
generateLinkHeaders: () => generateLinkHeaders,
|
|
30
31
|
generatePageContext: () => generatePageContext,
|
|
31
32
|
generateViewNonce: () => generateViewNonce,
|
|
33
|
+
getModuleGraphCacheKey: () => getModuleGraphCacheKey,
|
|
32
34
|
getModuleResource: () => getModuleResource,
|
|
33
35
|
getModuleResourceByUri: () => getModuleResourceByUri,
|
|
36
|
+
getViewDefCacheKey: () => getViewDefCacheKey,
|
|
34
37
|
getViewNonce: () => getViewNonce,
|
|
38
|
+
isViewDefinitionResponse: () => isViewDefinitionResponse,
|
|
35
39
|
isViewResponse: () => isViewResponse,
|
|
36
40
|
normalizeRenderOptions: () => normalizeRenderOptions,
|
|
37
41
|
normalizeRenderedResult: () => normalizeRenderedResult,
|
|
@@ -108,7 +112,8 @@ function normalizeRenderedResult({
|
|
|
108
112
|
renderedView,
|
|
109
113
|
metadata,
|
|
110
114
|
options,
|
|
111
|
-
cache
|
|
115
|
+
cache,
|
|
116
|
+
redirect
|
|
112
117
|
}) {
|
|
113
118
|
return {
|
|
114
119
|
renderedView,
|
|
@@ -121,7 +126,8 @@ function normalizeRenderedResult({
|
|
|
121
126
|
options: {
|
|
122
127
|
skipMetadataCollection: options ? options.skipMetadataCollection : false
|
|
123
128
|
},
|
|
124
|
-
cache: cache || {}
|
|
129
|
+
cache: cache || {},
|
|
130
|
+
redirect
|
|
125
131
|
};
|
|
126
132
|
}
|
|
127
133
|
function reduceSourceAssetReferences(assets) {
|
|
@@ -149,11 +155,16 @@ function generatePageContext({requestPath: url}, {id, contentTemplate, propertie
|
|
|
149
155
|
const title = properties?.title || getTitleFromFilePath(contentTemplate);
|
|
150
156
|
const locale = runtimeParams.locale;
|
|
151
157
|
const basePath = runtimeParams.basePath;
|
|
152
|
-
|
|
158
|
+
const assetBasePath = runtimeParams.assetBasePath;
|
|
159
|
+
const uiBasePath = runtimeParams.uiBasePath;
|
|
160
|
+
return {assetBasePath, basePath, id, locale, title, url, uiBasePath};
|
|
153
161
|
}
|
|
154
162
|
function isViewResponse(response) {
|
|
155
163
|
return response.body !== void 0;
|
|
156
164
|
}
|
|
165
|
+
function isViewDefinitionResponse(response) {
|
|
166
|
+
return response.view !== void 0;
|
|
167
|
+
}
|
|
157
168
|
async function toJsonFormat(viewRequest, viewDefinition, route, runtimeEnvironment, runtimeParams, moduleRegistry) {
|
|
158
169
|
const {viewRecord} = viewDefinition;
|
|
159
170
|
const {bootstrap, id: appName} = route;
|
|
@@ -291,3 +302,41 @@ function addExternalScriptNonce(def, nonce) {
|
|
|
291
302
|
def.nonce = nonce;
|
|
292
303
|
}
|
|
293
304
|
}
|
|
305
|
+
function generateLinkHeaders(assets, patterns) {
|
|
306
|
+
const assetConfig = {};
|
|
307
|
+
for (let i = 0; i < patterns.length; i++) {
|
|
308
|
+
const pattern = patterns[i].match;
|
|
309
|
+
assets.forEach((asset) => {
|
|
310
|
+
const path = (asset.override?.uri || asset.url).split("?")[0];
|
|
311
|
+
if (typeof pattern === "string" && path.endsWith(pattern) || typeof pattern === "object" && pattern.some((match) => path.endsWith(match))) {
|
|
312
|
+
assetConfig[path] = patterns[i].attributes;
|
|
313
|
+
}
|
|
314
|
+
});
|
|
315
|
+
}
|
|
316
|
+
return Object.keys(assetConfig).reduce((linkHeader, path) => {
|
|
317
|
+
linkHeader = `${linkHeader ? linkHeader + ", " : ""}<${path}>`;
|
|
318
|
+
const properties = assetConfig[path];
|
|
319
|
+
for (const prop in properties) {
|
|
320
|
+
linkHeader += properties[prop] !== "" ? `; ${prop}=${properties[prop]}` : `; ${prop}`;
|
|
321
|
+
}
|
|
322
|
+
return linkHeader;
|
|
323
|
+
}, "");
|
|
324
|
+
}
|
|
325
|
+
function getViewDefCacheKey(view, runtimeEnvironment, freezeAssets, runtimeParams) {
|
|
326
|
+
const {id, bootstrap, rootComponent, contentTemplate, layoutTemplate} = view;
|
|
327
|
+
return (0, import_shared_utils.getCacheKeyFromJson)({
|
|
328
|
+
id,
|
|
329
|
+
bootstrap,
|
|
330
|
+
rootComponent,
|
|
331
|
+
contentTemplate,
|
|
332
|
+
layoutTemplate,
|
|
333
|
+
freezeAssets,
|
|
334
|
+
locale: runtimeParams?.locale,
|
|
335
|
+
basePath: runtimeParams?.basePath,
|
|
336
|
+
debug: runtimeEnvironment.debug,
|
|
337
|
+
nonceEnabled: (0, import_shared_utils.getFeatureFlags)().ENABLE_NONCE
|
|
338
|
+
});
|
|
339
|
+
}
|
|
340
|
+
function getModuleGraphCacheKey(specifier, viewLinkCacheKey) {
|
|
341
|
+
return specifier + viewLinkCacheKey;
|
|
342
|
+
}
|
|
@@ -46,9 +46,11 @@ var LwrViewHandler = class {
|
|
|
46
46
|
}
|
|
47
47
|
const {view, viewParams, renderOptions} = normalizeViewProperties(viewRequest, response, route, this.globalConfig, runtimeParams);
|
|
48
48
|
const viewDefinition2 = await this.viewRegistry.getViewDefinition(view, viewParams, runtimeEnvironment, runtimeParams, renderOptions);
|
|
49
|
+
const link2 = !!route?.bootstrap?.preloadResources?.patterns?.length && (0, import_utils.generateLinkHeaders)(viewDefinition2.viewRecord.assetReferences || [], route?.bootstrap?.preloadResources?.patterns || []);
|
|
49
50
|
return {
|
|
50
51
|
...response,
|
|
51
52
|
body: viewDefinition2.renderedView,
|
|
53
|
+
...!!link2 && {headers: {link: link2}},
|
|
52
54
|
metadata: {
|
|
53
55
|
viewDefinition: viewDefinition2
|
|
54
56
|
},
|
|
@@ -56,12 +58,14 @@ var LwrViewHandler = class {
|
|
|
56
58
|
};
|
|
57
59
|
}
|
|
58
60
|
const viewDefinition = await this.getDefaultRouteViewDefinition(viewRequest, route, runtimeEnvironment, runtimeParams);
|
|
61
|
+
const link = !!route?.bootstrap?.preloadResources?.patterns?.length && (0, import_utils.generateLinkHeaders)(viewDefinition.viewRecord.assetReferences || [], route.bootstrap?.preloadResources?.patterns || []);
|
|
59
62
|
return {
|
|
60
63
|
body: viewDefinition.renderedView,
|
|
61
64
|
metadata: {
|
|
62
65
|
viewDefinition
|
|
63
66
|
},
|
|
64
|
-
cache: viewDefinition.cache
|
|
67
|
+
cache: viewDefinition.cache,
|
|
68
|
+
...!!link && {headers: {link}}
|
|
65
69
|
};
|
|
66
70
|
}
|
|
67
71
|
async getViewJson(viewRequest, route, runtimeEnvironment, runtimeParams = {}) {
|
|
@@ -153,6 +157,22 @@ var LwrViewHandler = class {
|
|
|
153
157
|
if (response?.locale) {
|
|
154
158
|
runtimeParams.locale = response.locale;
|
|
155
159
|
}
|
|
160
|
+
const preloadResources = route?.bootstrap?.preloadResources?.patterns;
|
|
161
|
+
if (preloadResources && preloadResources.length) {
|
|
162
|
+
let viewDefintionMeta = response.metadata?.viewDefinition;
|
|
163
|
+
if (!viewDefintionMeta && (0, import_utils.isViewDefinitionResponse)(response)) {
|
|
164
|
+
viewDefintionMeta = (await viewApi.getViewResponse(response.view, response.viewParams, response.renderOptions)).metadata?.viewDefinition;
|
|
165
|
+
}
|
|
166
|
+
if (viewDefintionMeta) {
|
|
167
|
+
const link = (0, import_utils.generateLinkHeaders)(viewDefintionMeta?.viewRecord.assetReferences || [], preloadResources);
|
|
168
|
+
if (link) {
|
|
169
|
+
response.headers = {
|
|
170
|
+
...response.headers,
|
|
171
|
+
link
|
|
172
|
+
};
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
}
|
|
156
176
|
return response;
|
|
157
177
|
}
|
|
158
178
|
getBoundApi(viewRequest, route, runtimeEnvironment, runtimeParams) {
|