@lwrjs/core 0.5.11 → 0.6.0-alpha.12

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.
@@ -24,122 +24,15 @@ var __toModule = (module2) => {
24
24
  // packages/@lwrjs/core/src/tools/static-generation.ts
25
25
  __markAsModule(exports);
26
26
  __export(exports, {
27
+ ViewImportMetadataImpl: () => ViewImportMetadataImpl,
27
28
  default: () => static_generation_default
28
29
  });
30
+ var import_shared_utils = __toModule(require("@lwrjs/shared-utils"));
29
31
  var import_path = __toModule(require("path"));
30
32
  var import_fs_extra = __toModule(require("fs-extra"));
31
33
  var import_stream = __toModule(require("./utils/stream.cjs"));
32
34
  var import_dir = __toModule(require("./utils/dir.cjs"));
33
35
  var SiteGenerator = class {
34
- async dispatchResourceRecursive(url, dispatcher, resourceOpts, siteConfig) {
35
- const {outputDir, visitedUrls} = siteConfig;
36
- if (!visitedUrls.has(url)) {
37
- visitedUrls.add(url);
38
- if (url.indexOf("/:") !== -1) {
39
- console.error("Skipped url with variable path segment: " + url);
40
- return;
41
- }
42
- const context = await dispatcher.dispatchUrl(url, "GET", siteConfig.locale);
43
- const {resourceType} = resourceOpts;
44
- if (resourceType === "route") {
45
- const dir = (0, import_dir.createResourceDir)(url, outputDir);
46
- const localeDir = (0, import_dir.createResourceDir)(url, (0, import_path.join)(outputDir, siteConfig.locale));
47
- const filePath = (0, import_path.join)(dir, "index.html");
48
- const fileLocalePath = (0, import_path.join)(localeDir, "index.html");
49
- if (siteConfig.locale.toLowerCase().startsWith("en")) {
50
- await (0, import_stream.writeResponse)(context, filePath);
51
- }
52
- (0, import_dir.createDir)(localeDir);
53
- await (0, import_stream.writeResponse)(context, fileLocalePath);
54
- const viewDefinition = context.fs?.metadata?.viewDefinition;
55
- if (viewDefinition) {
56
- const assets = viewDefinition.viewRecord.assetReferences || [];
57
- for (const asset of assets) {
58
- const assetUrl = asset.override?.uri || asset.url;
59
- if (assetUrl && !assetUrl.startsWith("data:")) {
60
- await this.dispatchResourceRecursive(assetUrl, dispatcher, {resourceType: "asset", asset}, siteConfig);
61
- }
62
- }
63
- const customElements = viewDefinition.viewRecord.customElements || [];
64
- for (const customElement of customElements) {
65
- const jsUris = Object.values(customElement.flatGraph.uriMap);
66
- for (const jsUri of jsUris) {
67
- await this.dispatchResourceRecursive(jsUri, dispatcher, {resourceType: "js"}, siteConfig);
68
- }
69
- }
70
- if (viewDefinition.viewRecord.bootstrapModule) {
71
- const boot = viewDefinition.viewRecord.bootstrapModule;
72
- const jsUris = Object.values(boot.flatGraph.uriMap);
73
- for (const jsUri of jsUris) {
74
- await this.dispatchResourceRecursive(jsUri, dispatcher, {resourceType: "js"}, siteConfig);
75
- }
76
- }
77
- const bootstrapResources = viewDefinition.viewRecord.bootstrapModule?.resources || [];
78
- for (const resource of bootstrapResources) {
79
- if (!resource.inline) {
80
- const resourceUri = resource.src || resource.specifier;
81
- if (resourceUri) {
82
- await this.dispatchResourceRecursive(resourceUri, dispatcher, {resourceType: "resource"}, siteConfig);
83
- } else {
84
- console.warn("Skipped inline bootstrap resource: %j", resource);
85
- }
86
- }
87
- }
88
- const resources = viewDefinition.viewRecord.resources || [];
89
- for (const resource of resources) {
90
- const resourceUri = resource.src || resource.specifier || "";
91
- if (resourceUri.startsWith("/")) {
92
- await this.dispatchResourceRecursive(resourceUri, dispatcher, {resourceType: "resource"}, siteConfig);
93
- } else {
94
- console.warn("Skipped resource: %j", resource);
95
- }
96
- }
97
- }
98
- } else if (resourceType === "asset" || resourceType === "resource") {
99
- const normalizedUrl = decodeURIComponent(url);
100
- (0, import_dir.createResourceDir)((0, import_path.dirname)(normalizedUrl), outputDir);
101
- const fullPath = (0, import_path.join)(outputDir, normalizedUrl);
102
- await (0, import_stream.writeResponse)(context, fullPath);
103
- } else if (resourceType === "js") {
104
- const normalizedUrl = decodeURIComponent(url);
105
- (0, import_dir.createResourceDir)((0, import_path.dirname)(normalizedUrl), outputDir);
106
- const ext = (0, import_path.extname)(normalizedUrl);
107
- const fullPath = (0, import_path.join)(outputDir, `${normalizedUrl}${ext ? "" : ".js"}`);
108
- await (0, import_stream.writeResponse)(context, fullPath);
109
- if (normalizedUrl.indexOf("/s/") !== -1) {
110
- const rewriteUrl = normalizedUrl.substring(0, normalizedUrl.indexOf("/s/"));
111
- siteConfig.urlRewriteMap.set(rewriteUrl, normalizedUrl);
112
- siteConfig.urlRewriteMap.set(url.substring(0, url.indexOf("/s/")), normalizedUrl);
113
- }
114
- const moduleDefinition = context.fs?.metadata.moduleDefinition;
115
- if (moduleDefinition) {
116
- const imports = moduleDefinition.linkedModuleRecord?.imports || moduleDefinition.bundleRecord?.imports || [];
117
- for (const importModule of imports) {
118
- const jsUri = importModule.specifier;
119
- if (jsUri.startsWith("/")) {
120
- await this.dispatchResourceRecursive(jsUri, dispatcher, {resourceType: "js"}, siteConfig);
121
- } else {
122
- if (jsUri !== "lwc")
123
- console.warn("Skipped import: " + jsUri);
124
- }
125
- }
126
- const dynamicImports = moduleDefinition.linkedModuleRecord?.dynamicImports || moduleDefinition.bundleRecord?.dynamicImports || [];
127
- for (const importModule of dynamicImports) {
128
- const jsUri = importModule.specifier;
129
- if (jsUri.startsWith("/")) {
130
- await this.dispatchResourceRecursive(jsUri, dispatcher, {resourceType: "js"}, siteConfig);
131
- } else {
132
- console.warn("Skipped dynamic import: " + jsUri);
133
- }
134
- }
135
- }
136
- const uris = context.fs?.metadata.resolvedUris || [];
137
- for (const jsUri of uris) {
138
- await this.dispatchResourceRecursive(jsUri, dispatcher, {resourceType: "js"}, siteConfig);
139
- }
140
- }
141
- }
142
- }
143
36
  async buildStaticApplication(config, dispatcher) {
144
37
  console.log("[Static Generation] starting");
145
38
  const {routes, staticSiteGenerator, rootDir, assets} = config;
@@ -147,9 +40,11 @@ var SiteGenerator = class {
147
40
  staticSiteGenerator.outputDir = "__generated_site__";
148
41
  }
149
42
  const outputDir = (0, import_path.join)(rootDir, staticSiteGenerator.outputDir);
43
+ console.log(`[INFO] Clear Output Location: ${outputDir}`);
44
+ import_fs_extra.default.rmSync(outputDir, {recursive: true, force: true});
150
45
  const urlRewriteMap = new Map();
151
46
  await this.generateRoutes(staticSiteGenerator, routes, dispatcher, outputDir, urlRewriteMap);
152
- this.writeUrlMappings(outputDir, urlRewriteMap);
47
+ this.writeNetlifyRedirectConfig(outputDir, urlRewriteMap);
153
48
  this.copyAssets(assets, outputDir);
154
49
  console.log("[Static Generation] complete");
155
50
  }
@@ -157,19 +52,203 @@ var SiteGenerator = class {
157
52
  if (!staticSiteGenerator.locales) {
158
53
  staticSiteGenerator.locales = ["en-US"];
159
54
  }
55
+ const dispatchRequests = [];
56
+ const generateUrl = this.createGenerateURLFunction(dispatcher);
160
57
  for (const locale of staticSiteGenerator.locales) {
161
- const visitedUrls = new Set();
162
58
  for (const route of routes) {
163
- await this.dispatchResourceRecursive(route.path, dispatcher, {resourceType: "route"}, {outputDir, visitedUrls, locale, urlRewriteMap});
59
+ const siteConfig = this.createSiteConfig(outputDir, locale, urlRewriteMap);
60
+ dispatchRequests.push(generateUrl(route.path, siteConfig));
164
61
  }
165
62
  if (staticSiteGenerator._additionalRoutePaths) {
166
63
  for (const uri of staticSiteGenerator._additionalRoutePaths) {
167
- await this.dispatchResourceRecursive(uri, dispatcher, {resourceType: "route"}, {outputDir, visitedUrls, locale, urlRewriteMap});
64
+ const siteConfig = this.createSiteConfig(outputDir, locale, urlRewriteMap);
65
+ dispatchRequests.push(generateUrl(uri, siteConfig));
168
66
  }
169
67
  }
170
68
  }
69
+ await Promise.all(dispatchRequests);
70
+ }
71
+ createGenerateURLFunction(dispatcher) {
72
+ const generateRoute = async (uri, siteConfig) => {
73
+ const locale = siteConfig.locale;
74
+ console.log(`[INFO] Start Generate: ${locale} ${uri}`);
75
+ await this.dispatchResourceRecursive(uri, dispatcher, {resourceType: "route"}, siteConfig);
76
+ this.addAdditionalImportMetadataToViewConfig(siteConfig);
77
+ console.log(`[INFO] End Generate ${locale} ${uri}`);
78
+ };
79
+ return generateRoute.bind(this);
171
80
  }
172
- writeUrlMappings(outputDir, urlRewriteMap) {
81
+ async dispatchResourceRecursive(url, dispatcher, resourceOpts, siteConfig) {
82
+ const {visitedUrls} = siteConfig;
83
+ if (!visitedUrls.has(url)) {
84
+ visitedUrls.add(url);
85
+ if (url.indexOf("/:") !== -1) {
86
+ console.error("Skipped url with variable path segment: " + url);
87
+ return;
88
+ }
89
+ const context = await dispatcher.dispatchUrl(url, "GET", siteConfig.locale);
90
+ const {resourceType} = resourceOpts;
91
+ if (resourceType === "route") {
92
+ await this.handleHtmlResource(url, context, siteConfig, dispatcher);
93
+ } else if (resourceType === "asset" || resourceType === "resource") {
94
+ await this.handleAssetOrResource(url, context, siteConfig);
95
+ } else if (resourceType == "mapping") {
96
+ await this.handleMappingResource(url, context, siteConfig, dispatcher);
97
+ } else if (resourceType === "js") {
98
+ await this.handleJavascriptResource(url, context, siteConfig, dispatcher);
99
+ }
100
+ }
101
+ }
102
+ async handleJavascriptResource(url, context, siteConfig, dispatcher) {
103
+ const {outputDir} = siteConfig;
104
+ const normalizedUrl = decodeURIComponent(url);
105
+ (0, import_dir.createResourceDir)((0, import_path.dirname)(normalizedUrl), outputDir);
106
+ const ext = (0, import_path.extname)(normalizedUrl);
107
+ const fullPath = (0, import_path.join)(outputDir, `${normalizedUrl}${ext ? "" : ".js"}`);
108
+ await (0, import_stream.writeResponse)(context, fullPath);
109
+ const dispatchRequests = [];
110
+ if (normalizedUrl.indexOf("/s/") !== -1) {
111
+ const rewriteUrl = normalizedUrl.substring(0, normalizedUrl.indexOf("/s/"));
112
+ siteConfig.urlRewriteMap.set(rewriteUrl, normalizedUrl);
113
+ siteConfig.urlRewriteMap.set(url.substring(0, url.indexOf("/s/")), normalizedUrl);
114
+ }
115
+ const moduleDefinition = context.fs?.metadata?.moduleDefinition;
116
+ if (moduleDefinition) {
117
+ const imports = moduleDefinition.linkedModuleRecord?.imports || moduleDefinition.bundleRecord?.imports || [];
118
+ for (const importModule of imports) {
119
+ const jsUri = (0, import_shared_utils.getSpecifier)(importModule);
120
+ dispatchRequests.push(this.dispatchJSResourceRecursive(jsUri, dispatcher, siteConfig));
121
+ }
122
+ const dynamicImports = moduleDefinition.linkedModuleRecord?.dynamicImports || moduleDefinition.bundleRecord?.dynamicImports || [];
123
+ for (const importModule of dynamicImports) {
124
+ const jsUri = (0, import_shared_utils.getSpecifier)(importModule);
125
+ dispatchRequests.push(this.dispatchJSResourceRecursive(jsUri, dispatcher, siteConfig));
126
+ }
127
+ }
128
+ const uris = context.fs?.metadata?.resolvedUris || [];
129
+ for (const jsUri of uris) {
130
+ dispatchRequests.push(this.dispatchJSResourceRecursive(jsUri, dispatcher, siteConfig));
131
+ }
132
+ await Promise.all(dispatchRequests);
133
+ }
134
+ async handleMappingResource(url, context, siteConfig, dispatcher) {
135
+ const {importMetadata: importMetatdata} = siteConfig;
136
+ const statusCode = context.response?.status;
137
+ if (statusCode === 200) {
138
+ const newImportMetadata = context.fs?.body;
139
+ if (!importMetatdata) {
140
+ console.warn("[WARN] Import metadata collector was never initialized");
141
+ return;
142
+ }
143
+ const filteredImportMetadata = importMetatdata.addAdditionalMetadata(newImportMetadata);
144
+ const dispatchRequests = [];
145
+ for (const uri of Object.keys(filteredImportMetadata.imports)) {
146
+ dispatchRequests.push(this.dispatchResourceRecursive(uri, dispatcher, {resourceType: "js"}, siteConfig));
147
+ }
148
+ await Promise.all(dispatchRequests);
149
+ } else {
150
+ const body = context.fs?.body;
151
+ console.warn(`[WARN] Failed to fetch ${url}: (${statusCode}) ${body}`);
152
+ }
153
+ }
154
+ async handleHtmlResource(url, context, siteConfig, dispatcher) {
155
+ const {outputDir} = siteConfig;
156
+ const dir = (0, import_dir.createResourceDir)(url, outputDir);
157
+ const localeDir = (0, import_dir.createResourceDir)(url, (0, import_path.join)(outputDir, siteConfig.locale));
158
+ const filePath = (0, import_path.join)(dir, "index.html");
159
+ const fileLocalePath = (0, import_path.join)(localeDir, "index.html");
160
+ if (siteConfig.locale.toLowerCase().startsWith("en")) {
161
+ await (0, import_stream.writeResponse)(context, filePath);
162
+ }
163
+ (0, import_dir.createDir)(localeDir);
164
+ await (0, import_stream.writeResponse)(context, fileLocalePath);
165
+ const viewDefinition = context.fs?.metadata?.viewDefinition;
166
+ if (viewDefinition) {
167
+ await this.handleViewDefinition(viewDefinition, siteConfig, dispatcher);
168
+ }
169
+ }
170
+ async handleViewDefinition(viewDefinition, siteConfig, dispatcher) {
171
+ siteConfig.endpoints = viewDefinition.viewRecord.endpoints;
172
+ if (viewDefinition.viewRecord.importMetadata) {
173
+ siteConfig.importMetadata = new ViewImportMetadataImpl(viewDefinition.viewRecord.importMetadata);
174
+ }
175
+ const dispatchRequests = [];
176
+ const assets = viewDefinition.viewRecord.assetReferences || [];
177
+ for (const asset of assets) {
178
+ const assetUrl = asset.override?.uri || asset.url;
179
+ if (assetUrl && !assetUrl.startsWith("data:")) {
180
+ dispatchRequests.push(this.dispatchResourceRecursive(assetUrl, dispatcher, {resourceType: "asset", asset}, siteConfig));
181
+ }
182
+ }
183
+ const customElements = viewDefinition.viewRecord.customElements || [];
184
+ for (const customElement of customElements) {
185
+ const jsUris = Object.values(customElement.flatGraph.uriMap);
186
+ for (const jsUri of jsUris) {
187
+ dispatchRequests.push(this.dispatchJSResourceRecursive(jsUri, dispatcher, siteConfig));
188
+ }
189
+ }
190
+ if (viewDefinition.viewRecord.bootstrapModule) {
191
+ const boot = viewDefinition.viewRecord.bootstrapModule;
192
+ const jsUris = Object.values(boot.flatGraph.uriMap);
193
+ for (const jsUri of jsUris) {
194
+ dispatchRequests.push(this.dispatchJSResourceRecursive(jsUri, dispatcher, siteConfig));
195
+ }
196
+ }
197
+ const bootstrapResources = viewDefinition.viewRecord.bootstrapModule?.resources || [];
198
+ for (const resource of bootstrapResources) {
199
+ if (!resource.inline) {
200
+ const resourceUri = resource.src || resource.specifier;
201
+ if (resourceUri) {
202
+ dispatchRequests.push(this.dispatchResourceRecursive(resourceUri, dispatcher, {resourceType: "resource"}, siteConfig));
203
+ if (resourceUri.match(/\/application\/.*\/ai\/.*\/configuration/)) {
204
+ siteConfig.viewConfigPath = this.getResourcePathFromUrl(siteConfig, resourceUri);
205
+ }
206
+ } else {
207
+ console.warn("Skipped inline bootstrap resource: %j", resource);
208
+ }
209
+ }
210
+ }
211
+ const resources = viewDefinition.viewRecord.resources || [];
212
+ for (const resource of resources) {
213
+ const resourceUri = resource.src || resource.specifier || "";
214
+ if (resourceUri.startsWith("/")) {
215
+ dispatchRequests.push(this.dispatchResourceRecursive(resourceUri, dispatcher, {resourceType: "resource"}, siteConfig));
216
+ } else {
217
+ console.warn("Skipped resource: %j", resource);
218
+ }
219
+ }
220
+ await Promise.all(dispatchRequests);
221
+ }
222
+ async dispatchJSResourceRecursive(jsUri, dispatcher, siteConfig) {
223
+ if (jsUri.startsWith("/")) {
224
+ await this.dispatchResourceRecursive(jsUri, dispatcher, {resourceType: "js"}, siteConfig);
225
+ } else {
226
+ const supportsFingerprints = siteConfig.experimentalFeatures?.ENABLE_FINGERPRINTS;
227
+ if (supportsFingerprints) {
228
+ const mappingEndpoint = siteConfig.endpoints?.uris?.mapping;
229
+ if (mappingEndpoint) {
230
+ const mappingURL = siteConfig.endpoints?.uris?.mapping + encodeURIComponent(jsUri);
231
+ await this.dispatchResourceRecursive(mappingURL, dispatcher, {resourceType: "mapping"}, siteConfig);
232
+ } else {
233
+ console.warn('[WARN] Unable to fetch mapping for bare specifier or variable dynamic import: "' + jsUri + '"');
234
+ }
235
+ } else {
236
+ console.warn('[WARN] Unable to resolve bare specifier or variable dynamic import: "' + jsUri + '"');
237
+ }
238
+ }
239
+ }
240
+ async handleAssetOrResource(url, context, siteConfig) {
241
+ const fullPath = this.getResourcePathFromUrl(siteConfig, url);
242
+ await (0, import_stream.writeResponse)(context, fullPath);
243
+ }
244
+ getResourcePathFromUrl(siteConfig, url) {
245
+ const {outputDir} = siteConfig;
246
+ const normalizedUrl = decodeURIComponent(url);
247
+ (0, import_dir.createResourceDir)((0, import_path.dirname)(normalizedUrl), outputDir);
248
+ const fullPath = (0, import_path.join)(outputDir, normalizedUrl);
249
+ return fullPath;
250
+ }
251
+ writeNetlifyRedirectConfig(outputDir, urlRewriteMap) {
173
252
  const serveJsonPath = (0, import_path.join)(outputDir, "serve.json");
174
253
  const _redirectsPath = (0, import_path.join)(outputDir, "_redirects");
175
254
  if (import_fs_extra.default.existsSync(_redirectsPath)) {
@@ -202,5 +281,71 @@ var SiteGenerator = class {
202
281
  }
203
282
  }
204
283
  }
284
+ createSiteConfig(outputDir, locale, urlRewriteMap) {
285
+ const experimentalFeatures = this.filterExperimentalFeatures();
286
+ return {
287
+ outputDir,
288
+ visitedUrls: new Set(),
289
+ locale,
290
+ urlRewriteMap,
291
+ ...experimentalFeatures
292
+ };
293
+ }
294
+ filterExperimentalFeatures() {
295
+ if ((0, import_shared_utils.getExperimentalFeatures)().ENABLE_FINGERPRINTS) {
296
+ return {experimentalFeatures: {ENABLE_FINGERPRINTS: true}};
297
+ } else {
298
+ return void 0;
299
+ }
300
+ }
301
+ addAdditionalImportMetadataToViewConfig(siteConfig) {
302
+ const supportsFingerprints = siteConfig.experimentalFeatures?.ENABLE_FINGERPRINTS;
303
+ const additionalImportMetadata = siteConfig?.importMetadata?.getAdditionalImportMetadata();
304
+ if (supportsFingerprints && siteConfig.viewConfigPath && additionalImportMetadata?.imports && Object.keys(additionalImportMetadata.imports).length > 0) {
305
+ const imports = additionalImportMetadata.imports ? JSON.stringify(additionalImportMetadata.imports) : "{}";
306
+ const initImports = `if (!globalThis.LWR.imports) { globalThis.LWR.imports = {}; }`;
307
+ const mergeImports = `Object.assign(globalThis.LWR.imports, ${imports})`;
308
+ const index = additionalImportMetadata.index ? JSON.stringify(additionalImportMetadata.index) : "{}";
309
+ const initIndex = `if (!globalThis.LWR.index) { globalThis.LWR.index = {}; }`;
310
+ const mergeIndex = `Object.assign(globalThis.LWR.index, ${index})`;
311
+ import_fs_extra.default.appendFileSync(siteConfig.viewConfigPath, `
312
+ // Appended by Static Site Generator
313
+ ${initImports}
314
+ ${mergeImports}
315
+ ${initIndex}
316
+ ${mergeIndex}
317
+ `);
318
+ }
319
+ }
205
320
  };
206
321
  var static_generation_default = SiteGenerator;
322
+ var ViewImportMetadataImpl = class {
323
+ constructor(existingImportMetadata, additionalImportMetadata) {
324
+ this.existing = existingImportMetadata;
325
+ this.additional = additionalImportMetadata || {imports: {}, index: {}};
326
+ }
327
+ getAdditionalImportMetadata() {
328
+ return this.additional;
329
+ }
330
+ addAdditionalMetadata(newMetadata) {
331
+ const filteredImports = this.filterMetadata(newMetadata);
332
+ this.mergeImportMetadata(this.additional, filteredImports);
333
+ return filteredImports;
334
+ }
335
+ filterMetadata(newMetadata) {
336
+ const importsArray = Object.entries(newMetadata.imports);
337
+ const filteredImports = importsArray.filter(([key]) => !this.existing.imports[key]);
338
+ const imports = Object.fromEntries(filteredImports);
339
+ const indexArray = Object.entries(newMetadata.index || {});
340
+ const filteredIndex = indexArray.filter(([key]) => !this.existing.index || !this.existing.index[key]);
341
+ const index = Object.fromEntries(filteredIndex);
342
+ return {
343
+ imports,
344
+ index
345
+ };
346
+ }
347
+ mergeImportMetadata(targetImportMetdadata, newImportMetadata) {
348
+ Object.assign(targetImportMetdadata.imports, newImportMetadata.imports);
349
+ Object.assign(targetImportMetdadata.index, newImportMetadata.index);
350
+ }
351
+ };
@@ -28,9 +28,14 @@ __export(exports, {
28
28
  });
29
29
  var import_http = __toModule(require("http"));
30
30
  var import_https = __toModule(require("https"));
31
+ var import_diagnostics = __toModule(require("@lwrjs/diagnostics"));
31
32
  var NetworkDispatcher = class {
32
33
  constructor(port, internalRequestKey) {
33
34
  this.port = port || 3e3;
35
+ const httpClient = this.port == 443 ? import_https.default : import_http.default;
36
+ this.pool = new httpClient.Agent({
37
+ maxSockets: 25
38
+ });
34
39
  this.internalRequestKey = internalRequestKey || "";
35
40
  }
36
41
  dispatchUrl(url, method, lang) {
@@ -39,6 +44,7 @@ var NetworkDispatcher = class {
39
44
  host: "localhost",
40
45
  port: this.port,
41
46
  path: url,
47
+ agent: this.pool,
42
48
  headers: {
43
49
  "Accept-Language": lang,
44
50
  "lwr-metadata-request": this.internalRequestKey
@@ -57,13 +63,27 @@ var NetworkDispatcher = class {
57
63
  const jsonResponse = JSON.parse(body);
58
64
  resolve(jsonResponse);
59
65
  } catch (e) {
60
- console.error(`[NetworkDispatcher] unexpected response body: '${body}'`, e);
66
+ console.error(`[ERROR][NetworkDispatcher] unexpected response body: [${method}][${lang}] ${url}: '${body}'`);
67
+ if (e instanceof import_diagnostics.DiagnosticsError) {
68
+ console.log("LWR Diagnostic Error: ");
69
+ console.log(e.diagnostics);
70
+ console.log(e.stack);
71
+ } else {
72
+ console.error(e);
73
+ }
61
74
  resolve({});
62
75
  }
63
76
  });
64
77
  });
65
78
  req.on("error", (err) => {
66
- console.error("Error occurred fetching metadata: " + err.message);
79
+ console.error(`[ERROR][NetworkDispatcher] Request: [${method}][${lang}] ${url}`);
80
+ if (err instanceof import_diagnostics.DiagnosticsError) {
81
+ console.log("LWR Diagnostic Error: ");
82
+ console.log(err.diagnostics);
83
+ console.log(err.stack);
84
+ } else {
85
+ console.error(err);
86
+ }
67
87
  reject(err);
68
88
  });
69
89
  req.end();
@@ -24,6 +24,7 @@ var __toModule = (module2) => {
24
24
  // packages/@lwrjs/core/src/tools/utils/stream.ts
25
25
  __markAsModule(exports);
26
26
  __export(exports, {
27
+ isObject: () => isObject,
27
28
  writeResponse: () => writeResponse,
28
29
  writeStream: () => writeStream
29
30
  });
@@ -42,6 +43,13 @@ async function writeResponse(context, fullPath) {
42
43
  await writeStream(stream, fullPath);
43
44
  } else if (context.fs?.body) {
44
45
  const body = context.fs?.body;
45
- import_fs.default.writeFileSync(fullPath, body, "utf-8");
46
+ if (isObject(body)) {
47
+ import_fs.default.writeFileSync(fullPath, JSON.stringify(body), "utf-8");
48
+ } else {
49
+ import_fs.default.writeFileSync(fullPath, body, "utf-8");
50
+ }
46
51
  }
47
52
  }
53
+ function isObject(o) {
54
+ return typeof o === "object" && o !== null && !Array.isArray(o);
55
+ }
@@ -44,6 +44,7 @@ var ROOT_ATTRIBUTE_KEYS = createKeys("root", [
44
44
  "apiVersion",
45
45
  "assets",
46
46
  "assetProviders",
47
+ "assetTransformers",
47
48
  "bundleConfig",
48
49
  "cacheDir",
49
50
  "contentDir",
@@ -68,7 +69,8 @@ var ROOT_ATTRIBUTE_KEYS = createKeys("root", [
68
69
  "serverMode",
69
70
  "serverType",
70
71
  "templateEngine",
71
- "viewProviders"
72
+ "viewProviders",
73
+ "viewTransformers"
72
74
  ]);
73
75
  var ASSET_DIR_ATTRIBUTE_KEYS = createKeys("assetDir", ["alias", "dir", "urlPath"]);
74
76
  var ASSET_FILE_ATTRIBUTE_KEYS = createKeys("assetFile", ["alias", "file", "urlPath"]);
@@ -101,7 +103,8 @@ var BOOTSTRAP_ATTRIBUTE_KEYS = createKeys("bootstrap", [
101
103
  "syntheticShadow",
102
104
  "workers",
103
105
  "services",
104
- "configAsSrc"
106
+ "configAsSrc",
107
+ "experimentalSSR"
105
108
  ]);
106
109
  var SPECIFIER_REGEX = /^@?[\w-]+(\/[\w-]+)*$/;
107
110
  function isNotEmptyString(node) {
@@ -42,6 +42,7 @@ function validateBootstrap(node, validationContext, propPrefix) {
42
42
  validationContext.assertValidKeys(node, "bootstrap", import_app_config_context.BOOTSTRAP_ATTRIBUTE_KEYS);
43
43
  validationContext.assertArrayOfSpecifiers((0, import_jsonc_parser.findNodeAtLocation)(node, ["services"]), `${propPrefix}.services`);
44
44
  validationContext.assertIsBoolean((0, import_jsonc_parser.findNodeAtLocation)(node, ["autoBoot"]), `${propPrefix}.autoBoot`);
45
+ validationContext.assertIsBoolean((0, import_jsonc_parser.findNodeAtLocation)(node, ["experimentalSSR"]), `${propPrefix}.experimentalSSR`);
45
46
  validationContext.assertIsBoolean((0, import_jsonc_parser.findNodeAtLocation)(node, ["configAsSrc"]), `${propPrefix}.configAsSrc`);
46
47
  validationContext.assertIsBoolean((0, import_jsonc_parser.findNodeAtLocation)(node, ["syntheticShadow"]), `${propPrefix}.syntheticShadow`);
47
48
  const workers = (0, import_jsonc_parser.findNodeAtLocation)(node, ["workers"]);
@@ -26,6 +26,7 @@ const DEFAULT_DATA_DIR = '$rootDir/src/data';
26
26
  // Providers
27
27
  const DEFAULT_MODULE_PROVIDERS = [
28
28
  '@lwrjs/app-service/moduleProvider',
29
+ '@lwrjs/lwc-ssr/moduleProvider',
29
30
  '@lwrjs/lwc-module-provider',
30
31
  '@lwrjs/npm-module-provider',
31
32
  ];
@@ -36,7 +37,9 @@ const DEFAULT_VIEW_PROVIDERS = [
36
37
  '@lwrjs/markdown-view-provider',
37
38
  '@lwrjs/base-view-provider',
38
39
  ];
40
+ const DEFAULT_VIEW_TRANFORM_PLUGINS = ['@lwrjs/base-view-transformer', '@lwrjs/lwc-ssr/viewTransformer'];
39
41
  const DEFAULT_ASSET_PROVIDERS = ['@lwrjs/fs-asset-provider'];
42
+ const DEFAULT_ASSET_TRANFORM_PLUGINS = ['@lwrjs/asset-transformer'];
40
43
  // Packages/modules
41
44
  const DEFAULT_TEMPLATE_ENGINE = '@lwrjs/base-template-engine';
42
45
  const DEFAULT_AMD_LOADER = 'lwr/loader';
@@ -47,9 +50,17 @@ const DEFAULT_LWR_MODULES = [
47
50
  { npm: getLWCEngineSpecifier() },
48
51
  { npm: '@lwrjs/client-modules' },
49
52
  { npm: '@lwrjs/loader' },
53
+ { npm: '@lwrjs/o11y' },
50
54
  { npm: '@lwrjs/router' },
51
55
  { npm: '@lwc/synthetic-shadow' },
52
56
  ];
57
+ const DEFAULT_BUNDLE_EXCLUSIONS = [
58
+ 'lwc',
59
+ '@lwc/synthetic-shadow',
60
+ 'lwr/navigation',
61
+ 'lwr/esmLoader',
62
+ 'lwr/profiler',
63
+ ];
53
64
  // Default config objects
54
65
  const DEFAULT_LWR_CONFIG = {
55
66
  port: PORT,
@@ -60,6 +71,8 @@ const DEFAULT_LWR_CONFIG = {
60
71
  serverMode: MODE,
61
72
  apiVersion: DEFAULT_API_VERSION,
62
73
  assets: DEFAULT_ASSETS_DIR,
74
+ assetProviders: DEFAULT_ASSET_PROVIDERS,
75
+ assetTransformers: DEFAULT_ASSET_TRANFORM_PLUGINS,
63
76
  contentDir: DEFAULT_CONTENT_DIR,
64
77
  layoutsDir: DEFAULT_LAYOUTS_DIR,
65
78
  staticSiteGenerator: DEFAULT_GENERATOR_CONFIG,
@@ -69,12 +82,13 @@ const DEFAULT_LWR_CONFIG = {
69
82
  moduleProviders: DEFAULT_MODULE_PROVIDERS,
70
83
  resourceProviders: DEFAULT_RESOURCE_PROVIDERS,
71
84
  viewProviders: DEFAULT_VIEW_PROVIDERS,
85
+ viewTransformers: DEFAULT_VIEW_TRANFORM_PLUGINS,
72
86
  templateEngine: DEFAULT_TEMPLATE_ENGINE,
73
87
  environment: {},
74
88
  lwc: { modules: [] },
75
89
  routes: [],
76
90
  errorRoutes: [],
77
- bundleConfig: {},
91
+ bundleConfig: { exclude: DEFAULT_BUNDLE_EXCLUSIONS },
78
92
  serverType: DEFAULT_SERVER_TYPE,
79
93
  locker: DEFAULT_LWR_LOCKER_CONFIG,
80
94
  };
@@ -192,6 +206,16 @@ function mergeLWCConfigs(config1, config2) {
192
206
  : undefined,
193
207
  };
194
208
  }
209
+ // merge default bundle exclusions with any bundle exclusions specified in config
210
+ function mergeBundleConfig(jsonConfig, config) {
211
+ const defaultExclusions = DEFAULT_BUNDLE_EXCLUSIONS;
212
+ const configExclusions = config?.bundleConfig?.exclude || jsonConfig?.bundleConfig?.exclude || [];
213
+ return {
214
+ ...jsonConfig?.bundleConfig,
215
+ ...config?.bundleConfig,
216
+ exclude: [...new Set([...defaultExclusions, ...configExclusions])],
217
+ };
218
+ }
195
219
  // merge default locker trusted namespaces/cmps with any trusted namespaces/cmps specified in config
196
220
  function mergeLockerConfig(jsonConfig, config) {
197
221
  const defaultNamespaces = DEFAULT_LOCKER_TRUSTED_CMP;
@@ -222,6 +246,13 @@ function normalizeLwcConfig(config) {
222
246
  : undefined,
223
247
  };
224
248
  }
249
+ function trimLwrConfig(config) {
250
+ Object.keys(config).forEach((k) => {
251
+ if (config[k] === undefined)
252
+ delete config[k];
253
+ });
254
+ return config;
255
+ }
225
256
  /**
226
257
  * Merge and normalize all LWR configurations.
227
258
  *
@@ -233,7 +264,8 @@ function normalizeLwcConfig(config) {
233
264
  * @returns the merged and normalized LWR configuration
234
265
  */
235
266
  export function normalizeConfig(config) {
236
- if (config) {
267
+ if (config !== undefined) {
268
+ config = trimLwrConfig(config);
237
269
  validateLwrAppConfig(JSON.stringify(config), 'pre');
238
270
  }
239
271
  // Merge all configurations together, and return
@@ -246,6 +278,7 @@ export function normalizeConfig(config) {
246
278
  ...lwrJsonConfig,
247
279
  ...config,
248
280
  lwc: normalizeLwcConfig(mergeLWCConfigs(lwrJsonConfig, config)),
281
+ bundleConfig: mergeBundleConfig(lwrJsonConfig, config),
249
282
  locker: mergeLockerConfig(lwrJsonConfig, config),
250
283
  rootDir,
251
284
  };
@@ -270,9 +303,11 @@ export function normalizeConfig(config) {
270
303
  interchangeableModulesMap: mergedLwrGlobalConfig.lwc.interchangeableModulesMap,
271
304
  },
272
305
  moduleProviders: normalizeServices(mergedLwrGlobalConfig.moduleProviders, rootDir),
273
- assetProviders: normalizeServices(DEFAULT_ASSET_PROVIDERS, rootDir),
306
+ assetProviders: normalizeServices(mergedLwrGlobalConfig.assetProviders, rootDir),
307
+ assetTransformers: normalizeServices(mergedLwrGlobalConfig.assetTransformers, rootDir),
274
308
  resourceProviders: normalizeServices(mergedLwrGlobalConfig.resourceProviders, rootDir),
275
309
  viewProviders: normalizeServices(mergedLwrGlobalConfig.viewProviders, rootDir),
310
+ viewTransformers: normalizeServices(mergedLwrGlobalConfig.viewTransformers, rootDir),
276
311
  routes: normalizeRoutes(mergedLwrGlobalConfig.routes, { rootDir, assets, contentDir, layoutsDir }),
277
312
  errorRoutes: normalizeRoutes(mergedLwrGlobalConfig.errorRoutes, {
278
313
  rootDir,