@lwrjs/view-registry 0.10.0-alpha.15 → 0.10.0-alpha.16

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.
@@ -30,12 +30,12 @@ __export(exports, {
30
30
  var import_shared_utils = __toModule(require("@lwrjs/shared-utils"));
31
31
  var import_utils = __toModule(require("./utils.cjs"));
32
32
  var import_link_lwr_resources = __toModule(require("./linkers/link-lwr-resources.cjs"));
33
+ var import_lru_cache = __toModule(require("lru-cache"));
33
34
  var import_view_handler = __toModule(require("./view-handler.cjs"));
34
35
  var LwrViewRegistry = class {
35
36
  constructor(context, globalConfig) {
36
37
  this.viewProviders = [];
37
38
  this.compiledViews = new Map();
38
- this.viewDefinitions = new Map();
39
39
  this.immutableAssets = new Map();
40
40
  this.pendingViewDefinitions = new import_shared_utils.InflightTasks();
41
41
  this.name = "lwr-view-registry";
@@ -49,14 +49,17 @@ var LwrViewRegistry = class {
49
49
  this.globalData = context.globalData;
50
50
  this.appEmitter = context.appEmitter;
51
51
  const observer = context.appObserver;
52
+ this.viewDefinitions = new import_lru_cache.LRUCache({max: parseInt(process.env.VIEW_CACHE_SIZE || "500", 10)});
52
53
  observer.onViewSourceChange(({payload}) => this.onViewSourceChange(payload));
53
54
  observer.onModuleDefinitionChange(({payload}) => this.onModuleDefinitionChange(payload));
54
55
  observer.onAssetSourceChange(({payload}) => this.onAssetSourceChange(payload));
55
56
  }
56
57
  async onModuleDefinitionChange(moduleDefinition) {
57
58
  const versionedSpecifier = (0, import_shared_utils.getSpecifier)(moduleDefinition);
58
- for (const [id, {viewDefinition}] of this.viewDefinitions.entries()) {
59
- const {viewRecord} = viewDefinition;
59
+ for (const [id, viewDefEntry] of this.viewDefinitions.entries()) {
60
+ const {
61
+ viewDefinition: {viewRecord}
62
+ } = viewDefEntry;
60
63
  const uriMap = viewRecord.bootstrapModule?.flatGraph.uriMap;
61
64
  if (uriMap) {
62
65
  Object.keys(uriMap);
@@ -74,12 +77,12 @@ var LwrViewRegistry = class {
74
77
  const {contentTemplate, rootComponent} = compiledView.viewId;
75
78
  const compiledViewCacheKey = (0, import_shared_utils.getCacheKeyFromJson)({contentTemplate, rootComponent});
76
79
  this.compiledViews.set(compiledViewCacheKey, compiledView);
77
- for (const [id, {view}] of this.viewDefinitions.entries()) {
80
+ for (const [id, viewDefEntry] of this.viewDefinitions.entries()) {
78
81
  const {
79
82
  contentTemplate: eContentTempl,
80
83
  layoutTemplate: eLayoutTemplate,
81
84
  rootComponent: eRootComponent
82
- } = view;
85
+ } = viewDefEntry.view;
83
86
  if (eContentTempl === contentTemplate || eLayoutTemplate === contentTemplate || eRootComponent === rootComponent) {
84
87
  this.viewDefinitions.delete(id);
85
88
  }
@@ -87,8 +90,10 @@ var LwrViewRegistry = class {
87
90
  }
88
91
  onAssetSourceChange(asset) {
89
92
  const assetId = asset.entry;
90
- for (const [id, {viewDefinition}] of this.viewDefinitions.entries()) {
91
- const {viewRecord} = viewDefinition;
93
+ for (const [id, viewDefEntry] of this.viewDefinitions.entries()) {
94
+ const {
95
+ viewDefinition: {viewRecord}
96
+ } = viewDefEntry;
92
97
  const someAssets = viewRecord.assetReferences?.some((ref) => {
93
98
  return ref.override?.entry === assetId;
94
99
  });
@@ -174,11 +179,13 @@ var LwrViewRegistry = class {
174
179
  const pendingViewDefCacheKey = viewDefCacheKey + viewParamKey;
175
180
  const viewDefinition = await this.pendingViewDefinitions.execute(pendingViewDefCacheKey, () => this.renderView(view, viewParams, runtimeEnvironment, runtimeParams, renderOptions));
176
181
  if (cacheDisabled === false) {
182
+ const route = this.globalConfig.routes.find((r) => r.id === view.id);
183
+ const ttl = (0, import_shared_utils.shortestTtl)(viewDefinition.cache?.ttl, route?.cache?.ttl);
177
184
  this.viewDefinitions.set(viewDefCacheKey, {
178
185
  view,
179
186
  viewDefinition,
180
187
  paramKey: viewParamKey
181
- });
188
+ }, {ttl: ttl ? ttl * 1e3 : void 0});
182
189
  }
183
190
  return viewDefinition;
184
191
  }
@@ -127,20 +127,20 @@ var LwrViewHandler = class {
127
127
  if (!route.routeHandler) {
128
128
  throw new Error("Route handler is required for a CustomView");
129
129
  }
130
- const routeHandler = this.routeHandlers[route.routeHandler];
131
- if (!routeHandler) {
130
+ const [routeHandlerFn, routeHandlerOptions] = this.routeHandlers[route.routeHandler[0]];
131
+ if (!routeHandlerFn) {
132
132
  throw new Error(`Route handler does not exist for id: ${route.routeHandler}`);
133
133
  }
134
134
  const {rootDir, assets, contentDir, layoutsDir} = this.globalConfig;
135
135
  const paths = {rootDir, assets, contentDir, layoutsDir};
136
136
  const locale = runtimeParams.locale;
137
- const viewApi = this.getBoundApi(route, runtimeEnvironment, runtimeParams);
138
- const response = await routeHandler({...viewRequest, locale}, {route, viewApi, ...paths});
137
+ const viewApi = this.getBoundApi(viewRequest, route, runtimeEnvironment, runtimeParams);
138
+ const response = await routeHandlerFn({...viewRequest, locale}, {route, viewApi, ...paths}, routeHandlerOptions);
139
139
  return response;
140
140
  }
141
- getBoundApi(route, runtimeEnvironment, runtimeParams) {
141
+ getBoundApi(viewRequest, route, runtimeEnvironment, runtimeParams) {
142
142
  return {
143
- getViewResponse: this.getViewResponse.bind(this, route, runtimeEnvironment, runtimeParams),
143
+ getViewResponse: this.getViewResponse.bind(this, viewRequest, route, runtimeEnvironment, runtimeParams),
144
144
  hasViewResponse: this.hasViewResponse.bind(this, route, runtimeEnvironment, runtimeParams)
145
145
  };
146
146
  }
@@ -149,10 +149,20 @@ var LwrViewHandler = class {
149
149
  const managedView = {...view, id, bootstrap};
150
150
  return this.viewRegistry.hasViewDefinition(managedView, viewParams, runtimeEnvironment, runtimeParams, renderOptions);
151
151
  }
152
- async getViewResponse(route, runtimeEnvironment, runtimeParams = {}, view, viewParams, renderOptions) {
152
+ async getViewResponse(viewRequest, route, runtimeEnvironment, runtimeParams = {}, view, viewParams, renderOptions) {
153
153
  const {id, bootstrap} = route;
154
154
  const managedView = {...view, id, bootstrap};
155
- const viewDefinition = await this.viewRegistry.getViewDefinition(managedView, viewParams, runtimeEnvironment, runtimeParams, renderOptions);
155
+ const viewResponse = {
156
+ view: managedView,
157
+ viewParams,
158
+ renderOptions
159
+ };
160
+ const {
161
+ view: normalizedView,
162
+ viewParams: normalizedViewParams,
163
+ renderOptions: normalizedRenderOptions
164
+ } = normalizeViewProperties(viewRequest, viewResponse, route, this.globalConfig);
165
+ const viewDefinition = await this.viewRegistry.getViewDefinition(normalizedView, normalizedViewParams, runtimeEnvironment, runtimeParams, normalizedRenderOptions);
156
166
  return {
157
167
  body: viewDefinition.renderedView,
158
168
  metadata: {
@@ -1,5 +1,5 @@
1
- import { AssetRegistry, CompiledView, Json, LinkedModuleDefinition, LinkedViewDefinition, LwrAppEmitter, LwrAppObserver, ModuleBundler, ModuleRegistry, NormalizedLwrGlobalConfig, PublicViewRegistry, RenderOptions, ResourceRegistry, RuntimeEnvironment, RuntimeParams, View, ViewIdentity, ViewParams, ViewProvider, ViewRegistry, ViewTransformPlugin } from '@lwrjs/types';
2
- import { AssetSource } from '@lwrjs/types';
1
+ import type { AssetRegistry, AssetSource, CompiledView, Json, LinkedModuleDefinition, LinkedViewDefinition, LwrAppEmitter, LwrAppObserver, ModuleBundler, ModuleRegistry, NormalizedLwrGlobalConfig, PublicViewRegistry, RenderOptions, ResourceRegistry, RuntimeEnvironment, RuntimeParams, View, ViewIdentity, ViewParams, ViewProvider, ViewRegistry, ViewTransformPlugin } from '@lwrjs/types';
2
+ import { LRUCache } from 'lru-cache';
3
3
  export { LwrViewHandler } from './view-handler.js';
4
4
  interface ViewProviderContext {
5
5
  viewTransformers?: ViewTransformPlugin[];
@@ -21,7 +21,7 @@ export declare class LwrViewRegistry implements ViewRegistry {
21
21
  name: string;
22
22
  viewProviders: ViewProvider[];
23
23
  compiledViews: Map<string, CompiledView>;
24
- viewDefinitions: Map<string, ViewDefinitionCacheEntry>;
24
+ viewDefinitions: LRUCache<string, ViewDefinitionCacheEntry>;
25
25
  resourceRegistry: ResourceRegistry;
26
26
  moduleRegistry: ModuleRegistry;
27
27
  moduleBundler: ModuleBundler;
package/build/es/index.js CHANGED
@@ -1,6 +1,7 @@
1
- import { extractMetadataFromHtml, getCacheKeyFromJson, getSpecifier, normalizeResourcePath, createStringBuilder, shortestTtl, InflightTasks, } from '@lwrjs/shared-utils';
1
+ import { InflightTasks, createStringBuilder, extractMetadataFromHtml, getCacheKeyFromJson, getSpecifier, normalizeResourcePath, shortestTtl, } from '@lwrjs/shared-utils';
2
2
  import { normalizeRenderOptions, normalizeRenderedResult, reduceSourceAssetReferences } from './utils.js';
3
3
  import { linkLwrResources } from './linkers/link-lwr-resources.js';
4
+ import { LRUCache } from 'lru-cache';
4
5
  export { LwrViewHandler } from './view-handler.js';
5
6
  export class LwrViewRegistry {
6
7
  constructor(context, globalConfig) {
@@ -8,9 +9,6 @@ export class LwrViewRegistry {
8
9
  // Cache of compiled views retrieved from the viewProviders
9
10
  // Cache key: ViewIdentity
10
11
  this.compiledViews = new Map();
11
- // Cache of linked view definitions, keyed by the View
12
- // Cache key: View
13
- this.viewDefinitions = new Map();
14
12
  this.immutableAssets = new Map();
15
13
  // Cache of unresolved view definitions
16
14
  // Cache key: View + View Params
@@ -29,6 +27,7 @@ export class LwrViewRegistry {
29
27
  this.globalData = context.globalData;
30
28
  this.appEmitter = context.appEmitter;
31
29
  const observer = context.appObserver;
30
+ this.viewDefinitions = new LRUCache({ max: parseInt(process.env.VIEW_CACHE_SIZE || '500', 10) });
32
31
  // Observers for cached entries external dependencies -- view templates, modules, and assets
33
32
  observer.onViewSourceChange(({ payload }) => this.onViewSourceChange(payload));
34
33
  observer.onModuleDefinitionChange(({ payload }) => this.onModuleDefinitionChange(payload));
@@ -37,8 +36,8 @@ export class LwrViewRegistry {
37
36
  async onModuleDefinitionChange(moduleDefinition) {
38
37
  const versionedSpecifier = getSpecifier(moduleDefinition);
39
38
  // invalidate viewDefinition cache entries with references to the LinkedModuleDefinition
40
- for (const [id, { viewDefinition }] of this.viewDefinitions.entries()) {
41
- const { viewRecord } = viewDefinition;
39
+ for (const [id, viewDefEntry] of this.viewDefinitions.entries()) {
40
+ const { viewDefinition: { viewRecord }, } = viewDefEntry;
42
41
  const uriMap = viewRecord.bootstrapModule?.flatGraph.uriMap;
43
42
  if (uriMap) {
44
43
  Object.keys(uriMap);
@@ -61,8 +60,8 @@ export class LwrViewRegistry {
61
60
  const compiledViewCacheKey = getCacheKeyFromJson({ contentTemplate, rootComponent });
62
61
  this.compiledViews.set(compiledViewCacheKey, compiledView);
63
62
  // invalidate viewDefinitions cache
64
- for (const [id, { view }] of this.viewDefinitions.entries()) {
65
- const { contentTemplate: eContentTempl, layoutTemplate: eLayoutTemplate, rootComponent: eRootComponent, } = view;
63
+ for (const [id, viewDefEntry] of this.viewDefinitions.entries()) {
64
+ const { contentTemplate: eContentTempl, layoutTemplate: eLayoutTemplate, rootComponent: eRootComponent, } = viewDefEntry.view;
66
65
  if (eContentTempl === contentTemplate ||
67
66
  eLayoutTemplate === contentTemplate ||
68
67
  eRootComponent === rootComponent) {
@@ -74,8 +73,8 @@ export class LwrViewRegistry {
74
73
  onAssetSourceChange(asset) {
75
74
  // invalidate viewDefinition cache entries with references to the AssetSource entry.
76
75
  const assetId = asset.entry;
77
- for (const [id, { viewDefinition }] of this.viewDefinitions.entries()) {
78
- const { viewRecord } = viewDefinition;
76
+ for (const [id, viewDefEntry] of this.viewDefinitions.entries()) {
77
+ const { viewDefinition: { viewRecord }, } = viewDefEntry;
79
78
  const someAssets = viewRecord.assetReferences?.some((ref) => {
80
79
  return ref.override?.entry === assetId;
81
80
  });
@@ -180,11 +179,15 @@ export class LwrViewRegistry {
180
179
  const pendingViewDefCacheKey = viewDefCacheKey + viewParamKey;
181
180
  const viewDefinition = await this.pendingViewDefinitions.execute(pendingViewDefCacheKey, () => this.renderView(view, viewParams, runtimeEnvironment, runtimeParams, renderOptions));
182
181
  if (cacheDisabled === false) {
182
+ const route = this.globalConfig.routes.find((r) => r.id === view.id);
183
+ const ttl = shortestTtl(viewDefinition.cache?.ttl, route?.cache?.ttl);
183
184
  this.viewDefinitions.set(viewDefCacheKey, {
184
185
  view,
185
186
  viewDefinition,
186
187
  paramKey: viewParamKey,
187
- });
188
+ },
189
+ // s -> ms
190
+ { ttl: ttl ? ttl * 1000 : undefined });
188
191
  }
189
192
  return viewDefinition;
190
193
  }
@@ -143,26 +143,26 @@ export class LwrViewHandler {
143
143
  if (!route.routeHandler) {
144
144
  throw new Error('Route handler is required for a CustomView');
145
145
  }
146
- const routeHandler = this.routeHandlers[route.routeHandler];
147
- if (!routeHandler) {
146
+ const [routeHandlerFn, routeHandlerOptions] = this.routeHandlers[route.routeHandler[0]];
147
+ if (!routeHandlerFn) {
148
148
  throw new Error(`Route handler does not exist for id: ${route.routeHandler}`);
149
149
  }
150
150
  const { rootDir, assets, contentDir, layoutsDir } = this.globalConfig;
151
151
  const paths = { rootDir, assets, contentDir, layoutsDir };
152
152
  const locale = runtimeParams.locale;
153
- const viewApi = this.getBoundApi(route, runtimeEnvironment, runtimeParams);
154
- const response = await routeHandler({ ...viewRequest, locale }, { route: route, viewApi, ...paths });
153
+ const viewApi = this.getBoundApi(viewRequest, route, runtimeEnvironment, runtimeParams);
154
+ const response = await routeHandlerFn({ ...viewRequest, locale }, { route: route, viewApi, ...paths }, routeHandlerOptions);
155
155
  return response;
156
156
  }
157
157
  /*
158
158
  The Custom Route Handler accessible APIS are bound to runtime request when provided to a
159
159
  Route Handler.
160
160
  */
161
- getBoundApi(route, runtimeEnvironment, runtimeParams) {
161
+ getBoundApi(viewRequest, route, runtimeEnvironment, runtimeParams) {
162
162
  return {
163
163
  // Create a version of renderView() to pass to the route handler, it will:
164
164
  // - handle and protect the runtime environment
165
- getViewResponse: this.getViewResponse.bind(this, route, runtimeEnvironment, runtimeParams),
165
+ getViewResponse: this.getViewResponse.bind(this, viewRequest, route, runtimeEnvironment, runtimeParams),
166
166
  hasViewResponse: this.hasViewResponse.bind(this, route, runtimeEnvironment, runtimeParams),
167
167
  };
168
168
  }
@@ -173,12 +173,18 @@ export class LwrViewHandler {
173
173
  const managedView = { ...view, id, bootstrap };
174
174
  return this.viewRegistry.hasViewDefinition(managedView, viewParams, runtimeEnvironment, runtimeParams, renderOptions);
175
175
  }
176
- async getViewResponse(route, runtimeEnvironment, runtimeParams = {},
176
+ async getViewResponse(viewRequest, route, runtimeEnvironment, runtimeParams = {},
177
177
  // custom route handler managed properties
178
178
  view, viewParams, renderOptions) {
179
179
  const { id, bootstrap } = route;
180
180
  const managedView = { ...view, id, bootstrap };
181
- const viewDefinition = await this.viewRegistry.getViewDefinition(managedView, viewParams, runtimeEnvironment, runtimeParams, renderOptions);
181
+ const viewResponse = {
182
+ view: managedView,
183
+ viewParams,
184
+ renderOptions,
185
+ };
186
+ const { view: normalizedView, viewParams: normalizedViewParams, renderOptions: normalizedRenderOptions, } = normalizeViewProperties(viewRequest, viewResponse, route, this.globalConfig);
187
+ const viewDefinition = await this.viewRegistry.getViewDefinition(normalizedView, normalizedViewParams, runtimeEnvironment, runtimeParams, normalizedRenderOptions);
182
188
  return {
183
189
  body: viewDefinition.renderedView,
184
190
  metadata: {
package/package.json CHANGED
@@ -4,7 +4,7 @@
4
4
  "publishConfig": {
5
5
  "access": "public"
6
6
  },
7
- "version": "0.10.0-alpha.15",
7
+ "version": "0.10.0-alpha.16",
8
8
  "homepage": "https://developer.salesforce.com/docs/platform/lwr/overview",
9
9
  "repository": {
10
10
  "type": "git",
@@ -30,15 +30,16 @@
30
30
  "build/**/*.d.ts"
31
31
  ],
32
32
  "dependencies": {
33
- "@lwrjs/app-service": "0.10.0-alpha.15",
34
- "@lwrjs/diagnostics": "0.10.0-alpha.15",
35
- "@lwrjs/shared-utils": "0.10.0-alpha.15"
33
+ "@lwrjs/app-service": "0.10.0-alpha.16",
34
+ "@lwrjs/diagnostics": "0.10.0-alpha.16",
35
+ "@lwrjs/shared-utils": "0.10.0-alpha.16",
36
+ "lru-cache": "9.1.2"
36
37
  },
37
38
  "devDependencies": {
38
- "@lwrjs/types": "0.10.0-alpha.15"
39
+ "@lwrjs/types": "0.10.0-alpha.16"
39
40
  },
40
41
  "engines": {
41
42
  "node": ">=16.0.0 <20"
42
43
  },
43
- "gitHead": "70557f63a46167c40cf1415f12af69f78ae402d6"
44
+ "gitHead": "c5a13d471330c0f738d0c783fd1b69f456c544bd"
44
45
  }