@lwrjs/everywhere 0.12.0-alpha.20 → 0.12.0-alpha.22

Sign up to get free protection for your applications and to get access to all the features.
Files changed (23) hide show
  1. package/build/__generated_site_amd_modules__/1/application/amd/l/en-US/ai/amd-bootstrap/configuration/ci/-/-/s/d57750f23bab0eda6f7134272c0014e3/config.js +7 -0
  2. package/build/__generated_site_amd_modules__/1/module/amd/1/l/en-US/mi/@lwrjs/app-service/amd-bootstrap/module/amd/v/0_12_0-alpha_22/s/8bce578258518655194bd71d1d72aad5/@lwrjs_app-service_amd-bootstrap_module_amd.js +14 -0
  3. package/build/__generated_site_amd_modules__/1/module/amd/1/l/en-US/mi/lwr/everywhereAmd/v/{0_12_0-alpha_20 → 0_12_0-alpha_22}/s/cb931ebef2b89dcf8ab51456e3a68864/lwr_everywhereAmd.js +3 -3
  4. package/build/__generated_site_amd_modules__/1/module/amd/1/l/en-US/mi/lwr/init/v/{0_12_0-alpha_20 → 0_12_0-alpha_22}/s/f30361ad8ff7af505bf4d465c8499181/lwr_init.js +19 -19
  5. package/build/__generated_site_amd_modules__/1/module/amd/1/l/en-US/mi/lwr/metrics/v/{0_12_0-alpha_20 → 0_12_0-alpha_22}/s/274c8343f810353bbad085a79709395f/lwr_metrics.js +1 -1
  6. package/build/__generated_site_amd_modules__/1/module/amd/1/l/en-US/mi/lwr/preInit/v/{0_12_0-alpha_20 → 0_12_0-alpha_22}/s/ec0fad0e38a96bb0b88c9f4553460347/lwr_preInit.js +1 -1
  7. package/build/__generated_site_amd_modules__/1/module/amd/1/l/en-US/mi/lwr/profiler/v/0_12_0-alpha_22/s/a152b8d35f12ca1b5147c5cd1ee155fb/lwr_profiler.js +89 -0
  8. package/build/__generated_site_amd_modules__/1/module/amd/1/l/en-US/mi/lwr/vault/v/{0_12_0-alpha_20 → 0_12_0-alpha_22}/s/c92abd8c1fec2d7eff62e4b097abbe14/lwr_vault.js +1 -1
  9. package/build/__generated_site_amd_modules__/1/resource/amd/lwr-error-shim.js/v/{0_12_0-alpha_20 → 0_12_0-alpha_22}/lwr-error-shim.js +1 -1
  10. package/build/__generated_site_amd_modules__/1/resource/amd/lwr-loader-shim.bundle.js/v/{0_12_0-alpha_20 → 0_12_0-alpha_22}/lwr-loader-shim.bundle.js +6 -6
  11. package/build/assets/amd/lwr-everywhere-debug.js +8 -8
  12. package/build/assets/amd/lwr-everywhere-min.js +2 -2
  13. package/build/assets/amd/lwr-everywhere.js +8 -8
  14. package/build/assets/core/lwr-everywhere-debug.js +4 -4
  15. package/build/assets/core/lwr-everywhere.js +4 -4
  16. package/build/assets/esm/lwr-everywhere-debug.js +1 -1
  17. package/build/assets/esm/lwr-everywhere-min.js +1 -1
  18. package/build/assets/esm/lwr-everywhere.js +1 -1
  19. package/package.json +8 -8
  20. package/build/__generated_site_amd_modules__/1/application/amd/l/en-US/ai/amd-bootstrap/configuration/ci/-/-/s/d2bc824adc68fd6940971a813d7a2982/config.js +0 -12
  21. package/build/__generated_site_amd_modules__/1/module/amd/1/l/en-US/mi/@lwrjs/app-service/amd-bootstrap/module/amd/v/0_12_0-alpha_20/s/8bce578258518655194bd71d1d72aad5/@lwrjs_app-service_amd-bootstrap_module_amd.js +0 -14
  22. package/build/__generated_site_amd_modules__/1/module/amd/1/l/en-US/mi/lwr/loader/v/0_12_0-alpha_20/s/6b6bdc36fe2545be9aa85a6e581dfdd7/lwr_loader.js +0 -1396
  23. package/build/__generated_site_amd_modules__/1/module/amd/1/l/en-US/mi/lwr/profiler/v/0_12_0-alpha_20/s/a152b8d35f12ca1b5147c5cd1ee155fb/lwr_profiler.js +0 -99
@@ -1,1396 +0,0 @@
1
- LWR.define('lwr/loader/v/0_12_0-alpha_20', ['exports'], (function (exports) { 'use strict';
2
-
3
- /**
4
- * Copyright (c) 2021, salesforce.com, inc.
5
- * All rights reserved.
6
- * SPDX-License-Identifier: MIT
7
- * For full license text, see the LICENSE file in the repo root or https://opensource.org/licenses/MIT
8
- */
9
- /* LWR Module Loader v0.12.0-alpha.20 */
10
- const templateRegex = /\{([0-9]+)\}/g;
11
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
12
- function templateString(template, args) {
13
- return template.replace(templateRegex, (_, index) => {
14
- return args[index];
15
- });
16
- }
17
-
18
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
19
- function generateErrorMessage(errorInfo, args) {
20
- const message = Array.isArray(args) ? templateString(errorInfo.message, args) : errorInfo.message;
21
- return `LWR${errorInfo.code}: ${message}`;
22
- }
23
- class LoaderError extends Error {
24
- constructor(errorInfo, errorArgs) {
25
- super();
26
- this.message = generateErrorMessage(errorInfo, errorArgs);
27
- }
28
- /*LWC compiler v6.2.1*/
29
- }
30
- function invariant(condition, errorInfo) {
31
- if (!condition) {
32
- throw new LoaderError(errorInfo);
33
- }
34
- }
35
- const MISSING_NAME = Object.freeze({
36
- code: 3000,
37
- message: 'A module name is required.',
38
- level: 0
39
- });
40
- const FAIL_INSTANTIATE = Object.freeze({
41
- code: 3004,
42
- message: 'Failed to instantiate module: {0}',
43
- level: 0
44
- });
45
- const NO_AMD_REQUIRE = Object.freeze({
46
- code: 3005,
47
- message: 'AMD require not supported.',
48
- level: 0
49
- });
50
- const FAILED_DEP = Object.freeze({
51
- code: 3006,
52
- level: 0,
53
- message: 'Failed to load dependency: {0}'
54
- });
55
- const INVALID_DEPS = Object.freeze({
56
- code: 3007,
57
- message: 'Unexpected value received for dependencies argument; expected an array.',
58
- level: 0
59
- });
60
- const FAIL_LOAD = Object.freeze({
61
- code: 3008,
62
- level: 0,
63
- message: 'Error loading {0}'
64
- });
65
- const UNRESOLVED = Object.freeze({
66
- code: 3009,
67
- level: 0,
68
- message: 'Unable to resolve bare specifier: {0}'
69
- });
70
- const NO_BASE_URL = Object.freeze({
71
- code: 3010,
72
- level: 0,
73
- message: 'baseUrl not set'
74
- });
75
- Object.freeze({
76
- code: 3011,
77
- level: 0,
78
- message: 'Cannot set a loader service multiple times'
79
- });
80
- const INVALID_HOOK = Object.freeze({
81
- code: 3012,
82
- level: 0,
83
- message: 'Invalid hook received'
84
- });
85
- const INVALID_LOADER_SERVICE_RESPONSE = Object.freeze({
86
- code: 3013,
87
- level: 0,
88
- message: 'Invalid response received from hook'
89
- });
90
- const MODULE_LOAD_TIMEOUT = Object.freeze({
91
- code: 3014,
92
- level: 0,
93
- message: 'Error loading {0} - timed out'
94
- });
95
- const HTTP_FAIL_LOAD = Object.freeze({
96
- code: 3015,
97
- level: 0,
98
- message: 'Error loading {0}, status code {1}'
99
- });
100
- const STALE_HOOK_ERROR = Object.freeze({
101
- code: 3016,
102
- level: 0,
103
- message: 'An error occurred handling module conflict'
104
- });
105
- const MODULE_ALREADY_LOADED = Object.freeze({
106
- code: 3017,
107
- level: 0,
108
- message: 'Marking module(s) as externally loaded, but they are already loaded:'
109
- });
110
- const FAIL_HOOK_LOAD = Object.freeze({
111
- code: 3018,
112
- level: 0,
113
- message: 'Error loading "{0}" from hook'
114
- });
115
- const NO_MAPPING_URL = Object.freeze({
116
- code: 3019,
117
- level: 0,
118
- message: 'Mapping endpoint not set'
119
- });
120
- const BAD_IMPORT_METADATA = Object.freeze({
121
- code: 3020,
122
- level: 0,
123
- message: 'Invalid import metadata: {0} {1}'
124
- });
125
- const EXPORTER_ERROR = Object.freeze({
126
- code: 3021,
127
- level: 0,
128
- message: 'Error evaluating module "{0}", error was "{1}"'
129
- });
130
-
131
- /* importMap errors */
132
- Object.freeze({
133
- code: 3011,
134
- level: 0,
135
- message: 'import map is not valid'
136
- });
137
-
138
- /* eslint-disable lwr/no-unguarded-apis */
139
- const hasDocument = typeof document !== 'undefined';
140
- const hasSetTimeout = typeof setTimeout === 'function';
141
- const hasConsole = typeof console !== 'undefined';
142
- /* eslint-enable lwr/no-unguarded-apis */
143
-
144
- function getBaseUrl() {
145
- let baseUrl = undefined;
146
- if (hasDocument) {
147
- // eslint-disable-next-line lwr/no-unguarded-apis, no-undef
148
- const baseEl = document.querySelector('base[href]');
149
- baseUrl = baseEl && baseEl.href;
150
- }
151
- // eslint-disable-next-line lwr/no-unguarded-apis
152
- if (!baseUrl && typeof location !== 'undefined') {
153
- // eslint-disable-next-line lwr/no-unguarded-apis, no-undef
154
- baseUrl = location.href.split('#')[0].split('?')[0];
155
- const lastSepIndex = baseUrl.lastIndexOf('/');
156
- if (lastSepIndex !== -1) {
157
- baseUrl = baseUrl.slice(0, lastSepIndex + 1);
158
- }
159
- }
160
- return baseUrl;
161
- }
162
-
163
- /**
164
- * Check if a string is a URL based on Common Internet Scheme Syntax
165
- * https://www.ietf.org/rfc/rfc1738.txt
166
- *
167
- * URL Format:
168
- * <scheme>:<scheme-specific-part>
169
- * Common Internet Scheme Syntax:
170
- * The scheme specific part starts with a double slash('//')
171
- *
172
- * A valid URL has a colon that is followed by a double slash.
173
- *
174
- * @param url - the url that is being checked
175
- * @returns boolean
176
- *
177
- * @example Valid URLs
178
- * 'https://salesforce.com'
179
- * 'http://localhost:3000'
180
- *
181
- * @example Invalid URLs
182
- * 'salesforce.com'
183
- * 'localhost:3000'
184
- * '@salesforce/label/type:namespace:name'
185
- */
186
- function isUrl(url) {
187
- return url.indexOf('://') !== -1;
188
- }
189
-
190
- // Borrowed and adapted from https://github.com/systemjs/systemjs/blob/master/src/common.js
191
- // Resolves the first path segment relative to the second/parent URL
192
- // eg: resolveIfNotPlainOrUrl('../test', 'http://www.site.com/one/two') => 'http://www.site.com/test'
193
- // eg: resolveIfNotPlainOrUrl('./x/y/z', 'https://my.com/segment')).toBe('https://my.com/x/y/z')
194
- function resolveIfNotPlainOrUrl(relUrl, parentUrl) {
195
- const backslashRegEx = /\\/g;
196
- if (relUrl.indexOf('\\') !== -1) relUrl = relUrl.replace(backslashRegEx, '/');
197
- // protocol-relative
198
- if (relUrl[0] === '/' && relUrl[1] === '/') {
199
- return parentUrl.slice(0, parentUrl.indexOf(':') + 1) + relUrl;
200
- }
201
- // relative-url
202
- else if (relUrl[0] === '.' && (relUrl[1] === '/' || relUrl[1] === '.' && (relUrl[2] === '/' || relUrl.length === 2 && (relUrl += '/')) || relUrl.length === 1 && (relUrl += '/')) || relUrl[0] === '/') {
203
- const parentProtocol = parentUrl.slice(0, parentUrl.indexOf(':') + 1);
204
- let pathname;
205
- if (parentUrl[parentProtocol.length + 1] === '/') {
206
- // resolving to a :// so we need to read out the auth and host
207
- if (parentProtocol !== 'file:') {
208
- pathname = parentUrl.slice(parentProtocol.length + 2);
209
- pathname = pathname.slice(pathname.indexOf('/') + 1);
210
- } else {
211
- pathname = parentUrl.slice(8);
212
- }
213
- } else {
214
- // resolving to :/ so pathname is the /... part
215
- pathname = parentUrl.slice(parentProtocol.length + (parentUrl[parentProtocol.length] === '/' ? 1 : 0));
216
- }
217
- if (relUrl[0] === '/') return parentUrl.slice(0, parentUrl.length - pathname.length - 1) + relUrl;
218
-
219
- // join together and split for removal of .. and . segments
220
- // looping the string instead of anything fancy for perf reasons
221
- // '../../../../../z' resolved to 'x/y' is just 'z'
222
- const segmented = pathname.slice(0, pathname.lastIndexOf('/') + 1) + relUrl;
223
- const output = [];
224
- let segmentIndex = -1;
225
- for (let i = 0; i < segmented.length; i++) {
226
- // busy reading a segment - only terminate on '/'
227
- if (segmentIndex !== -1) {
228
- if (segmented[i] === '/') {
229
- output.push(segmented.slice(segmentIndex, i + 1));
230
- segmentIndex = -1;
231
- }
232
- }
233
-
234
- // new segment - check if it is relative
235
- else if (segmented[i] === '.') {
236
- // ../ segment
237
- if (segmented[i + 1] === '.' && (segmented[i + 2] === '/' || i + 2 === segmented.length)) {
238
- output.pop();
239
- i += 2;
240
- }
241
- // ./ segment
242
- else if (segmented[i + 1] === '/' || i + 1 === segmented.length) {
243
- i += 1;
244
- } else {
245
- // the start of a new segment as below
246
- segmentIndex = i;
247
- }
248
- }
249
- // it is the start of a new segment
250
- else {
251
- segmentIndex = i;
252
- }
253
- }
254
- // finish reading out the last segment
255
- if (segmentIndex !== -1) output.push(segmented.slice(segmentIndex));
256
- return parentUrl.slice(0, parentUrl.length - pathname.length) + output.join('');
257
- }
258
- }
259
- function resolveUrl(relUrl, parentUrl) {
260
- const resolvedUrl = resolveIfNotPlainOrUrl(relUrl, parentUrl) || (isUrl(relUrl) ? relUrl : resolveIfNotPlainOrUrl('./' + relUrl, parentUrl));
261
- return resolvedUrl;
262
- }
263
- function createScript(url) {
264
- // eslint-disable-next-line lwr/no-unguarded-apis, no-undef
265
- const script = document.createElement('script');
266
- script.async = true;
267
- script.crossOrigin = 'anonymous';
268
- script.src = url;
269
- return script;
270
- }
271
- let lastWindowError$1, lastWindowErrorUrl;
272
- function loadModuleDef(url) {
273
- return new Promise(function (resolve, reject) {
274
- if (hasDocument) {
275
- /* eslint-disable lwr/no-unguarded-apis, no-undef */
276
- const script = createScript(url);
277
- script.addEventListener('error', () => {
278
- reject(new LoaderError(FAIL_LOAD, [url]));
279
- });
280
- script.addEventListener('load', () => {
281
- document.head.removeChild(script);
282
- if (lastWindowErrorUrl === url) {
283
- reject(lastWindowError$1);
284
- } else {
285
- resolve();
286
- }
287
- });
288
- document.head.appendChild(script);
289
- /* eslint-enable lwr/no-unguarded-apis, no-undef */
290
- }
291
- });
292
- }
293
- if (hasDocument) {
294
- // When a script is executed, runtime errors are on the global/window scope which are NOT caught by the script's onerror handler.
295
- // eslint-disable-next-line lwr/no-unguarded-apis, no-undef
296
- window.addEventListener('error', evt => {
297
- lastWindowErrorUrl = evt.filename;
298
- lastWindowError$1 = evt.error;
299
- });
300
- }
301
-
302
- // Bootstrap / shim
303
-
304
- // Loader: modules
305
- const LOADER_PREFIX = 'lwr.loader.';
306
- const MODULE_DEFINE = `${LOADER_PREFIX}module.define`;
307
- const MODULE_DYNAMIC_LOAD = `${LOADER_PREFIX}moduleRegistry.dynamicLoad`;
308
- const MODULE_FETCH = `${LOADER_PREFIX}module.fetch`;
309
- const MODULE_ERROR = `${LOADER_PREFIX}module.error`;
310
-
311
- // Loader: mappings
312
- const MAPPINGS_FETCH = `${LOADER_PREFIX}mappings.fetch`;
313
- const MAPPINGS_ERROR = `${LOADER_PREFIX}mappings.error`;
314
-
315
- /* spec based import map resolver */
316
- class ImportMetadataResolver {
317
- // Default to empty mappings
318
- __init() {
319
- this.importURICache = new Map();
320
- }
321
- __init2() {
322
- this.pendingURICache = new Map();
323
- }
324
- __init3() {
325
- this.loadMappingHooks = [];
326
- }
327
- constructor(config, invalidationCallback) {
328
- ImportMetadataResolver.prototype.__init.call(this);
329
- ImportMetadataResolver.prototype.__init2.call(this);
330
- ImportMetadataResolver.prototype.__init3.call(this);
331
- this.config = config;
332
- this.invalidationCallback = invalidationCallback;
333
- }
334
- addLoadMappingHook(hook) {
335
- this.loadMappingHooks.push(hook);
336
- }
337
- getMappingEndpoint() {
338
- return this.config.endpoints && this.config.endpoints.uris ? this.config.endpoints.uris.mapping : undefined;
339
- }
340
- getModifiersAsUrlParams() {
341
- const modifiers = this.config.endpoints ? this.config.endpoints.modifiers : undefined;
342
- if (!modifiers) {
343
- // No modifiers return an empty string to append to the URL
344
- return '';
345
- } else {
346
- const qs = Object.keys(modifiers).map(key => `${encodeURIComponent(key)}=${encodeURIComponent(modifiers[key])}`).join('&');
347
- return `?${qs}`;
348
- }
349
- }
350
- buildMappingUrl(specifier) {
351
- const mappingEndpoint = this.getMappingEndpoint();
352
- const specifiers = encodeURIComponent(specifier);
353
- const modifiers = this.getModifiersAsUrlParams();
354
- return `${mappingEndpoint}${specifiers}${modifiers}`;
355
- }
356
- getBaseUrl() {
357
- return this.config.baseUrl;
358
- }
359
- registerImportMappings(newImportMetadata, rootSpecifiers) {
360
- if (!rootSpecifiers || rootSpecifiers.length === 0) {
361
- const imports = newImportMetadata ? JSON.stringify(newImportMetadata) : 'undefined';
362
- throw new LoaderError(BAD_IMPORT_METADATA, [imports, rootSpecifiers ? '[]' : 'undefined']);
363
- }
364
- if (!newImportMetadata) {
365
- throw new LoaderError(BAD_IMPORT_METADATA, ['undefined', JSON.stringify(rootSpecifiers)]);
366
- }
367
- if (!newImportMetadata.imports || Object.keys(newImportMetadata.imports).length === 0) {
368
- throw new LoaderError(BAD_IMPORT_METADATA, [JSON.stringify(newImportMetadata), JSON.stringify(rootSpecifiers)]);
369
- }
370
- const index = newImportMetadata.index || {};
371
- for (const [uri, specifiers] of Object.entries(newImportMetadata.imports)) {
372
- specifiers.forEach(specifier => {
373
- const indexValue = index[specifier];
374
- const existing = this.importURICache.get(specifier);
375
- if (!existing) {
376
- this.saveImportURIRecord(specifier, uri, indexValue, rootSpecifiers.includes(specifier));
377
- } else {
378
- const identity = indexValue || uri;
379
- const existingIdentity = existing.identity || existing.uri;
380
- if (existingIdentity !== identity) {
381
- this.invalidationCallback({
382
- name: specifier,
383
- oldUrl: existingIdentity,
384
- newUrl: identity
385
- });
386
- }
387
- }
388
- });
389
- }
390
- }
391
-
392
- // Get URL from the local cache or return undefiend
393
- getURI(specifier) {
394
- return this.importURICache.has(specifier) ? resolveUrl(this.importURICache.get(specifier).uri, this.getBaseUrl()) : undefined;
395
- }
396
- resolveLocal(specifier) {
397
- const uri = this.getURI(specifier);
398
- if (uri) {
399
- return uri;
400
- } else if (isUrl(specifier) || specifier.startsWith('/')) {
401
- return specifier;
402
- }
403
- return undefined;
404
- }
405
-
406
- /**
407
- * Resolves a the URI for a specified module. It will return the value in this order:
408
- *
409
- * 1) Mapping from local URI cache
410
- * 2) The URI if a specifier is already an absolute URI
411
- * 3) Mapping fetched from a registered loader hook
412
- * 4)
413
- * @param specifier
414
- * @returns module URI
415
- */
416
- async resolve(specifier) {
417
- let uri = this.getURI(specifier);
418
- if (uri) {
419
- return uri;
420
- } else if (isUrl(specifier) || specifier.startsWith('/')) {
421
- return specifier;
422
- } else {
423
- const pending = this.pendingURICache.get(specifier);
424
- if (pending) {
425
- return pending;
426
- }
427
- this.config.profiler.logOperationStart({
428
- id: MAPPINGS_FETCH,
429
- specifier
430
- });
431
- const fetchMappingService = this.hasMappingHooks() ? this.evaluateMappingHooks : this.fetchNewMappings;
432
- const promise = fetchMappingService.bind(this)(specifier).then(importMetadata => {
433
- if (!importMetadata || !importMetadata.imports) {
434
- throw new LoaderError(UNRESOLVED, [specifier]);
435
- }
436
- this.registerImportMappings(importMetadata, [specifier]);
437
- uri = this.getURI(specifier);
438
- if (!uri) {
439
- throw new LoaderError(UNRESOLVED, [specifier]);
440
- }
441
- this.config.profiler.logOperationEnd({
442
- id: MAPPINGS_FETCH,
443
- specifier
444
- });
445
- return uri;
446
- }).finally(() => {
447
- this.pendingURICache.delete(specifier);
448
- });
449
- this.pendingURICache.set(specifier, promise);
450
- return promise;
451
- }
452
- }
453
- hasMappingHooks() {
454
- return this.loadMappingHooks.length > 0;
455
- }
456
-
457
- /**
458
- * Evaluates mapping hooks. Returns first match. If all hooks return null call the mapping service.
459
- * @param specifier Request module identifier
460
- * @returns Import Metadata from the module root
461
- */
462
- async evaluateMappingHooks(specifier) {
463
- // Check with any registered loadMappingHooks
464
- const loadMappingHooks = this.loadMappingHooks;
465
- if (loadMappingHooks.length) {
466
- const knownModules = Array.from(this.importURICache.keys());
467
- for (let i = 0; i < loadMappingHooks.length; i++) {
468
- const loadMappingHook = loadMappingHooks[i];
469
- // eslint-disable-next-line no-await-in-loop
470
- const response = await loadMappingHook(specifier, {
471
- knownModules
472
- });
473
- // undefined (but not null) is considered an un expected response so we will stop processing hooks here and throw an error
474
- if (response || response === undefined) {
475
- return response;
476
- }
477
- }
478
- }
479
-
480
- // If we still do not have a match call the mapping service
481
- return this.fetchNewMappings(specifier);
482
- }
483
- async fetchNewMappings(specifier) {
484
- if (typeof globalThis.fetch !== 'function') {
485
- throw new LoaderError(UNRESOLVED, [specifier]);
486
- }
487
-
488
- // TODO For module invalidation with bundles it is recommended we have to send back all loaded root specified
489
- // to ensure we detect all conflicts.
490
- const uri = resolveUrl(this.buildMappingUrl(specifier), this.getBaseUrl());
491
- return globalThis.fetch(uri).then(res => {
492
- if (!res.ok) {
493
- this.config.profiler.logOperationStart({
494
- id: MAPPINGS_ERROR,
495
- specifier
496
- });
497
- throw new LoaderError(UNRESOLVED, [specifier]);
498
- }
499
- return res.json().then(ret => {
500
- return ret;
501
- }).catch(err => {
502
- throw new LoaderError(UNRESOLVED, [specifier]);
503
- });
504
- });
505
- }
506
- saveImportURIRecord(specifier, uri, identity, isRoot) {
507
- if (!identity || uri === identity) {
508
- this.importURICache.set(specifier, {
509
- uri,
510
- isRoot: isRoot
511
- });
512
- } else {
513
- this.importURICache.set(specifier, {
514
- uri,
515
- identity,
516
- isRoot: isRoot
517
- });
518
- }
519
- }
520
- }
521
- function reportError(error) {
522
- // TODO eventually this should be configurable instrumentation to send this somewhere
523
- // eslint-disable-next-line lwr/no-unguarded-apis, no-undef
524
- if (hasConsole) console.error(error);
525
- }
526
- function evaluateHandleStaleModuleHooks(handleStaleModuleHooks, hookArgs) {
527
- const {
528
- name,
529
- oldUrl,
530
- newUrl
531
- } = hookArgs;
532
- // keep evaluating hooks if return value is null
533
- for (let i = 0; i < handleStaleModuleHooks.length; i++) {
534
- const hook = handleStaleModuleHooks[i];
535
- try {
536
- const hookResult = hook({
537
- name,
538
- oldUrl,
539
- newUrl
540
- });
541
- if (hookResult !== null) {
542
- break;
543
- }
544
- } catch (e) {
545
- reportError(new LoaderError(STALE_HOOK_ERROR));
546
- }
547
- }
548
- }
549
- const MODULE_LOAD_TIMEOUT_TIMER = 60 * 1000; // 1m
550
-
551
- /*!
552
- * Copyright (C) 2023 salesforce.com, inc.
553
- */
554
- // @ts-ignore: Prevent cannot find name 'trustedTypes' error.
555
- const SUPPORTS_TRUSTED_TYPES = typeof trustedTypes !== 'undefined';
556
- function createTrustedTypesPolicy(name, options) {
557
- // @ts-ignore: Prevent cannot find name 'trustedTypes' error.
558
- return trustedTypes.createPolicy(name, options);
559
- }
560
- function createFallbackPolicy(_name, options) {
561
- return options;
562
- }
563
- // https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy/trusted-types
564
- const createPolicy = SUPPORTS_TRUSTED_TYPES ? createTrustedTypesPolicy : createFallbackPolicy;
565
- const policyOptions = {
566
- createHTML(value) {
567
- return value;
568
- },
569
- createScript(value) {
570
- return value;
571
- },
572
- createScriptURL(value) {
573
- return value;
574
- }
575
- };
576
- // Temporarily surround in try-catch until migration to AMD run.
577
- try {
578
- // istanbul ignore next: this creates a special policy described here https://developer.mozilla.org/en-US/docs/Web/API/TrustedTypePolicyFactory/createPolicy
579
- createPolicy('default', {
580
- createHTML(dirty) {
581
- // Treat null & undefined separately
582
- if (dirty === 'null' || dirty === 'undefined') {
583
- return dirty;
584
- }
585
- return dirty;
586
- },
587
- // Ignore typescript type validation for this policy.
588
- // Returning `undefined` from a TT policy blocks usages
589
- // of specific DOM sinks affected by this hook.
590
- // We want to block eval and inline scripts.
591
- // @ts-ignore
592
- createScript(dirty) {
593
- // Treat null & undefined separately
594
- if (dirty === 'null' || dirty === 'undefined') {
595
- return dirty;
596
- }
597
- // Block script evaluation
598
- return undefined;
599
- },
600
- createScriptURL(dirty) {
601
- // Treat null & undefined separately
602
- if (dirty === 'null' || dirty === 'undefined') {
603
- return dirty;
604
- }
605
- return dirty;
606
- }
607
- });
608
- } catch (_unused) {
609
- // swallow
610
- }
611
- const trusted = createPolicy('trusted', policyOptions);
612
- /*! version: 0.21.3 */
613
-
614
- /* global console,process */
615
-
616
- let lastWindowError;
617
- if (hasDocument) {
618
- globalThis.addEventListener('error', evt => {
619
- lastWindowError = evt.error;
620
- });
621
- }
622
- if (process.env.NODE_ENV !== 'production') {
623
- if (!hasSetTimeout && hasConsole) {
624
- // eslint-disable-next-line lwr/no-unguarded-apis
625
- console.warn('setTimeout API is not available, watchdog timer on load hook will not be set');
626
- }
627
- }
628
- function isCustomResponse(response) {
629
- return Object.prototype.hasOwnProperty.call(response, 'data') && !Object.prototype.hasOwnProperty.call(response, 'blob');
630
- }
631
- function isFetchResponse(response) {
632
- // if it quacks like a duck...
633
- return typeof response.blob === 'function';
634
- }
635
- function isResponseAPromise(response) {
636
- return !!(response && response.then);
637
- }
638
- async function evaluateLoadHookResponse(response, id) {
639
- return Promise.resolve().then(async () => {
640
- if (!response || !response.status) {
641
- throw new LoaderError(INVALID_LOADER_SERVICE_RESPONSE);
642
- }
643
- if (response.status !== 200) {
644
- throw new LoaderError(HTTP_FAIL_LOAD, [id, `${response.status}`]);
645
- }
646
- const isResponse = isFetchResponse(response);
647
- let code;
648
- if (isCustomResponse(response)) {
649
- code = response.data;
650
- } else if (isResponse) {
651
- // handle fetch response
652
- code = await response.text();
653
- } else {
654
- throw new LoaderError(INVALID_LOADER_SERVICE_RESPONSE);
655
- }
656
- if (!code) {
657
- throw new LoaderError(FAIL_LOAD, [id]);
658
- }
659
- code = `${code}\n//# sourceURL=${id}`; // append sourceURL for debugging
660
- try {
661
- // TODO eval source maps for debugging
662
- eval(trusted.createScript(code));
663
- } catch (e) {
664
- if (process.env.NODE_ENV !== 'production' && hasConsole) {
665
- // eslint-disable-next-line lwr/no-unguarded-apis
666
- console.error(e);
667
- }
668
- throw new LoaderError(FAIL_LOAD, [id]);
669
- }
670
- if (lastWindowError) {
671
- throw new LoaderError(FAIL_LOAD, [id]);
672
- }
673
- return true;
674
- });
675
- }
676
- async function evaluateLoadHook(id, hookPromise) {
677
- if (!hasSetTimeout) {
678
- return hookPromise;
679
- }
680
- return new Promise((resolve, reject) => {
681
- // wrap the hook in a watchdog timer
682
- // eslint-disable-next-line lwr/no-unguarded-apis, no-undef
683
- const timer = setTimeout(() => {
684
- reject(new LoaderError(MODULE_LOAD_TIMEOUT, [id]));
685
- }, MODULE_LOAD_TIMEOUT_TIMER);
686
- hookPromise.then(response => {
687
- resolve(response);
688
- }).catch(() => {
689
- reject(new LoaderError(FAIL_HOOK_LOAD, [id]));
690
- }).finally(() => {
691
- // eslint-disable-next-line lwr/no-unguarded-apis, no-undef
692
- clearTimeout(timer);
693
- });
694
- });
695
- }
696
-
697
- /* global console,process */
698
-
699
- class ModuleRegistry {
700
- constructor(config) {
701
- ModuleRegistry.prototype.__init.call(this);
702
- ModuleRegistry.prototype.__init2.call(this);
703
- ModuleRegistry.prototype.__init3.call(this);
704
- this.profiler = config.profiler;
705
- this.resolver = new ImportMetadataResolver(config, this.importMetadataInvalidationCallback.bind(this));
706
- }
707
- async load(id, importer) {
708
- const metadata = importer ? {
709
- importer
710
- } : {};
711
- this.profiler.logOperationStart({
712
- id: MODULE_DYNAMIC_LOAD,
713
- specifier: id,
714
- metadata
715
- });
716
- const resolvedId = await this.resolve(id, importer);
717
- const moduleRecord = await this.getModuleRecord(resolvedId, id);
718
- if (moduleRecord.evaluated) {
719
- return moduleRecord.module;
720
- } else {
721
- if (!moduleRecord.evaluationPromise) {
722
- moduleRecord.evaluationPromise = this.topLevelEvaluation(moduleRecord);
723
- }
724
- return moduleRecord.evaluationPromise;
725
- }
726
- }
727
- async resolve(id, importer) {
728
- const parentUrl = this.resolver.getBaseUrl(); // only support baseUrl for now
729
-
730
- let resolved;
731
- let aliasedId = id;
732
- const resolveHooks = this.resolveHook;
733
- if (resolveHooks) {
734
- for (let i = 0; i < resolveHooks.length; i++) {
735
- const resolveHook = resolveHooks[i];
736
- const response = resolveHook(aliasedId, {
737
- parentUrl
738
- });
739
- let result;
740
- if (response || response === null) {
741
- // eslint-disable-next-line no-await-in-loop
742
- result = isResponseAPromise(response) ? await response : response;
743
- }
744
- if (!this.isValidResolveResponse(result)) {
745
- throw new LoaderError(INVALID_LOADER_SERVICE_RESPONSE);
746
- }
747
-
748
- // if result is not null, attempt resolution
749
- if (result !== null) {
750
- if (typeof result === 'string') {
751
- if (resolveIfNotPlainOrUrl(result, parentUrl)) {
752
- // string response can't be a URL
753
- throw new LoaderError(INVALID_LOADER_SERVICE_RESPONSE);
754
- }
755
- aliasedId = result; // the next hook will receive the new id
756
- continue;
757
- }
758
- resolved = result && result.url && (resolveIfNotPlainOrUrl(result.url, parentUrl) || result.url);
759
- if (!resolved) {
760
- throw new LoaderError(INVALID_LOADER_SERVICE_RESPONSE);
761
- }
762
- // Don't process any more hooks if we have resolved
763
- break;
764
- }
765
- }
766
- if (aliasedId !== id) {
767
- // resolved module id is the aliased module if it has already been defined
768
- if (!resolved && this.namedDefineRegistry.has(aliasedId)) {
769
- return aliasedId;
770
- } else {
771
- id = aliasedId;
772
- }
773
- }
774
- }
775
- if (!resolved) {
776
- const resolvedOrPlain = resolveIfNotPlainOrUrl(id, parentUrl) || id;
777
-
778
- // if module registry already has named module the resolved id is the plain id
779
- if (this.moduleRegistry.has(resolvedOrPlain)) {
780
- return resolvedOrPlain;
781
- }
782
- const resolvedUrl = this.resolver.resolveLocal(resolvedOrPlain);
783
- if (resolvedUrl) {
784
- // resolve to the bare specifier if conditions are met
785
- if (this.namedDefineRegistry.has(resolvedOrPlain)) {
786
- const namedDefineRecord = this.namedDefineRegistry.get(resolvedOrPlain);
787
- if (namedDefineRecord.external || namedDefineRecord.defined) {
788
- const record = this.moduleRegistry.get(resolvedUrl);
789
- if (!record || !this.aliases.has(resolvedOrPlain)) {
790
- return resolvedOrPlain;
791
- }
792
- }
793
- }
794
- return resolvedUrl;
795
- }
796
- if (this.namedDefineRegistry.has(resolvedOrPlain)) {
797
- return resolvedOrPlain;
798
- }
799
- try {
800
- resolved = await this.resolver.resolve(resolvedOrPlain);
801
- } catch (e) {
802
- // defer to error handling below for unresolved
803
- }
804
- }
805
- if (!resolved || !isUrl(resolved)) {
806
- if (this.namedDefineRegistry.has(id)) {
807
- return id;
808
- }
809
- throw new LoaderError(UNRESOLVED, [id]);
810
- }
811
- if (importer && isUrl(resolved)) {
812
- resolved += `?importer=${encodeURIComponent(importer)}`;
813
- }
814
- return resolved;
815
- }
816
- has(id) {
817
- return this.moduleRegistry.has(id);
818
- }
819
- define(name, dependencies, exporter) {
820
- const mod = this.namedDefineRegistry.get(name);
821
- // Don't allow redefining a module.
822
- if (mod && mod.defined) {
823
- if (process.env.NODE_ENV !== 'production' && hasConsole) {
824
- // eslint-disable-next-line lwr/no-unguarded-apis
825
- console.warn(`Module redefine attempted: ${name}`);
826
- }
827
- this.lastDefine = mod;
828
- return;
829
- }
830
- const moduleDef = {
831
- name,
832
- dependencies,
833
- exporter,
834
- defined: true
835
- };
836
- if (mod && mod.external) {
837
- // if module is "external", resolve the external promise to notify any dependees
838
- mod.external.resolveExternal(moduleDef);
839
- }
840
- this.profiler.logOperationStart({
841
- id: MODULE_DEFINE,
842
- specifier: name
843
- });
844
- this.namedDefineRegistry.set(name, moduleDef);
845
- this.lastDefine = moduleDef;
846
- }
847
-
848
- /**
849
- * Marks modules as "externally" loaded/provided, so that the loader does not attempt to fetch them.
850
- *
851
- * @param modules - list of module identifiers
852
- */
853
- registerExternalModules(modules) {
854
- modules.map(id => {
855
- if (!this.namedDefineRegistry.has(id)) {
856
- let resolveExternal;
857
- let timer;
858
- const moduleDefPromise = new Promise((resolve, reject) => {
859
- resolveExternal = resolve;
860
-
861
- // watch the external for timeout
862
- // eslint-disable-next-line lwr/no-unguarded-apis, no-undef
863
- timer = setTimeout(() => {
864
- reject(new LoaderError(MODULE_LOAD_TIMEOUT, [id]));
865
- }, MODULE_LOAD_TIMEOUT_TIMER);
866
- }).finally(() => {
867
- // eslint-disable-next-line lwr/no-unguarded-apis, no-undef
868
- clearTimeout(timer);
869
- });
870
- const moduleDef = {
871
- name: id,
872
- defined: false,
873
- external: {
874
- resolveExternal,
875
- moduleDefPromise
876
- }
877
- };
878
- this.namedDefineRegistry.set(id, moduleDef);
879
- } else if (process.env.NODE_ENV !== 'production' && hasConsole) {
880
- // eslint-disable-next-line lwr/no-unguarded-apis
881
- console.warn(MODULE_ALREADY_LOADED.message, id);
882
- }
883
- });
884
- }
885
-
886
- // A registry for named AMD defines containing the *metadata* of AMD module
887
- __init() {
888
- this.namedDefineRegistry = new Map();
889
- }
890
-
891
- // The evaluated module registry where the module identifier (name or URL?) is the key
892
- __init2() {
893
- this.moduleRegistry = new Map();
894
- }
895
-
896
- // Aliases of modules in the registry
897
- __init3() {
898
- this.aliases = new Map();
899
- }
900
- getImportMetadataResolver() {
901
- return this.resolver;
902
- }
903
-
904
- // Returns an existing module record by the resolvedId or aliased id
905
- getExistingModuleRecord(resolvedId, aliasId) {
906
- const moduleRecord = this.moduleRegistry.get(resolvedId);
907
- if (moduleRecord) {
908
- this.storeModuleAlias(aliasId, resolvedId);
909
- return moduleRecord;
910
- }
911
-
912
- // Check if this is a known alias
913
- if (resolvedId !== aliasId) {
914
- const alias = this.aliases.get(aliasId);
915
- if (alias) {
916
- const aliasedModule = this.moduleRegistry.get(alias);
917
- if (aliasedModule) {
918
- return aliasedModule;
919
- }
920
- }
921
- }
922
- return moduleRecord;
923
- }
924
- async getModuleRecord(resolvedId, id) {
925
- // Look for an existing record
926
- const existingRecord = this.getExistingModuleRecord(resolvedId, id);
927
- if (existingRecord) {
928
- // return existing
929
- return existingRecord;
930
- }
931
-
932
- // Create a new Module Record
933
- const instantiation = this.getModuleDef(resolvedId, id);
934
- const dependencyRecords = instantiation.then(moduleDef => {
935
- const dependencies = moduleDef.dependencies || [];
936
- // get dep and filter out exports
937
- const filtered = dependencies.map(dep => {
938
- if (dep === 'exports') {
939
- return;
940
- }
941
- invariant(dep !== 'require', NO_AMD_REQUIRE);
942
- return this.getModuleDependencyRecord.call(this, dep);
943
- }).filter(depRecord => depRecord !== undefined);
944
- return Promise.all(filtered);
945
- });
946
- const newModuleRecord = {
947
- id: resolvedId,
948
- module: Object.create(null),
949
- dependencyRecords,
950
- instantiation,
951
- evaluated: false,
952
- evaluationPromise: null
953
- };
954
- this.moduleRegistry.set(resolvedId, newModuleRecord);
955
- this.storeModuleAlias(id, resolvedId);
956
-
957
- // Wait for the dependencies to resolve the return the moduleRecord
958
- return dependencyRecords.then(() => newModuleRecord);
959
- }
960
- storeModuleAlias(aliasId, resolvedId) {
961
- if (aliasId !== resolvedId) {
962
- if (!this.aliases.has(aliasId)) {
963
- this.aliases.set(aliasId, resolvedId);
964
- } else if (process.env.NODE_ENV !== 'production' && hasConsole) {
965
- // Warn the user if they were not aliasing to the resolvedId
966
- const currentResolvedId = this.aliases.get(aliasId);
967
- if (currentResolvedId !== resolvedId) {
968
- // eslint-disable-next-line lwr/no-unguarded-apis, no-undef
969
- if (process.env.NODE_ENV !== 'production' && hasConsole) {
970
- // eslint-disable-next-line lwr/no-unguarded-apis, no-undef
971
- console.warn(`Alias update attempt: ${aliasId}=>${currentResolvedId}, ${resolvedId}`);
972
- }
973
- }
974
- }
975
- }
976
- }
977
- async getModuleDependencyRecord(dependency) {
978
- const resolvedDepId = await this.resolve(dependency);
979
- return this.getModuleRecord(resolvedDepId, dependency);
980
- }
981
-
982
- // execute the "top-level code" (the code outside of functions) of a module
983
- async topLevelEvaluation(moduleRecord) {
984
- await this.instantiateAll(moduleRecord, {});
985
- return this.evaluateModule(moduleRecord, {});
986
- }
987
-
988
- // Returns a promise when a module and all of it's dependencies have finished instantiation
989
- async instantiateAll(moduleRecord, instantiatedMap) {
990
- if (!instantiatedMap[moduleRecord.id]) {
991
- instantiatedMap[moduleRecord.id] = true;
992
- const dependencyModuleRecords = await moduleRecord.dependencyRecords;
993
- if (dependencyModuleRecords) {
994
- for (let i = 0; i < dependencyModuleRecords.length; i++) {
995
- const depRecord = dependencyModuleRecords[i];
996
- // eslint-disable-next-line no-await-in-loop
997
- await this.instantiateAll(depRecord, instantiatedMap);
998
- }
999
- }
1000
- }
1001
- }
1002
- async evaluateModule(moduleRecord, evaluationMap) {
1003
- const dependencyModuleRecords = await moduleRecord.dependencyRecords;
1004
- if (dependencyModuleRecords.length > 0) {
1005
- evaluationMap[moduleRecord.id] = true;
1006
- // evaluate dependencies first
1007
- await this.evaluateModuleDependencies(dependencyModuleRecords, evaluationMap);
1008
- }
1009
- const {
1010
- exporter,
1011
- dependencies
1012
- } = await moduleRecord.instantiation;
1013
- // The exports object automatically gets filled in by the exporter evaluation
1014
- const exports = {};
1015
- const depsMapped = dependencies ? await Promise.all(dependencies.map(async dep => {
1016
- if (dep === 'exports') {
1017
- return exports;
1018
- }
1019
- const resolvedDepId = await this.resolve(dep);
1020
- const moduleRecord = this.moduleRegistry.get(resolvedDepId);
1021
- if (!moduleRecord) {
1022
- throw new LoaderError(FAILED_DEP, [resolvedDepId]);
1023
- }
1024
- const module = moduleRecord.module;
1025
-
1026
- /**
1027
- * Circular dependencies are handled properly when named exports are used,
1028
- * however, for default exports there is a bug: https://github.com/rollup/rollup/issues/3384
1029
- *
1030
- * The workaround below applies for circular dependencies (!moduleRecord.evaluated)
1031
- */
1032
- if (!moduleRecord.evaluated) {
1033
- return this.getCircularDependencyWrapper(module);
1034
- }
1035
- if (module) {
1036
- return module.__defaultInterop ? module.default : module;
1037
- }
1038
- throw new LoaderError(FAILED_DEP, [resolvedDepId]);
1039
- })) : [];
1040
-
1041
- // 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
1042
- if (moduleRecord.evaluated) {
1043
- return moduleRecord.module;
1044
- }
1045
-
1046
- // evaluates the module function
1047
- let moduleDefault;
1048
- try {
1049
- moduleDefault = exporter(...depsMapped);
1050
- } catch (e) {
1051
- throw new LoaderError(EXPORTER_ERROR, [moduleRecord.id, e.message || e]);
1052
- }
1053
- // value is returned from exporter, then we are not using named exports
1054
- if (moduleDefault !== undefined) {
1055
- moduleDefault = {
1056
- default: moduleDefault
1057
- };
1058
- // __defaultInterop is ONLY used to support backwards compatibility
1059
- // of importing default exports the "wrong" way (when not using named exports).
1060
- // See https://github.com/salesforce-experience-platform-emu/lwr/pull/816
1061
- Object.defineProperty(moduleDefault, '__defaultInterop', {
1062
- value: true
1063
- });
1064
- }
1065
- // if no return value, then we are using the exports object
1066
- else {
1067
- // handle only default export with Rollup forced named exports
1068
- if (this.isNamedExportDefaultOnly(exports)) {
1069
- Object.defineProperty(exports, '__useDefault', {
1070
- value: true
1071
- });
1072
- }
1073
- }
1074
- const moduleExports = moduleDefault || exports;
1075
-
1076
- // update the module record
1077
- // copy over enumerable public methods to module
1078
- for (const key in moduleExports) {
1079
- Object.defineProperty(moduleRecord.module, key, {
1080
- enumerable: true,
1081
- set(value) {
1082
- moduleExports[key] = value;
1083
- },
1084
- get() {
1085
- return moduleExports[key];
1086
- }
1087
- });
1088
- }
1089
-
1090
- // copy non-enumerable to module
1091
- if (moduleExports.__useDefault) {
1092
- Object.defineProperty(moduleRecord.module, '__useDefault', {
1093
- value: true
1094
- });
1095
- }
1096
- if (moduleExports.__defaultInterop) {
1097
- Object.defineProperty(moduleRecord.module, '__defaultInterop', {
1098
- value: true
1099
- });
1100
- }
1101
- if (moduleExports.__esModule) {
1102
- Object.defineProperty(moduleRecord.module, '__esModule', {
1103
- value: true
1104
- });
1105
- }
1106
- moduleRecord.evaluated = true;
1107
- Object.freeze(moduleRecord.module);
1108
- return moduleRecord.module;
1109
- }
1110
-
1111
- // Determines if named exports module has only default export
1112
- isNamedExportDefaultOnly(exports) {
1113
- return exports !== undefined && Object.getOwnPropertyNames(exports).length === 2 && Object.prototype.hasOwnProperty.call(exports, 'default') && Object.prototype.hasOwnProperty.call(exports, '__esModule');
1114
- }
1115
-
1116
- // Wrap the dependency in a function that can be called and detected by __circular__ property.
1117
- // The LWC engine checks for __circular__ to detect circular dependencies.
1118
- getCircularDependencyWrapper(module) {
1119
- const tmp = () => {
1120
- return module.__useDefault || module.__defaultInterop ? module.default : module;
1121
- };
1122
- tmp.__circular__ = true;
1123
- return tmp;
1124
- }
1125
- async evaluateModuleDependencies(dependencyModuleRecords, evaluationMap) {
1126
- for (let i = 0; i < dependencyModuleRecords.length; i++) {
1127
- const depRecord = dependencyModuleRecords[i];
1128
- if (!depRecord.evaluated && !evaluationMap[depRecord.id]) {
1129
- evaluationMap[depRecord.id] = true;
1130
- // eslint-disable-next-line no-await-in-loop
1131
- await this.evaluateModule(depRecord, evaluationMap);
1132
- }
1133
- }
1134
- }
1135
- async getModuleDef(resolvedId, originalId) {
1136
- // reset lastDefine
1137
- this.lastDefine = undefined;
1138
-
1139
- // the module name can be the resolved ID or the original ID if neither are URL's.
1140
- const moduleName = !isUrl(resolvedId) ? resolvedId : originalId !== resolvedId ? originalId : undefined;
1141
- let moduleDef = moduleName && this.namedDefineRegistry.get(moduleName);
1142
- if (moduleDef && moduleDef.external) {
1143
- return moduleDef.external.moduleDefPromise;
1144
- }
1145
- if (moduleDef && moduleDef.defined) {
1146
- return moduleDef;
1147
- }
1148
- const parentUrl = this.resolver.getBaseUrl(); // only support baseUrl for now
1149
- const specifier = moduleName || originalId;
1150
- this.profiler.logOperationStart({
1151
- id: MODULE_FETCH,
1152
- specifier
1153
- });
1154
- return Promise.resolve().then(async () => {
1155
- const loadHooks = this.loadHook;
1156
- if (loadHooks) {
1157
- for (let i = 0; i < loadHooks.length; i++) {
1158
- const loadHook = loadHooks[i];
1159
- const response = loadHook(resolvedId, parentUrl);
1160
- const result = isResponseAPromise(response) ?
1161
- // eslint-disable-next-line no-await-in-loop
1162
- await evaluateLoadHook(resolvedId, response) : response;
1163
- if (result === undefined) {
1164
- throw new LoaderError(INVALID_LOADER_SERVICE_RESPONSE);
1165
- }
1166
- if (result && result !== null) {
1167
- return evaluateLoadHookResponse(result, resolvedId);
1168
- }
1169
- }
1170
- }
1171
- return false;
1172
- }).then(result => {
1173
- if (result !== true && hasDocument) {
1174
- return loadModuleDef(resolvedId);
1175
- }
1176
- }).then(() => {
1177
- // Attempt to retrieve the module definition by name first
1178
- moduleDef = moduleName && this.namedDefineRegistry.get(moduleName);
1179
-
1180
- // Fallback to the last loader.define call
1181
- if (!moduleDef) {
1182
- moduleDef = this.lastDefine;
1183
- }
1184
-
1185
- // This should not happen
1186
- if (!moduleDef) {
1187
- throw new LoaderError(FAIL_INSTANTIATE, [resolvedId]);
1188
- }
1189
- this.profiler.logOperationEnd({
1190
- id: MODULE_FETCH,
1191
- specifier
1192
- });
1193
- return moduleDef;
1194
- }).catch(e => {
1195
- // Create module error marks for all errors caused by the loader
1196
- // Note: these marks do not include errors caused by invalid server responses or loader hooks
1197
- if (!(e instanceof LoaderError)) {
1198
- this.profiler.logOperationStart({
1199
- id: MODULE_ERROR,
1200
- specifier
1201
- });
1202
- }
1203
- throw e;
1204
- });
1205
- }
1206
- addLoaderPlugin(hooks) {
1207
- if (typeof hooks !== 'object') {
1208
- throw new LoaderError(INVALID_HOOK);
1209
- }
1210
- const {
1211
- loadModule: loadHook,
1212
- resolveModule: resolveHook,
1213
- loadMapping
1214
- } = hooks;
1215
- if (resolveHook) {
1216
- if (this.resolveHook) {
1217
- this.resolveHook.push(resolveHook);
1218
- } else {
1219
- this.resolveHook = [resolveHook];
1220
- }
1221
- }
1222
- if (loadHook) {
1223
- if (this.loadHook) {
1224
- this.loadHook.push(loadHook);
1225
- } else {
1226
- this.loadHook = [loadHook];
1227
- }
1228
- }
1229
- if (loadMapping) {
1230
- this.resolver.addLoadMappingHook(loadMapping);
1231
- }
1232
- }
1233
- importMetadataInvalidationCallback({
1234
- name,
1235
- oldUrl,
1236
- newUrl
1237
- }) {
1238
- const handleStaleModuleHooks = this.handleStaleModuleHook;
1239
- if (handleStaleModuleHooks) {
1240
- evaluateHandleStaleModuleHooks(handleStaleModuleHooks, {
1241
- name,
1242
- oldUrl,
1243
- newUrl
1244
- });
1245
- } else {
1246
- if (process.env.NODE_ENV !== 'production' && hasConsole) {
1247
- // eslint-disable-next-line lwr/no-unguarded-apis, no-undef
1248
- console.warn(`stale module detected ${name}, current URL:${oldUrl}, new URL:${newUrl}`);
1249
- }
1250
- }
1251
- }
1252
- registerHandleStaleModuleHook(handleStaleModule) {
1253
- if (this.handleStaleModuleHook) {
1254
- this.handleStaleModuleHook.push(handleStaleModule);
1255
- } else {
1256
- this.handleStaleModuleHook = [handleStaleModule];
1257
- }
1258
- }
1259
- isValidResolveResponse(res) {
1260
- return res === null || typeof res === 'string' || res && typeof res.url === 'string';
1261
- }
1262
- }
1263
-
1264
- /**
1265
- * The LWR loader is inspired and borrows from the algorithms and native browser principles of https://github.com/systemjs/systemjs
1266
- */
1267
- class Loader {
1268
- constructor(config) {
1269
- let baseUrl = config.baseUrl;
1270
- const mappingEndpoint = config.endpoints ? config.endpoints.uris.mapping : undefined;
1271
- let profiler = config.profiler;
1272
- if (!mappingEndpoint) {
1273
- throw new LoaderError(NO_MAPPING_URL);
1274
- }
1275
-
1276
- // add a trailing slash, if it does not exist
1277
- config.endpoints.uris.mapping = mappingEndpoint.replace(/\/?$/, '/');
1278
- if (baseUrl) {
1279
- // add a trailing slash, if it does not exist
1280
- baseUrl = baseUrl.replace(/\/?$/, '/');
1281
- }
1282
- if (!baseUrl) {
1283
- baseUrl = getBaseUrl();
1284
- }
1285
- if (!baseUrl) {
1286
- throw new LoaderError(NO_BASE_URL);
1287
- }
1288
- if (!profiler) {
1289
- // default noop profiler
1290
- profiler = {
1291
- logOperationStart: () => {
1292
- /* noop */
1293
- },
1294
- logOperationEnd: () => {
1295
- /* noop */
1296
- }
1297
- };
1298
- }
1299
- this.registry = new ModuleRegistry(Object.freeze({
1300
- endpoints: config.endpoints,
1301
- baseUrl,
1302
- profiler
1303
- }));
1304
-
1305
- // TODO: W-10539691 - temp workaround for LWR-Java -- remove once appId is implemented there
1306
- if (config.appMetadata && !config.appMetadata.appId) {
1307
- // Parse the appId from the bootstrapModule
1308
- // LWR-Java bootstrap module format: @lwr-bootstrap/my/app/v/0_0_1 -- my/app is the appId
1309
- const match = config.appMetadata.bootstrapModule.match(/@lwr-bootstrap\/(.+)\/v\/.+/);
1310
- const appId = match && match[1];
1311
- config.appMetadata.appId = appId;
1312
- }
1313
-
1314
- // TODO: https://github.com/salesforce-experience-platform-emu/lwr/issues/1087
1315
- this.services = Object.freeze({
1316
- addLoaderPlugin: this.registry.addLoaderPlugin.bind(this.registry),
1317
- handleStaleModule: this.registry.registerHandleStaleModuleHook.bind(this.registry),
1318
- appMetadata: config.appMetadata,
1319
- serverData: config.serverData || {}
1320
- });
1321
- }
1322
-
1323
- /**
1324
- * Defines/registers a single named AMD module definition.
1325
- *
1326
- * @param {string} name The module name
1327
- * @param {string[]} dependencies A list of module dependencies (module imports)
1328
- * @param {Function} execute The function containing the module code. AKA exporter as it also returns the modules exports when executed
1329
- * @return {void}
1330
- */
1331
- define(name, dependencies, execute) {
1332
- invariant(typeof name === 'string', MISSING_NAME);
1333
- let ctor = execute;
1334
- let deps = dependencies;
1335
-
1336
- // Convert no dependencies form `define('name', function(){}, {});` to: `define('name', [], function(){}, {})`
1337
- if (typeof deps === 'function') {
1338
- ctor = dependencies;
1339
- deps = [];
1340
- }
1341
- invariant(Array.isArray(deps), INVALID_DEPS);
1342
- this.registry.define(name, deps, ctor);
1343
- }
1344
-
1345
- /**
1346
- * Retrieves/loads a module, returning it from the registry if it exists and fetching it if it doesn't.
1347
- *
1348
- * @param {string} id - A module identifier or URL
1349
- * @param {string} importer - The versioned specifier of the module importer
1350
- * Used when the ID is not versioned (eg: variable dynamic imports)
1351
- * @return {Promise<Module>}
1352
- */
1353
- async load(id, importer) {
1354
- return this.registry.load(id, importer);
1355
- }
1356
-
1357
- /**
1358
- * 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).
1359
- *
1360
- * @param {string} id - A module identifier or URL
1361
- * @return {boolean}
1362
- */
1363
- has(id) {
1364
- return this.registry.has(id);
1365
- }
1366
-
1367
- /**
1368
- * Resolves the module identifier or URL. Returns the module identifier if the moduleDefinition exists, or the full resolved URL if a URL is given.
1369
- *
1370
- * @param {string} id - A module identifier or URL
1371
- * @param {string} importer - The versioned specifier of the module importer
1372
- * Used when the ID is not versioned (eg: variable dynamic imports)
1373
- * @return {string}
1374
- */
1375
- async resolve(id, importer) {
1376
- return this.registry.resolve(id, importer);
1377
- }
1378
- async registerImportMappings(mappings, rootSpecifiers) {
1379
- this.registry.getImportMetadataResolver().registerImportMappings(mappings, rootSpecifiers);
1380
- }
1381
-
1382
- /**
1383
- * Marks modules as "externally" loaded/provided (e.g. preloaded), so that the loader does not attempt to load them.
1384
- *
1385
- * @param modules - list of module identifiers
1386
- */
1387
- registerExternalModules(modules) {
1388
- this.registry.registerExternalModules(modules);
1389
- }
1390
- }
1391
-
1392
- exports.Loader = Loader;
1393
-
1394
- Object.defineProperty(exports, '__esModule', { value: true });
1395
-
1396
- }));