@lwrjs/loader 0.13.0-alpha.2 → 0.13.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.
- package/build/assets/prod/lwr-error-shim.js +2 -2
- package/build/assets/prod/lwr-loader-shim-legacy.bundle.js +34 -29
- package/build/assets/prod/lwr-loader-shim-legacy.bundle.min.js +3 -3
- package/build/assets/prod/lwr-loader-shim-legacy.js +21 -16
- package/build/assets/prod/lwr-loader-shim.bundle.js +45 -23
- package/build/assets/prod/lwr-loader-shim.bundle.min.js +3 -3
- package/build/assets/prod/lwr-loader-shim.js +27 -12
- package/build/bundle/prod/lwr/esmLoader/esmLoader.js +1 -1
- package/build/cjs/index.cjs +28 -1
- package/build/cjs/modules/lwr/esmLoader/esmLoader.cjs +2 -2
- package/build/cjs/modules/lwr/esmLoader/importResolver.cjs +0 -17
- package/build/cjs/modules/lwr/esmLoader/importResolverLegacy.cjs +1 -18
- package/build/cjs/modules/lwr/loader/errors/messages.cjs +7 -1
- package/build/cjs/modules/lwr/loader/errors/reportError.cjs +1 -2
- package/build/cjs/modules/lwr/loader/hooks/moduleInvalidation.cjs +2 -3
- package/build/cjs/modules/lwr/loader/hooks/resolveAndLoadHook.cjs +3 -4
- package/build/cjs/modules/lwr/loader/moduleRegistry/importMetadataResolver.cjs +7 -6
- package/build/cjs/modules/lwr/loader/moduleRegistry/moduleRegistry.cjs +8 -10
- package/build/cjs/modules/lwr/loader/moduleRegistry/scriptLoad.cjs +2 -2
- package/build/cjs/modules/lwr/loader/utils/url.cjs +1 -1
- package/build/cjs/modules/lwr/loaderLegacy/errors/messages.cjs +1 -1
- package/build/cjs/modules/lwr/loaderLegacy/errors/reportError.cjs +1 -2
- package/build/cjs/modules/lwr/loaderLegacy/hooks/moduleInvalidation.cjs +2 -3
- package/build/cjs/modules/lwr/loaderLegacy/hooks/resolveAndLoadHook.cjs +3 -4
- package/build/cjs/modules/lwr/loaderLegacy/importMap/dom.cjs +4 -4
- package/build/cjs/modules/lwr/loaderLegacy/importMap/importMap.cjs +2 -2
- package/build/cjs/modules/lwr/loaderLegacy/importMap/importMapResolver.cjs +1 -2
- package/build/cjs/modules/lwr/loaderLegacy/importMap/utils.cjs +1 -1
- package/build/cjs/modules/lwr/loaderLegacy/importResolver/importResolver.cjs +0 -17
- package/build/cjs/modules/lwr/loaderLegacy/moduleRegistry/moduleRegistry.cjs +7 -10
- package/build/cjs/modules/lwr/loaderLegacy/moduleRegistry/scriptLoad.cjs +2 -2
- package/build/cjs/modules/lwr/loaderLegacy/utils/url.cjs +1 -1
- package/build/cjs/package.d.cjs +0 -0
- package/build/cjs/types.cjs +5 -0
- package/build/error-shim/index.d.ts +2 -0
- package/build/error-shim/index.js +17 -0
- package/build/index.d.ts +1 -1
- package/build/index.js +28 -1
- package/build/modules/lwr/esmLoader/esmLoader.d.ts +6 -0
- package/build/modules/lwr/esmLoader/esmLoader.js +2 -2
- package/build/modules/lwr/esmLoader/importResolver.d.ts +17 -0
- package/build/modules/lwr/esmLoader/importResolver.js +47 -0
- package/build/modules/lwr/esmLoader/importResolverLegacy.d.ts +16 -0
- package/build/modules/lwr/esmLoader/importResolverLegacy.js +18 -0
- package/build/modules/lwr/loader/constants/constants.d.ts +2 -0
- package/build/modules/lwr/loader/constants/constants.js +2 -0
- package/build/modules/lwr/loader/errors/messages.d.ts +33 -0
- package/build/modules/lwr/loader/errors/messages.js +128 -0
- package/build/modules/lwr/loader/errors/reportError.d.ts +4 -0
- package/build/modules/lwr/loader/errors/reportError.js +9 -0
- package/build/modules/lwr/loader/errors/utils.d.ts +2 -0
- package/build/modules/lwr/loader/errors/utils.js +8 -0
- package/build/modules/lwr/loader/hooks/moduleInvalidation.d.ts +3 -0
- package/build/modules/lwr/loader/hooks/moduleInvalidation.js +19 -0
- package/build/modules/lwr/loader/hooks/resolveAndLoadHook.d.ts +7 -0
- package/build/modules/lwr/loader/hooks/resolveAndLoadHook.js +94 -0
- package/build/modules/lwr/loader/loader.d.ts +53 -0
- package/build/modules/lwr/loader/loader.js +18 -11
- package/build/modules/lwr/loader/moduleRegistry/importMetadataResolver.d.ts +44 -0
- package/build/modules/lwr/loader/moduleRegistry/importMetadataResolver.js +211 -0
- package/build/modules/lwr/loader/moduleRegistry/moduleRegistry.d.ts +47 -0
- package/build/modules/lwr/loader/moduleRegistry/moduleRegistry.js +530 -0
- package/build/modules/lwr/loader/moduleRegistry/scriptLoad.d.ts +3 -0
- package/build/modules/lwr/loader/moduleRegistry/scriptLoad.js +43 -0
- package/build/modules/lwr/loader/utils/dom.d.ts +4 -0
- package/build/modules/lwr/loader/utils/dom.js +6 -0
- package/build/modules/lwr/loader/utils/url.d.ts +28 -0
- package/build/modules/lwr/loader/utils/url.js +128 -0
- package/build/modules/lwr/loaderLegacy/constants/constants.d.ts +2 -0
- package/build/modules/lwr/loaderLegacy/constants/constants.js +2 -0
- package/build/modules/lwr/loaderLegacy/errors/messages.d.ts +30 -0
- package/build/modules/lwr/loaderLegacy/errors/messages.js +113 -0
- package/build/modules/lwr/loaderLegacy/errors/reportError.d.ts +4 -0
- package/build/modules/lwr/loaderLegacy/errors/reportError.js +9 -0
- package/build/modules/lwr/loaderLegacy/errors/utils.d.ts +2 -0
- package/build/modules/lwr/loaderLegacy/errors/utils.js +8 -0
- package/build/modules/lwr/loaderLegacy/hooks/moduleInvalidation.d.ts +3 -0
- package/build/modules/lwr/loaderLegacy/hooks/moduleInvalidation.js +19 -0
- package/build/modules/lwr/loaderLegacy/hooks/resolveAndLoadHook.d.ts +7 -0
- package/build/modules/lwr/loaderLegacy/hooks/resolveAndLoadHook.js +94 -0
- package/build/modules/lwr/loaderLegacy/importMap/dom.d.ts +10 -0
- package/build/modules/lwr/loaderLegacy/importMap/dom.js +63 -0
- package/build/modules/lwr/loaderLegacy/importMap/importMap.d.ts +22 -0
- package/build/modules/lwr/loaderLegacy/importMap/importMap.js +108 -0
- package/build/modules/lwr/loaderLegacy/importMap/importMapResolver.d.ts +8 -0
- package/build/modules/lwr/loaderLegacy/importMap/importMapResolver.js +11 -0
- package/build/modules/lwr/loaderLegacy/importMap/utils.d.ts +4 -0
- package/build/modules/lwr/loaderLegacy/importMap/utils.js +23 -0
- package/build/modules/lwr/loaderLegacy/importResolver/importResolver.d.ts +6 -0
- package/build/modules/lwr/loaderLegacy/importResolver/importResolver.js +2 -0
- package/build/modules/lwr/loaderLegacy/loaderLegacy.d.ts +57 -0
- package/build/modules/lwr/loaderLegacy/loaderLegacy.js +13 -13
- package/build/modules/lwr/loaderLegacy/moduleRegistry/moduleRegistry.d.ts +53 -0
- package/build/modules/lwr/loaderLegacy/moduleRegistry/moduleRegistry.js +544 -0
- package/build/modules/lwr/loaderLegacy/moduleRegistry/scriptLoad.d.ts +3 -0
- package/build/modules/lwr/loaderLegacy/moduleRegistry/scriptLoad.js +43 -0
- package/build/modules/lwr/loaderLegacy/utils/dom.d.ts +4 -0
- package/build/modules/lwr/loaderLegacy/utils/dom.js +6 -0
- package/build/modules/lwr/loaderLegacy/utils/url.d.ts +28 -0
- package/build/modules/lwr/loaderLegacy/utils/url.js +128 -0
- package/build/shim/constants.d.ts +2 -0
- package/build/shim/constants.js +2 -0
- package/build/shim/customInit.d.ts +4 -0
- package/build/shim/customInit.js +29 -0
- package/build/shim/index.d.ts +2 -0
- package/build/shim/index.js +9 -0
- package/build/shim/loader.d.ts +3 -0
- package/build/shim/loader.js +27 -0
- package/build/shim/shim.d.ts +31 -0
- package/build/shim/shim.js +194 -0
- package/build/shim-legacy/index.d.ts +2 -0
- package/build/shim-legacy/index.js +9 -0
- package/build/shim-legacy/loaderLegacy.d.ts +3 -0
- package/build/shim-legacy/loaderLegacy.js +29 -0
- package/build/shim-legacy/shimLegacy.d.ts +31 -0
- package/build/shim-legacy/shimLegacy.js +188 -0
- package/build/types.d.ts +56 -0
- package/build/types.js +2 -0
- package/package.json +9 -10
|
@@ -0,0 +1,530 @@
|
|
|
1
|
+
/* global console,process */
|
|
2
|
+
import { invariant, NO_AMD_REQUIRE, LoaderError, FAIL_INSTANTIATE, FAILED_DEP, UNRESOLVED, INVALID_HOOK, INVALID_LOADER_SERVICE_RESPONSE, MODULE_ALREADY_LOADED, MODULE_LOAD_TIMEOUT, EXPORTER_ERROR, } from '../errors/messages.js';
|
|
3
|
+
import { resolveIfNotPlainOrUrl, isUrl } from '../utils/url.js';
|
|
4
|
+
import { hasDocument, hasConsole } from '../utils/dom.js';
|
|
5
|
+
import { loadModuleDef } from './scriptLoad.js';
|
|
6
|
+
import { ImportMetadataResolver } from './importMetadataResolver.js';
|
|
7
|
+
import { evaluateHandleStaleModuleHooks } from '../hooks/moduleInvalidation.js';
|
|
8
|
+
import { evaluateLoadHookResponse, evaluateLoadHook, isResponseAPromise, } from '../hooks/resolveAndLoadHook.js';
|
|
9
|
+
import { MODULE_DEFINE, MODULE_ERROR, MODULE_FETCH, MODULE_DYNAMIC_LOAD } from 'lwr/metrics';
|
|
10
|
+
import { MODULE_LOAD_TIMEOUT_TIMER } from '../constants/constants.js';
|
|
11
|
+
export class ModuleRegistry {
|
|
12
|
+
constructor(config) {
|
|
13
|
+
// A registry for named AMD defines containing the *metadata* of AMD module
|
|
14
|
+
this.namedDefineRegistry = new Map();
|
|
15
|
+
// The evaluated module registry where the module identifier (name or URL?) is the key
|
|
16
|
+
this.moduleRegistry = new Map();
|
|
17
|
+
// Aliases of modules in the registry
|
|
18
|
+
this.aliases = new Map();
|
|
19
|
+
this.profiler = config.profiler;
|
|
20
|
+
this.resolver = new ImportMetadataResolver(config, this.importMetadataInvalidationCallback.bind(this));
|
|
21
|
+
}
|
|
22
|
+
async load(id, importer) {
|
|
23
|
+
const metadata = importer ? { importer } : {};
|
|
24
|
+
this.profiler.logOperationStart({
|
|
25
|
+
id: MODULE_DYNAMIC_LOAD,
|
|
26
|
+
specifier: id,
|
|
27
|
+
metadata,
|
|
28
|
+
});
|
|
29
|
+
const resolvedId = await this.resolve(id, importer);
|
|
30
|
+
const moduleRecord = await this.getModuleRecord(resolvedId, id);
|
|
31
|
+
if (moduleRecord.evaluated) {
|
|
32
|
+
return moduleRecord.module;
|
|
33
|
+
}
|
|
34
|
+
else {
|
|
35
|
+
if (!moduleRecord.evaluationPromise) {
|
|
36
|
+
moduleRecord.evaluationPromise = this.topLevelEvaluation(moduleRecord);
|
|
37
|
+
}
|
|
38
|
+
return moduleRecord.evaluationPromise;
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
async resolve(id, importer) {
|
|
42
|
+
const parentUrl = this.resolver.getBaseUrl(); // only support baseUrl for now
|
|
43
|
+
let resolved;
|
|
44
|
+
let aliasedId = id;
|
|
45
|
+
const resolveHooks = this.resolveHook;
|
|
46
|
+
if (resolveHooks) {
|
|
47
|
+
for (let i = 0; i < resolveHooks.length; i++) {
|
|
48
|
+
const resolveHook = resolveHooks[i];
|
|
49
|
+
const response = resolveHook(aliasedId, { parentUrl });
|
|
50
|
+
let result;
|
|
51
|
+
if (response || response === null) {
|
|
52
|
+
// eslint-disable-next-line no-await-in-loop
|
|
53
|
+
result = isResponseAPromise(response) ? await response : response;
|
|
54
|
+
}
|
|
55
|
+
if (!this.isValidResolveResponse(result)) {
|
|
56
|
+
throw new LoaderError(INVALID_LOADER_SERVICE_RESPONSE);
|
|
57
|
+
}
|
|
58
|
+
// if result is not null, attempt resolution
|
|
59
|
+
if (result !== null) {
|
|
60
|
+
if (typeof result === 'string') {
|
|
61
|
+
if (resolveIfNotPlainOrUrl(result, parentUrl)) {
|
|
62
|
+
// string response can't be a URL
|
|
63
|
+
throw new LoaderError(INVALID_LOADER_SERVICE_RESPONSE);
|
|
64
|
+
}
|
|
65
|
+
aliasedId = result; // the next hook will receive the new id
|
|
66
|
+
continue;
|
|
67
|
+
}
|
|
68
|
+
resolved =
|
|
69
|
+
result && result.url && (resolveIfNotPlainOrUrl(result.url, parentUrl) || result.url);
|
|
70
|
+
if (!resolved) {
|
|
71
|
+
throw new LoaderError(INVALID_LOADER_SERVICE_RESPONSE);
|
|
72
|
+
}
|
|
73
|
+
// Don't process any more hooks if we have resolved
|
|
74
|
+
break;
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
if (aliasedId !== id) {
|
|
78
|
+
// resolved module id is the aliased module if it has already been defined
|
|
79
|
+
if (!resolved && this.namedDefineRegistry.has(aliasedId)) {
|
|
80
|
+
return aliasedId;
|
|
81
|
+
}
|
|
82
|
+
else {
|
|
83
|
+
id = aliasedId;
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
if (!resolved) {
|
|
88
|
+
const resolvedOrPlain = resolveIfNotPlainOrUrl(id, parentUrl) || id;
|
|
89
|
+
// if module registry already has named module the resolved id is the plain id
|
|
90
|
+
if (this.moduleRegistry.has(resolvedOrPlain)) {
|
|
91
|
+
return resolvedOrPlain;
|
|
92
|
+
}
|
|
93
|
+
const resolvedUrl = this.resolver.resolveLocal(resolvedOrPlain);
|
|
94
|
+
if (resolvedUrl) {
|
|
95
|
+
// resolve to the bare specifier if conditions are met
|
|
96
|
+
if (this.namedDefineRegistry.has(resolvedOrPlain)) {
|
|
97
|
+
const namedDefineRecord = this.namedDefineRegistry.get(resolvedOrPlain);
|
|
98
|
+
if (namedDefineRecord.external || namedDefineRecord.defined) {
|
|
99
|
+
const record = this.moduleRegistry.get(resolvedUrl);
|
|
100
|
+
if (!record || !this.aliases.has(resolvedOrPlain)) {
|
|
101
|
+
return resolvedOrPlain;
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
return resolvedUrl;
|
|
106
|
+
}
|
|
107
|
+
if (this.namedDefineRegistry.has(resolvedOrPlain)) {
|
|
108
|
+
return resolvedOrPlain;
|
|
109
|
+
}
|
|
110
|
+
try {
|
|
111
|
+
resolved = await this.resolver.resolve(resolvedOrPlain);
|
|
112
|
+
}
|
|
113
|
+
catch (e) {
|
|
114
|
+
// defer to error handling below for unresolved
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
if (!resolved || !isUrl(resolved)) {
|
|
118
|
+
if (this.namedDefineRegistry.has(id)) {
|
|
119
|
+
return id;
|
|
120
|
+
}
|
|
121
|
+
throw new LoaderError(UNRESOLVED, [id]);
|
|
122
|
+
}
|
|
123
|
+
if (importer && isUrl(resolved)) {
|
|
124
|
+
resolved += `?importer=${encodeURIComponent(importer)}`;
|
|
125
|
+
}
|
|
126
|
+
return resolved;
|
|
127
|
+
}
|
|
128
|
+
has(id) {
|
|
129
|
+
return this.moduleRegistry.has(id);
|
|
130
|
+
}
|
|
131
|
+
define(name, dependencies, exporter) {
|
|
132
|
+
const mod = this.namedDefineRegistry.get(name);
|
|
133
|
+
// Don't allow redefining a module.
|
|
134
|
+
if (mod && mod.defined) {
|
|
135
|
+
if (process.env.NODE_ENV !== 'production' && hasConsole) {
|
|
136
|
+
// eslint-disable-next-line lwr/no-unguarded-apis
|
|
137
|
+
console.warn(`Module redefine attempted: ${name}`);
|
|
138
|
+
}
|
|
139
|
+
this.lastDefine = mod;
|
|
140
|
+
return;
|
|
141
|
+
}
|
|
142
|
+
const moduleDef = {
|
|
143
|
+
name,
|
|
144
|
+
dependencies,
|
|
145
|
+
exporter,
|
|
146
|
+
defined: true,
|
|
147
|
+
};
|
|
148
|
+
if (mod && mod.external) {
|
|
149
|
+
// if module is "external", resolve the external promise to notify any dependees
|
|
150
|
+
mod.external.resolveExternal(moduleDef);
|
|
151
|
+
}
|
|
152
|
+
this.profiler.logOperationStart({ id: MODULE_DEFINE, specifier: name });
|
|
153
|
+
this.namedDefineRegistry.set(name, moduleDef);
|
|
154
|
+
this.lastDefine = moduleDef;
|
|
155
|
+
}
|
|
156
|
+
/**
|
|
157
|
+
* Marks modules as "externally" loaded/provided, so that the loader does not attempt to fetch them.
|
|
158
|
+
*
|
|
159
|
+
* @param modules - list of module identifiers
|
|
160
|
+
*/
|
|
161
|
+
registerExternalModules(modules) {
|
|
162
|
+
modules.map((id) => {
|
|
163
|
+
if (!this.namedDefineRegistry.has(id)) {
|
|
164
|
+
let resolveExternal;
|
|
165
|
+
let timer;
|
|
166
|
+
const moduleDefPromise = new Promise((resolve, reject) => {
|
|
167
|
+
resolveExternal = resolve;
|
|
168
|
+
// watch the external for timeout
|
|
169
|
+
// eslint-disable-next-line lwr/no-unguarded-apis, no-undef
|
|
170
|
+
timer = setTimeout(() => {
|
|
171
|
+
reject(new LoaderError(MODULE_LOAD_TIMEOUT, [id]));
|
|
172
|
+
}, MODULE_LOAD_TIMEOUT_TIMER);
|
|
173
|
+
}).finally(() => {
|
|
174
|
+
// eslint-disable-next-line lwr/no-unguarded-apis, no-undef
|
|
175
|
+
clearTimeout(timer);
|
|
176
|
+
});
|
|
177
|
+
const moduleDef = {
|
|
178
|
+
name: id,
|
|
179
|
+
defined: false,
|
|
180
|
+
external: {
|
|
181
|
+
resolveExternal,
|
|
182
|
+
moduleDefPromise,
|
|
183
|
+
},
|
|
184
|
+
};
|
|
185
|
+
this.namedDefineRegistry.set(id, moduleDef);
|
|
186
|
+
}
|
|
187
|
+
else if (process.env.NODE_ENV !== 'production' && hasConsole) {
|
|
188
|
+
// eslint-disable-next-line lwr/no-unguarded-apis
|
|
189
|
+
console.warn(MODULE_ALREADY_LOADED.message, id);
|
|
190
|
+
}
|
|
191
|
+
});
|
|
192
|
+
}
|
|
193
|
+
getImportMetadataResolver() {
|
|
194
|
+
return this.resolver;
|
|
195
|
+
}
|
|
196
|
+
// Returns an existing module record by the resolvedId or aliased id
|
|
197
|
+
getExistingModuleRecord(resolvedId, aliasId) {
|
|
198
|
+
const moduleRecord = this.moduleRegistry.get(resolvedId);
|
|
199
|
+
if (moduleRecord) {
|
|
200
|
+
this.storeModuleAlias(aliasId, resolvedId);
|
|
201
|
+
return moduleRecord;
|
|
202
|
+
}
|
|
203
|
+
// Check if this is a known alias
|
|
204
|
+
if (resolvedId !== aliasId) {
|
|
205
|
+
const alias = this.aliases.get(aliasId);
|
|
206
|
+
if (alias) {
|
|
207
|
+
const aliasedModule = this.moduleRegistry.get(alias);
|
|
208
|
+
if (aliasedModule) {
|
|
209
|
+
return aliasedModule;
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
return moduleRecord;
|
|
214
|
+
}
|
|
215
|
+
async getModuleRecord(resolvedId, id) {
|
|
216
|
+
// Look for an existing record
|
|
217
|
+
const existingRecord = this.getExistingModuleRecord(resolvedId, id);
|
|
218
|
+
if (existingRecord) {
|
|
219
|
+
// return existing
|
|
220
|
+
return existingRecord;
|
|
221
|
+
}
|
|
222
|
+
// Create a new Module Record
|
|
223
|
+
const instantiation = this.getModuleDef(resolvedId, id);
|
|
224
|
+
const dependencyRecords = instantiation.then((moduleDef) => {
|
|
225
|
+
const dependencies = moduleDef.dependencies || [];
|
|
226
|
+
// get dep and filter out exports
|
|
227
|
+
const filtered = dependencies
|
|
228
|
+
.map((dep) => {
|
|
229
|
+
if (dep === 'exports') {
|
|
230
|
+
return;
|
|
231
|
+
}
|
|
232
|
+
invariant(dep !== 'require', NO_AMD_REQUIRE);
|
|
233
|
+
return this.getModuleDependencyRecord.call(this, dep);
|
|
234
|
+
})
|
|
235
|
+
.filter((depRecord) => depRecord !== undefined);
|
|
236
|
+
return Promise.all(filtered);
|
|
237
|
+
});
|
|
238
|
+
const newModuleRecord = {
|
|
239
|
+
id: resolvedId,
|
|
240
|
+
module: Object.create(null),
|
|
241
|
+
dependencyRecords,
|
|
242
|
+
instantiation,
|
|
243
|
+
evaluated: false,
|
|
244
|
+
evaluationPromise: null,
|
|
245
|
+
};
|
|
246
|
+
this.moduleRegistry.set(resolvedId, newModuleRecord);
|
|
247
|
+
this.storeModuleAlias(id, resolvedId);
|
|
248
|
+
// Wait for the dependencies to resolve the return the moduleRecord
|
|
249
|
+
return dependencyRecords.then(() => newModuleRecord);
|
|
250
|
+
}
|
|
251
|
+
storeModuleAlias(aliasId, resolvedId) {
|
|
252
|
+
if (aliasId !== resolvedId) {
|
|
253
|
+
if (!this.aliases.has(aliasId)) {
|
|
254
|
+
this.aliases.set(aliasId, resolvedId);
|
|
255
|
+
}
|
|
256
|
+
else if (process.env.NODE_ENV !== 'production' && hasConsole) {
|
|
257
|
+
// Warn the user if they were not aliasing to the resolvedId
|
|
258
|
+
const currentResolvedId = this.aliases.get(aliasId);
|
|
259
|
+
if (currentResolvedId !== resolvedId) {
|
|
260
|
+
// eslint-disable-next-line lwr/no-unguarded-apis, no-undef
|
|
261
|
+
if (process.env.NODE_ENV !== 'production' && hasConsole) {
|
|
262
|
+
// eslint-disable-next-line lwr/no-unguarded-apis, no-undef
|
|
263
|
+
console.warn(`Alias update attempt: ${aliasId}=>${currentResolvedId}, ${resolvedId}`);
|
|
264
|
+
}
|
|
265
|
+
}
|
|
266
|
+
}
|
|
267
|
+
}
|
|
268
|
+
}
|
|
269
|
+
async getModuleDependencyRecord(dependency) {
|
|
270
|
+
const resolvedDepId = await this.resolve(dependency);
|
|
271
|
+
return this.getModuleRecord(resolvedDepId, dependency);
|
|
272
|
+
}
|
|
273
|
+
// execute the "top-level code" (the code outside of functions) of a module
|
|
274
|
+
async topLevelEvaluation(moduleRecord) {
|
|
275
|
+
await this.instantiateAll(moduleRecord, {});
|
|
276
|
+
return this.evaluateModule(moduleRecord, {});
|
|
277
|
+
}
|
|
278
|
+
// Returns a promise when a module and all of it's dependencies have finished instantiation
|
|
279
|
+
async instantiateAll(moduleRecord, instantiatedMap) {
|
|
280
|
+
if (!instantiatedMap[moduleRecord.id]) {
|
|
281
|
+
instantiatedMap[moduleRecord.id] = true;
|
|
282
|
+
const dependencyModuleRecords = await moduleRecord.dependencyRecords;
|
|
283
|
+
if (dependencyModuleRecords) {
|
|
284
|
+
for (let i = 0; i < dependencyModuleRecords.length; i++) {
|
|
285
|
+
const depRecord = dependencyModuleRecords[i];
|
|
286
|
+
// eslint-disable-next-line no-await-in-loop
|
|
287
|
+
await this.instantiateAll(depRecord, instantiatedMap);
|
|
288
|
+
}
|
|
289
|
+
}
|
|
290
|
+
}
|
|
291
|
+
}
|
|
292
|
+
async evaluateModule(moduleRecord, evaluationMap) {
|
|
293
|
+
const dependencyModuleRecords = await moduleRecord.dependencyRecords;
|
|
294
|
+
if (dependencyModuleRecords.length > 0) {
|
|
295
|
+
evaluationMap[moduleRecord.id] = true;
|
|
296
|
+
// evaluate dependencies first
|
|
297
|
+
await this.evaluateModuleDependencies(dependencyModuleRecords, evaluationMap);
|
|
298
|
+
}
|
|
299
|
+
const { exporter, dependencies } = await moduleRecord.instantiation;
|
|
300
|
+
// The exports object automatically gets filled in by the exporter evaluation
|
|
301
|
+
const exports = {};
|
|
302
|
+
const depsMapped = dependencies
|
|
303
|
+
? await Promise.all(dependencies.map(async (dep) => {
|
|
304
|
+
if (dep === 'exports') {
|
|
305
|
+
return exports;
|
|
306
|
+
}
|
|
307
|
+
const resolvedDepId = await this.resolve(dep);
|
|
308
|
+
const moduleRecord = this.moduleRegistry.get(resolvedDepId);
|
|
309
|
+
if (!moduleRecord) {
|
|
310
|
+
throw new LoaderError(FAILED_DEP, [resolvedDepId]);
|
|
311
|
+
}
|
|
312
|
+
const module = moduleRecord.module;
|
|
313
|
+
/**
|
|
314
|
+
* Circular dependencies are handled properly when named exports are used,
|
|
315
|
+
* however, for default exports there is a bug: https://github.com/rollup/rollup/issues/3384
|
|
316
|
+
*
|
|
317
|
+
* The workaround below applies for circular dependencies (!moduleRecord.evaluated)
|
|
318
|
+
*/
|
|
319
|
+
if (!moduleRecord.evaluated) {
|
|
320
|
+
return this.getCircularDependencyWrapper(module);
|
|
321
|
+
}
|
|
322
|
+
if (module) {
|
|
323
|
+
return module.__defaultInterop ? module.default : module;
|
|
324
|
+
}
|
|
325
|
+
throw new LoaderError(FAILED_DEP, [resolvedDepId]);
|
|
326
|
+
}))
|
|
327
|
+
: [];
|
|
328
|
+
// 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
|
|
329
|
+
if (moduleRecord.evaluated) {
|
|
330
|
+
return moduleRecord.module;
|
|
331
|
+
}
|
|
332
|
+
// evaluates the module function
|
|
333
|
+
let moduleDefault;
|
|
334
|
+
try {
|
|
335
|
+
moduleDefault = exporter(...depsMapped);
|
|
336
|
+
}
|
|
337
|
+
catch (e) {
|
|
338
|
+
throw new LoaderError(EXPORTER_ERROR, [moduleRecord.id, e.message || e]);
|
|
339
|
+
}
|
|
340
|
+
// value is returned from exporter, then we are not using named exports
|
|
341
|
+
if (moduleDefault !== undefined) {
|
|
342
|
+
moduleDefault = { default: moduleDefault };
|
|
343
|
+
// __defaultInterop is ONLY used to support backwards compatibility
|
|
344
|
+
// of importing default exports the "wrong" way (when not using named exports).
|
|
345
|
+
// See https://github.com/salesforce-experience-platform-emu/lwr/pull/816
|
|
346
|
+
Object.defineProperty(moduleDefault, '__defaultInterop', { value: true });
|
|
347
|
+
}
|
|
348
|
+
// if no return value, then we are using the exports object
|
|
349
|
+
else {
|
|
350
|
+
// handle only default export with Rollup forced named exports
|
|
351
|
+
if (this.isNamedExportDefaultOnly(exports)) {
|
|
352
|
+
Object.defineProperty(exports, '__useDefault', { value: true });
|
|
353
|
+
}
|
|
354
|
+
}
|
|
355
|
+
const moduleExports = moduleDefault || exports;
|
|
356
|
+
// update the module record
|
|
357
|
+
// copy over enumerable public methods to module
|
|
358
|
+
for (const key in moduleExports) {
|
|
359
|
+
Object.defineProperty(moduleRecord.module, key, {
|
|
360
|
+
enumerable: true,
|
|
361
|
+
set(value) {
|
|
362
|
+
moduleExports[key] = value;
|
|
363
|
+
},
|
|
364
|
+
get() {
|
|
365
|
+
return moduleExports[key];
|
|
366
|
+
},
|
|
367
|
+
});
|
|
368
|
+
}
|
|
369
|
+
// copy non-enumerable to module
|
|
370
|
+
if (moduleExports.__useDefault) {
|
|
371
|
+
Object.defineProperty(moduleRecord.module, '__useDefault', { value: true });
|
|
372
|
+
}
|
|
373
|
+
if (moduleExports.__defaultInterop) {
|
|
374
|
+
Object.defineProperty(moduleRecord.module, '__defaultInterop', { value: true });
|
|
375
|
+
}
|
|
376
|
+
if (moduleExports.__esModule) {
|
|
377
|
+
Object.defineProperty(moduleRecord.module, '__esModule', { value: true });
|
|
378
|
+
}
|
|
379
|
+
moduleRecord.evaluated = true;
|
|
380
|
+
Object.freeze(moduleRecord.module);
|
|
381
|
+
return moduleRecord.module;
|
|
382
|
+
}
|
|
383
|
+
// Determines if named exports module has only default export
|
|
384
|
+
isNamedExportDefaultOnly(exports) {
|
|
385
|
+
return (exports !== undefined &&
|
|
386
|
+
Object.getOwnPropertyNames(exports).length === 2 &&
|
|
387
|
+
Object.prototype.hasOwnProperty.call(exports, 'default') &&
|
|
388
|
+
Object.prototype.hasOwnProperty.call(exports, '__esModule'));
|
|
389
|
+
}
|
|
390
|
+
// Wrap the dependency in a function that can be called and detected by __circular__ property.
|
|
391
|
+
// The LWC engine checks for __circular__ to detect circular dependencies.
|
|
392
|
+
getCircularDependencyWrapper(module) {
|
|
393
|
+
const tmp = () => {
|
|
394
|
+
return module.__useDefault || module.__defaultInterop ? module.default : module;
|
|
395
|
+
};
|
|
396
|
+
tmp.__circular__ = true;
|
|
397
|
+
return tmp;
|
|
398
|
+
}
|
|
399
|
+
async evaluateModuleDependencies(dependencyModuleRecords, evaluationMap) {
|
|
400
|
+
for (let i = 0; i < dependencyModuleRecords.length; i++) {
|
|
401
|
+
const depRecord = dependencyModuleRecords[i];
|
|
402
|
+
if (!depRecord.evaluated && !evaluationMap[depRecord.id]) {
|
|
403
|
+
evaluationMap[depRecord.id] = true;
|
|
404
|
+
// eslint-disable-next-line no-await-in-loop
|
|
405
|
+
await this.evaluateModule(depRecord, evaluationMap);
|
|
406
|
+
}
|
|
407
|
+
}
|
|
408
|
+
}
|
|
409
|
+
async getModuleDef(resolvedId, originalId) {
|
|
410
|
+
// reset lastDefine
|
|
411
|
+
this.lastDefine = undefined;
|
|
412
|
+
// the module name can be the resolved ID or the original ID if neither are URL's.
|
|
413
|
+
const moduleName = !isUrl(resolvedId)
|
|
414
|
+
? resolvedId
|
|
415
|
+
: originalId !== resolvedId
|
|
416
|
+
? originalId
|
|
417
|
+
: undefined;
|
|
418
|
+
let moduleDef = moduleName && this.namedDefineRegistry.get(moduleName);
|
|
419
|
+
if (moduleDef && moduleDef.external) {
|
|
420
|
+
return moduleDef.external.moduleDefPromise;
|
|
421
|
+
}
|
|
422
|
+
if (moduleDef && moduleDef.defined) {
|
|
423
|
+
return moduleDef;
|
|
424
|
+
}
|
|
425
|
+
const parentUrl = this.resolver.getBaseUrl(); // only support baseUrl for now
|
|
426
|
+
const specifier = moduleName || originalId;
|
|
427
|
+
this.profiler.logOperationStart({ id: MODULE_FETCH, specifier });
|
|
428
|
+
return Promise.resolve()
|
|
429
|
+
.then(async () => {
|
|
430
|
+
const loadHooks = this.loadHook;
|
|
431
|
+
if (loadHooks) {
|
|
432
|
+
for (let i = 0; i < loadHooks.length; i++) {
|
|
433
|
+
const loadHook = loadHooks[i];
|
|
434
|
+
const response = loadHook(resolvedId, parentUrl);
|
|
435
|
+
const result = (isResponseAPromise(response)
|
|
436
|
+
? // eslint-disable-next-line no-await-in-loop
|
|
437
|
+
await evaluateLoadHook(resolvedId, response)
|
|
438
|
+
: response);
|
|
439
|
+
if (result === undefined) {
|
|
440
|
+
throw new LoaderError(INVALID_LOADER_SERVICE_RESPONSE);
|
|
441
|
+
}
|
|
442
|
+
if (result && result !== null) {
|
|
443
|
+
return evaluateLoadHookResponse(result, resolvedId);
|
|
444
|
+
}
|
|
445
|
+
}
|
|
446
|
+
}
|
|
447
|
+
return false;
|
|
448
|
+
})
|
|
449
|
+
.then((result) => {
|
|
450
|
+
if (result !== true && hasDocument) {
|
|
451
|
+
return loadModuleDef(resolvedId);
|
|
452
|
+
}
|
|
453
|
+
})
|
|
454
|
+
.then(() => {
|
|
455
|
+
// Attempt to retrieve the module definition by name first
|
|
456
|
+
moduleDef = moduleName && this.namedDefineRegistry.get(moduleName);
|
|
457
|
+
// Fallback to the last loader.define call
|
|
458
|
+
if (!moduleDef) {
|
|
459
|
+
moduleDef = this.lastDefine;
|
|
460
|
+
}
|
|
461
|
+
// This should not happen
|
|
462
|
+
if (!moduleDef) {
|
|
463
|
+
throw new LoaderError(FAIL_INSTANTIATE, [resolvedId]);
|
|
464
|
+
}
|
|
465
|
+
this.profiler.logOperationEnd({ id: MODULE_FETCH, specifier });
|
|
466
|
+
return moduleDef;
|
|
467
|
+
})
|
|
468
|
+
.catch((e) => {
|
|
469
|
+
// Create module error marks for all errors caused by the loader
|
|
470
|
+
// Note: these marks do not include errors caused by invalid server responses or loader hooks
|
|
471
|
+
if (!(e instanceof LoaderError)) {
|
|
472
|
+
this.profiler.logOperationStart({ id: MODULE_ERROR, specifier });
|
|
473
|
+
}
|
|
474
|
+
throw e;
|
|
475
|
+
});
|
|
476
|
+
}
|
|
477
|
+
addLoaderPlugin(hooks) {
|
|
478
|
+
if (typeof hooks !== 'object') {
|
|
479
|
+
throw new LoaderError(INVALID_HOOK);
|
|
480
|
+
}
|
|
481
|
+
const { loadModule: loadHook, resolveModule: resolveHook, loadMapping } = hooks;
|
|
482
|
+
if (resolveHook) {
|
|
483
|
+
if (this.resolveHook) {
|
|
484
|
+
this.resolveHook.push(resolveHook);
|
|
485
|
+
}
|
|
486
|
+
else {
|
|
487
|
+
this.resolveHook = [resolveHook];
|
|
488
|
+
}
|
|
489
|
+
}
|
|
490
|
+
if (loadHook) {
|
|
491
|
+
if (this.loadHook) {
|
|
492
|
+
this.loadHook.push(loadHook);
|
|
493
|
+
}
|
|
494
|
+
else {
|
|
495
|
+
this.loadHook = [loadHook];
|
|
496
|
+
}
|
|
497
|
+
}
|
|
498
|
+
if (loadMapping) {
|
|
499
|
+
this.resolver.addLoadMappingHook(loadMapping);
|
|
500
|
+
}
|
|
501
|
+
}
|
|
502
|
+
importMetadataInvalidationCallback({ name, oldUrl, newUrl }) {
|
|
503
|
+
const handleStaleModuleHooks = this.handleStaleModuleHook;
|
|
504
|
+
if (handleStaleModuleHooks) {
|
|
505
|
+
evaluateHandleStaleModuleHooks(handleStaleModuleHooks, {
|
|
506
|
+
name,
|
|
507
|
+
oldUrl,
|
|
508
|
+
newUrl,
|
|
509
|
+
});
|
|
510
|
+
}
|
|
511
|
+
else {
|
|
512
|
+
if (process.env.NODE_ENV !== 'production' && hasConsole) {
|
|
513
|
+
// eslint-disable-next-line lwr/no-unguarded-apis, no-undef
|
|
514
|
+
console.warn(`stale module detected ${name}, current URL:${oldUrl}, new URL:${newUrl}`);
|
|
515
|
+
}
|
|
516
|
+
}
|
|
517
|
+
}
|
|
518
|
+
registerHandleStaleModuleHook(handleStaleModule) {
|
|
519
|
+
if (this.handleStaleModuleHook) {
|
|
520
|
+
this.handleStaleModuleHook.push(handleStaleModule);
|
|
521
|
+
}
|
|
522
|
+
else {
|
|
523
|
+
this.handleStaleModuleHook = [handleStaleModule];
|
|
524
|
+
}
|
|
525
|
+
}
|
|
526
|
+
isValidResolveResponse(res) {
|
|
527
|
+
return (res === null || typeof res === 'string' || (res && typeof res.url === 'string'));
|
|
528
|
+
}
|
|
529
|
+
}
|
|
530
|
+
//# sourceMappingURL=moduleRegistry.js.map
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { LoaderError, FAIL_LOAD } from '../errors/messages.js';
|
|
2
|
+
import { hasDocument } from '../utils/dom.js';
|
|
3
|
+
function createScript(url) {
|
|
4
|
+
// eslint-disable-next-line lwr/no-unguarded-apis, no-undef
|
|
5
|
+
const script = document.createElement('script');
|
|
6
|
+
script.async = true;
|
|
7
|
+
script.crossOrigin = 'anonymous';
|
|
8
|
+
script.src = url;
|
|
9
|
+
return script;
|
|
10
|
+
}
|
|
11
|
+
let lastWindowError, lastWindowErrorUrl;
|
|
12
|
+
function loadModuleDef(url) {
|
|
13
|
+
return new Promise(function (resolve, reject) {
|
|
14
|
+
if (hasDocument) {
|
|
15
|
+
/* eslint-disable lwr/no-unguarded-apis, no-undef */
|
|
16
|
+
const script = createScript(url);
|
|
17
|
+
script.addEventListener('error', () => {
|
|
18
|
+
reject(new LoaderError(FAIL_LOAD, [url]));
|
|
19
|
+
});
|
|
20
|
+
script.addEventListener('load', () => {
|
|
21
|
+
document.head.removeChild(script);
|
|
22
|
+
if (lastWindowErrorUrl === url) {
|
|
23
|
+
reject(lastWindowError);
|
|
24
|
+
}
|
|
25
|
+
else {
|
|
26
|
+
resolve();
|
|
27
|
+
}
|
|
28
|
+
});
|
|
29
|
+
document.head.appendChild(script);
|
|
30
|
+
/* eslint-enable lwr/no-unguarded-apis, no-undef */
|
|
31
|
+
}
|
|
32
|
+
});
|
|
33
|
+
}
|
|
34
|
+
if (hasDocument) {
|
|
35
|
+
// When a script is executed, runtime errors are on the global/window scope which are NOT caught by the script's onerror handler.
|
|
36
|
+
// eslint-disable-next-line lwr/no-unguarded-apis, no-undef
|
|
37
|
+
window.addEventListener('error', (evt) => {
|
|
38
|
+
lastWindowErrorUrl = evt.filename;
|
|
39
|
+
lastWindowError = evt.error;
|
|
40
|
+
});
|
|
41
|
+
}
|
|
42
|
+
export { loadModuleDef };
|
|
43
|
+
//# sourceMappingURL=scriptLoad.js.map
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
/* eslint-disable lwr/no-unguarded-apis */
|
|
2
|
+
export const hasDocument = typeof document !== 'undefined';
|
|
3
|
+
export const hasSetTimeout = typeof setTimeout === 'function';
|
|
4
|
+
export const hasConsole = typeof console !== 'undefined';
|
|
5
|
+
/* eslint-enable lwr/no-unguarded-apis */
|
|
6
|
+
//# sourceMappingURL=dom.js.map
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
export declare function getBaseUrl(): string | undefined;
|
|
2
|
+
/**
|
|
3
|
+
* Check if a string is a URL based on Common Internet Scheme Syntax
|
|
4
|
+
* https://www.ietf.org/rfc/rfc1738.txt
|
|
5
|
+
*
|
|
6
|
+
* URL Format:
|
|
7
|
+
* <scheme>:<scheme-specific-part>
|
|
8
|
+
* Common Internet Scheme Syntax:
|
|
9
|
+
* The scheme specific part starts with a double slash('//')
|
|
10
|
+
*
|
|
11
|
+
* A valid URL has a colon that is followed by a double slash.
|
|
12
|
+
*
|
|
13
|
+
* @param url - the url that is being checked
|
|
14
|
+
* @returns boolean
|
|
15
|
+
*
|
|
16
|
+
* @example Valid URLs
|
|
17
|
+
* 'https://salesforce.com'
|
|
18
|
+
* 'http://localhost:3000'
|
|
19
|
+
*
|
|
20
|
+
* @example Invalid URLs
|
|
21
|
+
* 'salesforce.com'
|
|
22
|
+
* 'localhost:3000'
|
|
23
|
+
* '@salesforce/label/type:namespace:name'
|
|
24
|
+
*/
|
|
25
|
+
export declare function isUrl(url: string): boolean;
|
|
26
|
+
export declare function resolveIfNotPlainOrUrl(relUrl: string, parentUrl: string): string | undefined;
|
|
27
|
+
export declare function resolveUrl(relUrl: string, parentUrl: string): string | undefined;
|
|
28
|
+
//# sourceMappingURL=url.d.ts.map
|