@lwrjs/core 0.8.0-alpha.9 → 0.9.0-alpha.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.
@@ -43,7 +43,7 @@ async function runConfigurationsHook(hookPlugins, lwrConfig, dataConfig, runtime
43
43
  (0, import_config.validateLwrAppConfig)(JSON.stringify(lwrConfig), "post");
44
44
  } catch (e) {
45
45
  if (process.env.UNSAFE_IGNORE_CONFIG_VALIDATION === "true") {
46
- console.warn("ignoring config validation errors due to UNSAFE_IGNORE_CONFIG_VALIDATION flag...proceed with caution");
46
+ import_shared_utils.logger.warn("ignoring config validation errors due to UNSAFE_IGNORE_CONFIG_VALIDATION flag...proceed with caution");
47
47
  console.dir(e, {depth: null});
48
48
  } else {
49
49
  throw e;
@@ -37,7 +37,7 @@ var import_asset_registry = __toModule(require("@lwrjs/asset-registry"));
37
37
  var import_view_registry = __toModule(require("@lwrjs/view-registry"));
38
38
  var import_diagnostics = __toModule(require("@lwrjs/diagnostics"));
39
39
  var import_config = __toModule(require("@lwrjs/config"));
40
- var import_lwr_app_observer = __toModule(require("./lwr-app-observer.cjs"));
40
+ var import_shared_utils2 = __toModule(require("@lwrjs/shared-utils"));
41
41
  var import_locale_middleware = __toModule(require("./middlewares/locale-middleware.cjs"));
42
42
  var import_api_middleware = __toModule(require("./middlewares/api-middleware.cjs"));
43
43
  var import_ui_middleware = __toModule(require("./middlewares/ui-middleware.cjs"));
@@ -80,7 +80,7 @@ async function initContext(app, server, rawLwrConfig) {
80
80
  const hookProviders = await getServices(rawLwrConfig.hooks, void 0, rawLwrConfig);
81
81
  const {lwrConfig, dataConfig, runtimeConfig} = await (0, import_hooks.runConfigurationsHook)(hookProviders, rawLwrConfig, rawDataConfig, rawRuntimeEnvConfig);
82
82
  const assetTransformers = await getServices(rawLwrConfig.assetTransformers, void 0, rawLwrConfig);
83
- const appObserver = new import_lwr_app_observer.LwrApplicationObserver();
83
+ const appObserver = new import_shared_utils2.LwrApplicationObserver();
84
84
  const appEmitter = appObserver.createLwrEmitter();
85
85
  const compiler = new import_compiler.LwrCompiler();
86
86
  const assetRegistry = new import_asset_registry.LwrAssetRegistry({
@@ -264,7 +264,7 @@ async function generateStaticSite(config) {
264
264
  config.serverType = "fs";
265
265
  const {serverMode} = config;
266
266
  if (serverMode === "dev" || serverMode === "compat") {
267
- console.warn("[WARN] static generation in `dev` or `compat` mode is currently not fully supported");
267
+ import_shared_utils.logger.warn("static generation in `dev` or `compat` mode is currently not fully supported");
268
268
  }
269
269
  const lwrApp = createServer(config);
270
270
  overrideConfigAsSrc(lwrApp);
@@ -342,7 +342,7 @@ function apiMiddleware(app, context) {
342
342
  const specifier = req.params[0] ? `/${req.params[0]}` : req.originalUrl;
343
343
  const basePathSpecifier = `${basePath}${specifier}`;
344
344
  try {
345
- const assetObj = await context.assetRegistry.getAsset({specifier: basePathSpecifier, signature, type}, runtimeEnvironment);
345
+ const assetObj = await context.assetRegistry.getAsset({specifier: basePathSpecifier, signature, type}, runtimeEnvironment, req.isSiteGeneration());
346
346
  if (immutable) {
347
347
  }
348
348
  if (assetObj.mime) {
@@ -42,7 +42,7 @@ var Hmr = class {
42
42
  }
43
43
  setupHotModuleReload() {
44
44
  const {server} = this;
45
- const wss = new import_ws.default.Server({server});
45
+ const wss = new import_ws.WebSocketServer({server});
46
46
  const connectedClients = new Map();
47
47
  this.connectedClients = connectedClients;
48
48
  wss.on("connection", function connection(ws, req) {
@@ -31,6 +31,7 @@ var import_diagnostics = __toModule(require("@lwrjs/diagnostics"));
31
31
  var import_view_registry = __toModule(require("@lwrjs/view-registry"));
32
32
  var import_utils = __toModule(require("./utils.cjs"));
33
33
  var import_shared_utils = __toModule(require("@lwrjs/shared-utils"));
34
+ var import_router = __toModule(require("@lwrjs/router"));
34
35
  function uiMiddleware(app, context) {
35
36
  const {viewRegistry, moduleRegistry, runtimeEnvironment: defaultRuntimeEnvironment} = context;
36
37
  const {environment: environmentConfig, routes, errorRoutes} = context.appConfig;
@@ -145,16 +146,25 @@ function uiMiddleware(app, context) {
145
146
  await sendViewResponse(req, res, route);
146
147
  });
147
148
  } else {
148
- app.get(route.path, async (req, res) => {
149
- await sendViewResponse(req, res, route);
150
- });
151
- app.get([
152
- `/:apiVersion/application/:format/l/:locale/ai/:appId${route.path}`,
153
- `/:apiVersion/application/:format/l/:locale/e/:environment/ai/:appId${route.path}`,
154
- `/:apiVersion/application/:format/ai/:appId${route.path}`,
155
- `/:apiVersion/application/:format/e/:environment/ai/:appId${route.path}`
156
- ], async (req, res) => {
157
- await sendViewResponse(req, res, route);
149
+ const serverPath = route.path;
150
+ const paths = [serverPath];
151
+ const subRoutes = route.subRoutes ? (0, import_router.getClientRoutes)(route.subRoutes) : void 0;
152
+ if (subRoutes) {
153
+ const prefix = serverPath === "/" ? "" : serverPath;
154
+ subRoutes.routes.forEach((r) => paths.push(`${prefix}${r.uri}`));
155
+ }
156
+ paths.forEach((path) => {
157
+ app.get(path, async (req, res) => {
158
+ await sendViewResponse(req, res, route);
159
+ });
160
+ app.get([
161
+ `/:apiVersion/application/:format/l/:locale/ai/:appId${path}`,
162
+ `/:apiVersion/application/:format/l/:locale/e/:environment/ai/:appId${path}`,
163
+ `/:apiVersion/application/:format/ai/:appId${path}`,
164
+ `/:apiVersion/application/:format/e/:environment/ai/:appId${path}`
165
+ ], async (req, res) => {
166
+ await sendViewResponse(req, res, route);
167
+ });
158
168
  });
159
169
  }
160
170
  });
@@ -30,8 +30,12 @@ var import_static_generation = __toModule(require("./static-generation.cjs"));
30
30
  var import_dir = __toModule(require("./utils/dir.cjs"));
31
31
  var import_network_dispatcher = __toModule(require("./utils/network-dispatcher.cjs"));
32
32
  var import_config = __toModule(require("@lwrjs/config"));
33
+ var import_shared_utils = __toModule(require("@lwrjs/shared-utils"));
33
34
  async function warmupServer(config, internalRequestKey) {
34
- console.log("[Server Warmup] starting");
35
+ if (!import_shared_utils.logger.currentLevel || import_shared_utils.logger.currentLevel == import_shared_utils.WARN || import_shared_utils.logger.currentLevel == import_shared_utils.INFO) {
36
+ import_shared_utils.logger.setOptions({dedupe: new Set([import_shared_utils.WARN])});
37
+ }
38
+ import_shared_utils.logger.info("[Server Warmup] starting");
35
39
  const {routes, staticSiteGenerator, port, apiVersion, basePath, lwrVersion, serverMode} = config;
36
40
  staticSiteGenerator.outputDir = import_dir.skipDirCreation;
37
41
  const urlRewriteMap = new Map();
@@ -44,5 +48,5 @@ async function warmupServer(config, internalRequestKey) {
44
48
  serverMode
45
49
  };
46
50
  await new import_static_generation.default().generateRoutes(runtimeEnvironment, staticSiteGenerator, routes, new import_network_dispatcher.default(port, internalRequestKey), staticSiteGenerator.outputDir, urlRewriteMap);
47
- console.log("[Server Warmup] complete");
51
+ import_shared_utils.logger.info("[Server Warmup] complete");
48
52
  }
@@ -37,13 +37,16 @@ var import_config = __toModule(require("@lwrjs/config"));
37
37
  var SiteGenerator = class {
38
38
  async buildStaticApplication(config, dispatcher) {
39
39
  const startTime = import_perf_hooks.performance.now();
40
- console.log("[Static Generation] starting");
40
+ import_shared_utils.logger.info("[Static Generation] starting");
41
+ if (!import_shared_utils.logger.currentLevel || import_shared_utils.logger.currentLevel == import_shared_utils.WARN || import_shared_utils.logger.currentLevel == import_shared_utils.INFO) {
42
+ import_shared_utils.logger.setOptions({dedupe: new Set([import_shared_utils.WARN])});
43
+ }
41
44
  const {routes, staticSiteGenerator, rootDir, assets} = config;
42
45
  if (!staticSiteGenerator.outputDir) {
43
46
  staticSiteGenerator.outputDir = "__generated_site__";
44
47
  }
45
48
  const outputDir = (0, import_path.join)(rootDir, staticSiteGenerator.outputDir);
46
- console.log(`[INFO] Clear Output Location: ${outputDir}`);
49
+ import_shared_utils.logger.info(`Clear Output Location: ${outputDir}`);
47
50
  import_fs_extra.default.rmSync(outputDir, {recursive: true, force: true});
48
51
  const urlRewriteMap = new Map();
49
52
  const {apiVersion, basePath, lwrVersion, serverMode} = config;
@@ -60,7 +63,7 @@ var SiteGenerator = class {
60
63
  this.copyAssets(assets, outputDir);
61
64
  const endTime = import_perf_hooks.performance.now();
62
65
  const timeDiff = (endTime - startTime) / 1e3;
63
- console.log(`[Static Generation] complete in ${Math.round(timeDiff)} seconds`);
66
+ import_shared_utils.logger.info(`[Static Generation] complete in ${Math.round(timeDiff)} seconds`);
64
67
  }
65
68
  async generateRoutes(runtimeEnvironment, staticSiteGenerator, routes, dispatcher, outputDir, urlRewriteMap = new Map()) {
66
69
  if (!staticSiteGenerator.locales) {
@@ -90,10 +93,10 @@ var SiteGenerator = class {
90
93
  createGenerateURLFunction(dispatcher) {
91
94
  const generateRoute = async (uri, siteConfig) => {
92
95
  const locale = siteConfig.locale;
93
- console.log(`[INFO] Start Generate: ${locale} ${uri}`);
96
+ import_shared_utils.logger.info(`Start Generate: ${locale} ${uri}`);
94
97
  await this.dispatchResourceRecursive(uri, dispatcher, {resourceType: "route"}, siteConfig);
95
98
  this.addAdditionalImportMetadataToViewConfig(siteConfig);
96
- console.log(`[INFO] End Generate ${locale} ${uri}`);
99
+ import_shared_utils.logger.info(`End Generate ${locale} ${uri}`);
97
100
  };
98
101
  return generateRoute.bind(this);
99
102
  }
@@ -102,7 +105,7 @@ var SiteGenerator = class {
102
105
  if (!visitedUrls.has(url)) {
103
106
  visitedUrls.add(url);
104
107
  if (url.indexOf("/:") !== -1 || url.indexOf("*") !== -1) {
105
- console.error("Skipped generation of url with variable path segment: " + url);
108
+ import_shared_utils.logger.warn("Skipped generation of url with variable path segment: " + url);
106
109
  return;
107
110
  }
108
111
  let context;
@@ -117,7 +120,7 @@ var SiteGenerator = class {
117
120
  if (resourceType === "route") {
118
121
  await this.handleHtmlResource(url, context, siteConfig, dispatcher);
119
122
  } else if (resourceType === "asset" || resourceType === "resource") {
120
- await this.handleAssetOrResource(url, context, siteConfig);
123
+ await this.handleAssetOrResource(url, context, siteConfig, dispatcher);
121
124
  } else if (resourceType == "mapping") {
122
125
  await this.handleMappingResource(url, context, siteConfig, dispatcher);
123
126
  } else if (resourceType === "js") {
@@ -176,7 +179,7 @@ var SiteGenerator = class {
176
179
  await Promise.all(dispatchRequests);
177
180
  } else {
178
181
  const body = context.fs?.body;
179
- console.warn(`[WARN] Failed to fetch ${url}: (${statusCode}) ${body}`);
182
+ import_shared_utils.logger.warn(`Failed to fetch ${url}: (${statusCode}) ${body}`);
180
183
  }
181
184
  }
182
185
  async handleHtmlResource(url, context, siteConfig, dispatcher) {
@@ -212,7 +215,7 @@ var SiteGenerator = class {
212
215
  const assets = viewDefinition.viewRecord.assetReferences || [];
213
216
  for (const asset of assets) {
214
217
  const assetUrl = asset.override?.uri || asset.url;
215
- if (assetUrl && !assetUrl.startsWith("data:")) {
218
+ if (assetUrl && !(0, import_shared_utils.isSelfUrl)(assetUrl)) {
216
219
  dispatchRequests.push(this.dispatchResourceRecursive(assetUrl, dispatcher, {resourceType: "asset", asset}, siteConfig));
217
220
  }
218
221
  }
@@ -240,7 +243,7 @@ var SiteGenerator = class {
240
243
  siteConfig.viewConfigPath = this.getResourcePathFromUrl(siteConfig, resourceUri);
241
244
  }
242
245
  } else {
243
- console.warn("Skipped inline bootstrap resource: %j", resource);
246
+ import_shared_utils.logger.warn("Skipped inline bootstrap resource: %j", resource);
244
247
  }
245
248
  }
246
249
  }
@@ -250,7 +253,7 @@ var SiteGenerator = class {
250
253
  if (resourceUri.startsWith("/")) {
251
254
  dispatchRequests.push(this.dispatchResourceRecursive(resourceUri, dispatcher, {resourceType: "resource"}, siteConfig));
252
255
  } else {
253
- console.warn("Skipped resource: %j", resource);
256
+ import_shared_utils.logger.warn("Skipped resource: %j", resource);
254
257
  }
255
258
  }
256
259
  await Promise.all(dispatchRequests);
@@ -266,7 +269,7 @@ var SiteGenerator = class {
266
269
  const mappingURL = siteConfig.endpoints?.uris?.mapping + encodeURIComponent(jsUri);
267
270
  await this.dispatchResourceRecursive(mappingURL, dispatcher, {resourceType: "mapping"}, siteConfig);
268
271
  } else {
269
- console.warn('[WARN] Unable to fetch mapping for bare specifier or variable dynamic import: "' + jsUri + '"');
272
+ import_shared_utils.logger.warn('Unable to fetch mapping for bare specifier or variable dynamic import: "' + jsUri + '"');
270
273
  }
271
274
  } else if (isAdditionalModulesRequest) {
272
275
  const uri = `${siteConfig.endpoints?.uris.legacyDefault}${encodeURIComponent(jsUri)}`;
@@ -274,9 +277,19 @@ var SiteGenerator = class {
274
277
  }
275
278
  }
276
279
  }
277
- async handleAssetOrResource(url, context, siteConfig) {
280
+ async handleAssetOrResource(url, context, siteConfig, dispatcher) {
281
+ const metadata = context.fs?.metadata;
278
282
  const fullPath = this.getResourcePathFromUrl(siteConfig, url);
279
283
  await (0, import_stream.writeResponse)(context, fullPath);
284
+ const assetReferences = metadata?.asset?.metadata?.assetReferences || [];
285
+ const dispatchRequests = [];
286
+ for (const ref of assetReferences) {
287
+ const refUrl = ref.override?.uri || ref.url;
288
+ dispatchRequests.push(this.dispatchResourceRecursive(refUrl, dispatcher, {resourceType: "asset", asset: metadata?.asset}, siteConfig).catch((err) => {
289
+ import_shared_utils.logger.warn(`Failed to fetch asset reference => ${refUrl} from ${url}`, err);
290
+ }));
291
+ }
292
+ return Promise.all(dispatchRequests);
280
293
  }
281
294
  getResourcePathFromUrl(siteConfig, url) {
282
295
  const {outputDir} = siteConfig;
@@ -310,11 +323,10 @@ var SiteGenerator = class {
310
323
  if (assetSrcDir && import_fs_extra.default.existsSync(assetSrcDir)) {
311
324
  import_fs_extra.default.copySync(assetSrcDir, assetOutputDir);
312
325
  } else {
313
- throw new Error("Could not find assets to copy at path: " + assetSrcDir);
326
+ import_shared_utils.logger.warn("Could not find assets to copy at path: " + assetSrcDir);
314
327
  }
315
328
  } catch (e) {
316
- console.error("Error occurred processing asset config: " + JSON.stringify(asset));
317
- console.error(e);
329
+ import_shared_utils.logger.error("Error occurred processing asset config: " + JSON.stringify(asset), e);
318
330
  }
319
331
  }
320
332
  }
@@ -1,4 +1,4 @@
1
- import { DEFAULT_LWR_BOOTSTRAP_CONFIG } from '@lwrjs/shared-utils';
1
+ import { DEFAULT_LWR_BOOTSTRAP_CONFIG, logger } from '@lwrjs/shared-utils';
2
2
  import { validateLwrAppConfig } from '@lwrjs/config';
3
3
  // Add missing bootstrap objects to routes
4
4
  function normalizeRoutesBootstrap({ routes, errorRoutes }) {
@@ -19,7 +19,7 @@ export async function runConfigurationsHook(hookPlugins, lwrConfig, dataConfig,
19
19
  catch (e) {
20
20
  // TODO: temporary workaround for https://github.com/salesforce/lwr/issues/825
21
21
  if (process.env.UNSAFE_IGNORE_CONFIG_VALIDATION === 'true') {
22
- console.warn('ignoring config validation errors due to UNSAFE_IGNORE_CONFIG_VALIDATION flag...proceed with caution');
22
+ logger.warn('ignoring config validation errors due to UNSAFE_IGNORE_CONFIG_VALIDATION flag...proceed with caution');
23
23
  console.dir(e, { depth: null });
24
24
  }
25
25
  else {
package/build/es/index.js CHANGED
@@ -1,4 +1,4 @@
1
- import { deepFreeze, getFeatureFlags, DEFAULT_LWR_BOOTSTRAP_CONFIG } from '@lwrjs/shared-utils';
1
+ import { deepFreeze, getFeatureFlags, DEFAULT_LWR_BOOTSTRAP_CONFIG, logger } from '@lwrjs/shared-utils';
2
2
  import { LwrCompiler } from '@lwrjs/compiler';
3
3
  import { LwrModuleBundler } from '@lwrjs/module-bundler';
4
4
  import { LwrModuleRegistry } from '@lwrjs/module-registry';
@@ -7,7 +7,7 @@ import { LwrAssetRegistry } from '@lwrjs/asset-registry';
7
7
  import { LwrViewRegistry } from '@lwrjs/view-registry';
8
8
  import { LwrServerError, createSingleDiagnosticError, descriptions } from '@lwrjs/diagnostics';
9
9
  import { normalizeConfig, explodeMode } from '@lwrjs/config';
10
- import { LwrApplicationObserver } from './lwr-app-observer.js';
10
+ import { LwrApplicationObserver } from '@lwrjs/shared-utils';
11
11
  import localeMiddleware from './middlewares/locale-middleware.js';
12
12
  import apiMiddleware from './middlewares/api-middleware.js';
13
13
  import uiMiddleware from './middlewares/ui-middleware.js';
@@ -235,7 +235,7 @@ export async function generateStaticSite(config) {
235
235
  if (serverMode === 'dev' || serverMode === 'compat') {
236
236
  // TODO: dynamic imports are not generated in dev mode
237
237
  // https://github.com/salesforce/lwr/issues/1111
238
- console.warn('[WARN] static generation in `dev` or `compat` mode is currently not fully supported');
238
+ logger.warn('static generation in `dev` or `compat` mode is currently not fully supported');
239
239
  }
240
240
  const lwrApp = createServer(config);
241
241
  overrideConfigAsSrc(lwrApp);
@@ -390,7 +390,7 @@ export default function apiMiddleware(app, context) {
390
390
  const specifier = req.params[0] ? `/${req.params[0]}` : req.originalUrl;
391
391
  const basePathSpecifier = `${basePath}${specifier}`;
392
392
  try {
393
- const assetObj = await context.assetRegistry.getAsset({ specifier: basePathSpecifier, signature, type: type }, runtimeEnvironment);
393
+ const assetObj = await context.assetRegistry.getAsset({ specifier: basePathSpecifier, signature, type: type }, runtimeEnvironment, req.isSiteGeneration());
394
394
  if (immutable) {
395
395
  // WIP: ?
396
396
  }
@@ -1,4 +1,4 @@
1
- import WebSocket from 'ws';
1
+ import { WebSocketServer } from 'ws';
2
2
  import { getCacheKeyFromJson } from '@lwrjs/shared-utils';
3
3
  import { getRequestProperties } from './utils.js';
4
4
  let hmr;
@@ -14,7 +14,7 @@ class Hmr {
14
14
  }
15
15
  setupHotModuleReload() {
16
16
  const { server } = this;
17
- const wss = new WebSocket.Server({ server });
17
+ const wss = new WebSocketServer({ server });
18
18
  const connectedClients = new Map();
19
19
  this.connectedClients = connectedClients;
20
20
  wss.on('connection', function connection(ws, req) {
@@ -3,6 +3,7 @@ import { DiagnosticsError } from '@lwrjs/diagnostics';
3
3
  import { LwrViewHandler } from '@lwrjs/view-registry';
4
4
  import { isSupportedEnvironment } from './utils.js';
5
5
  import { decodeViewPath, getClientBootstrapConfigurationRoutes, extractRequestParams, } from '@lwrjs/shared-utils';
6
+ import { getClientRoutes } from '@lwrjs/router';
6
7
  export default function uiMiddleware(app, context) {
7
8
  const { viewRegistry, moduleRegistry, runtimeEnvironment: defaultRuntimeEnvironment } = context;
8
9
  const { environment: environmentConfig, routes, errorRoutes } = context.appConfig;
@@ -135,18 +136,30 @@ export default function uiMiddleware(app, context) {
135
136
  });
136
137
  }
137
138
  else {
138
- // vanity urls
139
- app.get(route.path, async (req, res) => {
140
- await sendViewResponse(req, res, route);
141
- });
142
- // canonical URL
143
- app.get([
144
- `/:apiVersion/application/:format/l/:locale/ai/:appId${route.path}`,
145
- `/:apiVersion/application/:format/l/:locale/e/:environment/ai/:appId${route.path}`,
146
- `/:apiVersion/application/:format/ai/:appId${route.path}`,
147
- `/:apiVersion/application/:format/e/:environment/ai/:appId${route.path}`,
148
- ], async (req, res) => {
149
- await sendViewResponse(req, res, route);
139
+ // Get the client-side routes
140
+ const serverPath = route.path;
141
+ const paths = [serverPath];
142
+ const subRoutes = route.subRoutes ? getClientRoutes(route.subRoutes) : undefined;
143
+ if (subRoutes) {
144
+ // Concatenate each client uri to the server route.path, creating the full list of composite paths
145
+ const prefix = serverPath === '/' ? '' : serverPath;
146
+ subRoutes.routes.forEach((r) => paths.push(`${prefix}${r.uri}`));
147
+ }
148
+ // Register the server route.path and each composite client path, to enable full page refreshes of client pages
149
+ paths.forEach((path) => {
150
+ // vanity urls
151
+ app.get(path, async (req, res) => {
152
+ await sendViewResponse(req, res, route);
153
+ });
154
+ // canonical URL
155
+ app.get([
156
+ `/:apiVersion/application/:format/l/:locale/ai/:appId${path}`,
157
+ `/:apiVersion/application/:format/l/:locale/e/:environment/ai/:appId${path}`,
158
+ `/:apiVersion/application/:format/ai/:appId${path}`,
159
+ `/:apiVersion/application/:format/e/:environment/ai/:appId${path}`,
160
+ ], async (req, res) => {
161
+ await sendViewResponse(req, res, route);
162
+ });
150
163
  });
151
164
  }
152
165
  });
@@ -2,8 +2,13 @@ import SiteGenerator from './static-generation.js';
2
2
  import { skipDirCreation } from './utils/dir.js';
3
3
  import NetworkDispatcher from './utils/network-dispatcher.js';
4
4
  import { explodeMode } from '@lwrjs/config';
5
+ import { logger, WARN, INFO } from '@lwrjs/shared-utils';
5
6
  export async function warmupServer(config, internalRequestKey) {
6
- console.log('[Server Warmup] starting');
7
+ // De-duplicate warming messages if log level is warn or info
8
+ if (!logger.currentLevel || logger.currentLevel == WARN || logger.currentLevel == INFO) {
9
+ logger.setOptions({ dedupe: new Set([WARN]) });
10
+ }
11
+ logger.info('[Server Warmup] starting');
7
12
  const { routes, staticSiteGenerator, port, apiVersion, basePath, lwrVersion, serverMode } = config;
8
13
  staticSiteGenerator.outputDir = skipDirCreation;
9
14
  const urlRewriteMap = new Map();
@@ -17,6 +22,6 @@ export async function warmupServer(config, internalRequestKey) {
17
22
  };
18
23
  // For each locale, generate all the modules
19
24
  await new SiteGenerator().generateRoutes(runtimeEnvironment, staticSiteGenerator, routes, new NetworkDispatcher(port, internalRequestKey), staticSiteGenerator.outputDir, urlRewriteMap);
20
- console.log('[Server Warmup] complete');
25
+ logger.info('[Server Warmup] complete');
21
26
  }
22
27
  //# sourceMappingURL=server-warmup.js.map
@@ -1,5 +1,5 @@
1
1
  import { performance } from 'perf_hooks';
2
- import { getSpecifier, getFeatureFlags, hashContent, getModuleUriPrefix, getMappingUriPrefix, } from '@lwrjs/shared-utils';
2
+ import { getSpecifier, getFeatureFlags, hashContent, isSelfUrl, getModuleUriPrefix, getMappingUriPrefix, logger, WARN, INFO, } from '@lwrjs/shared-utils';
3
3
  import { join, dirname, extname } from 'path';
4
4
  import fs from 'fs-extra';
5
5
  import { writeResponse } from './utils/stream.js';
@@ -16,13 +16,17 @@ export default class SiteGenerator {
16
16
  */
17
17
  async buildStaticApplication(config, dispatcher) {
18
18
  const startTime = performance.now();
19
- console.log('[Static Generation] starting');
19
+ logger.info('[Static Generation] starting');
20
+ // De-duplicate warming messages if log level is warn or info
21
+ if (!logger.currentLevel || logger.currentLevel == WARN || logger.currentLevel == INFO) {
22
+ logger.setOptions({ dedupe: new Set([WARN]) });
23
+ }
20
24
  const { routes, staticSiteGenerator, rootDir, assets } = config;
21
25
  if (!staticSiteGenerator.outputDir) {
22
26
  staticSiteGenerator.outputDir = '__generated_site__';
23
27
  }
24
28
  const outputDir = join(rootDir, staticSiteGenerator.outputDir);
25
- console.log(`[INFO] Clear Output Location: ${outputDir}`);
29
+ logger.info(`Clear Output Location: ${outputDir}`);
26
30
  fs.rmSync(outputDir, { recursive: true, force: true });
27
31
  const urlRewriteMap = new Map();
28
32
  const { apiVersion, basePath, lwrVersion, serverMode } = config;
@@ -42,7 +46,7 @@ export default class SiteGenerator {
42
46
  this.copyAssets(assets, outputDir);
43
47
  const endTime = performance.now();
44
48
  const timeDiff = (endTime - startTime) / 1000;
45
- console.log(`[Static Generation] complete in ${Math.round(timeDiff)} seconds`);
49
+ logger.info(`[Static Generation] complete in ${Math.round(timeDiff)} seconds`);
46
50
  }
47
51
  /**
48
52
  * Crawl all view routes for a site
@@ -85,12 +89,12 @@ export default class SiteGenerator {
85
89
  createGenerateURLFunction(dispatcher) {
86
90
  const generateRoute = async (uri, siteConfig) => {
87
91
  const locale = siteConfig.locale;
88
- console.log(`[INFO] Start Generate: ${locale} ${uri}`);
92
+ logger.info(`Start Generate: ${locale} ${uri}`);
89
93
  // Kick off site generation for the current route
90
94
  await this.dispatchResourceRecursive(uri, dispatcher, { resourceType: 'route' }, siteConfig);
91
95
  // If there is a view config add any extra collected import metadata to the config
92
96
  this.addAdditionalImportMetadataToViewConfig(siteConfig);
93
- console.log(`[INFO] End Generate ${locale} ${uri}`);
97
+ logger.info(`End Generate ${locale} ${uri}`);
94
98
  };
95
99
  return generateRoute.bind(this);
96
100
  }
@@ -109,7 +113,7 @@ export default class SiteGenerator {
109
113
  // Skip urls with path segment variables (i.e. '/custom/:bar')
110
114
  // Users can specify specific urls via the '_additionalRoutePaths' config property
111
115
  if (url.indexOf('/:') !== -1 || url.indexOf('*') !== -1) {
112
- console.error('Skipped generation of url with variable path segment: ' + url);
116
+ logger.warn('Skipped generation of url with variable path segment: ' + url);
113
117
  return;
114
118
  }
115
119
  // Generate resource
@@ -129,7 +133,7 @@ export default class SiteGenerator {
129
133
  // -- Process Assets (css, images, ...) && Resources (lwr-loader-shim ...)
130
134
  }
131
135
  else if (resourceType === 'asset' || resourceType === 'resource') {
132
- await this.handleAssetOrResource(url, context, siteConfig);
136
+ await this.handleAssetOrResource(url, context, siteConfig, dispatcher);
133
137
  // -- Import Metadata Mappings
134
138
  }
135
139
  else if (resourceType == 'mapping') {
@@ -240,7 +244,7 @@ export default class SiteGenerator {
240
244
  }
241
245
  else {
242
246
  const body = context.fs?.body;
243
- console.warn(`[WARN] Failed to fetch ${url}: (${statusCode}) ${body}`);
247
+ logger.warn(`Failed to fetch ${url}: (${statusCode}) ${body}`);
244
248
  }
245
249
  }
246
250
  /**
@@ -306,8 +310,8 @@ export default class SiteGenerator {
306
310
  const assets = viewDefinition.viewRecord.assetReferences || [];
307
311
  for (const asset of assets) {
308
312
  const assetUrl = asset.override?.uri || asset.url;
309
- // skip empty asset urls / data urls (i.e. <img src="" /> <img src="data:image/png;base64, iVBORw0..." />)
310
- if (assetUrl && !assetUrl.startsWith('data:')) {
313
+ // skip self referential asset urls / data urls (i.e. <img src="" /> <img src="data:image/png;base64, iVBORw0..." />)
314
+ if (assetUrl && !isSelfUrl(assetUrl)) {
311
315
  dispatchRequests.push(this.dispatchResourceRecursive(assetUrl, dispatcher, { resourceType: 'asset', asset }, siteConfig));
312
316
  }
313
317
  }
@@ -341,7 +345,7 @@ export default class SiteGenerator {
341
345
  }
342
346
  }
343
347
  else {
344
- console.warn('Skipped inline bootstrap resource: %j', resource);
348
+ logger.warn('Skipped inline bootstrap resource: %j', resource);
345
349
  }
346
350
  }
347
351
  }
@@ -353,7 +357,7 @@ export default class SiteGenerator {
353
357
  dispatchRequests.push(this.dispatchResourceRecursive(resourceUri, dispatcher, { resourceType: 'resource' }, siteConfig));
354
358
  }
355
359
  else {
356
- console.warn('Skipped resource: %j', resource);
360
+ logger.warn('Skipped resource: %j', resource);
357
361
  }
358
362
  }
359
363
  // -- Dispatch dependencies
@@ -373,7 +377,7 @@ export default class SiteGenerator {
373
377
  await this.dispatchResourceRecursive(mappingURL, dispatcher, { resourceType: 'mapping' }, siteConfig);
374
378
  }
375
379
  else {
376
- console.warn('[WARN] Unable to fetch mapping for bare specifier or variable dynamic import: "' +
380
+ logger.warn('Unable to fetch mapping for bare specifier or variable dynamic import: "' +
377
381
  jsUri +
378
382
  '"');
379
383
  }
@@ -394,9 +398,21 @@ export default class SiteGenerator {
394
398
  * @param context - Response Context
395
399
  * @param siteConfig - Global metadata about the site
396
400
  */
397
- async handleAssetOrResource(url, context, siteConfig) {
401
+ async handleAssetOrResource(url, context, siteConfig, dispatcher) {
402
+ const metadata = context.fs?.metadata;
398
403
  const fullPath = this.getResourcePathFromUrl(siteConfig, url);
399
404
  await writeResponse(context, fullPath);
405
+ // Call and referenced assets...
406
+ const assetReferences = metadata?.asset?.metadata?.assetReferences || [];
407
+ const dispatchRequests = [];
408
+ for (const ref of assetReferences) {
409
+ const refUrl = ref.override?.uri || ref.url;
410
+ dispatchRequests.push(this.dispatchResourceRecursive(refUrl, dispatcher, { resourceType: 'asset', asset: metadata?.asset }, siteConfig).catch((err) => {
411
+ // Warn the user that the we failed to fetch a referenced asset
412
+ logger.warn(`Failed to fetch asset reference => ${refUrl} from ${url}`, err);
413
+ }));
414
+ }
415
+ return Promise.all(dispatchRequests);
400
416
  }
401
417
  getResourcePathFromUrl(siteConfig, url) {
402
418
  const { outputDir } = siteConfig;
@@ -451,12 +467,11 @@ export default class SiteGenerator {
451
467
  fs.copySync(assetSrcDir, assetOutputDir);
452
468
  }
453
469
  else {
454
- throw new Error('Could not find assets to copy at path: ' + assetSrcDir);
470
+ logger.warn('Could not find assets to copy at path: ' + assetSrcDir);
455
471
  }
456
472
  }
457
473
  catch (e) {
458
- console.error('Error occurred processing asset config: ' + JSON.stringify(asset));
459
- console.error(e);
474
+ logger.error('Error occurred processing asset config: ' + JSON.stringify(asset), e);
460
475
  }
461
476
  }
462
477
  }
@@ -8,7 +8,7 @@ export interface RouteResourceOpts extends BaseResourceContextOpts {
8
8
  }
9
9
  export interface AssetResourceOpts extends BaseResourceContextOpts {
10
10
  resourceType: 'asset';
11
- asset: RenderedAssetReference;
11
+ asset?: RenderedAssetReference;
12
12
  }
13
13
  export interface JsResourceOpts extends BaseResourceContextOpts {
14
14
  resourceType: 'js';
package/package.json CHANGED
@@ -4,7 +4,7 @@
4
4
  "publishConfig": {
5
5
  "access": "public"
6
6
  },
7
- "version": "0.8.0-alpha.9",
7
+ "version": "0.9.0-alpha.0",
8
8
  "homepage": "https://developer.salesforce.com/docs/platform/lwr/overview",
9
9
  "repository": {
10
10
  "type": "git",
@@ -32,45 +32,47 @@
32
32
  "package.cjs"
33
33
  ],
34
34
  "dependencies": {
35
- "@lwrjs/app-service": "0.8.0-alpha.9",
36
- "@lwrjs/asset-registry": "0.8.0-alpha.9",
37
- "@lwrjs/asset-transformer": "0.8.0-alpha.9",
38
- "@lwrjs/base-template-engine": "0.8.0-alpha.9",
39
- "@lwrjs/base-view-provider": "0.8.0-alpha.9",
40
- "@lwrjs/base-view-transformer": "0.8.0-alpha.9",
41
- "@lwrjs/client-modules": "0.8.0-alpha.9",
42
- "@lwrjs/compiler": "0.8.0-alpha.9",
43
- "@lwrjs/config": "0.8.0-alpha.9",
44
- "@lwrjs/diagnostics": "0.8.0-alpha.9",
45
- "@lwrjs/fs-asset-provider": "0.8.0-alpha.9",
46
- "@lwrjs/html-view-provider": "0.8.0-alpha.9",
47
- "@lwrjs/loader": "0.8.0-alpha.9",
48
- "@lwrjs/lwc-module-provider": "0.8.0-alpha.9",
49
- "@lwrjs/lwc-ssr": "0.8.0-alpha.9",
50
- "@lwrjs/markdown-view-provider": "0.8.0-alpha.9",
51
- "@lwrjs/module-bundler": "0.8.0-alpha.9",
52
- "@lwrjs/module-registry": "0.8.0-alpha.9",
53
- "@lwrjs/npm-module-provider": "0.8.0-alpha.9",
54
- "@lwrjs/nunjucks-view-provider": "0.8.0-alpha.9",
55
- "@lwrjs/o11y": "0.8.0-alpha.9",
56
- "@lwrjs/resource-registry": "0.8.0-alpha.9",
57
- "@lwrjs/router": "0.8.0-alpha.9",
58
- "@lwrjs/server": "0.8.0-alpha.9",
59
- "@lwrjs/shared-utils": "0.8.0-alpha.9",
60
- "@lwrjs/view-registry": "0.8.0-alpha.9",
35
+ "@lwrjs/app-service": "0.9.0-alpha.0",
36
+ "@lwrjs/asset-registry": "0.9.0-alpha.0",
37
+ "@lwrjs/asset-transformer": "0.9.0-alpha.0",
38
+ "@lwrjs/base-template-engine": "0.9.0-alpha.0",
39
+ "@lwrjs/base-view-provider": "0.9.0-alpha.0",
40
+ "@lwrjs/base-view-transformer": "0.9.0-alpha.0",
41
+ "@lwrjs/client-modules": "0.9.0-alpha.0",
42
+ "@lwrjs/compiler": "0.9.0-alpha.0",
43
+ "@lwrjs/config": "0.9.0-alpha.0",
44
+ "@lwrjs/diagnostics": "0.9.0-alpha.0",
45
+ "@lwrjs/fs-asset-provider": "0.9.0-alpha.0",
46
+ "@lwrjs/html-view-provider": "0.9.0-alpha.0",
47
+ "@lwrjs/loader": "0.9.0-alpha.0",
48
+ "@lwrjs/lwc-module-provider": "0.9.0-alpha.0",
49
+ "@lwrjs/lwc-ssr": "0.9.0-alpha.0",
50
+ "@lwrjs/markdown-view-provider": "0.9.0-alpha.0",
51
+ "@lwrjs/module-bundler": "0.9.0-alpha.0",
52
+ "@lwrjs/module-registry": "0.9.0-alpha.0",
53
+ "@lwrjs/npm-module-provider": "0.9.0-alpha.0",
54
+ "@lwrjs/nunjucks-view-provider": "0.9.0-alpha.0",
55
+ "@lwrjs/o11y": "0.9.0-alpha.0",
56
+ "@lwrjs/resource-registry": "0.9.0-alpha.0",
57
+ "@lwrjs/router": "0.9.0-alpha.0",
58
+ "@lwrjs/server": "0.9.0-alpha.0",
59
+ "@lwrjs/shared-utils": "0.9.0-alpha.0",
60
+ "@lwrjs/view-registry": "0.9.0-alpha.0",
61
61
  "fs-extra": "^10.1.0",
62
62
  "ms": "^2.1.3",
63
63
  "path-to-regexp": "^6.2.0",
64
- "qs": "^6.9.4"
64
+ "qs": "^6.9.4",
65
+ "ws": "^8.8.1"
65
66
  },
66
67
  "devDependencies": {
67
- "@lwrjs/types": "0.8.0-alpha.9"
68
+ "@lwrjs/types": "0.9.0-alpha.0",
69
+ "@types/ws": "^8.5.3"
68
70
  },
69
71
  "peerDependencies": {
70
- "lwc": ">= 1.x <= 2.x"
72
+ "lwc": "2.x"
71
73
  },
72
74
  "engines": {
73
75
  "node": ">=14.15.4 <19"
74
76
  },
75
- "gitHead": "037c471903c6753fc6866ef598571b0df83e58f9"
77
+ "gitHead": "6890d8619b295a49ee1ed8253a372337d83863be"
76
78
  }
@@ -1,82 +0,0 @@
1
- var __create = Object.create;
2
- var __defProp = Object.defineProperty;
3
- var __getProtoOf = Object.getPrototypeOf;
4
- var __hasOwnProp = Object.prototype.hasOwnProperty;
5
- var __getOwnPropNames = Object.getOwnPropertyNames;
6
- var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
7
- var __markAsModule = (target) => __defProp(target, "__esModule", {value: true});
8
- var __export = (target, all) => {
9
- for (var name in all)
10
- __defProp(target, name, {get: all[name], enumerable: true});
11
- };
12
- var __exportStar = (target, module2, desc) => {
13
- if (module2 && typeof module2 === "object" || typeof module2 === "function") {
14
- for (let key of __getOwnPropNames(module2))
15
- if (!__hasOwnProp.call(target, key) && key !== "default")
16
- __defProp(target, key, {get: () => module2[key], enumerable: !(desc = __getOwnPropDesc(module2, key)) || desc.enumerable});
17
- }
18
- return target;
19
- };
20
- var __toModule = (module2) => {
21
- return __exportStar(__markAsModule(__defProp(module2 != null ? __create(__getProtoOf(module2)) : {}, "default", module2 && module2.__esModule && "default" in module2 ? {get: () => module2.default, enumerable: true} : {value: module2, enumerable: true})), module2);
22
- };
23
-
24
- // packages/@lwrjs/core/src/lwr-app-observer.ts
25
- __markAsModule(exports);
26
- __export(exports, {
27
- LwrApplicationObserver: () => LwrApplicationObserver
28
- });
29
- var import_events = __toModule(require("events"));
30
- var MODULE_DEF_CHANGED_EVENT = "module_definition_changed";
31
- var MODULE_SOURCE_CHANGED_EVENT = "module_source_changed";
32
- var VIEW_SOURCE_CHANGED_EVENT = "view_source_changed";
33
- var ASSET_SOURCE_CHANGED_EVENT = "asset_source_changed";
34
- var LwrEmitter = class {
35
- constructor(observer) {
36
- this.observer = observer;
37
- }
38
- notifyAssetSourceChanged(payload) {
39
- this.observer.emit(ASSET_SOURCE_CHANGED_EVENT, {
40
- eventType: ASSET_SOURCE_CHANGED_EVENT,
41
- payload
42
- });
43
- }
44
- notifyViewSourceChanged(payload) {
45
- this.observer.emit(VIEW_SOURCE_CHANGED_EVENT, {
46
- eventType: VIEW_SOURCE_CHANGED_EVENT,
47
- payload
48
- });
49
- }
50
- notifyModuleDefinitionChanged(payload) {
51
- this.observer.emit(MODULE_DEF_CHANGED_EVENT, {
52
- eventType: MODULE_DEF_CHANGED_EVENT,
53
- payload
54
- });
55
- }
56
- notifyModuleSourceChanged(payload) {
57
- this.observer.emit(MODULE_SOURCE_CHANGED_EVENT, {
58
- eventType: MODULE_SOURCE_CHANGED_EVENT,
59
- payload
60
- });
61
- }
62
- };
63
- var LwrApplicationObserver = class extends import_events.EventEmitter {
64
- constructor() {
65
- super();
66
- }
67
- onModuleDefinitionChange(listener) {
68
- this.on(MODULE_DEF_CHANGED_EVENT, listener);
69
- }
70
- onModuleSourceChange(listener) {
71
- this.on(MODULE_SOURCE_CHANGED_EVENT, listener);
72
- }
73
- onViewSourceChange(listener) {
74
- this.on(VIEW_SOURCE_CHANGED_EVENT, listener);
75
- }
76
- onAssetSourceChange(listener) {
77
- this.on(ASSET_SOURCE_CHANGED_EVENT, listener);
78
- }
79
- createLwrEmitter() {
80
- return new LwrEmitter(this);
81
- }
82
- };
@@ -1,21 +0,0 @@
1
- /// <reference types="node" />
2
- import { EventEmitter } from 'events';
3
- import { ModuleCompiled, LwrAppEmitter, LwrAppObserver, ModuleDefinitionChangedEvent, ModuleSourceChangedEvent, CompiledView, AssetSource, AssetSourceChangedEvent, ViewSourceChangedEvent } from '@lwrjs/types';
4
- declare class LwrEmitter implements LwrAppEmitter {
5
- observer: LwrApplicationObserver;
6
- constructor(observer: LwrApplicationObserver);
7
- notifyAssetSourceChanged(payload: AssetSource): void;
8
- notifyViewSourceChanged(payload: CompiledView): void;
9
- notifyModuleDefinitionChanged(payload: ModuleCompiled): void;
10
- notifyModuleSourceChanged(payload: ModuleCompiled): void;
11
- }
12
- export declare class LwrApplicationObserver extends EventEmitter implements LwrAppObserver {
13
- constructor();
14
- onModuleDefinitionChange(listener: (event: ModuleDefinitionChangedEvent) => void): void;
15
- onModuleSourceChange(listener: (event: ModuleSourceChangedEvent) => void): void;
16
- onViewSourceChange(listener: (event: ViewSourceChangedEvent) => void): void;
17
- onAssetSourceChange(listener: (event: AssetSourceChangedEvent) => void): void;
18
- createLwrEmitter(): LwrEmitter;
19
- }
20
- export {};
21
- //# sourceMappingURL=lwr-app-observer.d.ts.map
@@ -1,55 +0,0 @@
1
- import { EventEmitter } from 'events';
2
- const MODULE_DEF_CHANGED_EVENT = 'module_definition_changed';
3
- const MODULE_SOURCE_CHANGED_EVENT = 'module_source_changed';
4
- const VIEW_SOURCE_CHANGED_EVENT = 'view_source_changed';
5
- const ASSET_SOURCE_CHANGED_EVENT = 'asset_source_changed';
6
- class LwrEmitter {
7
- constructor(observer) {
8
- this.observer = observer;
9
- }
10
- notifyAssetSourceChanged(payload) {
11
- this.observer.emit(ASSET_SOURCE_CHANGED_EVENT, {
12
- eventType: ASSET_SOURCE_CHANGED_EVENT,
13
- payload,
14
- });
15
- }
16
- notifyViewSourceChanged(payload) {
17
- this.observer.emit(VIEW_SOURCE_CHANGED_EVENT, {
18
- eventType: VIEW_SOURCE_CHANGED_EVENT,
19
- payload,
20
- });
21
- }
22
- notifyModuleDefinitionChanged(payload) {
23
- this.observer.emit(MODULE_DEF_CHANGED_EVENT, {
24
- eventType: MODULE_DEF_CHANGED_EVENT,
25
- payload,
26
- });
27
- }
28
- notifyModuleSourceChanged(payload) {
29
- this.observer.emit(MODULE_SOURCE_CHANGED_EVENT, {
30
- eventType: MODULE_SOURCE_CHANGED_EVENT,
31
- payload,
32
- });
33
- }
34
- }
35
- export class LwrApplicationObserver extends EventEmitter {
36
- constructor() {
37
- super();
38
- }
39
- onModuleDefinitionChange(listener) {
40
- this.on(MODULE_DEF_CHANGED_EVENT, listener);
41
- }
42
- onModuleSourceChange(listener) {
43
- this.on(MODULE_SOURCE_CHANGED_EVENT, listener);
44
- }
45
- onViewSourceChange(listener) {
46
- this.on(VIEW_SOURCE_CHANGED_EVENT, listener);
47
- }
48
- onAssetSourceChange(listener) {
49
- this.on(ASSET_SOURCE_CHANGED_EVENT, listener);
50
- }
51
- createLwrEmitter() {
52
- return new LwrEmitter(this);
53
- }
54
- }
55
- //# sourceMappingURL=lwr-app-observer.js.map