@lwrjs/loader 0.6.0-alpha.8 → 0.6.1

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.
@@ -4,274 +4,308 @@
4
4
  * SPDX-License-Identifier: MIT
5
5
  * For full license text, see the LICENSE file in the repo root or https://opensource.org/licenses/MIT
6
6
  */
7
- /* LWR Module Loader Shim v0.6.0-alpha.8 */
7
+ /* LWR Module Loader Shim v0.6.1 */
8
8
  (function () {
9
- 'use strict';
9
+ 'use strict';
10
10
 
11
- function createLoader(name, definition, config, externalModules) {
12
- if (!definition || typeof definition[2] !== 'function') {
13
- throw new Error(`Expected loader with specifier "${name}" to be a module`);
14
- }
15
- // Create a Loader instance
16
- const exports = {};
17
- definition[2].call(null, exports);
18
- const { Loader } = exports;
19
- const loader = new Loader(config);
20
- if (externalModules && externalModules.length) {
21
- loader.registerExternalModules(externalModules);
22
- }
23
- // Define the loader module with public API: { define, load, services }
24
- const exporter = (exports) => {
25
- Object.assign(exports, {
26
- define: loader.define.bind(loader),
27
- load: loader.load.bind(loader),
28
- services: loader.services,
29
- });
30
- return;
31
- };
32
- loader.define(name, ['exports'], exporter);
33
- return loader;
34
- }
11
+ // Bootstrap / shim
12
+ const BOOTSTRAP_PREFIX = 'lwr.bootstrap.';
13
+ const BOOTSTRAP_ERROR = `${BOOTSTRAP_PREFIX}error`;
35
14
 
36
- const REQUIRED_MODULES_TIMEOUT = 300 * 1000;
37
- const METRIC_INIT = 'lwr.bootstrap.init';
38
- const METRIC_APP = 'lwr.bootstrap.application';
39
- const METRIC_END = 'lwr.bootstrap.end';
40
- const METRIC_ERROR = 'lwr.bootstrap.error';
15
+ var Phase;
41
16
 
42
- var Phase;
43
- (function (Phase) {
44
- Phase[Phase["Start"] = 0] = "Start";
45
- })(Phase || (Phase = {}));
46
- // Attach a custom dispatcher
47
- let customDispatcher;
48
- function attachDispatcher(dispatcher) {
49
- customDispatcher = dispatcher;
50
- }
51
- // Check if the Performance API is available
52
- // e.g. JSDom (used in Jest) doesn't implement these
53
- const isPerfSupported = typeof globalThis.performance !== 'undefined' && typeof globalThis.performance.mark === 'function';
54
- // For marking request metrics
55
- // Fallback to the Performance API if there is no custom dispatcher
56
- function logOperationStart({ id, specifier }) {
57
- if (customDispatcher) {
58
- customDispatcher({ id, phase: Phase.Start, specifier });
59
- }
60
- else if (isPerfSupported) {
61
- globalThis.performance.mark(id + (specifier ? `.${specifier}` : ''));
62
- }
63
- }
64
- function getProfilerAPI() {
65
- // Create the public Profiler API
66
- return { logOperationStart: logOperationStart.bind(this) };
67
- }
17
+ (function (Phase) {
18
+ Phase[Phase["Start"] = 0] = "Start";
19
+ Phase[Phase["End"] = 1] = "End";
20
+ })(Phase || (Phase = {}));
68
21
 
69
- // Check for errors with autoBoot and customInit
70
- function validatePreInit(autoBoot, customInit) {
71
- // If autoBoot === false, there must be a customInit hook
72
- if (!autoBoot && !customInit) {
73
- throw new Error('The customInit hook is required when autoBoot is false');
74
- }
75
- // If autoBoot === true, there must NOT be a customInit hook
76
- if (autoBoot && customInit) {
77
- throw new Error('The customInit hook must not be defined when autoBoot is true');
78
- }
79
- }
80
- // Process the customInit hook
81
- function customInit(config, initializeApp, define, onBootstrapError) {
82
- // Validate config
83
- const { autoBoot, customInit } = config;
84
- validatePreInit(autoBoot, customInit);
85
- // Set up arguments and call the customInit hook, if available
86
- if (customInit) {
87
- const lwr = {
88
- initializeApp,
89
- define,
90
- onBootstrapError,
91
- attachDispatcher,
92
- };
93
- customInit(lwr, config);
94
- }
95
- }
22
+ // Attach a custom dispatcher
23
+ let customDispatcher;
24
+ function attachDispatcher(dispatcher) {
25
+ customDispatcher = dispatcher;
26
+ } // Check if the Performance API is available
27
+ // e.g. JSDom (used in Jest) doesn't implement these
96
28
 
97
- /* global document */
98
- /* eslint-disable lwr/no-unguarded-apis */
99
- const hasSetTimeout = typeof setTimeout === 'function';
100
- const hasConsole = typeof console !== 'undefined';
101
- /* eslint-enable lwr/no-unguarded-apis */
102
- class LoaderShim {
103
- constructor(global) {
104
- this.defineCache = {};
105
- this.orderedDefs = [];
106
- // Parse configuration
107
- this.global = global;
108
- this.config = global.LWR;
109
- this.loaderModule = 'lwr/loader/v/0_6_0-alpha_8';
110
- // Set up the profiler for instrumentation
111
- this.profiler = getProfilerAPI();
112
- // Set up the temporary LWR.define function and customInit hook
113
- const tempDefine = this.tempDefine.bind(this);
114
- global.LWR.define = tempDefine;
115
- this.bootReady = this.config.autoBoot;
116
- // Start watchdog timer
117
- if (hasSetTimeout) {
118
- this.watchdogTimerId = this.startWatchdogTimer();
119
- }
120
- try {
121
- customInit(Object.freeze(this.config), this.postCustomInit.bind(this), tempDefine, (e) => {
122
- this.errorHandler = e;
123
- });
124
- // Mark "bootstrap init" here so:
125
- // - a custom dispatcher set in customInit receives the log
126
- // - the customInit duration is excluded from the "bootstrap init" duration
127
- this.profiler.logOperationStart({ id: METRIC_INIT });
128
- }
129
- catch (e) {
130
- this.enterErrorState(e);
131
- }
132
- }
133
- // Return true if the app can be initialized
134
- canInit() {
135
- // Initialize the app if:
136
- // - bootReady: autoBoot is on OR customInit has finished
137
- // - all required modules are defined
138
- const allDefined = this.config.requiredModules.every((m) => this.orderedDefs.includes(m));
139
- return this.bootReady && allDefined;
140
- }
141
- /**
142
- * Create a temporary LWR.define() function which captures all
143
- * calls that occur BEFORE the full loader module is available
144
- *
145
- * Each call to LWR.define() is stored in 2 ways:
146
- * - in a map as [moduleName, arguments] pairs
147
- * - each moduleName is pushed onto an array, to preserve
148
- * the order in which the modules were defined
149
- */
150
- tempDefine(...args) {
151
- // Cache the incoming module
152
- const moduleName = args[0];
153
- this.defineCache[moduleName] = args;
154
- this.orderedDefs.push(moduleName);
155
- if (this.canInit()) {
156
- if (hasSetTimeout) {
157
- // requiredModules are defined, clear watchdog timer
158
- // eslint-disable-next-line lwr/no-unguarded-apis, no-undef
159
- clearTimeout(this.watchdogTimerId);
160
- }
161
- this.initApp();
162
- }
163
- }
164
- // Called by the customInit hook via lwr.initializeApp()
165
- postCustomInit() {
166
- this.bootReady = true;
167
- if (this.canInit()) {
168
- this.initApp();
169
- }
170
- }
171
- // Create the loader and initialize the application
172
- initApp() {
173
- try {
174
- const loaderConfig = {
175
- endpoints: this.config.endpoints,
176
- baseUrl: this.config.baseUrl,
177
- profiler: this.profiler,
178
- };
179
- const loader = createLoader(this.loaderModule, this.defineCache[this.loaderModule], loaderConfig, this.config.preloadModules);
180
- this.mountApp(loader);
181
- }
182
- catch (e) {
183
- this.enterErrorState(e);
184
- }
185
- }
186
- waitForDOMContentLoaded() {
187
- // eslint-disable-next-line lwr/no-unguarded-apis
188
- if (typeof document === undefined) {
189
- return Promise.resolve();
190
- }
191
- // Resolve if document is already "ready" https://developer.mozilla.org/en-US/docs/Web/API/Document/readyState
192
- // eslint-disable-next-line lwr/no-unguarded-apis
193
- if (document.readyState === 'interactive' || document.readyState === 'complete') {
194
- return Promise.resolve();
195
- }
196
- return new Promise((resolve) => {
197
- // eslint-disable-next-line lwr/no-unguarded-apis
198
- document.addEventListener('DOMContentLoaded', () => {
199
- resolve();
200
- });
201
- });
202
- }
203
- // Set up the application globals, import map, root custom element...
204
- mountApp(loader) {
205
- const { bootstrapModule, rootComponent, rootComponents, endpoints, imports, index } = this.config;
206
- // Set global LWR.define to loader.define
207
- this.global.LWR = Object.freeze({
208
- define: loader.define.bind(loader),
209
- rootComponent,
210
- rootComponents,
211
- endpoints,
212
- imports: imports || {},
213
- index: index || {},
214
- });
215
- // Redefine all modules in the temporary cache
216
- this.orderedDefs.forEach((specifier) => {
217
- if (specifier !== this.loaderModule) {
218
- loader.define(...this.defineCache[specifier]);
219
- }
220
- });
221
- // by default, app initialization is gated on waiting for document to be parsed (via DOMContentLoaded)
222
- const { disableInitDefer } = this.config;
223
- // Load the import mappings and application bootstrap module
224
- loader
225
- .registerImportMappings({ imports, index }, [bootstrapModule, rootComponent])
226
- .then(() => {
227
- if (!disableInitDefer) {
228
- return this.waitForDOMContentLoaded();
229
- }
230
- })
231
- .then(() => {
232
- this.profiler.logOperationStart({ id: METRIC_APP });
233
- })
234
- .then(() => loader.load(bootstrapModule))
235
- .then(() => {
236
- this.profiler.logOperationStart({ id: METRIC_END });
237
- })
238
- .catch((reason) => {
239
- this.enterErrorState(new Error(`Application ${rootComponent} could not be loaded: ${reason}`));
240
- });
241
- }
242
- // Trigger bootstrap error state, and call error handler if registered
243
- enterErrorState(error) {
244
- this.profiler.logOperationStart({ id: METRIC_ERROR });
245
- if (this.errorHandler) {
246
- this.errorHandler(error);
247
- }
248
- else {
249
- if (hasConsole) {
250
- // eslint-disable-next-line lwr/no-unguarded-apis, no-undef
251
- console.error(`An error occurred during LWR bootstrap. ${error.message}`, error.stack);
252
- }
253
- }
254
- }
255
- // eslint-disable-next-line no-undef, lwr/no-unguarded-apis
256
- startWatchdogTimer() {
257
- // eslint-disable-next-line lwr/no-unguarded-apis, no-undef
258
- return setTimeout(() => {
259
- this.enterErrorState(new Error('Failed to load required modules - timed out'));
260
- }, REQUIRED_MODULES_TIMEOUT);
261
- }
29
+ const perf = globalThis.performance;
30
+ const isPerfSupported = typeof perf !== 'undefined' && typeof perf.mark === 'function' && typeof perf.clearMarks === 'function' && typeof perf.measure === 'function' && typeof perf.clearMeasures === 'function'; // For marking request metrics
31
+ // Fallback to the Performance API if there is no custom dispatcher
32
+
33
+ function logOperationStart({
34
+ id,
35
+ specifier
36
+ }) {
37
+ if (customDispatcher) {
38
+ customDispatcher({
39
+ id,
40
+ phase: Phase.Start,
41
+ specifier
42
+ });
43
+ } else if (isPerfSupported) {
44
+ perf.mark(id + (specifier ? `.${specifier}` : ''));
262
45
  }
46
+ } // For measuring duration metrics
47
+ // Fallback to the Performance API if there is no custom dispatcher
263
48
 
264
- // The loader module is ALWAYS required
265
- const GLOBAL = globalThis;
266
- GLOBAL.LWR.requiredModules = GLOBAL.LWR.requiredModules || [];
267
- if (GLOBAL.LWR.requiredModules.indexOf('lwr/loader/v/0_6_0-alpha_8') < 0) {
268
- GLOBAL.LWR.requiredModules.push('lwr/loader/v/0_6_0-alpha_8');
49
+ /* istanbul ignore next */
50
+
51
+ function logOperationEnd({
52
+ id,
53
+ specifier
54
+ }) {
55
+ if (customDispatcher) {
56
+ customDispatcher({
57
+ id,
58
+ phase: Phase.End,
59
+ specifier
60
+ });
61
+ } else if (isPerfSupported) {
62
+ const suffix = specifier ? `.${specifier}` : '';
63
+ const markName = id + suffix;
64
+ const measureName = `${id}.duration${suffix}`;
65
+ perf.measure(measureName, markName); // Clear the created mark and measure to avoid filling the performance entry buffer
66
+ // Even if they get deleted, existing PerformanceObservers preserve copies of the entries
67
+
68
+ perf.clearMarks(markName);
69
+ perf.clearMeasures(measureName);
269
70
  }
270
- new LoaderShim(GLOBAL);
71
+ }
72
+
73
+ function createLoader(name, definition, config, externalModules) {
74
+ if (!definition || typeof definition[2] !== 'function') {
75
+ throw new Error(`Expected loader with specifier "${name}" to be a module`);
76
+ }
77
+ // Create a Loader instance
78
+ const exports = {};
79
+ definition[2].call(null, exports);
80
+ const { Loader } = exports;
81
+ const loader = new Loader(config);
82
+ if (externalModules && externalModules.length) {
83
+ loader.registerExternalModules(externalModules);
84
+ }
85
+ // Define the loader module with public API: { define, load, services }
86
+ const exporter = (exports) => {
87
+ Object.assign(exports, {
88
+ define: loader.define.bind(loader),
89
+ load: loader.load.bind(loader),
90
+ services: loader.services,
91
+ });
92
+ };
93
+ loader.define(name, ['exports'], exporter);
94
+ return loader;
95
+ }
96
+
97
+ const REQUIRED_MODULES_TIMEOUT = 300 * 1000;
98
+
99
+ // Check for errors with autoBoot and customInit
100
+ function validatePreInit(autoBoot, customInit) {
101
+ // If autoBoot === false, there must be a customInit hook
102
+ if (!autoBoot && !customInit) {
103
+ throw new Error('The customInit hook is required when autoBoot is false');
104
+ }
105
+ // If autoBoot === true, there must NOT be a customInit hook
106
+ if (autoBoot && customInit) {
107
+ throw new Error('The customInit hook must not be defined when autoBoot is true');
108
+ }
109
+ }
110
+ // Process the customInit hook
111
+ function customInit(config, initializeApp, define, onBootstrapError) {
112
+ // Validate config
113
+ const { autoBoot, customInit } = config;
114
+ validatePreInit(autoBoot, customInit);
115
+ // Set up arguments and call the customInit hook, if available
116
+ if (customInit) {
117
+ const lwr = {
118
+ initializeApp,
119
+ define,
120
+ onBootstrapError,
121
+ attachDispatcher,
122
+ };
123
+ customInit(lwr, config);
124
+ }
125
+ }
126
+
127
+ /* global document */
128
+ /* eslint-disable lwr/no-unguarded-apis */
129
+ const hasSetTimeout = typeof setTimeout === 'function';
130
+ const hasConsole = typeof console !== 'undefined';
131
+ /* eslint-enable lwr/no-unguarded-apis */
132
+ class LoaderShim {
133
+ constructor(global) {
134
+ this.defineCache = {};
135
+ this.orderedDefs = [];
136
+ // Parse configuration
137
+ this.global = global;
138
+ this.config = global.LWR;
139
+ this.loaderSpecifier = 'lwr/loader/v/0_6_1';
140
+ // Set up the temporary LWR.define function and customInit hook
141
+ const tempDefine = this.tempDefine.bind(this);
142
+ global.LWR.define = tempDefine;
143
+ this.bootReady = this.config.autoBoot;
144
+ // Start watchdog timer
145
+ if (hasSetTimeout) {
146
+ this.watchdogTimerId = this.startWatchdogTimer();
147
+ }
148
+ try {
149
+ customInit(Object.freeze(this.config), this.postCustomInit.bind(this), tempDefine, (e) => {
150
+ this.errorHandler = e;
151
+ });
152
+ }
153
+ catch (e) {
154
+ this.enterErrorState(e);
155
+ }
156
+ }
157
+ // Return true if the app can be initialized
158
+ canInit() {
159
+ // Initialize the app if:
160
+ // - bootReady: autoBoot is on OR customInit has finished
161
+ // - all required modules are defined
162
+ const allDefined = this.config.requiredModules.every((m) => this.orderedDefs.includes(m));
163
+ return this.bootReady && allDefined;
164
+ }
165
+ /**
166
+ * Create a temporary LWR.define() function which captures all
167
+ * calls that occur BEFORE the full loader module is available
168
+ *
169
+ * Each call to LWR.define() is stored in 2 ways:
170
+ * - in a map as [moduleName, arguments] pairs
171
+ * - each moduleName is pushed onto an array, to preserve
172
+ * the order in which the modules were defined
173
+ */
174
+ tempDefine(...args) {
175
+ // Cache the incoming module
176
+ const moduleName = args[0];
177
+ this.defineCache[moduleName] = args;
178
+ this.orderedDefs.push(moduleName);
179
+ if (this.canInit()) {
180
+ if (hasSetTimeout) {
181
+ // requiredModules are defined, clear watchdog timer
182
+ // eslint-disable-next-line lwr/no-unguarded-apis, no-undef
183
+ clearTimeout(this.watchdogTimerId);
184
+ }
185
+ this.initApp();
186
+ }
187
+ }
188
+ // Called by the customInit hook via lwr.initializeApp()
189
+ postCustomInit() {
190
+ this.bootReady = true;
191
+ if (this.canInit()) {
192
+ this.initApp();
193
+ }
194
+ }
195
+ // Create the loader and initialize the application
196
+ initApp() {
197
+ try {
198
+ const loaderConfig = {
199
+ endpoints: this.config.endpoints,
200
+ baseUrl: this.config.baseUrl,
201
+ profiler: { logOperationStart, logOperationEnd },
202
+ // TODO: can be removed following https://github.com/salesforce/lwr/issues/1087
203
+ appMetadata: {
204
+ appId: this.config.appId,
205
+ bootstrapModule: this.config.bootstrapModule,
206
+ rootComponent: this.config.rootComponent,
207
+ rootComponents: this.config.rootComponents,
208
+ },
209
+ };
210
+ const loader = createLoader(this.loaderSpecifier, this.defineCache[this.loaderSpecifier], loaderConfig, this.config.preloadModules);
211
+ this.createProfilerModule(loader);
212
+ this.mountApp(loader);
213
+ }
214
+ catch (e) {
215
+ this.enterErrorState(e);
216
+ }
217
+ }
218
+ waitForDOMContentLoaded() {
219
+ // eslint-disable-next-line lwr/no-unguarded-apis
220
+ if (typeof document === undefined) {
221
+ return Promise.resolve();
222
+ }
223
+ // Resolve if document is already "ready" https://developer.mozilla.org/en-US/docs/Web/API/Document/readyState
224
+ // eslint-disable-next-line lwr/no-unguarded-apis
225
+ if (document.readyState === 'interactive' || document.readyState === 'complete') {
226
+ return Promise.resolve();
227
+ }
228
+ return new Promise((resolve) => {
229
+ // eslint-disable-next-line lwr/no-unguarded-apis
230
+ document.addEventListener('DOMContentLoaded', () => {
231
+ resolve();
232
+ });
233
+ });
234
+ }
235
+ // Create a module out of the profiler
236
+ // Note: The profiler is also available as a module through lwc module resolution (see package.json)
237
+ createProfilerModule(loader) {
238
+ const exporter = (exports) => {
239
+ Object.assign(exports, { logOperationStart, logOperationEnd });
240
+ };
241
+ loader.define('lwr/profiler/v/0_6_1', ['exports'], exporter);
242
+ }
243
+ // Set up the application globals, import map, root custom element...
244
+ mountApp(loader) {
245
+ const { bootstrapModule, rootComponent, rootComponents, endpoints, imports, index } = this.config;
246
+ // Set global LWR.define to loader.define
247
+ this.global.LWR = Object.freeze({
248
+ define: loader.define.bind(loader),
249
+ rootComponent,
250
+ rootComponents,
251
+ endpoints,
252
+ imports: imports || {},
253
+ index: index || {},
254
+ });
255
+ // Redefine all modules in the temporary cache
256
+ this.orderedDefs.forEach((specifier) => {
257
+ if (specifier !== this.loaderSpecifier) {
258
+ loader.define(...this.defineCache[specifier]);
259
+ }
260
+ });
261
+ // by default, app initialization is gated on waiting for document to be parsed (via DOMContentLoaded)
262
+ const { disableInitDefer } = this.config;
263
+ // Load the import mappings and application bootstrap module
264
+ loader
265
+ .registerImportMappings({ imports, index }, [bootstrapModule, rootComponent])
266
+ .then(() => {
267
+ if (!disableInitDefer) {
268
+ return this.waitForDOMContentLoaded();
269
+ }
270
+ })
271
+ .then(() => loader.load(bootstrapModule))
272
+ .catch((reason) => {
273
+ this.enterErrorState(new Error(`Application ${rootComponent} could not be loaded: ${reason}`));
274
+ });
275
+ }
276
+ // Trigger bootstrap error state, and call error handler if registered
277
+ enterErrorState(error) {
278
+ logOperationStart({ id: BOOTSTRAP_ERROR });
279
+ if (this.errorHandler) {
280
+ this.errorHandler(error);
281
+ }
282
+ else {
283
+ if (hasConsole) {
284
+ // eslint-disable-next-line lwr/no-unguarded-apis, no-undef
285
+ console.error(`An error occurred during LWR bootstrap. ${error.message}`, error.stack);
286
+ }
287
+ }
288
+ }
289
+ // eslint-disable-next-line no-undef, lwr/no-unguarded-apis
290
+ startWatchdogTimer() {
291
+ // eslint-disable-next-line lwr/no-unguarded-apis, no-undef
292
+ return setTimeout(() => {
293
+ this.enterErrorState(new Error('Failed to load required modules - timed out'));
294
+ }, REQUIRED_MODULES_TIMEOUT);
295
+ }
296
+ }
297
+
298
+ // The loader module is ALWAYS required
299
+ const GLOBAL = globalThis;
300
+ GLOBAL.LWR.requiredModules = GLOBAL.LWR.requiredModules || [];
301
+ if (GLOBAL.LWR.requiredModules.indexOf('lwr/loader/v/0_6_1') < 0) {
302
+ GLOBAL.LWR.requiredModules.push('lwr/loader/v/0_6_1');
303
+ }
304
+ new LoaderShim(GLOBAL);
271
305
 
272
306
  }());
273
307
 
274
- LWR.define('lwr/loader/v/0_6_0-alpha_8', ['exports'], function (exports) { 'use strict';
308
+ LWR.define('lwr/loader/v/0_6_1', ['exports'], function (exports) { 'use strict';
275
309
 
276
310
  const templateRegex = /\{([0-9]+)\}/g;
277
311
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
@@ -568,11 +602,15 @@ LWR.define('lwr/loader/v/0_6_0-alpha_8', ['exports'], function (exports) { 'use
568
602
  });
569
603
  }
570
604
 
571
- const MODULE_LOAD_TIMEOUT_TIMER = 300000;
572
- const METRIC_MODULE_FETCH = 'lwr.loader.module.fetch';
573
- const METRIC_MAPPINGS_FETCH = 'lwr.loader.mappings.fetch';
574
- const METRIC_MODULE_ERROR = 'lwr.loader.module.error';
575
- const METRIC_MAPPINGS_ERROR = 'lwr.loader.mappings.error';
605
+ // Bootstrap / shim
606
+
607
+ const LOADER_PREFIX = 'lwr.loader.';
608
+ const MODULE_DEFINE = `${LOADER_PREFIX}module.define`;
609
+ const MODULE_FETCH = `${LOADER_PREFIX}module.fetch`;
610
+ const MODULE_ERROR = `${LOADER_PREFIX}module.error`;
611
+
612
+ const MAPPINGS_FETCH = `${LOADER_PREFIX}mappings.fetch`;
613
+ const MAPPINGS_ERROR = `${LOADER_PREFIX}mappings.error`;
576
614
 
577
615
  /* spec based import map resolver */
578
616
  class ImportMetadataResolver {
@@ -689,7 +727,7 @@ LWR.define('lwr/loader/v/0_6_0-alpha_8', ['exports'], function (exports) { 'use
689
727
  if (pending) {
690
728
  return pending;
691
729
  }
692
- this.config.profiler.logOperationStart({ id: METRIC_MAPPINGS_FETCH, specifier });
730
+ this.config.profiler.logOperationStart({ id: MAPPINGS_FETCH, specifier });
693
731
  const fetchMappingService = this.hasMappingHooks()
694
732
  ? this.evaluateMappingHooks
695
733
  : this.fetchNewMappings;
@@ -704,6 +742,7 @@ LWR.define('lwr/loader/v/0_6_0-alpha_8', ['exports'], function (exports) { 'use
704
742
  if (!uri) {
705
743
  throw new LoaderError(UNRESOLVED, [specifier]);
706
744
  }
745
+ this.config.profiler.logOperationEnd({ id: MAPPINGS_FETCH, specifier });
707
746
  return uri;
708
747
  })
709
748
  .finally(() => {
@@ -748,7 +787,7 @@ LWR.define('lwr/loader/v/0_6_0-alpha_8', ['exports'], function (exports) { 'use
748
787
  const uri = resolveUrl(this.buildMappingUrl(specifier), this.getBaseUrl());
749
788
  return globalThis.fetch(uri).then((res) => {
750
789
  if (!res.ok) {
751
- this.config.profiler.logOperationStart({ id: METRIC_MAPPINGS_ERROR, specifier });
790
+ this.config.profiler.logOperationStart({ id: MAPPINGS_ERROR, specifier });
752
791
  throw new LoaderError(UNRESOLVED, [specifier]);
753
792
  }
754
793
  return res
@@ -802,6 +841,8 @@ LWR.define('lwr/loader/v/0_6_0-alpha_8', ['exports'], function (exports) { 'use
802
841
  }
803
842
  }
804
843
 
844
+ const MODULE_LOAD_TIMEOUT_TIMER = 300000;
845
+
805
846
  let lastWindowError;
806
847
  if (hasDocument) {
807
848
  globalThis.addEventListener('error', (evt) => {
@@ -1016,6 +1057,7 @@ LWR.define('lwr/loader/v/0_6_0-alpha_8', ['exports'], function (exports) { 'use
1016
1057
  // if module is "external", resolve the external promise to notify any dependees
1017
1058
  mod.external.resolveExternal(moduleDef);
1018
1059
  }
1060
+ this.profiler.logOperationStart({ id: MODULE_DEFINE, specifier: name });
1019
1061
  this.namedDefineRegistry.set(name, moduleDef);
1020
1062
  this.lastDefine = moduleDef;
1021
1063
  }
@@ -1198,6 +1240,9 @@ LWR.define('lwr/loader/v/0_6_0-alpha_8', ['exports'], function (exports) { 'use
1198
1240
  if (moduleExports.__defaultInterop) {
1199
1241
  Object.defineProperty(moduleRecord.module, '__defaultInterop', { value: true });
1200
1242
  }
1243
+ if (moduleExports.__esModule) {
1244
+ Object.defineProperty(moduleRecord.module, '__esModule', { value: true });
1245
+ }
1201
1246
  moduleRecord.evaluated = true;
1202
1247
  Object.freeze(moduleRecord.module);
1203
1248
  return moduleRecord.module;
@@ -1246,7 +1291,7 @@ LWR.define('lwr/loader/v/0_6_0-alpha_8', ['exports'], function (exports) { 'use
1246
1291
  }
1247
1292
  const parentUrl = this.resolver.getBaseUrl(); // only support baseUrl for now
1248
1293
  const specifier = moduleName || originalId;
1249
- this.profiler.logOperationStart({ id: METRIC_MODULE_FETCH, specifier });
1294
+ this.profiler.logOperationStart({ id: MODULE_FETCH, specifier });
1250
1295
  return Promise.resolve()
1251
1296
  .then(async () => {
1252
1297
  const loadHooks = this.loadHook;
@@ -1284,10 +1329,11 @@ LWR.define('lwr/loader/v/0_6_0-alpha_8', ['exports'], function (exports) { 'use
1284
1329
  if (!moduleDef) {
1285
1330
  throw new LoaderError(FAIL_INSTANTIATE, [resolvedId]);
1286
1331
  }
1332
+ this.profiler.logOperationEnd({ id: MODULE_FETCH, specifier });
1287
1333
  return moduleDef;
1288
1334
  })
1289
1335
  .catch((e) => {
1290
- this.profiler.logOperationStart({ id: METRIC_MODULE_ERROR, specifier });
1336
+ this.profiler.logOperationStart({ id: MODULE_ERROR, specifier });
1291
1337
  throw e;
1292
1338
  });
1293
1339
  }
@@ -1371,12 +1417,25 @@ LWR.define('lwr/loader/v/0_6_0-alpha_8', ['exports'], function (exports) { 'use
1371
1417
  logOperationStart: () => {
1372
1418
  /* noop */
1373
1419
  },
1420
+ logOperationEnd: () => {
1421
+ /* noop */
1422
+ },
1374
1423
  };
1375
1424
  }
1376
1425
  this.registry = new ModuleRegistry(Object.freeze({ endpoints: config.endpoints, baseUrl, profiler }));
1426
+ // TODO: W-10539691 - temp workaround for LWR-Java -- remove once appId is implemented there
1427
+ if (config.appMetadata && !config.appMetadata.appId) {
1428
+ // Parse the appId from the bootstrapModule
1429
+ // LWR-Java bootstrap module format: @lwr-bootstrap/my/app/v/0_0_1 -- my/app is the appId
1430
+ const match = config.appMetadata.bootstrapModule.match(/@lwr-bootstrap\/(.+)\/v\/.+/);
1431
+ const appId = match && match[1];
1432
+ config.appMetadata.appId = appId;
1433
+ }
1434
+ // TODO: https://github.com/salesforce/lwr/issues/1087
1377
1435
  this.services = Object.freeze({
1378
1436
  addLoaderPlugin: this.registry.addLoaderPlugin.bind(this.registry),
1379
1437
  handleStaleModule: this.registry.registerHandleStaleModuleHook.bind(this.registry),
1438
+ appMetadata: config.appMetadata,
1380
1439
  });
1381
1440
  }
1382
1441
  /**