@resolid/di 0.6.1 → 0.7.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -17,7 +17,6 @@ and avoids circular dependency issues.
17
17
  - Optional dependency resolution.
18
18
  - Detects circular dependencies.
19
19
  - Handles disposable instances with dispose() support.
20
- - Fully async-compatible with inject() and injectAsync() functions.
21
20
  - Context-aware injection with InjectionContext.
22
21
 
23
22
  ## Installation
@@ -95,58 +94,6 @@ container.add({
95
94
  });
96
95
  ```
97
96
 
98
- ### Asynchronous Dependencies
99
-
100
- ```typescript
101
- import { Container, injectAsync } from "@resolid/di";
102
-
103
- class AsyncDatabaseService {
104
- async connect(): Promise<void> {
105
- await new Promise((resolve) => setTimeout(resolve, 100));
106
- console.log("Database connected");
107
- }
108
- }
109
-
110
- class AsyncUserService {
111
- private db: AsyncDatabaseService;
112
-
113
- constructor(db: AsyncDatabaseService) {
114
- this.db = db;
115
- }
116
-
117
- async getUser(id: number): Promise<string> {
118
- return `User ${id}`;
119
- }
120
- }
121
-
122
- const container = new Container();
123
-
124
- container.add({
125
- token: AsyncDatabaseService,
126
- factory: async () => {
127
- const db = new AsyncDatabaseService();
128
- await db.connect();
129
- return db;
130
- },
131
- async: true,
132
- });
133
-
134
- container.add({
135
- token: AsyncUserService,
136
- factory: async () => {
137
- const db = await injectAsync(AsyncDatabaseService);
138
- return new AsyncUserService(db);
139
- },
140
- async: true,
141
- });
142
-
143
- // Resolve async services
144
- const userService = await container.getAsync(AsyncUserService);
145
- const user = await userService.getUser(1);
146
-
147
- console.log(user); // Output: User 1
148
- ```
149
-
150
97
  ### Optional Dependencies
151
98
 
152
99
  ```typescript
@@ -255,11 +202,10 @@ const container = new Container();
255
202
 
256
203
  container.add({
257
204
  token: DatabaseConnection,
258
- factory: async () => new DatabaseConnection(),
259
- async: true,
205
+ factory: () => new DatabaseConnection(),
260
206
  });
261
207
 
262
- const db = await container.getAsync(DatabaseConnection);
208
+ const db = container.get(DatabaseConnection);
263
209
 
264
210
  // Dispose all singleton instances
265
211
  await container.dispose(); // Output: Database connection closed
@@ -21,45 +21,21 @@ interface Resolver {
21
21
  lazy?: boolean;
22
22
  optional?: boolean;
23
23
  }) => T | undefined | (() => T | undefined));
24
- getAsync: (<T>(token: Token<T>) => Promise<T>) & (<T>(token: Token<T>, options: {
25
- optional: true;
26
- }) => Promise<T | undefined>) & (<T>(token: Token<T>, options: {
27
- lazy: true;
28
- }) => () => Promise<T>) & (<T>(token: Token<T>, options: {
29
- lazy: true;
30
- optional: true;
31
- }) => () => Promise<T | undefined>) & (<T>(token: Token<T>, options: {
32
- lazy?: false;
33
- optional?: boolean;
34
- }) => Promise<T | undefined>) & (<T>(token: Token<T>, options?: {
35
- lazy?: boolean;
36
- optional?: boolean;
37
- }) => Promise<T | undefined> | (() => Promise<T | undefined>));
38
24
  }
39
25
  //#endregion
40
26
  //#region src/container/index.d.ts
41
27
  type Scope = "singleton" | "transient";
42
- type SyncProvider<T = unknown> = {
43
- token: Token<T>;
44
- factory: (resolver: Resolver) => T;
45
- async?: false;
46
- scope?: Scope;
47
- };
48
- type AsyncProvider<T = unknown> = {
28
+ interface Provider<T = unknown> {
49
29
  token: Token<T>;
50
- factory: (resolver: Resolver) => Promise<T>;
51
- async?: true;
30
+ factory: () => T;
52
31
  scope?: Scope;
53
- };
54
- type Provider<T = unknown> = SyncProvider<T> | AsyncProvider<T>;
32
+ }
55
33
  declare class Container implements Resolver, Disposable {
56
34
  private readonly _providers;
57
35
  private readonly _singletons;
58
36
  private readonly _constructing;
59
37
  private _checkCircularDependency;
60
- private _resolveProvide;
61
38
  private _resolve;
62
- private _resolveAsync;
63
39
  add(provider: Provider): void;
64
40
  get<T>(token: Token<T>): T;
65
41
  get<T>(token: Token<T>, options: {
@@ -73,24 +49,9 @@ declare class Container implements Resolver, Disposable {
73
49
  optional: true;
74
50
  }): () => T | undefined;
75
51
  get<T>(token: Token<T>, options: {
76
- lazy?: false;
52
+ lazy: false;
77
53
  optional?: boolean;
78
54
  }): T | undefined;
79
- getAsync<T>(token: Token<T>): Promise<T>;
80
- getAsync<T>(token: Token<T>, options: {
81
- optional: true;
82
- }): Promise<T | undefined>;
83
- getAsync<T>(token: Token<T>, options: {
84
- lazy: true;
85
- }): () => Promise<T>;
86
- getAsync<T>(token: Token<T>, options: {
87
- lazy: true;
88
- optional: true;
89
- }): () => Promise<T | undefined>;
90
- getAsync<T>(token: Token<T>, options: {
91
- lazy?: false;
92
- optional?: boolean;
93
- }): Promise<T | undefined>;
94
55
  dispose(): Promise<void>;
95
56
  }
96
57
  //#endregion
@@ -106,16 +67,5 @@ declare function inject<T>(token: Token<T>, options: {
106
67
  lazy: true;
107
68
  optional: true;
108
69
  }): () => T | undefined;
109
- declare function injectAsync<T>(token: Token<T>): Promise<T>;
110
- declare function injectAsync<T>(token: Token<T>, options: {
111
- optional: true;
112
- }): Promise<T | undefined>;
113
- declare function injectAsync<T>(token: Token<T>, options: {
114
- lazy: true;
115
- }): () => Promise<T>;
116
- declare function injectAsync<T>(token: Token<T>, options: {
117
- lazy: true;
118
- optional: true;
119
- }): () => Promise<T | undefined>;
120
70
  //#endregion
121
- export { Container, Provider, type Resolver, Scope, type Token, inject, injectAsync };
71
+ export { Container, Provider, Scope, type Token, inject };
package/dist/index.mjs ADDED
@@ -0,0 +1 @@
1
+ var e=class extends Error{constructor(){super(`inject() must be called within a injection context`)}},t=class t{static contextStack=[];resolver;constructor(e){this.resolver=e}static current(){let t=this.contextStack[this.contextStack.length-1];if(t===void 0)throw new e;return t}run(e){t.contextStack.push(this);try{return e(this.resolver)}finally{t.contextStack.pop()}}};function n(e){return typeof e==`symbol`?e.description??String(e):e.name}var r=class{_providers=new Map;_singletons=new Map;_constructing=[];_checkCircularDependency(e){if(this._constructing.includes(e))throw Error(`Circular dependency detected ${[...this._constructing,e].map(n).join(` -> `)}`)}_resolve(e,r){this._checkCircularDependency(e);let i=this._providers.get(e);if(i===void 0){if(!r)throw Error(`No provider found for ${n(e)}`);return}let a=i.scope!==`transient`;if(a&&this._singletons.has(e))return this._singletons.get(e);this._constructing.push(e);try{let n=new t(this).run(()=>i.factory());return a&&this._singletons.set(e,n),n}finally{this._constructing.pop()}}add(e){this._providers.set(e.token,e)}get(e,t){return t?.lazy??!1?()=>this.get(e,{...t,lazy:!1}):this._resolve(e,t?.optional??!1)}async dispose(){let e=0,t=``;for(let[r,i]of this._singletons)if(typeof i.dispose==`function`)try{await i.dispose()}catch(i){e++,t+=`${n(r)}: ${i instanceof Error?i.message:i}; `}if(this._singletons.clear(),e>0)throw Error(`Failed to dispose ${e} provider(s):\n${t.slice(0,-2)}`)}};function i(n,r){try{return t.current().run(e=>e.get(n,r))}catch(t){if(t instanceof e&&r?.optional==1)return;throw t}}export{r as Container,i as inject};
package/package.json CHANGED
@@ -1,56 +1,53 @@
1
1
  {
2
2
  "name": "@resolid/di",
3
- "version": "0.6.1",
3
+ "version": "0.7.1",
4
4
  "private": false,
5
5
  "description": "TypeScript Dependency Injection Container",
6
6
  "keywords": [
7
- "resolid",
8
7
  "container",
9
- "ioc",
10
- "inversion of control",
8
+ "dependency injection",
11
9
  "di",
12
- "dependency injection"
10
+ "inversion of control",
11
+ "ioc",
12
+ "resolid"
13
13
  ],
14
14
  "homepage": "https://www.resolid.tech",
15
- "repository": {
16
- "type": "git",
17
- "url": "git+https://github.com/resolid/framework.git",
18
- "directory": "packages/di"
19
- },
20
15
  "license": "MIT",
21
16
  "author": {
22
17
  "name": "Huijie Wei",
23
18
  "email": "hello@resolid.tech"
24
19
  },
25
- "sideEffects": false,
26
- "type": "module",
27
- "exports": {
28
- ".": {
29
- "types": "./dist/index.d.ts",
30
- "import": "./dist/index.js"
31
- }
20
+ "repository": {
21
+ "type": "git",
22
+ "url": "git+https://github.com/resolid/framework.git",
23
+ "directory": "packages/di"
32
24
  },
33
- "main": "./dist/index.js",
34
- "types": "./dist/index.d.ts",
35
25
  "files": [
36
26
  "dist"
37
27
  ],
38
- "devDependencies": {
39
- "@vitest/coverage-v8": "^4.0.4",
40
- "tsdown": "^0.15.11",
41
- "typescript": "^5.9.3",
42
- "vitest": "^4.0.4"
43
- },
44
- "engines": {
45
- "node": "^20.19.0 || ^22.13.0 || >=24"
28
+ "type": "module",
29
+ "sideEffects": false,
30
+ "types": "./dist/index.d.mts",
31
+ "exports": {
32
+ ".": {
33
+ "types": "./dist/index.d.mts",
34
+ "import": "./dist/index.mjs"
35
+ }
46
36
  },
47
37
  "publishConfig": {
48
38
  "access": "public",
49
39
  "provenance": true
50
40
  },
41
+ "devDependencies": {
42
+ "tsdown": "^0.20.3",
43
+ "typescript": "^5.9.3"
44
+ },
45
+ "engines": {
46
+ "node": "^22.13.0 || >=24"
47
+ },
51
48
  "scripts": {
52
49
  "build": "tsdown",
53
- "lint": "eslint .",
50
+ "lint": "oxlint",
54
51
  "test": "vitest run",
55
52
  "typecheck": "tsc --noEmit"
56
53
  }
package/dist/index.js DELETED
@@ -1 +0,0 @@
1
- var e=class extends Error{constructor(){super(`inject() / injectAsync() must be called within a injection context`)}},t=class t{static contextStack=[];resolver;constructor(e){this.resolver=e}static current(){let t=this.contextStack[this.contextStack.length-1];if(t===void 0)throw new e;return t}run(e){t.contextStack.push(this);try{return e(this.resolver)}finally{t.contextStack.pop()}}async runAsync(e){t.contextStack.push(this);try{return await e(this.resolver)}finally{t.contextStack.pop()}}};function n(e){return typeof e==`symbol`?e.description??String(e):e.name}var r=class{_providers=new Map;_singletons=new Map;_constructing=[];_checkCircularDependency(e){if(this._constructing.includes(e))throw Error(`Circular dependency detected ${[...this._constructing,e].map(n).join(` -> `)}`)}_resolveProvide(e,t){let r=this._providers.get(e);if(r===void 0&&!t)throw Error(`No provider found for ${n(e)}`);return r}_resolve(e,r){this._checkCircularDependency(e);let i=this._resolveProvide(e,r);if(i===void 0)return;if(i.async)throw Error(`Provider for ${n(e)} is async, please use injectAsync()`);let a=i.scope!==`transient`;if(a&&this._singletons.has(e))return this._singletons.get(e);this._constructing.push(e);try{let n=new t(this).run(()=>i.factory(this));return a&&this._singletons.set(e,n),n}finally{this._constructing.pop()}}async _resolveAsync(e,n){this._checkCircularDependency(e);let r=this._resolveProvide(e,n);if(r===void 0)return;let i=r.scope!==`transient`;if(i&&this._singletons.has(e))return this._singletons.get(e);this._constructing.push(e);try{let n=await new t(this).runAsync(async()=>await r.factory(this));return i&&this._singletons.set(e,n),n}finally{this._constructing.pop()}}add(e){this._providers.set(e.token,e)}get(e,t){return t?.lazy??!1?()=>this.get(e,{...t,lazy:!1}):this._resolve(e,t?.optional??!1)}getAsync(e,t){return t?.lazy??!1?()=>this.getAsync(e,{...t,lazy:!1}):this._resolveAsync(e,t?.optional??!1)}async dispose(){let e=0,t=``;for(let[r,i]of this._singletons)if(typeof i.dispose==`function`)try{await i.dispose()}catch(i){e++,t+=`${n(r)}: ${i instanceof Error?i.message:i}; `}if(this._singletons.clear(),e>0)throw Error(`Failed to dispose ${e} provider(s):\n${t.slice(0,-2)}`)}};function i(n,r){try{return t.current().run(e=>e.get(n,r))}catch(t){if(t instanceof e&&r?.optional==1)return;throw t}}function a(n,r){try{return r?.lazy?t.current().run(e=>e.getAsync(n,{...r,lazy:!0})):t.current().runAsync(e=>e.getAsync(n,{...r,lazy:!1}))}catch(t){return t instanceof e&&r?.optional===!0?r?.lazy?()=>Promise.resolve(void 0):Promise.resolve(void 0):Promise.reject(t)}}export{r as Container,i as inject,a as injectAsync};