@lwrjs/view-registry 0.12.0-alpha.12 → 0.12.0-alpha.13

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.
@@ -167,44 +167,53 @@ var LwrViewRegistry = class {
167
167
  return false;
168
168
  }
169
169
  async getViewDefinition(view, viewParams, runtimeEnvironment, runtimeParams, renderOptions) {
170
- const {skipCaching, freezeAssets, viewParamCacheKey} = (0, import_utils.normalizeRenderOptions)(this.runtimeEnvironment, renderOptions);
171
- const viewDefCacheKey = (0, import_shared_utils.getCacheKeyFromJson)({
172
- ...view,
173
- freezeAssets,
174
- locale: runtimeParams?.locale,
175
- basePath: runtimeParams?.basePath,
176
- debug: runtimeEnvironment.debug
177
- });
178
- import_diagnostics.logger.debug(`[view-registry][getViewDefinition] viewDefCacheKey=${viewDefCacheKey}`);
179
- const viewParamKey = viewParamCacheKey ? (0, import_shared_utils.getCacheKeyFromJson)(viewParamCacheKey) : (0, import_shared_utils.getCacheKeyFromJson)(viewParams);
180
- import_diagnostics.logger.debug(`[view-registry][getViewDefinition] viewParamKey=${viewParamKey}`);
181
- const cacheDisabled = process.env.NOCACHE === "true" || skipCaching;
182
- if (cacheDisabled === false && this.viewDefinitions.has(viewDefCacheKey)) {
183
- const viewDefinition2 = this.viewDefinitions.get(viewDefCacheKey);
184
- if (viewDefinition2 && viewDefinition2.paramKey === viewParamKey && viewDefinition2.viewDefinition.immutable) {
185
- return viewDefinition2.viewDefinition;
170
+ try {
171
+ const {skipCaching, freezeAssets, viewParamCacheKey} = (0, import_utils.normalizeRenderOptions)(this.runtimeEnvironment, renderOptions);
172
+ const viewDefCacheKey = (0, import_shared_utils.getCacheKeyFromJson)({
173
+ ...view,
174
+ freezeAssets,
175
+ locale: runtimeParams?.locale,
176
+ basePath: runtimeParams?.basePath,
177
+ debug: runtimeEnvironment.debug
178
+ });
179
+ import_diagnostics.logger.debug(`[view-registry][getViewDefinition] viewDefCacheKey=${viewDefCacheKey}`);
180
+ const viewParamKey = viewParamCacheKey ? (0, import_shared_utils.getCacheKeyFromJson)(viewParamCacheKey) : (0, import_shared_utils.getCacheKeyFromJson)(viewParams);
181
+ import_diagnostics.logger.debug(`[view-registry][getViewDefinition] viewParamKey=${viewParamKey}`);
182
+ const cacheDisabled = process.env.NOCACHE === "true" || skipCaching;
183
+ if (cacheDisabled === false && this.viewDefinitions.has(viewDefCacheKey)) {
184
+ const viewDefinition2 = this.viewDefinitions.get(viewDefCacheKey);
185
+ if (viewDefinition2 && viewDefinition2.paramKey === viewParamKey && viewDefinition2.viewDefinition.immutable) {
186
+ return viewDefinition2.viewDefinition;
187
+ }
186
188
  }
187
- }
188
- const pendingViewDefCacheKey = viewDefCacheKey + viewParamKey;
189
- const viewDefinition = await this.pendingViewDefinitions.execute(pendingViewDefCacheKey, () => (0, import_instrumentation.getTracer)().trace({
190
- name: import_instrumentation.ViewSpan.RenderView,
191
- attributes: {
192
- view: view.id,
193
- ssr: view.bootstrap?.ssr === true
189
+ const pendingViewDefCacheKey = viewDefCacheKey + viewParamKey;
190
+ const viewDefinition = await this.pendingViewDefinitions.execute(pendingViewDefCacheKey, () => (0, import_instrumentation.getTracer)().trace({
191
+ name: import_instrumentation.ViewSpan.RenderView,
192
+ attributes: {
193
+ view: view.id,
194
+ ssr: view.bootstrap?.ssr === true
195
+ }
196
+ }, () => this.renderView(view, viewParams, runtimeEnvironment, runtimeParams, renderOptions)));
197
+ if (cacheDisabled === false) {
198
+ const route = this.globalConfig.routes.find((r) => r.id === view.id);
199
+ const ttl = (0, import_shared_utils.shortestTtl)(viewDefinition.cache?.ttl, route?.cache?.ttl);
200
+ if (ttl !== 0) {
201
+ this.viewDefinitions.set(viewDefCacheKey, {
202
+ view,
203
+ viewDefinition,
204
+ paramKey: viewParamKey
205
+ }, {ttl: ttl ? ttl * 1e3 : void 0});
206
+ }
194
207
  }
195
- }, () => this.renderView(view, viewParams, runtimeEnvironment, runtimeParams, renderOptions)));
196
- if (cacheDisabled === false) {
197
- const route = this.globalConfig.routes.find((r) => r.id === view.id);
198
- const ttl = (0, import_shared_utils.shortestTtl)(viewDefinition.cache?.ttl, route?.cache?.ttl);
199
- if (ttl !== 0) {
200
- this.viewDefinitions.set(viewDefCacheKey, {
201
- view,
202
- viewDefinition,
203
- paramKey: viewParamKey
204
- }, {ttl: ttl ? ttl * 1e3 : void 0});
208
+ return viewDefinition;
209
+ } catch (err) {
210
+ if (err instanceof import_diagnostics.DiagnosticsError) {
211
+ throw err;
205
212
  }
213
+ import_diagnostics.logger.error(`Failed to get view definition "${view.id}": ${err}`);
214
+ const message = err instanceof Error ? err.message : String(err);
215
+ throw (0, import_diagnostics.createSingleDiagnosticError)({description: import_diagnostics.descriptions.SERVER.UNEXPECTED_ERROR(message)}, import_diagnostics.LwrServerError);
206
216
  }
207
- return viewDefinition;
208
217
  }
209
218
  async renderView(view, viewParams, runtimeEnvironment, runtimeParams = {}, renderOptions) {
210
219
  const {id, contentTemplate, rootComponent, layoutTemplate} = view;
@@ -45,8 +45,10 @@ function getViewBootstrapConfigurationResource(viewInfo, config, runtimeEnvironm
45
45
  },
46
46
  ...debug && {modifiers: {debug: "true"}}
47
47
  };
48
- const environment = {
49
- NODE_ENV: runtimeEnvironment.serverMode,
48
+ const nodeEnv = {
49
+ NODE_ENV: runtimeEnvironment.serverMode
50
+ };
51
+ const lwrEnv = {
50
52
  SSR: false,
51
53
  ...(0, import_shared_utils.buildEnvironmentContext)(runtimeParams)
52
54
  };
@@ -58,7 +60,8 @@ function getViewBootstrapConfigurationResource(viewInfo, config, runtimeEnvironm
58
60
  ...config,
59
61
  endpoints
60
62
  })});`,
61
- `globalThis.process = { env: ${JSON.stringify(environment)} };`,
63
+ `globalThis.LWR = {...globalThis.LWR, env: ${JSON.stringify(lwrEnv)}};`,
64
+ `globalThis.process={...globalThis.process,env:{...globalThis.process?.env,...${JSON.stringify(nodeEnv)}}};`,
62
65
  `globalThis.lwcRuntimeFlags = { ENABLE_MIXED_SHADOW_MODE: ${viewInfo.mixedMode} };`,
63
66
  debug && debugMessage && `console.warn(${JSON.stringify(debugMessage)});`
64
67
  ].filter(Boolean).join("\n");
@@ -30,6 +30,7 @@ var import_path = __toModule(require("path"));
30
30
  var import_shared_utils = __toModule(require("@lwrjs/shared-utils"));
31
31
  var import_instrumentation = __toModule(require("@lwrjs/instrumentation"));
32
32
  var import_utils = __toModule(require("./utils.cjs"));
33
+ var import_diagnostics = __toModule(require("@lwrjs/diagnostics"));
33
34
  var LwrViewHandler = class {
34
35
  constructor(context, globalConfig) {
35
36
  this.globalConfig = globalConfig;
@@ -135,7 +136,17 @@ var LwrViewHandler = class {
135
136
  view: route.id,
136
137
  route: viewRequest.requestPath
137
138
  }
138
- }, async () => routeHandlerFn({...viewRequest, locale}, {route, viewApi, ...paths}, routeHandlerOptions));
139
+ }, async () => {
140
+ try {
141
+ return await routeHandlerFn({...viewRequest, locale}, {route, viewApi, ...paths}, routeHandlerOptions);
142
+ } catch (err) {
143
+ if (err instanceof import_diagnostics.DiagnosticsError) {
144
+ throw err;
145
+ }
146
+ const message = err instanceof Error ? err.message : String(err);
147
+ throw (0, import_diagnostics.createSingleDiagnosticError)({description: import_diagnostics.descriptions.APPLICATION.ROUTE_HANDLER_ERROR(route.id, message)}, import_diagnostics.LwrApplicationError);
148
+ }
149
+ });
139
150
  return response;
140
151
  }
141
152
  getBoundApi(viewRequest, route, runtimeEnvironment, runtimeParams) {
package/build/es/index.js CHANGED
@@ -3,7 +3,7 @@ import { getTracer, ViewSpan } from '@lwrjs/instrumentation';
3
3
  import { normalizeRenderOptions, normalizeRenderedResult, reduceSourceAssetReferences } from './utils.js';
4
4
  import { linkLwrResources } from './linkers/link-lwr-resources.js';
5
5
  import { LRUCache } from 'lru-cache';
6
- import { logger } from '@lwrjs/diagnostics';
6
+ import { DiagnosticsError, LwrServerError, createSingleDiagnosticError, descriptions, logger, } from '@lwrjs/diagnostics';
7
7
  export { LwrViewHandler } from './view-handler.js';
8
8
  export class LwrViewRegistry {
9
9
  constructor(context, globalConfig) {
@@ -159,55 +159,65 @@ export class LwrViewRegistry {
159
159
  return false;
160
160
  }
161
161
  async getViewDefinition(view, viewParams, runtimeEnvironment, runtimeParams, renderOptions) {
162
- const { skipCaching, freezeAssets, viewParamCacheKey } = normalizeRenderOptions(this.runtimeEnvironment, renderOptions);
163
- const viewDefCacheKey = getCacheKeyFromJson({
164
- ...view,
165
- freezeAssets,
166
- locale: runtimeParams?.locale,
167
- basePath: runtimeParams?.basePath,
168
- debug: runtimeEnvironment.debug,
169
- });
170
- logger.debug(`[view-registry][getViewDefinition] viewDefCacheKey=${viewDefCacheKey}`);
171
- // viewParams is an unbounded object and can be very large (17MB/view for developer.salesforce.com). Allowing consumers
172
- // to provide a simple override avoids the excess memory / performance overhead of serializing & storing the viewParams
173
- // on every request, while still reusing our caching logic.
174
- const viewParamKey = viewParamCacheKey
175
- ? getCacheKeyFromJson(viewParamCacheKey)
176
- : getCacheKeyFromJson(viewParams);
177
- logger.debug(`[view-registry][getViewDefinition] viewParamKey=${viewParamKey}`);
178
- const cacheDisabled = process.env.NOCACHE === 'true' || skipCaching;
179
- // important: cache key does not include the unbounded viewParams
180
- if (cacheDisabled === false && this.viewDefinitions.has(viewDefCacheKey)) {
181
- const viewDefinition = this.viewDefinitions.get(viewDefCacheKey);
182
- if (viewDefinition &&
183
- viewDefinition.paramKey === viewParamKey &&
184
- viewDefinition.viewDefinition.immutable) {
185
- return viewDefinition.viewDefinition;
162
+ try {
163
+ const { skipCaching, freezeAssets, viewParamCacheKey } = normalizeRenderOptions(this.runtimeEnvironment, renderOptions);
164
+ const viewDefCacheKey = getCacheKeyFromJson({
165
+ ...view,
166
+ freezeAssets,
167
+ locale: runtimeParams?.locale,
168
+ basePath: runtimeParams?.basePath,
169
+ debug: runtimeEnvironment.debug,
170
+ });
171
+ logger.debug(`[view-registry][getViewDefinition] viewDefCacheKey=${viewDefCacheKey}`);
172
+ // viewParams is an unbounded object and can be very large (17MB/view for developer.salesforce.com). Allowing consumers
173
+ // to provide a simple override avoids the excess memory / performance overhead of serializing & storing the viewParams
174
+ // on every request, while still reusing our caching logic.
175
+ const viewParamKey = viewParamCacheKey
176
+ ? getCacheKeyFromJson(viewParamCacheKey)
177
+ : getCacheKeyFromJson(viewParams);
178
+ logger.debug(`[view-registry][getViewDefinition] viewParamKey=${viewParamKey}`);
179
+ const cacheDisabled = process.env.NOCACHE === 'true' || skipCaching;
180
+ // important: cache key does not include the unbounded viewParams
181
+ if (cacheDisabled === false && this.viewDefinitions.has(viewDefCacheKey)) {
182
+ const viewDefinition = this.viewDefinitions.get(viewDefCacheKey);
183
+ if (viewDefinition &&
184
+ viewDefinition.paramKey === viewParamKey &&
185
+ viewDefinition.viewDefinition.immutable) {
186
+ return viewDefinition.viewDefinition;
187
+ }
186
188
  }
189
+ const pendingViewDefCacheKey = viewDefCacheKey + viewParamKey;
190
+ const viewDefinition = await this.pendingViewDefinitions.execute(pendingViewDefCacheKey, () => getTracer().trace({
191
+ name: ViewSpan.RenderView,
192
+ attributes: {
193
+ view: view.id,
194
+ ssr: view.bootstrap?.ssr === true,
195
+ },
196
+ }, () => this.renderView(view, viewParams, runtimeEnvironment, runtimeParams, renderOptions)));
197
+ if (cacheDisabled === false) {
198
+ const route = this.globalConfig.routes.find((r) => r.id === view.id);
199
+ const ttl = shortestTtl(viewDefinition.cache?.ttl, route?.cache?.ttl);
200
+ if (ttl !== 0) {
201
+ // cache view definition for the shortest ttl or until it is the least recently used when ttl is undefined
202
+ this.viewDefinitions.set(viewDefCacheKey, {
203
+ view,
204
+ viewDefinition,
205
+ paramKey: viewParamKey,
206
+ },
207
+ // s -> ms
208
+ { ttl: ttl ? ttl * 1000 : undefined });
209
+ }
210
+ }
211
+ return viewDefinition;
187
212
  }
188
- const pendingViewDefCacheKey = viewDefCacheKey + viewParamKey;
189
- const viewDefinition = await this.pendingViewDefinitions.execute(pendingViewDefCacheKey, () => getTracer().trace({
190
- name: ViewSpan.RenderView,
191
- attributes: {
192
- view: view.id,
193
- ssr: view.bootstrap?.ssr === true,
194
- },
195
- }, () => this.renderView(view, viewParams, runtimeEnvironment, runtimeParams, renderOptions)));
196
- if (cacheDisabled === false) {
197
- const route = this.globalConfig.routes.find((r) => r.id === view.id);
198
- const ttl = shortestTtl(viewDefinition.cache?.ttl, route?.cache?.ttl);
199
- if (ttl !== 0) {
200
- // cache view definition for the shortest ttl or until it is the least recently used when ttl is undefined
201
- this.viewDefinitions.set(viewDefCacheKey, {
202
- view,
203
- viewDefinition,
204
- paramKey: viewParamKey,
205
- },
206
- // s -> ms
207
- { ttl: ttl ? ttl * 1000 : undefined });
213
+ catch (err) {
214
+ if (err instanceof DiagnosticsError) {
215
+ throw err;
208
216
  }
217
+ logger.error(`Failed to get view definition "${view.id}": ${err}`);
218
+ const message = err instanceof Error ? err.message : String(err);
219
+ throw createSingleDiagnosticError({ description: descriptions.SERVER.UNEXPECTED_ERROR(message) }, LwrServerError);
209
220
  }
210
- return viewDefinition;
211
221
  }
212
222
  async renderView(view, viewParams, runtimeEnvironment, runtimeParams = {}, renderOptions) {
213
223
  const { id, contentTemplate, rootComponent, layoutTemplate } = view;
@@ -17,9 +17,11 @@ export function getViewBootstrapConfigurationResource(viewInfo, config, runtimeE
17
17
  },
18
18
  ...(debug && { modifiers: { debug: 'true' } }),
19
19
  };
20
- const environment = {
20
+ const nodeEnv = {
21
21
  // TODO: W-12639529 change NODE_ENV after addressing downstream customers
22
22
  NODE_ENV: runtimeEnvironment.serverMode,
23
+ };
24
+ const lwrEnv = {
23
25
  // Note: SSR is always false because this script is executed on the client
24
26
  SSR: false,
25
27
  // Used by `lwr/environment`
@@ -33,7 +35,8 @@ export function getViewBootstrapConfigurationResource(viewInfo, config, runtimeE
33
35
  ...config,
34
36
  endpoints,
35
37
  })});`,
36
- `globalThis.process = { env: ${JSON.stringify(environment)} };`,
38
+ `globalThis.LWR = {...globalThis.LWR, env: ${JSON.stringify(lwrEnv)}};`,
39
+ `globalThis.process={...globalThis.process,env:{...globalThis.process?.env,...${JSON.stringify(nodeEnv)}}};`,
37
40
  `globalThis.lwcRuntimeFlags = { ENABLE_MIXED_SHADOW_MODE: ${viewInfo.mixedMode} };`,
38
41
  debug && debugMessage && `console.warn(${JSON.stringify(debugMessage)});`,
39
42
  ]
@@ -2,6 +2,7 @@ import { resolve } from 'path';
2
2
  import { normalizeResourcePath, shortestTtl } from '@lwrjs/shared-utils';
3
3
  import { getTracer, ViewSpan } from '@lwrjs/instrumentation';
4
4
  import { generateHtmlTag, generatePageContext, isViewResponse, toJsonFormat } from './utils.js';
5
+ import { DiagnosticsError, LwrApplicationError, createSingleDiagnosticError, descriptions, } from '@lwrjs/diagnostics';
5
6
  export class LwrViewHandler {
6
7
  constructor(context, globalConfig) {
7
8
  this.globalConfig = globalConfig;
@@ -145,14 +146,24 @@ export class LwrViewHandler {
145
146
  const paths = { rootDir, assets, contentDir, layoutsDir };
146
147
  const locale = runtimeParams.locale;
147
148
  const viewApi = this.getBoundApi(viewRequest, route, runtimeEnvironment, runtimeParams);
148
- // TODO: add trace attributes
149
149
  const response = await getTracer().trace({
150
150
  name: ViewSpan.ExecuteRouteHandler,
151
151
  attributes: {
152
152
  view: route.id,
153
153
  route: viewRequest.requestPath,
154
154
  },
155
- }, async () => routeHandlerFn({ ...viewRequest, locale }, { route: route, viewApi, ...paths }, routeHandlerOptions));
155
+ }, async () => {
156
+ try {
157
+ return await routeHandlerFn({ ...viewRequest, locale }, { route: route, viewApi, ...paths }, routeHandlerOptions);
158
+ }
159
+ catch (err) {
160
+ if (err instanceof DiagnosticsError) {
161
+ throw err;
162
+ }
163
+ const message = err instanceof Error ? err.message : String(err);
164
+ throw createSingleDiagnosticError({ description: descriptions.APPLICATION.ROUTE_HANDLER_ERROR(route.id, message) }, LwrApplicationError);
165
+ }
166
+ });
156
167
  return response;
157
168
  }
158
169
  /*
package/package.json CHANGED
@@ -4,7 +4,7 @@
4
4
  "publishConfig": {
5
5
  "access": "public"
6
6
  },
7
- "version": "0.12.0-alpha.12",
7
+ "version": "0.12.0-alpha.13",
8
8
  "homepage": "https://developer.salesforce.com/docs/platform/lwr/overview",
9
9
  "repository": {
10
10
  "type": "git",
@@ -30,17 +30,17 @@
30
30
  "build/**/*.d.ts"
31
31
  ],
32
32
  "dependencies": {
33
- "@lwrjs/app-service": "0.12.0-alpha.12",
34
- "@lwrjs/diagnostics": "0.12.0-alpha.12",
35
- "@lwrjs/instrumentation": "0.12.0-alpha.12",
36
- "@lwrjs/shared-utils": "0.12.0-alpha.12",
33
+ "@lwrjs/app-service": "0.12.0-alpha.13",
34
+ "@lwrjs/diagnostics": "0.12.0-alpha.13",
35
+ "@lwrjs/instrumentation": "0.12.0-alpha.13",
36
+ "@lwrjs/shared-utils": "0.12.0-alpha.13",
37
37
  "lru-cache": "^10.2.0"
38
38
  },
39
39
  "devDependencies": {
40
- "@lwrjs/types": "0.12.0-alpha.12"
40
+ "@lwrjs/types": "0.12.0-alpha.13"
41
41
  },
42
42
  "engines": {
43
43
  "node": ">=18.0.0"
44
44
  },
45
- "gitHead": "bc8a88bce246e9ec00641955152de526ea030ebb"
45
+ "gitHead": "7a63e416f9e5f27b44331311a371f68e20ce685c"
46
46
  }