@lwrjs/lwc-ssr 0.13.3 → 0.13.5

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.
@@ -53,7 +53,8 @@ async function createAMDModuleLoader(config, resourceRegistry, bundleRegistry, r
53
53
  fn(context, ...Object.values(context));
54
54
  } else {
55
55
  ((context) => {
56
- eval(`${Object.keys(context).reduce((c, k) => c + `const ${k} = context['${k}'];`, "globalThis=context;")} ${source}`);
56
+ const evalSource = `${Object.keys(context).reduce((c, k) => c + `const ${k} = context['${k}'];`, "const globalThis=context;")} ${source}`;
57
+ eval(evalSource);
57
58
  })(context);
58
59
  }
59
60
  };
@@ -79,7 +80,7 @@ async function createAMDModuleLoader(config, resourceRegistry, bundleRegistry, r
79
80
  const moduleId = (0, import_shared_utils.explodeSpecifier)(bundle);
80
81
  const def = await bundleRegistry.getModuleBundle(moduleId, runtimeEnvironment, runtimeParams);
81
82
  if (typeof def.src === "string" && !def.code.includes("//# sourceURL=")) {
82
- const srcUrl = (0, import_shared_utils.isLocalDev)() ? (0, import_shared_utils.getLocalDevOverrideUrl)(config.cacheDir, moduleId.specifier, def.src) : def.src;
83
+ const srcUrl = def.srcOverride ?? def.src;
83
84
  def.code += `
84
85
  //# sourceURL=${import_path.default.resolve(srcUrl)}`;
85
86
  }
@@ -187,7 +187,7 @@ var Renderer = class {
187
187
  getCachedBootstrapContext(route, runtimeEnvironment, runtimeParams, serverData, reevaluateModules) {
188
188
  let loader, bootstrapServiceEvaluationMap;
189
189
  if (reevaluateModules) {
190
- if (!this.cachedBootstrapContext) {
190
+ if (!this.cachedBootstrapContext || (0, import_shared_utils.isLocalDev)()) {
191
191
  this.cachedBootstrapContext = {
192
192
  loader: (0, import_moduleLoader.createModuleLoader)(this.config, this.resourceRegistry, this.bundleRegistry, runtimeEnvironment, runtimeParams, serverData, route.bootstrap),
193
193
  bootstrapServiceEvaluationMap: new Map()
@@ -29,6 +29,7 @@ __export(exports, {
29
29
  addHeadMarkup: () => addHeadMarkup,
30
30
  createFetchEndowment: () => createFetchEndowment,
31
31
  createHeadMarkup: () => createHeadMarkup,
32
+ createSsrErrorMarkup: () => createSsrErrorMarkup,
32
33
  createSsrErrorMessage: () => createSsrErrorMessage,
33
34
  getLoaderConfig: () => getLoaderConfig,
34
35
  getLoaderId: () => getLoaderId,
@@ -49,8 +50,17 @@ function getRenderTimeout() {
49
50
  const override = process.env.SSR_TIMEOUT;
50
51
  return override ? Number.parseInt(override) : DEFAULT_SSR_TIMEOUT;
51
52
  }
52
- function createSsrErrorMessage(specifier, e) {
53
- return `Server-side rendering for "${specifier}" failed. Falling back to client-side rendering. Reason: ${(0, import_diagnostics.stringifyError)(e)}`;
53
+ function createSsrErrorMessage(specifier, e, fallback = true) {
54
+ const fallbackMsg = fallback ? " Falling back to client-side rendering." : "";
55
+ return `Server-side rendering for "${specifier}" failed.${fallbackMsg} Reason: ${(0, import_diagnostics.stringifyError)(e)}`;
56
+ }
57
+ function createSsrErrorMarkup(errors, basePath) {
58
+ let markup = '<div style="font-family:sans-serif;margin:50px;font-size:1.2em;"><h1>500: Server-side rendering failed</h1><p>Reasons:</p><ul>';
59
+ Object.entries(errors).forEach(([specifier, reason]) => {
60
+ markup += `<li><strong>${specifier}</strong>: ${(0, import_diagnostics.stringifyError)(reason)}</li>`;
61
+ });
62
+ markup += `</ul><p style="padding-top:1em;">See more information in the browser console. Contact your administrator for assistance.</p></div>`;
63
+ return markup;
54
64
  }
55
65
  async function getLoaderShim(resourceRegistry, runtimeEnvironment, bootstrapConfig) {
56
66
  const {debug} = runtimeEnvironment;
@@ -77,10 +77,10 @@ var LwcViewProvider = class extends import_base_view_provider.default {
77
77
  if (!debug && !(0, import_shared_utils.getFeatureFlags)().SSR_WITH_CSR_FALLBACK) {
78
78
  throw new Error(errorString);
79
79
  }
80
- const message = (0, import_utils.createSsrErrorMessage)(specifier, errorString);
80
+ const message = (0, import_utils.createSsrErrorMessage)(specifier, errorString, false);
81
81
  import_diagnostics.logger.warn(message, errors[specifier]);
82
82
  return {
83
- renderedView: `<${element} ${import_shared_utils.HYDRATE_DIRECTIVE}="${import_shared_utils.HYDRATE_CLIENT_VALUE}"></${element}>`,
83
+ renderedView: (0, import_utils.createSsrErrorMarkup)(errors, this.runtimeEnvironment.basePath),
84
84
  metadata: {
85
85
  serverDebug: {message: debug ? message : void 0},
86
86
  customElements: [],
@@ -1,7 +1,7 @@
1
1
  import path from 'path';
2
2
  import crypto from 'crypto';
3
3
  import { getTracer } from '@lwrjs/instrumentation';
4
- import { explodeSpecifier, getLocalDevOverrideUrl, getSpecifier, isLocalDev } from '@lwrjs/shared-utils';
4
+ import { explodeSpecifier, getSpecifier } from '@lwrjs/shared-utils';
5
5
  import { FetchController, createFetchEndowment, getLoaderConfig, getLoaderId, getLoaderShim, } from './utils.js';
6
6
  export const FETCH_ABORT_KEY = '__fetchAbortId__';
7
7
  const BOOTSTRAP_SPECIFIER = '@lwrjs/ssr-bootstrap';
@@ -23,13 +23,15 @@ async function createAMDModuleLoader(config, resourceRegistry, bundleRegistry, r
23
23
  const useEval = process.env.SSR_DEBUG === 'true';
24
24
  const init = (source) => {
25
25
  if (!useEval) {
26
+ // Runtime Default: use new Function() for source evaluation due its to performance benefits / code isolation
26
27
  const fn = new Function('globalThis', ...Object.keys(context), source);
27
28
  fn(context, ...Object.values(context));
28
29
  }
29
30
  else {
30
- // use eval to ensure source map line numbers are correct for debugging
31
+ // Debugging: use eval() when debugging SSR to ensure source map line numbers are correct
31
32
  ((context) => {
32
- eval(`${Object.keys(context).reduce((c, k) => c + `const ${k} = context['${k}'];`, 'globalThis=context;')} ${source}`);
33
+ const evalSource = `${Object.keys(context).reduce((c, k) => c + `const ${k} = context['${k}'];`, 'const globalThis=context;')} ${source}`;
34
+ eval(evalSource);
33
35
  })(context);
34
36
  }
35
37
  };
@@ -61,9 +63,7 @@ async function createAMDModuleLoader(config, resourceRegistry, bundleRegistry, r
61
63
  const def = await bundleRegistry.getModuleBundle(moduleId, runtimeEnvironment, runtimeParams);
62
64
  if (typeof def.src === 'string' && !def.code.includes('//# sourceURL=')) {
63
65
  // @view bundles are stored in a special location during local-dev
64
- const srcUrl = isLocalDev()
65
- ? getLocalDevOverrideUrl(config.cacheDir, moduleId.specifier, def.src)
66
- : def.src;
66
+ const srcUrl = def.srcOverride ?? def.src;
67
67
  def.code += `\n//# sourceURL=${path.resolve(srcUrl)}`;
68
68
  }
69
69
  const staticImports = def.bundleRecord.imports?.map((dep) => getSpecifier(dep)) ?? [];
@@ -1,7 +1,7 @@
1
1
  // TODO: investigate perf impact W-16056356
2
2
  import { LRUCache } from 'lru-cache';
3
3
  import { LwrUnresolvableError, createSingleDiagnosticError, descriptions, logger, stringifyError, } from '@lwrjs/diagnostics';
4
- import { buildEnvironmentContext, getCacheKeyFromJson, getSpecifier, isLambdaEnv, moduleSpecifierToKebabCase, getFeatureFlags, TaskPool, } from '@lwrjs/shared-utils';
4
+ import { buildEnvironmentContext, getCacheKeyFromJson, getSpecifier, isLambdaEnv, moduleSpecifierToKebabCase, getFeatureFlags, TaskPool, isLocalDev, } from '@lwrjs/shared-utils';
5
5
  import { ViewSpan, getTracer } from '@lwrjs/instrumentation';
6
6
  import { getServerBootstrapServices, getRenderTimeout } from './utils.js';
7
7
  import { createModuleLoader } from './moduleLoader.js';
@@ -228,7 +228,7 @@ export class Renderer {
228
228
  let loader, bootstrapServiceEvaluationMap;
229
229
  // when `REEEVALUTE_MODULES` is true, we only have a single context/loader, regardless of the env
230
230
  if (reevaluateModules) {
231
- if (!this.cachedBootstrapContext) {
231
+ if (!this.cachedBootstrapContext || isLocalDev()) {
232
232
  this.cachedBootstrapContext = {
233
233
  loader: createModuleLoader(this.config, this.resourceRegistry, this.bundleRegistry, runtimeEnvironment, runtimeParams, serverData, route.bootstrap),
234
234
  bootstrapServiceEvaluationMap: new Map(),
@@ -6,7 +6,8 @@ interface ServerEnvironment extends EnvironmentContext {
6
6
  export declare const SSR_PROPS_ATTR = "data-lwr-props-id";
7
7
  export declare function getPropsId(): string;
8
8
  export declare function getRenderTimeout(): number;
9
- export declare function createSsrErrorMessage(specifier: string, e: any): string;
9
+ export declare function createSsrErrorMessage(specifier: string, e: any, fallback?: boolean): string;
10
+ export declare function createSsrErrorMarkup(errors: Record<string, string>, basePath: string): string;
10
11
  export declare function getLoaderShim(resourceRegistry: PublicResourceRegistry, runtimeEnvironment: RuntimeEnvironment, bootstrapConfig: NormalizedLwrAppBootstrapConfig): Promise<string>;
11
12
  export declare function getLoaderId(config: ClientBootstrapConfig, bootstrapConfig: NormalizedLwrAppBootstrapConfig): string;
12
13
  export declare function getLoaderConfig(bootstrapModule: string, config: ProviderAppConfig, runtimeParams: RuntimeParams, serverData: ServerData): ClientBootstrapConfig & {
package/build/es/utils.js CHANGED
@@ -10,8 +10,17 @@ export function getRenderTimeout() {
10
10
  const override = process.env.SSR_TIMEOUT;
11
11
  return override ? Number.parseInt(override) : DEFAULT_SSR_TIMEOUT;
12
12
  }
13
- export function createSsrErrorMessage(specifier, e) {
14
- return `Server-side rendering for "${specifier}" failed. Falling back to client-side rendering. Reason: ${stringifyError(e)}`;
13
+ export function createSsrErrorMessage(specifier, e, fallback = true) {
14
+ const fallbackMsg = fallback ? ' Falling back to client-side rendering.' : '';
15
+ return `Server-side rendering for "${specifier}" failed.${fallbackMsg} Reason: ${stringifyError(e)}`;
16
+ }
17
+ export function createSsrErrorMarkup(errors, basePath) {
18
+ let markup = '<div style="font-family:sans-serif;margin:50px;font-size:1.2em;"><h1>500: Server-side rendering failed</h1><p>Reasons:</p><ul>';
19
+ Object.entries(errors).forEach(([specifier, reason]) => {
20
+ markup += `<li><strong>${specifier}</strong>: ${stringifyError(reason)}</li>`;
21
+ });
22
+ markup += `</ul><p style="padding-top:1em;">See more information in the browser console. Contact your administrator for assistance.</p></div>`;
23
+ return markup;
15
24
  }
16
25
  export async function getLoaderShim(resourceRegistry, runtimeEnvironment, bootstrapConfig) {
17
26
  const { debug } = runtimeEnvironment;
@@ -1,8 +1,8 @@
1
1
  import BaseViewProvider from '@lwrjs/base-view-provider';
2
2
  import { logger } from '@lwrjs/diagnostics';
3
3
  import { ViewSpan, getTracer } from '@lwrjs/instrumentation';
4
- import { HYDRATE_CLIENT_VALUE, HYDRATE_DIRECTIVE, getFeatureFlags, hashContent, isSpecifier, moduleSpecifierToKebabCase, slugify, } from '@lwrjs/shared-utils';
5
- import { createHeadMarkup, createSsrErrorMessage } from '../utils.js';
4
+ import { getFeatureFlags, hashContent, isSpecifier, moduleSpecifierToKebabCase, slugify, } from '@lwrjs/shared-utils';
5
+ import { createHeadMarkup, createSsrErrorMarkup, createSsrErrorMessage } from '../utils.js';
6
6
  import { getRenderer } from '../renderer.js';
7
7
  export default class LwcViewProvider extends BaseViewProvider {
8
8
  constructor(_pluginConfig, providerConfig) {
@@ -18,7 +18,7 @@ export default class LwcViewProvider extends BaseViewProvider {
18
18
  return;
19
19
  }
20
20
  async getView(viewId) {
21
- // This view provider creates content templates from LWC component specifiers
21
+ // This view provider creates content templates with islands from LWC component specifiers
22
22
  const specifier = viewId.contentTemplate?.component;
23
23
  if (!specifier || !isSpecifier(specifier)) {
24
24
  return;
@@ -48,18 +48,19 @@ export default class LwcViewProvider extends BaseViewProvider {
48
48
  const { results = {}, errors } = await getRenderer(config, moduleBundler, resourceRegistry).render({ [specifier]: { specifier, props: {} } }, route, runtimeEnvironment, Object(runtimeParams), undefined,
49
49
  // lets the renderer know this is the first of 2-pass SSR
50
50
  true);
51
- // Handle errors: fallback to CSR or throw
51
+ // Handle errors: throw or return an error page
52
52
  if (errors) {
53
53
  const errorString = Object.values(errors).join(', ');
54
54
  if (!debug && !getFeatureFlags().SSR_WITH_CSR_FALLBACK) {
55
55
  // 500 error for the page request
56
56
  throw new Error(errorString);
57
57
  }
58
- // fallback to CSR
59
- const message = createSsrErrorMessage(specifier, errorString);
58
+ // error page
59
+ const message = createSsrErrorMessage(specifier, errorString, false);
60
60
  logger.warn(message, errors[specifier]); // TODO specific metadata for errors
61
61
  return {
62
- renderedView: `<${element} ${HYDRATE_DIRECTIVE}="${HYDRATE_CLIENT_VALUE}"></${element}>`,
62
+ // render the errors on the browser page; fallback to CSR is not possible on the 1st pass
63
+ renderedView: createSsrErrorMarkup(errors, this.runtimeEnvironment.basePath),
63
64
  // send an error message to the client if debug mode is on
64
65
  metadata: {
65
66
  serverDebug: { message: debug ? message : undefined },
package/package.json CHANGED
@@ -4,7 +4,7 @@
4
4
  "publishConfig": {
5
5
  "access": "public"
6
6
  },
7
- "version": "0.13.3",
7
+ "version": "0.13.5",
8
8
  "homepage": "https://developer.salesforce.com/docs/platform/lwr/overview",
9
9
  "repository": {
10
10
  "type": "git",
@@ -42,18 +42,18 @@
42
42
  "build/**/*.d.ts"
43
43
  ],
44
44
  "dependencies": {
45
- "@lwrjs/config": "0.13.3",
46
- "@lwrjs/diagnostics": "0.13.3",
47
- "@lwrjs/instrumentation": "0.13.3",
48
- "@lwrjs/loader": "0.13.3",
49
- "@lwrjs/shared-utils": "0.13.3",
45
+ "@lwrjs/config": "0.13.5",
46
+ "@lwrjs/diagnostics": "0.13.5",
47
+ "@lwrjs/instrumentation": "0.13.5",
48
+ "@lwrjs/loader": "0.13.5",
49
+ "@lwrjs/shared-utils": "0.13.5",
50
50
  "fs-extra": "^11.2.0",
51
51
  "lru-cache": "^10.4.3"
52
52
  },
53
53
  "devDependencies": {
54
- "@lwrjs/types": "0.13.3",
54
+ "@lwrjs/types": "0.13.5",
55
55
  "jest": "^26.6.3",
56
- "mock-fs": "^5.2.0",
56
+ "memfs": "^4.9.3",
57
57
  "ts-jest": "^26.5.6"
58
58
  },
59
59
  "engines": {
@@ -62,5 +62,5 @@
62
62
  "volta": {
63
63
  "extends": "../../../package.json"
64
64
  },
65
- "gitHead": "adaedf286df20aed374d9eb07eaf74668084073c"
65
+ "gitHead": "8a0b773b7ed0e017f3fa29f1e918e0c0e31bd74f"
66
66
  }