@lwrjs/lwc-ssr 0.8.0-alpha.0 → 0.8.0-alpha.3

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/README.md CHANGED
@@ -63,7 +63,7 @@ Because of this, the [`@lwrjs/router`](https://github.com/salesforce/lwr-recipes
63
63
 
64
64
  ### Preloading data during SSR
65
65
 
66
- Many components depend on external data. LWR provides a `getProps()` hook for developers to fetch that data on the server. LWR passes the data to the component during SSR as [properties](<(https://developer.salesforce.com/docs/component-library/documentation/en/lwc/reactivity_public)>).
66
+ Many components depend on external data. LWR provides a `getProps()` hook for developers to fetch that data on the server. SSR Sandbox supports `fetch` with its `globalThis` so developers could use `fetch` as if the module is executed by the browser. LWR passes the data to the component during SSR as [properties](<(https://developer.salesforce.com/docs/component-library/documentation/en/lwc/reactivity_public)>).
67
67
 
68
68
  > **Important**: This hook is **only** run for root components.
69
69
 
@@ -83,7 +83,7 @@ export async function getProps(context: PropsRequestContext): Promise<PropsRespo
83
83
  const category = context.params.category;
84
84
  // page.html template => context.props = { limit: '10' }
85
85
  const num = context.props.limit || '25';
86
- const res = await context.fetch(`https://www.some-api.com/${category}?lang=${context.locale}&num=${num}`);
86
+ const res = await fetch(`https://www.some-api.com/${category}?lang=${context.locale}&num=${num}`);
87
87
  const data = await res.json();
88
88
  return {
89
89
  props: {
@@ -107,8 +107,6 @@ interface PropsRequestContext {
107
107
  query: { [key: string]: string };
108
108
  // locale string for the request, eg: 'en-US'
109
109
  locale: string;
110
- // server-friendly fetch() function for accessing data
111
- fetch: Function;
112
110
  }
113
111
 
114
112
  interface PropsResponse {
@@ -40,10 +40,7 @@ import Ctor, * as rootComponent from '${rootSpecifier}';
40
40
  const context = globalThis.getContext();
41
41
  let props = context.props;
42
42
  if (rootComponent.getProps) {
43
- const data = await rootComponent.getProps({
44
- ...context,
45
- fetch: globalThis.fetch,
46
- });
43
+ const data = await rootComponent.getProps(context);
47
44
  props = data.props; // overwrite public props
48
45
  }
49
46
 
@@ -76,9 +76,18 @@ function lwcDefineOverride(lwcSpecifier) {
76
76
  return `LWR.define("${lwcSpecifier}", ["${lwcSpecifier.replace("lwc", "@lwc/engine-server")}"], function(lwcEngine) { return lwcEngine; });`;
77
77
  }
78
78
  var GLOBALTHIS_LWR = `globalThis.LWR = globalThis.LWR || {};`;
79
- async function getCode(runtimeEnvironment, lwrVersion, lwcSpecifier, bundleSpecifier) {
79
+ async function getCode(runtimeEnvironment, lwrVersion, bundleSpecifier, includedModules) {
80
80
  const loaderShimSource2 = await getLoaderShim(runtimeEnvironment);
81
81
  const lwrConfigString = JSON.stringify(getLwrConfig(bundleSpecifier, lwrVersion));
82
+ const lwcSpecifier = includedModules.reduce((specifier, includedModule) => {
83
+ if (includedModule.startsWith("lwc/v")) {
84
+ return includedModule;
85
+ }
86
+ if (!specifier && includedModule.startsWith("@lwc/engine-server/v")) {
87
+ return includedModule.replace("@lwc/engine-server", "lwc");
88
+ }
89
+ return specifier;
90
+ }, "");
82
91
  return [
83
92
  GLOBALTHIS_LWR,
84
93
  `Object.assign(globalThis.LWR, ${lwrConfigString});`,
@@ -60,7 +60,9 @@ function lwcSsrViewTranformer(options, {moduleBundler}) {
60
60
  const [, remain] = html.split(`<${tagName}`);
61
61
  html = [`<${tagName}`, ` ${import_identity.SSR_PROPS_ATTR}="${propsId}"`, remain].join("");
62
62
  }
63
- stringBuilder.overwrite(startOffset, endOffset, html);
63
+ if (html.length > 0) {
64
+ stringBuilder.overwrite(startOffset, endOffset, html);
65
+ }
64
66
  });
65
67
  }));
66
68
  if (Object.keys(ssrProps).length) {
@@ -35,12 +35,13 @@ var bundleConfigOverrides = {
35
35
  }
36
36
  };
37
37
  async function ssrElement({specifier, props: templateProps}, moduleBundler, {runtimeEnvironment, runtimeParams}) {
38
+ const {format, bundle} = runtimeEnvironment;
38
39
  const {
39
40
  bundleRecord,
40
41
  code,
41
42
  specifier: bundleSpecifier,
42
43
  version
43
- } = await moduleBundler.getModuleBundle({specifier}, {...runtimeEnvironment, bundle: false}, void 0, bundleConfigOverrides);
44
+ } = await moduleBundler.getModuleBundle({specifier}, {...runtimeEnvironment, bundle: format === "esm" ? false : bundle}, void 0, bundleConfigOverrides);
44
45
  const context = {
45
46
  props: templateProps,
46
47
  params: runtimeParams.params || {},
@@ -48,11 +49,12 @@ async function ssrElement({specifier, props: templateProps}, moduleBundler, {run
48
49
  locale: runtimeParams.locale || runtimeEnvironment.defaultLocale
49
50
  };
50
51
  const {error, result, props} = runtimeEnvironment.format === "amd" ? await (0, import_sandbox.default)([
51
- ...await (0, import_amd_utils.default)(runtimeEnvironment, version.replace(/\./g, "_"), bundleRecord.includedModules.find((m) => m.startsWith("lwc/v")), bundleSpecifier),
52
+ ...await (0, import_amd_utils.default)(runtimeEnvironment, version.replace(/\./g, "_"), bundleSpecifier, bundleRecord.includedModules),
52
53
  code
53
54
  ], context) : await (0, import_sandbox.default)([code], context);
54
55
  if (error) {
55
- throw new Error(error);
56
+ console.error(`Server-side rendering for "${specifier}" failed. Falling back to client-side rendering. Reason: `, error);
57
+ return {html: "", props: void 0};
56
58
  } else {
57
59
  return {html: result, props};
58
60
  }
@@ -24,10 +24,7 @@ import Ctor, * as rootComponent from '${rootSpecifier}';
24
24
  const context = globalThis.getContext();
25
25
  let props = context.props;
26
26
  if (rootComponent.getProps) {
27
- const data = await rootComponent.getProps({
28
- ...context,
29
- fetch: globalThis.fetch,
30
- });
27
+ const data = await rootComponent.getProps(context);
31
28
  props = data.props; // overwrite public props
32
29
  }
33
30
 
@@ -1,3 +1,3 @@
1
1
  import { RuntimeEnvironment } from '@lwrjs/types';
2
- export default function getCode(runtimeEnvironment: RuntimeEnvironment, lwrVersion: string, lwcSpecifier: string | undefined, bundleSpecifier: string): Promise<string[]>;
2
+ export default function getCode(runtimeEnvironment: RuntimeEnvironment, lwrVersion: string, bundleSpecifier: string, includedModules: string[]): Promise<string[]>;
3
3
  //# sourceMappingURL=amd-utils.d.ts.map
@@ -54,9 +54,20 @@ function lwcDefineOverride(lwcSpecifier) {
54
54
  return `LWR.define("${lwcSpecifier}", ["${lwcSpecifier.replace('lwc', '@lwc/engine-server')}"], function(lwcEngine) { return lwcEngine; });`;
55
55
  }
56
56
  const GLOBALTHIS_LWR = `globalThis.LWR = globalThis.LWR || {};`;
57
- export default async function getCode(runtimeEnvironment, lwrVersion, lwcSpecifier, bundleSpecifier) {
57
+ export default async function getCode(runtimeEnvironment, lwrVersion, bundleSpecifier, includedModules) {
58
58
  const loaderShimSource = await getLoaderShim(runtimeEnvironment);
59
59
  const lwrConfigString = JSON.stringify(getLwrConfig(bundleSpecifier, lwrVersion));
60
+ const lwcSpecifier = includedModules.reduce((specifier, includedModule) => {
61
+ if (includedModule.startsWith('lwc/v')) {
62
+ return includedModule;
63
+ }
64
+ // define `lwc` when `@lwc/engine-server` is included in the bundle
65
+ // `lwc` will be excluded by default when bundling is enabled
66
+ if (!specifier && includedModule.startsWith('@lwc/engine-server/v')) {
67
+ return includedModule.replace('@lwc/engine-server', 'lwc');
68
+ }
69
+ return specifier;
70
+ }, '');
60
71
  // Order matters:
61
72
  // 1. "globalThis.LWR" must be defined prior to executing the shim and loader
62
73
  // 2. the lwc module override needs to be defined before lwc is [re]defined in the custom element code (first define wins)
@@ -56,8 +56,10 @@ export default function lwcSsrViewTranformer(options, { moduleBundler }) {
56
56
  const [, remain] = html.split(`<${tagName}`);
57
57
  html = [`<${tagName}`, ` ${SSR_PROPS_ATTR}="${propsId}"`, remain].join('');
58
58
  }
59
- // Overwrite the custom element with the SSRed component string
60
- stringBuilder.overwrite(startOffset, endOffset, html);
59
+ if (html.length > 0) {
60
+ // Overwrite the custom element with the SSRed component string
61
+ stringBuilder.overwrite(startOffset, endOffset, html);
62
+ }
61
63
  });
62
64
  }));
63
65
  if (Object.keys(ssrProps).length) {
@@ -4,6 +4,6 @@ interface SandboxResults {
4
4
  error?: string;
5
5
  props?: Json;
6
6
  }
7
- export default function runCode(codes: string[], context: Partial<PropsRequestContext>): Promise<SandboxResults>;
7
+ export default function runCode(codes: string[], context: PropsRequestContext): Promise<SandboxResults>;
8
8
  export {};
9
9
  //# sourceMappingURL=sandbox.d.ts.map
@@ -15,11 +15,12 @@ const bundleConfigOverrides = {
15
15
  * @returns a promise to the SSRed code string
16
16
  */
17
17
  export async function ssrElement({ specifier, props: templateProps }, moduleBundler, { runtimeEnvironment, runtimeParams }) {
18
+ const { format, bundle } = runtimeEnvironment;
18
19
  const { bundleRecord, code, specifier: bundleSpecifier, version, } = await moduleBundler.getModuleBundle({ specifier },
19
- // Ensure the bundle flag is always off,
20
+ // Ensure the bundle flag is always off in ESM,
20
21
  // otherwise TOO much gets bundled in the module registry
21
22
  // in ESM, resulting lwc clashes/duplication
22
- { ...runtimeEnvironment, bundle: false }, undefined, bundleConfigOverrides);
23
+ { ...runtimeEnvironment, bundle: format === 'esm' ? false : bundle }, undefined, bundleConfigOverrides);
23
24
  // Gather context to send into the SSR sandbox
24
25
  const context = {
25
26
  props: templateProps,
@@ -30,12 +31,13 @@ export async function ssrElement({ specifier, props: templateProps }, moduleBund
30
31
  // Get the SSR string and properties bag
31
32
  const { error, result, props } = runtimeEnvironment.format === 'amd'
32
33
  ? await runCode([
33
- ...(await getCode(runtimeEnvironment, version.replace(/\./g, '_'), bundleRecord.includedModules.find((m) => m.startsWith('lwc/v')), bundleSpecifier)),
34
+ ...(await getCode(runtimeEnvironment, version.replace(/\./g, '_'), bundleSpecifier, bundleRecord.includedModules)),
34
35
  code,
35
36
  ], context)
36
37
  : await runCode([code], context);
37
38
  if (error) {
38
- throw new Error(error);
39
+ console.error(`Server-side rendering for "${specifier}" failed. Falling back to client-side rendering. Reason: `, error);
40
+ return { html: '', props: undefined };
39
41
  }
40
42
  else {
41
43
  return { html: result, props };
package/package.json CHANGED
@@ -4,7 +4,7 @@
4
4
  "publishConfig": {
5
5
  "access": "public"
6
6
  },
7
- "version": "0.8.0-alpha.0",
7
+ "version": "0.8.0-alpha.3",
8
8
  "homepage": "https://developer.salesforce.com/docs/platform/lwr/overview",
9
9
  "repository": {
10
10
  "type": "git",
@@ -33,14 +33,14 @@
33
33
  "build/**/*.d.ts"
34
34
  ],
35
35
  "dependencies": {
36
- "@lwrjs/diagnostics": "0.8.0-alpha.0",
37
- "@lwrjs/shared-utils": "0.8.0-alpha.0"
36
+ "@lwrjs/diagnostics": "0.8.0-alpha.3",
37
+ "@lwrjs/shared-utils": "0.8.0-alpha.3"
38
38
  },
39
39
  "devDependencies": {
40
- "@lwrjs/types": "0.8.0-alpha.0"
40
+ "@lwrjs/types": "0.8.0-alpha.3"
41
41
  },
42
42
  "engines": {
43
43
  "node": ">=14.15.4 <19"
44
44
  },
45
- "gitHead": "2e1f60ed13f9f8079f1333af9b614cd24715f3ad"
45
+ "gitHead": "bf22045bd29a832ff98f6bafa1120b5453960f8c"
46
46
  }