@lwrjs/loader 0.12.0-alpha.6 → 0.12.0-alpha.8

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 Legacy Module Loader v0.12.0-alpha.6 */
7
+ /* LWR Legacy Module Loader v0.12.0-alpha.8 */
8
8
  const templateRegex = /\{([0-9]+)\}/g;
9
9
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
10
10
  function templateString(template, args) {
@@ -572,19 +572,32 @@ const MODULE_ERROR = `${LOADER_PREFIX}module.error`;
572
572
 
573
573
 
574
574
 
575
-
576
-
577
575
 
578
576
 
579
577
 
580
578
  class ModuleRegistry {
581
579
 
580
+
581
+
582
+ // A registry for named AMD defines containing the *metadata* of AMD module
583
+ __init() {this.namedDefineRegistry = new Map();}
584
+ // The evaluated module registry where the module identifier (name or URL?) is the key
585
+ __init2() {this.moduleRegistry = new Map();}
586
+ // Aliases of modules in the registry
587
+ __init3() {this.aliases = new Map();}
588
+
589
+
590
+
591
+
582
592
 
583
593
  constructor(config) {ModuleRegistry.prototype.__init.call(this);ModuleRegistry.prototype.__init2.call(this);ModuleRegistry.prototype.__init3.call(this);
584
594
  this.baseUrl = config.baseUrl || '';
585
595
  this.profiler = config.profiler;
586
596
  }
587
597
 
598
+ /**
599
+ * Module import
600
+ */
588
601
  async load(id, importer) {
589
602
  const metadata = importer ? { importer } : {};
590
603
  this.profiler.logOperationStart({
@@ -593,17 +606,21 @@ class ModuleRegistry {
593
606
  metadata,
594
607
  });
595
608
  const resolvedId = await this.resolve(id, importer);
596
- const moduleRecord = await this.getModuleRecord(resolvedId, id);
609
+ const moduleRecord = this.getModuleRecord(resolvedId, id);
610
+
597
611
  if (moduleRecord.evaluated) {
598
612
  return moduleRecord.module;
599
613
  } else {
600
614
  if (!moduleRecord.evaluationPromise) {
601
- moduleRecord.evaluationPromise = this.topLevelEvaluation(moduleRecord);
615
+ moduleRecord.evaluationPromise = this.evaluateModule(moduleRecord, {});
602
616
  }
603
617
  return moduleRecord.evaluationPromise;
604
618
  }
605
619
  }
606
620
 
621
+ /**
622
+ * Resolve id for a module
623
+ */
607
624
  async resolve(id, importer) {
608
625
  const parentUrl = this.baseUrl; // only support baseUrl for now
609
626
 
@@ -620,7 +637,7 @@ class ModuleRegistry {
620
637
  // eslint-disable-next-line no-await-in-loop
621
638
  result = isResponseAPromise(response) ? await response : response;
622
639
  }
623
- if (!this.isValidResolveResponse(result)) {
640
+ if (!isValidResolveResponse(result)) {
624
641
  throw new LoaderError(INVALID_LOADER_SERVICE_RESPONSE);
625
642
  }
626
643
 
@@ -701,6 +718,9 @@ class ModuleRegistry {
701
718
  return this.moduleRegistry.has(id);
702
719
  }
703
720
 
721
+ /**
722
+ * Module entry point LWR.define()
723
+ */
704
724
  define(
705
725
  name,
706
726
  dependencies,
@@ -815,24 +835,10 @@ class ModuleRegistry {
815
835
  }
816
836
  }
817
837
 
818
-
819
838
  setImportResolver(resolver) {
820
839
  this.resolver = resolver;
821
840
  }
822
841
 
823
-
824
-
825
- // A registry for named AMD defines containing the *metadata* of AMD module
826
- __init() {this.namedDefineRegistry = new Map();}
827
-
828
- // The evaluated module registry where the module identifier (name or URL?) is the key
829
- __init2() {this.moduleRegistry = new Map();}
830
-
831
- // Aliases of modules in the registry
832
- __init3() {this.aliases = new Map();}
833
-
834
-
835
-
836
842
  // Returns an existing module record by the resolvedId or aliased id
837
843
  getExistingModuleRecord(resolvedId, aliasId) {
838
844
  const moduleRecord = this.moduleRegistry.get(resolvedId);
@@ -854,7 +860,8 @@ class ModuleRegistry {
854
860
  return moduleRecord;
855
861
  }
856
862
 
857
- async getModuleRecord(resolvedId, id) {
863
+ // Module Records Inflight Cache
864
+ getModuleRecord(resolvedId, id) {
858
865
  // Look for an existing record
859
866
  const existingRecord = this.getExistingModuleRecord(resolvedId, id);
860
867
  if (existingRecord) {
@@ -862,37 +869,17 @@ class ModuleRegistry {
862
869
  return existingRecord;
863
870
  }
864
871
 
865
- // Create a new Module Record
866
- const instantiation = this.getModuleDef(resolvedId, id);
867
- const dependencyRecords = instantiation.then((moduleDef) => {
868
- const dependencies = (moduleDef && moduleDef.dependencies) || [];
869
- // get dep and filter out exports
870
- const filtered = dependencies
871
- .map((dep) => {
872
- if (dep === 'exports') {
873
- return;
874
- }
875
- invariant(dep !== 'require', NO_AMD_REQUIRE);
876
- return this.getModuleDependencyRecord.call(this, dep);
877
- })
878
- .filter((depRecord) => depRecord !== undefined) ;
879
-
880
- return Promise.all(filtered);
881
- });
882
-
883
872
  const newModuleRecord = {
884
873
  id: resolvedId,
885
874
  module: Object.create(null),
886
- dependencyRecords,
887
- instantiation,
875
+ instantiation: this.getModuleDef(resolvedId, id),
888
876
  evaluated: false,
889
877
  evaluationPromise: null,
890
878
  };
891
879
  this.moduleRegistry.set(resolvedId, newModuleRecord);
892
880
  this.storeModuleAlias(id, resolvedId);
893
881
 
894
- // Wait for the dependencies to resolve the return the moduleRecord
895
- return dependencyRecords.then(() => newModuleRecord);
882
+ return newModuleRecord;
896
883
  }
897
884
 
898
885
  storeModuleAlias(aliasId, resolvedId) {
@@ -912,96 +899,85 @@ class ModuleRegistry {
912
899
  }
913
900
  }
914
901
 
915
- async getModuleDependencyRecord(dependency) {
916
- const resolvedDepId = await this.resolve(dependency);
917
- return this.getModuleRecord(resolvedDepId, dependency);
918
- }
902
+ /**
903
+ * Evaluate all module dependencies
904
+ */
905
+ async evaluateDependencies(
906
+ dependencies,
907
+ evaluationMap,
908
+ ) {
909
+ const exports = {};
910
+ const promiseArray = [];
911
+ if (dependencies) {
912
+ for (const dep of dependencies) {
913
+ if (dep === 'exports') {
914
+ promiseArray.push(Promise.resolve(exports));
915
+ } else {
916
+ invariant(dep !== 'require', NO_AMD_REQUIRE);
917
+ promiseArray.push(this.evaluateDependent(dep, evaluationMap));
918
+ }
919
+ }
920
+ }
919
921
 
920
- // execute the "top-level code" (the code outside of functions) of a module
921
- async topLevelEvaluation(moduleRecord) {
922
- await this.instantiateAll(moduleRecord, {});
923
- return this.evaluateModule(moduleRecord, {});
922
+ return Promise.all(promiseArray).then((results) => {
923
+ const depsMapped = results.filter((result) => result !== undefined);
924
+ return { depsMapped, exports };
925
+ });
924
926
  }
925
927
 
926
- // Returns a promise when a module and all of it's dependencies have finished instantiation
927
- async instantiateAll(
928
- moduleRecord,
929
- instantiatedMap,
930
- ) {
931
- if (!instantiatedMap[moduleRecord.id]) {
932
- instantiatedMap[moduleRecord.id] = true;
933
- const dependencyModuleRecords = await moduleRecord.dependencyRecords;
934
- if (dependencyModuleRecords) {
935
- for (let i = 0; i < dependencyModuleRecords.length; i++) {
936
- const depRecord = dependencyModuleRecords[i];
937
- // eslint-disable-next-line no-await-in-loop
938
- await this.instantiateAll(depRecord, instantiatedMap);
939
- }
928
+ async evaluateDependent(dep, evaluationMap) {
929
+ const resolvedDepId = await this.resolve(dep);
930
+
931
+ const depModuleRecord = this.getModuleRecord(resolvedDepId, dep);
932
+ let module = depModuleRecord.module;
933
+ const handleReturn = (module) => {
934
+ if (module) {
935
+ return module.__defaultInterop ? module.default : module;
940
936
  }
937
+ throw new LoaderError(FAILED_DEP, [resolvedDepId]);
938
+ };
939
+
940
+ // If evaluated return the module
941
+ if (depModuleRecord.evaluated) {
942
+ return handleReturn(module);
943
+ }
944
+ /**
945
+ * Circular dependencies are handled properly when named exports are used,
946
+ * however, for default exports there is a bug: https://github.com/rollup/rollup/issues/3384
947
+ *
948
+ * The workaround below applies for circular dependencies (!moduleRecord.evaluated)
949
+ */
950
+ if (!evaluationMap[depModuleRecord.id]) {
951
+ // If we have not started dependency evaluation kick it off
952
+ if (!depModuleRecord.evaluationPromise) {
953
+ depModuleRecord.evaluationPromise = this.evaluateModule(depModuleRecord, evaluationMap);
954
+ }
955
+ return depModuleRecord.evaluationPromise.then((module) => {
956
+ return handleReturn(module);
957
+ });
958
+ } else {
959
+ // Otherwise return a dummy circular module wrapper
960
+ module = getCircularDependencyWrapper(module);
941
961
  }
962
+ return handleReturn(module);
942
963
  }
943
964
 
944
965
  async evaluateModule(
945
966
  moduleRecord,
946
967
  evaluationMap,
947
968
  ) {
948
- const dependencyModuleRecords = await moduleRecord.dependencyRecords;
949
- if (dependencyModuleRecords.length > 0) {
950
- evaluationMap[moduleRecord.id] = true;
951
- // evaluate dependencies first
952
- await this.evaluateModuleDependencies(dependencyModuleRecords, evaluationMap);
953
- }
969
+ // Create a evaluationMap to detect cycles in this dep chain
970
+ const chainMap = { ...evaluationMap };
971
+ chainMap[moduleRecord.id] = true;
954
972
 
973
+ // Wait for load to finish
955
974
  const { exporter, dependencies } = await moduleRecord.instantiation;
956
- // The exports object automatically gets filled in by the exporter evaluation
957
- const exports = {};
958
- const depsMapped = dependencies
959
- ? await Promise.all(
960
- dependencies.map(async (dep) => {
961
- if (dep === 'exports') {
962
- return exports;
963
- }
964
- const resolvedDepId = await this.resolve(dep);
965
-
966
- const moduleRecord = this.moduleRegistry.get(resolvedDepId) ;
967
- if (!moduleRecord) {
968
- throw new LoaderError(FAILED_DEP, [resolvedDepId]);
969
- }
970
-
971
- const module = moduleRecord.module;
972
-
973
- /**
974
- * Circular dependencies are handled properly when named exports are used,
975
- * however, for default exports there is a bug: https://github.com/rollup/rollup/issues/3384
976
- *
977
- * The workaround below applies for circular dependencies (!moduleRecord.evaluated)
978
- */
979
- if (!moduleRecord.evaluated) {
980
- return this.getCircularDependencyWrapper(module);
981
- }
982
-
983
- if (module) {
984
- return module.__defaultInterop ? module.default : module;
985
- }
986
-
987
- throw new LoaderError(FAILED_DEP, [resolvedDepId]);
988
- }),
989
- )
990
- : [];
991
-
992
- // 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
993
- if (moduleRecord.evaluated) {
994
- return moduleRecord.module;
995
- }
996
975
 
997
- // evaluates the module function
998
- let moduleDefault;
999
- try {
1000
- moduleDefault = exporter(...depsMapped);
1001
- } catch (e) {
1002
- throw new LoaderError(EXPORTER_ERROR, [moduleRecord.id, e.message || e]);
1003
- }
976
+ // Evaluate all it's dependents
977
+ const { depsMapped, exports } = await this.evaluateDependencies(dependencies, chainMap);
1004
978
 
979
+ // evaluates the module function
980
+ let moduleDefault = this.evaluateModuleCode(exporter, depsMapped, moduleRecord);
1005
981
  // value is returned from exporter, then we are not using named exports
1006
982
  if (moduleDefault !== undefined) {
1007
983
  moduleDefault = { default: moduleDefault };
@@ -1013,7 +989,7 @@ class ModuleRegistry {
1013
989
  // if no return value, then we are using the exports object
1014
990
  else {
1015
991
  // handle only default export with Rollup forced named exports
1016
- if (this.isNamedExportDefaultOnly(exports)) {
992
+ if (isNamedExportDefaultOnly(exports)) {
1017
993
  Object.defineProperty(exports, '__useDefault', { value: true });
1018
994
  }
1019
995
  }
@@ -1045,42 +1021,17 @@ class ModuleRegistry {
1045
1021
  Object.defineProperty(moduleRecord.module, '__esModule', { value: true });
1046
1022
  }
1047
1023
 
1048
- moduleRecord.evaluated = true;
1049
1024
  Object.freeze(moduleRecord.module);
1025
+ moduleRecord.evaluated = true;
1026
+ moduleRecord.evaluationPromise = null;
1050
1027
  return moduleRecord.module;
1051
1028
  }
1052
1029
 
1053
- // Determines if named exports module has only default export
1054
- isNamedExportDefaultOnly(exports) {
1055
- return (
1056
- exports !== undefined &&
1057
- Object.getOwnPropertyNames(exports).length === 2 &&
1058
- Object.prototype.hasOwnProperty.call(exports, 'default') &&
1059
- Object.prototype.hasOwnProperty.call(exports, '__esModule')
1060
- );
1061
- }
1062
-
1063
- // Wrap the dependency in a function that can be called and detected by __circular__ property.
1064
- // The LWC engine checks for __circular__ to detect circular dependencies.
1065
- getCircularDependencyWrapper(module) {
1066
- const tmp = () => {
1067
- return module.__useDefault || module.__defaultInterop ? module.default : module;
1068
- };
1069
- tmp.__circular__ = true;
1070
- return tmp;
1071
- }
1072
-
1073
- async evaluateModuleDependencies(
1074
- dependencyModuleRecords,
1075
- evaluationMap,
1076
- ) {
1077
- for (let i = 0; i < dependencyModuleRecords.length; i++) {
1078
- const depRecord = dependencyModuleRecords[i];
1079
- if (!depRecord.evaluated && !evaluationMap[depRecord.id]) {
1080
- evaluationMap[depRecord.id] = true;
1081
- // eslint-disable-next-line no-await-in-loop
1082
- await this.evaluateModule(depRecord, evaluationMap);
1083
- }
1030
+ evaluateModuleCode(evaluatedExporter, depsMapped, moduleRecord) {
1031
+ try {
1032
+ return evaluatedExporter(...depsMapped);
1033
+ } catch (e) {
1034
+ throw new LoaderError(EXPORTER_ERROR, [moduleRecord.id, e.message || e]);
1084
1035
  }
1085
1036
  }
1086
1037
 
@@ -1160,8 +1111,6 @@ class ModuleRegistry {
1160
1111
  });
1161
1112
  }
1162
1113
 
1163
-
1164
-
1165
1114
  addLoaderPlugin(hooks) {
1166
1115
  if (typeof hooks !== 'object') {
1167
1116
  throw new LoaderError(INVALID_HOOK);
@@ -1184,7 +1133,6 @@ class ModuleRegistry {
1184
1133
  }
1185
1134
  }
1186
1135
 
1187
-
1188
1136
  registerHandleStaleModuleHook(handleStaleModule) {
1189
1137
  if (this.handleStaleModuleHook) {
1190
1138
  this.handleStaleModuleHook.push(handleStaleModule);
@@ -1192,12 +1140,30 @@ class ModuleRegistry {
1192
1140
  this.handleStaleModuleHook = [handleStaleModule];
1193
1141
  }
1194
1142
  }
1143
+ }
1195
1144
 
1196
- isValidResolveResponse(res) {
1197
- return (
1198
- res === null || typeof res === 'string' || (res && typeof (res ).url === 'string')
1199
- );
1200
- }
1145
+ function isValidResolveResponse(res) {
1146
+ return res === null || typeof res === 'string' || (res && typeof (res ).url === 'string');
1147
+ }
1148
+
1149
+ // Determines if named exports module has only default export
1150
+ function isNamedExportDefaultOnly(exports) {
1151
+ return (
1152
+ exports !== undefined &&
1153
+ Object.getOwnPropertyNames(exports).length === 2 &&
1154
+ Object.prototype.hasOwnProperty.call(exports, 'default') &&
1155
+ Object.prototype.hasOwnProperty.call(exports, '__esModule')
1156
+ );
1157
+ }
1158
+
1159
+ // Wrap the dependency in a function that can be called and detected by __circular__ property.
1160
+ // The LWC engine checks for __circular__ to detect circular dependencies.
1161
+ function getCircularDependencyWrapper(module) {
1162
+ const tmp = () => {
1163
+ return module.__useDefault || module.__defaultInterop ? module.default : module;
1164
+ };
1165
+ tmp.__circular__ = true;
1166
+ return tmp;
1201
1167
  }
1202
1168
 
1203
1169
  // find the longest set of segments from path which are a key in matchObj
package/package.json CHANGED
@@ -5,7 +5,7 @@
5
5
  "publishConfig": {
6
6
  "access": "public"
7
7
  },
8
- "version": "0.12.0-alpha.6",
8
+ "version": "0.12.0-alpha.8",
9
9
  "homepage": "https://developer.salesforce.com/docs/platform/lwr/overview",
10
10
  "repository": {
11
11
  "type": "git",
@@ -62,16 +62,16 @@
62
62
  },
63
63
  "devDependencies": {
64
64
  "@locker/trusted-types": "0.21.0",
65
- "@lwrjs/diagnostics": "0.12.0-alpha.6",
66
- "@lwrjs/types": "0.12.0-alpha.6",
65
+ "@lwrjs/diagnostics": "0.12.0-alpha.8",
66
+ "@lwrjs/types": "0.12.0-alpha.8",
67
67
  "@rollup/plugin-node-resolve": "^15.2.3",
68
68
  "@rollup/plugin-sucrase": "^5.0.2",
69
69
  "@rollup/plugin-terser": "^0.4.4",
70
70
  "rollup": "^2.78.0"
71
71
  },
72
72
  "dependencies": {
73
- "@lwrjs/client-modules": "0.12.0-alpha.6",
74
- "@lwrjs/shared-utils": "0.12.0-alpha.6"
73
+ "@lwrjs/client-modules": "0.12.0-alpha.8",
74
+ "@lwrjs/shared-utils": "0.12.0-alpha.8"
75
75
  },
76
76
  "lwc": {
77
77
  "modules": [
@@ -91,5 +91,5 @@
91
91
  "volta": {
92
92
  "extends": "../../../package.json"
93
93
  },
94
- "gitHead": "d9428f6168feea04d3de54129a5861eb4590b26c"
94
+ "gitHead": "fa2d2189d7309adfb47f7b125616d26cb721ed6f"
95
95
  }