@lwrjs/module-registry 0.5.11 → 0.6.0-alpha.12

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.
@@ -38,6 +38,7 @@ var LwrModuleRegistry = class {
38
38
  this.providers = [];
39
39
  this.moduleDefCache = new Map();
40
40
  this.moduleLinkedCache = new Map();
41
+ this.inflightModuleDefinitions = new import_shared_utils.InflightTasks();
41
42
  this.name = "lwr-module-registry";
42
43
  this.context = context;
43
44
  this.globalConfig = globalConfig;
@@ -88,12 +89,23 @@ var LwrModuleRegistry = class {
88
89
  return this.delegateGetModuleEntryOnServices(moduleId, runtimeParams);
89
90
  }
90
91
  async getModule(moduleId, runtimeParams) {
91
- const {locker} = this.globalConfig;
92
92
  const moduleEntry = await this.getModuleEntry(moduleId, runtimeParams);
93
93
  const cacheDisabled = process.env.NOCACHE === "true";
94
94
  if (cacheDisabled === false && this.moduleDefCache.has(moduleEntry.id)) {
95
95
  return this.moduleDefCache.get(moduleEntry.id);
96
96
  }
97
+ const createModulePromiseCtor = async () => {
98
+ return this.createModuleDefinition(moduleId, runtimeParams).then((moduleDef) => {
99
+ if (cacheDisabled === false) {
100
+ this.moduleDefCache.set(moduleDef.id, moduleDef);
101
+ }
102
+ return moduleDef;
103
+ });
104
+ };
105
+ return this.inflightModuleDefinitions.execute(moduleEntry.id, createModulePromiseCtor, this);
106
+ }
107
+ async createModuleDefinition(moduleId, runtimeParams) {
108
+ const {locker} = this.globalConfig;
97
109
  const moduleCompiled = await this.delegateGetModuleOnProviders(moduleId, runtimeParams);
98
110
  if (locker.enabled && !locker.clientOnly) {
99
111
  const {runtimeEnvironment} = this.context;
@@ -102,11 +114,7 @@ var LwrModuleRegistry = class {
102
114
  moduleCompiled.compiledSource = lockerizedCode;
103
115
  }
104
116
  const moduleRecord = await (0, import_module_record.getModuleRecord)(moduleCompiled, this, this.context.compiler);
105
- const moduleDef = {...moduleCompiled, moduleRecord};
106
- if (cacheDisabled === false) {
107
- this.moduleDefCache.set(moduleDef.id, moduleDef);
108
- }
109
- return moduleDef;
117
+ return {...moduleCompiled, moduleRecord};
110
118
  }
111
119
  async getLinkedModule(moduleId, runtimeEnvironment, runtimeParams) {
112
120
  const moduleEntry = await this.getModuleEntry(moduleId, runtimeParams);
@@ -164,6 +172,7 @@ var LwrModuleRegistry = class {
164
172
  const {code: minifiedCode} = await this.context.compiler.minifyJavascript(amdSource);
165
173
  linkedAmdSource = minifiedCode;
166
174
  }
175
+ linkedModuleRecord.dynamicImports = linkedModuleRecord.dynamicImports?.filter((imp) => imp.moduleNameType !== import_shared_utils.ModuleNameType.unresolved);
167
176
  return {
168
177
  ...moduleDef,
169
178
  linkedSource: linkedAmdSource,
@@ -187,6 +196,7 @@ var LwrModuleRegistry = class {
187
196
  const {code: minifiedEsm} = await this.context.compiler.minifyJavascript(transformedEsmCode);
188
197
  transformedEsmCode = minifiedEsm;
189
198
  }
199
+ linkedModuleRecord.dynamicImports = linkedModuleRecord.dynamicImports?.filter((imp) => imp.moduleNameType !== import_shared_utils.ModuleNameType.unresolved);
190
200
  return {
191
201
  ...moduleDef,
192
202
  linkedConfig: {
@@ -26,13 +26,13 @@ __markAsModule(exports);
26
26
  __export(exports, {
27
27
  link: () => link
28
28
  });
29
- var import_magic_string = __toModule(require("magic-string"));
30
29
  var import_shared_utils = __toModule(require("@lwrjs/shared-utils"));
30
+ var import_shared_utils2 = __toModule(require("@lwrjs/shared-utils"));
31
31
  var import_signature = __toModule(require("../signature.cjs"));
32
32
  async function link(moduleRegistry, moduleDef, strategy, runtimeEnvironment, runtimeParams, config, interchangeableModules, exclude) {
33
33
  const {specifier, version, compiledSource, moduleRecord} = moduleDef;
34
34
  const {imports, dynamicImports} = moduleRecord;
35
- const codeStringBuilder = new import_magic_string.default(compiledSource);
35
+ const codeStringBuilder = (0, import_shared_utils.createStringBuilder)(compiledSource);
36
36
  const amdLoaderModule = config?.amdLoaderModule;
37
37
  const esmLoaderModule = config?.esmLoaderModule;
38
38
  const id = strategy({specifier, version}, runtimeEnvironment, runtimeParams);
@@ -80,7 +80,7 @@ async function link(moduleRegistry, moduleDef, strategy, runtimeEnvironment, run
80
80
  linkedDynamicImports = await Promise.all(dynamicImports.map(async (importRef) => {
81
81
  const {locations, sourceSpecifier} = importRef;
82
82
  let signature;
83
- const isStringLiteral = importRef.moduleNameType === import_shared_utils.ModuleNameType.string;
83
+ const isStringLiteral = importRef.moduleNameType === import_shared_utils2.ModuleNameType.string;
84
84
  if (isStringLiteral && runtimeEnvironment.bundle && runtimeEnvironment.format === "esm") {
85
85
  signature = await (0, import_signature.getBundleSignature)(importRef, moduleRegistry);
86
86
  }
@@ -95,7 +95,7 @@ async function link(moduleRegistry, moduleDef, strategy, runtimeEnvironment, run
95
95
  codeStringBuilder.overwrite(importStart, importEnd, "load(");
96
96
  loaderSizeOffset = 2;
97
97
  if (!isStringLiteral) {
98
- const importerSpecifier = (0, import_shared_utils.getSpecifier)({specifier, version});
98
+ const importerSpecifier = (0, import_shared_utils2.getSpecifier)({specifier, version});
99
99
  codeStringBuilder.overwrite(endColumn, endColumn + 1, `, '${importerSpecifier}')`);
100
100
  loaderSizeOffset = -1 * importerSpecifier.length - 2;
101
101
  }
@@ -116,8 +116,12 @@ async function link(moduleRegistry, moduleDef, strategy, runtimeEnvironment, run
116
116
  }
117
117
  if (dynamicImports && dynamicImports.length > 0 && (amdLoaderModule || esmLoaderModule)) {
118
118
  const {version: version2, specifier: specifier2} = amdLoaderModule || esmLoaderModule;
119
- const {namespace, name} = (0, import_shared_utils.explodeSpecifier)(specifier2);
120
- const loaderLink = strategy({specifier: specifier2, version: version2}, runtimeEnvironment, runtimeParams);
119
+ const {namespace, name} = (0, import_shared_utils2.explodeSpecifier)(specifier2);
120
+ let signature;
121
+ if (esmLoaderModule && runtimeEnvironment.bundle) {
122
+ signature = await (0, import_signature.getBundleSignature)({version: version2, specifier: specifier2}, moduleRegistry);
123
+ }
124
+ const loaderLink = strategy({specifier: specifier2, version: version2}, runtimeEnvironment, runtimeParams, signature);
121
125
  codeStringBuilder.prepend(`import { load } from "${loaderLink}";
122
126
  `);
123
127
  linkedImports.unshift({
@@ -37,7 +37,7 @@ function linkEsm(moduleId, environment, params = {}, signature) {
37
37
  const encodedVSpecifier = encodeURIComponent(vSpecifier);
38
38
  const latestSignature = signature === void 0 || signature === LATEST_SIG;
39
39
  const sigilSignature = latestSignature ? LATEST_SIG : `${SIGNATURE_SIGIL}/${signature}`;
40
- const prettyUrl = (bundle ? "bundle_" : "") + `${specifier.replace(/[\/\.\#]/g, "_")}`;
40
+ const prettyUrl = (bundle ? "bundle_" : "") + (0, import_shared_utils.prettyModuleUriSuffix)(specifier);
41
41
  const debugModifier = debug ? "?debug=true" : "";
42
42
  return `${uriPrefix}${encodedVSpecifier}/${sigilSignature}/${prettyUrl}.js${debugModifier}`;
43
43
  }
@@ -79,7 +79,7 @@ async function getModuleRecord(compiledModule, registry, compiler) {
79
79
  imports: compiledModuleImports,
80
80
  dynamicImports: compiledModuleDynamicImports
81
81
  });
82
- if (compiledMetadata && compiledMetadata.imports) {
82
+ if (compiledMetadata && compiledMetadata.imports && compiledMetadata.imports.length > 0) {
83
83
  const visitedImports = new Set();
84
84
  for (const {moduleSpecifier, location} of compiledMetadata.imports) {
85
85
  if (!visitedImports.has(moduleSpecifier)) {
@@ -99,7 +99,7 @@ async function getModuleRecord(compiledModule, registry, compiler) {
99
99
  }
100
100
  }
101
101
  }
102
- if (compiledMetadata && compiledMetadata.dynamicImports) {
102
+ if (compiledMetadata && compiledMetadata.dynamicImports && compiledMetadata.dynamicImports.length > 0) {
103
103
  const visitedDynamicImports = new Set();
104
104
  for (const {
105
105
  moduleSpecifier,
@@ -28,6 +28,7 @@ __export(exports, {
28
28
  });
29
29
  var import_crypto = __toModule(require("crypto"));
30
30
  var import_path = __toModule(require("path"));
31
+ var import_process = __toModule(require("process"));
31
32
  var import_module = __toModule(require("module"));
32
33
  var import_shared_utils = __toModule(require("@lwrjs/shared-utils"));
33
34
  var LWC_VERSION = getLWCVersion();
@@ -62,7 +63,7 @@ async function getBundleSignature(moduleId, registry) {
62
63
  return hash.digest("hex");
63
64
  }
64
65
  function getLWCVersion() {
65
- const require2 = (0, import_module.createRequire)(import_path.default.join(process.cwd(), "./env-config.js"));
66
+ const require2 = (0, import_module.createRequire)(import_path.default.join((0, import_process.cwd)(), "./env-config.js"));
66
67
  const {version} = require2("lwc/package.json");
67
68
  return version;
68
69
  }
@@ -14,11 +14,13 @@ export declare class LwrModuleRegistry implements ModuleRegistry {
14
14
  emitter: LwrAppEmitter;
15
15
  globalConfig: NormalizedLwrGlobalConfig;
16
16
  private interchangeableModules?;
17
+ private inflightModuleDefinitions;
17
18
  constructor(context: RegistryContext, globalConfig: NormalizedLwrGlobalConfig, registries?: ModuleProvider[]);
18
19
  resolveModuleUri<R extends RuntimeEnvironment, S extends string | undefined>(moduleId: Required<Pick<ModuleId, 'specifier' | 'version'>>, runtimeEnvironment: R, runtimeParams?: RuntimeParams, signature?: S): S extends string ? string : Promise<string>;
19
20
  addModuleProviders(registries: ModuleProvider[]): void;
20
21
  getModuleEntry<T extends AbstractModuleId>(moduleId: T, runtimeParams?: RuntimeParams): Promise<ModuleEntry>;
21
22
  getModule<T extends AbstractModuleId>(moduleId: T, runtimeParams?: RuntimeParams): Promise<ModuleDefinition>;
23
+ private createModuleDefinition;
22
24
  getLinkedModule<T extends AbstractModuleId>(moduleId: T, runtimeEnvironment: RuntimeEnvironment, runtimeParams?: RuntimeParams): Promise<LinkedModuleDefinition>;
23
25
  private createLinkedModuleDefinition;
24
26
  private delegateGetModuleEntryOnServices;
package/build/es/index.js CHANGED
@@ -1,5 +1,5 @@
1
1
  import { LwrUnresolvableError, createSingleDiagnosticError, descriptions } from '@lwrjs/diagnostics';
2
- import { discoverInterchangeableModules, getCacheKeyFromJson, LATEST_SIGNATURE, ModuleNameType, } from '@lwrjs/shared-utils';
2
+ import { discoverInterchangeableModules, getCacheKeyFromJson, InflightTasks, LATEST_SIGNATURE, ModuleNameType, } from '@lwrjs/shared-utils';
3
3
  import { link } from './linker/linker.js';
4
4
  import { getModuleRecord } from './module-record.js';
5
5
  import amdLinkingStrategy from './linker/strategies/amd-strategy.js';
@@ -10,6 +10,7 @@ export class LwrModuleRegistry {
10
10
  this.providers = [];
11
11
  this.moduleDefCache = new Map();
12
12
  this.moduleLinkedCache = new Map();
13
+ this.inflightModuleDefinitions = new InflightTasks();
13
14
  this.name = 'lwr-module-registry';
14
15
  this.context = context;
15
16
  this.globalConfig = globalConfig;
@@ -72,12 +73,25 @@ export class LwrModuleRegistry {
72
73
  return this.delegateGetModuleEntryOnServices(moduleId, runtimeParams);
73
74
  }
74
75
  async getModule(moduleId, runtimeParams) {
75
- const { locker } = this.globalConfig;
76
76
  const moduleEntry = await this.getModuleEntry(moduleId, runtimeParams);
77
77
  const cacheDisabled = process.env.NOCACHE === 'true';
78
78
  if (cacheDisabled === false && this.moduleDefCache.has(moduleEntry.id)) {
79
+ // TODO add to profiling
80
+ // console.log('[INFO] Module Cache Hit: %s', moduleEntry.id);
79
81
  return this.moduleDefCache.get(moduleEntry.id);
80
82
  }
83
+ const createModulePromiseCtor = async () => {
84
+ return this.createModuleDefinition(moduleId, runtimeParams).then((moduleDef) => {
85
+ if (cacheDisabled === false) {
86
+ this.moduleDefCache.set(moduleDef.id, moduleDef);
87
+ }
88
+ return moduleDef;
89
+ });
90
+ };
91
+ return this.inflightModuleDefinitions.execute(moduleEntry.id, createModulePromiseCtor, this);
92
+ }
93
+ async createModuleDefinition(moduleId, runtimeParams) {
94
+ const { locker } = this.globalConfig;
81
95
  const moduleCompiled = await this.delegateGetModuleOnProviders(moduleId, runtimeParams); // provider source + hash
82
96
  /** Locker before collecting dep module records so locker imports are processed normally */
83
97
  if (locker.enabled && !locker.clientOnly) {
@@ -87,11 +101,7 @@ export class LwrModuleRegistry {
87
101
  moduleCompiled.compiledSource = lockerizedCode;
88
102
  }
89
103
  const moduleRecord = await getModuleRecord(moduleCompiled, this, this.context.compiler);
90
- const moduleDef = { ...moduleCompiled, moduleRecord };
91
- if (cacheDisabled === false) {
92
- this.moduleDefCache.set(moduleDef.id, moduleDef);
93
- }
94
- return moduleDef;
104
+ return { ...moduleCompiled, moduleRecord };
95
105
  }
96
106
  async getLinkedModule(moduleId, runtimeEnvironment, runtimeParams) {
97
107
  const moduleEntry = await this.getModuleEntry(moduleId, runtimeParams);
@@ -149,6 +159,8 @@ export class LwrModuleRegistry {
149
159
  const { code: minifiedCode } = await this.context.compiler.minifyJavascript(amdSource);
150
160
  linkedAmdSource = minifiedCode;
151
161
  }
162
+ // Filter out variable dynamic imports
163
+ linkedModuleRecord.dynamicImports = linkedModuleRecord.dynamicImports?.filter((imp) => imp.moduleNameType !== ModuleNameType.unresolved);
152
164
  return {
153
165
  ...moduleDef,
154
166
  linkedSource: linkedAmdSource,
@@ -178,6 +190,8 @@ export class LwrModuleRegistry {
178
190
  const { code: minifiedEsm } = await this.context.compiler.minifyJavascript(transformedEsmCode);
179
191
  transformedEsmCode = minifiedEsm;
180
192
  }
193
+ // Filter out variable dynamic imports
194
+ linkedModuleRecord.dynamicImports = linkedModuleRecord.dynamicImports?.filter((imp) => imp.moduleNameType !== ModuleNameType.unresolved);
181
195
  return {
182
196
  ...moduleDef,
183
197
  linkedConfig: {
@@ -1,4 +1,4 @@
1
- import MagicString from 'magic-string';
1
+ import { createStringBuilder } from '@lwrjs/shared-utils';
2
2
  import { explodeSpecifier, getSpecifier, ModuleNameType } from '@lwrjs/shared-utils';
3
3
  import { getBundleSignature } from '../signature.js';
4
4
  /**
@@ -10,7 +10,7 @@ import { getBundleSignature } from '../signature.js';
10
10
  export async function link(moduleRegistry, moduleDef, strategy, runtimeEnvironment, runtimeParams, config, interchangeableModules, exclude) {
11
11
  const { specifier, version, compiledSource, moduleRecord } = moduleDef;
12
12
  const { imports, dynamicImports } = moduleRecord;
13
- const codeStringBuilder = new MagicString(compiledSource);
13
+ const codeStringBuilder = createStringBuilder(compiledSource);
14
14
  const amdLoaderModule = config?.amdLoaderModule;
15
15
  const esmLoaderModule = config?.esmLoaderModule;
16
16
  const id = strategy({ specifier, version }, runtimeEnvironment, runtimeParams);
@@ -114,7 +114,12 @@ export async function link(moduleRegistry, moduleDef, strategy, runtimeEnvironme
114
114
  // mutate ModuleEntry to ImportModuleRecord
115
115
  const { version, specifier } = amdLoaderModule || esmLoaderModule;
116
116
  const { namespace, name } = explodeSpecifier(specifier);
117
- const loaderLink = strategy({ specifier, version }, runtimeEnvironment, runtimeParams);
117
+ let signature;
118
+ if (esmLoaderModule && runtimeEnvironment.bundle) {
119
+ // Ensure the ESM loader is signed, or there may be a clash between this import and an existing one
120
+ signature = await getBundleSignature({ version, specifier }, moduleRegistry);
121
+ }
122
+ const loaderLink = strategy({ specifier, version }, runtimeEnvironment, runtimeParams, signature);
118
123
  // import {load} from 'loader/loader'
119
124
  codeStringBuilder.prepend(`import { load } from "${loaderLink}";\n`);
120
125
  linkedImports.unshift({
@@ -1,4 +1,4 @@
1
- import { getModuleUriPrefix, getSpecifier, normalizeVersionToUri } from '@lwrjs/shared-utils';
1
+ import { getModuleUriPrefix, getSpecifier, normalizeVersionToUri, prettyModuleUriSuffix, } from '@lwrjs/shared-utils';
2
2
  const SIGNATURE_SIGIL = 's';
3
3
  const LATEST_SIG = 'latest';
4
4
  export default function linkEsm(moduleId, environment, params = {}, signature) {
@@ -9,8 +9,7 @@ export default function linkEsm(moduleId, environment, params = {}, signature) {
9
9
  const encodedVSpecifier = encodeURIComponent(vSpecifier);
10
10
  const latestSignature = signature === undefined || signature === LATEST_SIG;
11
11
  const sigilSignature = latestSignature ? LATEST_SIG : `${SIGNATURE_SIGIL}/${signature}`;
12
- // eslint-disable-next-line no-useless-escape
13
- const prettyUrl = (bundle ? 'bundle_' : '') + `${specifier.replace(/[\/\.\#]/g, '_')}`;
12
+ const prettyUrl = (bundle ? 'bundle_' : '') + prettyModuleUriSuffix(specifier);
14
13
  const debugModifier = debug ? '?debug=true' : '';
15
14
  return `${uriPrefix}${encodedVSpecifier}/${sigilSignature}/${prettyUrl}.js${debugModifier}`;
16
15
  }
@@ -63,7 +63,7 @@ export async function getModuleRecord(compiledModule, registry, compiler) {
63
63
  dynamicImports: compiledModuleDynamicImports,
64
64
  });
65
65
  // Process imports
66
- if (compiledMetadata && compiledMetadata.imports) {
66
+ if (compiledMetadata && compiledMetadata.imports && compiledMetadata.imports.length > 0) {
67
67
  const visitedImports = new Set(); // Avoids multiple imports to the same specifier
68
68
  for (const { moduleSpecifier, location } of compiledMetadata.imports) {
69
69
  // Check for dupes first
@@ -90,7 +90,7 @@ export async function getModuleRecord(compiledModule, registry, compiler) {
90
90
  }
91
91
  }
92
92
  // Process dynamic imports
93
- if (compiledMetadata && compiledMetadata.dynamicImports) {
93
+ if (compiledMetadata && compiledMetadata.dynamicImports && compiledMetadata.dynamicImports.length > 0) {
94
94
  const visitedDynamicImports = new Set(); // Avoids multiple imports to the same specifier
95
95
  for (const { moduleSpecifier, location, importLocation, moduleNameType, } of compiledMetadata.dynamicImports) {
96
96
  // Check for dupes first
@@ -1,5 +1,6 @@
1
1
  import crypto from 'crypto';
2
2
  import path from 'path';
3
+ import { cwd } from 'process';
3
4
  import { createRequire } from 'module';
4
5
  import { getExperimentalFeatures } from '@lwrjs/shared-utils';
5
6
  const LWC_VERSION = getLWCVersion();
@@ -37,7 +38,7 @@ export async function getBundleSignature(moduleId, registry) {
37
38
  * Get the configured LWC version
38
39
  */
39
40
  function getLWCVersion() {
40
- const require = createRequire(path.join(process.cwd(), './env-config.js'));
41
+ const require = createRequire(path.join(cwd(), './env-config.js'));
41
42
  // eslint-disable-next-line @typescript-eslint/no-var-requires
42
43
  const { version } = require('lwc/package.json');
43
44
  return version;
package/package.json CHANGED
@@ -4,8 +4,8 @@
4
4
  "publishConfig": {
5
5
  "access": "public"
6
6
  },
7
- "version": "0.5.11",
8
- "homepage": "https://lwr.dev/",
7
+ "version": "0.6.0-alpha.12",
8
+ "homepage": "https://developer.salesforce.com/docs/platform/lwr/overview",
9
9
  "repository": {
10
10
  "type": "git",
11
11
  "url": "https://github.com/salesforce/lwr.git",
@@ -30,19 +30,18 @@
30
30
  "build/**/*.d.ts"
31
31
  ],
32
32
  "dependencies": {
33
- "@lwrjs/diagnostics": "0.5.11",
34
- "@lwrjs/shared-utils": "0.5.11",
33
+ "@lwrjs/diagnostics": "0.6.0-alpha.12",
34
+ "@lwrjs/shared-utils": "0.6.0-alpha.12",
35
35
  "es-module-lexer": "^0.3.18",
36
- "magic-string": "^0.25.7",
37
36
  "ws": "^7.2.5"
38
37
  },
39
38
  "devDependencies": {
40
- "@lwrjs/types": "0.5.11",
39
+ "@lwrjs/types": "0.6.0-alpha.12",
41
40
  "@types/es-module-lexer": "^0.3.0",
42
41
  "@types/ws": "^7.2.4"
43
42
  },
44
43
  "engines": {
45
44
  "node": ">=14.15.4 <17"
46
45
  },
47
- "gitHead": "2ee810c0a4f1f36d1e0f8378a1fe00c19b4c5bc1"
46
+ "gitHead": "876b56ca4f98f3299303f2193c0dec8f46a69b84"
48
47
  }