@lwrjs/everywhere 0.12.0-alpha.2 → 0.12.0-alpha.21

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.
Files changed (26) hide show
  1. package/README.md +3 -1
  2. package/build/__generated_site_amd_modules__/1/application/amd/l/en-US/ai/amd-bootstrap/configuration/ci/-/-/s/4566daf7b8cc8ea3da69bc9cac33bfc9/config.js +7 -0
  3. 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_21/s/8bce578258518655194bd71d1d72aad5/@lwrjs_app-service_amd-bootstrap_module_amd.js +14 -0
  4. package/build/__generated_site_amd_modules__/1/module/amd/1/l/en-US/mi/lwc/v/{5_1_0/s/aff256c8afef6eb76ff8626ad5f54e3b → 6_2_1/s/2670f5386c68fa67ae710174187505e9}/lwc.js +812 -300
  5. package/build/__generated_site_amd_modules__/1/module/amd/1/l/en-US/mi/lwr/everywhereAmd/v/{0_12_0-alpha_2 → 0_12_0-alpha_21}/s/cb931ebef2b89dcf8ab51456e3a68864/lwr_everywhereAmd.js +3 -3
  6. package/build/__generated_site_amd_modules__/1/module/amd/1/l/en-US/mi/lwr/init/v/{0_12_0-alpha_2 → 0_12_0-alpha_21}/s/f30361ad8ff7af505bf4d465c8499181/lwr_init.js +21 -21
  7. package/build/__generated_site_amd_modules__/1/module/amd/1/l/en-US/mi/lwr/metrics/v/{0_12_0-alpha_2 → 0_12_0-alpha_21}/s/274c8343f810353bbad085a79709395f/lwr_metrics.js +1 -1
  8. package/build/__generated_site_amd_modules__/1/module/amd/1/l/en-US/mi/lwr/preInit/v/{0_12_0-alpha_2/s/f3a204ef43fb3057d910f80d7e9f9ba7 → 0_12_0-alpha_21/s/ec0fad0e38a96bb0b88c9f4553460347}/lwr_preInit.js +4 -3
  9. package/build/__generated_site_amd_modules__/1/module/amd/1/l/en-US/mi/lwr/profiler/v/0_12_0-alpha_21/s/a152b8d35f12ca1b5147c5cd1ee155fb/lwr_profiler.js +89 -0
  10. package/build/__generated_site_amd_modules__/1/module/amd/1/l/en-US/mi/lwr/vault/v/{0_12_0-alpha_2 → 0_12_0-alpha_21}/s/c92abd8c1fec2d7eff62e4b097abbe14/lwr_vault.js +1 -1
  11. package/build/__generated_site_amd_modules__/1/resource/amd/lwr-error-shim.js/v/{0_12_0-alpha_2 → 0_12_0-alpha_21}/lwr-error-shim.js +1 -1
  12. package/build/__generated_site_amd_modules__/1/resource/amd/lwr-loader-shim.bundle.js/v/{0_12_0-alpha_2 → 0_12_0-alpha_21}/lwr-loader-shim.bundle.js +10 -9
  13. package/build/assets/amd/lwr-everywhere-debug.js +11 -11
  14. package/build/assets/amd/lwr-everywhere-min.js +2 -2
  15. package/build/assets/amd/lwr-everywhere.js +11 -11
  16. package/build/assets/core/lwr-everywhere-debug.js +7 -7
  17. package/build/assets/core/lwr-everywhere-min.js +1 -1
  18. package/build/assets/core/lwr-everywhere.js +7 -7
  19. package/build/assets/esm/lwr-everywhere-debug.js +1 -1
  20. package/build/assets/esm/lwr-everywhere-min.js +1 -1
  21. package/build/assets/esm/lwr-everywhere.js +1 -1
  22. package/package.json +9 -9
  23. package/build/__generated_site_amd_modules__/1/application/amd/l/en-US/ai/amd-bootstrap/configuration/ci/-/-/s/3f1cbc09dcda95f1f74fba817c81fa86/config.js +0 -11
  24. 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_2/s/8bce578258518655194bd71d1d72aad5/@lwrjs_app-service_amd-bootstrap_module_amd.js +0 -14
  25. package/build/__generated_site_amd_modules__/1/module/amd/1/l/en-US/mi/lwr/loader/v/0_12_0-alpha_2/s/e11ffe74ed86b1153c4eb8b001587909/lwr_loader.js +0 -1396
  26. package/build/__generated_site_amd_modules__/1/module/amd/1/l/en-US/mi/lwr/profiler/v/0_12_0-alpha_2/s/a152b8d35f12ca1b5147c5cd1ee155fb/lwr_profiler.js +0 -99
@@ -1,1396 +0,0 @@
1
- LWR.define('lwr/loader/v/0_12_0-alpha_2', ['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.2 */
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 v5.1.0*/
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.20.8 */
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
- }));