@lwrjs/core 0.11.0-alpha.8 → 0.11.0
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/build/cjs/context/server.cjs +1 -1
- package/build/cjs/index.cjs +3 -1
- package/build/cjs/middleware/asset-middleware.cjs +10 -2
- package/build/cjs/middleware/bundle-middleware.cjs +20 -7
- package/build/cjs/middleware/hmr-middleware.cjs +6 -5
- package/build/cjs/middleware/locale-middleware.cjs +3 -1
- package/build/cjs/middleware/mapping-middleware.cjs +14 -4
- package/build/cjs/middleware/module-middleware.cjs +12 -4
- package/build/cjs/middleware/request-processor-middleware.cjs +64 -0
- package/build/cjs/middleware/resource-middleware.cjs +3 -3
- package/build/cjs/middleware/utils/error-handling.cjs +5 -4
- package/build/cjs/middleware/view-middleware.cjs +37 -8
- package/build/cjs/middleware.cjs +2 -0
- package/build/cjs/tools/server-warmup.cjs +6 -6
- package/build/cjs/tools/static-generation.cjs +72 -66
- package/build/cjs/tools/utils/network-dispatcher.cjs +12 -11
- package/build/es/context/server.js +1 -2
- package/build/es/index.js +5 -2
- package/build/es/middleware/asset-middleware.js +10 -2
- package/build/es/middleware/bundle-middleware.js +17 -9
- package/build/es/middleware/hmr-middleware.js +6 -5
- package/build/es/middleware/locale-middleware.js +1 -1
- package/build/es/middleware/mapping-middleware.js +9 -4
- package/build/es/middleware/module-middleware.js +14 -6
- package/build/es/middleware/request-processor-middleware.d.ts +3 -0
- package/build/es/middleware/request-processor-middleware.js +53 -0
- package/build/es/middleware/resource-middleware.js +3 -3
- package/build/es/middleware/utils/error-handling.js +5 -4
- package/build/es/middleware/view-middleware.js +48 -8
- package/build/es/middleware.d.ts +1 -0
- package/build/es/middleware.js +1 -0
- package/build/es/tools/server-warmup.js +2 -2
- package/build/es/tools/static-generation.d.ts +4 -0
- package/build/es/tools/static-generation.js +66 -52
- package/build/es/tools/types.d.ts +2 -1
- package/build/es/tools/utils/network-dispatcher.js +2 -1
- package/package.json +31 -29
|
@@ -28,6 +28,7 @@ __export(exports, {
|
|
|
28
28
|
default: () => static_generation_default
|
|
29
29
|
});
|
|
30
30
|
var import_perf_hooks = __toModule(require("perf_hooks"));
|
|
31
|
+
var import_diagnostics = __toModule(require("@lwrjs/diagnostics"));
|
|
31
32
|
var import_shared_utils = __toModule(require("@lwrjs/shared-utils"));
|
|
32
33
|
var import_site_metadata = __toModule(require("@lwrjs/static/site-metadata"));
|
|
33
34
|
var import_path = __toModule(require("path"));
|
|
@@ -38,74 +39,82 @@ var import_config = __toModule(require("@lwrjs/config"));
|
|
|
38
39
|
var SiteGenerator = class {
|
|
39
40
|
async buildStaticApplication(config, dispatcher) {
|
|
40
41
|
const startTime = import_perf_hooks.performance.now();
|
|
41
|
-
|
|
42
|
-
if (!
|
|
43
|
-
|
|
42
|
+
import_diagnostics.logger.info("[SSG] Static Site Generation");
|
|
43
|
+
if (!import_diagnostics.logger.currentLevel || import_diagnostics.logger.currentLevel == import_diagnostics.WARN || import_diagnostics.logger.currentLevel == import_diagnostics.INFO) {
|
|
44
|
+
import_diagnostics.logger.setOptions({dedupe: new Set([import_diagnostics.WARN])});
|
|
44
45
|
}
|
|
45
|
-
const {
|
|
46
|
+
const {assets, basePath, rootDir, routes, staticSiteGenerator} = config;
|
|
46
47
|
if (!staticSiteGenerator.outputDir) {
|
|
47
48
|
staticSiteGenerator.outputDir = "site";
|
|
48
49
|
}
|
|
49
50
|
const outputDir = (0, import_path.join)(rootDir, staticSiteGenerator.outputDir);
|
|
50
51
|
if (!staticSiteGenerator.skipCleanOutputDir) {
|
|
51
|
-
|
|
52
|
+
import_diagnostics.logger.info(`[SSG] Clearing output directory: ${outputDir}`);
|
|
52
53
|
import_fs_extra.default.rmSync(outputDir, {recursive: true, force: true});
|
|
53
54
|
} else if (import_fs_extra.default.existsSync(outputDir)) {
|
|
54
|
-
|
|
55
|
+
import_diagnostics.logger.info(`[SSG] Reusing existing output directory: ${outputDir}`);
|
|
55
56
|
}
|
|
56
57
|
const urlRewriteMap = new Map();
|
|
57
|
-
const {basePath} = config;
|
|
58
58
|
const runtimeEnvironment = (0, import_config.getRuntimeEnvironment)(config);
|
|
59
|
-
|
|
59
|
+
import_diagnostics.logger.info(`[SSG] Building routes (this may take some time to complete)`);
|
|
60
60
|
await this.generateRoutes(runtimeEnvironment, staticSiteGenerator, routes, basePath, dispatcher, outputDir, urlRewriteMap);
|
|
61
61
|
this.writeNetlifyRedirectConfig(outputDir, urlRewriteMap);
|
|
62
62
|
await this.copyAssets(assets, outputDir, config);
|
|
63
63
|
const endTime = import_perf_hooks.performance.now();
|
|
64
64
|
const timeDiff = (endTime - startTime) / 1e3;
|
|
65
|
-
|
|
65
|
+
import_diagnostics.logger.info(`[SSG] Static Site Generation complete in ${Math.round(timeDiff)} seconds`);
|
|
66
66
|
}
|
|
67
67
|
async generateRoutes(runtimeEnvironment, staticSiteGenerator, routes, basePath, dispatcher, outputDir, urlRewriteMap = new Map()) {
|
|
68
|
-
if (!staticSiteGenerator.locales) {
|
|
69
|
-
staticSiteGenerator.locales = ["en-US"];
|
|
70
|
-
}
|
|
71
68
|
const generateUrl = this.createGenerateURLFunction(dispatcher);
|
|
72
69
|
const {skipBaseDocumentGeneration = false} = staticSiteGenerator;
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
70
|
+
const i18n = runtimeEnvironment.i18n;
|
|
71
|
+
if (!i18n.uriPattern) {
|
|
72
|
+
await this.generateRoutesForLocale(routes, outputDir, {id: i18n.defaultLocale}, urlRewriteMap, skipBaseDocumentGeneration, runtimeEnvironment, basePath, generateUrl, staticSiteGenerator, dispatcher);
|
|
73
|
+
} else {
|
|
74
|
+
const sortedLocales = (0, import_shared_utils.sortLocalesByFallback)(i18n);
|
|
75
|
+
for (const locale of sortedLocales) {
|
|
76
|
+
import_diagnostics.logger.debug(`[SSG] Generate routes of locale: ${locale.id}`);
|
|
77
|
+
await this.generateRoutesForLocale(routes, outputDir, locale, urlRewriteMap, skipBaseDocumentGeneration, runtimeEnvironment, basePath, generateUrl, staticSiteGenerator, dispatcher);
|
|
77
78
|
}
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
async generateRoutesForLocale(routes, outputDir, locale, urlRewriteMap, skipBaseDocumentGeneration, runtimeEnvironment, basePath, generateUrl, staticSiteGenerator, dispatcher) {
|
|
82
|
+
const i18n = runtimeEnvironment.i18n;
|
|
83
|
+
for (const route of routes) {
|
|
84
|
+
const siteConfig = this.createSiteConfig(outputDir, locale.id, urlRewriteMap, skipBaseDocumentGeneration, runtimeEnvironment, i18n);
|
|
85
|
+
const localizedPath = (0, import_shared_utils.getViewUri)(route.path, basePath, locale.id, i18n);
|
|
86
|
+
await generateUrl(localizedPath, siteConfig);
|
|
87
|
+
}
|
|
88
|
+
if (staticSiteGenerator._additionalRoutePaths) {
|
|
89
|
+
for (const uri of staticSiteGenerator._additionalRoutePaths) {
|
|
90
|
+
const siteConfig = this.createSiteConfig(outputDir, locale.id, urlRewriteMap, skipBaseDocumentGeneration, runtimeEnvironment, i18n);
|
|
91
|
+
await generateUrl(uri, siteConfig);
|
|
83
92
|
}
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
}
|
|
93
|
+
}
|
|
94
|
+
const {_additionalModules} = staticSiteGenerator;
|
|
95
|
+
if (_additionalModules) {
|
|
96
|
+
for (const specifier of _additionalModules) {
|
|
97
|
+
import_diagnostics.logger.debug(`[SSG] Additional Module: ${locale.id} ${specifier}`);
|
|
98
|
+
const startTime = import_perf_hooks.performance.now();
|
|
99
|
+
const siteConfig = this.createSiteConfig(outputDir, locale.id, urlRewriteMap, skipBaseDocumentGeneration, runtimeEnvironment, i18n);
|
|
100
|
+
await this.dispatchJSResourceRecursive(specifier, dispatcher, siteConfig, true);
|
|
101
|
+
await this.captureAdditionalRouteMetadata(siteConfig);
|
|
102
|
+
const endTime = import_perf_hooks.performance.now();
|
|
103
|
+
const timeDiff = endTime - startTime;
|
|
104
|
+
import_diagnostics.logger.info(`[SSG] Additional Module ${locale.id} ${specifier} in ${Math.round(timeDiff)} ms`);
|
|
96
105
|
}
|
|
97
106
|
}
|
|
98
107
|
}
|
|
99
108
|
createGenerateURLFunction(dispatcher) {
|
|
100
109
|
const generateRoute = async (uri, siteConfig) => {
|
|
101
110
|
const locale = siteConfig.locale;
|
|
102
|
-
|
|
111
|
+
import_diagnostics.logger.debug(`[SSG] Start Generate: ${locale} ${uri}`);
|
|
103
112
|
const startTime = import_perf_hooks.performance.now();
|
|
104
113
|
await this.dispatchResourceRecursive(uri, dispatcher, {resourceType: "route"}, siteConfig);
|
|
105
114
|
await this.captureAdditionalRouteMetadata(siteConfig);
|
|
106
115
|
const endTime = import_perf_hooks.performance.now();
|
|
107
116
|
const timeDiff = endTime - startTime;
|
|
108
|
-
|
|
117
|
+
import_diagnostics.logger.info(`[SSG] ${locale} ${uri} in ${Math.round(timeDiff)} ms`);
|
|
109
118
|
};
|
|
110
119
|
return generateRoute.bind(this);
|
|
111
120
|
}
|
|
@@ -114,11 +123,11 @@ var SiteGenerator = class {
|
|
|
114
123
|
if (!visitedUrls.has(url)) {
|
|
115
124
|
visitedUrls.add(url);
|
|
116
125
|
if ((0, import_shared_utils.isExternalUrl)(url)) {
|
|
117
|
-
|
|
126
|
+
import_diagnostics.logger.warn("[SSG] Skipped generation of external url: " + url);
|
|
118
127
|
return;
|
|
119
128
|
}
|
|
120
129
|
if (url.indexOf("/:") !== -1 || url.indexOf("*") !== -1) {
|
|
121
|
-
|
|
130
|
+
import_diagnostics.logger.warn("[SSG] Skipped generation of url with variable path segment: " + url);
|
|
122
131
|
return;
|
|
123
132
|
}
|
|
124
133
|
let context;
|
|
@@ -179,13 +188,16 @@ var SiteGenerator = class {
|
|
|
179
188
|
}
|
|
180
189
|
addBundleToSiteMetadata(bundleDefinition, url, siteConfig) {
|
|
181
190
|
if (siteConfig.siteMetadata) {
|
|
182
|
-
const
|
|
191
|
+
const locale = siteConfig.locale;
|
|
192
|
+
const specifier = siteConfig.i18n.defaultLocale === locale ? bundleDefinition.specifier : `${bundleDefinition.specifier}|l/${locale}`;
|
|
183
193
|
const imports = bundleDefinition.bundleRecord.imports?.map((moduleRef) => (0, import_shared_utils.getSpecifier)(moduleRef)) || [];
|
|
194
|
+
const dynamicImports = bundleDefinition.bundleRecord.dynamicImports?.map((moduleRef) => (0, import_shared_utils.getSpecifier)(moduleRef));
|
|
184
195
|
const bundleMetadata = {
|
|
185
196
|
version: bundleDefinition.version,
|
|
186
197
|
path: decodeURIComponent(url),
|
|
187
198
|
includedModules: bundleDefinition.bundleRecord.includedModules || [],
|
|
188
|
-
imports
|
|
199
|
+
imports,
|
|
200
|
+
dynamicImports
|
|
189
201
|
};
|
|
190
202
|
const siteBundles = siteConfig.siteMetadata.getSiteBundles().bundles;
|
|
191
203
|
siteBundles[specifier] = bundleMetadata;
|
|
@@ -194,7 +206,7 @@ var SiteGenerator = class {
|
|
|
194
206
|
addResourceToSiteMetadata(resourceDefinition, url, siteConfig) {
|
|
195
207
|
if (siteConfig.siteMetadata) {
|
|
196
208
|
if (!resourceDefinition.specifier) {
|
|
197
|
-
|
|
209
|
+
import_diagnostics.logger.warn("[SSG] Could not save resource metadata. There was no specifier.", resourceDefinition);
|
|
198
210
|
} else {
|
|
199
211
|
const specifier = resourceDefinition.specifier;
|
|
200
212
|
const resourceMetadata = {
|
|
@@ -210,7 +222,7 @@ var SiteGenerator = class {
|
|
|
210
222
|
addAssetToSiteMetadata(assetDefinition, url, siteConfig) {
|
|
211
223
|
if (siteConfig.siteMetadata) {
|
|
212
224
|
if (!assetDefinition.uri) {
|
|
213
|
-
|
|
225
|
+
import_diagnostics.logger.warn("[SSG] Could not save asset metadata. There was no uri.", assetDefinition);
|
|
214
226
|
} else {
|
|
215
227
|
const specifier = assetDefinition.uri;
|
|
216
228
|
const resourceMetadata = {
|
|
@@ -221,7 +233,7 @@ var SiteGenerator = class {
|
|
|
221
233
|
if (!siteAssets.assets[specifier]) {
|
|
222
234
|
siteAssets.assets[specifier] = resourceMetadata;
|
|
223
235
|
} else {
|
|
224
|
-
|
|
236
|
+
import_diagnostics.logger.debug(`[SSG] Ignore asset redefinition ${specifier}`);
|
|
225
237
|
}
|
|
226
238
|
}
|
|
227
239
|
}
|
|
@@ -244,7 +256,7 @@ var SiteGenerator = class {
|
|
|
244
256
|
await Promise.all(dispatchRequests);
|
|
245
257
|
} else {
|
|
246
258
|
const body = context.fs?.body;
|
|
247
|
-
|
|
259
|
+
import_diagnostics.logger.warn(`[SSG] Failed to fetch ${url}: (${statusCode}) ${body}`);
|
|
248
260
|
}
|
|
249
261
|
}
|
|
250
262
|
async handleHtmlResource(url, context, siteConfig, dispatcher) {
|
|
@@ -258,16 +270,9 @@ var SiteGenerator = class {
|
|
|
258
270
|
directoryPath = url.substring(0, lastPathIndex);
|
|
259
271
|
}
|
|
260
272
|
const dir = (0, import_dir.createResourceDir)(directoryPath, outputDir);
|
|
261
|
-
const localeDir = (0, import_dir.createResourceDir)(directoryPath, (0, import_path.join)(outputDir, siteConfig.locale));
|
|
262
273
|
const filePath = (0, import_path.join)(dir, fileName);
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
siteConfig.viewPaths.add(filePath);
|
|
266
|
-
await (0, import_stream.writeResponse)(context, filePath);
|
|
267
|
-
}
|
|
268
|
-
(0, import_dir.createDir)(localeDir);
|
|
269
|
-
siteConfig.viewPaths.add(fileLocalePath);
|
|
270
|
-
await (0, import_stream.writeResponse)(context, fileLocalePath);
|
|
274
|
+
siteConfig.viewPaths.add(filePath);
|
|
275
|
+
await (0, import_stream.writeResponse)(context, filePath);
|
|
271
276
|
}
|
|
272
277
|
const viewDefinition = context.fs?.metadata?.viewDefinition;
|
|
273
278
|
if (viewDefinition) {
|
|
@@ -310,7 +315,7 @@ var SiteGenerator = class {
|
|
|
310
315
|
siteConfig.viewConfigPath = this.getResourcePathFromUrl(siteConfig, resourceUri);
|
|
311
316
|
}
|
|
312
317
|
} else {
|
|
313
|
-
|
|
318
|
+
import_diagnostics.logger.warn("[SSG] Skipped inline bootstrap resource: %j", resource);
|
|
314
319
|
}
|
|
315
320
|
}
|
|
316
321
|
}
|
|
@@ -320,7 +325,7 @@ var SiteGenerator = class {
|
|
|
320
325
|
if (resourceUri.startsWith("/")) {
|
|
321
326
|
dispatchRequests.push(this.dispatchResourceRecursive(resourceUri, dispatcher, {resourceType: "resource"}, siteConfig));
|
|
322
327
|
} else {
|
|
323
|
-
|
|
328
|
+
import_diagnostics.logger.warn("[SSG] Skipped resource: %j", resource);
|
|
324
329
|
}
|
|
325
330
|
}
|
|
326
331
|
await Promise.all(dispatchRequests);
|
|
@@ -336,7 +341,7 @@ var SiteGenerator = class {
|
|
|
336
341
|
const mappingURL = siteConfig.endpoints?.uris?.mapping + encodeURIComponent(jsUri);
|
|
337
342
|
await this.dispatchResourceRecursive(mappingURL, dispatcher, {resourceType: "mapping"}, siteConfig);
|
|
338
343
|
} else {
|
|
339
|
-
|
|
344
|
+
import_diagnostics.logger.warn('[SSG] Unable to fetch mapping for bare specifier or variable dynamic import: "' + jsUri + '"');
|
|
340
345
|
}
|
|
341
346
|
} else if (isAdditionalModulesRequest) {
|
|
342
347
|
const uri = `${siteConfig.endpoints?.uris.legacyDefault}${encodeURIComponent(jsUri)}`;
|
|
@@ -358,7 +363,7 @@ var SiteGenerator = class {
|
|
|
358
363
|
for (const ref of assetReferences) {
|
|
359
364
|
const refUrl = ref.override?.uri || ref.url;
|
|
360
365
|
dispatchRequests.push(this.dispatchResourceRecursive(refUrl, dispatcher, {resourceType: "asset", asset: metadata?.asset}, siteConfig).catch((err) => {
|
|
361
|
-
|
|
366
|
+
import_diagnostics.logger.warn(`[SSG] Failed to fetch asset reference => ${refUrl} from ${url}`, err);
|
|
362
367
|
}));
|
|
363
368
|
}
|
|
364
369
|
return Promise.all(dispatchRequests);
|
|
@@ -391,7 +396,7 @@ var SiteGenerator = class {
|
|
|
391
396
|
async copyAssets(assets, outputDir, config) {
|
|
392
397
|
const {basePath} = config;
|
|
393
398
|
const runtimeEnvironment = (0, import_config.getRuntimeEnvironment)(config);
|
|
394
|
-
const siteConfig = this.createSiteConfig(outputDir, "en-US", new Map(), true, runtimeEnvironment);
|
|
399
|
+
const siteConfig = this.createSiteConfig(outputDir, "en-US", new Map(), true, runtimeEnvironment, config.i18n);
|
|
395
400
|
for (const asset of assets) {
|
|
396
401
|
try {
|
|
397
402
|
const assetSrcFile = asset.file;
|
|
@@ -418,11 +423,11 @@ var SiteGenerator = class {
|
|
|
418
423
|
import_fs_extra.default.copySync(assetSrcFile, assetsPath);
|
|
419
424
|
this.addAssetToMetadata(assetsPath, siteConfig);
|
|
420
425
|
} else {
|
|
421
|
-
|
|
426
|
+
import_diagnostics.logger.warn("[SSG] Could not find assets to copy at path: " + assetsPath);
|
|
422
427
|
}
|
|
423
428
|
} catch (e) {
|
|
424
|
-
|
|
425
|
-
|
|
429
|
+
import_diagnostics.logger.error("[SSG] Error occurred processing asset config: " + JSON.stringify(asset));
|
|
430
|
+
import_diagnostics.logger.error(e);
|
|
426
431
|
}
|
|
427
432
|
}
|
|
428
433
|
await siteConfig.siteMetadata?.persistSiteMetadata();
|
|
@@ -439,7 +444,7 @@ var SiteGenerator = class {
|
|
|
439
444
|
}
|
|
440
445
|
}
|
|
441
446
|
} catch (err) {
|
|
442
|
-
|
|
447
|
+
import_diagnostics.logger.warn(`[SSG] Unexpected error collecting asset directory metadata for ${directoryPath}`, err);
|
|
443
448
|
}
|
|
444
449
|
}
|
|
445
450
|
addAssetToMetadata(filePath, siteConfig) {
|
|
@@ -448,22 +453,22 @@ var SiteGenerator = class {
|
|
|
448
453
|
this.addAssetToSiteMetadata({
|
|
449
454
|
uri,
|
|
450
455
|
type: "asset",
|
|
451
|
-
stream: function(
|
|
456
|
+
stream: function(_encoding) {
|
|
452
457
|
throw new Error("Function not implemented.");
|
|
453
458
|
},
|
|
454
459
|
entry: filePath,
|
|
455
460
|
ext: (0, import_path.extname)(filePath),
|
|
456
461
|
mime: (0, import_shared_utils.mimeLookup)(filePath),
|
|
457
462
|
ownHash: "not-provided",
|
|
458
|
-
content: function(
|
|
463
|
+
content: function(_encoding) {
|
|
459
464
|
throw new Error("Function not implemented.");
|
|
460
465
|
}
|
|
461
466
|
}, uri, siteConfig);
|
|
462
467
|
} catch (err) {
|
|
463
|
-
|
|
468
|
+
import_diagnostics.logger.warn(`[SSG] Unexpected error collecting asset metadata for ${filePath}`, err);
|
|
464
469
|
}
|
|
465
470
|
}
|
|
466
|
-
createSiteConfig(outputDir, locale, urlRewriteMap, skipBaseDocumentGeneration, runtimeEnvironment) {
|
|
471
|
+
createSiteConfig(outputDir, locale, urlRewriteMap, skipBaseDocumentGeneration, runtimeEnvironment, i18n) {
|
|
467
472
|
const featureFlags = this.filterFeatureFlags();
|
|
468
473
|
const endpoints = {
|
|
469
474
|
uris: {
|
|
@@ -480,7 +485,8 @@ var SiteGenerator = class {
|
|
|
480
485
|
endpoints,
|
|
481
486
|
skipBaseDocumentGeneration,
|
|
482
487
|
...featureFlags,
|
|
483
|
-
siteMetadata: new import_site_metadata.SiteMetadataImpl({rootDir: outputDir})
|
|
488
|
+
siteMetadata: new import_site_metadata.SiteMetadataImpl({rootDir: outputDir}),
|
|
489
|
+
i18n
|
|
484
490
|
};
|
|
485
491
|
}
|
|
486
492
|
filterFeatureFlags() {
|
|
@@ -28,6 +28,7 @@ __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 import_shared_utils = __toModule(require("@lwrjs/shared-utils"));
|
|
32
33
|
var NetworkDispatcher = class {
|
|
33
34
|
constructor(port, internalRequestKey) {
|
|
@@ -59,46 +60,46 @@ var NetworkDispatcher = class {
|
|
|
59
60
|
return new Promise((resolve, reject) => {
|
|
60
61
|
const httpClient = options.port == 443 ? import_https.default : import_http.default;
|
|
61
62
|
const bodyChunks = [];
|
|
62
|
-
|
|
63
|
+
import_diagnostics.logger.verbose(`[NetworkDispatcher] Request: [${method}][${lang}] ${url}`);
|
|
63
64
|
const req = httpClient.request(options, (res) => {
|
|
64
65
|
res.on("data", (chunk) => {
|
|
65
66
|
bodyChunks.push(chunk);
|
|
66
67
|
});
|
|
67
68
|
res.on("end", () => {
|
|
68
|
-
|
|
69
|
+
import_diagnostics.logger.verbose(`[END][NetworkDispatcher] Request: [${method}][${lang}] ${url}`);
|
|
69
70
|
if (!res.statusCode || res.statusCode >= 200 && res.statusCode < 300) {
|
|
70
71
|
const body = Buffer.concat(bodyChunks).toString();
|
|
71
72
|
try {
|
|
72
73
|
const jsonResponse = JSON.parse(body);
|
|
73
74
|
resolve(jsonResponse);
|
|
74
75
|
} catch (err) {
|
|
75
|
-
if (
|
|
76
|
-
|
|
76
|
+
if (import_diagnostics.logger.currentLevel == import_diagnostics.DEBUG || import_diagnostics.logger.currentLevel == import_diagnostics.VERBOSE) {
|
|
77
|
+
import_diagnostics.logger.warn(`[NetworkDispatcher] unexpected response body: [${method}][${lang}] ${url}: '${body}'`, err);
|
|
77
78
|
} else {
|
|
78
|
-
|
|
79
|
+
import_diagnostics.logger.warn(`[NetworkDispatcher] unexpected response body: [${method}][${lang}] ${url}: '${body}'`);
|
|
79
80
|
}
|
|
80
81
|
resolve({});
|
|
81
82
|
}
|
|
82
83
|
} else if (res.statusCode === 301 || res.statusCode === 302) {
|
|
83
84
|
if (res.headers?.location && (0, import_shared_utils.isModuleOrBundleUrl)(res.headers?.location)) {
|
|
84
|
-
|
|
85
|
+
import_diagnostics.logger.debug(`[NetworkDispatcher] Follow redirect: [${method}][${lang}][${res.statusCode}] ${url} -> ${res.headers.location}`);
|
|
85
86
|
const location = res.headers.location;
|
|
86
87
|
return this.handleRequest(this.createRequestOptions(location, method, lang), location, method, lang).then((resRedirect) => resolve(resRedirect)).catch((rejectRedirect) => reject(rejectRedirect));
|
|
87
88
|
} else {
|
|
88
|
-
|
|
89
|
+
import_diagnostics.logger.warn(`Redirect not followed: [${method}][${lang}][${res.statusCode}] ${url} -> ${res.headers.location}`);
|
|
89
90
|
resolve({});
|
|
90
91
|
}
|
|
91
92
|
} else {
|
|
92
|
-
|
|
93
|
+
import_diagnostics.logger.warn(`Unexpected status code: [${method}][${lang}][${res.statusCode}] ${url}`);
|
|
93
94
|
resolve({});
|
|
94
95
|
}
|
|
95
96
|
});
|
|
96
97
|
});
|
|
97
98
|
req.on("error", (err) => {
|
|
98
|
-
if (
|
|
99
|
-
|
|
99
|
+
if (import_diagnostics.logger.currentLevel == import_diagnostics.DEBUG || import_diagnostics.logger.currentLevel == import_diagnostics.VERBOSE) {
|
|
100
|
+
import_diagnostics.logger.warn(`[NetworkDispatcher] Request Failed: [${method}][${lang}] ${url}`, err);
|
|
100
101
|
} else {
|
|
101
|
-
|
|
102
|
+
import_diagnostics.logger.warn(`[NetworkDispatcher] Request Failed: [${method}][${lang}] ${url}`);
|
|
102
103
|
}
|
|
103
104
|
resolve({});
|
|
104
105
|
});
|
|
@@ -4,8 +4,7 @@ import { LwrModuleRegistry } from '@lwrjs/module-registry';
|
|
|
4
4
|
import { LwrResourceRegistry } from '@lwrjs/resource-registry';
|
|
5
5
|
import { LwrApplicationObserver } from '@lwrjs/shared-utils';
|
|
6
6
|
import { LwrViewRegistry } from '@lwrjs/view-registry';
|
|
7
|
-
|
|
8
|
-
import { WatcherFactoryImpl } from '@lwrjs/shared-utils/fs-watch';
|
|
7
|
+
import { WatcherFactoryImpl } from '@lwrjs/fs-watch';
|
|
9
8
|
export function createServerContext(appConfig, runtimeEnvironment, globalData) {
|
|
10
9
|
const appObserver = new LwrApplicationObserver();
|
|
11
10
|
const appEmitter = appObserver.createLwrEmitter();
|
package/build/es/index.js
CHANGED
|
@@ -1,12 +1,13 @@
|
|
|
1
|
-
import { getFeatureFlags, DEFAULT_LWR_BOOTSTRAP_CONFIG
|
|
1
|
+
import { getFeatureFlags, DEFAULT_LWR_BOOTSTRAP_CONFIG } from '@lwrjs/shared-utils';
|
|
2
2
|
import { createInternalServer } from '@lwrjs/server';
|
|
3
|
-
import { LwrServerError, createSingleDiagnosticError, descriptions } from '@lwrjs/diagnostics';
|
|
3
|
+
import { LwrServerError, createSingleDiagnosticError, descriptions, logger } from '@lwrjs/diagnostics';
|
|
4
4
|
import { loadConfig, executeConfigHooks, executeStartHooks, executeInstrumentationHooks, } from '@lwrjs/config';
|
|
5
5
|
import { loadHooks, loadServices, loadRouteHandlers } from '@lwrjs/config/modules';
|
|
6
6
|
import SiteGenerator from './tools/static-generation.js';
|
|
7
7
|
import { warmupServer } from './tools/server-warmup.js';
|
|
8
8
|
import { createServerContext } from './context/server.js';
|
|
9
9
|
import { createProviderContext } from './context/provider.js';
|
|
10
|
+
import { requestProcessorMiddleware } from './middleware/request-processor-middleware.js';
|
|
10
11
|
import { localeMiddleware } from './middleware/locale-middleware.js';
|
|
11
12
|
import { moduleMiddleware } from './middleware/module-middleware.js';
|
|
12
13
|
import { bundleMiddleware } from './middleware/bundle-middleware.js';
|
|
@@ -17,6 +18,8 @@ import { resourceMiddleware } from './middleware/resource-middleware.js';
|
|
|
17
18
|
import { hmrMiddleware } from './middleware/hmr-middleware.js';
|
|
18
19
|
import { getTracer, CoreSpan } from '@lwrjs/instrumentation';
|
|
19
20
|
function initMiddleware(app, server, serverContext) {
|
|
21
|
+
// TODO if we knew the target here we could make this middleware optional to target=mrt
|
|
22
|
+
requestProcessorMiddleware(app, serverContext);
|
|
20
23
|
localeMiddleware(app, serverContext);
|
|
21
24
|
moduleMiddleware(app, serverContext);
|
|
22
25
|
bundleMiddleware(app, serverContext);
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import path from 'path';
|
|
2
|
+
import { DiagnosticsError } from '@lwrjs/diagnostics';
|
|
3
|
+
import { RequestHandlerSpan, getTracer } from '@lwrjs/instrumentation';
|
|
2
4
|
import { getAssetIdentity } from './utils/identity.js';
|
|
3
5
|
import { handleErrors } from './utils/error-handling.js';
|
|
4
|
-
import { DiagnosticsError } from '@lwrjs/diagnostics';
|
|
5
6
|
function createAssetMiddleware(context) {
|
|
6
7
|
const { assetRegistry, runtimeEnvironment: { basePath }, } = context;
|
|
7
8
|
return async (req, res, next) => {
|
|
@@ -21,7 +22,14 @@ function createAssetMiddleware(context) {
|
|
|
21
22
|
res.sendStatus(302);
|
|
22
23
|
return;
|
|
23
24
|
}
|
|
24
|
-
const asset = await
|
|
25
|
+
const asset = await getTracer().trace({
|
|
26
|
+
name: RequestHandlerSpan.GetAsset,
|
|
27
|
+
attributes: {
|
|
28
|
+
specifier: assetId.specifier,
|
|
29
|
+
},
|
|
30
|
+
}, () => {
|
|
31
|
+
return assetRegistry.getAsset({ ...assetId, signature }, runtimeEnvironment, req.isSiteGeneration());
|
|
32
|
+
});
|
|
25
33
|
if (req.isSiteGeneration()) {
|
|
26
34
|
res.setSiteGenerationMetadata({ asset });
|
|
27
35
|
}
|
|
@@ -1,15 +1,16 @@
|
|
|
1
1
|
import { LATEST_SIGNATURE } from '@lwrjs/shared-utils';
|
|
2
2
|
import { descriptions } from '@lwrjs/diagnostics';
|
|
3
|
+
import { RequestHandlerSpan, getTracer } from '@lwrjs/instrumentation';
|
|
3
4
|
import { getRequestImporter } from './utils/request.js';
|
|
4
5
|
import { getModuleIdentity } from './utils/identity.js';
|
|
5
6
|
import { normalizeResolvedUris } from './utils/metadata.js';
|
|
6
7
|
import { createUnsignedBundleRedirect } from './redirects/unsigned-module-redirect.js';
|
|
7
8
|
import { handleErrors } from './utils/error-handling.js';
|
|
8
9
|
function createBundleMiddleware(context) {
|
|
9
|
-
const { moduleRegistry, moduleBundler } = context;
|
|
10
|
+
const { appConfig, moduleRegistry, moduleBundler, runtimeEnvironment: defaultRuntimeEnvironment, } = context;
|
|
10
11
|
const unsignedBundleRedirect = createUnsignedBundleRedirect(moduleBundler);
|
|
11
12
|
return async (req, res) => {
|
|
12
|
-
if (!req.validateEnvironmentRequest(
|
|
13
|
+
if (!req.validateEnvironmentRequest(appConfig)) {
|
|
13
14
|
res.status(400);
|
|
14
15
|
res.send(descriptions.UNRESOLVABLE.INVALID_ENVIRONMENT(req.params.environment).message);
|
|
15
16
|
return;
|
|
@@ -19,7 +20,7 @@ function createBundleMiddleware(context) {
|
|
|
19
20
|
res.send(descriptions.UNRESOLVABLE.INVALID_JSON().message);
|
|
20
21
|
return;
|
|
21
22
|
}
|
|
22
|
-
const { runtimeEnvironment, runtimeParams } = req.getRuntimeContext(
|
|
23
|
+
const { runtimeEnvironment, runtimeParams } = req.getRuntimeContext(defaultRuntimeEnvironment);
|
|
23
24
|
const importer = req.query.importer
|
|
24
25
|
? await getRequestImporter(req, moduleRegistry, runtimeParams)
|
|
25
26
|
: undefined;
|
|
@@ -29,9 +30,16 @@ function createBundleMiddleware(context) {
|
|
|
29
30
|
return;
|
|
30
31
|
}
|
|
31
32
|
const sourceMapUrl = req.path.replace('/bundle/', '/sourcemaps/bundle/');
|
|
32
|
-
const bundleDefinition = await
|
|
33
|
-
|
|
34
|
-
|
|
33
|
+
const bundleDefinition = await getTracer().trace({
|
|
34
|
+
name: RequestHandlerSpan.GetBundle,
|
|
35
|
+
attributes: {
|
|
36
|
+
specifier: moduleId.specifier,
|
|
37
|
+
},
|
|
38
|
+
}, () => {
|
|
39
|
+
return moduleBundler.getModuleBundle(moduleId,
|
|
40
|
+
// bundle must be `true` to properly resolve bundles in amd
|
|
41
|
+
{ ...runtimeEnvironment, bundle: true, sourceMapUrl }, runtimeParams);
|
|
42
|
+
});
|
|
35
43
|
if (req.isSiteGeneration()) {
|
|
36
44
|
res.setSiteGenerationMetadata({
|
|
37
45
|
moduleDefinition: bundleDefinition,
|
|
@@ -45,14 +53,14 @@ function createBundleMiddleware(context) {
|
|
|
45
53
|
};
|
|
46
54
|
}
|
|
47
55
|
function createSourceMapMiddleware(context) {
|
|
48
|
-
const { moduleBundler } = context;
|
|
56
|
+
const { appConfig, moduleBundler, runtimeEnvironment: defaultRuntimeEnvironment } = context;
|
|
49
57
|
return async (req, res) => {
|
|
50
|
-
if (!req.validateEnvironmentRequest(
|
|
58
|
+
if (!req.validateEnvironmentRequest(appConfig)) {
|
|
51
59
|
res.status(400);
|
|
52
60
|
res.send(descriptions.UNRESOLVABLE.INVALID_ENVIRONMENT(req.params.environment).message);
|
|
53
61
|
return;
|
|
54
62
|
}
|
|
55
|
-
const { runtimeEnvironment } = req.getRuntimeContext(
|
|
63
|
+
const { runtimeEnvironment } = req.getRuntimeContext(defaultRuntimeEnvironment);
|
|
56
64
|
const { moduleId, signature } = getModuleIdentity(req);
|
|
57
65
|
const bundleDef = await moduleBundler.getModuleBundle(moduleId, runtimeEnvironment);
|
|
58
66
|
if (signature !== LATEST_SIGNATURE) {
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { WebSocketServer } from 'ws';
|
|
2
|
+
import { logger } from '@lwrjs/diagnostics';
|
|
2
3
|
import { getCacheKeyFromJson } from '@lwrjs/shared-utils';
|
|
3
4
|
import { getRequestProperties } from './utils/request.js';
|
|
4
5
|
let hmr;
|
|
@@ -33,10 +34,10 @@ class Hmr {
|
|
|
33
34
|
});
|
|
34
35
|
wss.on('error', (error) => {
|
|
35
36
|
if (error.code === 'EADDRINUSE') {
|
|
36
|
-
|
|
37
|
+
logger.error(`HMR Socket Server: Port ${this.context.appConfig.port} already in use.`);
|
|
37
38
|
}
|
|
38
39
|
else {
|
|
39
|
-
|
|
40
|
+
logger.error(error);
|
|
40
41
|
}
|
|
41
42
|
});
|
|
42
43
|
}
|
|
@@ -44,7 +45,7 @@ class Hmr {
|
|
|
44
45
|
const { moduleRegistry } = this;
|
|
45
46
|
const { specifier, namespace, name, version, ownHash: signature, runtimeEnvironment, runtimeParams, } = moduleDefinition;
|
|
46
47
|
const { format, debug, compat } = runtimeEnvironment;
|
|
47
|
-
|
|
48
|
+
logger.info(`Recompiled module: ${specifier}, ${signature}`);
|
|
48
49
|
const moduleId = {
|
|
49
50
|
specifier,
|
|
50
51
|
namespace,
|
|
@@ -72,7 +73,7 @@ class Hmr {
|
|
|
72
73
|
}
|
|
73
74
|
}
|
|
74
75
|
updateTemplateOnClients(compiledView) {
|
|
75
|
-
|
|
76
|
+
logger.info('Recompiled view source', compiledView.viewId);
|
|
76
77
|
const { contentTemplate } = compiledView.viewId;
|
|
77
78
|
if (this.connectedClients && contentTemplate) {
|
|
78
79
|
for (const ws of this.connectedClients.keys()) {
|
|
@@ -87,7 +88,7 @@ class Hmr {
|
|
|
87
88
|
}
|
|
88
89
|
updateAssetOnClients(asset) {
|
|
89
90
|
const assetId = asset.entry;
|
|
90
|
-
|
|
91
|
+
logger.info(`Updated asset: ${assetId}`);
|
|
91
92
|
if (this.connectedClients) {
|
|
92
93
|
for (const ws of this.connectedClients.keys()) {
|
|
93
94
|
ws.send(JSON.stringify({
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
export function localeMiddleware(app, context) {
|
|
2
|
-
const { defaultLocale } = context.runtimeEnvironment;
|
|
2
|
+
const { i18n: { defaultLocale }, } = context.runtimeEnvironment;
|
|
3
3
|
app.use(async (req, _res, next) => {
|
|
4
4
|
const langs = req.acceptsLanguages();
|
|
5
5
|
req.locale = langs?.length > 0 && langs[0] != '*' ? langs[0] : defaultLocale;
|
|
@@ -1,18 +1,23 @@
|
|
|
1
1
|
import { getImportMetadataMappings } from '@lwrjs/shared-utils';
|
|
2
2
|
import { descriptions } from '@lwrjs/diagnostics';
|
|
3
|
+
import { RequestHandlerSpan, getTracer } from '@lwrjs/instrumentation';
|
|
3
4
|
import { getMappingIdentity } from './utils/identity.js';
|
|
4
5
|
import { handleErrors } from './utils/error-handling.js';
|
|
5
6
|
function createMappingMiddleware(context) {
|
|
6
|
-
const { moduleBundler, moduleRegistry } = context;
|
|
7
|
+
const { appConfig, moduleBundler, moduleRegistry, runtimeEnvironment: defaultRuntimeEnvironment, } = context;
|
|
7
8
|
return async (req, res) => {
|
|
8
|
-
if (!req.validateEnvironmentRequest(
|
|
9
|
+
if (!req.validateEnvironmentRequest(appConfig)) {
|
|
9
10
|
res.status(400);
|
|
10
11
|
res.send(descriptions.UNRESOLVABLE.INVALID_ENVIRONMENT(req.params.environment).message);
|
|
11
12
|
return;
|
|
12
13
|
}
|
|
13
|
-
const { runtimeEnvironment, runtimeParams } = req.getRuntimeContext(
|
|
14
|
+
const { runtimeEnvironment, runtimeParams } = req.getRuntimeContext(defaultRuntimeEnvironment);
|
|
14
15
|
const { moduleIds } = getMappingIdentity(req);
|
|
15
|
-
const importMetadata = await
|
|
16
|
+
const importMetadata = await getTracer().trace({
|
|
17
|
+
name: RequestHandlerSpan.GetMapping,
|
|
18
|
+
}, () => {
|
|
19
|
+
return getImportMetadataMappings(moduleIds, runtimeEnvironment, runtimeParams, moduleRegistry, moduleBundler);
|
|
20
|
+
});
|
|
16
21
|
if (req.isSiteGeneration()) {
|
|
17
22
|
res.setSiteGenerationMetadata({ importMetadata });
|
|
18
23
|
}
|
|
@@ -1,14 +1,15 @@
|
|
|
1
1
|
import { descriptions } from '@lwrjs/diagnostics';
|
|
2
2
|
import { LATEST_SIGNATURE, serializeModuleToJson } from '@lwrjs/shared-utils';
|
|
3
|
+
import { RequestHandlerSpan, getTracer } from '@lwrjs/instrumentation';
|
|
3
4
|
import { getRequestImporter } from './utils/request.js';
|
|
4
5
|
import { getModuleIdentity } from './utils/identity.js';
|
|
5
6
|
import { createUnsignedModuleRedirect } from './redirects/unsigned-module-redirect.js';
|
|
6
7
|
import { handleErrors } from './utils/error-handling.js';
|
|
7
8
|
function createModuleMiddleware(context) {
|
|
8
|
-
const { moduleRegistry } = context;
|
|
9
|
+
const { appConfig, moduleRegistry, runtimeEnvironment: defaultRuntimeEnvironment } = context;
|
|
9
10
|
const unsignedRedirect = createUnsignedModuleRedirect(moduleRegistry);
|
|
10
11
|
return async (req, res) => {
|
|
11
|
-
if (!req.validateEnvironmentRequest(
|
|
12
|
+
if (!req.validateEnvironmentRequest(appConfig)) {
|
|
12
13
|
res.status(400);
|
|
13
14
|
res.send(descriptions.UNRESOLVABLE.INVALID_ENVIRONMENT(req.params.environment).message);
|
|
14
15
|
return;
|
|
@@ -18,7 +19,7 @@ function createModuleMiddleware(context) {
|
|
|
18
19
|
res.send(descriptions.UNRESOLVABLE.INVALID_JSON().message);
|
|
19
20
|
return;
|
|
20
21
|
}
|
|
21
|
-
const { runtimeEnvironment, runtimeParams } = req.getRuntimeContext(
|
|
22
|
+
const { runtimeEnvironment, runtimeParams } = req.getRuntimeContext(defaultRuntimeEnvironment);
|
|
22
23
|
const importer = req.query.importer
|
|
23
24
|
? await getRequestImporter(req, moduleRegistry, runtimeParams)
|
|
24
25
|
: undefined;
|
|
@@ -27,9 +28,16 @@ function createModuleMiddleware(context) {
|
|
|
27
28
|
await unsignedRedirect(req, res, moduleId, runtimeEnvironment, runtimeParams);
|
|
28
29
|
return;
|
|
29
30
|
}
|
|
30
|
-
const moduleDefinition = await
|
|
31
|
-
|
|
32
|
-
|
|
31
|
+
const moduleDefinition = await getTracer().trace({
|
|
32
|
+
name: RequestHandlerSpan.GetModule,
|
|
33
|
+
attributes: {
|
|
34
|
+
specifier: moduleId.specifier,
|
|
35
|
+
},
|
|
36
|
+
}, () => {
|
|
37
|
+
return moduleRegistry.getLinkedModule(moduleId,
|
|
38
|
+
// bundle must be `false` to resolve amd modules in `prod-compat` mode
|
|
39
|
+
{ ...runtimeEnvironment, bundle: false }, runtimeParams);
|
|
40
|
+
});
|
|
33
41
|
const { ownHash, linkedSource } = moduleDefinition;
|
|
34
42
|
// validate the requested instances exists
|
|
35
43
|
if (signature !== LATEST_SIGNATURE && ownHash !== signature) {
|