@lwrjs/loader 0.10.0-alpha.4 → 0.10.0-alpha.6
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-error-shim.js +2 -1
- package/build/assets/prod/lwr-loader-shim-legacy.bundle.js +563 -243
- package/build/assets/prod/lwr-loader-shim-legacy.bundle.min.js +2 -2
- package/build/assets/prod/lwr-loader-shim-legacy.js +108 -44
- package/build/assets/prod/lwr-loader-shim.bundle.js +510 -246
- package/build/assets/prod/lwr-loader-shim.bundle.min.js +2 -2
- package/build/assets/prod/lwr-loader-shim.js +107 -44
- package/build/bundle/prod/lwr/esmLoader/esmLoader.js +1 -1
- package/build/modules/lwr/esmLoader/esmLoader.js +44 -15
- package/build/modules/lwr/loader/loader.js +403 -201
- package/build/modules/lwr/loaderLegacy/loaderLegacy.js +454 -198
- package/package.json +12 -7
|
@@ -4,7 +4,7 @@
|
|
|
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.10.0-alpha.
|
|
7
|
+
/* LWR Module Loader Shim v0.10.0-alpha.6 */
|
|
8
8
|
(function () {
|
|
9
9
|
'use strict';
|
|
10
10
|
|
|
@@ -12,11 +12,11 @@
|
|
|
12
12
|
const BOOTSTRAP_PREFIX = 'lwr.bootstrap.';
|
|
13
13
|
const BOOTSTRAP_ERROR = `${BOOTSTRAP_PREFIX}error`;
|
|
14
14
|
|
|
15
|
-
var Phase
|
|
16
|
-
(function (Phase) {
|
|
15
|
+
var Phase = /*#__PURE__*/function (Phase) {
|
|
17
16
|
Phase[Phase["Start"] = 0] = "Start";
|
|
18
17
|
Phase[Phase["End"] = 1] = "End";
|
|
19
|
-
|
|
18
|
+
return Phase;
|
|
19
|
+
}(Phase || {});
|
|
20
20
|
// Attach a custom dispatcher
|
|
21
21
|
let customDispatcher;
|
|
22
22
|
function attachDispatcher(dispatcher) {
|
|
@@ -71,18 +71,26 @@
|
|
|
71
71
|
}
|
|
72
72
|
}
|
|
73
73
|
|
|
74
|
-
function createLoader(
|
|
74
|
+
function createLoader(
|
|
75
|
+
name,
|
|
76
|
+
definition,
|
|
77
|
+
config,
|
|
78
|
+
externalModules,
|
|
79
|
+
) {
|
|
75
80
|
if (!definition || typeof definition[2] !== 'function') {
|
|
76
81
|
throw new Error(`Expected loader with specifier "${name}" to be a module`);
|
|
77
82
|
}
|
|
83
|
+
|
|
78
84
|
// Create a Loader instance
|
|
79
85
|
const exports = {};
|
|
80
86
|
definition[2].call(null, exports);
|
|
81
87
|
const { Loader } = exports;
|
|
82
88
|
const loader = new Loader(config);
|
|
89
|
+
|
|
83
90
|
if (externalModules && externalModules.length) {
|
|
84
91
|
loader.registerExternalModules(externalModules);
|
|
85
92
|
}
|
|
93
|
+
|
|
86
94
|
// Define the loader module with public API: { define, load, services }
|
|
87
95
|
const exporter = (exports) => {
|
|
88
96
|
Object.assign(exports, {
|
|
@@ -92,6 +100,7 @@
|
|
|
92
100
|
});
|
|
93
101
|
};
|
|
94
102
|
loader.define(name, ['exports'], exporter);
|
|
103
|
+
|
|
95
104
|
return loader;
|
|
96
105
|
}
|
|
97
106
|
|
|
@@ -108,11 +117,18 @@
|
|
|
108
117
|
throw new Error('The customInit hook must not be defined when autoBoot is true');
|
|
109
118
|
}
|
|
110
119
|
}
|
|
120
|
+
|
|
111
121
|
// Process the customInit hook
|
|
112
|
-
function customInit(
|
|
122
|
+
function customInit(
|
|
123
|
+
config,
|
|
124
|
+
initializeApp,
|
|
125
|
+
define,
|
|
126
|
+
onBootstrapError,
|
|
127
|
+
) {
|
|
113
128
|
// Validate config
|
|
114
129
|
const { autoBoot, customInit } = config;
|
|
115
130
|
validatePreInit(autoBoot, customInit);
|
|
131
|
+
|
|
116
132
|
// Set up arguments and call the customInit hook, if available
|
|
117
133
|
if (customInit) {
|
|
118
134
|
const lwr = {
|
|
@@ -126,48 +142,74 @@
|
|
|
126
142
|
}
|
|
127
143
|
|
|
128
144
|
/* global document */
|
|
145
|
+
|
|
146
|
+
|
|
147
|
+
|
|
148
|
+
|
|
149
|
+
|
|
150
|
+
|
|
151
|
+
|
|
152
|
+
|
|
129
153
|
/* eslint-disable lwr/no-unguarded-apis */
|
|
130
154
|
const hasSetTimeout = typeof setTimeout === 'function';
|
|
131
155
|
const hasConsole = typeof console !== 'undefined';
|
|
132
156
|
/* eslint-enable lwr/no-unguarded-apis */
|
|
157
|
+
|
|
133
158
|
class LoaderShim {
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
159
|
+
|
|
160
|
+
|
|
161
|
+
|
|
162
|
+
|
|
163
|
+
__init() {this.defineCache = {};}
|
|
164
|
+
__init2() {this.orderedDefs = [];}
|
|
165
|
+
|
|
166
|
+
// eslint-disable-line no-undef, lwr/no-unguarded-apis
|
|
167
|
+
|
|
168
|
+
constructor(global) {LoaderShim.prototype.__init.call(this);LoaderShim.prototype.__init2.call(this);
|
|
137
169
|
// Start watchdog timer
|
|
138
170
|
if (hasSetTimeout) {
|
|
139
171
|
this.watchdogTimerId = this.startWatchdogTimer();
|
|
140
172
|
}
|
|
173
|
+
|
|
141
174
|
// Parse configuration
|
|
142
175
|
this.global = global;
|
|
143
|
-
this.config = global.LWR;
|
|
144
|
-
this.loaderSpecifier = 'lwr/loader/v/0_10_0-
|
|
176
|
+
this.config = global.LWR ;
|
|
177
|
+
this.loaderSpecifier = 'lwr/loader/v/0_10_0-alpha_6';
|
|
178
|
+
|
|
145
179
|
// Set up error handler
|
|
146
180
|
this.errorHandler = this.config.onError;
|
|
181
|
+
|
|
147
182
|
// Set up the temporary LWR.define function and customInit hook
|
|
148
183
|
const tempDefine = this.tempDefine.bind(this);
|
|
149
184
|
global.LWR.define = tempDefine;
|
|
150
185
|
this.bootReady = this.config.autoBoot;
|
|
186
|
+
|
|
151
187
|
try {
|
|
152
188
|
this.createProfilerModule(this.config);
|
|
153
|
-
customInit(
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
189
|
+
customInit(
|
|
190
|
+
Object.freeze(this.config),
|
|
191
|
+
this.postCustomInit.bind(this),
|
|
192
|
+
tempDefine,
|
|
193
|
+
(e) => {
|
|
194
|
+
// customInit handlers can overwrite
|
|
195
|
+
// the error handler with onBootstrapError
|
|
196
|
+
this.errorHandler = e;
|
|
197
|
+
},
|
|
198
|
+
);
|
|
199
|
+
} catch (e) {
|
|
160
200
|
this.enterErrorState(e);
|
|
161
201
|
}
|
|
162
202
|
}
|
|
203
|
+
|
|
163
204
|
// Return true if the app can be initialized
|
|
164
|
-
|
|
205
|
+
canInit() {
|
|
165
206
|
// Initialize the app if:
|
|
166
207
|
// - bootReady: autoBoot is on OR customInit has finished
|
|
167
208
|
// - all required modules are defined
|
|
168
209
|
const allDefined = this.config.requiredModules.every((m) => this.orderedDefs.includes(m));
|
|
169
210
|
return this.bootReady && allDefined;
|
|
170
211
|
}
|
|
212
|
+
|
|
171
213
|
/**
|
|
172
214
|
* Create a temporary LWR.define() function which captures all
|
|
173
215
|
* calls that occur BEFORE the full loader module is available
|
|
@@ -177,7 +219,7 @@
|
|
|
177
219
|
* - each moduleName is pushed onto an array, to preserve
|
|
178
220
|
* the order in which the modules were defined
|
|
179
221
|
*/
|
|
180
|
-
|
|
222
|
+
tempDefine(...args) {
|
|
181
223
|
// Cache the incoming module
|
|
182
224
|
const moduleName = args[0];
|
|
183
225
|
this.defineCache[moduleName] = args;
|
|
@@ -191,15 +233,17 @@
|
|
|
191
233
|
this.initApp();
|
|
192
234
|
}
|
|
193
235
|
}
|
|
236
|
+
|
|
194
237
|
// Called by the customInit hook via lwr.initializeApp()
|
|
195
|
-
|
|
238
|
+
postCustomInit() {
|
|
196
239
|
this.bootReady = true;
|
|
197
240
|
if (this.canInit()) {
|
|
198
241
|
this.initApp();
|
|
199
242
|
}
|
|
200
243
|
}
|
|
244
|
+
|
|
201
245
|
// Create the loader and initialize the application
|
|
202
|
-
|
|
246
|
+
initApp() {
|
|
203
247
|
try {
|
|
204
248
|
const loaderConfig = {
|
|
205
249
|
endpoints: this.config.endpoints,
|
|
@@ -213,18 +257,24 @@
|
|
|
213
257
|
rootComponents: this.config.rootComponents,
|
|
214
258
|
},
|
|
215
259
|
};
|
|
216
|
-
const loader = createLoader(
|
|
260
|
+
const loader = createLoader(
|
|
261
|
+
this.loaderSpecifier,
|
|
262
|
+
this.defineCache[this.loaderSpecifier],
|
|
263
|
+
loaderConfig,
|
|
264
|
+
this.config.preloadModules,
|
|
265
|
+
);
|
|
217
266
|
this.mountApp(loader);
|
|
218
|
-
}
|
|
219
|
-
catch (e) {
|
|
267
|
+
} catch (e) {
|
|
220
268
|
this.enterErrorState(e);
|
|
221
269
|
}
|
|
222
270
|
}
|
|
223
|
-
|
|
271
|
+
|
|
272
|
+
waitForDOMContentLoaded() {
|
|
224
273
|
// eslint-disable-next-line lwr/no-unguarded-apis
|
|
225
274
|
if (typeof document === undefined) {
|
|
226
275
|
return Promise.resolve();
|
|
227
276
|
}
|
|
277
|
+
|
|
228
278
|
// Resolve if document is already "ready" https://developer.mozilla.org/en-US/docs/Web/API/Document/readyState
|
|
229
279
|
// eslint-disable-next-line lwr/no-unguarded-apis
|
|
230
280
|
if (document.readyState === 'interactive' || document.readyState === 'complete') {
|
|
@@ -237,17 +287,21 @@
|
|
|
237
287
|
});
|
|
238
288
|
});
|
|
239
289
|
}
|
|
290
|
+
|
|
240
291
|
// Create a module out of the profiler
|
|
241
292
|
// Note: The profiler is also available as a module through lwc module resolution (see package.json)
|
|
242
|
-
|
|
293
|
+
createProfilerModule(globalLWR) {
|
|
243
294
|
const exporter = (exports) => {
|
|
244
295
|
Object.assign(exports, { logOperationStart, logOperationEnd });
|
|
245
296
|
};
|
|
246
|
-
globalLWR.define('lwr/profiler/v/0_10_0-
|
|
297
|
+
globalLWR.define('lwr/profiler/v/0_10_0-alpha_6', ['exports'], exporter);
|
|
247
298
|
}
|
|
299
|
+
|
|
248
300
|
// Set up the application globals, import map, root custom element...
|
|
249
|
-
|
|
250
|
-
const { bootstrapModule, rootComponent, rootComponents, ssrProps, endpoints, imports, index } =
|
|
301
|
+
mountApp(loader) {
|
|
302
|
+
const { bootstrapModule, rootComponent, rootComponents, ssrProps, endpoints, imports, index } =
|
|
303
|
+
this.config;
|
|
304
|
+
|
|
251
305
|
// Set global LWR.define to loader.define
|
|
252
306
|
this.global.LWR = Object.freeze({
|
|
253
307
|
define: loader.define.bind(loader),
|
|
@@ -258,42 +312,50 @@
|
|
|
258
312
|
imports: imports || {},
|
|
259
313
|
index: index || {},
|
|
260
314
|
});
|
|
315
|
+
|
|
261
316
|
// Redefine all modules in the temporary cache
|
|
262
317
|
this.orderedDefs.forEach((specifier) => {
|
|
263
318
|
if (specifier !== this.loaderSpecifier) {
|
|
264
319
|
loader.define(...this.defineCache[specifier]);
|
|
265
320
|
}
|
|
266
321
|
});
|
|
322
|
+
|
|
267
323
|
// by default, app initialization is gated on waiting for document to be parsed (via DOMContentLoaded)
|
|
268
324
|
const { disableInitDefer } = this.config;
|
|
325
|
+
|
|
269
326
|
// Load the import mappings and application bootstrap module
|
|
270
327
|
loader
|
|
271
328
|
.registerImportMappings({ imports, index }, [bootstrapModule, rootComponent])
|
|
272
329
|
.then(() => {
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
330
|
+
if (!disableInitDefer) {
|
|
331
|
+
return this.waitForDOMContentLoaded();
|
|
332
|
+
}
|
|
333
|
+
})
|
|
277
334
|
.then(() => loader.load(bootstrapModule))
|
|
278
335
|
.catch((reason) => {
|
|
279
|
-
|
|
280
|
-
|
|
336
|
+
this.enterErrorState(
|
|
337
|
+
new Error(
|
|
338
|
+
`Application ${rootComponent || bootstrapModule} could not be loaded: ${reason}`,
|
|
339
|
+
),
|
|
340
|
+
);
|
|
341
|
+
});
|
|
281
342
|
}
|
|
343
|
+
|
|
282
344
|
// Trigger bootstrap error state, and call error handler if registered
|
|
283
|
-
|
|
345
|
+
enterErrorState(error) {
|
|
284
346
|
logOperationStart({ id: BOOTSTRAP_ERROR });
|
|
285
347
|
if (this.errorHandler) {
|
|
286
348
|
this.errorHandler(error);
|
|
287
|
-
}
|
|
288
|
-
else {
|
|
349
|
+
} else {
|
|
289
350
|
if (hasConsole) {
|
|
290
351
|
// eslint-disable-next-line lwr/no-unguarded-apis, no-undef
|
|
291
352
|
console.error(`An error occurred during LWR bootstrap. ${error.message}`, error.stack);
|
|
292
353
|
}
|
|
293
354
|
}
|
|
294
355
|
}
|
|
356
|
+
|
|
295
357
|
// eslint-disable-next-line no-undef, lwr/no-unguarded-apis
|
|
296
|
-
|
|
358
|
+
startWatchdogTimer() {
|
|
297
359
|
// eslint-disable-next-line lwr/no-unguarded-apis, no-undef
|
|
298
360
|
return setTimeout(() => {
|
|
299
361
|
this.enterErrorState(new Error('Failed to load required modules - timed out'));
|
|
@@ -302,16 +364,17 @@
|
|
|
302
364
|
}
|
|
303
365
|
|
|
304
366
|
// The loader module is ALWAYS required
|
|
305
|
-
const GLOBAL = globalThis;
|
|
367
|
+
const GLOBAL = globalThis ;
|
|
306
368
|
GLOBAL.LWR.requiredModules = GLOBAL.LWR.requiredModules || [];
|
|
307
|
-
if (GLOBAL.LWR.requiredModules.indexOf('lwr/loader/v/0_10_0-
|
|
308
|
-
GLOBAL.LWR.requiredModules.push('lwr/loader/v/0_10_0-
|
|
369
|
+
if (GLOBAL.LWR.requiredModules.indexOf('lwr/loader/v/0_10_0-alpha_6') < 0) {
|
|
370
|
+
GLOBAL.LWR.requiredModules.push('lwr/loader/v/0_10_0-alpha_6');
|
|
309
371
|
}
|
|
310
372
|
new LoaderShim(GLOBAL);
|
|
311
373
|
|
|
312
|
-
}()
|
|
374
|
+
})();
|
|
375
|
+
//# sourceMappingURL=lwr-loader-shim.js.map
|
|
313
376
|
|
|
314
|
-
LWR.define('lwr/loader/v/0_10_0-
|
|
377
|
+
LWR.define('lwr/loader/v/0_10_0-alpha_6', ['exports'], (function (exports) { 'use strict';
|
|
315
378
|
|
|
316
379
|
const templateRegex = /\{([0-9]+)\}/g;
|
|
317
380
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
@@ -326,17 +389,26 @@ LWR.define('lwr/loader/v/0_10_0-alpha_4', ['exports'], function (exports) { 'use
|
|
|
326
389
|
const message = Array.isArray(args) ? templateString(errorInfo.message, args) : errorInfo.message;
|
|
327
390
|
return `LWR${errorInfo.code}: ${message}`;
|
|
328
391
|
}
|
|
392
|
+
|
|
329
393
|
class LoaderError extends Error {
|
|
330
394
|
constructor(errorInfo, errorArgs) {
|
|
331
395
|
super();
|
|
332
396
|
this.message = generateErrorMessage(errorInfo, errorArgs);
|
|
333
397
|
}
|
|
334
398
|
}
|
|
399
|
+
|
|
335
400
|
function invariant(condition, errorInfo) {
|
|
336
401
|
if (!condition) {
|
|
337
402
|
throw new LoaderError(errorInfo);
|
|
338
403
|
}
|
|
339
404
|
}
|
|
405
|
+
|
|
406
|
+
|
|
407
|
+
|
|
408
|
+
|
|
409
|
+
|
|
410
|
+
|
|
411
|
+
|
|
340
412
|
const MISSING_NAME = Object.freeze({
|
|
341
413
|
code: 3000,
|
|
342
414
|
message: 'A module name is required.',
|
|
@@ -427,6 +499,7 @@ LWR.define('lwr/loader/v/0_10_0-alpha_4', ['exports'], function (exports) { 'use
|
|
|
427
499
|
level: 0,
|
|
428
500
|
message: 'Invalid import metadata: {0} {1}',
|
|
429
501
|
});
|
|
502
|
+
|
|
430
503
|
/* importMap errors */
|
|
431
504
|
Object.freeze({
|
|
432
505
|
code: 3011,
|
|
@@ -436,7 +509,9 @@ LWR.define('lwr/loader/v/0_10_0-alpha_4', ['exports'], function (exports) { 'use
|
|
|
436
509
|
|
|
437
510
|
/* eslint-disable lwr/no-unguarded-apis */
|
|
438
511
|
const hasDocument = typeof document !== 'undefined';
|
|
512
|
+
|
|
439
513
|
const hasSetTimeout = typeof setTimeout === 'function';
|
|
514
|
+
|
|
440
515
|
const hasConsole = typeof console !== 'undefined';
|
|
441
516
|
/* eslint-enable lwr/no-unguarded-apis */
|
|
442
517
|
|
|
@@ -444,7 +519,7 @@ LWR.define('lwr/loader/v/0_10_0-alpha_4', ['exports'], function (exports) { 'use
|
|
|
444
519
|
let baseUrl = undefined;
|
|
445
520
|
if (hasDocument) {
|
|
446
521
|
// eslint-disable-next-line lwr/no-unguarded-apis, no-undef
|
|
447
|
-
const baseEl = document.querySelector('base[href]');
|
|
522
|
+
const baseEl = document.querySelector('base[href]') ;
|
|
448
523
|
baseUrl = baseEl && baseEl.href;
|
|
449
524
|
}
|
|
450
525
|
// eslint-disable-next-line lwr/no-unguarded-apis
|
|
@@ -456,8 +531,10 @@ LWR.define('lwr/loader/v/0_10_0-alpha_4', ['exports'], function (exports) { 'use
|
|
|
456
531
|
baseUrl = baseUrl.slice(0, lastSepIndex + 1);
|
|
457
532
|
}
|
|
458
533
|
}
|
|
534
|
+
|
|
459
535
|
return baseUrl;
|
|
460
536
|
}
|
|
537
|
+
|
|
461
538
|
/**
|
|
462
539
|
* Check if a string is a URL based on Common Internet Scheme Syntax
|
|
463
540
|
* https://www.ietf.org/rfc/rfc1738.txt
|
|
@@ -484,24 +561,26 @@ LWR.define('lwr/loader/v/0_10_0-alpha_4', ['exports'], function (exports) { 'use
|
|
|
484
561
|
function isUrl(url) {
|
|
485
562
|
return url.indexOf('://') !== -1;
|
|
486
563
|
}
|
|
564
|
+
|
|
487
565
|
// Borrowed and adapted from https://github.com/systemjs/systemjs/blob/master/src/common.js
|
|
488
566
|
// Resolves the first path segment relative to the second/parent URL
|
|
489
567
|
// eg: resolveIfNotPlainOrUrl('../test', 'http://www.site.com/one/two') => 'http://www.site.com/test'
|
|
490
568
|
// eg: resolveIfNotPlainOrUrl('./x/y/z', 'https://my.com/segment')).toBe('https://my.com/x/y/z')
|
|
491
569
|
function resolveIfNotPlainOrUrl(relUrl, parentUrl) {
|
|
492
570
|
const backslashRegEx = /\\/g;
|
|
493
|
-
if (relUrl.indexOf('\\') !== -1)
|
|
494
|
-
relUrl = relUrl.replace(backslashRegEx, '/');
|
|
571
|
+
if (relUrl.indexOf('\\') !== -1) relUrl = relUrl.replace(backslashRegEx, '/');
|
|
495
572
|
// protocol-relative
|
|
496
573
|
if (relUrl[0] === '/' && relUrl[1] === '/') {
|
|
497
574
|
return parentUrl.slice(0, parentUrl.indexOf(':') + 1) + relUrl;
|
|
498
575
|
}
|
|
499
576
|
// relative-url
|
|
500
|
-
else if (
|
|
501
|
-
(relUrl[
|
|
502
|
-
(relUrl[1] === '
|
|
503
|
-
|
|
504
|
-
|
|
577
|
+
else if (
|
|
578
|
+
(relUrl[0] === '.' &&
|
|
579
|
+
(relUrl[1] === '/' ||
|
|
580
|
+
(relUrl[1] === '.' && (relUrl[2] === '/' || (relUrl.length === 2 && (relUrl += '/')))) ||
|
|
581
|
+
(relUrl.length === 1 && (relUrl += '/')))) ||
|
|
582
|
+
relUrl[0] === '/'
|
|
583
|
+
) {
|
|
505
584
|
const parentProtocol = parentUrl.slice(0, parentUrl.indexOf(':') + 1);
|
|
506
585
|
let pathname;
|
|
507
586
|
if (parentUrl[parentProtocol.length + 1] === '/') {
|
|
@@ -509,21 +588,23 @@ LWR.define('lwr/loader/v/0_10_0-alpha_4', ['exports'], function (exports) { 'use
|
|
|
509
588
|
if (parentProtocol !== 'file:') {
|
|
510
589
|
pathname = parentUrl.slice(parentProtocol.length + 2);
|
|
511
590
|
pathname = pathname.slice(pathname.indexOf('/') + 1);
|
|
512
|
-
}
|
|
513
|
-
else {
|
|
591
|
+
} else {
|
|
514
592
|
pathname = parentUrl.slice(8);
|
|
515
593
|
}
|
|
516
|
-
}
|
|
517
|
-
else {
|
|
594
|
+
} else {
|
|
518
595
|
// resolving to :/ so pathname is the /... part
|
|
519
|
-
pathname = parentUrl.slice(
|
|
596
|
+
pathname = parentUrl.slice(
|
|
597
|
+
parentProtocol.length + (parentUrl[parentProtocol.length] === '/' ? 1 : 0),
|
|
598
|
+
);
|
|
520
599
|
}
|
|
521
|
-
|
|
522
|
-
|
|
600
|
+
|
|
601
|
+
if (relUrl[0] === '/') return parentUrl.slice(0, parentUrl.length - pathname.length - 1) + relUrl;
|
|
602
|
+
|
|
523
603
|
// join together and split for removal of .. and . segments
|
|
524
604
|
// looping the string instead of anything fancy for perf reasons
|
|
525
605
|
// '../../../../../z' resolved to 'x/y' is just 'z'
|
|
526
606
|
const segmented = pathname.slice(0, pathname.lastIndexOf('/') + 1) + relUrl;
|
|
607
|
+
|
|
527
608
|
const output = [];
|
|
528
609
|
let segmentIndex = -1;
|
|
529
610
|
for (let i = 0; i < segmented.length; i++) {
|
|
@@ -534,6 +615,7 @@ LWR.define('lwr/loader/v/0_10_0-alpha_4', ['exports'], function (exports) { 'use
|
|
|
534
615
|
segmentIndex = -1;
|
|
535
616
|
}
|
|
536
617
|
}
|
|
618
|
+
|
|
537
619
|
// new segment - check if it is relative
|
|
538
620
|
else if (segmented[i] === '.') {
|
|
539
621
|
// ../ segment
|
|
@@ -544,8 +626,7 @@ LWR.define('lwr/loader/v/0_10_0-alpha_4', ['exports'], function (exports) { 'use
|
|
|
544
626
|
// ./ segment
|
|
545
627
|
else if (segmented[i + 1] === '/' || i + 1 === segmented.length) {
|
|
546
628
|
i += 1;
|
|
547
|
-
}
|
|
548
|
-
else {
|
|
629
|
+
} else {
|
|
549
630
|
// the start of a new segment as below
|
|
550
631
|
segmentIndex = i;
|
|
551
632
|
}
|
|
@@ -556,13 +637,14 @@ LWR.define('lwr/loader/v/0_10_0-alpha_4', ['exports'], function (exports) { 'use
|
|
|
556
637
|
}
|
|
557
638
|
}
|
|
558
639
|
// finish reading out the last segment
|
|
559
|
-
if (segmentIndex !== -1)
|
|
560
|
-
output.push(segmented.slice(segmentIndex));
|
|
640
|
+
if (segmentIndex !== -1) output.push(segmented.slice(segmentIndex));
|
|
561
641
|
return parentUrl.slice(0, parentUrl.length - pathname.length) + output.join('');
|
|
562
642
|
}
|
|
563
643
|
}
|
|
644
|
+
|
|
564
645
|
function resolveUrl(relUrl, parentUrl) {
|
|
565
|
-
const resolvedUrl =
|
|
646
|
+
const resolvedUrl =
|
|
647
|
+
resolveIfNotPlainOrUrl(relUrl, parentUrl) ||
|
|
566
648
|
(isUrl(relUrl) ? relUrl : resolveIfNotPlainOrUrl('./' + relUrl, parentUrl));
|
|
567
649
|
return resolvedUrl;
|
|
568
650
|
}
|
|
@@ -575,6 +657,7 @@ LWR.define('lwr/loader/v/0_10_0-alpha_4', ['exports'], function (exports) { 'use
|
|
|
575
657
|
script.src = url;
|
|
576
658
|
return script;
|
|
577
659
|
}
|
|
660
|
+
|
|
578
661
|
let lastWindowError$1, lastWindowErrorUrl;
|
|
579
662
|
function loadModuleDef(url) {
|
|
580
663
|
return new Promise(function (resolve, reject) {
|
|
@@ -588,8 +671,7 @@ LWR.define('lwr/loader/v/0_10_0-alpha_4', ['exports'], function (exports) { 'use
|
|
|
588
671
|
document.head.removeChild(script);
|
|
589
672
|
if (lastWindowErrorUrl === url) {
|
|
590
673
|
reject(lastWindowError$1);
|
|
591
|
-
}
|
|
592
|
-
else {
|
|
674
|
+
} else {
|
|
593
675
|
resolve();
|
|
594
676
|
}
|
|
595
677
|
});
|
|
@@ -598,6 +680,7 @@ LWR.define('lwr/loader/v/0_10_0-alpha_4', ['exports'], function (exports) { 'use
|
|
|
598
680
|
}
|
|
599
681
|
});
|
|
600
682
|
}
|
|
683
|
+
|
|
601
684
|
if (hasDocument) {
|
|
602
685
|
// When a script is executed, runtime errors are on the global/window scope which are NOT caught by the script's onerror handler.
|
|
603
686
|
// eslint-disable-next-line lwr/no-unguarded-apis, no-undef
|
|
@@ -621,44 +704,53 @@ LWR.define('lwr/loader/v/0_10_0-alpha_4', ['exports'], function (exports) { 'use
|
|
|
621
704
|
|
|
622
705
|
/* spec based import map resolver */
|
|
623
706
|
class ImportMetadataResolver {
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
707
|
+
// Default to empty mappings
|
|
708
|
+
__init() {this.importURICache = new Map();}
|
|
709
|
+
__init2() {this.pendingURICache = new Map();}
|
|
710
|
+
|
|
711
|
+
|
|
712
|
+
__init3() {this.loadMappingHooks = [];}
|
|
713
|
+
|
|
714
|
+
constructor(config, invalidationCallback) {ImportMetadataResolver.prototype.__init.call(this);ImportMetadataResolver.prototype.__init2.call(this);ImportMetadataResolver.prototype.__init3.call(this);
|
|
629
715
|
this.config = config;
|
|
630
716
|
this.invalidationCallback = invalidationCallback;
|
|
631
717
|
}
|
|
718
|
+
|
|
632
719
|
addLoadMappingHook(hook) {
|
|
633
720
|
this.loadMappingHooks.push(hook);
|
|
634
721
|
}
|
|
722
|
+
|
|
635
723
|
getMappingEndpoint() {
|
|
636
724
|
return this.config.endpoints && this.config.endpoints.uris
|
|
637
725
|
? this.config.endpoints.uris.mapping
|
|
638
726
|
: undefined;
|
|
639
727
|
}
|
|
728
|
+
|
|
640
729
|
getModifiersAsUrlParams() {
|
|
641
730
|
const modifiers = this.config.endpoints ? this.config.endpoints.modifiers : undefined;
|
|
731
|
+
|
|
642
732
|
if (!modifiers) {
|
|
643
733
|
// No modifiers return an empty string to append to the URL
|
|
644
734
|
return '';
|
|
645
|
-
}
|
|
646
|
-
else {
|
|
735
|
+
} else {
|
|
647
736
|
const qs = Object.keys(modifiers)
|
|
648
737
|
.map((key) => `${encodeURIComponent(key)}=${encodeURIComponent(modifiers[key])}`)
|
|
649
738
|
.join('&');
|
|
650
739
|
return `?${qs}`;
|
|
651
740
|
}
|
|
652
741
|
}
|
|
742
|
+
|
|
653
743
|
buildMappingUrl(specifier) {
|
|
654
744
|
const mappingEndpoint = this.getMappingEndpoint();
|
|
655
745
|
const specifiers = encodeURIComponent(specifier);
|
|
656
746
|
const modifiers = this.getModifiersAsUrlParams();
|
|
657
747
|
return `${mappingEndpoint}${specifiers}${modifiers}`;
|
|
658
748
|
}
|
|
749
|
+
|
|
659
750
|
getBaseUrl() {
|
|
660
751
|
return this.config.baseUrl;
|
|
661
752
|
}
|
|
753
|
+
|
|
662
754
|
registerImportMappings(newImportMetadata, rootSpecifiers) {
|
|
663
755
|
if (!rootSpecifiers || rootSpecifiers.length === 0) {
|
|
664
756
|
const imports = newImportMetadata ? JSON.stringify(newImportMetadata) : 'undefined';
|
|
@@ -680,8 +772,7 @@ LWR.define('lwr/loader/v/0_10_0-alpha_4', ['exports'], function (exports) { 'use
|
|
|
680
772
|
const existing = this.importURICache.get(specifier);
|
|
681
773
|
if (!existing) {
|
|
682
774
|
this.saveImportURIRecord(specifier, uri, indexValue, rootSpecifiers.includes(specifier));
|
|
683
|
-
}
|
|
684
|
-
else {
|
|
775
|
+
} else {
|
|
685
776
|
const identity = indexValue || uri;
|
|
686
777
|
const existingIdentity = existing.identity || existing.uri;
|
|
687
778
|
if (existingIdentity !== identity) {
|
|
@@ -695,22 +786,24 @@ LWR.define('lwr/loader/v/0_10_0-alpha_4', ['exports'], function (exports) { 'use
|
|
|
695
786
|
});
|
|
696
787
|
}
|
|
697
788
|
}
|
|
789
|
+
|
|
698
790
|
// Get URL from the local cache or return undefiend
|
|
699
|
-
|
|
791
|
+
getURI(specifier) {
|
|
700
792
|
return this.importURICache.has(specifier)
|
|
701
793
|
? resolveUrl(this.importURICache.get(specifier).uri, this.getBaseUrl())
|
|
702
794
|
: undefined;
|
|
703
795
|
}
|
|
796
|
+
|
|
704
797
|
resolveLocal(specifier) {
|
|
705
798
|
const uri = this.getURI(specifier);
|
|
706
799
|
if (uri) {
|
|
707
800
|
return uri;
|
|
708
|
-
}
|
|
709
|
-
else if (isUrl(specifier) || specifier.startsWith('/')) {
|
|
801
|
+
} else if (isUrl(specifier) || specifier.startsWith('/')) {
|
|
710
802
|
return specifier;
|
|
711
803
|
}
|
|
712
804
|
return undefined;
|
|
713
805
|
}
|
|
806
|
+
|
|
714
807
|
/**
|
|
715
808
|
* Resolves a the URI for a specified module. It will return the value in this order:
|
|
716
809
|
*
|
|
@@ -725,15 +818,14 @@ LWR.define('lwr/loader/v/0_10_0-alpha_4', ['exports'], function (exports) { 'use
|
|
|
725
818
|
let uri = this.getURI(specifier);
|
|
726
819
|
if (uri) {
|
|
727
820
|
return uri;
|
|
728
|
-
}
|
|
729
|
-
else if (isUrl(specifier) || specifier.startsWith('/')) {
|
|
821
|
+
} else if (isUrl(specifier) || specifier.startsWith('/')) {
|
|
730
822
|
return specifier;
|
|
731
|
-
}
|
|
732
|
-
else {
|
|
823
|
+
} else {
|
|
733
824
|
const pending = this.pendingURICache.get(specifier);
|
|
734
825
|
if (pending) {
|
|
735
826
|
return pending;
|
|
736
827
|
}
|
|
828
|
+
|
|
737
829
|
this.config.profiler.logOperationStart({ id: MAPPINGS_FETCH, specifier });
|
|
738
830
|
const fetchMappingService = this.hasMappingHooks()
|
|
739
831
|
? this.evaluateMappingHooks
|
|
@@ -741,33 +833,37 @@ LWR.define('lwr/loader/v/0_10_0-alpha_4', ['exports'], function (exports) { 'use
|
|
|
741
833
|
const promise = fetchMappingService
|
|
742
834
|
.bind(this)(specifier)
|
|
743
835
|
.then((importMetadata) => {
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
|
|
753
|
-
|
|
754
|
-
|
|
836
|
+
if (!importMetadata || !importMetadata.imports) {
|
|
837
|
+
throw new LoaderError(UNRESOLVED, [specifier]);
|
|
838
|
+
}
|
|
839
|
+
this.registerImportMappings(importMetadata, [specifier]);
|
|
840
|
+
uri = this.getURI(specifier);
|
|
841
|
+
if (!uri) {
|
|
842
|
+
throw new LoaderError(UNRESOLVED, [specifier]);
|
|
843
|
+
}
|
|
844
|
+
|
|
845
|
+
this.config.profiler.logOperationEnd({ id: MAPPINGS_FETCH, specifier });
|
|
846
|
+
return uri;
|
|
847
|
+
})
|
|
755
848
|
.finally(() => {
|
|
756
|
-
|
|
757
|
-
|
|
849
|
+
this.pendingURICache.delete(specifier);
|
|
850
|
+
});
|
|
851
|
+
|
|
758
852
|
this.pendingURICache.set(specifier, promise);
|
|
759
853
|
return promise;
|
|
760
854
|
}
|
|
761
855
|
}
|
|
762
|
-
|
|
856
|
+
|
|
857
|
+
hasMappingHooks() {
|
|
763
858
|
return this.loadMappingHooks.length > 0;
|
|
764
859
|
}
|
|
860
|
+
|
|
765
861
|
/**
|
|
766
862
|
* Evaluates mapping hooks. Returns first match. If all hooks return null call the mapping service.
|
|
767
863
|
* @param specifier Request module identifier
|
|
768
864
|
* @returns Import Metadata from the module root
|
|
769
865
|
*/
|
|
770
|
-
|
|
866
|
+
async evaluateMappingHooks(specifier) {
|
|
771
867
|
// Check with any registered loadMappingHooks
|
|
772
868
|
const loadMappingHooks = this.loadMappingHooks;
|
|
773
869
|
if (loadMappingHooks.length) {
|
|
@@ -782,13 +878,16 @@ LWR.define('lwr/loader/v/0_10_0-alpha_4', ['exports'], function (exports) { 'use
|
|
|
782
878
|
}
|
|
783
879
|
}
|
|
784
880
|
}
|
|
881
|
+
|
|
785
882
|
// If we still do not have a match call the mapping service
|
|
786
883
|
return this.fetchNewMappings(specifier);
|
|
787
884
|
}
|
|
788
|
-
|
|
885
|
+
|
|
886
|
+
async fetchNewMappings(specifier) {
|
|
789
887
|
if (typeof globalThis.fetch !== 'function') {
|
|
790
888
|
throw new LoaderError(UNRESOLVED, [specifier]);
|
|
791
889
|
}
|
|
890
|
+
|
|
792
891
|
// TODO For module invalidation with bundles it is recommended we have to send back all loaded root specified
|
|
793
892
|
// to ensure we detect all conflicts.
|
|
794
893
|
const uri = resolveUrl(this.buildMappingUrl(specifier), this.getBaseUrl());
|
|
@@ -800,21 +899,21 @@ LWR.define('lwr/loader/v/0_10_0-alpha_4', ['exports'], function (exports) { 'use
|
|
|
800
899
|
return res
|
|
801
900
|
.json()
|
|
802
901
|
.then((ret) => {
|
|
803
|
-
|
|
804
|
-
|
|
902
|
+
return ret ;
|
|
903
|
+
})
|
|
805
904
|
.catch((err) => {
|
|
806
|
-
|
|
807
|
-
|
|
905
|
+
throw new LoaderError(UNRESOLVED, [specifier]);
|
|
906
|
+
});
|
|
808
907
|
});
|
|
809
908
|
}
|
|
810
|
-
|
|
909
|
+
|
|
910
|
+
saveImportURIRecord(specifier, uri, identity, isRoot) {
|
|
811
911
|
if (!identity || uri === identity) {
|
|
812
912
|
this.importURICache.set(specifier, {
|
|
813
913
|
uri,
|
|
814
914
|
isRoot: isRoot,
|
|
815
915
|
});
|
|
816
|
-
}
|
|
817
|
-
else {
|
|
916
|
+
} else {
|
|
818
917
|
this.importURICache.set(specifier, {
|
|
819
918
|
uri,
|
|
820
919
|
identity,
|
|
@@ -827,11 +926,13 @@ LWR.define('lwr/loader/v/0_10_0-alpha_4', ['exports'], function (exports) { 'use
|
|
|
827
926
|
function reportError(error) {
|
|
828
927
|
// TODO eventually this should be configurable instrumentation to send this somewhere
|
|
829
928
|
// eslint-disable-next-line lwr/no-unguarded-apis, no-undef
|
|
830
|
-
if (hasConsole)
|
|
831
|
-
console.error(error);
|
|
929
|
+
if (hasConsole) console.error(error);
|
|
832
930
|
}
|
|
833
931
|
|
|
834
|
-
function evaluateHandleStaleModuleHooks(
|
|
932
|
+
function evaluateHandleStaleModuleHooks(
|
|
933
|
+
handleStaleModuleHooks,
|
|
934
|
+
hookArgs,
|
|
935
|
+
) {
|
|
835
936
|
const { name, oldUrl, newUrl } = hookArgs;
|
|
836
937
|
// keep evaluating hooks if return value is null
|
|
837
938
|
for (let i = 0; i < handleStaleModuleHooks.length; i++) {
|
|
@@ -841,8 +942,7 @@ LWR.define('lwr/loader/v/0_10_0-alpha_4', ['exports'], function (exports) { 'use
|
|
|
841
942
|
if (hookResult !== null) {
|
|
842
943
|
break;
|
|
843
944
|
}
|
|
844
|
-
}
|
|
845
|
-
catch (e) {
|
|
945
|
+
} catch (e) {
|
|
846
946
|
reportError(new LoaderError(STALE_HOOK_ERROR));
|
|
847
947
|
}
|
|
848
948
|
}
|
|
@@ -851,29 +951,45 @@ LWR.define('lwr/loader/v/0_10_0-alpha_4', ['exports'], function (exports) { 'use
|
|
|
851
951
|
const MODULE_LOAD_TIMEOUT_TIMER = 300000;
|
|
852
952
|
|
|
853
953
|
/* global console,process */
|
|
954
|
+
|
|
955
|
+
|
|
854
956
|
let lastWindowError;
|
|
855
957
|
if (hasDocument) {
|
|
856
958
|
globalThis.addEventListener('error', (evt) => {
|
|
857
959
|
lastWindowError = evt.error;
|
|
858
960
|
});
|
|
859
961
|
}
|
|
962
|
+
|
|
860
963
|
if (process.env.NODE_ENV !== 'production') {
|
|
861
964
|
if (!hasSetTimeout && hasConsole) {
|
|
862
965
|
// eslint-disable-next-line lwr/no-unguarded-apis
|
|
863
966
|
console.warn('setTimeout API is not available, watchdog timer on load hook will not be set');
|
|
864
967
|
}
|
|
865
968
|
}
|
|
969
|
+
|
|
866
970
|
function isCustomResponse(response) {
|
|
867
|
-
return (
|
|
868
|
-
|
|
971
|
+
return (
|
|
972
|
+
Object.prototype.hasOwnProperty.call(response, 'data') &&
|
|
973
|
+
!Object.prototype.hasOwnProperty.call(response, 'blob')
|
|
974
|
+
);
|
|
869
975
|
}
|
|
870
|
-
function isFetchResponse(
|
|
976
|
+
function isFetchResponse(
|
|
977
|
+
response,
|
|
978
|
+
) {
|
|
871
979
|
// if it quacks like a duck...
|
|
872
|
-
return typeof response.blob === 'function';
|
|
980
|
+
return typeof (response ).blob === 'function';
|
|
873
981
|
}
|
|
874
|
-
|
|
875
|
-
|
|
982
|
+
|
|
983
|
+
function isResponseAPromise(
|
|
984
|
+
response
|
|
985
|
+
|
|
986
|
+
|
|
987
|
+
|
|
988
|
+
,
|
|
989
|
+
) {
|
|
990
|
+
return !!(response && (response ).then);
|
|
876
991
|
}
|
|
992
|
+
|
|
877
993
|
async function evaluateLoadHookResponse(response, id) {
|
|
878
994
|
return Promise.resolve().then(async () => {
|
|
879
995
|
if (!response.status) {
|
|
@@ -882,36 +998,41 @@ LWR.define('lwr/loader/v/0_10_0-alpha_4', ['exports'], function (exports) { 'use
|
|
|
882
998
|
if (response.status !== 200) {
|
|
883
999
|
throw new LoaderError(HTTP_FAIL_LOAD, [id, `${response.status}`]);
|
|
884
1000
|
}
|
|
1001
|
+
|
|
885
1002
|
const isResponse = isFetchResponse(response);
|
|
886
1003
|
let code;
|
|
887
1004
|
if (isCustomResponse(response)) {
|
|
888
1005
|
code = response.data;
|
|
889
|
-
}
|
|
890
|
-
else if (isResponse) {
|
|
1006
|
+
} else if (isResponse) {
|
|
891
1007
|
// handle fetch response
|
|
892
|
-
code = await response.text();
|
|
893
|
-
}
|
|
894
|
-
else {
|
|
1008
|
+
code = await (response ).text();
|
|
1009
|
+
} else {
|
|
895
1010
|
throw new LoaderError(INVALID_LOADER_SERVICE_RESPONSE);
|
|
896
1011
|
}
|
|
1012
|
+
|
|
897
1013
|
if (!code) {
|
|
898
1014
|
throw new LoaderError(FAIL_LOAD, [id]);
|
|
899
1015
|
}
|
|
1016
|
+
|
|
900
1017
|
code = `${code}\n//# sourceURL=${id}`; // append sourceURL for debugging
|
|
901
1018
|
try {
|
|
902
1019
|
// TODO eval source maps for debugging
|
|
903
1020
|
eval(code);
|
|
904
|
-
}
|
|
905
|
-
catch (e) {
|
|
1021
|
+
} catch (e) {
|
|
906
1022
|
throw new LoaderError(FAIL_LOAD, [id]);
|
|
907
1023
|
}
|
|
1024
|
+
|
|
908
1025
|
if (lastWindowError) {
|
|
909
1026
|
throw new LoaderError(FAIL_LOAD, [id]);
|
|
910
1027
|
}
|
|
911
1028
|
return true;
|
|
912
1029
|
});
|
|
913
1030
|
}
|
|
914
|
-
|
|
1031
|
+
|
|
1032
|
+
async function evaluateLoadHook(
|
|
1033
|
+
id,
|
|
1034
|
+
hookPromise,
|
|
1035
|
+
) {
|
|
915
1036
|
if (!hasSetTimeout) {
|
|
916
1037
|
return hookPromise;
|
|
917
1038
|
}
|
|
@@ -923,45 +1044,91 @@ LWR.define('lwr/loader/v/0_10_0-alpha_4', ['exports'], function (exports) { 'use
|
|
|
923
1044
|
}, MODULE_LOAD_TIMEOUT_TIMER);
|
|
924
1045
|
hookPromise
|
|
925
1046
|
.then((response) => {
|
|
926
|
-
|
|
927
|
-
|
|
1047
|
+
resolve(response);
|
|
1048
|
+
})
|
|
928
1049
|
.catch(() => {
|
|
929
|
-
|
|
930
|
-
|
|
1050
|
+
reject(new LoaderError(FAIL_HOOK_LOAD, [id]));
|
|
1051
|
+
})
|
|
931
1052
|
.finally(() => {
|
|
932
|
-
|
|
933
|
-
|
|
934
|
-
|
|
1053
|
+
// eslint-disable-next-line lwr/no-unguarded-apis, no-undef
|
|
1054
|
+
clearTimeout(timer);
|
|
1055
|
+
});
|
|
935
1056
|
});
|
|
936
1057
|
}
|
|
937
1058
|
|
|
938
1059
|
/* global console,process */
|
|
1060
|
+
|
|
1061
|
+
|
|
1062
|
+
|
|
1063
|
+
|
|
1064
|
+
|
|
1065
|
+
|
|
1066
|
+
|
|
1067
|
+
|
|
1068
|
+
|
|
1069
|
+
|
|
1070
|
+
|
|
1071
|
+
|
|
1072
|
+
|
|
1073
|
+
|
|
1074
|
+
|
|
1075
|
+
|
|
1076
|
+
|
|
1077
|
+
|
|
1078
|
+
|
|
1079
|
+
|
|
1080
|
+
|
|
1081
|
+
|
|
1082
|
+
|
|
1083
|
+
|
|
1084
|
+
|
|
1085
|
+
|
|
1086
|
+
|
|
1087
|
+
|
|
1088
|
+
|
|
1089
|
+
|
|
1090
|
+
|
|
1091
|
+
|
|
1092
|
+
|
|
1093
|
+
|
|
1094
|
+
|
|
1095
|
+
|
|
1096
|
+
|
|
1097
|
+
|
|
1098
|
+
|
|
1099
|
+
|
|
1100
|
+
|
|
1101
|
+
|
|
1102
|
+
|
|
1103
|
+
|
|
1104
|
+
|
|
939
1105
|
class ModuleRegistry {
|
|
940
|
-
|
|
941
|
-
|
|
942
|
-
|
|
943
|
-
// The evaluated module registry where the module identifier (name or URL?) is the key
|
|
944
|
-
this.moduleRegistry = new Map();
|
|
945
|
-
// Aliases of modules in the registry
|
|
946
|
-
this.aliases = new Map();
|
|
1106
|
+
|
|
1107
|
+
|
|
1108
|
+
constructor(config) {ModuleRegistry.prototype.__init.call(this);ModuleRegistry.prototype.__init2.call(this);ModuleRegistry.prototype.__init3.call(this);
|
|
947
1109
|
this.profiler = config.profiler;
|
|
948
|
-
this.resolver = new ImportMetadataResolver(
|
|
1110
|
+
this.resolver = new ImportMetadataResolver(
|
|
1111
|
+
config,
|
|
1112
|
+
this.importMetadataInvalidationCallback.bind(this),
|
|
1113
|
+
);
|
|
949
1114
|
}
|
|
1115
|
+
|
|
950
1116
|
async load(id, importer) {
|
|
951
1117
|
const resolvedId = await this.resolve(id, importer);
|
|
952
1118
|
const moduleRecord = this.getModuleRecord(resolvedId, id);
|
|
953
1119
|
if (moduleRecord.evaluated) {
|
|
954
1120
|
return moduleRecord.module;
|
|
955
|
-
}
|
|
956
|
-
else {
|
|
1121
|
+
} else {
|
|
957
1122
|
if (!moduleRecord.evaluationPromise) {
|
|
958
1123
|
moduleRecord.evaluationPromise = this.topLevelEvaluation(moduleRecord);
|
|
959
1124
|
}
|
|
960
1125
|
return moduleRecord.evaluationPromise;
|
|
961
1126
|
}
|
|
962
1127
|
}
|
|
1128
|
+
|
|
963
1129
|
async resolve(id, importer) {
|
|
964
1130
|
const parentUrl = this.resolver.getBaseUrl(); // only support baseUrl for now
|
|
1131
|
+
|
|
965
1132
|
let resolved;
|
|
966
1133
|
let aliasedId = id;
|
|
967
1134
|
const resolveHooks = this.resolveHook;
|
|
@@ -974,6 +1141,7 @@ LWR.define('lwr/loader/v/0_10_0-alpha_4', ['exports'], function (exports) { 'use
|
|
|
974
1141
|
// eslint-disable-next-line no-await-in-loop
|
|
975
1142
|
result = isResponseAPromise(response) ? await response : response;
|
|
976
1143
|
}
|
|
1144
|
+
|
|
977
1145
|
// if result is not null, attempt resolution
|
|
978
1146
|
if (result !== null) {
|
|
979
1147
|
if (typeof result === 'string') {
|
|
@@ -984,6 +1152,7 @@ LWR.define('lwr/loader/v/0_10_0-alpha_4', ['exports'], function (exports) { 'use
|
|
|
984
1152
|
aliasedId = result; // the next hook will receive the new id
|
|
985
1153
|
continue;
|
|
986
1154
|
}
|
|
1155
|
+
|
|
987
1156
|
resolved =
|
|
988
1157
|
result && result.url && (resolveIfNotPlainOrUrl(result.url, parentUrl) || result.url);
|
|
989
1158
|
if (!resolved) {
|
|
@@ -993,27 +1162,32 @@ LWR.define('lwr/loader/v/0_10_0-alpha_4', ['exports'], function (exports) { 'use
|
|
|
993
1162
|
break;
|
|
994
1163
|
}
|
|
995
1164
|
}
|
|
1165
|
+
|
|
996
1166
|
if (aliasedId !== id) {
|
|
997
1167
|
// resolved module id is the aliased module if it has already been defined
|
|
998
1168
|
if (!resolved && this.namedDefineRegistry.has(aliasedId)) {
|
|
999
1169
|
return aliasedId;
|
|
1000
|
-
}
|
|
1001
|
-
else {
|
|
1170
|
+
} else {
|
|
1002
1171
|
id = aliasedId;
|
|
1003
1172
|
}
|
|
1004
1173
|
}
|
|
1005
1174
|
}
|
|
1175
|
+
|
|
1006
1176
|
if (!resolved) {
|
|
1007
1177
|
const resolvedOrPlain = resolveIfNotPlainOrUrl(id, parentUrl) || id;
|
|
1178
|
+
|
|
1008
1179
|
// if module registry already has named module the resolved id is the plain id
|
|
1009
1180
|
if (this.moduleRegistry.has(resolvedOrPlain)) {
|
|
1010
1181
|
return resolvedOrPlain;
|
|
1011
1182
|
}
|
|
1183
|
+
|
|
1012
1184
|
const resolvedUrl = this.resolver.resolveLocal(resolvedOrPlain);
|
|
1013
1185
|
if (resolvedUrl) {
|
|
1014
1186
|
// return the plain id if it is already defined && the resolvedUrl is NOT already in the module registry
|
|
1015
|
-
if (
|
|
1016
|
-
this.namedDefineRegistry.
|
|
1187
|
+
if (
|
|
1188
|
+
this.namedDefineRegistry.has(resolvedOrPlain) &&
|
|
1189
|
+
this.namedDefineRegistry.get(resolvedOrPlain).defined
|
|
1190
|
+
) {
|
|
1017
1191
|
const record = this.moduleRegistry.get(resolvedUrl);
|
|
1018
1192
|
if (!record || !this.aliases.has(resolvedOrPlain)) {
|
|
1019
1193
|
return resolvedOrPlain;
|
|
@@ -1021,13 +1195,13 @@ LWR.define('lwr/loader/v/0_10_0-alpha_4', ['exports'], function (exports) { 'use
|
|
|
1021
1195
|
}
|
|
1022
1196
|
return resolvedUrl;
|
|
1023
1197
|
}
|
|
1198
|
+
|
|
1024
1199
|
if (this.namedDefineRegistry.has(resolvedOrPlain)) {
|
|
1025
1200
|
return resolvedOrPlain;
|
|
1026
1201
|
}
|
|
1027
1202
|
try {
|
|
1028
1203
|
resolved = await this.resolver.resolve(resolvedOrPlain);
|
|
1029
|
-
}
|
|
1030
|
-
catch (e) {
|
|
1204
|
+
} catch (e) {
|
|
1031
1205
|
// defer to error handling below for unresolved
|
|
1032
1206
|
}
|
|
1033
1207
|
}
|
|
@@ -1035,6 +1209,7 @@ LWR.define('lwr/loader/v/0_10_0-alpha_4', ['exports'], function (exports) { 'use
|
|
|
1035
1209
|
if (this.namedDefineRegistry.has(id)) {
|
|
1036
1210
|
return id;
|
|
1037
1211
|
}
|
|
1212
|
+
|
|
1038
1213
|
throw new LoaderError(UNRESOLVED, [id]);
|
|
1039
1214
|
}
|
|
1040
1215
|
if (importer && isUrl(resolved)) {
|
|
@@ -1042,9 +1217,11 @@ LWR.define('lwr/loader/v/0_10_0-alpha_4', ['exports'], function (exports) { 'use
|
|
|
1042
1217
|
}
|
|
1043
1218
|
return resolved;
|
|
1044
1219
|
}
|
|
1220
|
+
|
|
1045
1221
|
has(id) {
|
|
1046
1222
|
return this.moduleRegistry.has(id);
|
|
1047
1223
|
}
|
|
1224
|
+
|
|
1048
1225
|
define(name, dependencies, exporter) {
|
|
1049
1226
|
const mod = this.namedDefineRegistry.get(name);
|
|
1050
1227
|
// Don't allow redefining a module.
|
|
@@ -1056,6 +1233,7 @@ LWR.define('lwr/loader/v/0_10_0-alpha_4', ['exports'], function (exports) { 'use
|
|
|
1056
1233
|
this.lastDefine = mod;
|
|
1057
1234
|
return;
|
|
1058
1235
|
}
|
|
1236
|
+
|
|
1059
1237
|
const moduleDef = {
|
|
1060
1238
|
name,
|
|
1061
1239
|
dependencies,
|
|
@@ -1066,10 +1244,12 @@ LWR.define('lwr/loader/v/0_10_0-alpha_4', ['exports'], function (exports) { 'use
|
|
|
1066
1244
|
// if module is "external", resolve the external promise to notify any dependees
|
|
1067
1245
|
mod.external.resolveExternal(moduleDef);
|
|
1068
1246
|
}
|
|
1247
|
+
|
|
1069
1248
|
this.profiler.logOperationStart({ id: MODULE_DEFINE, specifier: name });
|
|
1070
1249
|
this.namedDefineRegistry.set(name, moduleDef);
|
|
1071
1250
|
this.lastDefine = moduleDef;
|
|
1072
1251
|
}
|
|
1252
|
+
|
|
1073
1253
|
/**
|
|
1074
1254
|
* Marks modules as "externally" loaded/provided, so that the loader does not attempt to fetch them.
|
|
1075
1255
|
*
|
|
@@ -1082,6 +1262,7 @@ LWR.define('lwr/loader/v/0_10_0-alpha_4', ['exports'], function (exports) { 'use
|
|
|
1082
1262
|
let timer;
|
|
1083
1263
|
const moduleDefPromise = new Promise((resolve, reject) => {
|
|
1084
1264
|
resolveExternal = resolve;
|
|
1265
|
+
|
|
1085
1266
|
// watch the external for timeout
|
|
1086
1267
|
// eslint-disable-next-line lwr/no-unguarded-apis, no-undef
|
|
1087
1268
|
timer = setTimeout(() => {
|
|
@@ -1099,24 +1280,39 @@ LWR.define('lwr/loader/v/0_10_0-alpha_4', ['exports'], function (exports) { 'use
|
|
|
1099
1280
|
moduleDefPromise,
|
|
1100
1281
|
},
|
|
1101
1282
|
};
|
|
1102
|
-
this.namedDefineRegistry.set(id, moduleDef);
|
|
1103
|
-
}
|
|
1104
|
-
else if (process.env.NODE_ENV !== 'production' && hasConsole) {
|
|
1283
|
+
this.namedDefineRegistry.set(id, moduleDef );
|
|
1284
|
+
} else if (process.env.NODE_ENV !== 'production' && hasConsole) {
|
|
1105
1285
|
// eslint-disable-next-line lwr/no-unguarded-apis
|
|
1106
1286
|
console.warn(MODULE_ALREADY_LOADED.message, id);
|
|
1107
1287
|
}
|
|
1108
1288
|
});
|
|
1109
1289
|
}
|
|
1290
|
+
|
|
1291
|
+
|
|
1292
|
+
|
|
1293
|
+
// A registry for named AMD defines containing the *metadata* of AMD module
|
|
1294
|
+
__init() {this.namedDefineRegistry = new Map();}
|
|
1295
|
+
|
|
1296
|
+
// The evaluated module registry where the module identifier (name or URL?) is the key
|
|
1297
|
+
__init2() {this.moduleRegistry = new Map();}
|
|
1298
|
+
|
|
1299
|
+
// Aliases of modules in the registry
|
|
1300
|
+
__init3() {this.aliases = new Map();}
|
|
1301
|
+
|
|
1302
|
+
|
|
1303
|
+
|
|
1110
1304
|
getImportMetadataResolver() {
|
|
1111
1305
|
return this.resolver;
|
|
1112
1306
|
}
|
|
1307
|
+
|
|
1113
1308
|
// Returns an existing module record by the resolvedId or aliased id
|
|
1114
|
-
|
|
1309
|
+
getExistingModuleRecord(resolvedId, aliasId) {
|
|
1115
1310
|
const moduleRecord = this.moduleRegistry.get(resolvedId);
|
|
1116
1311
|
if (moduleRecord) {
|
|
1117
1312
|
this.storeModuleAlias(aliasId, resolvedId);
|
|
1118
1313
|
return moduleRecord;
|
|
1119
1314
|
}
|
|
1315
|
+
|
|
1120
1316
|
// Check if this is a known alias
|
|
1121
1317
|
if (resolvedId !== aliasId) {
|
|
1122
1318
|
const alias = this.aliases.get(aliasId);
|
|
@@ -1129,13 +1325,15 @@ LWR.define('lwr/loader/v/0_10_0-alpha_4', ['exports'], function (exports) { 'use
|
|
|
1129
1325
|
}
|
|
1130
1326
|
return moduleRecord;
|
|
1131
1327
|
}
|
|
1132
|
-
|
|
1328
|
+
|
|
1329
|
+
getModuleRecord(resolvedId, id) {
|
|
1133
1330
|
// Look for an existing record
|
|
1134
1331
|
const existingRecord = this.getExistingModuleRecord(resolvedId, id);
|
|
1135
1332
|
if (existingRecord) {
|
|
1136
1333
|
// return existing
|
|
1137
1334
|
return existingRecord;
|
|
1138
1335
|
}
|
|
1336
|
+
|
|
1139
1337
|
// Create a new Module Record
|
|
1140
1338
|
const instantiation = this.getModuleDef(resolvedId, id);
|
|
1141
1339
|
const dependencyRecords = instantiation.then((moduleDef) => {
|
|
@@ -1143,15 +1341,17 @@ LWR.define('lwr/loader/v/0_10_0-alpha_4', ['exports'], function (exports) { 'use
|
|
|
1143
1341
|
// get dep and filter out exports
|
|
1144
1342
|
const filtered = dependencies
|
|
1145
1343
|
.map((dep) => {
|
|
1146
|
-
|
|
1147
|
-
|
|
1148
|
-
|
|
1149
|
-
|
|
1150
|
-
|
|
1151
|
-
|
|
1152
|
-
.filter((depRecord) => depRecord !== undefined);
|
|
1344
|
+
if (dep === 'exports') {
|
|
1345
|
+
return;
|
|
1346
|
+
}
|
|
1347
|
+
invariant(dep !== 'require', NO_AMD_REQUIRE);
|
|
1348
|
+
return this.getModuleDependencyRecord.call(this, dep);
|
|
1349
|
+
})
|
|
1350
|
+
.filter((depRecord) => depRecord !== undefined) ;
|
|
1351
|
+
|
|
1153
1352
|
return Promise.all(filtered);
|
|
1154
1353
|
});
|
|
1354
|
+
|
|
1155
1355
|
const newModuleRecord = {
|
|
1156
1356
|
id: resolvedId,
|
|
1157
1357
|
module: Object.create(null),
|
|
@@ -1160,16 +1360,17 @@ LWR.define('lwr/loader/v/0_10_0-alpha_4', ['exports'], function (exports) { 'use
|
|
|
1160
1360
|
evaluated: false,
|
|
1161
1361
|
evaluationPromise: null,
|
|
1162
1362
|
};
|
|
1363
|
+
|
|
1163
1364
|
this.moduleRegistry.set(resolvedId, newModuleRecord);
|
|
1164
1365
|
this.storeModuleAlias(id, resolvedId);
|
|
1165
1366
|
return newModuleRecord;
|
|
1166
1367
|
}
|
|
1167
|
-
|
|
1368
|
+
|
|
1369
|
+
storeModuleAlias(aliasId, resolvedId) {
|
|
1168
1370
|
if (aliasId !== resolvedId) {
|
|
1169
1371
|
if (!this.aliases.has(aliasId)) {
|
|
1170
1372
|
this.aliases.set(aliasId, resolvedId);
|
|
1171
|
-
}
|
|
1172
|
-
else if (process.env.NODE_ENV !== 'production' && hasConsole) {
|
|
1373
|
+
} else if (process.env.NODE_ENV !== 'production' && hasConsole) {
|
|
1173
1374
|
// Warn the user if they were not aliasing to the resolvedId
|
|
1174
1375
|
const currentResolvedId = this.aliases.get(aliasId);
|
|
1175
1376
|
if (currentResolvedId !== resolvedId) {
|
|
@@ -1179,17 +1380,23 @@ LWR.define('lwr/loader/v/0_10_0-alpha_4', ['exports'], function (exports) { 'use
|
|
|
1179
1380
|
}
|
|
1180
1381
|
}
|
|
1181
1382
|
}
|
|
1182
|
-
|
|
1383
|
+
|
|
1384
|
+
async getModuleDependencyRecord(dependency) {
|
|
1183
1385
|
const resolvedDepId = await this.resolve(dependency);
|
|
1184
1386
|
return this.getModuleRecord(resolvedDepId, dependency);
|
|
1185
1387
|
}
|
|
1388
|
+
|
|
1186
1389
|
// execute the "top-level code" (the code outside of functions) of a module
|
|
1187
|
-
|
|
1390
|
+
async topLevelEvaluation(moduleRecord) {
|
|
1188
1391
|
await this.instantiateAll(moduleRecord, {});
|
|
1189
1392
|
return this.evaluateModule(moduleRecord, {});
|
|
1190
1393
|
}
|
|
1394
|
+
|
|
1191
1395
|
// Returns a promise when a module and all of it's dependencies have finished instantiation
|
|
1192
|
-
|
|
1396
|
+
async instantiateAll(
|
|
1397
|
+
moduleRecord,
|
|
1398
|
+
instantiatedMap,
|
|
1399
|
+
) {
|
|
1193
1400
|
if (!instantiatedMap[moduleRecord.id]) {
|
|
1194
1401
|
instantiatedMap[moduleRecord.id] = true;
|
|
1195
1402
|
const dependencyModuleRecords = await moduleRecord.dependencyRecords;
|
|
@@ -1202,46 +1409,61 @@ LWR.define('lwr/loader/v/0_10_0-alpha_4', ['exports'], function (exports) { 'use
|
|
|
1202
1409
|
}
|
|
1203
1410
|
}
|
|
1204
1411
|
}
|
|
1205
|
-
|
|
1412
|
+
|
|
1413
|
+
async evaluateModule(
|
|
1414
|
+
moduleRecord,
|
|
1415
|
+
evaluationMap,
|
|
1416
|
+
) {
|
|
1206
1417
|
const dependencyModuleRecords = await moduleRecord.dependencyRecords;
|
|
1207
1418
|
if (dependencyModuleRecords.length > 0) {
|
|
1208
1419
|
evaluationMap[moduleRecord.id] = true;
|
|
1209
1420
|
// evaluate dependencies first
|
|
1210
1421
|
await this.evaluateModuleDependencies(dependencyModuleRecords, evaluationMap);
|
|
1211
1422
|
}
|
|
1423
|
+
|
|
1212
1424
|
const { exporter, dependencies } = await moduleRecord.instantiation;
|
|
1213
1425
|
// The exports object automatically gets filled in by the exporter evaluation
|
|
1214
1426
|
const exports = {};
|
|
1215
|
-
const depsMapped = await Promise.all(
|
|
1216
|
-
|
|
1217
|
-
|
|
1218
|
-
|
|
1219
|
-
|
|
1220
|
-
|
|
1221
|
-
|
|
1427
|
+
const depsMapped = await Promise.all(
|
|
1428
|
+
dependencies.map(async (dep) => {
|
|
1429
|
+
if (dep === 'exports') {
|
|
1430
|
+
return exports;
|
|
1431
|
+
}
|
|
1432
|
+
const resolvedDepId = await this.resolve(dep);
|
|
1433
|
+
|
|
1434
|
+
const moduleRecord = this.moduleRegistry.get(resolvedDepId) ;
|
|
1435
|
+
if (!moduleRecord) {
|
|
1436
|
+
throw new LoaderError(FAILED_DEP, [resolvedDepId]);
|
|
1437
|
+
}
|
|
1438
|
+
|
|
1439
|
+
const module = moduleRecord.module;
|
|
1440
|
+
|
|
1441
|
+
/**
|
|
1442
|
+
* Circular dependencies are handled properly when named exports are used,
|
|
1443
|
+
* however, for default exports there is a bug: https://github.com/rollup/rollup/issues/3384
|
|
1444
|
+
*
|
|
1445
|
+
* The workaround below applies for circular dependencies (!moduleRecord.evaluated)
|
|
1446
|
+
*/
|
|
1447
|
+
if (!moduleRecord.evaluated) {
|
|
1448
|
+
return this.getCircularDependencyWrapper(module);
|
|
1449
|
+
}
|
|
1450
|
+
|
|
1451
|
+
if (module) {
|
|
1452
|
+
return module.__defaultInterop ? module.default : module;
|
|
1453
|
+
}
|
|
1454
|
+
|
|
1222
1455
|
throw new LoaderError(FAILED_DEP, [resolvedDepId]);
|
|
1223
|
-
}
|
|
1224
|
-
|
|
1225
|
-
|
|
1226
|
-
* Circular dependencies are handled properly when named exports are used,
|
|
1227
|
-
* however, for default exports there is a bug: https://github.com/rollup/rollup/issues/3384
|
|
1228
|
-
*
|
|
1229
|
-
* The workaround below applies for circular dependencies (!moduleRecord.evaluated)
|
|
1230
|
-
*/
|
|
1231
|
-
if (!moduleRecord.evaluated) {
|
|
1232
|
-
return this.getCircularDependencyWrapper(module);
|
|
1233
|
-
}
|
|
1234
|
-
if (module) {
|
|
1235
|
-
return module.__defaultInterop ? module.default : module;
|
|
1236
|
-
}
|
|
1237
|
-
throw new LoaderError(FAILED_DEP, [resolvedDepId]);
|
|
1238
|
-
}));
|
|
1456
|
+
}),
|
|
1457
|
+
);
|
|
1458
|
+
|
|
1239
1459
|
// W-10029836 - In the case where we could be instantiating multiple graphs at the same time lets make sure the module have not already been evaluated
|
|
1240
1460
|
if (moduleRecord.evaluated) {
|
|
1241
1461
|
return moduleRecord.module;
|
|
1242
1462
|
}
|
|
1463
|
+
|
|
1243
1464
|
// evaluates the module function
|
|
1244
1465
|
let moduleDefault = exporter(...depsMapped);
|
|
1466
|
+
|
|
1245
1467
|
// value is returned from exporter, then we are not using named exports
|
|
1246
1468
|
if (moduleDefault !== undefined) {
|
|
1247
1469
|
moduleDefault = { default: moduleDefault };
|
|
@@ -1257,7 +1479,9 @@ LWR.define('lwr/loader/v/0_10_0-alpha_4', ['exports'], function (exports) { 'use
|
|
|
1257
1479
|
Object.defineProperty(exports, '__useDefault', { value: true });
|
|
1258
1480
|
}
|
|
1259
1481
|
}
|
|
1482
|
+
|
|
1260
1483
|
const moduleExports = moduleDefault || exports;
|
|
1484
|
+
|
|
1261
1485
|
// update the module record
|
|
1262
1486
|
// copy over enumerable public methods to module
|
|
1263
1487
|
for (const key in moduleExports) {
|
|
@@ -1271,6 +1495,7 @@ LWR.define('lwr/loader/v/0_10_0-alpha_4', ['exports'], function (exports) { 'use
|
|
|
1271
1495
|
},
|
|
1272
1496
|
});
|
|
1273
1497
|
}
|
|
1498
|
+
|
|
1274
1499
|
// copy non-enumerable to module
|
|
1275
1500
|
if (moduleExports.__useDefault) {
|
|
1276
1501
|
Object.defineProperty(moduleRecord.module, '__useDefault', { value: true });
|
|
@@ -1281,27 +1506,36 @@ LWR.define('lwr/loader/v/0_10_0-alpha_4', ['exports'], function (exports) { 'use
|
|
|
1281
1506
|
if (moduleExports.__esModule) {
|
|
1282
1507
|
Object.defineProperty(moduleRecord.module, '__esModule', { value: true });
|
|
1283
1508
|
}
|
|
1509
|
+
|
|
1284
1510
|
moduleRecord.evaluated = true;
|
|
1285
1511
|
Object.freeze(moduleRecord.module);
|
|
1286
1512
|
return moduleRecord.module;
|
|
1287
1513
|
}
|
|
1514
|
+
|
|
1288
1515
|
// Determines if named exports module has only default export
|
|
1289
|
-
|
|
1290
|
-
return (
|
|
1516
|
+
isNamedExportDefaultOnly(exports) {
|
|
1517
|
+
return (
|
|
1518
|
+
exports !== undefined &&
|
|
1291
1519
|
Object.getOwnPropertyNames(exports).length === 2 &&
|
|
1292
1520
|
Object.prototype.hasOwnProperty.call(exports, 'default') &&
|
|
1293
|
-
Object.prototype.hasOwnProperty.call(exports, '__esModule')
|
|
1521
|
+
Object.prototype.hasOwnProperty.call(exports, '__esModule')
|
|
1522
|
+
);
|
|
1294
1523
|
}
|
|
1524
|
+
|
|
1295
1525
|
// Wrap the dependency in a function that can be called and detected by __circular__ property.
|
|
1296
1526
|
// The LWC engine checks for __circular__ to detect circular dependencies.
|
|
1297
|
-
|
|
1527
|
+
getCircularDependencyWrapper(module) {
|
|
1298
1528
|
const tmp = () => {
|
|
1299
1529
|
return module.__useDefault || module.__defaultInterop ? module.default : module;
|
|
1300
1530
|
};
|
|
1301
1531
|
tmp.__circular__ = true;
|
|
1302
1532
|
return tmp;
|
|
1303
1533
|
}
|
|
1304
|
-
|
|
1534
|
+
|
|
1535
|
+
async evaluateModuleDependencies(
|
|
1536
|
+
dependencyModuleRecords,
|
|
1537
|
+
evaluationMap,
|
|
1538
|
+
) {
|
|
1305
1539
|
for (let i = 0; i < dependencyModuleRecords.length; i++) {
|
|
1306
1540
|
const depRecord = dependencyModuleRecords[i];
|
|
1307
1541
|
if (!depRecord.evaluated && !evaluationMap[depRecord.id]) {
|
|
@@ -1311,15 +1545,17 @@ LWR.define('lwr/loader/v/0_10_0-alpha_4', ['exports'], function (exports) { 'use
|
|
|
1311
1545
|
}
|
|
1312
1546
|
}
|
|
1313
1547
|
}
|
|
1314
|
-
|
|
1548
|
+
|
|
1549
|
+
async getModuleDef(resolvedId, originalId) {
|
|
1315
1550
|
// reset lastDefine
|
|
1316
1551
|
this.lastDefine = undefined;
|
|
1552
|
+
|
|
1317
1553
|
// the module name can be the resolved ID or the original ID if neither are URL's.
|
|
1318
1554
|
const moduleName = !isUrl(resolvedId)
|
|
1319
1555
|
? resolvedId
|
|
1320
1556
|
: originalId !== resolvedId
|
|
1321
|
-
|
|
1322
|
-
|
|
1557
|
+
? originalId
|
|
1558
|
+
: undefined;
|
|
1323
1559
|
let moduleDef = moduleName && this.namedDefineRegistry.get(moduleName);
|
|
1324
1560
|
if (moduleDef && moduleDef.external) {
|
|
1325
1561
|
return moduleDef.external.moduleDefPromise;
|
|
@@ -1332,67 +1568,75 @@ LWR.define('lwr/loader/v/0_10_0-alpha_4', ['exports'], function (exports) { 'use
|
|
|
1332
1568
|
this.profiler.logOperationStart({ id: MODULE_FETCH, specifier });
|
|
1333
1569
|
return Promise.resolve()
|
|
1334
1570
|
.then(async () => {
|
|
1335
|
-
|
|
1336
|
-
|
|
1337
|
-
|
|
1338
|
-
|
|
1339
|
-
|
|
1340
|
-
|
|
1341
|
-
|
|
1342
|
-
|
|
1343
|
-
|
|
1344
|
-
|
|
1345
|
-
|
|
1346
|
-
|
|
1347
|
-
|
|
1348
|
-
|
|
1571
|
+
const loadHooks = this.loadHook;
|
|
1572
|
+
if (loadHooks) {
|
|
1573
|
+
for (let i = 0; i < loadHooks.length; i++) {
|
|
1574
|
+
const loadHook = loadHooks[i];
|
|
1575
|
+
const response = loadHook(resolvedId, parentUrl);
|
|
1576
|
+
const result = (
|
|
1577
|
+
isResponseAPromise(response)
|
|
1578
|
+
? // eslint-disable-next-line no-await-in-loop
|
|
1579
|
+
await evaluateLoadHook(resolvedId, response)
|
|
1580
|
+
: response
|
|
1581
|
+
) ;
|
|
1582
|
+
if (result === undefined) {
|
|
1583
|
+
throw new LoaderError(INVALID_LOADER_SERVICE_RESPONSE);
|
|
1584
|
+
}
|
|
1585
|
+
if (result && result !== null) {
|
|
1586
|
+
return evaluateLoadHookResponse(result, resolvedId);
|
|
1587
|
+
}
|
|
1349
1588
|
}
|
|
1350
1589
|
}
|
|
1351
|
-
|
|
1352
|
-
|
|
1353
|
-
})
|
|
1590
|
+
return false;
|
|
1591
|
+
})
|
|
1354
1592
|
.then((result) => {
|
|
1355
|
-
|
|
1356
|
-
|
|
1357
|
-
|
|
1358
|
-
|
|
1593
|
+
if (result !== true && hasDocument) {
|
|
1594
|
+
return loadModuleDef(resolvedId);
|
|
1595
|
+
}
|
|
1596
|
+
})
|
|
1359
1597
|
.then(() => {
|
|
1360
|
-
|
|
1361
|
-
|
|
1362
|
-
|
|
1363
|
-
|
|
1364
|
-
moduleDef
|
|
1365
|
-
|
|
1366
|
-
|
|
1367
|
-
|
|
1368
|
-
|
|
1369
|
-
|
|
1370
|
-
|
|
1371
|
-
|
|
1372
|
-
|
|
1598
|
+
// Attempt to retrieve the module definition by name first
|
|
1599
|
+
moduleDef = moduleName && this.namedDefineRegistry.get(moduleName);
|
|
1600
|
+
|
|
1601
|
+
// Fallback to the last loader.define call
|
|
1602
|
+
if (!moduleDef) {
|
|
1603
|
+
moduleDef = this.lastDefine;
|
|
1604
|
+
}
|
|
1605
|
+
|
|
1606
|
+
// This should not happen
|
|
1607
|
+
if (!moduleDef) {
|
|
1608
|
+
throw new LoaderError(FAIL_INSTANTIATE, [resolvedId]);
|
|
1609
|
+
}
|
|
1610
|
+
|
|
1611
|
+
this.profiler.logOperationEnd({ id: MODULE_FETCH, specifier });
|
|
1612
|
+
return moduleDef;
|
|
1613
|
+
})
|
|
1373
1614
|
.catch((e) => {
|
|
1374
|
-
|
|
1375
|
-
|
|
1376
|
-
|
|
1615
|
+
this.profiler.logOperationStart({ id: MODULE_ERROR, specifier });
|
|
1616
|
+
throw e;
|
|
1617
|
+
});
|
|
1377
1618
|
}
|
|
1619
|
+
|
|
1620
|
+
|
|
1621
|
+
|
|
1622
|
+
|
|
1378
1623
|
addLoaderPlugin(hooks) {
|
|
1379
1624
|
if (typeof hooks !== 'object') {
|
|
1380
1625
|
throw new LoaderError(INVALID_HOOK);
|
|
1381
1626
|
}
|
|
1382
1627
|
const { loadModule: loadHook, resolveModule: resolveHook, loadMapping } = hooks;
|
|
1628
|
+
|
|
1383
1629
|
if (resolveHook) {
|
|
1384
1630
|
if (this.resolveHook) {
|
|
1385
1631
|
this.resolveHook.push(resolveHook);
|
|
1386
|
-
}
|
|
1387
|
-
else {
|
|
1632
|
+
} else {
|
|
1388
1633
|
this.resolveHook = [resolveHook];
|
|
1389
1634
|
}
|
|
1390
1635
|
}
|
|
1391
1636
|
if (loadHook) {
|
|
1392
1637
|
if (this.loadHook) {
|
|
1393
1638
|
this.loadHook.push(loadHook);
|
|
1394
|
-
}
|
|
1395
|
-
else {
|
|
1639
|
+
} else {
|
|
1396
1640
|
this.loadHook = [loadHook];
|
|
1397
1641
|
}
|
|
1398
1642
|
}
|
|
@@ -1400,7 +1644,8 @@ LWR.define('lwr/loader/v/0_10_0-alpha_4', ['exports'], function (exports) { 'use
|
|
|
1400
1644
|
this.resolver.addLoadMappingHook(loadMapping);
|
|
1401
1645
|
}
|
|
1402
1646
|
}
|
|
1403
|
-
|
|
1647
|
+
|
|
1648
|
+
importMetadataInvalidationCallback({ name, oldUrl, newUrl }) {
|
|
1404
1649
|
const handleStaleModuleHooks = this.handleStaleModuleHook;
|
|
1405
1650
|
if (handleStaleModuleHooks) {
|
|
1406
1651
|
evaluateHandleStaleModuleHooks(handleStaleModuleHooks, {
|
|
@@ -1408,19 +1653,19 @@ LWR.define('lwr/loader/v/0_10_0-alpha_4', ['exports'], function (exports) { 'use
|
|
|
1408
1653
|
oldUrl,
|
|
1409
1654
|
newUrl,
|
|
1410
1655
|
});
|
|
1411
|
-
}
|
|
1412
|
-
else {
|
|
1656
|
+
} else {
|
|
1413
1657
|
if (process.env.NODE_ENV !== 'production' && hasConsole) {
|
|
1414
1658
|
// eslint-disable-next-line lwr/no-unguarded-apis, no-undef
|
|
1415
1659
|
console.warn(`stale module detected ${name}, current URL:${oldUrl}, new URL:${newUrl}`);
|
|
1416
1660
|
}
|
|
1417
1661
|
}
|
|
1418
1662
|
}
|
|
1663
|
+
|
|
1664
|
+
|
|
1419
1665
|
registerHandleStaleModuleHook(handleStaleModule) {
|
|
1420
1666
|
if (this.handleStaleModuleHook) {
|
|
1421
1667
|
this.handleStaleModuleHook.push(handleStaleModule);
|
|
1422
|
-
}
|
|
1423
|
-
else {
|
|
1668
|
+
} else {
|
|
1424
1669
|
this.handleStaleModuleHook = [handleStaleModule];
|
|
1425
1670
|
}
|
|
1426
1671
|
}
|
|
@@ -1430,15 +1675,21 @@ LWR.define('lwr/loader/v/0_10_0-alpha_4', ['exports'], function (exports) { 'use
|
|
|
1430
1675
|
* The LWR loader is inspired and borrows from the algorithms and native browser principles of https://github.com/systemjs/systemjs
|
|
1431
1676
|
*/
|
|
1432
1677
|
class Loader {
|
|
1678
|
+
|
|
1679
|
+
|
|
1680
|
+
|
|
1433
1681
|
constructor(config) {
|
|
1434
1682
|
let baseUrl = config.baseUrl;
|
|
1435
1683
|
const mappingEndpoint = config.endpoints ? config.endpoints.uris.mapping : undefined;
|
|
1436
1684
|
let profiler = config.profiler;
|
|
1685
|
+
|
|
1437
1686
|
if (!mappingEndpoint) {
|
|
1438
1687
|
throw new LoaderError(NO_MAPPING_URL);
|
|
1439
1688
|
}
|
|
1689
|
+
|
|
1440
1690
|
// add a trailing slash, if it does not exist
|
|
1441
1691
|
config.endpoints.uris.mapping = mappingEndpoint.replace(/\/?$/, '/');
|
|
1692
|
+
|
|
1442
1693
|
if (baseUrl) {
|
|
1443
1694
|
// add a trailing slash, if it does not exist
|
|
1444
1695
|
baseUrl = baseUrl.replace(/\/?$/, '/');
|
|
@@ -1449,6 +1700,7 @@ LWR.define('lwr/loader/v/0_10_0-alpha_4', ['exports'], function (exports) { 'use
|
|
|
1449
1700
|
if (!baseUrl) {
|
|
1450
1701
|
throw new LoaderError(NO_BASE_URL);
|
|
1451
1702
|
}
|
|
1703
|
+
|
|
1452
1704
|
if (!profiler) {
|
|
1453
1705
|
// default noop profiler
|
|
1454
1706
|
profiler = {
|
|
@@ -1460,7 +1712,9 @@ LWR.define('lwr/loader/v/0_10_0-alpha_4', ['exports'], function (exports) { 'use
|
|
|
1460
1712
|
},
|
|
1461
1713
|
};
|
|
1462
1714
|
}
|
|
1715
|
+
|
|
1463
1716
|
this.registry = new ModuleRegistry(Object.freeze({ endpoints: config.endpoints, baseUrl, profiler }));
|
|
1717
|
+
|
|
1464
1718
|
// TODO: W-10539691 - temp workaround for LWR-Java -- remove once appId is implemented there
|
|
1465
1719
|
if (config.appMetadata && !config.appMetadata.appId) {
|
|
1466
1720
|
// Parse the appId from the bootstrapModule
|
|
@@ -1469,6 +1723,7 @@ LWR.define('lwr/loader/v/0_10_0-alpha_4', ['exports'], function (exports) { 'use
|
|
|
1469
1723
|
const appId = match && match[1];
|
|
1470
1724
|
config.appMetadata.appId = appId;
|
|
1471
1725
|
}
|
|
1726
|
+
|
|
1472
1727
|
// TODO: https://github.com/salesforce-experience-platform-emu/lwr/issues/1087
|
|
1473
1728
|
this.services = Object.freeze({
|
|
1474
1729
|
addLoaderPlugin: this.registry.addLoaderPlugin.bind(this.registry),
|
|
@@ -1476,6 +1731,7 @@ LWR.define('lwr/loader/v/0_10_0-alpha_4', ['exports'], function (exports) { 'use
|
|
|
1476
1731
|
appMetadata: config.appMetadata,
|
|
1477
1732
|
});
|
|
1478
1733
|
}
|
|
1734
|
+
|
|
1479
1735
|
/**
|
|
1480
1736
|
* Defines/registers a single named AMD module definition.
|
|
1481
1737
|
*
|
|
@@ -1488,14 +1744,18 @@ LWR.define('lwr/loader/v/0_10_0-alpha_4', ['exports'], function (exports) { 'use
|
|
|
1488
1744
|
invariant(typeof name === 'string', MISSING_NAME);
|
|
1489
1745
|
let ctor = execute;
|
|
1490
1746
|
let deps = dependencies;
|
|
1747
|
+
|
|
1491
1748
|
// Convert no dependencies form `define('name', function(){}, {});` to: `define('name', [], function(){}, {})`
|
|
1492
1749
|
if (typeof deps === 'function') {
|
|
1493
1750
|
ctor = dependencies;
|
|
1494
1751
|
deps = [];
|
|
1495
1752
|
}
|
|
1753
|
+
|
|
1496
1754
|
invariant(Array.isArray(deps), INVALID_DEPS);
|
|
1497
|
-
|
|
1755
|
+
|
|
1756
|
+
this.registry.define(name, deps, ctor );
|
|
1498
1757
|
}
|
|
1758
|
+
|
|
1499
1759
|
/**
|
|
1500
1760
|
* Retrieves/loads a module, returning it from the registry if it exists and fetching it if it doesn't.
|
|
1501
1761
|
*
|
|
@@ -1507,6 +1767,7 @@ LWR.define('lwr/loader/v/0_10_0-alpha_4', ['exports'], function (exports) { 'use
|
|
|
1507
1767
|
async load(id, importer) {
|
|
1508
1768
|
return this.registry.load(id, importer);
|
|
1509
1769
|
}
|
|
1770
|
+
|
|
1510
1771
|
/**
|
|
1511
1772
|
* Checks if a Module exists in the registry. Note, returns false even if the ModuleDefinition exists but the Module has not been instantiated yet (executed).
|
|
1512
1773
|
*
|
|
@@ -1516,6 +1777,7 @@ LWR.define('lwr/loader/v/0_10_0-alpha_4', ['exports'], function (exports) { 'use
|
|
|
1516
1777
|
has(id) {
|
|
1517
1778
|
return this.registry.has(id);
|
|
1518
1779
|
}
|
|
1780
|
+
|
|
1519
1781
|
/**
|
|
1520
1782
|
* Resolves the module identifier or URL. Returns the module identifier if the moduleDefinition exists, or the full resolved URL if a URL is given.
|
|
1521
1783
|
*
|
|
@@ -1527,9 +1789,11 @@ LWR.define('lwr/loader/v/0_10_0-alpha_4', ['exports'], function (exports) { 'use
|
|
|
1527
1789
|
async resolve(id, importer) {
|
|
1528
1790
|
return this.registry.resolve(id, importer);
|
|
1529
1791
|
}
|
|
1792
|
+
|
|
1530
1793
|
async registerImportMappings(mappings, rootSpecifiers) {
|
|
1531
1794
|
this.registry.getImportMetadataResolver().registerImportMappings(mappings, rootSpecifiers);
|
|
1532
1795
|
}
|
|
1796
|
+
|
|
1533
1797
|
/**
|
|
1534
1798
|
* Marks modules as "externally" loaded/provided (e.g. preloaded), so that the loader does not attempt to load them.
|
|
1535
1799
|
*
|
|
@@ -1544,4 +1808,4 @@ LWR.define('lwr/loader/v/0_10_0-alpha_4', ['exports'], function (exports) { 'use
|
|
|
1544
1808
|
|
|
1545
1809
|
Object.defineProperty(exports, '__esModule', { value: true });
|
|
1546
1810
|
|
|
1547
|
-
});
|
|
1811
|
+
}));
|