@lwrjs/loader 0.12.0-alpha.9 → 0.12.1

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.
@@ -4,7 +4,7 @@
4
4
  * SPDX-License-Identifier: MIT
5
5
  * For full license text, see the LICENSE file in the repo root or https://opensource.org/licenses/MIT
6
6
  */
7
- /* LWR Module Loader v0.12.0-alpha.9 */
7
+ /* LWR Module Loader v0.12.1 */
8
8
  const templateRegex = /\{([0-9]+)\}/g;
9
9
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
10
10
  function templateString(template, args) {
@@ -646,7 +646,7 @@ try {
646
646
  // swallow
647
647
  }
648
648
  const trusted = createPolicy('trusted', policyOptions);
649
- /*! version: 0.21.0 */
649
+ /*! version: 0.21.4 */
650
650
 
651
651
  /* global console,process */
652
652
 
@@ -798,22 +798,13 @@ async function evaluateLoadHook(
798
798
 
799
799
 
800
800
 
801
+
802
+
801
803
 
802
804
 
803
805
 
804
806
  class ModuleRegistry {
805
807
 
806
-
807
- // A registry for named AMD defines containing the *metadata* of AMD module
808
- __init() {this.namedDefineRegistry = new Map();}
809
- // The evaluated module registry where the module identifier (name or URL?) is the key
810
- __init2() {this.moduleRegistry = new Map();}
811
- // Aliases of modules in the registry
812
- __init3() {this.aliases = new Map();}
813
-
814
-
815
-
816
-
817
808
 
818
809
  constructor(config) {ModuleRegistry.prototype.__init.call(this);ModuleRegistry.prototype.__init2.call(this);ModuleRegistry.prototype.__init3.call(this);
819
810
  this.profiler = config.profiler;
@@ -823,9 +814,6 @@ class ModuleRegistry {
823
814
  );
824
815
  }
825
816
 
826
- /**
827
- * Module import
828
- */
829
817
  async load(id, importer) {
830
818
  const metadata = importer ? { importer } : {};
831
819
  this.profiler.logOperationStart({
@@ -833,23 +821,18 @@ class ModuleRegistry {
833
821
  specifier: id,
834
822
  metadata,
835
823
  });
836
-
837
824
  const resolvedId = await this.resolve(id, importer);
838
- const moduleRecord = this.getModuleRecord(resolvedId, id);
839
-
825
+ const moduleRecord = await this.getModuleRecord(resolvedId, id);
840
826
  if (moduleRecord.evaluated) {
841
827
  return moduleRecord.module;
842
828
  } else {
843
829
  if (!moduleRecord.evaluationPromise) {
844
- moduleRecord.evaluationPromise = this.evaluateModule(moduleRecord, {});
830
+ moduleRecord.evaluationPromise = this.topLevelEvaluation(moduleRecord);
845
831
  }
846
832
  return moduleRecord.evaluationPromise;
847
833
  }
848
834
  }
849
835
 
850
- /**
851
- * Resolve id for a module
852
- */
853
836
  async resolve(id, importer) {
854
837
  const parentUrl = this.resolver.getBaseUrl(); // only support baseUrl for now
855
838
 
@@ -865,7 +848,7 @@ class ModuleRegistry {
865
848
  // eslint-disable-next-line no-await-in-loop
866
849
  result = isResponseAPromise(response) ? await response : response;
867
850
  }
868
- if (!isValidResolveResponse(result)) {
851
+ if (!this.isValidResolveResponse(result)) {
869
852
  throw new LoaderError(INVALID_LOADER_SERVICE_RESPONSE);
870
853
  }
871
854
 
@@ -951,9 +934,6 @@ class ModuleRegistry {
951
934
  return this.moduleRegistry.has(id);
952
935
  }
953
936
 
954
- /**
955
- * Module entry point LWR.define()
956
- */
957
937
  define(name, dependencies, exporter) {
958
938
  const mod = this.namedDefineRegistry.get(name);
959
939
  // Don't allow redefining a module.
@@ -1020,6 +1000,19 @@ class ModuleRegistry {
1020
1000
  });
1021
1001
  }
1022
1002
 
1003
+
1004
+
1005
+ // A registry for named AMD defines containing the *metadata* of AMD module
1006
+ __init() {this.namedDefineRegistry = new Map();}
1007
+
1008
+ // The evaluated module registry where the module identifier (name or URL?) is the key
1009
+ __init2() {this.moduleRegistry = new Map();}
1010
+
1011
+ // Aliases of modules in the registry
1012
+ __init3() {this.aliases = new Map();}
1013
+
1014
+
1015
+
1023
1016
  getImportMetadataResolver() {
1024
1017
  return this.resolver;
1025
1018
  }
@@ -1045,7 +1038,7 @@ class ModuleRegistry {
1045
1038
  return moduleRecord;
1046
1039
  }
1047
1040
 
1048
- getModuleRecord(resolvedId, id) {
1041
+ async getModuleRecord(resolvedId, id) {
1049
1042
  // Look for an existing record
1050
1043
  const existingRecord = this.getExistingModuleRecord(resolvedId, id);
1051
1044
  if (existingRecord) {
@@ -1053,10 +1046,29 @@ class ModuleRegistry {
1053
1046
  return existingRecord;
1054
1047
  }
1055
1048
 
1049
+ // Create a new Module Record
1050
+ const instantiation = this.getModuleDef(resolvedId, id);
1051
+ const dependencyRecords = instantiation.then((moduleDef) => {
1052
+ const dependencies = moduleDef.dependencies || [];
1053
+ // get dep and filter out exports
1054
+ const filtered = dependencies
1055
+ .map((dep) => {
1056
+ if (dep === 'exports') {
1057
+ return;
1058
+ }
1059
+ invariant(dep !== 'require', NO_AMD_REQUIRE);
1060
+ return this.getModuleDependencyRecord.call(this, dep);
1061
+ })
1062
+ .filter((depRecord) => depRecord !== undefined) ;
1063
+
1064
+ return Promise.all(filtered);
1065
+ });
1066
+
1056
1067
  const newModuleRecord = {
1057
1068
  id: resolvedId,
1058
1069
  module: Object.create(null),
1059
- instantiation: this.getModuleDef(resolvedId, id),
1070
+ dependencyRecords,
1071
+ instantiation,
1060
1072
  evaluated: false,
1061
1073
  evaluationPromise: null,
1062
1074
  };
@@ -1064,7 +1076,8 @@ class ModuleRegistry {
1064
1076
  this.moduleRegistry.set(resolvedId, newModuleRecord);
1065
1077
  this.storeModuleAlias(id, resolvedId);
1066
1078
 
1067
- return newModuleRecord;
1079
+ // Wait for the dependencies to resolve the return the moduleRecord
1080
+ return dependencyRecords.then(() => newModuleRecord);
1068
1081
  }
1069
1082
 
1070
1083
  storeModuleAlias(aliasId, resolvedId) {
@@ -1085,87 +1098,95 @@ class ModuleRegistry {
1085
1098
  }
1086
1099
  }
1087
1100
 
1088
- /**
1089
- * Evaluate all module dependencies
1090
- */
1091
- async evaluateDependencies(
1092
- dependencies,
1093
- evaluationMap,
1094
- ) {
1095
- const exports = {};
1096
- const promiseArray = [];
1097
-
1098
- if (dependencies) {
1099
- for (const dep of dependencies) {
1100
- if (dep === 'exports') {
1101
- promiseArray.push(Promise.resolve(exports));
1102
- } else {
1103
- invariant(dep !== 'require', NO_AMD_REQUIRE);
1104
- promiseArray.push(this.evaluateDependent(dep, evaluationMap));
1105
- }
1106
- }
1107
- }
1108
-
1109
- return Promise.all(promiseArray).then((results) => {
1110
- const depsMapped = results.filter((result) => result !== undefined);
1111
- return { depsMapped, exports };
1112
- });
1101
+ async getModuleDependencyRecord(dependency) {
1102
+ const resolvedDepId = await this.resolve(dependency);
1103
+ return this.getModuleRecord(resolvedDepId, dependency);
1113
1104
  }
1114
1105
 
1115
- async evaluateDependent(dep, evaluationMap) {
1116
- const resolvedDepId = await this.resolve(dep);
1117
-
1118
- const depModuleRecord = this.getModuleRecord(resolvedDepId, dep);
1119
- let module = depModuleRecord.module;
1120
-
1121
- const handleReturn = (module) => {
1122
- if (module) {
1123
- return module.__defaultInterop ? module.default : module;
1124
- }
1125
- throw new LoaderError(FAILED_DEP, [resolvedDepId]);
1126
- };
1106
+ // execute the "top-level code" (the code outside of functions) of a module
1107
+ async topLevelEvaluation(moduleRecord) {
1108
+ await this.instantiateAll(moduleRecord, {});
1109
+ return this.evaluateModule(moduleRecord, {});
1110
+ }
1127
1111
 
1128
- // If evaluated return the module
1129
- if (depModuleRecord.evaluated) {
1130
- return handleReturn(module);
1131
- }
1132
- /**
1133
- * Circular dependencies are handled properly when named exports are used,
1134
- * however, for default exports there is a bug: https://github.com/rollup/rollup/issues/3384
1135
- *
1136
- * The workaround below applies for circular dependencies (!moduleRecord.evaluated)
1137
- */
1138
- if (!evaluationMap[depModuleRecord.id]) {
1139
- // If we have not started dependency evaluation kick it off
1140
- if (!depModuleRecord.evaluationPromise) {
1141
- depModuleRecord.evaluationPromise = this.evaluateModule(depModuleRecord, evaluationMap);
1112
+ // Returns a promise when a module and all of it's dependencies have finished instantiation
1113
+ async instantiateAll(
1114
+ moduleRecord,
1115
+ instantiatedMap,
1116
+ ) {
1117
+ if (!instantiatedMap[moduleRecord.id]) {
1118
+ instantiatedMap[moduleRecord.id] = true;
1119
+ const dependencyModuleRecords = await moduleRecord.dependencyRecords;
1120
+ if (dependencyModuleRecords) {
1121
+ for (let i = 0; i < dependencyModuleRecords.length; i++) {
1122
+ const depRecord = dependencyModuleRecords[i];
1123
+ // eslint-disable-next-line no-await-in-loop
1124
+ await this.instantiateAll(depRecord, instantiatedMap);
1125
+ }
1142
1126
  }
1143
- return depModuleRecord.evaluationPromise.then((module) => {
1144
- return handleReturn(module);
1145
- });
1146
- } else {
1147
- // Otherwise return a dummy circular module wrapper
1148
- module = getCircularDependencyWrapper(module);
1149
1127
  }
1150
- return handleReturn(module);
1151
1128
  }
1152
1129
 
1153
1130
  async evaluateModule(
1154
1131
  moduleRecord,
1155
1132
  evaluationMap,
1156
1133
  ) {
1157
- // Create a evaluationMap to detect cycles in this dep chain
1158
- const chainMap = { ...evaluationMap };
1159
- chainMap[moduleRecord.id] = true;
1134
+ const dependencyModuleRecords = await moduleRecord.dependencyRecords;
1135
+ if (dependencyModuleRecords.length > 0) {
1136
+ evaluationMap[moduleRecord.id] = true;
1137
+ // evaluate dependencies first
1138
+ await this.evaluateModuleDependencies(dependencyModuleRecords, evaluationMap);
1139
+ }
1160
1140
 
1161
- // Wait for load to finish
1162
1141
  const { exporter, dependencies } = await moduleRecord.instantiation;
1163
-
1164
- // Evaluate all it's dependents
1165
- const { depsMapped, exports } = await this.evaluateDependencies(dependencies, chainMap);
1142
+ // The exports object automatically gets filled in by the exporter evaluation
1143
+ const exports = {};
1144
+ const depsMapped = dependencies
1145
+ ? await Promise.all(
1146
+ dependencies.map(async (dep) => {
1147
+ if (dep === 'exports') {
1148
+ return exports;
1149
+ }
1150
+ const resolvedDepId = await this.resolve(dep);
1151
+
1152
+ const moduleRecord = this.moduleRegistry.get(resolvedDepId) ;
1153
+ if (!moduleRecord) {
1154
+ throw new LoaderError(FAILED_DEP, [resolvedDepId]);
1155
+ }
1156
+
1157
+ const module = moduleRecord.module;
1158
+
1159
+ /**
1160
+ * Circular dependencies are handled properly when named exports are used,
1161
+ * however, for default exports there is a bug: https://github.com/rollup/rollup/issues/3384
1162
+ *
1163
+ * The workaround below applies for circular dependencies (!moduleRecord.evaluated)
1164
+ */
1165
+ if (!moduleRecord.evaluated) {
1166
+ return this.getCircularDependencyWrapper(module);
1167
+ }
1168
+
1169
+ if (module) {
1170
+ return module.__defaultInterop ? module.default : module;
1171
+ }
1172
+
1173
+ throw new LoaderError(FAILED_DEP, [resolvedDepId]);
1174
+ }),
1175
+ )
1176
+ : [];
1177
+
1178
+ // 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
1179
+ if (moduleRecord.evaluated) {
1180
+ return moduleRecord.module;
1181
+ }
1166
1182
 
1167
1183
  // evaluates the module function
1168
- let moduleDefault = this.evaluateModuleCode(exporter, depsMapped, moduleRecord);
1184
+ let moduleDefault;
1185
+ try {
1186
+ moduleDefault = exporter(...depsMapped);
1187
+ } catch (e) {
1188
+ throw new LoaderError(EXPORTER_ERROR, [moduleRecord.id, e.message || e]);
1189
+ }
1169
1190
  // value is returned from exporter, then we are not using named exports
1170
1191
  if (moduleDefault !== undefined) {
1171
1192
  moduleDefault = { default: moduleDefault };
@@ -1177,7 +1198,7 @@ class ModuleRegistry {
1177
1198
  // if no return value, then we are using the exports object
1178
1199
  else {
1179
1200
  // handle only default export with Rollup forced named exports
1180
- if (isNamedExportDefaultOnly(exports)) {
1201
+ if (this.isNamedExportDefaultOnly(exports)) {
1181
1202
  Object.defineProperty(exports, '__useDefault', { value: true });
1182
1203
  }
1183
1204
  }
@@ -1209,17 +1230,42 @@ class ModuleRegistry {
1209
1230
  Object.defineProperty(moduleRecord.module, '__esModule', { value: true });
1210
1231
  }
1211
1232
 
1212
- Object.freeze(moduleRecord.module);
1213
1233
  moduleRecord.evaluated = true;
1214
- moduleRecord.evaluationPromise = null;
1234
+ Object.freeze(moduleRecord.module);
1215
1235
  return moduleRecord.module;
1216
1236
  }
1217
1237
 
1218
- evaluateModuleCode(evaluatedExporter, depsMapped, moduleRecord) {
1219
- try {
1220
- return evaluatedExporter(...depsMapped);
1221
- } catch (e) {
1222
- throw new LoaderError(EXPORTER_ERROR, [moduleRecord.id, e.message || e]);
1238
+ // Determines if named exports module has only default export
1239
+ isNamedExportDefaultOnly(exports) {
1240
+ return (
1241
+ exports !== undefined &&
1242
+ Object.getOwnPropertyNames(exports).length === 2 &&
1243
+ Object.prototype.hasOwnProperty.call(exports, 'default') &&
1244
+ Object.prototype.hasOwnProperty.call(exports, '__esModule')
1245
+ );
1246
+ }
1247
+
1248
+ // Wrap the dependency in a function that can be called and detected by __circular__ property.
1249
+ // The LWC engine checks for __circular__ to detect circular dependencies.
1250
+ getCircularDependencyWrapper(module) {
1251
+ const tmp = () => {
1252
+ return module.__useDefault || module.__defaultInterop ? module.default : module;
1253
+ };
1254
+ tmp.__circular__ = true;
1255
+ return tmp;
1256
+ }
1257
+
1258
+ async evaluateModuleDependencies(
1259
+ dependencyModuleRecords,
1260
+ evaluationMap,
1261
+ ) {
1262
+ for (let i = 0; i < dependencyModuleRecords.length; i++) {
1263
+ const depRecord = dependencyModuleRecords[i];
1264
+ if (!depRecord.evaluated && !evaluationMap[depRecord.id]) {
1265
+ evaluationMap[depRecord.id] = true;
1266
+ // eslint-disable-next-line no-await-in-loop
1267
+ await this.evaluateModule(depRecord, evaluationMap);
1268
+ }
1223
1269
  }
1224
1270
  }
1225
1271
 
@@ -1231,8 +1277,8 @@ class ModuleRegistry {
1231
1277
  const moduleName = !isUrl(resolvedId)
1232
1278
  ? resolvedId
1233
1279
  : originalId !== resolvedId
1234
- ? originalId
1235
- : undefined;
1280
+ ? originalId
1281
+ : undefined;
1236
1282
  let moduleDef = moduleName && this.namedDefineRegistry.get(moduleName);
1237
1283
  if (moduleDef && moduleDef.external) {
1238
1284
  return moduleDef.external.moduleDefPromise;
@@ -1299,6 +1345,9 @@ class ModuleRegistry {
1299
1345
  });
1300
1346
  }
1301
1347
 
1348
+
1349
+
1350
+
1302
1351
  addLoaderPlugin(hooks) {
1303
1352
  if (typeof hooks !== 'object') {
1304
1353
  throw new LoaderError(INVALID_HOOK);
@@ -1340,6 +1389,7 @@ class ModuleRegistry {
1340
1389
  }
1341
1390
  }
1342
1391
 
1392
+
1343
1393
  registerHandleStaleModuleHook(handleStaleModule) {
1344
1394
  if (this.handleStaleModuleHook) {
1345
1395
  this.handleStaleModuleHook.push(handleStaleModule);
@@ -1347,30 +1397,12 @@ class ModuleRegistry {
1347
1397
  this.handleStaleModuleHook = [handleStaleModule];
1348
1398
  }
1349
1399
  }
1350
- }
1351
1400
 
1352
- // Determines if named exports module has only default export
1353
- function isNamedExportDefaultOnly(exports) {
1354
- return (
1355
- exports !== undefined &&
1356
- Object.getOwnPropertyNames(exports).length === 2 &&
1357
- Object.prototype.hasOwnProperty.call(exports, 'default') &&
1358
- Object.prototype.hasOwnProperty.call(exports, '__esModule')
1359
- );
1360
- }
1361
-
1362
- // Wrap the dependency in a function that can be called and detected by __circular__ property.
1363
- // The LWC engine checks for __circular__ to detect circular dependencies.
1364
- function getCircularDependencyWrapper(module) {
1365
- const tmp = () => {
1366
- return module.__useDefault || module.__defaultInterop ? module.default : module;
1367
- };
1368
- tmp.__circular__ = true;
1369
- return tmp;
1370
- }
1371
-
1372
- function isValidResolveResponse(res) {
1373
- return res === null || typeof res === 'string' || (res && typeof (res ).url === 'string');
1401
+ isValidResolveResponse(res) {
1402
+ return (
1403
+ res === null || typeof res === 'string' || (res && typeof (res ).url === 'string')
1404
+ );
1405
+ }
1374
1406
  }
1375
1407
 
1376
1408
  /**