@lwrjs/view-registry 0.15.0-alpha.8 → 0.15.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.
- package/build/cjs/index.cjs +81 -49
- package/build/cjs/linkers/legacy_view_bootstrap.cjs +39 -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 +40 -5
- package/build/cjs/utils.cjs +73 -3
- package/build/cjs/view-handler.cjs +21 -1
- package/build/es/index.js +86 -46
- package/build/es/linkers/legacy_view_bootstrap.d.ts +2 -14
- package/build/es/linkers/legacy_view_bootstrap.js +47 -6
- 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 +48 -6
- package/build/es/utils.d.ts +6 -2
- package/build/es/utils.js +75 -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
|
}
|
|
@@ -272,9 +265,11 @@ var LwrViewRegistry = class {
|
|
|
272
265
|
serverDebug: {
|
|
273
266
|
...renderedContent.metadata.serverDebug,
|
|
274
267
|
...renderedLayout.metadata.serverDebug
|
|
275
|
-
}
|
|
268
|
+
},
|
|
269
|
+
serverBundles: renderedContent.metadata.serverBundles
|
|
276
270
|
},
|
|
277
|
-
cache: renderedContent.cache
|
|
271
|
+
cache: renderedContent.cache,
|
|
272
|
+
status: renderedContent.status
|
|
278
273
|
}, {
|
|
279
274
|
view: {...view, layoutTemplate: layoutTemplatePath},
|
|
280
275
|
viewParams,
|
|
@@ -282,11 +277,12 @@ var LwrViewRegistry = class {
|
|
|
282
277
|
runtimeParams,
|
|
283
278
|
renderOptions: normalizedRenderOptions,
|
|
284
279
|
contentIds: {lwrResourcesId},
|
|
285
|
-
importer: renderedContent.compiledView.filePath
|
|
280
|
+
importer: renderedContent.compiledView.filePath,
|
|
281
|
+
viewCacheKey
|
|
286
282
|
});
|
|
287
283
|
return renderedViewDef;
|
|
288
284
|
}
|
|
289
|
-
async render(viewId, viewParams, runtimeParams, runtimeEnvironment
|
|
285
|
+
async render(viewId, viewParams, runtimeParams, runtimeEnvironment) {
|
|
290
286
|
const globalContext = this.globalData;
|
|
291
287
|
const {id, rootComponent, contentTemplate} = viewId;
|
|
292
288
|
const compiledView = await this.getView({id, contentTemplate, rootComponent});
|
|
@@ -310,7 +306,8 @@ var LwrViewRegistry = class {
|
|
|
310
306
|
runtimeParams,
|
|
311
307
|
renderOptions,
|
|
312
308
|
contentIds,
|
|
313
|
-
importer
|
|
309
|
+
importer,
|
|
310
|
+
viewCacheKey
|
|
314
311
|
} = viewContext;
|
|
315
312
|
const {skipMetadataCollection, freezeAssets} = renderOptions;
|
|
316
313
|
const {lwrResourcesId} = contentIds;
|
|
@@ -321,19 +318,37 @@ var LwrViewRegistry = class {
|
|
|
321
318
|
metadata: renderedViewMetadata,
|
|
322
319
|
compiledView: {immutable = true}
|
|
323
320
|
} = renderedView;
|
|
324
|
-
const linkedMetadata =
|
|
321
|
+
const {linkedMetadata, stringBuilder} = (0, import_instrumentation.getTracer)().trace({
|
|
322
|
+
name: import_instrumentation.ViewSpan.ParseView,
|
|
323
|
+
attributes: {
|
|
324
|
+
view: view.id,
|
|
325
|
+
ssr: view.bootstrap?.ssr === true
|
|
326
|
+
}
|
|
327
|
+
}, () => {
|
|
328
|
+
const linkedMetadata2 = skipMetadataCollection ? renderedViewMetadata : (0, import_shared_utils.extractMetadataFromHtml)(renderedViewContent, renderedViewMetadata, this.globalConfig);
|
|
329
|
+
const stringBuilder2 = (0, import_shared_utils.createStringBuilder)(renderedViewContent);
|
|
330
|
+
return {linkedMetadata: linkedMetadata2, stringBuilder: stringBuilder2};
|
|
331
|
+
});
|
|
325
332
|
const mergedViewContext = {
|
|
326
333
|
...viewContext,
|
|
327
334
|
config: this.globalConfig,
|
|
328
335
|
runtimeEnvironment,
|
|
329
336
|
importer: importer || renderedView.compiledView.filePath
|
|
330
337
|
};
|
|
331
|
-
const stringBuilder = (0, import_shared_utils.createStringBuilder)(renderedViewContent);
|
|
332
338
|
let pageTtl = renderedView.cache.ttl;
|
|
339
|
+
let pageStatus = renderedView.status;
|
|
333
340
|
for (const viewTransformer of this.viewTransformers) {
|
|
334
|
-
const linkResults = await
|
|
341
|
+
const linkResults = await (0, import_instrumentation.getTracer)().trace({
|
|
342
|
+
name: import_instrumentation.ViewSpan.Transform,
|
|
343
|
+
attributes: {
|
|
344
|
+
name: viewTransformer.name
|
|
345
|
+
}
|
|
346
|
+
}, () => viewTransformer.link?.(stringBuilder, mergedViewContext, linkedMetadata));
|
|
335
347
|
const ttl = linkResults && linkResults.cache?.ttl;
|
|
336
348
|
pageTtl = (0, import_shared_utils.shortestTtl)(ttl || void 0, pageTtl);
|
|
349
|
+
if (!pageStatus && linkResults) {
|
|
350
|
+
pageStatus = linkResults.status;
|
|
351
|
+
}
|
|
337
352
|
}
|
|
338
353
|
const linkedAssetContent = stringBuilder.toString();
|
|
339
354
|
if (linkedAssetContent.includes(lwrResourcesId)) {
|
|
@@ -345,16 +360,31 @@ var LwrViewRegistry = class {
|
|
|
345
360
|
resourceRegistry,
|
|
346
361
|
runtimeEnvironment,
|
|
347
362
|
runtimeParams,
|
|
348
|
-
bundleConfig: this.globalConfig.bundleConfig
|
|
363
|
+
bundleConfig: this.globalConfig.bundleConfig,
|
|
364
|
+
unsafeEnableViewLinkCaching: this.globalConfig.unsafeEnableViewLinkCaching,
|
|
365
|
+
viewLinkCacheKey: viewCacheKey
|
|
349
366
|
});
|
|
367
|
+
if (viewRecord.resources?.length) {
|
|
368
|
+
linkedMetadata.assetReferences.push(...viewRecord.resources.reduce((res, asset) => {
|
|
369
|
+
if (!asset.src)
|
|
370
|
+
return res;
|
|
371
|
+
res.push({
|
|
372
|
+
url: asset.src,
|
|
373
|
+
relative: (0, import_shared_utils.isRelative)(asset.src)
|
|
374
|
+
});
|
|
375
|
+
return res;
|
|
376
|
+
}, []));
|
|
377
|
+
}
|
|
350
378
|
return {
|
|
351
379
|
renderedView: linkedView,
|
|
352
380
|
immutable,
|
|
353
381
|
viewRecord: {
|
|
354
382
|
assetReferences: (0, import_utils.reduceSourceAssetReferences)(linkedMetadata.assetReferences),
|
|
355
|
-
...viewRecord
|
|
383
|
+
...viewRecord,
|
|
384
|
+
serverBundles: linkedMetadata.serverBundles
|
|
356
385
|
},
|
|
357
|
-
cache: {ttl: pageTtl}
|
|
386
|
+
cache: {ttl: pageTtl},
|
|
387
|
+
status: pageStatus
|
|
358
388
|
};
|
|
359
389
|
}
|
|
360
390
|
return {
|
|
@@ -362,9 +392,11 @@ var LwrViewRegistry = class {
|
|
|
362
392
|
immutable,
|
|
363
393
|
viewRecord: {
|
|
364
394
|
assetReferences: (0, import_utils.reduceSourceAssetReferences)(linkedMetadata.assetReferences),
|
|
365
|
-
moduleResources: []
|
|
395
|
+
moduleResources: [],
|
|
396
|
+
serverBundles: linkedMetadata.serverBundles
|
|
366
397
|
},
|
|
367
|
-
cache: {ttl: pageTtl}
|
|
398
|
+
cache: {ttl: pageTtl},
|
|
399
|
+
status: pageStatus
|
|
368
400
|
};
|
|
369
401
|
}
|
|
370
402
|
};
|
|
@@ -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,17 @@ function includeIdFactory(bundleConfig) {
|
|
|
40
41
|
return true;
|
|
41
42
|
};
|
|
42
43
|
}
|
|
44
|
+
var moduleGraphsCache = new import_lru_cache.LRUCache({
|
|
45
|
+
max: 500,
|
|
46
|
+
dispose: (_value, key) => {
|
|
47
|
+
if ((0, import_shared_utils.isLambdaEnv)()) {
|
|
48
|
+
import_diagnostics.logger.warn(`Module graph evicted from cache ${key}`);
|
|
49
|
+
} else {
|
|
50
|
+
import_diagnostics.logger.verbose(`Module graph evicted from cache ${key}`);
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
});
|
|
54
|
+
var isRunningLocalDev = (0, import_shared_utils.isLocalDev)();
|
|
43
55
|
async function getHtmlResources(view, viewParams, resourceContext) {
|
|
44
56
|
const {
|
|
45
57
|
runtimeEnvironment,
|
|
@@ -52,9 +64,10 @@ async function getHtmlResources(view, viewParams, resourceContext) {
|
|
|
52
64
|
const {format, hmrEnabled, bundle, debug, minify} = runtimeEnvironment;
|
|
53
65
|
const {customElements, serverData, serverDebug} = viewMetadata;
|
|
54
66
|
const isAMD = format === "amd";
|
|
55
|
-
const {bundleConfig} = resourceContext;
|
|
67
|
+
const {bundleConfig, unsafeEnableViewLinkCaching} = resourceContext;
|
|
56
68
|
const {external = {}, exclude = []} = bundleConfig;
|
|
57
69
|
const groups = isAMD ? bundleConfig.groups || {} : {};
|
|
70
|
+
const enableModuleGraphsCache = unsafeEnableViewLinkCaching && !isRunningLocalDev && !process.env.NOCACHE;
|
|
58
71
|
const getPreloadUri = function(rawSpecifier, uriMap) {
|
|
59
72
|
const {specifier} = (0, import_shared_utils.explodeSpecifier)(rawSpecifier);
|
|
60
73
|
if (Object.keys(external).some((e) => specifier === e))
|
|
@@ -139,7 +152,14 @@ async function getHtmlResources(view, viewParams, resourceContext) {
|
|
|
139
152
|
(0, import_utils.addExternalScriptNonce)(errorShimDef, nonce);
|
|
140
153
|
requiredResources.push(errorShimDef);
|
|
141
154
|
}
|
|
142
|
-
|
|
155
|
+
let bootstrapModuleGraph;
|
|
156
|
+
const bootstrapModuleGraphCacheKey = (0, import_utils.getModuleGraphCacheKey)(bootstrapSpecifier, runtimeEnvironment, runtimeParams);
|
|
157
|
+
if (enableModuleGraphsCache && moduleGraphsCache.has(bootstrapModuleGraphCacheKey)) {
|
|
158
|
+
bootstrapModuleGraph = moduleGraphsCache.get(bootstrapModuleGraphCacheKey);
|
|
159
|
+
} else {
|
|
160
|
+
bootstrapModuleGraph = await (0, import_shared_utils.getModuleGraphs)(bootstrapSpecifier, {includeUris: true, includeLinkedDefinitions: true, depth}, moduleRegistry, defRegistry, runtimeEnvironment, runtimeParams, visitedCache);
|
|
161
|
+
enableModuleGraphsCache && moduleGraphsCache.set(bootstrapModuleGraphCacheKey, bootstrapModuleGraph);
|
|
162
|
+
}
|
|
143
163
|
bootstrapModuleRef = {
|
|
144
164
|
specifier: bootstrapModuleGraph.graphs[0].specifier,
|
|
145
165
|
flatGraph: bootstrapModuleGraph,
|
|
@@ -170,7 +190,7 @@ async function getHtmlResources(view, viewParams, resourceContext) {
|
|
|
170
190
|
for (const staticDep of bootstrapModuleGraph.graphs[0].static) {
|
|
171
191
|
const uri2 = bootstrapModuleGraph.uriMap[staticDep];
|
|
172
192
|
imports[staticDep] = uri2;
|
|
173
|
-
if (services
|
|
193
|
+
if (services?.length) {
|
|
174
194
|
requiredAmdModules.push(staticDep);
|
|
175
195
|
}
|
|
176
196
|
}
|
|
@@ -188,7 +208,20 @@ async function getHtmlResources(view, viewParams, resourceContext) {
|
|
|
188
208
|
}
|
|
189
209
|
}
|
|
190
210
|
await Promise.all(flattenedElements.map(async ({tagName: element, props}) => {
|
|
191
|
-
const
|
|
211
|
+
const hydrateDirective = (0, import_shared_utils.getHydrateDirective)(props);
|
|
212
|
+
const isSsrOnly = isSSR && !hydrateDirective;
|
|
213
|
+
const elementSpecifier = (0, import_shared_utils.kebabCaseToModuleSpecifier)(element);
|
|
214
|
+
const moduleGraphCacheKey = (0, import_utils.getModuleGraphCacheKey)(elementSpecifier, runtimeEnvironment, {
|
|
215
|
+
...runtimeParams,
|
|
216
|
+
ssr: isSsrOnly
|
|
217
|
+
});
|
|
218
|
+
let graph;
|
|
219
|
+
if (enableModuleGraphsCache && moduleGraphsCache.has(moduleGraphCacheKey)) {
|
|
220
|
+
graph = moduleGraphsCache.get(moduleGraphCacheKey);
|
|
221
|
+
} else {
|
|
222
|
+
graph = await (0, import_shared_utils.getModuleGraphs)(elementSpecifier, {includeUris: true, includeLinkedDefinitions: true, depth}, moduleRegistry, defRegistry, runtimeEnvironment, {...runtimeParams, ssr: isSsrOnly}, visitedCache);
|
|
223
|
+
enableModuleGraphsCache && moduleGraphsCache.set(moduleGraphCacheKey, graph);
|
|
224
|
+
}
|
|
192
225
|
customElementsRecords.push({elementName: element, flatGraph: graph});
|
|
193
226
|
if (!isSSR || (0, import_shared_utils.getHydrateDirective)(props)) {
|
|
194
227
|
const specifier = graph.graphs[0].specifier;
|
|
@@ -231,7 +264,8 @@ async function getHtmlResources(view, viewParams, resourceContext) {
|
|
|
231
264
|
url: viewParams?.page?.url,
|
|
232
265
|
configAsSrc: view.bootstrap?.configAsSrc || false,
|
|
233
266
|
mixedMode: view.bootstrap?.mixedMode || false,
|
|
234
|
-
nonce: viewParams?.page?.nonce
|
|
267
|
+
nonce: viewParams?.page?.nonce,
|
|
268
|
+
ssr: view.bootstrap?.ssr || false
|
|
235
269
|
}, {
|
|
236
270
|
appId: appIdentity.appName,
|
|
237
271
|
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,23 @@ __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({
|
|
38
|
+
max: 500,
|
|
39
|
+
dispose: (_value, key) => {
|
|
40
|
+
if ((0, import_shared_utils.isLambdaEnv)()) {
|
|
41
|
+
import_diagnostics.logger.warn(`Module graph evicted from cache ${key}`);
|
|
42
|
+
} else {
|
|
43
|
+
import_diagnostics.logger.verbose(`Module graph evicted from cache ${key}`);
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
});
|
|
47
|
+
var isRunningLocalDev = (0, import_shared_utils.isLocalDev)();
|
|
35
48
|
async function getHtmlResources(view, viewParams, resourceContext) {
|
|
36
49
|
const {
|
|
37
50
|
runtimeEnvironment,
|
|
@@ -46,9 +59,10 @@ async function getHtmlResources(view, viewParams, resourceContext) {
|
|
|
46
59
|
const defRegistry = bundle ? moduleBundler : moduleRegistry;
|
|
47
60
|
const isAMD = format === "amd";
|
|
48
61
|
const depth = isAMD ? {static: import_shared_utils.GraphDepth.ALL, dynamic: 1} : {static: import_shared_utils.GraphDepth.NONE, dynamic: 1};
|
|
49
|
-
const {bundleConfig} = resourceContext;
|
|
62
|
+
const {bundleConfig, unsafeEnableViewLinkCaching} = resourceContext;
|
|
50
63
|
const {external = {}, exclude = []} = bundleConfig;
|
|
51
64
|
const groups = isAMD ? bundleConfig.groups || {} : {};
|
|
65
|
+
const enableModuleGraphsCache = unsafeEnableViewLinkCaching && !isRunningLocalDev && !process.env.NOCACHE;
|
|
52
66
|
const getPreloadUri = function(rawSpecifier, uriMap) {
|
|
53
67
|
const {specifier} = (0, import_shared_utils.explodeSpecifier)(rawSpecifier);
|
|
54
68
|
if (Object.keys(external).some((e) => specifier === e))
|
|
@@ -119,7 +133,14 @@ async function getHtmlResources(view, viewParams, resourceContext) {
|
|
|
119
133
|
(0, import_utils.addExternalScriptNonce)(errorShimDef, nonce);
|
|
120
134
|
requiredResources.push(errorShimDef);
|
|
121
135
|
}
|
|
122
|
-
|
|
136
|
+
let bootstrapModuleGraph;
|
|
137
|
+
const bootstrapModuleGraphCacheKey = (0, import_utils3.getModuleGraphCacheKey)(bootstrapSpecifier, runtimeEnvironment, runtimeParams);
|
|
138
|
+
if (enableModuleGraphsCache && moduleGraphsCache.has(bootstrapModuleGraphCacheKey)) {
|
|
139
|
+
bootstrapModuleGraph = moduleGraphsCache.get(bootstrapModuleGraphCacheKey);
|
|
140
|
+
} else {
|
|
141
|
+
bootstrapModuleGraph = await (0, import_shared_utils.getModuleGraphs)(bootstrapSpecifier, {includeUris: true, includeLinkedDefinitions: true, depth}, moduleRegistry, defRegistry, runtimeEnvironment, runtimeParams, visitedCache);
|
|
142
|
+
enableModuleGraphsCache && moduleGraphsCache.set(bootstrapModuleGraphCacheKey, bootstrapModuleGraph);
|
|
143
|
+
}
|
|
123
144
|
bootstrapModuleRef = {
|
|
124
145
|
specifier: bootstrapModuleGraph.graphs[0].specifier,
|
|
125
146
|
flatGraph: bootstrapModuleGraph,
|
|
@@ -150,7 +171,7 @@ async function getHtmlResources(view, viewParams, resourceContext) {
|
|
|
150
171
|
for (const staticDep of bootstrapModuleGraph.graphs[0].static) {
|
|
151
172
|
const uri2 = bootstrapModuleGraph.uriMap[staticDep];
|
|
152
173
|
imports[staticDep] = uri2;
|
|
153
|
-
if (services
|
|
174
|
+
if (services?.length) {
|
|
154
175
|
requiredAmdModules.push(staticDep);
|
|
155
176
|
}
|
|
156
177
|
}
|
|
@@ -169,7 +190,20 @@ async function getHtmlResources(view, viewParams, resourceContext) {
|
|
|
169
190
|
importMetadata = await (0, import_shared_utils.toImportMetadata)(bootstrapModuleGraph, {imports: {}, index: {}}, moduleRegistry, runtimeEnvironment, runtimeParams);
|
|
170
191
|
}
|
|
171
192
|
for (const {tagName: element, props} of flattenedElements) {
|
|
172
|
-
const
|
|
193
|
+
const hydrateDirective = (0, import_shared_utils.getHydrateDirective)(props);
|
|
194
|
+
const isSsrOnly = isSSR && !hydrateDirective;
|
|
195
|
+
const elementSpecifier = (0, import_shared_utils.kebabCaseToModuleSpecifier)(element);
|
|
196
|
+
const moduleGraphCacheKey = (0, import_utils3.getModuleGraphCacheKey)(elementSpecifier, runtimeEnvironment, {
|
|
197
|
+
...runtimeParams,
|
|
198
|
+
ssr: isSsrOnly
|
|
199
|
+
});
|
|
200
|
+
let graph;
|
|
201
|
+
if (enableModuleGraphsCache && moduleGraphsCache.has(moduleGraphCacheKey)) {
|
|
202
|
+
graph = moduleGraphsCache.get(moduleGraphCacheKey);
|
|
203
|
+
} else {
|
|
204
|
+
graph = await (0, import_shared_utils.getModuleGraphs)(elementSpecifier, {includeUris: true, includeLinkedDefinitions: true, depth}, moduleRegistry, defRegistry, runtimeEnvironment, {...runtimeParams, ssr: isSsrOnly}, visitedCache);
|
|
205
|
+
enableModuleGraphsCache && moduleGraphsCache.set(moduleGraphCacheKey, graph);
|
|
206
|
+
}
|
|
173
207
|
customElementsRecords.push({elementName: element, flatGraph: graph});
|
|
174
208
|
if (!isSSR || (0, import_shared_utils.getHydrateDirective)(props)) {
|
|
175
209
|
const specifier = graph.graphs[0].specifier;
|
|
@@ -206,7 +240,8 @@ async function getHtmlResources(view, viewParams, resourceContext) {
|
|
|
206
240
|
url: viewParams?.page?.url,
|
|
207
241
|
configAsSrc: view.bootstrap?.configAsSrc || false,
|
|
208
242
|
mixedMode: view.bootstrap?.mixedMode || false,
|
|
209
|
-
nonce: viewParams?.page?.nonce
|
|
243
|
+
nonce: viewParams?.page?.nonce,
|
|
244
|
+
ssr: view.bootstrap?.ssr || false
|
|
210
245
|
}, {
|
|
211
246
|
appId: appIdentity.appName,
|
|
212
247
|
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,20 +112,23 @@ function normalizeRenderedResult({
|
|
|
108
112
|
renderedView,
|
|
109
113
|
metadata,
|
|
110
114
|
options,
|
|
111
|
-
cache
|
|
115
|
+
cache,
|
|
116
|
+
status
|
|
112
117
|
}) {
|
|
113
118
|
return {
|
|
114
119
|
renderedView,
|
|
115
120
|
metadata: {
|
|
116
121
|
customElements: metadata ? metadata.customElements : [],
|
|
117
122
|
assetReferences: metadata ? metadata.assetReferences : [],
|
|
123
|
+
serverBundles: metadata ? metadata.serverBundles : new Set(),
|
|
118
124
|
serverData: metadata ? metadata.serverData : {},
|
|
119
125
|
serverDebug: metadata ? metadata.serverDebug : {}
|
|
120
126
|
},
|
|
121
127
|
options: {
|
|
122
128
|
skipMetadataCollection: options ? options.skipMetadataCollection : false
|
|
123
129
|
},
|
|
124
|
-
cache: cache || {}
|
|
130
|
+
cache: cache || {},
|
|
131
|
+
status
|
|
125
132
|
};
|
|
126
133
|
}
|
|
127
134
|
function reduceSourceAssetReferences(assets) {
|
|
@@ -149,11 +156,16 @@ function generatePageContext({requestPath: url}, {id, contentTemplate, propertie
|
|
|
149
156
|
const title = properties?.title || getTitleFromFilePath(contentTemplate);
|
|
150
157
|
const locale = runtimeParams.locale;
|
|
151
158
|
const basePath = runtimeParams.basePath;
|
|
152
|
-
|
|
159
|
+
const assetBasePath = runtimeParams.assetBasePath;
|
|
160
|
+
const uiBasePath = runtimeParams.uiBasePath;
|
|
161
|
+
return {assetBasePath, basePath, id, locale, title, url, uiBasePath};
|
|
153
162
|
}
|
|
154
163
|
function isViewResponse(response) {
|
|
155
164
|
return response.body !== void 0;
|
|
156
165
|
}
|
|
166
|
+
function isViewDefinitionResponse(response) {
|
|
167
|
+
return response.view !== void 0;
|
|
168
|
+
}
|
|
157
169
|
async function toJsonFormat(viewRequest, viewDefinition, route, runtimeEnvironment, runtimeParams, moduleRegistry) {
|
|
158
170
|
const {viewRecord} = viewDefinition;
|
|
159
171
|
const {bootstrap, id: appName} = route;
|
|
@@ -291,3 +303,61 @@ function addExternalScriptNonce(def, nonce) {
|
|
|
291
303
|
def.nonce = nonce;
|
|
292
304
|
}
|
|
293
305
|
}
|
|
306
|
+
function generateLinkHeaders(assets, patterns) {
|
|
307
|
+
const assetConfig = {};
|
|
308
|
+
for (const assetRef of assets) {
|
|
309
|
+
const path = assetRef.override?.uri || assetRef.url;
|
|
310
|
+
let matched = null;
|
|
311
|
+
for (const pattern of patterns) {
|
|
312
|
+
const {match} = pattern;
|
|
313
|
+
const matchPatterns = Array.isArray(match) ? match : [match];
|
|
314
|
+
for (const filePattern of matchPatterns) {
|
|
315
|
+
const regex = new RegExp(filePattern);
|
|
316
|
+
if (regex.test(path)) {
|
|
317
|
+
matched = pattern.attributes;
|
|
318
|
+
break;
|
|
319
|
+
}
|
|
320
|
+
}
|
|
321
|
+
if (matched)
|
|
322
|
+
break;
|
|
323
|
+
}
|
|
324
|
+
if (matched) {
|
|
325
|
+
assetConfig[path] = matched;
|
|
326
|
+
}
|
|
327
|
+
}
|
|
328
|
+
return Object.keys(assetConfig).reduce((linkHeader, path) => {
|
|
329
|
+
linkHeader = `${linkHeader ? linkHeader + ", " : ""}<${path}>`;
|
|
330
|
+
const properties = assetConfig[path];
|
|
331
|
+
for (const prop in properties) {
|
|
332
|
+
linkHeader += properties[prop] !== "" ? `; ${prop}=${properties[prop]}` : `; ${prop}`;
|
|
333
|
+
}
|
|
334
|
+
return linkHeader;
|
|
335
|
+
}, "");
|
|
336
|
+
}
|
|
337
|
+
function getViewDefCacheKey(view, runtimeEnvironment, freezeAssets, runtimeParams) {
|
|
338
|
+
const {id, bootstrap, rootComponent, contentTemplate, layoutTemplate} = view;
|
|
339
|
+
return (0, import_shared_utils.getCacheKeyFromJson)({
|
|
340
|
+
id,
|
|
341
|
+
bootstrap,
|
|
342
|
+
rootComponent,
|
|
343
|
+
contentTemplate,
|
|
344
|
+
layoutTemplate,
|
|
345
|
+
freezeAssets,
|
|
346
|
+
locale: runtimeParams?.locale,
|
|
347
|
+
basePath: runtimeParams?.basePath,
|
|
348
|
+
debug: runtimeEnvironment.debug,
|
|
349
|
+
nonceEnabled: (0, import_shared_utils.getFeatureFlags)().ENABLE_NONCE
|
|
350
|
+
});
|
|
351
|
+
}
|
|
352
|
+
function getModuleGraphCacheKey(specifier, runtimeEnvironment, runtimeParams) {
|
|
353
|
+
const updatedParams = {
|
|
354
|
+
...runtimeParams
|
|
355
|
+
};
|
|
356
|
+
delete updatedParams.url;
|
|
357
|
+
delete updatedParams.query;
|
|
358
|
+
return (0, import_shared_utils.getCacheKeyFromJson)({
|
|
359
|
+
specifier,
|
|
360
|
+
updatedParams,
|
|
361
|
+
runtimeEnvironment
|
|
362
|
+
});
|
|
363
|
+
}
|
|
@@ -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) {
|