alloy-di 1.1.0 → 1.2.0

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.
@@ -2,7 +2,6 @@ import { Constructor, Newable, Token } from "./types.js";
2
2
  import { ServiceIdentifier } from "./service-identifiers.js";
3
3
 
4
4
  //#region src/lib/container.d.ts
5
-
6
5
  /**
7
6
  * Runtime dependency injection container used by generated modules and tests.
8
7
  *
@@ -10,12 +9,12 @@ import { ServiceIdentifier } from "./service-identifiers.js";
10
9
  * performs singleton caching, and supports token-based value providers.
11
10
  */
12
11
  declare class Container {
13
- private singletons;
14
- private pendingSingletons;
15
- private instanceOverrides;
16
- private metadataCache;
17
- private valueProviders;
18
- private factoryWarningCache;
12
+ private readonly singletons;
13
+ private readonly pendingSingletons;
14
+ private readonly instanceOverrides;
15
+ private readonly metadataCache;
16
+ private readonly valueProviders;
17
+ private readonly factoryWarningCache;
19
18
  /**
20
19
  * Resolve (and construct) the requested service.
21
20
  *
@@ -5,7 +5,6 @@ import { dependenciesRegistry } from "./decorators.js";
5
5
  import { DependencyResolutionError } from "./dependency-error.js";
6
6
  import { getConstructorByIdentifier, getServiceIdentifier } from "./service-identifiers.js";
7
7
  import { isDevEnvironment } from "./env-detection.js";
8
-
9
8
  //#region src/lib/container.ts
10
9
  function classifyDependency(value) {
11
10
  if (isLazy(value)) return {
@@ -261,6 +260,5 @@ var Container = class {
261
260
  return metadata;
262
261
  }
263
262
  };
264
-
265
263
  //#endregion
266
- export { Container };
264
+ export { Container };
@@ -3,7 +3,6 @@ import { Lazy } from "./lazy.js";
3
3
  import { ServiceScope } from "./scope.js";
4
4
 
5
5
  //#region src/lib/decorators.d.ts
6
-
7
6
  /**
8
7
  * Resolve a declared dependency to the constructor parameter type expected by the service.
9
8
  *
@@ -1,5 +1,4 @@
1
1
  import { ServiceScope } from "./scope.js";
2
-
3
2
  //#region src/lib/decorators.ts
4
3
  /**
5
4
  * Global registry for service metadata used by the runtime container.
@@ -27,16 +26,16 @@ const dependenciesRegistry = /* @__PURE__ */ new Map();
27
26
  */
28
27
  function createDecoratorWithDeps(scope, depsOpt) {
29
28
  if (typeof depsOpt === "function") {
30
- const depsFn$1 = depsOpt;
29
+ const depsFn = depsOpt;
31
30
  return (target) => {
32
31
  dependenciesRegistry.set(target, {
33
32
  scope,
34
- dependencies: depsFn$1
33
+ dependencies: depsFn
35
34
  });
36
35
  };
37
36
  }
38
- const deps$1 = depsOpt;
39
- const depsFn = () => deps$1;
37
+ const deps = depsOpt;
38
+ const depsFn = () => deps;
40
39
  return (target) => {
41
40
  dependenciesRegistry.set(target, {
42
41
  scope,
@@ -121,6 +120,5 @@ function deps(...items) {
121
120
  function assertDeps(depsFn, klass) {
122
121
  return klass;
123
122
  }
124
-
125
123
  //#endregion
126
- export { Injectable, Singleton, assertDeps, dependenciesRegistry, deps };
124
+ export { Injectable, Singleton, assertDeps, dependenciesRegistry, deps };
@@ -1,6 +1,5 @@
1
1
  import { isConstructor, isToken } from "./types.js";
2
2
  import { isLazy } from "./lazy.js";
3
-
4
3
  //#region src/lib/dependency-error.ts
5
4
  function describeDependency(value) {
6
5
  if (isConstructor(value)) return `constructor ${value.name || "<anonymous>"}`;
@@ -26,6 +25,5 @@ var DependencyResolutionError = class extends Error {
26
25
  return `${this.message}\nResolution path: ${stackPath}${dependencyInfo}`;
27
26
  }
28
27
  };
29
-
30
28
  //#endregion
31
- export { DependencyResolutionError };
29
+ export { DependencyResolutionError };
@@ -16,8 +16,7 @@ function readImportMetaEnvFromRuntime() {
16
16
  }
17
17
  function readProcessNodeEnv() {
18
18
  if (typeof process === "undefined") return;
19
- const nodeEnv = "development";
20
- return typeof nodeEnv === "string" ? nodeEnv : void 0;
19
+ return "development";
21
20
  }
22
21
  function getImportMetaEnv(overrides) {
23
22
  if (overrides?.importMetaEnv === null) return;
@@ -39,6 +38,5 @@ function isDevEnvironment(overrides) {
39
38
  if (typeof importMetaEnv?.NODE_ENV === "string") return importMetaEnv.NODE_ENV !== "production";
40
39
  return true;
41
40
  }
42
-
43
41
  //#endregion
44
- export { isDevEnvironment };
42
+ export { isDevEnvironment };
package/dist/lib/lazy.js CHANGED
@@ -13,6 +13,5 @@ function Lazy(importer, retry) {
13
13
  retry
14
14
  };
15
15
  }
16
-
17
16
  //#endregion
18
- export { LAZY_IDENTIFIER, Lazy, isLazy };
17
+ export { LAZY_IDENTIFIER, Lazy, isLazy };
@@ -4,7 +4,6 @@ import { Lazy } from "./lazy.js";
4
4
  import { ServiceScope } from "./scope.js";
5
5
 
6
6
  //#region src/lib/providers.d.ts
7
-
8
7
  /**
9
8
  * Explicit lifecycle choices for providers. Mirrors decorator scopes but externalized.
10
9
  */
@@ -2,7 +2,6 @@ import { ServiceScope } from "./scope.js";
2
2
  import { isConstructor } from "./types.js";
3
3
  import { Lazy } from "./lazy.js";
4
4
  import { dependenciesRegistry } from "./decorators.js";
5
-
6
5
  //#region src/lib/providers.ts
7
6
  /**
8
7
  * Hidden symbol used to attach lazy provider metadata to its placeholder constructor.
@@ -146,9 +145,9 @@ function applyProviders(container, definitions) {
146
145
  detectProviderCycles(planEntries);
147
146
  for (const definition of list) {
148
147
  for (const valueProvider of definition.values ?? []) container.provideValue(valueProvider.token, valueProvider.value);
149
- const registerService = (ctor, lifecycle$1, deps, factory) => {
148
+ const registerService = (ctor, lifecycle, deps, factory) => {
150
149
  dependenciesRegistry.set(ctor, {
151
- scope: lifecycle$1,
150
+ scope: lifecycle,
152
151
  dependencies: normalizeDependencies(deps),
153
152
  factory
154
153
  });
@@ -161,6 +160,5 @@ function applyProviders(container, definitions) {
161
160
  }
162
161
  }
163
162
  }
164
-
165
163
  //#endregion
166
- export { applyProviders, asClass, asLazyClass, asValue, defineProviders, lifecycle };
164
+ export { applyProviders, asClass, asLazyClass, asValue, defineProviders, lifecycle };
package/dist/lib/scope.js CHANGED
@@ -3,6 +3,5 @@ const ServiceScope = {
3
3
  SINGLETON: "singleton",
4
4
  TRANSIENT: "transient"
5
5
  };
6
-
7
6
  //#endregion
8
- export { ServiceScope };
7
+ export { ServiceScope };
@@ -1,7 +1,6 @@
1
1
  import { Constructor } from "./types.js";
2
2
 
3
3
  //#region src/lib/service-identifiers.d.ts
4
-
5
4
  /**
6
5
  * Symbol-based identifier used to resolve services in a minifier-safe way.
7
6
  * These identifiers never collide with minified constructor names and can be
@@ -49,6 +49,5 @@ function clearServiceIdentifierRegistry() {
49
49
  ctorToIdentifier = /* @__PURE__ */ new WeakMap();
50
50
  identifierToCtor.clear();
51
51
  }
52
-
53
52
  //#endregion
54
- export { clearServiceIdentifierRegistry, getConstructorByIdentifier, getServiceIdentifier, registerServiceIdentifier };
53
+ export { clearServiceIdentifierRegistry, getConstructorByIdentifier, getServiceIdentifier, registerServiceIdentifier };
@@ -5,9 +5,7 @@ import { vi } from "vitest";
5
5
  type MethodKeys<T> = { [K in keyof T]: T[K] extends ((...args: any[]) => any) ? K : never }[keyof T];
6
6
  /** Typed mock shape returned for class auto-mocking. */
7
7
  type MockOf<T> = Partial<T> & {
8
- /** Map of method name -> vi spy function */
9
- spies: Record<Extract<MethodKeys<T>, string>, ReturnType<typeof vi.fn>>;
10
- /** Original constructor reference for introspection */
8
+ /** Map of method name -> vi spy function */spies: Record<Extract<MethodKeys<T>, string>, ReturnType<typeof vi.fn>>; /** Original constructor reference for introspection */
11
9
  __target: Newable<T>;
12
10
  };
13
11
  //#endregion
@@ -2,7 +2,6 @@ import { isConstructor } from "../types.js";
2
2
  import { isLazy } from "../lazy.js";
3
3
  import { getRawDependencies } from "./registry.js";
4
4
  import { vi } from "vitest";
5
-
6
5
  //#region src/lib/testing/mocking.ts
7
6
  /** Create a lightweight auto-mock instance for a class constructor. */
8
7
  function mockClass(ctor) {
@@ -104,6 +103,5 @@ function buildMockCtorFrom(realCtor, mock) {
104
103
  }
105
104
  return MockCtor;
106
105
  }
107
-
108
106
  //#endregion
109
- export { applyAutoMocks };
107
+ export { applyAutoMocks };
@@ -1,5 +1,4 @@
1
1
  import { dependenciesRegistry } from "../decorators.js";
2
-
3
2
  //#region src/lib/testing/registry.ts
4
3
  /** Take a deep(ish) snapshot of current dependency registry state. */
5
4
  function snapshotRegistry() {
@@ -14,6 +13,5 @@ function restoreRegistry(snapshot) {
14
13
  function getRawDependencies(target) {
15
14
  return (dependenciesRegistry.get(target)?.dependencies ?? (() => []))();
16
15
  }
17
-
18
16
  //#endregion
19
- export { getRawDependencies, restoreRegistry, snapshotRegistry };
17
+ export { getRawDependencies, restoreRegistry, snapshotRegistry };
package/dist/lib/types.js CHANGED
@@ -16,6 +16,5 @@ function isConstructor(value) {
16
16
  if (proto.constructor !== value) return false;
17
17
  return true;
18
18
  }
19
-
20
19
  //#endregion
21
- export { createToken, isConstructor, isToken };
20
+ export { createToken, isConstructor, isToken };
@@ -1,10 +1,9 @@
1
1
  import { createClassKey, createSymbolKey, hashString, normalizeImportPath } from "./utils.js";
2
2
  import { IdentifierResolver } from "./identifier-resolver.js";
3
3
  import path from "node:path";
4
-
5
4
  //#region src/plugins/core/codegen.ts
6
5
  function escapeSingleQuotes(value) {
7
- return value.replace(/'/g, "\\'");
6
+ return value.replaceAll("'", "\\'");
8
7
  }
9
8
  /**
10
9
  * Generates a unique export key for the service identifier map.
@@ -26,23 +25,22 @@ function resolveDependencyImports(metas) {
26
25
  const importMap = /* @__PURE__ */ new Map();
27
26
  const nameCounts = /* @__PURE__ */ new Map();
28
27
  const getUniqueName = (name) => {
29
- const count = nameCounts.get(name) || 0;
28
+ const count = nameCounts.get(name) ?? 0;
30
29
  nameCounts.set(name, count + 1);
31
30
  return count === 0 ? name : `${name}_${count}`;
32
31
  };
33
- for (const meta of metas) if (meta.referencedImports) for (const ref of meta.referencedImports) {
34
- if (ref.isTypeOnly) continue;
35
- const dir = path.dirname(meta.filePath);
36
- const normalizedPath = normalizeImportPath(ref.path.startsWith(".") ? path.resolve(dir, ref.path) : ref.path);
37
- const key = `${normalizedPath}::${ref.originalName ?? "default"}`;
38
- let resolved = importMap.get(key);
39
- if (!resolved) {
40
- resolved = {
32
+ for (const meta of metas) {
33
+ if (!meta.referencedImports?.length) continue;
34
+ for (const ref of meta.referencedImports) {
35
+ if (ref.isTypeOnly) continue;
36
+ const normalizedPath = normalizeImportPath(ref.path.startsWith(".") ? path.resolve(path.dirname(meta.filePath), ref.path) : ref.path);
37
+ const key = `${normalizedPath}::${ref.originalName ?? "default"}`;
38
+ if (importMap.has(key)) continue;
39
+ importMap.set(key, {
41
40
  localName: getUniqueName(ref.name),
42
41
  importPath: normalizedPath,
43
42
  originalName: ref.originalName
44
- };
45
- importMap.set(key, resolved);
43
+ });
46
44
  }
47
45
  }
48
46
  return {
@@ -54,9 +52,9 @@ function reconstructDependencyExpression(dep, rewriter, contextDir) {
54
52
  let expr = dep.expression;
55
53
  for (const ident of dep.referencedIdentifiers) {
56
54
  const replacement = rewriter(ident);
57
- if (replacement && replacement !== ident) expr = expr.replace(new RegExp(`\\b${ident}\\b`, "g"), replacement);
55
+ if (replacement && replacement !== ident) expr = expr.replaceAll(new RegExp(`\\b${ident}\\b`, "g"), replacement);
58
56
  }
59
- if (dep.isLazy) expr = expr.replace(/import\s*\(\s*(['"])(.+?)\1\s*\)/g, (match, quote, importPath) => {
57
+ if (dep.isLazy) expr = expr.replaceAll(/import\s*\(\s*(['"])(.+?)\1\s*\)/g, (match, quote, importPath) => {
60
58
  if (importPath.startsWith(".")) return `import(${quote}${normalizeImportPath(path.resolve(contextDir, importPath))}${quote})`;
61
59
  return match;
62
60
  });
@@ -89,12 +87,25 @@ function reconstructOptionsText(meta, importMap) {
89
87
  return `{ ${parts.join(", ")} }`;
90
88
  }
91
89
  function buildImportsAndRegistrations(metas, lazyReferencedClassKeys, hasProviderModules) {
92
- const activeMetas = metas.filter((meta) => !lazyReferencedClassKeys.has(createClassKey(meta.filePath, meta.className)));
90
+ const activeMetas = filterActiveMetas(metas, lazyReferencedClassKeys);
93
91
  const { dependencyImports, importMap } = resolveDependencyImports(activeMetas);
94
- const resolver = new IdentifierResolver(activeMetas);
95
- const resolvedImports = activeMetas.map((meta) => {
92
+ const resolvedRegistrations = enrichRegistrations(activeMetas, new IdentifierResolver(activeMetas), importMap);
93
+ const runtimeImports = computeRuntimeImports(resolvedRegistrations, hasProviderModules);
94
+ const runtimeImportStatement = formatRuntimeImportStatement(runtimeImports);
95
+ const stubsBlock = createStubBlock(dependencyImports, resolvedRegistrations, runtimeImports);
96
+ return {
97
+ runtimeImportStatement,
98
+ registrationsBlock: createRegistrationsBlock(buildRegistrationEntries(resolvedRegistrations)),
99
+ stubsBlock,
100
+ identifierExportBlock: createIdentifierExports(resolvedRegistrations)
101
+ };
102
+ }
103
+ function filterActiveMetas(metas, lazyReferencedClassKeys) {
104
+ return metas.filter((meta) => !lazyReferencedClassKeys.has(createClassKey(meta.filePath, meta.className)));
105
+ }
106
+ function enrichRegistrations(activeMetas, resolver, importMap) {
107
+ return activeMetas.map((meta) => {
96
108
  const importName = resolver.resolve(meta.className, meta.filePath);
97
- const isFactoryLazy = !!meta.metadata.factory;
98
109
  const identifierConst = `${importName}Identifier`;
99
110
  const exportKey = createIdentifierExportKey(meta, resolver);
100
111
  const symbolDescription = meta.identifierKey ?? createSymbolDescription(meta);
@@ -102,53 +113,69 @@ function buildImportsAndRegistrations(metas, lazyReferencedClassKeys, hasProvide
102
113
  return {
103
114
  ...meta,
104
115
  importName,
105
- isFactoryLazy,
116
+ isFactoryLazy: Boolean(meta.metadata.factory),
106
117
  identifierConst,
107
118
  exportKey,
108
119
  symbolDescription,
109
120
  optionsText
110
121
  };
111
122
  });
112
- const needsLazyImport = activeMetas.some((m) => m.metadata.dependencies.some((d) => d.isLazy) || !!m.metadata.factory);
113
- const runtimeImports = new Set(["Container", "dependenciesRegistry"]);
114
- if (hasProviderModules) runtimeImports.add("applyProviders");
115
- if (needsLazyImport) runtimeImports.add("Lazy");
116
- if (resolvedImports.length) runtimeImports.add("registerServiceIdentifier");
117
- const runtimeImportStatement = `\nimport { ${Array.from(runtimeImports).join(", ")} } from 'alloy-di/runtime';\n`;
118
- const stubDeclarations = [];
123
+ }
124
+ function computeRuntimeImports(registrations, hasProviderModules) {
125
+ const imports = new Set(["Container", "dependenciesRegistry"]);
126
+ const needsLazyImport = registrations.some((m) => m.metadata.dependencies.some((d) => d.isLazy) || !!m.metadata.factory);
127
+ if (hasProviderModules) imports.add("applyProviders");
128
+ if (needsLazyImport) imports.add("Lazy");
129
+ if (registrations.length) imports.add("registerServiceIdentifier");
130
+ return imports;
131
+ }
132
+ function formatRuntimeImportStatement(imports) {
133
+ return `\nimport { ${Array.from(imports).join(", ")} } from 'alloy-di/runtime';\n`;
134
+ }
135
+ function createStubBlock(dependencyImports, registrations, runtimeImports) {
136
+ const statements = [];
119
137
  const importedNames = new Set(runtimeImports);
120
138
  for (const dep of dependencyImports) {
121
139
  if (dep.importPath === "alloy-di/runtime" && dep.originalName && dep.localName === dep.originalName && runtimeImports.has(dep.originalName)) continue;
122
140
  if (importedNames.has(dep.localName)) continue;
123
- if (dep.originalName === "default") stubDeclarations.push(`import ${dep.localName} from '${dep.importPath}';`);
124
- else if (dep.originalName === "*") stubDeclarations.push(`import * as ${dep.localName} from '${dep.importPath}';`);
125
- else if (dep.originalName && dep.originalName !== dep.localName) stubDeclarations.push(`import { ${dep.originalName} as ${dep.localName} } from '${dep.importPath}';`);
126
- else stubDeclarations.push(`import { ${dep.localName} } from '${dep.importPath}';`);
141
+ statements.push(createDependencyImportStatement(dep));
127
142
  importedNames.add(dep.localName);
128
143
  }
129
- for (const meta of resolvedImports) {
144
+ for (const meta of registrations) {
130
145
  if (meta.isFactoryLazy) {
131
- stubDeclarations.push(`class ${meta.importName} {}`);
146
+ statements.push(`class ${meta.importName} {}`);
132
147
  continue;
133
148
  }
134
149
  if (importedNames.has(meta.importName)) continue;
135
- const importPath = !/^(\/|[A-Za-z]:\\|\.|~)/.test(meta.filePath) && !meta.filePath.includes("\\") ? meta.filePath : normalizeImportPath(meta.filePath);
136
- if (meta.importName === meta.className) stubDeclarations.push(`import { ${meta.className} } from '${importPath}';`);
137
- else stubDeclarations.push(`import { ${meta.className} as ${meta.importName} } from '${importPath}';`);
150
+ statements.push(createServiceImportStatement(meta));
138
151
  importedNames.add(meta.importName);
139
152
  }
140
- const registrationEntries = resolvedImports.map((m) => ` { ctor: ${m.importName}, meta: ${m.optionsText} }`).join(",\n");
141
- const registrationsBlock = registrationEntries ? `const registrations = [\n${registrationEntries}\n];` : `const registrations = [];`;
142
- const stubsBlock = stubDeclarations.length ? `${stubDeclarations.join("\n")}\n` : "";
143
- const identifierDeclarations = resolvedImports.map((meta) => `const ${meta.identifierConst} = registerServiceIdentifier(${meta.importName}, Symbol.for('${escapeSingleQuotes(meta.symbolDescription)}'));`).join("\n");
144
- const identifierExportEntries = resolvedImports.map((meta) => ` '${meta.exportKey}': ${meta.identifierConst}`).join(",\n");
145
- return {
146
- runtimeImportStatement,
147
- registrationsBlock,
148
- stubsBlock,
149
- identifierDeclarations,
150
- identifierExportBlock: resolvedImports.length ? `${identifierDeclarations}\n\nexport const serviceIdentifiers = {\n${identifierExportEntries}\n};\n` : `export const serviceIdentifiers = {};\n`
151
- };
153
+ return statements.length ? `${statements.join("\n")}\n` : "";
154
+ }
155
+ function createDependencyImportStatement(dep) {
156
+ if (dep.originalName === "default") return `import ${dep.localName} from '${dep.importPath}';`;
157
+ if (dep.originalName === "*") return `import * as ${dep.localName} from '${dep.importPath}';`;
158
+ if (dep.originalName && dep.originalName !== dep.localName) return `import { ${dep.originalName} as ${dep.localName} } from '${dep.importPath}';`;
159
+ return `import { ${dep.localName} } from '${dep.importPath}';`;
160
+ }
161
+ function createServiceImportStatement(meta) {
162
+ const importPath = !/^(\/|[A-Za-z]:\\|\.|~)/.test(meta.filePath) && !meta.filePath.includes("\\") ? meta.filePath : normalizeImportPath(meta.filePath);
163
+ if (meta.importName === meta.className) return `import { ${meta.className} } from '${importPath}';`;
164
+ return `import { ${meta.className} as ${meta.importName} } from '${importPath}';`;
165
+ }
166
+ function buildRegistrationEntries(registrations) {
167
+ return registrations.map((m) => ({
168
+ ctorName: m.importName,
169
+ metaText: m.optionsText
170
+ }));
171
+ }
172
+ function createRegistrationsBlock(entries) {
173
+ if (!entries.length) return "const registrations = [];";
174
+ return `const registrations = [\n${entries.map((entry) => ` { ctor: ${entry.ctorName}, meta: ${entry.metaText} }`).join(",\n")}\n];`;
175
+ }
176
+ function createIdentifierExports(registrations) {
177
+ if (!registrations.length) return "export const serviceIdentifiers = {};\n";
178
+ return `${registrations.map((meta) => `const ${meta.identifierConst} = registerServiceIdentifier(${meta.importName}, Symbol.for('${escapeSingleQuotes(meta.symbolDescription)}'));`).join("\n")}\n\nexport const serviceIdentifiers = {\n${registrations.map((meta) => ` '${meta.exportKey}': ${meta.identifierConst}`).join(",\n")}\n};\n`;
152
179
  }
153
180
  /**
154
181
  * Generates the virtual container module code.
@@ -283,6 +310,5 @@ ${serviceIdentifiers}
283
310
  `;
284
311
  }).join("\n");
285
312
  }
286
-
287
313
  //#endregion
288
- export { generateContainerModule, generateContainerTypeDefinition, generateManifestTypeDefinition };
314
+ export { generateContainerModule, generateContainerTypeDefinition, generateManifestTypeDefinition };
@@ -1,6 +1,5 @@
1
1
  import { ServiceScope } from "../../lib/scope.js";
2
2
  import ts from "typescript";
3
-
4
3
  //#region src/plugins/core/decorators.ts
5
4
  function collectBindingIdentifiers(name, ignored) {
6
5
  if (ts.isIdentifier(name)) {
@@ -108,6 +107,5 @@ function extractServiceMetadata(decoratorName, callExpression, sourceFile) {
108
107
  dependencies
109
108
  };
110
109
  }
111
-
112
110
  //#endregion
113
- export { extractServiceMetadata };
111
+ export { extractServiceMetadata };
@@ -1,5 +1,4 @@
1
1
  import { scanSource } from "./scanner.js";
2
-
3
2
  //#region src/plugins/core/discovery-store.ts
4
3
  /**
5
4
  * Maintains a per-file cache of discovered DI metadata, lazy references, and
@@ -73,6 +72,5 @@ function createDiscoveryStore(options = {}) {
73
72
  clear
74
73
  };
75
74
  }
76
-
77
75
  //#endregion
78
- export { createDiscoveryStore };
76
+ export { createDiscoveryStore };
@@ -1,5 +1,4 @@
1
1
  import { createAliasName } from "./utils.js";
2
-
3
2
  //#region src/plugins/core/identifier-resolver.ts
4
3
  var IdentifierResolver = class {
5
4
  counts;
@@ -17,6 +16,5 @@ var IdentifierResolver = class {
17
16
  return this.count(className) > 1 ? createAliasName(className, importPath) : className;
18
17
  }
19
18
  };
20
-
21
19
  //#endregion
22
- export { IdentifierResolver };
20
+ export { IdentifierResolver };
@@ -1,7 +1,6 @@
1
1
  import { createClassKey } from "./utils.js";
2
2
  import ts from "typescript";
3
3
  import path from "path";
4
-
5
4
  //#region src/plugins/core/lazy.ts
6
5
  const RESOLVED_EXTENSIONS = [
7
6
  "",
@@ -15,22 +14,25 @@ const RESOLVED_EXTENSIONS = [
15
14
  function processLazyCall(node, fileId, sourceFile, localLazyRefs) {
16
15
  if (node.expression.getText(sourceFile) !== "Lazy") return;
17
16
  const classKeys = resolveLazyTarget(node, fileId);
18
- if (classKeys) for (const key of classKeys) localLazyRefs.add(key);
17
+ if (!classKeys) return;
18
+ for (const key of classKeys) localLazyRefs.add(key);
19
19
  }
20
20
  function resolveLazyTarget(node, fileId) {
21
- if (node.arguments.length === 0) return;
22
- const factory = node.arguments[0];
23
- if (!(ts.isArrowFunction(factory) || ts.isFunctionExpression(factory))) return;
21
+ const factory = getLazyFactory(node.arguments[0]);
22
+ if (!factory) return;
24
23
  const body = getReturnedExpression(factory);
25
24
  if (!body) return;
26
25
  const importInfo = extractImportInfo(body);
27
- if (!importInfo) return;
26
+ const exportName = importInfo?.exportName;
27
+ if (!importInfo || !exportName) return;
28
28
  const resolvedPaths = resolveModuleSpecifierCandidates(fileId, importInfo.specifier);
29
29
  if (!resolvedPaths.length) return;
30
- const exportName = importInfo.exportName;
31
- if (!exportName) return;
32
30
  return resolvedPaths.map((candidate) => createClassKey(candidate, exportName));
33
31
  }
32
+ function getLazyFactory(arg) {
33
+ if (!arg) return;
34
+ if (ts.isArrowFunction(arg) || ts.isFunctionExpression(arg)) return arg;
35
+ }
34
36
  function getReturnedExpression(fn) {
35
37
  if (ts.isBlock(fn.body)) {
36
38
  for (const statement of fn.body.statements) if (ts.isReturnStatement(statement) && statement.expression) return statement.expression;
@@ -39,40 +41,33 @@ function getReturnedExpression(fn) {
39
41
  return fn.body;
40
42
  }
41
43
  function extractImportInfo(expr) {
42
- if (ts.isCallExpression(expr)) {
43
- if (isDynamicImport(expr)) {
44
- const spec = getImportSpecifier(expr.arguments[0]);
45
- if (!spec) return;
46
- return {
47
- specifier: spec,
48
- exportName: void 0
49
- };
50
- }
51
- if (ts.isPropertyAccessExpression(expr.expression) && expr.expression.name.text === "then") {
52
- const importCall = expr.expression.expression;
53
- if (!ts.isCallExpression(importCall) || !isDynamicImport(importCall)) return;
54
- const spec = getImportSpecifier(importCall.arguments[0]);
55
- if (!spec) return;
56
- const callback = expr.arguments[0];
57
- return {
58
- specifier: spec,
59
- exportName: callback ? extractExportName(callback) : void 0
60
- };
61
- }
44
+ if (!ts.isCallExpression(expr)) return;
45
+ if (isDynamicImport(expr)) {
46
+ const spec = getImportSpecifier(expr.arguments[0]);
47
+ return spec ? { specifier: spec } : void 0;
62
48
  }
49
+ if (!ts.isPropertyAccessExpression(expr.expression)) return;
50
+ if (expr.expression.name.text !== "then") return;
51
+ const importCall = expr.expression.expression;
52
+ if (!ts.isCallExpression(importCall) || !isDynamicImport(importCall)) return;
53
+ const spec = getImportSpecifier(importCall.arguments[0]);
54
+ if (!spec) return;
55
+ const callback = expr.arguments[0];
56
+ return {
57
+ specifier: spec,
58
+ exportName: callback ? extractExportName(callback) : void 0
59
+ };
63
60
  }
64
61
  function isDynamicImport(node) {
65
62
  return node.expression.kind === ts.SyntaxKind.ImportKeyword;
66
63
  }
67
64
  function getImportSpecifier(node) {
68
- if (!node) return;
69
- if (ts.isStringLiteralLike(node)) return node.text;
65
+ return node && ts.isStringLiteralLike(node) ? node.text : void 0;
70
66
  }
71
67
  function extractExportName(callback) {
72
68
  if (ts.isArrowFunction(callback) || ts.isFunctionExpression(callback)) {
73
69
  const body = getReturnedExpression(callback);
74
- if (!body) return;
75
- return extractExportNameFromExpression(body);
70
+ return body ? extractExportNameFromExpression(body) : void 0;
76
71
  }
77
72
  return extractExportNameFromExpression(callback);
78
73
  }
@@ -85,14 +80,10 @@ function resolveModuleSpecifierCandidates(fromId, specifier) {
85
80
  if (!specifier.startsWith(".")) return [];
86
81
  const baseDir = path.dirname(fromId);
87
82
  const resolvedBase = path.resolve(baseDir, specifier);
88
- const candidates = [];
89
- if (Boolean(path.extname(resolvedBase))) candidates.push(resolvedBase);
90
- else {
91
- for (const ext of RESOLVED_EXTENSIONS) candidates.push(resolvedBase + ext);
92
- for (const ext of RESOLVED_EXTENSIONS) candidates.push(path.join(resolvedBase, "index" + ext));
93
- }
94
- return candidates;
83
+ if (path.extname(resolvedBase)) return [resolvedBase];
84
+ const fileCandidates = RESOLVED_EXTENSIONS.map((ext) => resolvedBase + ext);
85
+ const indexCandidates = RESOLVED_EXTENSIONS.map((ext) => path.join(resolvedBase, `index${ext}`));
86
+ return [...fileCandidates, ...indexCandidates];
95
87
  }
96
-
97
88
  //#endregion
98
- export { processLazyCall };
89
+ export { processLazyCall };