@sentzunhat/zacatl 0.0.25 → 0.0.26
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/build/dependency-injection/container.d.ts +3 -2
- package/build/dependency-injection/container.d.ts.map +1 -1
- package/build/dependency-injection/container.js +27 -6
- package/build/dependency-injection/container.js.map +1 -1
- package/build/service/architecture/architecture.d.ts +1 -1
- package/build/service/architecture/architecture.d.ts.map +1 -1
- package/build/service/architecture/architecture.js.map +1 -1
- package/build/test/tsconfig.tsbuildinfo +1 -1
- package/package.json +1 -1
- package/src/dependency-injection/container.ts +60 -12
- package/src/service/architecture/architecture.ts +6 -1
package/package.json
CHANGED
|
@@ -1,6 +1,17 @@
|
|
|
1
1
|
import "reflect-metadata";
|
|
2
2
|
import { container as tsyringeContainer } from "tsyringe";
|
|
3
3
|
import type { DependencyContainer, InjectionToken } from "tsyringe";
|
|
4
|
+
import type { Constructor } from "../service/architecture/architecture";
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Track registered classes to avoid requiring decorator metadata
|
|
8
|
+
*/
|
|
9
|
+
const registeredClasses = new Set<Constructor>();
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Cache for singleton instances
|
|
13
|
+
*/
|
|
14
|
+
const singletonInstances = new Map<Constructor, object>();
|
|
4
15
|
|
|
5
16
|
/**
|
|
6
17
|
* Standalone DI container decoupled from microservice architecture.
|
|
@@ -101,13 +112,25 @@ export const resolveDependency = <T>(token: InjectionToken<T>): T => {
|
|
|
101
112
|
* registerWithDependencies(MachineService, [MachineRepository]);
|
|
102
113
|
* ```
|
|
103
114
|
*/
|
|
104
|
-
export const registerWithDependencies = <T>(
|
|
105
|
-
serviceClass:
|
|
106
|
-
dependencies:
|
|
115
|
+
export const registerWithDependencies = <T extends object>(
|
|
116
|
+
serviceClass: Constructor<T>,
|
|
117
|
+
dependencies: Constructor[] = [],
|
|
107
118
|
): void => {
|
|
119
|
+
// Track this class as registered
|
|
120
|
+
registeredClasses.add(serviceClass);
|
|
121
|
+
|
|
108
122
|
tsyringeContainer.register(serviceClass, {
|
|
109
|
-
useFactory: (
|
|
110
|
-
const resolvedDeps = dependencies.map((dep) =>
|
|
123
|
+
useFactory: () => {
|
|
124
|
+
const resolvedDeps = dependencies.map((dep) => {
|
|
125
|
+
// Check if dependency was registered
|
|
126
|
+
if (!registeredClasses.has(dep)) {
|
|
127
|
+
throw new Error(
|
|
128
|
+
`Dependency ${dep.name} not registered. Register it before ${serviceClass.name}.`,
|
|
129
|
+
);
|
|
130
|
+
}
|
|
131
|
+
// Resolve from container (works because we registered it)
|
|
132
|
+
return tsyringeContainer.resolve(dep);
|
|
133
|
+
});
|
|
111
134
|
return new serviceClass(...resolvedDeps);
|
|
112
135
|
},
|
|
113
136
|
} as never);
|
|
@@ -128,14 +151,37 @@ export const registerWithDependencies = <T>(
|
|
|
128
151
|
* registerSingletonWithDependencies(MachineService, [MachineRepository]);
|
|
129
152
|
* ```
|
|
130
153
|
*/
|
|
131
|
-
export const registerSingletonWithDependencies = <T>(
|
|
132
|
-
serviceClass:
|
|
133
|
-
dependencies:
|
|
154
|
+
export const registerSingletonWithDependencies = <T extends object>(
|
|
155
|
+
serviceClass: Constructor<T>,
|
|
156
|
+
dependencies: Constructor[] = [],
|
|
134
157
|
): void => {
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
158
|
+
// Track this class as registered
|
|
159
|
+
registeredClasses.add(serviceClass);
|
|
160
|
+
|
|
161
|
+
// Use register() with manual singleton pattern (lifecycle can't be used with factories)
|
|
162
|
+
tsyringeContainer.register(serviceClass, {
|
|
163
|
+
useFactory: () => {
|
|
164
|
+
// Check if we already have a singleton instance
|
|
165
|
+
if (singletonInstances.has(serviceClass)) {
|
|
166
|
+
return singletonInstances.get(serviceClass) as T;
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
// Create new instance
|
|
170
|
+
const resolvedDeps = dependencies.map((dep) => {
|
|
171
|
+
// Check if dependency was registered
|
|
172
|
+
if (!registeredClasses.has(dep)) {
|
|
173
|
+
throw new Error(
|
|
174
|
+
`Dependency ${dep.name} not registered. Register it before ${serviceClass.name}.`,
|
|
175
|
+
);
|
|
176
|
+
}
|
|
177
|
+
// Resolve from container (works because we registered it)
|
|
178
|
+
return tsyringeContainer.resolve(dep);
|
|
179
|
+
});
|
|
180
|
+
const instance = new serviceClass(...resolvedDeps);
|
|
181
|
+
|
|
182
|
+
// Cache the singleton instance
|
|
183
|
+
singletonInstances.set(serviceClass, instance);
|
|
184
|
+
return instance;
|
|
139
185
|
},
|
|
140
186
|
} as never);
|
|
141
187
|
};
|
|
@@ -146,4 +192,6 @@ export const registerSingletonWithDependencies = <T>(
|
|
|
146
192
|
export const clearContainer = (): void => {
|
|
147
193
|
tsyringeContainer.clearInstances();
|
|
148
194
|
tsyringeContainer.reset();
|
|
195
|
+
singletonInstances.clear();
|
|
196
|
+
registeredClasses.clear();
|
|
149
197
|
};
|
|
@@ -1,6 +1,11 @@
|
|
|
1
1
|
import { container } from "tsyringe";
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
/**
|
|
4
|
+
* Constructor type that accepts classes with any parameter signature
|
|
5
|
+
* Uses contravariant any[] to allow flexibility in DI container
|
|
6
|
+
*/
|
|
7
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
8
|
+
export type Constructor<T = object> = new (...args: any[]) => T;
|
|
4
9
|
|
|
5
10
|
type Architecture = {
|
|
6
11
|
start: () => void;
|