getbox 1.2.0 → 1.3.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/CONTEXT.md +1 -3
- package/README.md +43 -26
- package/dist/context.d.cts +1 -1
- package/dist/context.d.mts +1 -1
- package/dist/index.cjs +70 -1
- package/dist/index.d.cts +63 -4
- package/dist/index.d.mts +63 -4
- package/dist/index.mjs +70 -2
- package/package.json +1 -1
package/CONTEXT.md
CHANGED
|
@@ -57,9 +57,7 @@ import { Box } from "getbox";
|
|
|
57
57
|
class UserService {
|
|
58
58
|
constructor(private db: Database, private logger: Logger) {}
|
|
59
59
|
|
|
60
|
-
static init
|
|
61
|
-
return box.for(UserService).get(Database, LoggerFactory);
|
|
62
|
-
}
|
|
60
|
+
static init = Box.init(UserService).get(Database, LoggerFactory);
|
|
63
61
|
}
|
|
64
62
|
```
|
|
65
63
|
|
package/README.md
CHANGED
|
@@ -6,8 +6,6 @@
|
|
|
6
6
|
|
|
7
7
|
Callers know the type of the value they need, but not how it will be derived. The box resolves constructors lazily and caches instances automatically.
|
|
8
8
|
|
|
9
|
-
For an alternative pattern using AsyncLocalStorage where classes can resolve dependencies directly in their constructors, see [getbox/context](./CONTEXT.md).
|
|
10
|
-
|
|
11
9
|
## Installation
|
|
12
10
|
|
|
13
11
|
```sh
|
|
@@ -16,7 +14,9 @@ npm install getbox
|
|
|
16
14
|
|
|
17
15
|
## Usage
|
|
18
16
|
|
|
19
|
-
`getbox` has a very small API surface. You typically only need
|
|
17
|
+
`getbox` has a very small API surface. You typically only need `box.get()` and optionally `static init` or the `factory` helper.
|
|
18
|
+
|
|
19
|
+
For an alternative pattern using AsyncLocalStorage where classes can resolve dependencies directly in their constructors, see [getbox/context](./CONTEXT.md).
|
|
20
20
|
|
|
21
21
|
### Create a class
|
|
22
22
|
|
|
@@ -33,20 +33,17 @@ export class Printer {
|
|
|
33
33
|
|
|
34
34
|
### Use in another class
|
|
35
35
|
|
|
36
|
-
|
|
36
|
+
The `static init` property tells the box what dependencies to pass when instantiating the class.
|
|
37
37
|
|
|
38
38
|
```ts
|
|
39
39
|
// office.ts
|
|
40
|
-
import { Box
|
|
40
|
+
import { Box } from "getbox";
|
|
41
41
|
import { Printer } from "./printer";
|
|
42
42
|
|
|
43
43
|
export class Office {
|
|
44
44
|
constructor(public printer: Printer) {}
|
|
45
45
|
|
|
46
|
-
static init
|
|
47
|
-
const printer = box.get(Printer);
|
|
48
|
-
return new Office(printer);
|
|
49
|
-
}
|
|
46
|
+
static init = Box.init(Office).get(Printer);
|
|
50
47
|
}
|
|
51
48
|
```
|
|
52
49
|
|
|
@@ -106,14 +103,12 @@ export interface Logger {
|
|
|
106
103
|
log(message: string): void;
|
|
107
104
|
}
|
|
108
105
|
|
|
109
|
-
export class ConsoleLogger implements Logger {
|
|
110
|
-
log(message: string): void {
|
|
111
|
-
console.log(`[LOG] ${message}`);
|
|
112
|
-
}
|
|
113
|
-
}
|
|
114
|
-
|
|
115
106
|
const LoggerFactory = factory((box: Box): Logger => {
|
|
116
|
-
return
|
|
107
|
+
return {
|
|
108
|
+
log(message: string): void {
|
|
109
|
+
console.log(`[LOG] ${message}`);
|
|
110
|
+
},
|
|
111
|
+
};
|
|
117
112
|
});
|
|
118
113
|
```
|
|
119
114
|
|
|
@@ -125,10 +120,7 @@ import { Logger, LoggerFactory } from "./logger";
|
|
|
125
120
|
export class UserService {
|
|
126
121
|
constructor(private logger: Logger) {}
|
|
127
122
|
|
|
128
|
-
static init
|
|
129
|
-
const logger = box.get(LoggerFactory);
|
|
130
|
-
return new UserService(logger);
|
|
131
|
-
}
|
|
123
|
+
static init = Box.init(UserService).get(LoggerFactory);
|
|
132
124
|
|
|
133
125
|
createUser(name: string) {
|
|
134
126
|
this.logger.log(`Creating user: ${name}`);
|
|
@@ -219,18 +211,15 @@ console.log(db === db2); // false (transient)
|
|
|
219
211
|
|
|
220
212
|
## Class constructors
|
|
221
213
|
|
|
222
|
-
Use `
|
|
214
|
+
Use `Box.init` to allow resolving classes that have constructor parameters.
|
|
223
215
|
|
|
224
216
|
```ts
|
|
225
|
-
import { Box
|
|
217
|
+
import { Box } from "getbox";
|
|
226
218
|
|
|
227
219
|
class UserService {
|
|
228
220
|
constructor(private db: Database, private logger: Logger) {}
|
|
229
221
|
|
|
230
|
-
static init
|
|
231
|
-
// Create new instance with cached dependencies
|
|
232
|
-
return box.for(UserService).get(Database, LoggerFactory);
|
|
233
|
-
}
|
|
222
|
+
static init = Box.init(UserService).get(Database, LoggerFactory);
|
|
234
223
|
|
|
235
224
|
createUser(name: string) {
|
|
236
225
|
this.logger.log(`Creating user: ${name}`);
|
|
@@ -242,6 +231,34 @@ const service = box.get(UserService);
|
|
|
242
231
|
service.createUser("Alice");
|
|
243
232
|
```
|
|
244
233
|
|
|
234
|
+
`Box.init` is shorthand for writing the `static init` method yourself.
|
|
235
|
+
|
|
236
|
+
```ts
|
|
237
|
+
class UserService {
|
|
238
|
+
constructor(private db: Database, private logger: Logger) {}
|
|
239
|
+
|
|
240
|
+
static init(box: Box) {
|
|
241
|
+
return new UserService(box.get(Database), box.get(LoggerFactory));
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
```
|
|
245
|
+
|
|
246
|
+
Use `box.for()` when you need custom logic alongside dependency resolution.
|
|
247
|
+
|
|
248
|
+
```ts
|
|
249
|
+
class UserService {
|
|
250
|
+
constructor(private db: Database, private logger: Logger) {}
|
|
251
|
+
|
|
252
|
+
static init(box: Box) {
|
|
253
|
+
const logger = box.get(LoggerFactory);
|
|
254
|
+
logger.log("Initializing UserService");
|
|
255
|
+
return box.for(UserService).get(Database, LoggerFactory);
|
|
256
|
+
}
|
|
257
|
+
}
|
|
258
|
+
```
|
|
259
|
+
|
|
260
|
+
Classes with no constructor parameters are resolved automatically without needing `static init`. If `static init` is defined, it takes priority over the default constructor.
|
|
261
|
+
|
|
245
262
|
## Mocking
|
|
246
263
|
|
|
247
264
|
You can mock dependencies for testing using `Box.mock`. This is particularly useful with factories and interfaces.
|
package/dist/context.d.cts
CHANGED
|
@@ -17,7 +17,7 @@ declare function useBox(): Box;
|
|
|
17
17
|
* Resolves a cached instance from the current {@link withBox} scope.
|
|
18
18
|
* Shorthand for `useBox().get(constructor)`.
|
|
19
19
|
*/
|
|
20
|
-
declare function resolve<T
|
|
20
|
+
declare function resolve<T extends Constructor<any>>(constructor: T): ConstructorInstanceType<T>;
|
|
21
21
|
/**
|
|
22
22
|
* Resolves multiple cached instances from the current {@link withBox} scope.
|
|
23
23
|
* Shorthand for `useBox().all.get(constructors)`.
|
package/dist/context.d.mts
CHANGED
|
@@ -17,7 +17,7 @@ declare function useBox(): Box;
|
|
|
17
17
|
* Resolves a cached instance from the current {@link withBox} scope.
|
|
18
18
|
* Shorthand for `useBox().get(constructor)`.
|
|
19
19
|
*/
|
|
20
|
-
declare function resolve<T
|
|
20
|
+
declare function resolve<T extends Constructor<any>>(constructor: T): ConstructorInstanceType<T>;
|
|
21
21
|
/**
|
|
22
22
|
* Resolves multiple cached instances from the current {@link withBox} scope.
|
|
23
23
|
* Shorthand for `useBox().all.get(constructors)`.
|
package/dist/index.cjs
CHANGED
|
@@ -16,7 +16,7 @@
|
|
|
16
16
|
function factory(init) {
|
|
17
17
|
return { init };
|
|
18
18
|
}
|
|
19
|
-
const noCacheSymbol = Symbol("Box
|
|
19
|
+
const noCacheSymbol = Symbol("Box.noCache");
|
|
20
20
|
/**
|
|
21
21
|
* Creates a {@link Constructor} from a factory function whose result is never cached.
|
|
22
22
|
* The factory is called on every resolution, always returning a fresh value
|
|
@@ -115,6 +115,21 @@ var Box = class {
|
|
|
115
115
|
return new Construct(this, constructor);
|
|
116
116
|
}
|
|
117
117
|
/**
|
|
118
|
+
* Returns a {@link StaticConstruct} builder for defining a `static init` method.
|
|
119
|
+
* The result can be assigned directly to `static init`.
|
|
120
|
+
*
|
|
121
|
+
* @example
|
|
122
|
+
* ```ts
|
|
123
|
+
* class UserService {
|
|
124
|
+
* constructor(private db: Database, private logger: Logger) {}
|
|
125
|
+
* static init = Box.init(UserService).get(Database, LoggerFactory);
|
|
126
|
+
* }
|
|
127
|
+
* ```
|
|
128
|
+
*/
|
|
129
|
+
static init(constructor) {
|
|
130
|
+
return new StaticConstruct(constructor);
|
|
131
|
+
}
|
|
132
|
+
/**
|
|
118
133
|
* Registers a mock value in the box's cache for a given constructor.
|
|
119
134
|
* Useful for replacing dependencies in tests.
|
|
120
135
|
*/
|
|
@@ -197,10 +212,64 @@ var Construct = class {
|
|
|
197
212
|
return new this.construct(...instances);
|
|
198
213
|
}
|
|
199
214
|
};
|
|
215
|
+
/**
|
|
216
|
+
* Builder for creating a `static init` function with constructor dependencies
|
|
217
|
+
* resolved from a {@link Box}.
|
|
218
|
+
*/
|
|
219
|
+
var StaticConstruct = class {
|
|
220
|
+
constructor(construct) {
|
|
221
|
+
this.construct = construct;
|
|
222
|
+
}
|
|
223
|
+
/**
|
|
224
|
+
* Resolves each dependency as a new transient instance via {@link Box.new},
|
|
225
|
+
* meaning dependencies are not cached or shared.
|
|
226
|
+
* Returns a function compatible with `static init` that can be assigned directly.
|
|
227
|
+
*
|
|
228
|
+
* The returned instance is cached or transient depending on whether the
|
|
229
|
+
* class is retrieved via {@link Box.get} or {@link Box.new}.
|
|
230
|
+
*
|
|
231
|
+
* @example
|
|
232
|
+
* ```ts
|
|
233
|
+
* class UserService {
|
|
234
|
+
* constructor(private db: Database, private logger: Logger) {}
|
|
235
|
+
* static init = Box.init(UserService).get(Database, LoggerFactory);
|
|
236
|
+
* }
|
|
237
|
+
* ```
|
|
238
|
+
*/
|
|
239
|
+
new(...args) {
|
|
240
|
+
return (box) => {
|
|
241
|
+
const instances = args.map((arg) => box.new(arg));
|
|
242
|
+
return new this.construct(...instances);
|
|
243
|
+
};
|
|
244
|
+
}
|
|
245
|
+
/**
|
|
246
|
+
* Resolves each dependency as a cached instance via {@link Box.get},
|
|
247
|
+
* meaning dependencies are shared across the box.
|
|
248
|
+
* Returns a function compatible with `static init` that can be assigned directly.
|
|
249
|
+
*
|
|
250
|
+
* The returned instance is cached or transient depending on whether the
|
|
251
|
+
* class is retrieved via {@link Box.get} or {@link Box.new}.
|
|
252
|
+
*
|
|
253
|
+
* @example
|
|
254
|
+
* ```ts
|
|
255
|
+
* class UserService {
|
|
256
|
+
* constructor(private db: Database, private logger: Logger) {}
|
|
257
|
+
* static init = Box.init(UserService).get(Database, LoggerFactory);
|
|
258
|
+
* }
|
|
259
|
+
* ```
|
|
260
|
+
*/
|
|
261
|
+
get(...args) {
|
|
262
|
+
return (box) => {
|
|
263
|
+
const instances = args.map((arg) => box.get(arg));
|
|
264
|
+
return new this.construct(...instances);
|
|
265
|
+
};
|
|
266
|
+
}
|
|
267
|
+
};
|
|
200
268
|
|
|
201
269
|
//#endregion
|
|
202
270
|
exports.Box = Box;
|
|
203
271
|
exports.Construct = Construct;
|
|
272
|
+
exports.StaticConstruct = StaticConstruct;
|
|
204
273
|
exports.constant = constant;
|
|
205
274
|
exports.factory = factory;
|
|
206
275
|
exports.transient = transient;
|
package/dist/index.d.cts
CHANGED
|
@@ -10,7 +10,11 @@ type Constructor<T> = {
|
|
|
10
10
|
new (): T;
|
|
11
11
|
};
|
|
12
12
|
/** Extracts the instance type from a {@link Constructor}. */
|
|
13
|
-
type ConstructorInstanceType<T> = T extends
|
|
13
|
+
type ConstructorInstanceType<T> = T extends {
|
|
14
|
+
init(box: Box): infer U;
|
|
15
|
+
} ? U : T extends {
|
|
16
|
+
new (): infer U;
|
|
17
|
+
} ? U : never;
|
|
14
18
|
/**
|
|
15
19
|
* Creates a {@link Constructor} from a factory function.
|
|
16
20
|
* The factory receives the box as an argument, allowing it to resolve other dependencies.
|
|
@@ -86,12 +90,12 @@ declare class Box {
|
|
|
86
90
|
* Creates a new (transient) instance without caching. Useful for instances
|
|
87
91
|
* that should not be shared.
|
|
88
92
|
*/
|
|
89
|
-
new<T
|
|
93
|
+
new<T extends Constructor<any>>(constructor: T): ConstructorInstanceType<T>;
|
|
90
94
|
/**
|
|
91
95
|
* Resolves an instance from the cache, or creates and caches a new one.
|
|
92
96
|
* Subsequent calls with the same constructor return the cached instance.
|
|
93
97
|
*/
|
|
94
|
-
get<T
|
|
98
|
+
get<T extends Constructor<any>>(constructor: T): ConstructorInstanceType<T>;
|
|
95
99
|
/** Resolves multiple constructors at once. */
|
|
96
100
|
readonly all: BoxAll;
|
|
97
101
|
/**
|
|
@@ -103,6 +107,19 @@ declare class Box {
|
|
|
103
107
|
* the class is retrieved via {@link Box.get} or kept transient via {@link Box.new}.
|
|
104
108
|
*/
|
|
105
109
|
for<T extends ClassConstructor<any>>(constructor: T): Construct<T>;
|
|
110
|
+
/**
|
|
111
|
+
* Returns a {@link StaticConstruct} builder for defining a `static init` method.
|
|
112
|
+
* The result can be assigned directly to `static init`.
|
|
113
|
+
*
|
|
114
|
+
* @example
|
|
115
|
+
* ```ts
|
|
116
|
+
* class UserService {
|
|
117
|
+
* constructor(private db: Database, private logger: Logger) {}
|
|
118
|
+
* static init = Box.init(UserService).get(Database, LoggerFactory);
|
|
119
|
+
* }
|
|
120
|
+
* ```
|
|
121
|
+
*/
|
|
122
|
+
static init<T extends ClassConstructor<any>>(constructor: T): StaticConstruct<T>;
|
|
106
123
|
/**
|
|
107
124
|
* Registers a mock value in the box's cache for a given constructor.
|
|
108
125
|
* Useful for replacing dependencies in tests.
|
|
@@ -173,6 +190,48 @@ declare class Construct<T extends ClassConstructor<any>> {
|
|
|
173
190
|
*/
|
|
174
191
|
get(...args: ClassConstructorArgs<T>): InstanceType<T>;
|
|
175
192
|
}
|
|
193
|
+
/**
|
|
194
|
+
* Builder for creating a `static init` function with constructor dependencies
|
|
195
|
+
* resolved from a {@link Box}.
|
|
196
|
+
*/
|
|
197
|
+
declare class StaticConstruct<T extends ClassConstructor<any>> {
|
|
198
|
+
private construct;
|
|
199
|
+
constructor(construct: T);
|
|
200
|
+
/**
|
|
201
|
+
* Resolves each dependency as a new transient instance via {@link Box.new},
|
|
202
|
+
* meaning dependencies are not cached or shared.
|
|
203
|
+
* Returns a function compatible with `static init` that can be assigned directly.
|
|
204
|
+
*
|
|
205
|
+
* The returned instance is cached or transient depending on whether the
|
|
206
|
+
* class is retrieved via {@link Box.get} or {@link Box.new}.
|
|
207
|
+
*
|
|
208
|
+
* @example
|
|
209
|
+
* ```ts
|
|
210
|
+
* class UserService {
|
|
211
|
+
* constructor(private db: Database, private logger: Logger) {}
|
|
212
|
+
* static init = Box.init(UserService).get(Database, LoggerFactory);
|
|
213
|
+
* }
|
|
214
|
+
* ```
|
|
215
|
+
*/
|
|
216
|
+
new(...args: ClassConstructorArgs<T>): (box: Box) => InstanceType<T>;
|
|
217
|
+
/**
|
|
218
|
+
* Resolves each dependency as a cached instance via {@link Box.get},
|
|
219
|
+
* meaning dependencies are shared across the box.
|
|
220
|
+
* Returns a function compatible with `static init` that can be assigned directly.
|
|
221
|
+
*
|
|
222
|
+
* The returned instance is cached or transient depending on whether the
|
|
223
|
+
* class is retrieved via {@link Box.get} or {@link Box.new}.
|
|
224
|
+
*
|
|
225
|
+
* @example
|
|
226
|
+
* ```ts
|
|
227
|
+
* class UserService {
|
|
228
|
+
* constructor(private db: Database, private logger: Logger) {}
|
|
229
|
+
* static init = Box.init(UserService).get(Database, LoggerFactory);
|
|
230
|
+
* }
|
|
231
|
+
* ```
|
|
232
|
+
*/
|
|
233
|
+
get(...args: ClassConstructorArgs<T>): (box: Box) => InstanceType<T>;
|
|
234
|
+
}
|
|
176
235
|
/** A class with any constructor signature. */
|
|
177
236
|
type ClassConstructor<T> = {
|
|
178
237
|
new (...args: any): T;
|
|
@@ -180,4 +239,4 @@ type ClassConstructor<T> = {
|
|
|
180
239
|
/** Maps each constructor parameter to its corresponding {@link Constructor} type. */
|
|
181
240
|
type ClassConstructorArgs<T extends ClassConstructor<any>, Args = ConstructorParameters<T>> = { [K in keyof Args]: Constructor<Args[K]> };
|
|
182
241
|
//#endregion
|
|
183
|
-
export { Box, Construct, Constructor, ConstructorInstanceType, constant, factory, transient };
|
|
242
|
+
export { Box, Construct, Constructor, ConstructorInstanceType, StaticConstruct, constant, factory, transient };
|
package/dist/index.d.mts
CHANGED
|
@@ -10,7 +10,11 @@ type Constructor<T> = {
|
|
|
10
10
|
new (): T;
|
|
11
11
|
};
|
|
12
12
|
/** Extracts the instance type from a {@link Constructor}. */
|
|
13
|
-
type ConstructorInstanceType<T> = T extends
|
|
13
|
+
type ConstructorInstanceType<T> = T extends {
|
|
14
|
+
init(box: Box): infer U;
|
|
15
|
+
} ? U : T extends {
|
|
16
|
+
new (): infer U;
|
|
17
|
+
} ? U : never;
|
|
14
18
|
/**
|
|
15
19
|
* Creates a {@link Constructor} from a factory function.
|
|
16
20
|
* The factory receives the box as an argument, allowing it to resolve other dependencies.
|
|
@@ -86,12 +90,12 @@ declare class Box {
|
|
|
86
90
|
* Creates a new (transient) instance without caching. Useful for instances
|
|
87
91
|
* that should not be shared.
|
|
88
92
|
*/
|
|
89
|
-
new<T
|
|
93
|
+
new<T extends Constructor<any>>(constructor: T): ConstructorInstanceType<T>;
|
|
90
94
|
/**
|
|
91
95
|
* Resolves an instance from the cache, or creates and caches a new one.
|
|
92
96
|
* Subsequent calls with the same constructor return the cached instance.
|
|
93
97
|
*/
|
|
94
|
-
get<T
|
|
98
|
+
get<T extends Constructor<any>>(constructor: T): ConstructorInstanceType<T>;
|
|
95
99
|
/** Resolves multiple constructors at once. */
|
|
96
100
|
readonly all: BoxAll;
|
|
97
101
|
/**
|
|
@@ -103,6 +107,19 @@ declare class Box {
|
|
|
103
107
|
* the class is retrieved via {@link Box.get} or kept transient via {@link Box.new}.
|
|
104
108
|
*/
|
|
105
109
|
for<T extends ClassConstructor<any>>(constructor: T): Construct<T>;
|
|
110
|
+
/**
|
|
111
|
+
* Returns a {@link StaticConstruct} builder for defining a `static init` method.
|
|
112
|
+
* The result can be assigned directly to `static init`.
|
|
113
|
+
*
|
|
114
|
+
* @example
|
|
115
|
+
* ```ts
|
|
116
|
+
* class UserService {
|
|
117
|
+
* constructor(private db: Database, private logger: Logger) {}
|
|
118
|
+
* static init = Box.init(UserService).get(Database, LoggerFactory);
|
|
119
|
+
* }
|
|
120
|
+
* ```
|
|
121
|
+
*/
|
|
122
|
+
static init<T extends ClassConstructor<any>>(constructor: T): StaticConstruct<T>;
|
|
106
123
|
/**
|
|
107
124
|
* Registers a mock value in the box's cache for a given constructor.
|
|
108
125
|
* Useful for replacing dependencies in tests.
|
|
@@ -173,6 +190,48 @@ declare class Construct<T extends ClassConstructor<any>> {
|
|
|
173
190
|
*/
|
|
174
191
|
get(...args: ClassConstructorArgs<T>): InstanceType<T>;
|
|
175
192
|
}
|
|
193
|
+
/**
|
|
194
|
+
* Builder for creating a `static init` function with constructor dependencies
|
|
195
|
+
* resolved from a {@link Box}.
|
|
196
|
+
*/
|
|
197
|
+
declare class StaticConstruct<T extends ClassConstructor<any>> {
|
|
198
|
+
private construct;
|
|
199
|
+
constructor(construct: T);
|
|
200
|
+
/**
|
|
201
|
+
* Resolves each dependency as a new transient instance via {@link Box.new},
|
|
202
|
+
* meaning dependencies are not cached or shared.
|
|
203
|
+
* Returns a function compatible with `static init` that can be assigned directly.
|
|
204
|
+
*
|
|
205
|
+
* The returned instance is cached or transient depending on whether the
|
|
206
|
+
* class is retrieved via {@link Box.get} or {@link Box.new}.
|
|
207
|
+
*
|
|
208
|
+
* @example
|
|
209
|
+
* ```ts
|
|
210
|
+
* class UserService {
|
|
211
|
+
* constructor(private db: Database, private logger: Logger) {}
|
|
212
|
+
* static init = Box.init(UserService).get(Database, LoggerFactory);
|
|
213
|
+
* }
|
|
214
|
+
* ```
|
|
215
|
+
*/
|
|
216
|
+
new(...args: ClassConstructorArgs<T>): (box: Box) => InstanceType<T>;
|
|
217
|
+
/**
|
|
218
|
+
* Resolves each dependency as a cached instance via {@link Box.get},
|
|
219
|
+
* meaning dependencies are shared across the box.
|
|
220
|
+
* Returns a function compatible with `static init` that can be assigned directly.
|
|
221
|
+
*
|
|
222
|
+
* The returned instance is cached or transient depending on whether the
|
|
223
|
+
* class is retrieved via {@link Box.get} or {@link Box.new}.
|
|
224
|
+
*
|
|
225
|
+
* @example
|
|
226
|
+
* ```ts
|
|
227
|
+
* class UserService {
|
|
228
|
+
* constructor(private db: Database, private logger: Logger) {}
|
|
229
|
+
* static init = Box.init(UserService).get(Database, LoggerFactory);
|
|
230
|
+
* }
|
|
231
|
+
* ```
|
|
232
|
+
*/
|
|
233
|
+
get(...args: ClassConstructorArgs<T>): (box: Box) => InstanceType<T>;
|
|
234
|
+
}
|
|
176
235
|
/** A class with any constructor signature. */
|
|
177
236
|
type ClassConstructor<T> = {
|
|
178
237
|
new (...args: any): T;
|
|
@@ -180,4 +239,4 @@ type ClassConstructor<T> = {
|
|
|
180
239
|
/** Maps each constructor parameter to its corresponding {@link Constructor} type. */
|
|
181
240
|
type ClassConstructorArgs<T extends ClassConstructor<any>, Args = ConstructorParameters<T>> = { [K in keyof Args]: Constructor<Args[K]> };
|
|
182
241
|
//#endregion
|
|
183
|
-
export { Box, Construct, Constructor, ConstructorInstanceType, constant, factory, transient };
|
|
242
|
+
export { Box, Construct, Constructor, ConstructorInstanceType, StaticConstruct, constant, factory, transient };
|
package/dist/index.mjs
CHANGED
|
@@ -15,7 +15,7 @@
|
|
|
15
15
|
function factory(init) {
|
|
16
16
|
return { init };
|
|
17
17
|
}
|
|
18
|
-
const noCacheSymbol = Symbol("Box
|
|
18
|
+
const noCacheSymbol = Symbol("Box.noCache");
|
|
19
19
|
/**
|
|
20
20
|
* Creates a {@link Constructor} from a factory function whose result is never cached.
|
|
21
21
|
* The factory is called on every resolution, always returning a fresh value
|
|
@@ -114,6 +114,21 @@ var Box = class {
|
|
|
114
114
|
return new Construct(this, constructor);
|
|
115
115
|
}
|
|
116
116
|
/**
|
|
117
|
+
* Returns a {@link StaticConstruct} builder for defining a `static init` method.
|
|
118
|
+
* The result can be assigned directly to `static init`.
|
|
119
|
+
*
|
|
120
|
+
* @example
|
|
121
|
+
* ```ts
|
|
122
|
+
* class UserService {
|
|
123
|
+
* constructor(private db: Database, private logger: Logger) {}
|
|
124
|
+
* static init = Box.init(UserService).get(Database, LoggerFactory);
|
|
125
|
+
* }
|
|
126
|
+
* ```
|
|
127
|
+
*/
|
|
128
|
+
static init(constructor) {
|
|
129
|
+
return new StaticConstruct(constructor);
|
|
130
|
+
}
|
|
131
|
+
/**
|
|
117
132
|
* Registers a mock value in the box's cache for a given constructor.
|
|
118
133
|
* Useful for replacing dependencies in tests.
|
|
119
134
|
*/
|
|
@@ -196,6 +211,59 @@ var Construct = class {
|
|
|
196
211
|
return new this.construct(...instances);
|
|
197
212
|
}
|
|
198
213
|
};
|
|
214
|
+
/**
|
|
215
|
+
* Builder for creating a `static init` function with constructor dependencies
|
|
216
|
+
* resolved from a {@link Box}.
|
|
217
|
+
*/
|
|
218
|
+
var StaticConstruct = class {
|
|
219
|
+
constructor(construct) {
|
|
220
|
+
this.construct = construct;
|
|
221
|
+
}
|
|
222
|
+
/**
|
|
223
|
+
* Resolves each dependency as a new transient instance via {@link Box.new},
|
|
224
|
+
* meaning dependencies are not cached or shared.
|
|
225
|
+
* Returns a function compatible with `static init` that can be assigned directly.
|
|
226
|
+
*
|
|
227
|
+
* The returned instance is cached or transient depending on whether the
|
|
228
|
+
* class is retrieved via {@link Box.get} or {@link Box.new}.
|
|
229
|
+
*
|
|
230
|
+
* @example
|
|
231
|
+
* ```ts
|
|
232
|
+
* class UserService {
|
|
233
|
+
* constructor(private db: Database, private logger: Logger) {}
|
|
234
|
+
* static init = Box.init(UserService).get(Database, LoggerFactory);
|
|
235
|
+
* }
|
|
236
|
+
* ```
|
|
237
|
+
*/
|
|
238
|
+
new(...args) {
|
|
239
|
+
return (box) => {
|
|
240
|
+
const instances = args.map((arg) => box.new(arg));
|
|
241
|
+
return new this.construct(...instances);
|
|
242
|
+
};
|
|
243
|
+
}
|
|
244
|
+
/**
|
|
245
|
+
* Resolves each dependency as a cached instance via {@link Box.get},
|
|
246
|
+
* meaning dependencies are shared across the box.
|
|
247
|
+
* Returns a function compatible with `static init` that can be assigned directly.
|
|
248
|
+
*
|
|
249
|
+
* The returned instance is cached or transient depending on whether the
|
|
250
|
+
* class is retrieved via {@link Box.get} or {@link Box.new}.
|
|
251
|
+
*
|
|
252
|
+
* @example
|
|
253
|
+
* ```ts
|
|
254
|
+
* class UserService {
|
|
255
|
+
* constructor(private db: Database, private logger: Logger) {}
|
|
256
|
+
* static init = Box.init(UserService).get(Database, LoggerFactory);
|
|
257
|
+
* }
|
|
258
|
+
* ```
|
|
259
|
+
*/
|
|
260
|
+
get(...args) {
|
|
261
|
+
return (box) => {
|
|
262
|
+
const instances = args.map((arg) => box.get(arg));
|
|
263
|
+
return new this.construct(...instances);
|
|
264
|
+
};
|
|
265
|
+
}
|
|
266
|
+
};
|
|
199
267
|
|
|
200
268
|
//#endregion
|
|
201
|
-
export { Box, Construct, constant, factory, transient };
|
|
269
|
+
export { Box, Construct, StaticConstruct, constant, factory, transient };
|