inwire 1.0.0 → 1.0.2

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/README.md CHANGED
@@ -2,13 +2,13 @@
2
2
 
3
3
  Zero-ceremony dependency injection for TypeScript. Full inference, no decorators, no tokens. Built-in introspection for AI tooling and debugging.
4
4
 
5
+ [![NPM Version](https://img.shields.io/npm/v/inwire)](https://www.npmjs.com/package/inwire)
6
+ [![CI](https://img.shields.io/github/actions/workflow/status/axelhamil/inwire/ci.yml)](https://github.com/axelhamil/inwire/actions)
5
7
  [![Bundle size](https://img.shields.io/bundlephobia/minzip/inwire)](https://bundlephobia.com/package/inwire)
6
- [![Dependencies](https://img.shields.io/librariesio/release/npm/inwire)](https://www.npmjs.com/package/inwire)
7
- [![Tests](https://img.shields.io/badge/tests-119%20passing-brightgreen)](https://github.com)
8
- [![Speed](https://img.shields.io/badge/tests-%3C30ms-brightgreen)](https://github.com)
9
- [![Coverage](https://img.shields.io/badge/coverage-%E2%89%A590%25-brightgreen)](./vitest.config.ts)
8
+ [![NPM Downloads](https://img.shields.io/npm/dm/inwire)](https://www.npmjs.com/package/inwire)
10
9
  [![TypeScript](https://img.shields.io/badge/TypeScript-strict-blue)](https://www.typescriptlang.org/)
11
- [![License](https://img.shields.io/badge/license-MIT-green)](./LICENSE)
10
+ [![License](https://img.shields.io/npm/l/inwire)](https://github.com/axelhamil/inwire/blob/main/LICENSE)
11
+ [![Zero Dependencies](https://img.shields.io/badge/dependencies-0-brightgreen)](https://www.npmjs.com/package/inwire)
12
12
 
13
13
  ## Install
14
14
 
@@ -1,3 +1,4 @@
1
+ //#region src/domain/types.d.ts
1
2
  /**
2
3
  * A factory function that receives the container and returns an instance.
3
4
  *
@@ -31,15 +32,13 @@ type DepsDefinition = Record<string, Factory>;
31
32
  * // { logger: LoggerService }
32
33
  * ```
33
34
  */
34
- type ResolvedDeps<T extends DepsDefinition> = {
35
- readonly [K in keyof T]: ReturnType<T[K]>;
36
- };
35
+ type ResolvedDeps<T extends DepsDefinition> = { readonly [K in keyof T]: ReturnType<T[K]> };
37
36
  /**
38
37
  * Options for creating a scoped container.
39
38
  */
40
39
  interface ScopeOptions {
41
- /** Optional name for the scope, useful for debugging and introspection. */
42
- name?: string;
40
+ /** Optional name for the scope, useful for debugging and introspection. */
41
+ name?: string;
43
42
  }
44
43
  /**
45
44
  * Full container type exposed to the user.
@@ -59,129 +58,130 @@ type Container<T extends Record<string, any> = Record<string, any>> = T & IConta
59
58
  * Container methods interface. Defines the API available on every container.
60
59
  */
61
60
  interface IContainer<T extends Record<string, any> = Record<string, any>> {
62
- /**
63
- * Creates a child container with additional dependencies.
64
- * Child inherits all parent singletons and can add/override deps.
65
- *
66
- * @example
67
- * ```typescript
68
- * const request = app.scope({
69
- * requestId: () => crypto.randomUUID(),
70
- * currentUser: () => extractUser(req),
71
- * });
72
- * request.requestId; // scoped singleton
73
- * request.logger; // inherited from parent
74
- * ```
75
- */
76
- scope<E extends DepsDefinition>(extra: E, options?: ScopeOptions): Container<T & ResolvedDeps<E>>;
77
- /**
78
- * Returns a new container with additional dependencies.
79
- * Existing singletons are shared. The original container is not modified.
80
- *
81
- * @example
82
- * ```typescript
83
- * const appWithAuth = app.extend(authDeps);
84
- * ```
85
- */
86
- extend<E extends DepsDefinition>(extra: E): Container<T & ResolvedDeps<E>>;
87
- /**
88
- * Pre-resolves dependencies (warm-up).
89
- * Call with specific keys to resolve only those, or without arguments to resolve all.
90
- *
91
- * @example
92
- * ```typescript
93
- * await container.preload('db', 'cache'); // specific deps
94
- * await container.preload(); // all deps
95
- * ```
96
- */
97
- preload(...keys: (keyof T)[]): Promise<void>;
98
- /**
99
- * Returns the full dependency graph as a serializable JSON object.
100
- * Useful for AI analysis of the architecture.
101
- *
102
- * @example
103
- * ```typescript
104
- * container.inspect();
105
- * // { providers: { logger: { key: 'logger', resolved: true, deps: [], scope: 'singleton' } } }
106
- * ```
107
- */
108
- inspect(): ContainerGraph;
109
- /**
110
- * Returns detailed information about a specific provider.
111
- *
112
- * @example
113
- * ```typescript
114
- * container.describe('userService');
115
- * // { key: 'userService', resolved: true, deps: ['userRepo', 'logger'], scope: 'singleton' }
116
- * ```
117
- */
118
- describe(key: keyof T): ProviderInfo;
119
- /**
120
- * Returns container health status and warnings.
121
- *
122
- * @example
123
- * ```typescript
124
- * container.health();
125
- * // { totalProviders: 12, resolved: ['db', 'logger'], unresolved: ['cache'], warnings: [] }
126
- * ```
127
- */
128
- health(): ContainerHealth;
129
- /**
130
- * Invalidates cached singletons, forcing re-creation on next access.
131
- * Does not affect parent scopes.
132
- *
133
- * @example
134
- * ```typescript
135
- * container.reset('db'); // reset one
136
- * container.reset('db', 'cache'); // reset multiple
137
- * ```
138
- */
139
- reset(...keys: (keyof T)[]): void;
140
- /**
141
- * Disposes the container. Calls `onDestroy()` on all resolved instances
142
- * that implement it, in reverse resolution order.
143
- *
144
- * @example
145
- * ```typescript
146
- * await container.dispose();
147
- * ```
148
- */
149
- dispose(): Promise<void>;
61
+ /**
62
+ * Creates a child container with additional dependencies.
63
+ * Child inherits all parent singletons and can add/override deps.
64
+ *
65
+ * @example
66
+ * ```typescript
67
+ * const request = app.scope({
68
+ * requestId: () => crypto.randomUUID(),
69
+ * currentUser: () => extractUser(req),
70
+ * });
71
+ * request.requestId; // scoped singleton
72
+ * request.logger; // inherited from parent
73
+ * ```
74
+ */
75
+ scope<E extends DepsDefinition>(extra: E, options?: ScopeOptions): Container<T & ResolvedDeps<E>>;
76
+ /**
77
+ * Returns a new container with additional dependencies.
78
+ * Existing singletons are shared. The original container is not modified.
79
+ *
80
+ * @example
81
+ * ```typescript
82
+ * const appWithAuth = app.extend(authDeps);
83
+ * ```
84
+ */
85
+ extend<E extends DepsDefinition>(extra: E): Container<T & ResolvedDeps<E>>;
86
+ /**
87
+ * Pre-resolves dependencies (warm-up).
88
+ * Call with specific keys to resolve only those, or without arguments to resolve all.
89
+ *
90
+ * @example
91
+ * ```typescript
92
+ * await container.preload('db', 'cache'); // specific deps
93
+ * await container.preload(); // all deps
94
+ * ```
95
+ */
96
+ preload(...keys: (keyof T)[]): Promise<void>;
97
+ /**
98
+ * Returns the full dependency graph as a serializable JSON object.
99
+ * Useful for AI analysis of the architecture.
100
+ *
101
+ * @example
102
+ * ```typescript
103
+ * container.inspect();
104
+ * // { providers: { logger: { key: 'logger', resolved: true, deps: [], scope: 'singleton' } } }
105
+ * ```
106
+ */
107
+ inspect(): ContainerGraph;
108
+ /**
109
+ * Returns detailed information about a specific provider.
110
+ *
111
+ * @example
112
+ * ```typescript
113
+ * container.describe('userService');
114
+ * // { key: 'userService', resolved: true, deps: ['userRepo', 'logger'], scope: 'singleton' }
115
+ * ```
116
+ */
117
+ describe(key: keyof T): ProviderInfo;
118
+ /**
119
+ * Returns container health status and warnings.
120
+ *
121
+ * @example
122
+ * ```typescript
123
+ * container.health();
124
+ * // { totalProviders: 12, resolved: ['db', 'logger'], unresolved: ['cache'], warnings: [] }
125
+ * ```
126
+ */
127
+ health(): ContainerHealth;
128
+ /**
129
+ * Invalidates cached singletons, forcing re-creation on next access.
130
+ * Does not affect parent scopes.
131
+ *
132
+ * @example
133
+ * ```typescript
134
+ * container.reset('db'); // reset one
135
+ * container.reset('db', 'cache'); // reset multiple
136
+ * ```
137
+ */
138
+ reset(...keys: (keyof T)[]): void;
139
+ /**
140
+ * Disposes the container. Calls `onDestroy()` on all resolved instances
141
+ * that implement it, in reverse resolution order.
142
+ *
143
+ * @example
144
+ * ```typescript
145
+ * await container.dispose();
146
+ * ```
147
+ */
148
+ dispose(): Promise<void>;
150
149
  }
151
150
  /**
152
151
  * Full dependency graph of the container.
153
152
  */
154
153
  interface ContainerGraph {
155
- name?: string;
156
- providers: Record<string, ProviderInfo>;
154
+ name?: string;
155
+ providers: Record<string, ProviderInfo>;
157
156
  }
158
157
  /**
159
158
  * Detailed information about a single provider/dependency.
160
159
  */
161
160
  interface ProviderInfo {
162
- key: string;
163
- resolved: boolean;
164
- deps: string[];
165
- scope: 'singleton' | 'transient';
161
+ key: string;
162
+ resolved: boolean;
163
+ deps: string[];
164
+ scope: 'singleton' | 'transient';
166
165
  }
167
166
  /**
168
167
  * Container health status with warnings.
169
168
  */
170
169
  interface ContainerHealth {
171
- totalProviders: number;
172
- resolved: string[];
173
- unresolved: string[];
174
- warnings: ContainerWarning[];
170
+ totalProviders: number;
171
+ resolved: string[];
172
+ unresolved: string[];
173
+ warnings: ContainerWarning[];
175
174
  }
176
175
  /**
177
176
  * A warning detected by the container's runtime analysis.
178
177
  */
179
178
  interface ContainerWarning {
180
- type: 'scope_mismatch' | 'duplicate_key';
181
- message: string;
182
- details: Record<string, unknown>;
179
+ type: 'scope_mismatch' | 'duplicate_key';
180
+ message: string;
181
+ details: Record<string, unknown>;
183
182
  }
184
-
183
+ //#endregion
184
+ //#region src/domain/errors.d.ts
185
185
  /**
186
186
  * Base class for all container errors.
187
187
  * Every error includes a human-readable `hint` and structured `details`
@@ -199,9 +199,9 @@ interface ContainerWarning {
199
199
  * ```
200
200
  */
201
201
  declare abstract class ContainerError extends Error {
202
- abstract readonly hint: string;
203
- abstract readonly details: Record<string, unknown>;
204
- constructor(message: string);
202
+ abstract readonly hint: string;
203
+ abstract readonly details: Record<string, unknown>;
204
+ constructor(message: string);
205
205
  }
206
206
  /**
207
207
  * Thrown when a non-function value is passed in the deps definition.
@@ -214,9 +214,9 @@ declare abstract class ContainerError extends Error {
214
214
  * ```
215
215
  */
216
216
  declare class ContainerConfigError extends ContainerError {
217
- readonly hint: string;
218
- readonly details: Record<string, unknown>;
219
- constructor(key: string, actualType: string);
217
+ readonly hint: string;
218
+ readonly details: Record<string, unknown>;
219
+ constructor(key: string, actualType: string);
220
220
  }
221
221
  /**
222
222
  * Thrown when a reserved container method name is used as a dependency key.
@@ -229,9 +229,9 @@ declare class ContainerConfigError extends ContainerError {
229
229
  * ```
230
230
  */
231
231
  declare class ReservedKeyError extends ContainerError {
232
- readonly hint: string;
233
- readonly details: Record<string, unknown>;
234
- constructor(key: string, reserved: readonly string[]);
232
+ readonly hint: string;
233
+ readonly details: Record<string, unknown>;
234
+ constructor(key: string, reserved: readonly string[]);
235
235
  }
236
236
  /**
237
237
  * Thrown when a dependency cannot be found during resolution.
@@ -245,9 +245,9 @@ declare class ReservedKeyError extends ContainerError {
245
245
  * ```
246
246
  */
247
247
  declare class ProviderNotFoundError extends ContainerError {
248
- readonly hint: string;
249
- readonly details: Record<string, unknown>;
250
- constructor(key: string, chain: string[], registered: string[], suggestion?: string);
248
+ readonly hint: string;
249
+ readonly details: Record<string, unknown>;
250
+ constructor(key: string, chain: string[], registered: string[], suggestion?: string);
251
251
  }
252
252
  /**
253
253
  * Thrown when a circular dependency is detected.
@@ -259,9 +259,9 @@ declare class ProviderNotFoundError extends ContainerError {
259
259
  * ```
260
260
  */
261
261
  declare class CircularDependencyError extends ContainerError {
262
- readonly hint: string;
263
- readonly details: Record<string, unknown>;
264
- constructor(key: string, chain: string[]);
262
+ readonly hint: string;
263
+ readonly details: Record<string, unknown>;
264
+ constructor(key: string, chain: string[]);
265
265
  }
266
266
  /**
267
267
  * Thrown when a factory function returns `undefined`.
@@ -274,9 +274,9 @@ declare class CircularDependencyError extends ContainerError {
274
274
  * ```
275
275
  */
276
276
  declare class UndefinedReturnError extends ContainerError {
277
- readonly hint: string;
278
- readonly details: Record<string, unknown>;
279
- constructor(key: string, chain: string[]);
277
+ readonly hint: string;
278
+ readonly details: Record<string, unknown>;
279
+ constructor(key: string, chain: string[]);
280
280
  }
281
281
  /**
282
282
  * Thrown when a factory function throws an error during resolution.
@@ -289,10 +289,10 @@ declare class UndefinedReturnError extends ContainerError {
289
289
  * ```
290
290
  */
291
291
  declare class FactoryError extends ContainerError {
292
- readonly hint: string;
293
- readonly details: Record<string, unknown>;
294
- readonly originalError: unknown;
295
- constructor(key: string, chain: string[], originalError: unknown);
292
+ readonly hint: string;
293
+ readonly details: Record<string, unknown>;
294
+ readonly originalError: unknown;
295
+ constructor(key: string, chain: string[], originalError: unknown);
296
296
  }
297
297
  /**
298
298
  * Warning emitted when a singleton depends on a transient dependency.
@@ -303,14 +303,15 @@ declare class FactoryError extends ContainerError {
303
303
  * // ScopeMismatchWarning: Singleton 'userService' depends on transient 'requestId'.
304
304
  * ```
305
305
  */
306
- declare class ScopeMismatchWarning {
307
- readonly type: "scope_mismatch";
308
- readonly message: string;
309
- readonly hint: string;
310
- readonly details: Record<string, unknown>;
311
- constructor(singletonKey: string, transientKey: string);
306
+ declare class ScopeMismatchWarning implements ContainerWarning {
307
+ readonly type: "scope_mismatch";
308
+ readonly message: string;
309
+ readonly hint: string;
310
+ readonly details: Record<string, unknown>;
311
+ constructor(singletonKey: string, transientKey: string);
312
312
  }
313
-
313
+ //#endregion
314
+ //#region src/application/create-container.d.ts
314
315
  /**
315
316
  * Creates a dependency injection container from an object of factory functions.
316
317
  * Each factory receives the container and returns an instance.
@@ -329,7 +330,8 @@ declare class ScopeMismatchWarning {
329
330
  * ```
330
331
  */
331
332
  declare function createContainer<T extends DepsDefinition>(defs: T): Container<ResolvedDeps<T>>;
332
-
333
+ //#endregion
334
+ //#region src/infrastructure/transient.d.ts
333
335
  /**
334
336
  * Wraps a factory function to produce a new instance on every access,
335
337
  * instead of the default singleton behavior.
@@ -348,7 +350,8 @@ declare function createContainer<T extends DepsDefinition>(defs: T): Container<R
348
350
  * ```
349
351
  */
350
352
  declare function transient<T>(factory: Factory<T>): Factory<T>;
351
-
353
+ //#endregion
354
+ //#region src/domain/lifecycle.d.ts
352
355
  /**
353
356
  * Implement this interface (or just add an `onInit` method) to run
354
357
  * initialization logic when the dependency is first resolved.
@@ -361,7 +364,7 @@ declare function transient<T>(factory: Factory<T>): Factory<T>;
361
364
  * ```
362
365
  */
363
366
  interface OnInit {
364
- onInit(): void | Promise<void>;
367
+ onInit(): void | Promise<void>;
365
368
  }
366
369
  /**
367
370
  * Implement this interface (or just add an `onDestroy` method) to run
@@ -375,13 +378,15 @@ interface OnInit {
375
378
  * ```
376
379
  */
377
380
  interface OnDestroy {
378
- onDestroy(): void | Promise<void>;
381
+ onDestroy(): void | Promise<void>;
379
382
  }
380
-
383
+ //#endregion
384
+ //#region src/domain/validation.d.ts
381
385
  /**
382
386
  * Detects duplicate keys across multiple modules (spread objects).
383
387
  * Returns an array of keys that appear in more than one source.
384
388
  */
385
389
  declare function detectDuplicateKeys(...modules: Record<string, unknown>[]): string[];
386
-
390
+ //#endregion
387
391
  export { CircularDependencyError, type Container, ContainerConfigError, ContainerError, type ContainerGraph, type ContainerHealth, type ContainerWarning, type DepsDefinition, type Factory, FactoryError, type IContainer, type OnDestroy, type OnInit, type ProviderInfo, ProviderNotFoundError, ReservedKeyError, type ResolvedDeps, ScopeMismatchWarning, type ScopeOptions, UndefinedReturnError, createContainer, detectDuplicateKeys, transient };
392
+ //# sourceMappingURL=index.d.mts.map
package/dist/index.mjs ADDED
@@ -0,0 +1,4 @@
1
+ function e(e){return typeof e==`object`&&!!e&&`onInit`in e&&typeof e.onInit==`function`}function t(e){return typeof e==`object`&&!!e&&`onDestroy`in e&&typeof e.onDestroy==`function`}const n=[`scope`,`extend`,`preload`,`reset`,`inspect`,`describe`,`health`,`dispose`,`toString`];var r=class extends Error{constructor(e){super(e),this.name=this.constructor.name}},i=class extends r{hint;details;constructor(e,t){super(`'${e}' must be a factory function, got ${t}.`),this.hint=`Wrap it: ${e}: () => ${JSON.stringify(e===e?`<your ${t} value>`:e)}`,this.details={key:e,actualType:t}}},a=class extends r{hint;details;constructor(e,t){super(`'${e}' is a reserved container method.`),this.hint=`Rename this dependency, e.g. '${e}Service' or 'my${e[0].toUpperCase()}${e.slice(1)}'.`,this.details={key:e,reserved:[...t]}}},o=class extends r{hint;details;constructor(e,t,n,r){let i=t.length>0?`\n\nResolution chain: ${[...t,`${e} (not found)`].join(` -> `)}`:``,a=`\nRegistered keys: [${n.join(`, `)}]`,o=r?`\n\nDid you mean '${r}'?`:``;super(`Cannot resolve '${t[0]??e}': dependency '${e}' not found.${i}${a}${o}`),this.hint=r?`Did you mean '${r}'? Or add '${e}' to your container:\n createContainer({\n ...existing,\n ${e}: (c) => new Your${e[0].toUpperCase()}${e.slice(1)}(/* deps */),\n });`:`Add '${e}' to your container:\n createContainer({\n ...existing,\n ${e}: (c) => new Your${e[0].toUpperCase()}${e.slice(1)}(/* deps */),\n });`,this.details={key:e,chain:t,registered:n,suggestion:r}}},s=class extends r{hint;details;constructor(e,t){let n=[...t,e].join(` -> `);super(`Circular dependency detected while resolving '${t[0]}'.\n\nCycle: ${n}`),this.hint=[`To fix:`,` 1. Extract shared logic into a new dependency both can use`,` 2. Restructure so one doesn't depend on the other`,` 3. Use a mediator/event pattern to decouple them`].join(`
2
+ `),this.details={key:e,chain:t,cycle:n}}},c=class extends r{hint;details;constructor(e,t){let n=t.length>1?`\n\nResolution chain: ${t.join(` -> `)}`:``;super(`Factory '${e}' returned undefined.${n}`),this.hint=`Your factory function returned undefined. Did you forget a return statement?`,this.details={key:e,chain:t}}},l=class extends r{hint;details;originalError;constructor(e,t,n){let r=n instanceof Error?n.message:String(n),i=t.length>1?`\n\nResolution chain: ${[...t.slice(0,-1),`${e} (factory threw)`].join(` -> `)}`:``;super(`Factory '${e}' threw an error: "${r}"${i}`),this.hint=`Check the factory function for '${e}'. The error occurred during instantiation.`,this.details={key:e,chain:t,originalError:r},this.originalError=n}},u=class{type=`scope_mismatch`;message;hint;details;constructor(e,t){this.message=`Singleton '${e}' depends on transient '${t}'.`,this.hint=[`The transient value was resolved once and is now frozen inside the singleton.`,`This is almost always a bug.`,``,`To fix:`,` 1. Make '${e}' transient too: transient((c) => new ${e[0].toUpperCase()}${e.slice(1)}(c.${t}))`,` 2. Make '${t}' singleton if it doesn't need to change`,` 3. Inject a factory instead: ${t}Factory: () => () => <your value>`].join(`
3
+ `),this.details={singleton:e,transient:t}}},d=class{validateConfig(e){for(let[t,r]of Object.entries(e)){if(n.includes(t))throw new a(t,n);if(typeof r!=`function`)throw new i(t,typeof r)}}suggestKey(e,t){let n,r=1/0;for(let i of t){let t=p(e,i);t<r&&(r=t,n=i)}if(!n)return;let i=Math.max(e.length,n.length);return 1-r/i>=.5?n:void 0}};function f(...e){let t=new Map,n=[];for(let r of e)for(let e of Object.keys(r)){let r=(t.get(e)??0)+1;t.set(e,r),r===2&&n.push(e)}return n}function p(e,t){let n=e.length,r=t.length;if(n===0)return r;if(r===0)return n;let i=Array(r+1),a=Array(r+1);for(let e=0;e<=r;e++)i[e]=e;for(let o=1;o<=n;o++){a[0]=o;for(let n=1;n<=r;n++){let r=e[o-1]===t[n-1]?0:1;a[n]=Math.min(i[n]+1,a[n-1]+1,i[n-1]+r)}[i,a]=[a,i]}return i[r]}const m=Symbol.for(`inwire:transient`);function h(e){let t=(t=>e(t));return t[m]=!0,t}function g(e){return typeof e==`function`&&m in e&&e[m]===!0}var _=class{factories;cache;resolving=new Set;depGraph=new Map;warnings=[];validator=new d;parent;name;constructor(e,t,n,r){this.factories=e,this.cache=t??new Map,this.parent=n,this.name=r}getName(){return this.name}resolve(t,n=[]){let r=this.factories.get(t);if(r&&!g(r)&&this.cache.has(t))return this.cache.get(t);if(!r){if(this.parent)return this.parent.resolve(t,n);let e=this.getAllRegisteredKeys();throw new o(t,n,e,this.validator.suggestKey(t,e))}if(this.resolving.has(t))throw new s(t,[...n]);this.resolving.add(t);let i=[...n,t];try{let n=[],a=r(this.createTrackingProxy(t,n,i));if(a===void 0)throw new c(t,i);if(this.depGraph.set(t,n),!g(r))for(let e of n){let n=this.getFactory(e);n&&g(n)&&this.warnings.push(new u(t,e))}if(g(r)||this.cache.set(t,a),e(a)){let e=a.onInit();e instanceof Promise&&e.catch(()=>{})}return a}catch(e){throw e instanceof s||e instanceof o||e instanceof c||e instanceof l?e:new l(t,i,e)}finally{this.resolving.delete(t)}}isResolved(e){return this.cache.has(e)}getDepGraph(){return new Map(this.depGraph)}getResolvedKeys(){return[...this.cache.keys()]}getFactories(){return this.factories}getCache(){return this.cache}getWarnings(){return[...this.warnings]}getAllRegisteredKeys(){let e=new Set(this.factories.keys());if(this.parent)for(let t of this.parent.getAllRegisteredKeys())e.add(t);return[...e]}createTrackingProxy(e,t,n){return new Proxy({},{get:(e,r)=>{if(typeof r==`symbol`)return;let i=r;return t.push(i),this.resolve(i,n)}})}getFactory(e){return this.factories.get(e)??this.parent?.getFactory(e)}},v=class{constructor(e){this.resolver=e}inspect(){let e={};for(let[t,n]of this.resolver.getFactories())e[t]={key:t,resolved:this.resolver.isResolved(t),deps:this.resolver.getDepGraph().get(t)??[],scope:g(n)?`transient`:`singleton`};let t=this.resolver.getName();return t?{name:t,providers:e}:{providers:e}}describe(e){let t=this.resolver.getFactories().get(e);return t?{key:e,resolved:this.resolver.isResolved(e),deps:this.resolver.getDepGraph().get(e)??[],scope:g(t)?`transient`:`singleton`}:{key:e,resolved:!1,deps:[],scope:`singleton`}}health(){let e=[...this.resolver.getFactories().keys()],t=this.resolver.getResolvedKeys(),n=new Set(t),r=this.resolver.getWarnings().map(e=>({type:e.type,message:e.message,details:e.details}));return{totalProviders:e.length,resolved:t,unresolved:e.filter(e=>!n.has(e)),warnings:r}}toString(){let e=[];for(let[t]of this.resolver.getFactories()){let n=this.resolver.isResolved(t),r=this.resolver.getDepGraph().get(t),i=r&&r.length>0?` -> [${r.join(`, `)}]`:``,a=n?`(resolved)`:`(pending)`;e.push(`${t}${i} ${a}`)}let t=this.resolver.getName();return`${t?`Scope(${t})`:`Container`} { ${e.join(`, `)} }`}};function y(e,t,n){let r=new Map;for(let[e,n]of Object.entries(t))r.set(e,n);return S(new _(r,new Map,e,n?.name))}const b=new d;function x(e){b.validateConfig(e);let t=new Map;for(let[n,r]of Object.entries(e))t.set(n,r);return S(new _(t))}function S(e){let n=new v(e),r={scope:(t,n)=>y(e,t,n),extend:t=>{b.validateConfig(t);let n=new Map(e.getFactories());for(let[e,r]of Object.entries(t))n.set(e,r);return S(new _(n,new Map(e.getCache())))},preload:async(...t)=>{let n=t.length>0?t:[...e.getFactories().keys()];for(let t of n)e.resolve(t)},reset:(...t)=>{let n=e.getCache();for(let e of t)n.delete(e)},inspect:()=>n.inspect(),describe:e=>n.describe(e),health:()=>n.health(),toString:()=>n.toString(),dispose:async()=>{let n=e.getCache(),r=[...n.entries()].reverse();for(let[,e]of r)t(e)&&await e.onDestroy();n.clear()}};return new Proxy({},{get(t,i){if(typeof i==`symbol`)return i===Symbol.toPrimitive||i===Symbol.toStringTag?()=>n.toString():void 0;let a=i;return a in r?r[a]:e.resolve(a)},has(t,n){if(typeof n==`symbol`)return!1;let i=n;return i in r||e.getFactories().has(i)||e.getAllRegisteredKeys().includes(i)},ownKeys(){return[...e.getAllRegisteredKeys(),...Object.keys(r)]},getOwnPropertyDescriptor(t,n){if(typeof n==`symbol`)return;let i=n;if(i in r||e.getFactories().has(i)||e.getAllRegisteredKeys().includes(i))return{configurable:!0,enumerable:!(i in r),writable:!1}}})}export{s as CircularDependencyError,i as ContainerConfigError,r as ContainerError,l as FactoryError,o as ProviderNotFoundError,a as ReservedKeyError,u as ScopeMismatchWarning,c as UndefinedReturnError,x as createContainer,f as detectDuplicateKeys,h as transient};
4
+ //# sourceMappingURL=index.mjs.map
package/package.json CHANGED
@@ -1,30 +1,22 @@
1
1
  {
2
2
  "name": "inwire",
3
- "version": "1.0.0",
3
+ "version": "1.0.2",
4
4
  "description": "Zero-ceremony dependency injection for TypeScript. Full inference, no decorators, no tokens. Built-in introspection for AI tooling.",
5
5
  "type": "module",
6
- "main": "./dist/index.cjs",
7
- "module": "./dist/index.js",
8
- "types": "./dist/index.d.ts",
6
+ "main": "./dist/index.mjs",
7
+ "types": "./dist/index.d.mts",
9
8
  "exports": {
10
9
  ".": {
11
- "import": {
12
- "types": "./dist/index.d.ts",
13
- "default": "./dist/index.js"
14
- },
15
- "require": {
16
- "types": "./dist/index.d.cts",
17
- "default": "./dist/index.cjs"
18
- }
10
+ "types": "./dist/index.d.mts",
11
+ "default": "./dist/index.mjs"
19
12
  }
20
13
  },
21
14
  "files": [
22
15
  "dist",
23
- "llms.txt",
24
- "llms-full.txt"
16
+ "!dist/*.map"
25
17
  ],
26
18
  "scripts": {
27
- "build": "tsup",
19
+ "build": "tsdown",
28
20
  "test": "vitest run",
29
21
  "test:watch": "vitest",
30
22
  "test:coverage": "vitest run --coverage",
@@ -56,8 +48,9 @@
56
48
  "@semantic-release/changelog": "^6.0.0",
57
49
  "@semantic-release/git": "^10.0.0",
58
50
  "@vitest/coverage-v8": "^3.2.4",
51
+ "publint": "^0.3.17",
59
52
  "semantic-release": "^24.0.0",
60
- "tsup": "^8.0.0",
53
+ "tsdown": "^0.20.3",
61
54
  "typescript": "^5.4.0",
62
55
  "vitest": "^3.0.0"
63
56
  }