@lwrjs/lwc-ssr 0.17.2-alpha.2 → 0.17.2-alpha.20

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.
@@ -21,7 +21,7 @@ var Renderer = class {
21
21
  }
22
22
  async render(components) {
23
23
  const results = {};
24
- const errors = {};
24
+ const warnings = [];
25
25
  for (const [specifier] of Object.entries(components)) {
26
26
  const mockOutput = mockComponents[specifier];
27
27
  if (!mockOutput) {
@@ -29,14 +29,14 @@ var Renderer = class {
29
29
  }
30
30
  if (mockOutput.result) {
31
31
  results[specifier] = mockOutput.result;
32
+ if (mockOutput.result.warnings) {
33
+ warnings.push(...mockOutput.result.warnings);
34
+ }
32
35
  }
33
36
  if (mockOutput.error) {
34
- errors[specifier] = mockOutput.error;
37
+ throw new Error(mockOutput.error);
35
38
  }
36
39
  }
37
- if (Object.keys(errors).length) {
38
- return {results, errors};
39
- }
40
- return {results, bundles: new Set([2, 3, 4])};
40
+ return {results, warnings, bundles: new Set([2, 3, 4])};
41
41
  }
42
42
  };
@@ -28,6 +28,7 @@ __export(exports, {
28
28
  });
29
29
  var import_diagnostics = __toModule(require("@lwrjs/diagnostics"));
30
30
  var import_instrumentation = __toModule(require("@lwrjs/instrumentation"));
31
+ var import_shared_utils = __toModule(require("@lwrjs/shared-utils"));
31
32
  var import_utils = __toModule(require("../utils.cjs"));
32
33
  var import_renderer = __toModule(require("../renderer.cjs"));
33
34
  var NAME = "preload-data-transformer";
@@ -44,7 +45,7 @@ function preloadDataViewTransformer(_options, {config, moduleBundler, resourceRe
44
45
  import_diagnostics.logger.debug({label: NAME, message: `Preload data for root component "${rootComponent}"`});
45
46
  const {
46
47
  results = {},
47
- errors,
48
+ warnings,
48
49
  bundles
49
50
  } = await (0, import_instrumentation.getTracer)().trace({
50
51
  name: import_instrumentation.ViewSpan.PreloadData,
@@ -54,24 +55,28 @@ function preloadDataViewTransformer(_options, {config, moduleBundler, resourceRe
54
55
  if (!route) {
55
56
  throw new Error(`Unable to resolve configuration for view: ${viewContext.view.id}`);
56
57
  }
57
- return await (0, import_renderer.getRenderer)(config, moduleBundler, resourceRegistry).render({[rootComponent]: {specifier: rootComponent, props: {}}}, route, viewContext.runtimeEnvironment, viewContext.runtimeParams);
58
- });
59
- if (errors) {
60
- for (const err of Object.entries(errors)) {
61
- import_diagnostics.logger.warn({
62
- label: "preloadDataViewTransformer",
63
- message: `Unexpected error during preload data: ${err[0]}`
64
- }, err[1]);
58
+ try {
59
+ return await (0, import_renderer.getRenderer)(config, moduleBundler, resourceRegistry).render({[rootComponent]: {specifier: rootComponent, props: {}}}, route, viewContext.runtimeEnvironment, viewContext.runtimeParams);
60
+ } catch (e) {
61
+ if (e instanceof import_diagnostics.LwrStatusError)
62
+ throw e;
63
+ const message = import_diagnostics.descriptions.APPLICATION.PRELOAD_DATA_ERROR(rootComponent, (0, import_diagnostics.stringifyError)(e));
64
+ import_diagnostics.logger.warn({label: "preloadDataViewTransformer", message});
65
+ return {warnings: [message]};
65
66
  }
67
+ });
68
+ (0, import_utils.mergeWarnings)(metadata, warnings);
69
+ const result = results[rootComponent];
70
+ if (!result) {
66
71
  return {};
67
72
  }
68
- const {props, markup, cache: {ttl} = {ttl: void 0}, status} = results[rootComponent];
73
+ const {props, markup, cache: {ttl} = {ttl: void 0}} = result || {};
69
74
  import_diagnostics.logger.verbose({label: NAME, message: "response", additionalInfo: props});
70
- markup && (0, import_utils.addHeadMarkup)([results[rootComponent]], stringBuilder);
75
+ markup && (0, import_shared_utils.addHeadMarkup)([result.markup], stringBuilder);
71
76
  metadata.serverData = metadata.serverData || {};
72
77
  Object.assign(metadata.serverData, props);
73
78
  metadata.serverBundles = bundles ? new Set([...allBundles, ...bundles]) : allBundles;
74
- return {cache: {ttl}, status};
79
+ return {cache: {ttl}};
75
80
  }
76
81
  };
77
82
  }
@@ -30,7 +30,6 @@ var import_undici = __toModule(require("undici"));
30
30
  var import_diagnostics = __toModule(require("@lwrjs/diagnostics"));
31
31
  var import_instrumentation = __toModule(require("@lwrjs/instrumentation"));
32
32
  var import_shared_utils = __toModule(require("@lwrjs/shared-utils"));
33
- var ROUTE_CORE_HEADER = "X-SFDC-Route-Core";
34
33
  var CORE_CLIENTS = new Map();
35
34
  var FetchController = class {
36
35
  constructor(context) {
@@ -72,10 +71,9 @@ var FetchController = class {
72
71
  this.noOpActivated = false;
73
72
  };
74
73
  this.setFetchRequestContext = (context) => {
75
- const {abortController, host, headers, requestDepth, coreProxy} = context;
74
+ const {abortController, host, headers, coreProxy} = context;
76
75
  this.host = host;
77
76
  this.headers = headers;
78
- this.requestDepth = requestDepth;
79
77
  this.coreProxy = coreProxy;
80
78
  this.abortController = abortController;
81
79
  };
@@ -105,19 +103,12 @@ var FetchController = class {
105
103
  });
106
104
  }
107
105
  createFetchEndowment() {
108
- return (request, init) => {
109
- const {host = "", requestDepth = 1, coreProxy} = this;
110
- const origin = coreProxy?.origin && coreProxy.origin.startsWith("http") ? coreProxy.origin : host;
106
+ return (request, init = {}) => {
107
+ const {host: forwardedOrigin = "", coreProxy} = this;
108
+ const origin = coreProxy?.origin && coreProxy.origin.startsWith("http") ? coreProxy.origin : forwardedOrigin;
111
109
  const {finalRequest, finalUrl} = this.getFinalRequest(request, origin);
112
- const finalInit = {
113
- ...init,
114
- headers: {
115
- ...init?.headers,
116
- [import_shared_utils.REQUEST_DEPTH_HEADER]: String(requestDepth)
117
- }
118
- };
119
- if (coreProxy || host && finalUrl.startsWith(host)) {
120
- finalInit.headers[ROUTE_CORE_HEADER] = "true";
110
+ if (coreProxy || forwardedOrigin && finalUrl.startsWith(forwardedOrigin)) {
111
+ init.headers[import_shared_utils.ROUTE_CORE_HEADER] = "true";
121
112
  }
122
113
  const proxyStr = coreProxy ? JSON.stringify(coreProxy) : "none";
123
114
  const hasCookies = this.headers && this.headers.Cookie ? "yes" : "no";
@@ -127,32 +118,39 @@ var FetchController = class {
127
118
  });
128
119
  return (0, import_instrumentation.getTracer)().trace({
129
120
  name: import_instrumentation.ViewSpan.Fetch,
130
- attributes: {url: finalUrl, fetchType: "cdn", coreProxy: proxyStr, hasCookies}
121
+ attributes: {
122
+ url: finalUrl,
123
+ fetchType: "cdn",
124
+ forwardedOrigin,
125
+ coreProxy: proxyStr,
126
+ hasCookies
127
+ }
131
128
  }, (span) => {
132
129
  const addInfoToSpan = (res) => {
133
130
  res.url && span.setAttributes({url: res.url});
134
131
  span.setAttributes({statusCode: res.status});
135
132
  return res;
136
133
  };
134
+ init.headers = {...init.headers, ...(0, import_shared_utils.getTraceHeaders)({}, span)};
137
135
  if (coreProxy) {
138
- return this.fetchWithAgent(finalUrl, finalInit, host, coreProxy, span).then((res) => addInfoToSpan(res)).catch((err) => {
139
- const {finalRequest: cdnRequest, finalUrl: cdnUrl} = this.getFinalRequest(request, host);
136
+ return this.fetchWithAgent(finalUrl, init, forwardedOrigin, coreProxy, span).then((res) => addInfoToSpan(res)).catch((err) => {
137
+ const {finalRequest: cdnRequest, finalUrl: cdnUrl} = this.getFinalRequest(request, forwardedOrigin);
140
138
  import_diagnostics.logger.warn(`Fetching data directly from Core failed, retrying through CDN: ${cdnUrl} Error is: ${err.message || err}`);
141
139
  span.setAttributes({fetchType: "cdnFallback"});
142
- return fetch(cdnRequest, finalInit).then((res) => addInfoToSpan(res));
140
+ return fetch(cdnRequest, init).then((res) => addInfoToSpan(res));
143
141
  });
144
142
  }
145
- return fetch(finalRequest, finalInit).then((res) => addInfoToSpan(res));
143
+ return fetch(finalRequest, init).then((res) => addInfoToSpan(res));
146
144
  });
147
145
  };
148
146
  }
149
- getFinalRequest(request, host) {
147
+ getFinalRequest(request, origin) {
150
148
  let finalRequest;
151
149
  let finalUrl;
152
150
  if (request instanceof Request) {
153
151
  const curUrl = request.url;
154
152
  if (curUrl.startsWith("/")) {
155
- finalUrl = host + curUrl;
153
+ finalUrl = origin + curUrl;
156
154
  finalRequest = new Request(finalUrl, request);
157
155
  } else {
158
156
  finalUrl = curUrl;
@@ -160,20 +158,22 @@ var FetchController = class {
160
158
  }
161
159
  } else {
162
160
  const curUrl = typeof request === "string" ? request : request.toString();
163
- finalRequest = finalUrl = curUrl.startsWith("/") ? host + curUrl : curUrl;
161
+ finalRequest = finalUrl = curUrl.startsWith("/") ? origin + curUrl : curUrl;
164
162
  }
165
163
  return {finalRequest, finalUrl};
166
164
  }
167
- async fetchWithAgent(rawUrl, init, forwardedHost, coreProxy, span) {
165
+ async fetchWithAgent(rawUrl, init, forwardedOrigin, coreProxy, span) {
168
166
  let {origin, servername} = coreProxy;
169
- const host = coreProxy.host ?? forwardedHost.replace(/^https?:\/\//, "");
167
+ const forwardedHostname = (0, import_shared_utils.toHostname)(forwardedOrigin);
168
+ const hostHeader = coreProxy.host ?? forwardedHostname;
170
169
  const ENHANCED_DOMAIN_TLD = ".site.com";
171
170
  const MY_DOMAIN_TLD = ".salesforce.com";
172
- if (forwardedHost.endsWith(ENHANCED_DOMAIN_TLD)) {
173
- origin = forwardedHost.slice(0, -ENHANCED_DOMAIN_TLD.length) + MY_DOMAIN_TLD;
174
- servername = origin;
171
+ if (forwardedHostname.endsWith(ENHANCED_DOMAIN_TLD)) {
172
+ const myHostname = forwardedHostname.slice(0, -ENHANCED_DOMAIN_TLD.length) + MY_DOMAIN_TLD;
173
+ origin = "https://" + myHostname;
174
+ servername = myHostname;
175
175
  } else if (origin.startsWith(".")) {
176
- origin = forwardedHost + origin;
176
+ origin = "https://" + forwardedHostname + origin;
177
177
  }
178
178
  const urlParts = new URL(rawUrl);
179
179
  const path = urlParts.pathname + urlParts.search;
@@ -182,7 +182,7 @@ var FetchController = class {
182
182
  fetchType: "direct",
183
183
  url,
184
184
  coreUrl: url,
185
- coreHostHeader: host,
185
+ coreHostHeader: hostHeader,
186
186
  coreServername: servername
187
187
  });
188
188
  let client = CORE_CLIENTS.get(origin);
@@ -197,7 +197,7 @@ var FetchController = class {
197
197
  ...init,
198
198
  method: init.method || "GET",
199
199
  path,
200
- headers: {...init?.headers, Host: host},
200
+ headers: {...init?.headers, Host: hostHeader},
201
201
  servername
202
202
  }).then(async (res) => {
203
203
  span.setAttributes({coreStatusCode: res.statusCode});
@@ -41,7 +41,7 @@ function createModuleLoader(config, resourceRegistry, bundleRegistry, runtimeEnv
41
41
  }
42
42
  async function createAMDModuleLoader(config, resourceRegistry, bundleRegistry, runtimeEnvironment, runtimeParams, serverData, bootstrapConfig, abortController) {
43
43
  const loaderConfig = (0, import_utils.getLoaderConfig)(BOOTSTRAP_SPECIFIER, config, runtimeParams, serverData);
44
- const {context, controller} = createContext(loaderConfig, runtimeParams, runtimeEnvironment, abortController);
44
+ const {context, controller} = createContext(loaderConfig, runtimeParams, abortController);
45
45
  const contextKeyMap = new Map(Object.keys(context).map((key) => [key, true]));
46
46
  let run;
47
47
  context.LWR.customInit = async (lwr) => {
@@ -218,10 +218,9 @@ function isValidResolveResponse(res) {
218
218
  async function createESMModuleLoader() {
219
219
  throw new Error("ESM support coming soon.");
220
220
  }
221
- function createContext(LWR, runtimeParams, runtimeEnvironment, abortController) {
221
+ function createContext(LWR, runtimeParams, abortController) {
222
222
  const fetchController = new import_fetchController.FetchController({
223
223
  host: runtimeParams.host,
224
- requestDepth: runtimeParams.requestDepth,
225
224
  coreProxy: runtimeParams.coreProxy,
226
225
  abortController
227
226
  });
@@ -87,47 +87,25 @@ var Renderer = class {
87
87
  }
88
88
  async renderComponents(components, route, runtimeEnvironment, runtimeParams, serverData = {}, isFirstOf2PassSSR = false, abortController) {
89
89
  const results = {};
90
- const errors = {};
90
+ const warnings = [];
91
91
  const roots = Object.keys(components);
92
92
  const services = (0, import_utils.getServerBootstrapServices)(route);
93
93
  const reevaluateModules = (0, import_shared_utils.getFeatureFlags)().REEVALUATE_MODULES === true;
94
94
  let loader, bootstrapServiceEvaluationMap;
95
95
  try {
96
96
  let lwcEngine, serverBootstrapServices;
97
- ({bootstrapServiceEvaluationMap, loader, lwcEngine, serverBootstrapServices} = await this.createLoader(components, route, serverData, isFirstOf2PassSSR, services, errors, runtimeEnvironment, runtimeParams, abortController));
97
+ ({bootstrapServiceEvaluationMap, loader, lwcEngine, serverBootstrapServices} = await this.createLoader(components, route, serverData, isFirstOf2PassSSR, services, runtimeEnvironment, runtimeParams, abortController));
98
98
  const componentModules = await this.loadAppCode(components, route, roots, loader);
99
- await this.executeDataServices(components, route, serverBootstrapServices, componentModules, serverData, results, errors, runtimeEnvironment, runtimeParams);
99
+ await this.executeDataServices(components, route, serverBootstrapServices, componentModules, serverData, results, warnings, runtimeEnvironment, runtimeParams);
100
100
  if (!route.bootstrap.ssr) {
101
- if (Object.keys(errors).length) {
102
- return {results, errors};
103
- }
104
- return {results, bundles: loader?.getBundles()};
101
+ return {results, warnings, bundles: loader?.getBundles()};
105
102
  }
106
103
  loader?.getFetchController().enableNoOpFetch();
107
104
  for (const component of componentModules) {
108
- if (errors[component.specifier]) {
109
- continue;
110
- }
111
- const {html, error} = await renderToString(lwcEngine.module, component, results[component.specifier].props);
112
- if (error) {
113
- errors[component.specifier] = error;
114
- continue;
115
- }
105
+ const {html} = await renderToString(lwcEngine.module, component, results[component.specifier].props);
116
106
  results[component.specifier].html = html;
117
107
  }
118
- const bundles = loader?.getBundles();
119
- if (Object.keys(errors).length) {
120
- return {results, errors, bundles};
121
- }
122
- return {results, bundles};
123
- } catch (e) {
124
- const error = Object(e);
125
- return {
126
- errors: {
127
- [roots.join(",")]: error.message ?? (0, import_diagnostics.stringifyError)(e)
128
- },
129
- bundles: loader?.getBundles()
130
- };
108
+ return {results, warnings, bundles: loader?.getBundles()};
131
109
  } finally {
132
110
  loader?.getFetchController().disableNoOpFetch();
133
111
  loader?.getFetchController().enableFetchKillSwitch();
@@ -162,7 +140,7 @@ var Renderer = class {
162
140
  });
163
141
  });
164
142
  }
165
- async executeDataServices(components, route, serverBootstrapServices, componentModules, serverData, results, errors, runtimeEnvironment, runtimeParams) {
143
+ async executeDataServices(components, route, serverBootstrapServices, componentModules, serverData, results, warnings, runtimeEnvironment, runtimeParams) {
166
144
  return (0, import_instrumentation.getTracer)().trace({
167
145
  name: import_instrumentation.ViewSpan.ExecuteServices,
168
146
  attributes: {
@@ -189,21 +167,18 @@ var Renderer = class {
189
167
  basePath: runtimeParams.basePath || runtimeEnvironment.basePath,
190
168
  crossRequestCache: this.globalCache
191
169
  };
192
- const {data, error} = await getServerData(component, context, serverData);
193
- if (error) {
194
- errors[component.specifier] = error;
195
- continue;
196
- }
170
+ const data = await getServerData(component, context, serverData);
197
171
  if (data) {
198
172
  results[component.specifier] = data;
199
173
  }
174
+ data.warnings && warnings.push(...data.warnings);
200
175
  }
201
176
  if (serverBootstrapServices) {
202
177
  serverBootstrapServices.evaluateServerDataHooks(serverData);
203
178
  }
204
179
  });
205
180
  }
206
- async createLoader(components, route, serverData, isFirstOf2PassSSR, services, errors, runtimeEnvironment, runtimeParams, abortController) {
181
+ async createLoader(components, route, serverData, isFirstOf2PassSSR, services, runtimeEnvironment, runtimeParams, abortController) {
207
182
  return (0, import_instrumentation.getTracer)().trace({
208
183
  name: import_instrumentation.ViewSpan.CreateLoader,
209
184
  attributes: {
@@ -232,10 +207,7 @@ var Renderer = class {
232
207
  const serviceModules = await Promise.all(services.map((specifier) => loader?.load(specifier)));
233
208
  serverBootstrapServices = (0, import_serverBootstrapServices.createServerBootstrapServices)(loader);
234
209
  for (const service of serviceModules) {
235
- const error = await (0, import_serverBootstrapServices.evaluateServerBootstrapModule)(service, serverBootstrapServices.serviceAPI);
236
- if (error) {
237
- errors[service.specifier] = error;
238
- }
210
+ await (0, import_serverBootstrapServices.evaluateServerBootstrapModule)(service, serverBootstrapServices.serviceAPI);
239
211
  }
240
212
  }
241
213
  const ret = {
@@ -257,13 +229,13 @@ var Renderer = class {
257
229
  }
258
230
  resetFetchController(fetchController, runtimeParams, route, abortController) {
259
231
  fetchController.disableFetchKillSwitch();
232
+ const baseHeaders = {
233
+ [import_shared_utils.REQUEST_DEPTH_HEADER]: runtimeParams.requestDepth ?? "0",
234
+ ...(0, import_shared_utils.getTraceHeaders)(runtimeParams)
235
+ };
260
236
  fetchController.setFetchRequestContext({
261
237
  host: runtimeParams.host,
262
- requestDepth: runtimeParams.requestDepth,
263
- headers: route.bootstrap.includeCookiesForSSR ? {
264
- Cookie: runtimeParams.cookie,
265
- "True-Client-IP": runtimeParams.trueClientIP
266
- } : {"True-Client-IP": runtimeParams.trueClientIP},
238
+ headers: route.bootstrap.includeCookiesForSSR ? {Cookie: runtimeParams.cookie, ...baseHeaders} : baseHeaders,
267
239
  coreProxy: runtimeParams.coreProxy,
268
240
  abortController
269
241
  });
@@ -299,30 +271,41 @@ function getServerData(component, context, serverData) {
299
271
  try {
300
272
  const data = await component.module.getServerData(context);
301
273
  Object.assign(serverData, data.props);
302
- return {data};
274
+ const dataRes = data;
275
+ if (dataRes.status) {
276
+ const {code, location} = dataRes.status;
277
+ throw new import_diagnostics.LwrStatusError(void 0, code, location ? {location} : void 0);
278
+ }
279
+ return data;
303
280
  } catch (e) {
304
- const message = `Error in "getServerData" for "${component.specifier}": ${(0, import_diagnostics.stringifyError)(e)}`;
305
- import_diagnostics.logger.error(message);
306
- return {error: message};
281
+ if (e instanceof import_diagnostics.LwrError)
282
+ throw e;
283
+ const statusError = e;
284
+ if (typeof statusError.status === "number") {
285
+ throw new import_diagnostics.LwrStatusError(statusError.message, statusError.status, statusError.headers);
286
+ }
287
+ throw new import_diagnostics.LwrApplicationError(`Error in "getServerData" for "${component.specifier}": ${(0, import_diagnostics.stringifyError)(e)}`);
307
288
  }
308
289
  });
309
290
  }
310
291
  async function renderToString(engine, component, props) {
292
+ const isSSRv2 = (0, import_shared_utils.getFeatureFlags)().SSR_COMPILER_ENABLED || false;
311
293
  return (0, import_instrumentation.getTracer)().trace({
312
294
  name: import_instrumentation.ViewSpan.RenderComponent,
313
- attributes: {specifier: component.specifier}
295
+ attributes: {specifier: component.specifier, isSSRv2}
314
296
  }, async () => {
315
297
  try {
316
298
  const elementName = (0, import_shared_utils.moduleSpecifierToKebabCase)(component.specifier);
317
299
  const moduleDefault = component.module.default;
318
- const html = (0, import_shared_utils.getFeatureFlags)().SSR_COMPILER_ENABLED ? await engine.renderComponent(elementName, moduleDefault, props, "sync") : engine.renderComponent(elementName, moduleDefault, props);
300
+ const html = isSSRv2 ? await engine.renderComponent(elementName, moduleDefault, props, "sync") : engine.renderComponent(elementName, moduleDefault, props);
319
301
  return {html};
320
302
  } catch (e) {
303
+ if (e instanceof import_diagnostics.LwrError)
304
+ throw e;
321
305
  const error = Object(e);
322
306
  const message = error.message ?? (0, import_diagnostics.stringifyError)(e);
323
307
  const detailedMessage = error.wcStack ? "An error occurred during server-side rendering for component stack: " + error.wcStack + ". Error was: " + message : `An error occurred during server-side rendering "${component.specifier}": ` + message;
324
- import_diagnostics.logger.error(detailedMessage);
325
- return {error: detailedMessage};
308
+ throw new import_diagnostics.LwrApplicationError(detailedMessage);
326
309
  }
327
310
  });
328
311
  }
@@ -76,9 +76,9 @@ function evaluateServerBootstrapModule(serviceModule, serviceApi) {
76
76
  try {
77
77
  await serviceModule.module.default(serviceApi);
78
78
  } catch (e) {
79
- const message = `An SSR error occurred in bootstrap service "${serviceModule.specifier}": ${(0, import_diagnostics.stringifyError)(e)}`;
80
- import_diagnostics.logger.error(message);
81
- return message;
79
+ if (e instanceof import_diagnostics.LwrError)
80
+ throw e;
81
+ throw new import_diagnostics.LwrApplicationError(`An SSR error occurred in bootstrap service "${serviceModule.specifier}": ${(0, import_diagnostics.stringifyError)(e)}`);
82
82
  }
83
83
  });
84
84
  }
@@ -25,18 +25,14 @@ var __toModule = (module2) => {
25
25
  __markAsModule(exports);
26
26
  __export(exports, {
27
27
  SSR_PROPS_ATTR: () => SSR_PROPS_ATTR,
28
- addHeadMarkup: () => addHeadMarkup,
29
- createHeadMarkup: () => createHeadMarkup,
30
- createSsrErrorMarkup: () => createSsrErrorMarkup,
31
- createSsrErrorMessage: () => createSsrErrorMessage,
32
28
  getLoaderConfig: () => getLoaderConfig,
33
29
  getLoaderId: () => getLoaderId,
34
30
  getLoaderShim: () => getLoaderShim,
35
31
  getPropsId: () => getPropsId,
36
32
  getRenderTimeout: () => getRenderTimeout,
37
- getServerBootstrapServices: () => getServerBootstrapServices
33
+ getServerBootstrapServices: () => getServerBootstrapServices,
34
+ mergeWarnings: () => mergeWarnings
38
35
  });
39
- var import_diagnostics = __toModule(require("@lwrjs/diagnostics"));
40
36
  var import_shared_utils = __toModule(require("@lwrjs/shared-utils"));
41
37
  var DEFAULT_SSR_TIMEOUT = 5e3;
42
38
  var SSR_PROPS_ATTR = "data-lwr-props-id";
@@ -47,18 +43,6 @@ function getRenderTimeout() {
47
43
  const override = process.env.SSR_TIMEOUT;
48
44
  return override ? Number.parseInt(override) : DEFAULT_SSR_TIMEOUT;
49
45
  }
50
- function createSsrErrorMessage(specifier, e, fallback = true) {
51
- const fallbackMsg = fallback ? " Falling back to client-side rendering." : "";
52
- return `Server-side rendering for "${specifier}" failed.${fallbackMsg} Reason: ${(0, import_diagnostics.stringifyError)(e)}`;
53
- }
54
- function createSsrErrorMarkup(errors, basePath) {
55
- 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>';
56
- Object.entries(errors).forEach(([specifier, reason]) => {
57
- markup += `<li><strong>${specifier}</strong>: ${(0, import_diagnostics.stringifyError)(reason)}</li>`;
58
- });
59
- markup += `</ul><p style="padding-top:1em;">See more information in the browser console. Contact your administrator for assistance.</p></div>`;
60
- return markup;
61
- }
62
46
  async function getLoaderShim(resourceRegistry, runtimeEnvironment, bootstrapConfig) {
63
47
  const {debug} = runtimeEnvironment;
64
48
  const useDebug = debug && !(0, import_shared_utils.isLambdaEnv)();
@@ -124,52 +108,12 @@ function getServerBootstrapServices(route) {
124
108
  return acc;
125
109
  }, []);
126
110
  }
127
- function createMetaTags(meta) {
128
- return meta.reduce((metaStr, {name, content, httpEquiv}) => {
129
- if (!name && !content && !httpEquiv)
130
- return metaStr;
131
- const nameStr = name ? ` name="${name}"` : "", httpEquivStr = httpEquiv ? ` http-equiv="${httpEquiv}"` : "", contentStr = content ? ` content="${content}"` : "";
132
- return metaStr + `<meta${nameStr}${httpEquivStr}${contentStr}>
133
- `;
134
- }, "");
135
- }
136
- function createScriptTags(scripts) {
137
- return scripts.reduce((scriptStr, {body}) => scriptStr + `<script type="application/ld+json">${body}</script>
138
- `, "");
139
- }
140
- function createLinkTags(links) {
141
- return links.reduce((linkStr, {href, rel, as, fetchpriority}) => {
142
- const relStr = rel ? ` rel="${rel}"` : "", asStr = as ? ` as="${as}"` : "", fetchStr = fetchpriority ? ` fetchpriority="${fetchpriority}"` : "";
143
- return linkStr + `<link href="${href}"${relStr}${asStr}${fetchStr}>
144
- `;
145
- }, "");
146
- }
147
- function createStyleTags(styles) {
148
- return styles.reduce((styleStr, {body, id}) => {
149
- const idStr = id ? ` id="${id}"` : "";
150
- return styleStr + `<style type="text/css"${idStr}>${body}</style>
151
- `;
152
- }, "");
153
- }
154
- function createHeadMarkup(results) {
155
- let hasTitle = false;
156
- return results.reduce((str, {markup: {title, scripts = [], meta = [], links = [], styles = []} = {}}) => {
157
- if (title && !hasTitle) {
158
- hasTitle = true;
159
- str += `<title>${title}</title>
160
- `;
161
- }
162
- return str + createMetaTags(meta) + createScriptTags(scripts) + createLinkTags(links) + createStyleTags(styles);
163
- }, "");
164
- }
165
- function addHeadMarkup(results, stringBuilder) {
166
- const headMarkup = createHeadMarkup(Object.values(results));
167
- if (headMarkup) {
168
- const headIndex = stringBuilder.original.indexOf("</head>");
169
- if (headIndex >= 0) {
170
- stringBuilder.prependLeft(headIndex, headMarkup);
171
- } else {
172
- import_diagnostics.logger.error("Adding markup during server-side rendering failed. Could not find the </head> tag.");
173
- }
111
+ function mergeWarnings(metadata, warnings = []) {
112
+ if (!warnings.length)
113
+ return;
114
+ if (!metadata.serverDebug) {
115
+ metadata.serverDebug = {};
174
116
  }
117
+ metadata.serverDebug.warnings = metadata.serverDebug.warnings || [];
118
+ metadata.serverDebug.warnings.push(...warnings);
175
119
  }
@@ -30,7 +30,6 @@ var import_base_view_provider = __toModule(require("@lwrjs/base-view-provider"))
30
30
  var import_diagnostics = __toModule(require("@lwrjs/diagnostics"));
31
31
  var import_instrumentation = __toModule(require("@lwrjs/instrumentation"));
32
32
  var import_shared_utils = __toModule(require("@lwrjs/shared-utils"));
33
- var import_utils = __toModule(require("../utils.cjs"));
34
33
  var import_renderer = __toModule(require("../renderer.cjs"));
35
34
  var LwcViewProvider = class extends import_base_view_provider.default {
36
35
  constructor(_pluginConfig, providerConfig) {
@@ -59,56 +58,41 @@ var LwcViewProvider = class extends import_base_view_provider.default {
59
58
  filePath: specifier,
60
59
  viewId,
61
60
  properties: viewProperties,
62
- render: async (runtimeParams, runtimeEnvironment) => {
61
+ render: async (context, runtimeEnvironment) => {
63
62
  const {config, moduleBundler, resourceRegistry} = this;
64
- const {debug} = runtimeEnvironment;
65
63
  const element = (0, import_shared_utils.moduleSpecifierToKebabCase)(specifier);
66
64
  return (0, import_instrumentation.getTracer)().trace({
67
65
  name: import_instrumentation.ViewSpan.RenderPage,
68
66
  attributes: {specifier}
69
67
  }, async () => {
70
- const route = this.routes.find((r) => r.id === viewId.id);
71
- if (!route) {
72
- throw new Error(`Unable to resolve configuration for view: ${viewId.id}`);
73
- }
74
- const {
75
- results = {},
76
- errors,
77
- bundles
78
- } = await (0, import_renderer.getRenderer)(config, moduleBundler, resourceRegistry).render({[specifier]: {specifier, props: {}}}, route, runtimeEnvironment, Object(runtimeParams), void 0, true);
79
- if (errors) {
80
- const errorString = Object.values(errors).join(", ");
81
- if (!debug || (0, import_shared_utils.isLocalDev)() && process.env.SSR_THROW_ERRORS === "true") {
82
- throw new import_diagnostics.LwrApplicationError(import_diagnostics.descriptions.APPLICATION.SSR_ERROR(specifier, errorString));
68
+ try {
69
+ const route = this.routes.find((r) => r.id === viewId.id);
70
+ if (!route) {
71
+ throw new Error(`Unable to resolve configuration for view: ${viewId.id}`);
72
+ }
73
+ const {results = {}, bundles} = await (0, import_renderer.getRenderer)(config, moduleBundler, resourceRegistry).render({[specifier]: {specifier, props: {}}}, route, runtimeEnvironment, context.runtimeParams, void 0, true);
74
+ const {html, props, markup, cache, warnings} = results[specifier] || {};
75
+ if (!html) {
76
+ throw new Error("Failed to render content template component");
83
77
  }
84
- const message = (0, import_utils.createSsrErrorMessage)(specifier, errorString, false);
85
- import_diagnostics.logger.warn(message, errors[specifier]);
78
+ if (markup)
79
+ viewProperties.serverHeadMarkup = (0, import_shared_utils.createHeadMarkup)([markup]);
86
80
  return {
87
- renderedView: (0, import_utils.createSsrErrorMarkup)(errors, this.runtimeEnvironment.basePath),
81
+ renderedView: html.replace(`<${element}`, `<${element} lwc:external`),
88
82
  metadata: {
89
- serverDebug: {message: debug ? message : void 0},
83
+ serverData: props,
90
84
  customElements: [],
91
- assetReferences: []
92
- }
85
+ assetReferences: [],
86
+ serverBundles: bundles,
87
+ serverDebug: {warnings}
88
+ },
89
+ cache
93
90
  };
91
+ } catch (e) {
92
+ if (e instanceof import_diagnostics.LwrError)
93
+ throw e;
94
+ throw new import_diagnostics.LwrApplicationError(import_diagnostics.descriptions.APPLICATION.SSR_ERROR(specifier, (0, import_diagnostics.stringifyError)(e)));
94
95
  }
95
- const {html, props, markup, cache, status} = results[specifier];
96
- if (!html) {
97
- throw new Error(`Failed to render content template component '${specifier}'`);
98
- }
99
- if (markup)
100
- viewProperties.serverHeadMarkup = (0, import_utils.createHeadMarkup)([results[specifier]]);
101
- return {
102
- renderedView: html.replace(`<${element}`, `<${element} lwc:external`),
103
- metadata: {
104
- serverData: props,
105
- customElements: [],
106
- assetReferences: [],
107
- serverBundles: bundles
108
- },
109
- cache,
110
- status
111
- };
112
96
  });
113
97
  }
114
98
  };