@illuma/core 0.2.0 → 1.1.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.
- package/README.md +170 -170
- package/dist/index.cjs +20 -101
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +76 -120
- package/dist/index.d.ts +76 -120
- package/dist/index.js +20 -99
- package/dist/index.js.map +1 -1
- package/dist/{injection-D22uAh1O.d.ts → injection-CSxu56ds.d.cts} +1 -1
- package/dist/{injection-CJGqGWJ6.d.cts → injection-Y_bVmBSk.d.ts} +1 -1
- package/dist/{plugin-container-CUw26ZhP.d.ts → plugin-container-CwkVlVS4.d.ts} +18 -21
- package/dist/{plugin-container-n0FIqLbh.d.cts → plugin-container-D8Zwpigq.d.cts} +18 -21
- package/dist/plugins.d.cts +3 -3
- package/dist/plugins.d.ts +3 -3
- package/dist/{token-BvQrvm-Q.d.cts → providers-D9YA8L_g.d.cts} +73 -73
- package/dist/{token-BvQrvm-Q.d.ts → providers-D9YA8L_g.d.ts} +73 -73
- package/dist/testkit.cjs +20 -62
- package/dist/testkit.cjs.map +1 -1
- package/dist/testkit.d.cts +2 -2
- package/dist/testkit.d.ts +2 -2
- package/dist/testkit.js +20 -62
- package/dist/testkit.js.map +1 -1
- package/package.json +74 -74
- package/CHANGELOG.md +0 -12
package/README.md
CHANGED
|
@@ -1,170 +1,170 @@
|
|
|
1
|
-
# 🔥 **Illuma** – Angular-style Dependency Injection for TypeScript
|
|
2
|
-
|
|
3
|
-

|
|
4
|
-

|
|
5
|
-

|
|
6
|
-

|
|
7
|
-
|
|
8
|
-
A lightweight, type-safe dependency injection container for TypeScript. Zero dependencies.
|
|
9
|
-
|
|
10
|
-
## ✨ Features
|
|
11
|
-
|
|
12
|
-
- 🎯 **Type-Safe** – Full TypeScript support with excellent type inference
|
|
13
|
-
- 🪶 **Lightweight** – Zero dependencies, minimal bundle size
|
|
14
|
-
- 🔄 **Flexible** – Classes, factories, values, and aliases
|
|
15
|
-
- 🎨 **Decorators** – Optional Angular-style `@NodeInjectable()` decorator
|
|
16
|
-
- 🔗 **Multi-Tokens** – Built-in multi-provider support
|
|
17
|
-
- 🔌 **Plugin System** – Extensible architecture with custom scanners and diagnostics
|
|
18
|
-
- 🌍 **Universal** – Node.js, Deno, browser, and Electron
|
|
19
|
-
|
|
20
|
-
## 📦 Installation
|
|
21
|
-
|
|
22
|
-
```bash
|
|
23
|
-
npm install @illuma/core
|
|
24
|
-
```
|
|
25
|
-
|
|
26
|
-
## 🤝 Compatibility
|
|
27
|
-
|
|
28
|
-
Anything that supports ES2015+ (ES6+).
|
|
29
|
-
Practically the library is compatible with Node.js (v14+) and all modern browsers.
|
|
30
|
-
For older environments, consider using a transpiler like Babel or TypeScript or provide polyfills as needed.
|
|
31
|
-
|
|
32
|
-
## 🚀 Quick Start
|
|
33
|
-
|
|
34
|
-
```typescript
|
|
35
|
-
import { NodeContainer, NodeInjectable, nodeInject } from '@illuma/core';
|
|
36
|
-
|
|
37
|
-
@NodeInjectable()
|
|
38
|
-
class Logger {
|
|
39
|
-
public log(message: string) {
|
|
40
|
-
console.log(`[LOG]: ${message}`);
|
|
41
|
-
}
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
@NodeInjectable()
|
|
45
|
-
class UserService {
|
|
46
|
-
private readonly logger = nodeInject(Logger);
|
|
47
|
-
|
|
48
|
-
public getUser(id: string) {
|
|
49
|
-
this.logger.log(`Fetching user ${id}`);
|
|
50
|
-
return { id, name: 'John Doe' };
|
|
51
|
-
}
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
const container = new NodeContainer();
|
|
55
|
-
container.provide([Logger, UserService]);
|
|
56
|
-
container.bootstrap();
|
|
57
|
-
|
|
58
|
-
const userService = container.get(UserService);
|
|
59
|
-
```
|
|
60
|
-
|
|
61
|
-
> **Note:** Requires `experimentalDecorators` and `emitDecoratorMetadata` in tsconfig. See [Getting Started](./docs/GETTING_STARTED.md) for decorator-free alternatives.
|
|
62
|
-
|
|
63
|
-
## 🏷️ Using Tokens
|
|
64
|
-
|
|
65
|
-
```typescript
|
|
66
|
-
import { NodeToken, MultiNodeToken, NodeContainer } from '@illuma/core';
|
|
67
|
-
|
|
68
|
-
// Single-value token
|
|
69
|
-
const CONFIG = new NodeToken<{ apiUrl: string }>('CONFIG');
|
|
70
|
-
|
|
71
|
-
// Multi-value token (when injected, returns array)
|
|
72
|
-
const PLUGINS = new MultiNodeToken<Plugin>('PLUGINS');
|
|
73
|
-
|
|
74
|
-
const container = new NodeContainer();
|
|
75
|
-
|
|
76
|
-
container.provide([
|
|
77
|
-
// Equivalent to:
|
|
78
|
-
// { provide: CONFIG, value: { apiUrl: 'https://api.example.com' } }
|
|
79
|
-
CONFIG.withValue({ apiUrl: 'https://api.example.com' }),
|
|
80
|
-
|
|
81
|
-
// Equivalent to:
|
|
82
|
-
// { provide: PLUGINS, useClass: AnalyticsPlugin }
|
|
83
|
-
PLUGINS.withClass(AnalyticsPlugin),
|
|
84
|
-
|
|
85
|
-
// Equivalent to:
|
|
86
|
-
// { provide: PLUGINS, useClass: LoggingPlugin }
|
|
87
|
-
PLUGINS.withClass(LoggingPlugin),
|
|
88
|
-
]);
|
|
89
|
-
|
|
90
|
-
container.bootstrap();
|
|
91
|
-
|
|
92
|
-
const config = container.get(CONFIG); // { apiUrl: string }
|
|
93
|
-
const plugins = container.get(PLUGINS); // Plugin[]: [AnalyticsPlugin, LoggingPlugin]
|
|
94
|
-
```
|
|
95
|
-
|
|
96
|
-
See [Tokens Guide](./docs/TOKENS.md) for more details.
|
|
97
|
-
|
|
98
|
-
## 🎨 Provider Types
|
|
99
|
-
|
|
100
|
-
```typescript
|
|
101
|
-
// Class provider
|
|
102
|
-
container.provide(MyService);
|
|
103
|
-
|
|
104
|
-
// Value provider
|
|
105
|
-
container.provide({ provide: CONFIG, value: { apiUrl: '...' } });
|
|
106
|
-
|
|
107
|
-
// Factory provider
|
|
108
|
-
container.provide({ provide: DATABASE, factory: () => {
|
|
109
|
-
const env = nodeInject(ENV);
|
|
110
|
-
return createDatabase(env.connectionString);
|
|
111
|
-
} });
|
|
112
|
-
|
|
113
|
-
// Class provider with custom implementation
|
|
114
|
-
container.provide({ provide: DATABASE, useClass: DatabaseImplementation });
|
|
115
|
-
|
|
116
|
-
// Alias provider
|
|
117
|
-
container.provide({ provide: Database, alias: ExistingDatabase });
|
|
118
|
-
```
|
|
119
|
-
|
|
120
|
-
See [Providers Guide](./docs/PROVIDERS.md) for details.
|
|
121
|
-
|
|
122
|
-
## 🧪 Testing
|
|
123
|
-
|
|
124
|
-
```typescript
|
|
125
|
-
import { createTestFactory } from '@illuma/core/testkit';
|
|
126
|
-
|
|
127
|
-
const createTest = createTestFactory({
|
|
128
|
-
target: UserService,
|
|
129
|
-
provide: [{ provide: Logger, useClass: MockLogger }],
|
|
130
|
-
});
|
|
131
|
-
|
|
132
|
-
it('should fetch user', () => {
|
|
133
|
-
const { instance } = createTest();
|
|
134
|
-
expect(instance.getUser('123')).toBeDefined();
|
|
135
|
-
});
|
|
136
|
-
```
|
|
137
|
-
|
|
138
|
-
See [Testing Guide](./docs/TESTKIT.md) for comprehensive examples.
|
|
139
|
-
|
|
140
|
-
## 📚 Documentation
|
|
141
|
-
|
|
142
|
-
| Guide | Description |
|
|
143
|
-
| -------------------------------------------------- | ----------------------------------------------------- |
|
|
144
|
-
| [Getting Started](./docs/GETTING_STARTED.md) | Installation, setup, and basic usage |
|
|
145
|
-
| [Providers](./docs/PROVIDERS.md) | Value, factory, class, and alias providers |
|
|
146
|
-
| [Tokens](./docs/TOKENS.md) | NodeToken and MultiNodeToken |
|
|
147
|
-
| [Async Injection](./docs/ASYNC_INJECTION.md) | Lazy loading and sub-containers |
|
|
148
|
-
| [Testing](./docs/TESTKIT.md) | Testkit and mocking |
|
|
149
|
-
| [Plugins](./docs/PLUGINS.md) | Extending Illuma with custom scanners and diagnostics |
|
|
150
|
-
| [Technical Overview](./docs/TECHNICAL_OVERVIEW.md) | Deep dive into how Illuma works |
|
|
151
|
-
| [API Reference](./docs/API.md) | Complete API documentation |
|
|
152
|
-
| [Troubleshooting](./docs/TROUBLESHOOTING.md) | Error codes and solutions |
|
|
153
|
-
|
|
154
|
-
## 🔌 Plugins
|
|
155
|
-
|
|
156
|
-
Illuma supports a plugin system for extending functionality. Check out these plugins:
|
|
157
|
-
|
|
158
|
-
- **[@illuma/reflect](https://github.com/git-illuma/reflect)** – Constructor metadata and property decorator injection support
|
|
159
|
-
|
|
160
|
-
See [Plugins Guide](./docs/PLUGINS.md) for creating your own plugins.
|
|
161
|
-
|
|
162
|
-
## 📄 License
|
|
163
|
-
|
|
164
|
-
MIT © [bebrasmell](https://github.com/bebrasmell)
|
|
165
|
-
|
|
166
|
-
## 🔗 Links
|
|
167
|
-
|
|
168
|
-
- [GitHub](https://github.com/git-illuma/core)
|
|
169
|
-
- [NPM](https://www.npmjs.com/package/@illuma/core)
|
|
170
|
-
- [Issues](https://github.com/git-illuma/core/issues)
|
|
1
|
+
# 🔥 **Illuma** – Angular-style Dependency Injection for TypeScript
|
|
2
|
+
|
|
3
|
+

|
|
4
|
+

|
|
5
|
+

|
|
6
|
+

|
|
7
|
+
|
|
8
|
+
A lightweight, type-safe dependency injection container for TypeScript. Zero dependencies.
|
|
9
|
+
|
|
10
|
+
## ✨ Features
|
|
11
|
+
|
|
12
|
+
- 🎯 **Type-Safe** – Full TypeScript support with excellent type inference
|
|
13
|
+
- 🪶 **Lightweight** – Zero dependencies, minimal bundle size
|
|
14
|
+
- 🔄 **Flexible** – Classes, factories, values, and aliases
|
|
15
|
+
- 🎨 **Decorators** – Optional Angular-style `@NodeInjectable()` decorator
|
|
16
|
+
- 🔗 **Multi-Tokens** – Built-in multi-provider support
|
|
17
|
+
- 🔌 **Plugin System** – Extensible architecture with custom scanners and diagnostics
|
|
18
|
+
- 🌍 **Universal** – Node.js, Deno, browser, and Electron
|
|
19
|
+
|
|
20
|
+
## 📦 Installation
|
|
21
|
+
|
|
22
|
+
```bash
|
|
23
|
+
npm install @illuma/core
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
## 🤝 Compatibility
|
|
27
|
+
|
|
28
|
+
Anything that supports ES2015+ (ES6+).
|
|
29
|
+
Practically the library is compatible with Node.js (v14+) and all modern browsers.
|
|
30
|
+
For older environments, consider using a transpiler like Babel or TypeScript or provide polyfills as needed.
|
|
31
|
+
|
|
32
|
+
## 🚀 Quick Start
|
|
33
|
+
|
|
34
|
+
```typescript
|
|
35
|
+
import { NodeContainer, NodeInjectable, nodeInject } from '@illuma/core';
|
|
36
|
+
|
|
37
|
+
@NodeInjectable()
|
|
38
|
+
class Logger {
|
|
39
|
+
public log(message: string) {
|
|
40
|
+
console.log(`[LOG]: ${message}`);
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
@NodeInjectable()
|
|
45
|
+
class UserService {
|
|
46
|
+
private readonly logger = nodeInject(Logger);
|
|
47
|
+
|
|
48
|
+
public getUser(id: string) {
|
|
49
|
+
this.logger.log(`Fetching user ${id}`);
|
|
50
|
+
return { id, name: 'John Doe' };
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
const container = new NodeContainer();
|
|
55
|
+
container.provide([Logger, UserService]);
|
|
56
|
+
container.bootstrap();
|
|
57
|
+
|
|
58
|
+
const userService = container.get(UserService);
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
> **Note:** Requires `experimentalDecorators` and `emitDecoratorMetadata` in tsconfig. See [Getting Started](./docs/GETTING_STARTED.md) for decorator-free alternatives.
|
|
62
|
+
|
|
63
|
+
## 🏷️ Using Tokens
|
|
64
|
+
|
|
65
|
+
```typescript
|
|
66
|
+
import { NodeToken, MultiNodeToken, NodeContainer } from '@illuma/core';
|
|
67
|
+
|
|
68
|
+
// Single-value token
|
|
69
|
+
const CONFIG = new NodeToken<{ apiUrl: string }>('CONFIG');
|
|
70
|
+
|
|
71
|
+
// Multi-value token (when injected, returns array)
|
|
72
|
+
const PLUGINS = new MultiNodeToken<Plugin>('PLUGINS');
|
|
73
|
+
|
|
74
|
+
const container = new NodeContainer();
|
|
75
|
+
|
|
76
|
+
container.provide([
|
|
77
|
+
// Equivalent to:
|
|
78
|
+
// { provide: CONFIG, value: { apiUrl: 'https://api.example.com' } }
|
|
79
|
+
CONFIG.withValue({ apiUrl: 'https://api.example.com' }),
|
|
80
|
+
|
|
81
|
+
// Equivalent to:
|
|
82
|
+
// { provide: PLUGINS, useClass: AnalyticsPlugin }
|
|
83
|
+
PLUGINS.withClass(AnalyticsPlugin),
|
|
84
|
+
|
|
85
|
+
// Equivalent to:
|
|
86
|
+
// { provide: PLUGINS, useClass: LoggingPlugin }
|
|
87
|
+
PLUGINS.withClass(LoggingPlugin),
|
|
88
|
+
]);
|
|
89
|
+
|
|
90
|
+
container.bootstrap();
|
|
91
|
+
|
|
92
|
+
const config = container.get(CONFIG); // { apiUrl: string }
|
|
93
|
+
const plugins = container.get(PLUGINS); // Plugin[]: [AnalyticsPlugin, LoggingPlugin]
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
See [Tokens Guide](./docs/TOKENS.md) for more details.
|
|
97
|
+
|
|
98
|
+
## 🎨 Provider Types
|
|
99
|
+
|
|
100
|
+
```typescript
|
|
101
|
+
// Class provider
|
|
102
|
+
container.provide(MyService);
|
|
103
|
+
|
|
104
|
+
// Value provider
|
|
105
|
+
container.provide({ provide: CONFIG, value: { apiUrl: '...' } });
|
|
106
|
+
|
|
107
|
+
// Factory provider
|
|
108
|
+
container.provide({ provide: DATABASE, factory: () => {
|
|
109
|
+
const env = nodeInject(ENV);
|
|
110
|
+
return createDatabase(env.connectionString);
|
|
111
|
+
} });
|
|
112
|
+
|
|
113
|
+
// Class provider with custom implementation
|
|
114
|
+
container.provide({ provide: DATABASE, useClass: DatabaseImplementation });
|
|
115
|
+
|
|
116
|
+
// Alias provider
|
|
117
|
+
container.provide({ provide: Database, alias: ExistingDatabase });
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
See [Providers Guide](./docs/PROVIDERS.md) for details.
|
|
121
|
+
|
|
122
|
+
## 🧪 Testing
|
|
123
|
+
|
|
124
|
+
```typescript
|
|
125
|
+
import { createTestFactory } from '@illuma/core/testkit';
|
|
126
|
+
|
|
127
|
+
const createTest = createTestFactory({
|
|
128
|
+
target: UserService,
|
|
129
|
+
provide: [{ provide: Logger, useClass: MockLogger }],
|
|
130
|
+
});
|
|
131
|
+
|
|
132
|
+
it('should fetch user', () => {
|
|
133
|
+
const { instance } = createTest();
|
|
134
|
+
expect(instance.getUser('123')).toBeDefined();
|
|
135
|
+
});
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
See [Testing Guide](./docs/TESTKIT.md) for comprehensive examples.
|
|
139
|
+
|
|
140
|
+
## 📚 Documentation
|
|
141
|
+
|
|
142
|
+
| Guide | Description |
|
|
143
|
+
| -------------------------------------------------- | ----------------------------------------------------- |
|
|
144
|
+
| [Getting Started](./docs/GETTING_STARTED.md) | Installation, setup, and basic usage |
|
|
145
|
+
| [Providers](./docs/PROVIDERS.md) | Value, factory, class, and alias providers |
|
|
146
|
+
| [Tokens](./docs/TOKENS.md) | NodeToken and MultiNodeToken |
|
|
147
|
+
| [Async Injection](./docs/ASYNC_INJECTION.md) | Lazy loading and sub-containers |
|
|
148
|
+
| [Testing](./docs/TESTKIT.md) | Testkit and mocking |
|
|
149
|
+
| [Plugins](./docs/PLUGINS.md) | Extending Illuma with custom scanners and diagnostics |
|
|
150
|
+
| [Technical Overview](./docs/TECHNICAL_OVERVIEW.md) | Deep dive into how Illuma works |
|
|
151
|
+
| [API Reference](./docs/API.md) | Complete API documentation |
|
|
152
|
+
| [Troubleshooting](./docs/TROUBLESHOOTING.md) | Error codes and solutions |
|
|
153
|
+
|
|
154
|
+
## 🔌 Plugins
|
|
155
|
+
|
|
156
|
+
Illuma supports a plugin system for extending functionality. Check out these plugins:
|
|
157
|
+
|
|
158
|
+
- **[@illuma/reflect](https://github.com/git-illuma/reflect)** – Constructor metadata and property decorator injection support
|
|
159
|
+
|
|
160
|
+
See [Plugins Guide](./docs/PLUGINS.md) for creating your own plugins.
|
|
161
|
+
|
|
162
|
+
## 📄 License
|
|
163
|
+
|
|
164
|
+
MIT © [bebrasmell](https://github.com/bebrasmell)
|
|
165
|
+
|
|
166
|
+
## 🔗 Links
|
|
167
|
+
|
|
168
|
+
- [GitHub](https://github.com/git-illuma/core)
|
|
169
|
+
- [NPM](https://www.npmjs.com/package/@illuma/core)
|
|
170
|
+
- [Issues](https://github.com/git-illuma/core/issues)
|
package/dist/index.cjs
CHANGED
|
@@ -21,7 +21,6 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
|
|
|
21
21
|
// src/index.ts
|
|
22
22
|
var index_exports = {};
|
|
23
23
|
__export(index_exports, {
|
|
24
|
-
ILLUMA_ERR_CODES: () => ERR_CODES,
|
|
25
24
|
INJECTION_SYMBOL: () => INJECTION_SYMBOL,
|
|
26
25
|
InjectionContext: () => InjectionContext,
|
|
27
26
|
InjectionError: () => InjectionError,
|
|
@@ -35,7 +34,6 @@ __export(index_exports, {
|
|
|
35
34
|
extractToken: () => extractToken,
|
|
36
35
|
getInjectableToken: () => getInjectableToken,
|
|
37
36
|
injectAsync: () => injectAsync,
|
|
38
|
-
injectDefer: () => injectDefer,
|
|
39
37
|
injectEntryAsync: () => injectEntryAsync,
|
|
40
38
|
injectGroupAsync: () => injectGroupAsync,
|
|
41
39
|
isConstructor: () => isConstructor,
|
|
@@ -47,29 +45,6 @@ __export(index_exports, {
|
|
|
47
45
|
module.exports = __toCommonJS(index_exports);
|
|
48
46
|
|
|
49
47
|
// src/lib/errors.ts
|
|
50
|
-
var ERR_CODES = {
|
|
51
|
-
// Provider errors
|
|
52
|
-
DUPLICATE_PROVIDER: 100,
|
|
53
|
-
DUPLICATE_FACTORY: 101,
|
|
54
|
-
INVALID_CTOR: 102,
|
|
55
|
-
INVALID_PROVIDER: 103,
|
|
56
|
-
// Alias errors
|
|
57
|
-
INVALID_ALIAS: 200,
|
|
58
|
-
LOOP_ALIAS: 201,
|
|
59
|
-
// Bootstrap errors
|
|
60
|
-
NOT_BOOTSTRAPPED: 300,
|
|
61
|
-
BOOTSTRAPPED: 301,
|
|
62
|
-
DOUBLE_BOOTSTRAP: 302,
|
|
63
|
-
// Retrieval errors
|
|
64
|
-
NOT_FOUND: 400,
|
|
65
|
-
CIRCULAR_DEPENDENCY: 401,
|
|
66
|
-
// Instantiation errors
|
|
67
|
-
UNTRACKED: 500,
|
|
68
|
-
OUTSIDE_CONTEXT: 501,
|
|
69
|
-
CALLED_UTILS_OUTSIDE_CONTEXT: 502,
|
|
70
|
-
INSTANCE_ACCESS_FAILED: 503,
|
|
71
|
-
ACCESS_FAILED: 504
|
|
72
|
-
};
|
|
73
48
|
var InjectionError = class _InjectionError extends Error {
|
|
74
49
|
static {
|
|
75
50
|
__name(this, "InjectionError");
|
|
@@ -81,70 +56,66 @@ var InjectionError = class _InjectionError extends Error {
|
|
|
81
56
|
}
|
|
82
57
|
// Provider errors
|
|
83
58
|
static duplicate(token) {
|
|
84
|
-
return new _InjectionError(
|
|
59
|
+
return new _InjectionError(100, `Duplicate provider for token "${token.toString()}" detected.`);
|
|
85
60
|
}
|
|
86
61
|
static duplicateFactory(token) {
|
|
87
|
-
return new _InjectionError(
|
|
62
|
+
return new _InjectionError(101, `Tried to re-provide factory for token "${token.toString()}" detected.`);
|
|
88
63
|
}
|
|
89
64
|
static invalidCtor(ctor) {
|
|
90
|
-
return new _InjectionError(
|
|
65
|
+
return new _InjectionError(102, `Cannot use constructor for token "${ctor.name}". Please make sure to use @nodeInjectable() decorator`);
|
|
91
66
|
}
|
|
92
67
|
static invalidProvider(provider) {
|
|
93
|
-
return new _InjectionError(
|
|
68
|
+
return new _InjectionError(103, `Cannot use provider as it is neither a NodeToken nor MultiNodeToken nor a valid constructor.:
|
|
94
69
|
${provider}`);
|
|
95
70
|
}
|
|
96
71
|
// Alias errors
|
|
97
72
|
static invalidAlias(alias) {
|
|
98
73
|
const aliasStr = typeof alias === "function" ? alias.name || "Unknown" : String(alias);
|
|
99
|
-
return new _InjectionError(
|
|
74
|
+
return new _InjectionError(200, `Invalid alias target "${aliasStr}". Alias must be a NodeToken, MultiNodeToken, or a class decorated with @NodeInjectable().`);
|
|
100
75
|
}
|
|
101
76
|
static loopAlias(alias) {
|
|
102
|
-
return new _InjectionError(
|
|
77
|
+
return new _InjectionError(201, `Token "${alias.toString()}" cannot alias itself in a loop.`);
|
|
103
78
|
}
|
|
104
79
|
// Bootstrap errors
|
|
105
80
|
static notBootstrapped() {
|
|
106
|
-
return new _InjectionError(
|
|
81
|
+
return new _InjectionError(300, "Cannot retrieve providers before the container has been bootstrapped.");
|
|
107
82
|
}
|
|
108
83
|
static bootstrapped() {
|
|
109
|
-
return new _InjectionError(
|
|
84
|
+
return new _InjectionError(301, "Cannot modify providers after the container has been bootstrapped.");
|
|
110
85
|
}
|
|
111
86
|
static doubleBootstrap() {
|
|
112
|
-
return new _InjectionError(
|
|
87
|
+
return new _InjectionError(302, "Container has already been bootstrapped and cannot be bootstrapped again.");
|
|
113
88
|
}
|
|
114
89
|
// Retrieval errors
|
|
115
90
|
static notFound(token) {
|
|
116
|
-
return new _InjectionError(
|
|
91
|
+
return new _InjectionError(400, `No provider found for "${token.toString()}".`);
|
|
117
92
|
}
|
|
118
93
|
static circularDependency(provider, path) {
|
|
119
94
|
const providerStr = provider instanceof NodeBase ? provider.toString() : provider.name;
|
|
120
95
|
const pathStr = path.map((p) => p instanceof NodeBase ? p.toString() : p.name).join(" -> ");
|
|
121
|
-
return new _InjectionError(
|
|
96
|
+
return new _InjectionError(401, `Circular dependency detected while resolving "${providerStr}":
|
|
122
97
|
${pathStr}`);
|
|
123
98
|
}
|
|
124
99
|
// Instantiation errors
|
|
125
100
|
static untracked(token, parent) {
|
|
126
101
|
const tokenStr = token instanceof NodeBase ? token.toString() : token.name;
|
|
127
102
|
const parentStr = parent instanceof NodeBase ? parent.toString() : parent.name;
|
|
128
|
-
return new _InjectionError(
|
|
103
|
+
return new _InjectionError(500, `Cannot instantiate ${parentStr} because it depends on untracked injection ${tokenStr}. Please make sure all injections are properly tracked.`);
|
|
129
104
|
}
|
|
130
105
|
static outsideContext(token) {
|
|
131
106
|
const tokenStr = token instanceof NodeBase ? token.toString() : token.name;
|
|
132
|
-
return new _InjectionError(
|
|
107
|
+
return new _InjectionError(501, `Cannot inject "${tokenStr}" outside of an injection context.`);
|
|
133
108
|
}
|
|
134
109
|
static calledUtilsOutsideContext() {
|
|
135
|
-
return new _InjectionError(
|
|
110
|
+
return new _InjectionError(502, "Cannot call injection utilities outside of an injection context.");
|
|
136
111
|
}
|
|
137
112
|
static instanceAccessFailed(token) {
|
|
138
|
-
return new _InjectionError(
|
|
113
|
+
return new _InjectionError(503, `Failed to access instance for token "${token.toString()}". It was not properly instantiated.`);
|
|
139
114
|
}
|
|
140
115
|
static accessFailed() {
|
|
141
|
-
return new _InjectionError(
|
|
116
|
+
return new _InjectionError(504, "Failed to access the requested instance due to an unknown error.");
|
|
142
117
|
}
|
|
143
118
|
};
|
|
144
|
-
function isNotFoundError(error) {
|
|
145
|
-
return error instanceof InjectionError && error.code === ERR_CODES.NOT_FOUND;
|
|
146
|
-
}
|
|
147
|
-
__name(isNotFoundError, "isNotFoundError");
|
|
148
119
|
|
|
149
120
|
// src/lib/api/token.ts
|
|
150
121
|
var NodeBase = class {
|
|
@@ -507,29 +478,23 @@ var TreeRootNode = class {
|
|
|
507
478
|
static {
|
|
508
479
|
__name(this, "TreeRootNode");
|
|
509
480
|
}
|
|
510
|
-
instant;
|
|
511
481
|
_deps = /* @__PURE__ */ new Set();
|
|
512
482
|
_treePool = /* @__PURE__ */ new Map();
|
|
513
|
-
constructor(instant = true) {
|
|
514
|
-
this.instant = instant;
|
|
515
|
-
}
|
|
516
483
|
get dependencies() {
|
|
517
484
|
return this._deps;
|
|
518
485
|
}
|
|
519
486
|
addDependency(node) {
|
|
520
487
|
this._deps.add(node);
|
|
521
488
|
}
|
|
522
|
-
|
|
489
|
+
instantiate() {
|
|
523
490
|
for (const dep of this._deps) {
|
|
491
|
+
dep.instantiate(this._treePool);
|
|
524
492
|
if ("token" in dep.proto) this._treePool.set(dep.proto.token, dep);
|
|
525
|
-
if (this.instant) dep.instantiate(this._treePool);
|
|
526
|
-
else dep.collectPool(this._treePool);
|
|
527
493
|
}
|
|
528
494
|
}
|
|
529
495
|
find(token) {
|
|
530
496
|
const node = this._treePool.get(token);
|
|
531
497
|
if (!node) return null;
|
|
532
|
-
if (!this.instant) node.instantiate(this._treePool);
|
|
533
498
|
return node;
|
|
534
499
|
}
|
|
535
500
|
toString() {
|
|
@@ -560,11 +525,6 @@ var TreeNodeSingle = class {
|
|
|
560
525
|
else this._deps.set(node.proto.token, node);
|
|
561
526
|
node.allocations++;
|
|
562
527
|
}
|
|
563
|
-
collectPool(pool) {
|
|
564
|
-
for (const node of this._deps.values()) node.collectPool(pool);
|
|
565
|
-
for (const dep of this._transparent) dep.collectPool(pool);
|
|
566
|
-
pool.set(this.proto.token, this);
|
|
567
|
-
}
|
|
568
528
|
instantiate(pool) {
|
|
569
529
|
if (this._resolved) return;
|
|
570
530
|
for (const node of this._deps.values()) node.instantiate(pool);
|
|
@@ -602,10 +562,6 @@ var TreeNodeTransparent = class _TreeNodeTransparent {
|
|
|
602
562
|
else this._deps.set(node.proto.token, node);
|
|
603
563
|
node.allocations++;
|
|
604
564
|
}
|
|
605
|
-
collectPool(pool) {
|
|
606
|
-
for (const node of this._deps.values()) node.collectPool(pool);
|
|
607
|
-
for (const dep of this._transparent) dep.collectPool(pool);
|
|
608
|
-
}
|
|
609
565
|
instantiate(pool) {
|
|
610
566
|
if (this._resolved) return;
|
|
611
567
|
for (const dep of this._transparent) dep.instantiate(pool);
|
|
@@ -630,10 +586,6 @@ var TreeNodeMulti = class _TreeNodeMulti {
|
|
|
630
586
|
constructor(proto) {
|
|
631
587
|
this.proto = proto;
|
|
632
588
|
}
|
|
633
|
-
collectPool(pool) {
|
|
634
|
-
for (const dep of this._deps) dep.collectPool(pool);
|
|
635
|
-
pool.set(this.proto.token, this);
|
|
636
|
-
}
|
|
637
589
|
instantiate(pool) {
|
|
638
590
|
if (this._resolved) return;
|
|
639
591
|
for (const dep of this._deps) {
|
|
@@ -810,37 +762,6 @@ var InjectorImpl = class {
|
|
|
810
762
|
};
|
|
811
763
|
var Injector = new NodeToken("Injector");
|
|
812
764
|
|
|
813
|
-
// src/lib/utils/defer.ts
|
|
814
|
-
function injectDefer(provider, options) {
|
|
815
|
-
const injector = nodeInject(Injector);
|
|
816
|
-
let token = provider;
|
|
817
|
-
if (isInjectable(provider)) token = getInjectableToken(provider);
|
|
818
|
-
if (!isNodeBase(token)) throw InjectionError.invalidProvider(String(token));
|
|
819
|
-
let resolved = false;
|
|
820
|
-
let instance = SHAPE_SHIFTER;
|
|
821
|
-
return () => {
|
|
822
|
-
if (resolved) return instance;
|
|
823
|
-
if (options?.optional) {
|
|
824
|
-
try {
|
|
825
|
-
instance = injector.get(token);
|
|
826
|
-
resolved = true;
|
|
827
|
-
return instance;
|
|
828
|
-
} catch (e) {
|
|
829
|
-
if (isNotFoundError(e)) {
|
|
830
|
-
resolved = true;
|
|
831
|
-
instance = null;
|
|
832
|
-
return instance;
|
|
833
|
-
}
|
|
834
|
-
throw e;
|
|
835
|
-
}
|
|
836
|
-
}
|
|
837
|
-
instance = injector.get(token);
|
|
838
|
-
resolved = true;
|
|
839
|
-
return instance;
|
|
840
|
-
};
|
|
841
|
-
}
|
|
842
|
-
__name(injectDefer, "injectDefer");
|
|
843
|
-
|
|
844
765
|
// src/lib/utils/inheritance.ts
|
|
845
766
|
function injectGroupAsync(fn, opts) {
|
|
846
767
|
const { container: parent } = nodeInject(Injector);
|
|
@@ -1035,7 +956,7 @@ var NodeContainer = class extends Illuma {
|
|
|
1035
956
|
return parentNode.findNode(token);
|
|
1036
957
|
}
|
|
1037
958
|
_buildInjectionTree() {
|
|
1038
|
-
const root = new TreeRootNode(
|
|
959
|
+
const root = new TreeRootNode();
|
|
1039
960
|
const cache = /* @__PURE__ */ new Map();
|
|
1040
961
|
const nodes = [
|
|
1041
962
|
...this._protoNodes.values(),
|
|
@@ -1080,7 +1001,7 @@ var NodeContainer = class extends Illuma {
|
|
|
1080
1001
|
value: new InjectorImpl(this)
|
|
1081
1002
|
});
|
|
1082
1003
|
this._rootNode = this._buildInjectionTree();
|
|
1083
|
-
this._rootNode.
|
|
1004
|
+
this._rootNode.instantiate();
|
|
1084
1005
|
this._bootstrapped = true;
|
|
1085
1006
|
const end = performance.now();
|
|
1086
1007
|
const duration = end - start;
|
|
@@ -1151,7 +1072,6 @@ var NodeContainer = class extends Illuma {
|
|
|
1151
1072
|
};
|
|
1152
1073
|
// Annotate the CommonJS export names for ESM import in node:
|
|
1153
1074
|
0 && (module.exports = {
|
|
1154
|
-
ILLUMA_ERR_CODES,
|
|
1155
1075
|
INJECTION_SYMBOL,
|
|
1156
1076
|
InjectionContext,
|
|
1157
1077
|
InjectionError,
|
|
@@ -1165,7 +1085,6 @@ var NodeContainer = class extends Illuma {
|
|
|
1165
1085
|
extractToken,
|
|
1166
1086
|
getInjectableToken,
|
|
1167
1087
|
injectAsync,
|
|
1168
|
-
injectDefer,
|
|
1169
1088
|
injectEntryAsync,
|
|
1170
1089
|
injectGroupAsync,
|
|
1171
1090
|
isConstructor,
|