@lwrjs/loader 0.6.0-alpha.11 → 0.6.0-alpha.15
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/assets/prod/lwr-loader-shim-legacy.bundle.js +323 -229
- package/build/assets/prod/lwr-loader-shim-legacy.bundle.min.js +2 -2
- package/build/assets/prod/lwr-loader-shim-legacy.js +289 -224
- package/build/assets/prod/lwr-loader-shim.bundle.js +300 -280
- package/build/assets/prod/lwr-loader-shim.bundle.min.js +2 -2
- package/build/assets/prod/lwr-loader-shim.js +288 -276
- package/build/bundle/prod/lwr/esmLoader/esmLoader.js +1 -1
- package/build/cjs/modules/lwr/esmLoader/esmLoader.cjs +9 -6
- package/build/cjs/modules/lwr/esmLoader/importResolver.cjs +24 -3
- package/build/cjs/modules/lwr/loader/moduleRegistry/importMetadataResolver.cjs +1 -1
- package/build/cjs/modules/lwr/loader/moduleRegistry/moduleRegistry.cjs +1 -1
- package/build/cjs/modules/lwr/loaderLegacy/moduleRegistry/moduleRegistry.cjs +9 -2
- package/build/modules/lwr/esmLoader/esmLoader.js +38 -10
- package/build/modules/lwr/loader/loader.js +12 -4
- package/build/modules/lwr/loaderLegacy/loaderLegacy.js +34 -5
- package/package.json +9 -18
- package/build/cjs/metrics.cjs +0 -43
- package/build/metrics.d.ts +0 -18
- package/build/metrics.js +0 -20
- package/build/shim/profiler.d.ts +0 -23
- package/build/shim/profiler.js +0 -47
|
@@ -4,243 +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 Legacy Module Loader Shim v0.6.0-alpha.
|
|
7
|
+
/* LWR Legacy Module Loader Shim v0.6.0-alpha.15 */
|
|
8
8
|
(function () {
|
|
9
|
-
|
|
9
|
+
'use strict';
|
|
10
10
|
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
}
|
|
15
|
-
// Create a Loader instance
|
|
16
|
-
const exports = {};
|
|
17
|
-
definition[2].call(null, exports);
|
|
18
|
-
const { Loader } = exports;
|
|
19
|
-
const loader = new Loader(baseUrl);
|
|
20
|
-
// register externally loaded modules
|
|
21
|
-
if (externalModules && externalModules.length) {
|
|
22
|
-
loader.registerExternalModules(externalModules);
|
|
23
|
-
}
|
|
24
|
-
// Define the loader module with public API: { define, load, services }
|
|
25
|
-
const exporter = (exports) => {
|
|
26
|
-
Object.assign(exports, {
|
|
27
|
-
define: loader.define.bind(loader),
|
|
28
|
-
load: loader.load.bind(loader),
|
|
29
|
-
services: loader.services,
|
|
30
|
-
});
|
|
31
|
-
return;
|
|
32
|
-
};
|
|
33
|
-
loader.define(name, ['exports'], exporter, definition[3]);
|
|
34
|
-
return loader;
|
|
35
|
-
}
|
|
11
|
+
// Bootstrap / shim
|
|
12
|
+
const BOOTSTRAP_PREFIX = 'lwr.bootstrap.';
|
|
13
|
+
const BOOTSTRAP_ERROR = `${BOOTSTRAP_PREFIX}error`;
|
|
36
14
|
|
|
37
|
-
|
|
15
|
+
var Phase;
|
|
38
16
|
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
})(Phase || (Phase = {}));
|
|
44
|
-
function attachDispatcher(dispatcher) {
|
|
45
|
-
}
|
|
17
|
+
(function (Phase) {
|
|
18
|
+
Phase[Phase["Start"] = 0] = "Start";
|
|
19
|
+
Phase[Phase["End"] = 1] = "End";
|
|
20
|
+
})(Phase || (Phase = {}));
|
|
46
21
|
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
// If autoBoot === true, there must NOT be a customInit hook
|
|
54
|
-
if (autoBoot && customInit) {
|
|
55
|
-
throw new Error('The customInit hook must not be defined when autoBoot is true');
|
|
56
|
-
}
|
|
57
|
-
}
|
|
58
|
-
// Process the customInit hook
|
|
59
|
-
function customInit(config, initializeApp, define, onBootstrapError) {
|
|
60
|
-
// Validate config
|
|
61
|
-
const { autoBoot, customInit } = config;
|
|
62
|
-
validatePreInit(autoBoot, customInit);
|
|
63
|
-
// Set up arguments and call the customInit hook, if available
|
|
64
|
-
if (customInit) {
|
|
65
|
-
const lwr = {
|
|
66
|
-
initializeApp,
|
|
67
|
-
define,
|
|
68
|
-
onBootstrapError,
|
|
69
|
-
attachDispatcher,
|
|
70
|
-
};
|
|
71
|
-
customInit(lwr, config);
|
|
72
|
-
}
|
|
73
|
-
}
|
|
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
|
|
74
28
|
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
this.bootReady = this.config.autoBoot;
|
|
92
|
-
// Start watchdog timer
|
|
93
|
-
if (hasSetTimeout) {
|
|
94
|
-
this.watchdogTimerId = this.startWatchdogTimer();
|
|
95
|
-
}
|
|
96
|
-
try {
|
|
97
|
-
customInit(Object.freeze(this.config), this.postCustomInit.bind(this), tempDefine, (e) => {
|
|
98
|
-
this.errorHandler = e;
|
|
99
|
-
});
|
|
100
|
-
}
|
|
101
|
-
catch (e) {
|
|
102
|
-
this.enterErrorState(e);
|
|
103
|
-
}
|
|
104
|
-
}
|
|
105
|
-
// Return true if the app can be initialized
|
|
106
|
-
canInit() {
|
|
107
|
-
// Initialize the app if:
|
|
108
|
-
// - bootReady: autoBoot is on OR customInit has finished
|
|
109
|
-
// - all required modules are defined
|
|
110
|
-
const allDefined = this.config.requiredModules.every((m) => this.orderedDefs.includes(m));
|
|
111
|
-
return this.bootReady && allDefined;
|
|
112
|
-
}
|
|
113
|
-
/**
|
|
114
|
-
* Create a temporary LWR.define() function which captures all
|
|
115
|
-
* calls that occur BEFORE the full loader module is available
|
|
116
|
-
*
|
|
117
|
-
* Each call to LWR.define() is stored in 2 ways:
|
|
118
|
-
* - in a map as [moduleName, arguments] pairs
|
|
119
|
-
* - each moduleName is pushed onto an array, to preserve
|
|
120
|
-
* the order in which the modules were defined
|
|
121
|
-
*/
|
|
122
|
-
tempDefine(...args) {
|
|
123
|
-
// Cache the incoming module
|
|
124
|
-
const moduleName = args[0];
|
|
125
|
-
this.defineCache[moduleName] = args;
|
|
126
|
-
this.orderedDefs.push(moduleName);
|
|
127
|
-
if (this.canInit()) {
|
|
128
|
-
if (hasSetTimeout) {
|
|
129
|
-
// requiredModules are defined, clear watchdog timer
|
|
130
|
-
// eslint-disable-next-line lwr/no-unguarded-apis, no-undef
|
|
131
|
-
clearTimeout(this.watchdogTimerId);
|
|
132
|
-
}
|
|
133
|
-
this.initApp();
|
|
134
|
-
}
|
|
135
|
-
}
|
|
136
|
-
// Called by the customInit hook via lwr.initializeApp()
|
|
137
|
-
postCustomInit() {
|
|
138
|
-
this.bootReady = true;
|
|
139
|
-
if (this.canInit()) {
|
|
140
|
-
this.initApp();
|
|
141
|
-
}
|
|
142
|
-
}
|
|
143
|
-
// Create the loader and initialize the application
|
|
144
|
-
initApp() {
|
|
145
|
-
try {
|
|
146
|
-
const loader = createLoader(this.loaderModule, this.defineCache[this.loaderModule], this.config.baseUrl, this.config.preloadModules);
|
|
147
|
-
this.mountApp(loader);
|
|
148
|
-
}
|
|
149
|
-
catch (e) {
|
|
150
|
-
this.enterErrorState(e);
|
|
151
|
-
}
|
|
152
|
-
}
|
|
153
|
-
waitForDOMContentLoaded() {
|
|
154
|
-
// eslint-disable-next-line lwr/no-unguarded-apis
|
|
155
|
-
if (typeof document === undefined) {
|
|
156
|
-
return Promise.resolve();
|
|
157
|
-
}
|
|
158
|
-
// Resolve if document is already "ready" https://developer.mozilla.org/en-US/docs/Web/API/Document/readyState
|
|
159
|
-
// eslint-disable-next-line lwr/no-unguarded-apis
|
|
160
|
-
if (document.readyState === 'interactive' || document.readyState === 'complete') {
|
|
161
|
-
return Promise.resolve();
|
|
162
|
-
}
|
|
163
|
-
return new Promise((resolve) => {
|
|
164
|
-
// eslint-disable-next-line lwr/no-unguarded-apis
|
|
165
|
-
document.addEventListener('DOMContentLoaded', () => {
|
|
166
|
-
resolve();
|
|
167
|
-
});
|
|
168
|
-
});
|
|
169
|
-
}
|
|
170
|
-
// Set up the application globals, import map, root custom element...
|
|
171
|
-
mountApp(loader) {
|
|
172
|
-
const { bootstrapModule, rootComponent, importMappings, rootComponents, endpoints } = this.config;
|
|
173
|
-
// Set global LWR.define to loader.define
|
|
174
|
-
this.global.LWR = Object.freeze({
|
|
175
|
-
define: loader.define.bind(loader),
|
|
176
|
-
rootComponent,
|
|
177
|
-
rootComponents,
|
|
178
|
-
importMappings,
|
|
179
|
-
endpoints,
|
|
180
|
-
});
|
|
181
|
-
// Redefine all modules in the temporary cache
|
|
182
|
-
this.orderedDefs.forEach((specifier) => {
|
|
183
|
-
if (specifier !== this.loaderModule) {
|
|
184
|
-
loader.define(...this.defineCache[specifier]);
|
|
185
|
-
}
|
|
186
|
-
});
|
|
187
|
-
// Define a dummy profiler since the "lwr/profiler" module is used in "lwr/init" (which is global to all server modes)
|
|
188
|
-
const profilerExporter = (exports) => {
|
|
189
|
-
Object.assign(exports, {
|
|
190
|
-
logOperationStart: () => {
|
|
191
|
-
/* noop */
|
|
192
|
-
},
|
|
193
|
-
});
|
|
194
|
-
return;
|
|
195
|
-
};
|
|
196
|
-
loader.define('lwr/profiler/v/0_6_0-alpha_11', ['exports'], profilerExporter, {});
|
|
197
|
-
// by default, app initialization is gated on waiting for document to be parsed (via DOMContentLoaded)
|
|
198
|
-
const { disableInitDefer } = this.config;
|
|
199
|
-
// Load the import mappings and application bootstrap module
|
|
200
|
-
loader
|
|
201
|
-
.registerImportMappings(importMappings)
|
|
202
|
-
.then(() => {
|
|
203
|
-
if (!disableInitDefer) {
|
|
204
|
-
return this.waitForDOMContentLoaded();
|
|
205
|
-
}
|
|
206
|
-
})
|
|
207
|
-
.then(() => loader.load(bootstrapModule))
|
|
208
|
-
.catch((reason) => {
|
|
209
|
-
this.enterErrorState(new Error(`Application ${rootComponent} could not be loaded: ${reason}`));
|
|
210
|
-
});
|
|
211
|
-
}
|
|
212
|
-
// Trigger bootstrap error state, and call error handler if registered
|
|
213
|
-
enterErrorState(error) {
|
|
214
|
-
if (this.errorHandler) {
|
|
215
|
-
this.errorHandler(error);
|
|
216
|
-
}
|
|
217
|
-
else {
|
|
218
|
-
if (hasConsole) {
|
|
219
|
-
// eslint-disable-next-line lwr/no-unguarded-apis, no-undef
|
|
220
|
-
console.error(`An error occurred during LWR bootstrap. ${error.message}`, error.stack);
|
|
221
|
-
}
|
|
222
|
-
}
|
|
223
|
-
}
|
|
224
|
-
// eslint-disable-next-line no-undef, lwr/no-unguarded-apis
|
|
225
|
-
startWatchdogTimer() {
|
|
226
|
-
// eslint-disable-next-line lwr/no-unguarded-apis, no-undef
|
|
227
|
-
return setTimeout(() => {
|
|
228
|
-
this.enterErrorState(new Error('Failed to load required modules - timed out'));
|
|
229
|
-
}, REQUIRED_MODULES_TIMEOUT);
|
|
230
|
-
}
|
|
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}` : ''));
|
|
231
45
|
}
|
|
46
|
+
} // For measuring duration metrics
|
|
47
|
+
// Fallback to the Performance API if there is no custom dispatcher
|
|
48
|
+
|
|
49
|
+
/* istanbul ignore next */
|
|
232
50
|
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
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);
|
|
238
70
|
}
|
|
239
|
-
|
|
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
|
+
// register externally loaded modules
|
|
83
|
+
if (externalModules && externalModules.length) {
|
|
84
|
+
loader.registerExternalModules(externalModules);
|
|
85
|
+
}
|
|
86
|
+
// Define the loader module with public API: { define, load, services }
|
|
87
|
+
const exporter = (exports) => {
|
|
88
|
+
Object.assign(exports, {
|
|
89
|
+
define: loader.define.bind(loader),
|
|
90
|
+
load: loader.load.bind(loader),
|
|
91
|
+
services: loader.services,
|
|
92
|
+
});
|
|
93
|
+
return;
|
|
94
|
+
};
|
|
95
|
+
loader.define(name, ['exports'], exporter, definition[3]);
|
|
96
|
+
return loader;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
const REQUIRED_MODULES_TIMEOUT = 300 * 1000;
|
|
100
|
+
|
|
101
|
+
// Check for errors with autoBoot and customInit
|
|
102
|
+
function validatePreInit(autoBoot, customInit) {
|
|
103
|
+
// If autoBoot === false, there must be a customInit hook
|
|
104
|
+
if (!autoBoot && !customInit) {
|
|
105
|
+
throw new Error('The customInit hook is required when autoBoot is false');
|
|
106
|
+
}
|
|
107
|
+
// If autoBoot === true, there must NOT be a customInit hook
|
|
108
|
+
if (autoBoot && customInit) {
|
|
109
|
+
throw new Error('The customInit hook must not be defined when autoBoot is true');
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
// Process the customInit hook
|
|
113
|
+
function customInit(config, initializeApp, define, onBootstrapError) {
|
|
114
|
+
// Validate config
|
|
115
|
+
const { autoBoot, customInit } = config;
|
|
116
|
+
validatePreInit(autoBoot, customInit);
|
|
117
|
+
// Set up arguments and call the customInit hook, if available
|
|
118
|
+
if (customInit) {
|
|
119
|
+
const lwr = {
|
|
120
|
+
initializeApp,
|
|
121
|
+
define,
|
|
122
|
+
onBootstrapError,
|
|
123
|
+
attachDispatcher,
|
|
124
|
+
};
|
|
125
|
+
customInit(lwr, config);
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
/* global document */
|
|
130
|
+
/* eslint-disable lwr/no-unguarded-apis */
|
|
131
|
+
const hasSetTimeout = typeof setTimeout === 'function';
|
|
132
|
+
const hasConsole = typeof console !== 'undefined';
|
|
133
|
+
/* eslint-enable lwr/no-unguarded-apis */
|
|
134
|
+
class LoaderShim {
|
|
135
|
+
constructor(global) {
|
|
136
|
+
this.defineCache = {};
|
|
137
|
+
this.orderedDefs = [];
|
|
138
|
+
// Parse configuration
|
|
139
|
+
this.global = global;
|
|
140
|
+
this.config = global.LWR;
|
|
141
|
+
this.loaderModule = 'lwr/loaderLegacy/v/0_6_0-alpha_15';
|
|
142
|
+
// Set up the temporary LWR.define function and customInit hook
|
|
143
|
+
const tempDefine = this.tempDefine.bind(this);
|
|
144
|
+
global.LWR.define = tempDefine;
|
|
145
|
+
this.bootReady = this.config.autoBoot;
|
|
146
|
+
// Start watchdog timer
|
|
147
|
+
if (hasSetTimeout) {
|
|
148
|
+
this.watchdogTimerId = this.startWatchdogTimer();
|
|
149
|
+
}
|
|
150
|
+
try {
|
|
151
|
+
customInit(Object.freeze(this.config), this.postCustomInit.bind(this), tempDefine, (e) => {
|
|
152
|
+
this.errorHandler = e;
|
|
153
|
+
});
|
|
154
|
+
}
|
|
155
|
+
catch (e) {
|
|
156
|
+
this.enterErrorState(e);
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
// Return true if the app can be initialized
|
|
160
|
+
canInit() {
|
|
161
|
+
// Initialize the app if:
|
|
162
|
+
// - bootReady: autoBoot is on OR customInit has finished
|
|
163
|
+
// - all required modules are defined
|
|
164
|
+
const allDefined = this.config.requiredModules.every((m) => this.orderedDefs.includes(m));
|
|
165
|
+
return this.bootReady && allDefined;
|
|
166
|
+
}
|
|
167
|
+
/**
|
|
168
|
+
* Create a temporary LWR.define() function which captures all
|
|
169
|
+
* calls that occur BEFORE the full loader module is available
|
|
170
|
+
*
|
|
171
|
+
* Each call to LWR.define() is stored in 2 ways:
|
|
172
|
+
* - in a map as [moduleName, arguments] pairs
|
|
173
|
+
* - each moduleName is pushed onto an array, to preserve
|
|
174
|
+
* the order in which the modules were defined
|
|
175
|
+
*/
|
|
176
|
+
tempDefine(...args) {
|
|
177
|
+
// Cache the incoming module
|
|
178
|
+
const moduleName = args[0];
|
|
179
|
+
this.defineCache[moduleName] = args;
|
|
180
|
+
this.orderedDefs.push(moduleName);
|
|
181
|
+
if (this.canInit()) {
|
|
182
|
+
if (hasSetTimeout) {
|
|
183
|
+
// requiredModules are defined, clear watchdog timer
|
|
184
|
+
// eslint-disable-next-line lwr/no-unguarded-apis, no-undef
|
|
185
|
+
clearTimeout(this.watchdogTimerId);
|
|
186
|
+
}
|
|
187
|
+
this.initApp();
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
// Called by the customInit hook via lwr.initializeApp()
|
|
191
|
+
postCustomInit() {
|
|
192
|
+
this.bootReady = true;
|
|
193
|
+
if (this.canInit()) {
|
|
194
|
+
this.initApp();
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
// Create the loader and initialize the application
|
|
198
|
+
initApp() {
|
|
199
|
+
try {
|
|
200
|
+
const loaderConfig = {
|
|
201
|
+
baseUrl: this.config.baseUrl,
|
|
202
|
+
profiler: { logOperationStart, logOperationEnd },
|
|
203
|
+
// TODO: can be removed following https://github.com/salesforce/lwr/issues/1087
|
|
204
|
+
appMetadata: {
|
|
205
|
+
appId: this.config.appId,
|
|
206
|
+
bootstrapModule: this.config.bootstrapModule,
|
|
207
|
+
rootComponent: this.config.rootComponent,
|
|
208
|
+
rootComponents: this.config.rootComponents,
|
|
209
|
+
},
|
|
210
|
+
};
|
|
211
|
+
const loader = createLoader(this.loaderModule, this.defineCache[this.loaderModule], loaderConfig, this.config.preloadModules);
|
|
212
|
+
this.createProfilerModule(loader);
|
|
213
|
+
this.mountApp(loader);
|
|
214
|
+
}
|
|
215
|
+
catch (e) {
|
|
216
|
+
this.enterErrorState(e);
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
waitForDOMContentLoaded() {
|
|
220
|
+
// eslint-disable-next-line lwr/no-unguarded-apis
|
|
221
|
+
if (typeof document === undefined) {
|
|
222
|
+
return Promise.resolve();
|
|
223
|
+
}
|
|
224
|
+
// Resolve if document is already "ready" https://developer.mozilla.org/en-US/docs/Web/API/Document/readyState
|
|
225
|
+
// eslint-disable-next-line lwr/no-unguarded-apis
|
|
226
|
+
if (document.readyState === 'interactive' || document.readyState === 'complete') {
|
|
227
|
+
return Promise.resolve();
|
|
228
|
+
}
|
|
229
|
+
return new Promise((resolve) => {
|
|
230
|
+
// eslint-disable-next-line lwr/no-unguarded-apis
|
|
231
|
+
document.addEventListener('DOMContentLoaded', () => {
|
|
232
|
+
resolve();
|
|
233
|
+
});
|
|
234
|
+
});
|
|
235
|
+
}
|
|
236
|
+
// Create a module out of the profiler
|
|
237
|
+
// Note: The profiler is also available as a module through lwc module resolution (see package.json)
|
|
238
|
+
createProfilerModule(loader) {
|
|
239
|
+
const exporter = (exports) => {
|
|
240
|
+
Object.assign(exports, { logOperationStart, logOperationEnd });
|
|
241
|
+
};
|
|
242
|
+
loader.define('lwr/profiler/v/0_6_0-alpha_15', ['exports'], exporter, {});
|
|
243
|
+
}
|
|
244
|
+
// Set up the application globals, import map, root custom element...
|
|
245
|
+
mountApp(loader) {
|
|
246
|
+
const { bootstrapModule, rootComponent, importMappings, rootComponents, endpoints } = this.config;
|
|
247
|
+
// Set global LWR.define to loader.define
|
|
248
|
+
this.global.LWR = Object.freeze({
|
|
249
|
+
define: loader.define.bind(loader),
|
|
250
|
+
rootComponent,
|
|
251
|
+
rootComponents,
|
|
252
|
+
importMappings,
|
|
253
|
+
endpoints,
|
|
254
|
+
});
|
|
255
|
+
// Redefine all modules in the temporary cache
|
|
256
|
+
this.orderedDefs.forEach((specifier) => {
|
|
257
|
+
if (specifier !== this.loaderModule) {
|
|
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(importMappings)
|
|
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/loaderLegacy/v/0_6_0-alpha_15') < 0) {
|
|
302
|
+
GLOBAL.LWR.requiredModules.push('lwr/loaderLegacy/v/0_6_0-alpha_15');
|
|
303
|
+
}
|
|
304
|
+
new LoaderShim(GLOBAL);
|
|
240
305
|
|
|
241
306
|
}());
|
|
242
307
|
|
|
243
|
-
LWR.define('lwr/loaderLegacy/v/0_6_0-
|
|
308
|
+
LWR.define('lwr/loaderLegacy/v/0_6_0-alpha_15', ['exports'], function (exports) { 'use strict';
|
|
244
309
|
|
|
245
310
|
const templateRegex = /\{([0-9]+)\}/g;
|
|
246
311
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
@@ -638,14 +703,22 @@ LWR.define('lwr/loaderLegacy/v/0_6_0-alpha_11', ['exports'], function (exports)
|
|
|
638
703
|
}
|
|
639
704
|
}
|
|
640
705
|
|
|
706
|
+
// Bootstrap / shim
|
|
707
|
+
|
|
708
|
+
const LOADER_PREFIX = 'lwr.loader.';
|
|
709
|
+
const MODULE_DEFINE = `${LOADER_PREFIX}module.define`;
|
|
710
|
+
const MODULE_FETCH = `${LOADER_PREFIX}module.fetch`;
|
|
711
|
+
const MODULE_ERROR = `${LOADER_PREFIX}module.error`; // Loader: mappings
|
|
712
|
+
|
|
641
713
|
/* global console,process */
|
|
642
714
|
class ModuleRegistry {
|
|
643
|
-
constructor(
|
|
715
|
+
constructor(config) {
|
|
644
716
|
// A registry for named AMD defines containing the *metadata* of AMD module
|
|
645
717
|
this.namedDefineRegistry = new Map();
|
|
646
718
|
// The evaluted module registry where the module identifier (name or URL?) is the key
|
|
647
719
|
this.moduleRegistry = new Map();
|
|
648
|
-
this.baseUrl = baseUrl;
|
|
720
|
+
this.baseUrl = config.baseUrl;
|
|
721
|
+
this.profiler = config.profiler;
|
|
649
722
|
}
|
|
650
723
|
async load(id, importer) {
|
|
651
724
|
const resolvedId = await this.resolve(id, importer);
|
|
@@ -760,6 +833,7 @@ LWR.define('lwr/loaderLegacy/v/0_6_0-alpha_11', ['exports'], function (exports)
|
|
|
760
833
|
// if module is "external", resolve the external promise to notify any dependees
|
|
761
834
|
mod.external.resolveExternal(moduleDef);
|
|
762
835
|
}
|
|
836
|
+
this.profiler.logOperationStart({ id: MODULE_DEFINE, specifier: name });
|
|
763
837
|
this.namedDefineRegistry.set(name, moduleDef);
|
|
764
838
|
this.lastDefine = moduleDef;
|
|
765
839
|
// Check signatures of dependencies against those in the namedDefineRegistry
|
|
@@ -1030,6 +1104,8 @@ LWR.define('lwr/loaderLegacy/v/0_6_0-alpha_11', ['exports'], function (exports)
|
|
|
1030
1104
|
return moduleDef;
|
|
1031
1105
|
}
|
|
1032
1106
|
const parentUrl = this.baseUrl; // only support baseUrl for now
|
|
1107
|
+
const specifier = moduleName || originalId;
|
|
1108
|
+
this.profiler.logOperationStart({ id: MODULE_FETCH, specifier });
|
|
1033
1109
|
return Promise.resolve()
|
|
1034
1110
|
.then(async () => {
|
|
1035
1111
|
const loadHooks = this.loadHook;
|
|
@@ -1067,9 +1143,11 @@ LWR.define('lwr/loaderLegacy/v/0_6_0-alpha_11', ['exports'], function (exports)
|
|
|
1067
1143
|
if (!moduleDef) {
|
|
1068
1144
|
throw new LoaderError(FAIL_INSTANTIATE, [resolvedId]);
|
|
1069
1145
|
}
|
|
1146
|
+
this.profiler.logOperationEnd({ id: MODULE_FETCH, specifier });
|
|
1070
1147
|
return moduleDef;
|
|
1071
1148
|
})
|
|
1072
1149
|
.catch((e) => {
|
|
1150
|
+
this.profiler.logOperationStart({ id: MODULE_ERROR, specifier });
|
|
1073
1151
|
throw e;
|
|
1074
1152
|
});
|
|
1075
1153
|
}
|
|
@@ -1297,7 +1375,10 @@ LWR.define('lwr/loaderLegacy/v/0_6_0-alpha_11', ['exports'], function (exports)
|
|
|
1297
1375
|
* The LWR loader is inspired and borrows from the algorithms and native browser principles of https://github.com/systemjs/systemjs
|
|
1298
1376
|
*/
|
|
1299
1377
|
class Loader {
|
|
1300
|
-
constructor(
|
|
1378
|
+
constructor(config) {
|
|
1379
|
+
config = config || {};
|
|
1380
|
+
let baseUrl = config.baseUrl;
|
|
1381
|
+
let profiler = config.profiler;
|
|
1301
1382
|
if (baseUrl) {
|
|
1302
1383
|
// add a trailing slash, if it does not exist
|
|
1303
1384
|
baseUrl = baseUrl.replace(/\/?$/, '/');
|
|
@@ -1309,10 +1390,23 @@ LWR.define('lwr/loaderLegacy/v/0_6_0-alpha_11', ['exports'], function (exports)
|
|
|
1309
1390
|
throw new LoaderError(NO_BASE_URL);
|
|
1310
1391
|
}
|
|
1311
1392
|
this.baseUrl = baseUrl;
|
|
1312
|
-
|
|
1393
|
+
if (!profiler) {
|
|
1394
|
+
// default noop profiler
|
|
1395
|
+
profiler = {
|
|
1396
|
+
logOperationStart: () => {
|
|
1397
|
+
/* noop */
|
|
1398
|
+
},
|
|
1399
|
+
logOperationEnd: () => {
|
|
1400
|
+
/* noop */
|
|
1401
|
+
},
|
|
1402
|
+
};
|
|
1403
|
+
}
|
|
1404
|
+
this.registry = new ModuleRegistry({ baseUrl, profiler });
|
|
1405
|
+
// TODO: https://github.com/salesforce/lwr/issues/1087
|
|
1313
1406
|
this.services = Object.freeze({
|
|
1314
1407
|
addLoaderPlugin: this.registry.addLoaderPlugin.bind(this.registry),
|
|
1315
1408
|
handleStaleModule: this.registry.registerHandleStaleModuleHook.bind(this.registry),
|
|
1409
|
+
appMetadata: config.appMetadata,
|
|
1316
1410
|
});
|
|
1317
1411
|
}
|
|
1318
1412
|
/**
|