getbox 1.3.1 → 1.4.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/CONTEXT.md CHANGED
@@ -11,8 +11,8 @@ import { withBox } from "getbox/context";
11
11
 
12
12
  withBox(() => {
13
13
  // All code in this scope can resolve dependencies
14
- const app = resolve(App);
15
- app.start();
14
+ const service = inject(UserService);
15
+ service.createUser("Alice");
16
16
  });
17
17
  ```
18
18
 
@@ -23,24 +23,24 @@ import { Box } from "getbox";
23
23
  import { withBox } from "getbox/context";
24
24
 
25
25
  const box = new Box();
26
- Box.mock(box, LoggerFactory, new TestLogger());
26
+ Box.mock(box, LoggerFactory, new MockLogger());
27
27
 
28
28
  withBox(box, () => {
29
- const app = resolve(App);
30
- app.start();
29
+ const service = inject(UserService);
30
+ service.createUser("Alice");
31
31
  });
32
32
  ```
33
33
 
34
34
  ## Resolving dependencies
35
35
 
36
- With the context pattern, classes can use `resolve` directly as field initializers. No `static init` method is needed.
36
+ With the context pattern, classes can use `inject` directly as field initializers. No `static init` property is needed.
37
37
 
38
38
  ```ts
39
- import { resolve } from "getbox/context";
39
+ import { inject } from "getbox/context";
40
40
 
41
41
  class UserService {
42
- public db = resolve(Database);
43
- public logger = resolve(LoggerFactory);
42
+ public db = inject(Database);
43
+ public logger = inject(LoggerFactory);
44
44
 
45
45
  createUser(name: string) {
46
46
  this.logger.log(`Creating user: ${name}`);
@@ -63,36 +63,21 @@ class UserService {
63
63
 
64
64
  ## Resolving multiple dependencies
65
65
 
66
- Use `resolveAll` to resolve multiple constructors at once. Accepts an object or array of constructors.
66
+ Use `injectAll` to resolve multiple constructors at once. Accepts an object or array of constructors.
67
67
 
68
68
  ```ts
69
69
  withBox(() => {
70
70
  // Object form
71
- const { db, logger } = resolveAll({ db: Database, logger: LoggerFactory });
71
+ const { db, logger } = injectAll({ db: Database, logger: LoggerFactory });
72
72
 
73
73
  // Array form
74
- const [db2, logger2] = resolveAll([Database, LoggerFactory]);
74
+ const [db2, logger2] = injectAll([Database, LoggerFactory]);
75
75
 
76
76
  console.log(db === db2); // true (cached)
77
77
  console.log(logger === logger2); // true (cached)
78
78
  });
79
79
  ```
80
80
 
81
- ## Resolving constructor parameters
82
-
83
- Use `construct` to create a class instance with resolved constructor parameters.
84
-
85
- ```ts
86
- class UserService {
87
- constructor(private db: Database, private logger: Logger) {}
88
- }
89
-
90
- withBox(() => {
91
- const service = construct(UserService).get(Database, LoggerFactory);
92
- service.createUser("Alice");
93
- });
94
- ```
95
-
96
81
  ## Accessing the box
97
82
 
98
83
  Use `useBox()` to get the current box from the scope. This is useful when you need full access to the box API.
@@ -110,11 +95,11 @@ Each `withBox` call creates an independent scope. Nested scopes do not share the
110
95
 
111
96
  ```ts
112
97
  withBox(() => {
113
- const db = resolve(Database);
98
+ const db = inject(Database);
114
99
 
115
- // Inner scope gets a fresh box
100
+ // Inner scope gets a new box
116
101
  withBox(() => {
117
- const db2 = resolve(Database);
102
+ const db2 = inject(Database);
118
103
  console.log(db === db2); // false (different scope)
119
104
  });
120
105
  });
package/README.md CHANGED
@@ -2,9 +2,9 @@
2
2
 
3
3
  ### Lightweight dependency injection for TypeScript.
4
4
 
5
- `getbox` provides a simple way of managing dependencies in TypeScript applications. Dependencies are defined as constructors that act as interfaces for the values they resolve.
5
+ `getbox` is a lightweight inversion of control container for TypeScript. Constructors declare their own dependencies, keeping instantiation logic colocated with the type that owns it.
6
6
 
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.
7
+ Callers depend on types, not implementations. The box resolves and caches instances automatically on first use.
8
8
 
9
9
  ## Installation
10
10
 
@@ -16,252 +16,204 @@ npm install getbox
16
16
 
17
17
  `getbox` has a very small API surface. You typically only need `box.get()` and optionally `static init` or the `factory` helper.
18
18
 
19
- For an alternative pattern using AsyncLocalStorage where classes can resolve dependencies directly in their constructors, see [getbox/context](./CONTEXT.md).
19
+ For an alternative pattern using AsyncLocalStorage where classes can resolve dependencies directly, see [getbox/context](./CONTEXT.md).
20
20
 
21
- ### Create a class
21
+ ### Quick start
22
22
 
23
- Classes are instantiated once and cached. Subsequent calls return the cached instance.
23
+ Create a `Box` instance and call `box.get()` to resolve instances. The box automatically resolves dependencies and caches every instance, so shared dependencies always point to the same reference.
24
24
 
25
25
  ```ts
26
- // printer.ts
27
- export class Printer {
28
- print(text: string): string {
26
+ import { Box } from "getbox";
27
+
28
+ class Printer {
29
+ print(text: string) {
29
30
  return text.toUpperCase();
30
31
  }
31
32
  }
32
- ```
33
-
34
- ### Use in another class
35
-
36
- The `static init` property tells the box what dependencies to pass when instantiating the class.
37
33
 
38
- ```ts
39
- // office.ts
40
- import { Box } from "getbox";
41
- import { Printer } from "./printer";
42
-
43
- export class Office {
34
+ class Office {
44
35
  constructor(public printer: Printer) {}
45
36
 
46
37
  static init = Box.init(Office).get(Printer);
47
38
  }
48
- ```
49
-
50
- ### Use in application
51
-
52
- Create a Box instance to hold cached instances.
53
-
54
- When initializing a class, any dependencies it has will also be cached, ensuring that shared dependencies use the same instance.
55
-
56
- ```ts
57
- // main.ts
58
- import { Box } from "getbox";
59
- import { Office } from "./office";
60
- import { Printer } from "./printer";
61
39
 
62
40
  const box = new Box();
63
41
 
64
42
  const office = box.get(Office);
65
43
  office.printer.print("hello world");
66
44
 
67
- // Instances are cached and shared
45
+ // Dependencies are cached and shared
68
46
  const printer = box.get(Printer);
69
47
  console.log(office.printer === printer); // true
70
48
  ```
71
49
 
72
- ## Transient instances
50
+ ## Constructors
51
+
52
+ Constructors define what the box resolves. `getbox` supports classes, factories, derived values, and constants. Because constructors act as interfaces, the underlying implementation can change without affecting any consumer.
53
+
54
+ ### Classes
73
55
 
74
- Use `box.new()` to create a new instance each time without caching. This is useful for instances that should not be shared.
56
+ Define a `static init` property to allow the box to resolve classes that have constructor parameters. Classes with no parameters do not require it.
75
57
 
76
58
  ```ts
77
- // main.ts
78
59
  import { Box } from "getbox";
79
60
 
80
- class Database {
81
- connect() {
82
- /* ... */
61
+ class UserService {
62
+ constructor(private db: Database, private logger: Logger) {}
63
+
64
+ static init = Box.init(UserService).get(Database, LoggerFactory);
65
+
66
+ createUser(name: string) {
67
+ this.logger.log(`Creating user: ${name}`);
83
68
  }
84
69
  }
85
70
 
86
71
  const box = new Box();
87
-
88
- const db1 = box.new(Database);
89
- const db2 = box.new(Database);
90
-
91
- console.log(db1 === db2); // false
72
+ const service = box.get(UserService);
73
+ service.createUser("Alice");
92
74
  ```
93
75
 
94
- ## Factory functions
95
-
96
- Use the `factory` helper to create function-based constructors instead of classes. Factories work well with interfaces for better abstraction.
76
+ `Box.init` is shorthand for writing the `static init` property yourself.
97
77
 
98
78
  ```ts
99
- // logger.ts
100
- import { Box, factory } from "getbox";
79
+ class UserService {
80
+ constructor(private db: Database, private logger: Logger) {}
101
81
 
102
- export interface Logger {
103
- log(message: string): void;
82
+ static init(box: Box) {
83
+ return new UserService(box.get(Database), box.get(LoggerFactory));
84
+ }
104
85
  }
105
-
106
- const LoggerFactory = factory((box: Box): Logger => {
107
- return {
108
- log(message: string): void {
109
- console.log(`[LOG] ${message}`);
110
- },
111
- };
112
- });
113
86
  ```
114
87
 
115
- ```ts
116
- // service.ts
117
- import { Box } from "getbox";
118
- import { Logger, LoggerFactory } from "./logger";
119
-
120
- export class UserService {
121
- constructor(private logger: Logger) {}
88
+ Use `box.for()` when you need custom logic alongside dependency resolution.
122
89
 
123
- static init = Box.init(UserService).get(LoggerFactory);
90
+ ```ts
91
+ class UserService {
92
+ constructor(private db: Database, private logger: Logger) {}
124
93
 
125
- createUser(name: string) {
126
- this.logger.log(`Creating user: ${name}`);
94
+ static init(box: Box) {
95
+ const logger = box.get(LoggerFactory);
96
+ logger.log("Initializing UserService");
97
+ return box.for(UserService).get(Database, LoggerFactory);
127
98
  }
128
99
  }
129
100
  ```
130
101
 
131
- ## Constants
132
-
133
- Use the `constant` helper to register constant values without needing a factory or class. Constant values are never cached since they are already fixed.
102
+ If `static init` is defined, it takes priority over the class constructor.
134
103
 
135
- ```ts
136
- import { Box, constant } from "getbox";
137
-
138
- const ApiUrl = constant("https://api.example.com");
139
- const Port = constant(3000);
140
- const Config = constant({
141
- baseUrl: "https://example.com",
142
- timeout: 5000,
143
- });
104
+ ### Factory functions
144
105
 
145
- const box = new Box();
106
+ Use the `factory` helper to create function-based constructors instead of classes. Factories work well with interfaces for better abstraction.
146
107
 
147
- const apiUrl = box.get(ApiUrl);
148
- const port = box.get(Port);
149
- const config = box.get(Config);
108
+ ```ts
109
+ import { Box, factory } from "getbox";
150
110
 
151
- console.log(apiUrl); // "https://api.example.com"
152
- console.log(port); // 3000
153
- console.log(config.timeout); // 5000
154
- ```
111
+ interface Logger {
112
+ log(message: string): void;
113
+ }
155
114
 
156
- Since constructors act as interfaces, a `constant` can later be replaced with a `factory` without changing any callers.
115
+ const LoggerFactory = factory(
116
+ (): Logger => ({
117
+ log(message: string) {
118
+ console.log(`[LOG] ${message}`);
119
+ },
120
+ }),
121
+ );
157
122
 
158
- ```ts
159
- const ApiUrl = factory((box: Box) => {
160
- const config = box.get(Config);
161
- return `${config.baseUrl}/api`;
162
- });
123
+ const box = new Box();
124
+ const logger = box.get(LoggerFactory);
163
125
 
164
- const apiUrl = box.get(ApiUrl); // "https://example.com/api"
126
+ logger.log("hello world");
165
127
  ```
166
128
 
167
- ## Transient factories
129
+ ### Derived values
168
130
 
169
- Use the `transient` helper to create a factory whose result is never cached. The factory is called on every resolution, even when retrieved via `box.get()`.
131
+ Use the `derive` helper to compute a value from the box without caching the result.
170
132
 
171
133
  ```ts
172
- import { Box, transient } from "getbox";
134
+ import { Box, derive } from "getbox";
173
135
 
174
- const RequestId = transient(() => crypto.randomUUID());
136
+ class Config {
137
+ baseUrl = "https://example.com";
138
+ }
139
+
140
+ const RequestContext = derive((box) => ({
141
+ baseUrl: box.get(Config).baseUrl,
142
+ timestamp: Date.now(),
143
+ }));
175
144
 
176
145
  const box = new Box();
177
146
 
178
- const id1 = box.get(RequestId);
179
- const id2 = box.get(RequestId);
147
+ const ctx1 = box.get(RequestContext);
148
+ const ctx2 = box.get(RequestContext);
180
149
 
181
- console.log(id1 === id2); // false
150
+ console.log(ctx1 === ctx2); // false
182
151
  ```
183
152
 
184
- ## Resolving multiple constructors
153
+ ### Constants
185
154
 
186
- Use `box.all.get()` to resolve multiple constructors at once. Pass an object to get an object of instances, or an array to get an array of instances.
155
+ Use the `constant` helper to wrap a fixed value as a constructor. Constant values are never cached and always return the same stable reference.
187
156
 
188
157
  ```ts
189
- import { Box } from "getbox";
190
-
191
- const box = new Box();
192
-
193
- // Object form
194
- const { db, logger } = box.all.get({ db: Database, logger: LoggerFactory });
195
-
196
- // Array form
197
- const [db2, logger2] = box.all.get([Database, LoggerFactory]);
198
-
199
- console.log(db === db2); // true (cached)
200
- console.log(logger === logger2); // true (cached)
201
- ```
158
+ import { Box, constant } from "getbox";
202
159
 
203
- Use `box.all.new()` to resolve multiple constructors as transient instances.
160
+ const ApiUrl = constant("https://api.example.com");
161
+ const Port = constant(3000);
162
+ const Config = constant({
163
+ baseUrl: "https://example.com",
164
+ timeout: 5000,
165
+ });
204
166
 
205
- ```ts
206
- const { db } = box.all.new({ db: Database });
207
- const [db2] = box.all.new([Database]);
167
+ const box = new Box();
208
168
 
209
- console.log(db === db2); // false (transient)
169
+ console.log(box.get(ApiUrl)); // "https://api.example.com"
170
+ console.log(box.get(Port)); // 3000
171
+ console.log(box.get(Config).timeout); // 5000
210
172
  ```
211
173
 
212
- ## Class constructors
174
+ ## Resolving instances
213
175
 
214
- Use `Box.init` to allow resolving classes that have constructor parameters.
176
+ Use `box.get()` to resolve a cached instance. The box resolves the constructor on first call and returns the same instance on every subsequent call. Use `box.new()` to always get a new instance without caching.
215
177
 
216
178
  ```ts
217
179
  import { Box } from "getbox";
218
180
 
219
- class UserService {
220
- constructor(private db: Database, private logger: Logger) {}
221
-
222
- static init = Box.init(UserService).get(Database, LoggerFactory);
223
-
224
- createUser(name: string) {
225
- this.logger.log(`Creating user: ${name}`);
181
+ class Database {
182
+ connect() {
183
+ /* ... */
226
184
  }
227
185
  }
228
186
 
229
187
  const box = new Box();
230
- const service = box.get(UserService);
231
- service.createUser("Alice");
232
- ```
233
-
234
- `Box.init` is shorthand for writing the `static init` method yourself.
235
188
 
236
- ```ts
237
- class UserService {
238
- constructor(private db: Database, private logger: Logger) {}
189
+ const db1 = box.get(Database);
190
+ const db2 = box.get(Database);
191
+ console.log(db1 === db2); // true (cached)
239
192
 
240
- static init(box: Box) {
241
- return new UserService(box.get(Database), box.get(LoggerFactory));
242
- }
243
- }
193
+ const db3 = box.new(Database);
194
+ const db4 = box.new(Database);
195
+ console.log(db3 === db4); // false (never cached)
244
196
  ```
245
197
 
246
- Use `box.for()` when you need custom logic alongside dependency resolution.
198
+ Use `box.all.get()` or `box.all.new()` to resolve multiple constructors at once. Pass an array to get an array of instances, or an object to get an object of instances.
247
199
 
248
200
  ```ts
249
- class UserService {
250
- constructor(private db: Database, private logger: Logger) {}
201
+ const box = new Box();
251
202
 
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
- }
203
+ // Cached
204
+ const { db, logger } = box.all.get({ db: Database, logger: LoggerFactory });
205
+ const [db2, logger2] = box.all.get([Database, LoggerFactory]);
206
+
207
+ // New instances
208
+ const { db3 } = box.all.new({ db3: Database });
209
+ const [db4] = box.all.new([Database]);
258
210
  ```
259
211
 
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.
212
+ > `box.get()` does not cache `derive` or `constant` values.
261
213
 
262
214
  ## Mocking
263
215
 
264
- You can mock dependencies for testing using `Box.mock`. This is particularly useful with factories and interfaces.
216
+ You can mock dependencies for testing using `Box.mock`.
265
217
 
266
218
  ```ts
267
219
  // service.test.ts
@@ -306,7 +258,7 @@ Box.clear(box);
306
258
 
307
259
  ## Circular dependencies
308
260
 
309
- `getbox` does not prevent circular dependencies. You should structure your code to avoid circular imports between modules.
261
+ `getbox` does not prevent circular dependencies. You should structure your code to avoid them.
310
262
 
311
263
  ## License
312
264
 
package/dist/context.cjs CHANGED
@@ -20,15 +20,26 @@ function useBox() {
20
20
  * Resolves a cached instance from the current {@link withBox} scope.
21
21
  * Shorthand for `useBox().get(constructor)`.
22
22
  */
23
- function resolve(constructor) {
23
+ function inject(constructor) {
24
24
  return useBox().get(constructor);
25
25
  }
26
- function resolveAll(constructors) {
26
+ /**
27
+ * @deprecated Use {@link inject} instead.
28
+ */
29
+ function resolve(constructor) {
30
+ return inject(constructor);
31
+ }
32
+ function injectAll(constructors) {
27
33
  return useBox().all.get(constructors);
28
34
  }
35
+ function resolveAll(constructors) {
36
+ return injectAll(constructors);
37
+ }
29
38
  /**
30
39
  * Returns a builder for creating a class instance with resolved constructor
31
40
  * parameters from the current {@link withBox} scope. Shorthand for `useBox().for(constructor)`.
41
+ *
42
+ * @deprecated
32
43
  */
33
44
  function construct(constructor) {
34
45
  return useBox().for(constructor);
@@ -36,6 +47,8 @@ function construct(constructor) {
36
47
 
37
48
  //#endregion
38
49
  exports.construct = construct;
50
+ exports.inject = inject;
51
+ exports.injectAll = injectAll;
39
52
  exports.resolve = resolve;
40
53
  exports.resolveAll = resolveAll;
41
54
  exports.useBox = useBox;
@@ -4,7 +4,7 @@ import { Box, Construct, Constructor, ConstructorInstanceType } from "./index.cj
4
4
 
5
5
  /**
6
6
  * Runs a function within a scoped {@link Box} context using AsyncLocalStorage.
7
- * Creates a fresh Box if none is provided.
7
+ * Creates a new Box if none is provided.
8
8
  */
9
9
  declare function withBox<T>(fn: () => T): T;
10
10
  declare function withBox<T>(box: Box, fn: () => T): T;
@@ -17,17 +17,28 @@ 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 inject<T extends Constructor<any>>(constructor: T): ConstructorInstanceType<T>;
21
+ /**
22
+ * @deprecated Use {@link inject} instead.
23
+ */
20
24
  declare function resolve<T extends Constructor<any>>(constructor: T): ConstructorInstanceType<T>;
21
25
  /**
22
26
  * Resolves multiple cached instances from the current {@link withBox} scope.
23
27
  * Shorthand for `useBox().all.get(constructors)`.
24
28
  */
29
+ declare function injectAll<const T extends Constructor<any>[]>(constructors: T): { [K in keyof T]: ConstructorInstanceType<T[K]> };
30
+ declare function injectAll<T extends Record<string, Constructor<any>>>(constructors: T): { [K in keyof T]: ConstructorInstanceType<T[K]> };
31
+ /**
32
+ * @deprecated Use {@link injectAll} instead.
33
+ */
25
34
  declare function resolveAll<const T extends Constructor<any>[]>(constructors: T): { [K in keyof T]: ConstructorInstanceType<T[K]> };
26
35
  declare function resolveAll<T extends Record<string, Constructor<any>>>(constructors: T): { [K in keyof T]: ConstructorInstanceType<T[K]> };
27
36
  /**
28
37
  * Returns a builder for creating a class instance with resolved constructor
29
38
  * parameters from the current {@link withBox} scope. Shorthand for `useBox().for(constructor)`.
39
+ *
40
+ * @deprecated
30
41
  */
31
42
  declare function construct<T extends new (...args: any) => any>(constructor: T): Construct<T>;
32
43
  //#endregion
33
- export { construct, resolve, resolveAll, useBox, withBox };
44
+ export { construct, inject, injectAll, resolve, resolveAll, useBox, withBox };
@@ -4,7 +4,7 @@ import { Box, Construct, Constructor, ConstructorInstanceType } from "./index.mj
4
4
 
5
5
  /**
6
6
  * Runs a function within a scoped {@link Box} context using AsyncLocalStorage.
7
- * Creates a fresh Box if none is provided.
7
+ * Creates a new Box if none is provided.
8
8
  */
9
9
  declare function withBox<T>(fn: () => T): T;
10
10
  declare function withBox<T>(box: Box, fn: () => T): T;
@@ -17,17 +17,28 @@ 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 inject<T extends Constructor<any>>(constructor: T): ConstructorInstanceType<T>;
21
+ /**
22
+ * @deprecated Use {@link inject} instead.
23
+ */
20
24
  declare function resolve<T extends Constructor<any>>(constructor: T): ConstructorInstanceType<T>;
21
25
  /**
22
26
  * Resolves multiple cached instances from the current {@link withBox} scope.
23
27
  * Shorthand for `useBox().all.get(constructors)`.
24
28
  */
29
+ declare function injectAll<const T extends Constructor<any>[]>(constructors: T): { [K in keyof T]: ConstructorInstanceType<T[K]> };
30
+ declare function injectAll<T extends Record<string, Constructor<any>>>(constructors: T): { [K in keyof T]: ConstructorInstanceType<T[K]> };
31
+ /**
32
+ * @deprecated Use {@link injectAll} instead.
33
+ */
25
34
  declare function resolveAll<const T extends Constructor<any>[]>(constructors: T): { [K in keyof T]: ConstructorInstanceType<T[K]> };
26
35
  declare function resolveAll<T extends Record<string, Constructor<any>>>(constructors: T): { [K in keyof T]: ConstructorInstanceType<T[K]> };
27
36
  /**
28
37
  * Returns a builder for creating a class instance with resolved constructor
29
38
  * parameters from the current {@link withBox} scope. Shorthand for `useBox().for(constructor)`.
39
+ *
40
+ * @deprecated
30
41
  */
31
42
  declare function construct<T extends new (...args: any) => any>(constructor: T): Construct<T>;
32
43
  //#endregion
33
- export { construct, resolve, resolveAll, useBox, withBox };
44
+ export { construct, inject, injectAll, resolve, resolveAll, useBox, withBox };
package/dist/context.mjs CHANGED
@@ -20,19 +20,30 @@ function useBox() {
20
20
  * Resolves a cached instance from the current {@link withBox} scope.
21
21
  * Shorthand for `useBox().get(constructor)`.
22
22
  */
23
- function resolve(constructor) {
23
+ function inject(constructor) {
24
24
  return useBox().get(constructor);
25
25
  }
26
- function resolveAll(constructors) {
26
+ /**
27
+ * @deprecated Use {@link inject} instead.
28
+ */
29
+ function resolve(constructor) {
30
+ return inject(constructor);
31
+ }
32
+ function injectAll(constructors) {
27
33
  return useBox().all.get(constructors);
28
34
  }
35
+ function resolveAll(constructors) {
36
+ return injectAll(constructors);
37
+ }
29
38
  /**
30
39
  * Returns a builder for creating a class instance with resolved constructor
31
40
  * parameters from the current {@link withBox} scope. Shorthand for `useBox().for(constructor)`.
41
+ *
42
+ * @deprecated
32
43
  */
33
44
  function construct(constructor) {
34
45
  return useBox().for(constructor);
35
46
  }
36
47
 
37
48
  //#endregion
38
- export { construct, resolve, resolveAll, useBox, withBox };
49
+ export { construct, inject, injectAll, resolve, resolveAll, useBox, withBox };
package/dist/index.cjs CHANGED
@@ -18,25 +18,37 @@ function factory(init) {
18
18
  }
19
19
  const noCacheSymbol = Symbol("Box.noCache");
20
20
  /**
21
- * Creates a {@link Constructor} from a factory function whose result is never cached.
22
- * The factory is called on every resolution, always returning a fresh value
23
- * even when retrieved via {@link Box.get}.
21
+ * Creates a {@link Constructor} that computes a value from the box without caching the result.
24
22
  *
25
23
  * @example
26
24
  * ```ts
27
- * const RequestId = transient(() => crypto.randomUUID());
28
- * const id1 = box.get(RequestId);
29
- * const id2 = box.get(RequestId);
30
- * console.log(id1 === id2); // false
25
+ * class Config {
26
+ * baseUrl = "https://example.com";
27
+ * }
28
+ *
29
+ * const RequestContext = derive((box) => ({
30
+ * baseUrl: box.get(Config).baseUrl,
31
+ * timestamp: Date.now(),
32
+ * }));
33
+ *
34
+ * const ctx1 = box.get(RequestContext);
35
+ * const ctx2 = box.get(RequestContext);
36
+ * console.log(ctx1 === ctx2); // false
31
37
  * ```
32
38
  */
33
- function transient(init) {
39
+ function derive(init) {
34
40
  return {
35
41
  init,
36
42
  [noCacheSymbol]: true
37
43
  };
38
44
  }
39
45
  /**
46
+ * @deprecated Use {@link derive} instead.
47
+ */
48
+ function transient(init) {
49
+ return derive(init);
50
+ }
51
+ /**
40
52
  * Creates a {@link Constructor} that always resolves to the given constant value.
41
53
  * Constant values are never cached since they are already fixed.
42
54
  *
@@ -69,9 +81,7 @@ function constant(value) {
69
81
  *
70
82
  * class UserService {
71
83
  * constructor(private db: Database) {}
72
- * static init(box: Box) {
73
- * return new UserService(box.get(Database));
74
- * }
84
+ * static init = Box.init(UserService).get(Database);
75
85
  * }
76
86
  *
77
87
  * const box = new Box();
@@ -79,14 +89,12 @@ function constant(value) {
79
89
  * const db = box.get(Database);
80
90
  *
81
91
  * console.log(service.db === db); // true (cached)
82
- * console.log(box.new(Database) === db); // false (transient)
83
92
  * ```
84
93
  */
85
94
  var Box = class {
86
95
  cache = /* @__PURE__ */ new Map();
87
96
  /**
88
- * Creates a new (transient) instance without caching. Useful for instances
89
- * that should not be shared.
97
+ * Creates a new instance without caching.
90
98
  */
91
99
  new(constructor) {
92
100
  return "init" in constructor ? constructor.init(this) : new constructor();
@@ -109,7 +117,7 @@ var Box = class {
109
117
  *
110
118
  * Intended to be used inside a class's `static init` method. The instance
111
119
  * returned by the builder is never cached itself, but can be cached when
112
- * the class is retrieved via {@link Box.get} or kept transient via {@link Box.new}.
120
+ * the class is retrieved via {@link Box.get} or new via {@link Box.new}.
113
121
  */
114
122
  for(constructor) {
115
123
  return new Construct(this, constructor);
@@ -150,18 +158,18 @@ var BoxAll = class {
150
158
  constructor(box) {
151
159
  this.box = box;
152
160
  }
153
- get(constructors) {
154
- if (Array.isArray(constructors)) return constructors.map((c) => this.box.get(c));
155
- const result = {};
156
- for (const [key, constructor] of Object.entries(constructors)) result[key] = this.box.get(constructor);
157
- return result;
158
- }
159
161
  new(constructors) {
160
162
  if (Array.isArray(constructors)) return constructors.map((c) => this.box.new(c));
161
163
  const result = {};
162
164
  for (const [key, constructor] of Object.entries(constructors)) result[key] = this.box.new(constructor);
163
165
  return result;
164
166
  }
167
+ get(constructors) {
168
+ if (Array.isArray(constructors)) return constructors.map((c) => this.box.get(c));
169
+ const result = {};
170
+ for (const [key, constructor] of Object.entries(constructors)) result[key] = this.box.get(constructor);
171
+ return result;
172
+ }
165
173
  };
166
174
  /** Builder for creating class instances with constructor dependencies resolved from a {@link Box}. */
167
175
  var Construct = class {
@@ -170,10 +178,10 @@ var Construct = class {
170
178
  this.construct = construct;
171
179
  }
172
180
  /**
173
- * Resolves each dependency as a new transient instance via {@link Box.new},
181
+ * Resolves each dependency as a new instance via {@link Box.new},
174
182
  * meaning dependencies are not cached or shared.
175
183
  *
176
- * The returned instance is cached or transient depending on whether the
184
+ * The returned instance is cached or new depending on whether the
177
185
  * class is retrieved via {@link Box.get} or {@link Box.new}.
178
186
  *
179
187
  * @example
@@ -194,7 +202,7 @@ var Construct = class {
194
202
  * Resolves each dependency as a cached instance via {@link Box.get},
195
203
  * meaning dependencies are shared across the box.
196
204
  *
197
- * The returned instance is cached or transient depending on whether the
205
+ * The returned instance is cached or new depending on whether the
198
206
  * class is retrieved via {@link Box.get} or {@link Box.new}.
199
207
  *
200
208
  * @example
@@ -221,11 +229,11 @@ var StaticConstruct = class {
221
229
  this.construct = construct;
222
230
  }
223
231
  /**
224
- * Resolves each dependency as a new transient instance via {@link Box.new},
232
+ * Resolves each dependency as a new instance via {@link Box.new},
225
233
  * meaning dependencies are not cached or shared.
226
234
  * Returns a function compatible with `static init` that can be assigned directly.
227
235
  *
228
- * The returned instance is cached or transient depending on whether the
236
+ * The returned instance is cached or new depending on whether the
229
237
  * class is retrieved via {@link Box.get} or {@link Box.new}.
230
238
  *
231
239
  * @example
@@ -247,7 +255,7 @@ var StaticConstruct = class {
247
255
  * meaning dependencies are shared across the box.
248
256
  * Returns a function compatible with `static init` that can be assigned directly.
249
257
  *
250
- * The returned instance is cached or transient depending on whether the
258
+ * The returned instance is cached or new depending on whether the
251
259
  * class is retrieved via {@link Box.get} or {@link Box.new}.
252
260
  *
253
261
  * @example
@@ -271,5 +279,6 @@ exports.Box = Box;
271
279
  exports.Construct = Construct;
272
280
  exports.StaticConstruct = StaticConstruct;
273
281
  exports.constant = constant;
282
+ exports.derive = derive;
274
283
  exports.factory = factory;
275
284
  exports.transient = transient;
package/dist/index.d.cts CHANGED
@@ -30,18 +30,28 @@ type ConstructorInstanceType<T> = T extends {
30
30
  */
31
31
  declare function factory<T>(init: (box: Box) => T): Constructor<T>;
32
32
  /**
33
- * Creates a {@link Constructor} from a factory function whose result is never cached.
34
- * The factory is called on every resolution, always returning a fresh value
35
- * even when retrieved via {@link Box.get}.
33
+ * Creates a {@link Constructor} that computes a value from the box without caching the result.
36
34
  *
37
35
  * @example
38
36
  * ```ts
39
- * const RequestId = transient(() => crypto.randomUUID());
40
- * const id1 = box.get(RequestId);
41
- * const id2 = box.get(RequestId);
42
- * console.log(id1 === id2); // false
37
+ * class Config {
38
+ * baseUrl = "https://example.com";
39
+ * }
40
+ *
41
+ * const RequestContext = derive((box) => ({
42
+ * baseUrl: box.get(Config).baseUrl,
43
+ * timestamp: Date.now(),
44
+ * }));
45
+ *
46
+ * const ctx1 = box.get(RequestContext);
47
+ * const ctx2 = box.get(RequestContext);
48
+ * console.log(ctx1 === ctx2); // false
43
49
  * ```
44
50
  */
51
+ declare function derive<T>(init: (box: Box) => T): Constructor<T>;
52
+ /**
53
+ * @deprecated Use {@link derive} instead.
54
+ */
45
55
  declare function transient<T>(init: (box: Box) => T): Constructor<T>;
46
56
  /**
47
57
  * Creates a {@link Constructor} that always resolves to the given constant value.
@@ -71,9 +81,7 @@ declare function constant<const T>(value: T): Constructor<T>;
71
81
  *
72
82
  * class UserService {
73
83
  * constructor(private db: Database) {}
74
- * static init(box: Box) {
75
- * return new UserService(box.get(Database));
76
- * }
84
+ * static init = Box.init(UserService).get(Database);
77
85
  * }
78
86
  *
79
87
  * const box = new Box();
@@ -81,14 +89,12 @@ declare function constant<const T>(value: T): Constructor<T>;
81
89
  * const db = box.get(Database);
82
90
  *
83
91
  * console.log(service.db === db); // true (cached)
84
- * console.log(box.new(Database) === db); // false (transient)
85
92
  * ```
86
93
  */
87
94
  declare class Box {
88
- private cache;
95
+ protected cache: Map<Constructor<any>, any>;
89
96
  /**
90
- * Creates a new (transient) instance without caching. Useful for instances
91
- * that should not be shared.
97
+ * Creates a new instance without caching.
92
98
  */
93
99
  new<T extends Constructor<any>>(constructor: T): ConstructorInstanceType<T>;
94
100
  /**
@@ -104,7 +110,7 @@ declare class Box {
104
110
  *
105
111
  * Intended to be used inside a class's `static init` method. The instance
106
112
  * returned by the builder is never cached itself, but can be cached when
107
- * the class is retrieved via {@link Box.get} or kept transient via {@link Box.new}.
113
+ * the class is retrieved via {@link Box.get} or new via {@link Box.new}.
108
114
  */
109
115
  for<T extends ClassConstructor<any>>(constructor: T): Construct<T>;
110
116
  /**
@@ -136,17 +142,17 @@ declare class BoxAll {
136
142
  private box;
137
143
  constructor(box: Box);
138
144
  /**
139
- * Resolves each constructor as a cached instance via {@link Box.get}.
145
+ * Resolves each constructor as a new instance via {@link Box.new}.
140
146
  * Accepts an array or object of constructors and returns instances in the same shape.
141
147
  */
142
- get<const T extends Constructor<any>[]>(constructors: T): { [K in keyof T]: ConstructorInstanceType<T[K]> };
143
- get<T extends Record<string, Constructor<any>>>(constructors: T): { [K in keyof T]: ConstructorInstanceType<T[K]> };
148
+ new<const T extends Constructor<any>[]>(constructors: T): { [K in keyof T]: ConstructorInstanceType<T[K]> };
149
+ new<T extends Record<string, Constructor<any>>>(constructors: T): { [K in keyof T]: ConstructorInstanceType<T[K]> };
144
150
  /**
145
- * Resolves each constructor as a new transient instance via {@link Box.new}.
151
+ * Resolves each constructor as a cached instance via {@link Box.get}.
146
152
  * Accepts an array or object of constructors and returns instances in the same shape.
147
153
  */
148
- new<const T extends Constructor<any>[]>(constructors: T): { [K in keyof T]: ConstructorInstanceType<T[K]> };
149
- new<T extends Record<string, Constructor<any>>>(constructors: T): { [K in keyof T]: ConstructorInstanceType<T[K]> };
154
+ get<const T extends Constructor<any>[]>(constructors: T): { [K in keyof T]: ConstructorInstanceType<T[K]> };
155
+ get<T extends Record<string, Constructor<any>>>(constructors: T): { [K in keyof T]: ConstructorInstanceType<T[K]> };
150
156
  }
151
157
  /** Builder for creating class instances with constructor dependencies resolved from a {@link Box}. */
152
158
  declare class Construct<T extends ClassConstructor<any>> {
@@ -154,10 +160,10 @@ declare class Construct<T extends ClassConstructor<any>> {
154
160
  private construct;
155
161
  constructor(box: Box, construct: T);
156
162
  /**
157
- * Resolves each dependency as a new transient instance via {@link Box.new},
163
+ * Resolves each dependency as a new instance via {@link Box.new},
158
164
  * meaning dependencies are not cached or shared.
159
165
  *
160
- * The returned instance is cached or transient depending on whether the
166
+ * The returned instance is cached or new depending on whether the
161
167
  * class is retrieved via {@link Box.get} or {@link Box.new}.
162
168
  *
163
169
  * @example
@@ -175,7 +181,7 @@ declare class Construct<T extends ClassConstructor<any>> {
175
181
  * Resolves each dependency as a cached instance via {@link Box.get},
176
182
  * meaning dependencies are shared across the box.
177
183
  *
178
- * The returned instance is cached or transient depending on whether the
184
+ * The returned instance is cached or new depending on whether the
179
185
  * class is retrieved via {@link Box.get} or {@link Box.new}.
180
186
  *
181
187
  * @example
@@ -198,11 +204,11 @@ declare class StaticConstruct<T extends ClassConstructor<any>> {
198
204
  private construct;
199
205
  constructor(construct: T);
200
206
  /**
201
- * Resolves each dependency as a new transient instance via {@link Box.new},
207
+ * Resolves each dependency as a new instance via {@link Box.new},
202
208
  * meaning dependencies are not cached or shared.
203
209
  * Returns a function compatible with `static init` that can be assigned directly.
204
210
  *
205
- * The returned instance is cached or transient depending on whether the
211
+ * The returned instance is cached or new depending on whether the
206
212
  * class is retrieved via {@link Box.get} or {@link Box.new}.
207
213
  *
208
214
  * @example
@@ -219,7 +225,7 @@ declare class StaticConstruct<T extends ClassConstructor<any>> {
219
225
  * meaning dependencies are shared across the box.
220
226
  * Returns a function compatible with `static init` that can be assigned directly.
221
227
  *
222
- * The returned instance is cached or transient depending on whether the
228
+ * The returned instance is cached or new depending on whether the
223
229
  * class is retrieved via {@link Box.get} or {@link Box.new}.
224
230
  *
225
231
  * @example
@@ -239,4 +245,4 @@ type ClassConstructor<T> = {
239
245
  /** Maps each constructor parameter to its corresponding {@link Constructor} type. */
240
246
  type ClassConstructorArgs<T extends ClassConstructor<any>, Args = ConstructorParameters<T>> = { [K in keyof Args]: Constructor<Args[K]> };
241
247
  //#endregion
242
- export { Box, Construct, Constructor, ConstructorInstanceType, StaticConstruct, constant, factory, transient };
248
+ export { Box, Construct, Constructor, ConstructorInstanceType, StaticConstruct, constant, derive, factory, transient };
package/dist/index.d.mts CHANGED
@@ -30,18 +30,28 @@ type ConstructorInstanceType<T> = T extends {
30
30
  */
31
31
  declare function factory<T>(init: (box: Box) => T): Constructor<T>;
32
32
  /**
33
- * Creates a {@link Constructor} from a factory function whose result is never cached.
34
- * The factory is called on every resolution, always returning a fresh value
35
- * even when retrieved via {@link Box.get}.
33
+ * Creates a {@link Constructor} that computes a value from the box without caching the result.
36
34
  *
37
35
  * @example
38
36
  * ```ts
39
- * const RequestId = transient(() => crypto.randomUUID());
40
- * const id1 = box.get(RequestId);
41
- * const id2 = box.get(RequestId);
42
- * console.log(id1 === id2); // false
37
+ * class Config {
38
+ * baseUrl = "https://example.com";
39
+ * }
40
+ *
41
+ * const RequestContext = derive((box) => ({
42
+ * baseUrl: box.get(Config).baseUrl,
43
+ * timestamp: Date.now(),
44
+ * }));
45
+ *
46
+ * const ctx1 = box.get(RequestContext);
47
+ * const ctx2 = box.get(RequestContext);
48
+ * console.log(ctx1 === ctx2); // false
43
49
  * ```
44
50
  */
51
+ declare function derive<T>(init: (box: Box) => T): Constructor<T>;
52
+ /**
53
+ * @deprecated Use {@link derive} instead.
54
+ */
45
55
  declare function transient<T>(init: (box: Box) => T): Constructor<T>;
46
56
  /**
47
57
  * Creates a {@link Constructor} that always resolves to the given constant value.
@@ -71,9 +81,7 @@ declare function constant<const T>(value: T): Constructor<T>;
71
81
  *
72
82
  * class UserService {
73
83
  * constructor(private db: Database) {}
74
- * static init(box: Box) {
75
- * return new UserService(box.get(Database));
76
- * }
84
+ * static init = Box.init(UserService).get(Database);
77
85
  * }
78
86
  *
79
87
  * const box = new Box();
@@ -81,14 +89,12 @@ declare function constant<const T>(value: T): Constructor<T>;
81
89
  * const db = box.get(Database);
82
90
  *
83
91
  * console.log(service.db === db); // true (cached)
84
- * console.log(box.new(Database) === db); // false (transient)
85
92
  * ```
86
93
  */
87
94
  declare class Box {
88
- private cache;
95
+ protected cache: Map<Constructor<any>, any>;
89
96
  /**
90
- * Creates a new (transient) instance without caching. Useful for instances
91
- * that should not be shared.
97
+ * Creates a new instance without caching.
92
98
  */
93
99
  new<T extends Constructor<any>>(constructor: T): ConstructorInstanceType<T>;
94
100
  /**
@@ -104,7 +110,7 @@ declare class Box {
104
110
  *
105
111
  * Intended to be used inside a class's `static init` method. The instance
106
112
  * returned by the builder is never cached itself, but can be cached when
107
- * the class is retrieved via {@link Box.get} or kept transient via {@link Box.new}.
113
+ * the class is retrieved via {@link Box.get} or new via {@link Box.new}.
108
114
  */
109
115
  for<T extends ClassConstructor<any>>(constructor: T): Construct<T>;
110
116
  /**
@@ -136,17 +142,17 @@ declare class BoxAll {
136
142
  private box;
137
143
  constructor(box: Box);
138
144
  /**
139
- * Resolves each constructor as a cached instance via {@link Box.get}.
145
+ * Resolves each constructor as a new instance via {@link Box.new}.
140
146
  * Accepts an array or object of constructors and returns instances in the same shape.
141
147
  */
142
- get<const T extends Constructor<any>[]>(constructors: T): { [K in keyof T]: ConstructorInstanceType<T[K]> };
143
- get<T extends Record<string, Constructor<any>>>(constructors: T): { [K in keyof T]: ConstructorInstanceType<T[K]> };
148
+ new<const T extends Constructor<any>[]>(constructors: T): { [K in keyof T]: ConstructorInstanceType<T[K]> };
149
+ new<T extends Record<string, Constructor<any>>>(constructors: T): { [K in keyof T]: ConstructorInstanceType<T[K]> };
144
150
  /**
145
- * Resolves each constructor as a new transient instance via {@link Box.new}.
151
+ * Resolves each constructor as a cached instance via {@link Box.get}.
146
152
  * Accepts an array or object of constructors and returns instances in the same shape.
147
153
  */
148
- new<const T extends Constructor<any>[]>(constructors: T): { [K in keyof T]: ConstructorInstanceType<T[K]> };
149
- new<T extends Record<string, Constructor<any>>>(constructors: T): { [K in keyof T]: ConstructorInstanceType<T[K]> };
154
+ get<const T extends Constructor<any>[]>(constructors: T): { [K in keyof T]: ConstructorInstanceType<T[K]> };
155
+ get<T extends Record<string, Constructor<any>>>(constructors: T): { [K in keyof T]: ConstructorInstanceType<T[K]> };
150
156
  }
151
157
  /** Builder for creating class instances with constructor dependencies resolved from a {@link Box}. */
152
158
  declare class Construct<T extends ClassConstructor<any>> {
@@ -154,10 +160,10 @@ declare class Construct<T extends ClassConstructor<any>> {
154
160
  private construct;
155
161
  constructor(box: Box, construct: T);
156
162
  /**
157
- * Resolves each dependency as a new transient instance via {@link Box.new},
163
+ * Resolves each dependency as a new instance via {@link Box.new},
158
164
  * meaning dependencies are not cached or shared.
159
165
  *
160
- * The returned instance is cached or transient depending on whether the
166
+ * The returned instance is cached or new depending on whether the
161
167
  * class is retrieved via {@link Box.get} or {@link Box.new}.
162
168
  *
163
169
  * @example
@@ -175,7 +181,7 @@ declare class Construct<T extends ClassConstructor<any>> {
175
181
  * Resolves each dependency as a cached instance via {@link Box.get},
176
182
  * meaning dependencies are shared across the box.
177
183
  *
178
- * The returned instance is cached or transient depending on whether the
184
+ * The returned instance is cached or new depending on whether the
179
185
  * class is retrieved via {@link Box.get} or {@link Box.new}.
180
186
  *
181
187
  * @example
@@ -198,11 +204,11 @@ declare class StaticConstruct<T extends ClassConstructor<any>> {
198
204
  private construct;
199
205
  constructor(construct: T);
200
206
  /**
201
- * Resolves each dependency as a new transient instance via {@link Box.new},
207
+ * Resolves each dependency as a new instance via {@link Box.new},
202
208
  * meaning dependencies are not cached or shared.
203
209
  * Returns a function compatible with `static init` that can be assigned directly.
204
210
  *
205
- * The returned instance is cached or transient depending on whether the
211
+ * The returned instance is cached or new depending on whether the
206
212
  * class is retrieved via {@link Box.get} or {@link Box.new}.
207
213
  *
208
214
  * @example
@@ -219,7 +225,7 @@ declare class StaticConstruct<T extends ClassConstructor<any>> {
219
225
  * meaning dependencies are shared across the box.
220
226
  * Returns a function compatible with `static init` that can be assigned directly.
221
227
  *
222
- * The returned instance is cached or transient depending on whether the
228
+ * The returned instance is cached or new depending on whether the
223
229
  * class is retrieved via {@link Box.get} or {@link Box.new}.
224
230
  *
225
231
  * @example
@@ -239,4 +245,4 @@ type ClassConstructor<T> = {
239
245
  /** Maps each constructor parameter to its corresponding {@link Constructor} type. */
240
246
  type ClassConstructorArgs<T extends ClassConstructor<any>, Args = ConstructorParameters<T>> = { [K in keyof Args]: Constructor<Args[K]> };
241
247
  //#endregion
242
- export { Box, Construct, Constructor, ConstructorInstanceType, StaticConstruct, constant, factory, transient };
248
+ export { Box, Construct, Constructor, ConstructorInstanceType, StaticConstruct, constant, derive, factory, transient };
package/dist/index.mjs CHANGED
@@ -17,25 +17,37 @@ function factory(init) {
17
17
  }
18
18
  const noCacheSymbol = Symbol("Box.noCache");
19
19
  /**
20
- * Creates a {@link Constructor} from a factory function whose result is never cached.
21
- * The factory is called on every resolution, always returning a fresh value
22
- * even when retrieved via {@link Box.get}.
20
+ * Creates a {@link Constructor} that computes a value from the box without caching the result.
23
21
  *
24
22
  * @example
25
23
  * ```ts
26
- * const RequestId = transient(() => crypto.randomUUID());
27
- * const id1 = box.get(RequestId);
28
- * const id2 = box.get(RequestId);
29
- * console.log(id1 === id2); // false
24
+ * class Config {
25
+ * baseUrl = "https://example.com";
26
+ * }
27
+ *
28
+ * const RequestContext = derive((box) => ({
29
+ * baseUrl: box.get(Config).baseUrl,
30
+ * timestamp: Date.now(),
31
+ * }));
32
+ *
33
+ * const ctx1 = box.get(RequestContext);
34
+ * const ctx2 = box.get(RequestContext);
35
+ * console.log(ctx1 === ctx2); // false
30
36
  * ```
31
37
  */
32
- function transient(init) {
38
+ function derive(init) {
33
39
  return {
34
40
  init,
35
41
  [noCacheSymbol]: true
36
42
  };
37
43
  }
38
44
  /**
45
+ * @deprecated Use {@link derive} instead.
46
+ */
47
+ function transient(init) {
48
+ return derive(init);
49
+ }
50
+ /**
39
51
  * Creates a {@link Constructor} that always resolves to the given constant value.
40
52
  * Constant values are never cached since they are already fixed.
41
53
  *
@@ -68,9 +80,7 @@ function constant(value) {
68
80
  *
69
81
  * class UserService {
70
82
  * constructor(private db: Database) {}
71
- * static init(box: Box) {
72
- * return new UserService(box.get(Database));
73
- * }
83
+ * static init = Box.init(UserService).get(Database);
74
84
  * }
75
85
  *
76
86
  * const box = new Box();
@@ -78,14 +88,12 @@ function constant(value) {
78
88
  * const db = box.get(Database);
79
89
  *
80
90
  * console.log(service.db === db); // true (cached)
81
- * console.log(box.new(Database) === db); // false (transient)
82
91
  * ```
83
92
  */
84
93
  var Box = class {
85
94
  cache = /* @__PURE__ */ new Map();
86
95
  /**
87
- * Creates a new (transient) instance without caching. Useful for instances
88
- * that should not be shared.
96
+ * Creates a new instance without caching.
89
97
  */
90
98
  new(constructor) {
91
99
  return "init" in constructor ? constructor.init(this) : new constructor();
@@ -108,7 +116,7 @@ var Box = class {
108
116
  *
109
117
  * Intended to be used inside a class's `static init` method. The instance
110
118
  * returned by the builder is never cached itself, but can be cached when
111
- * the class is retrieved via {@link Box.get} or kept transient via {@link Box.new}.
119
+ * the class is retrieved via {@link Box.get} or new via {@link Box.new}.
112
120
  */
113
121
  for(constructor) {
114
122
  return new Construct(this, constructor);
@@ -149,18 +157,18 @@ var BoxAll = class {
149
157
  constructor(box) {
150
158
  this.box = box;
151
159
  }
152
- get(constructors) {
153
- if (Array.isArray(constructors)) return constructors.map((c) => this.box.get(c));
154
- const result = {};
155
- for (const [key, constructor] of Object.entries(constructors)) result[key] = this.box.get(constructor);
156
- return result;
157
- }
158
160
  new(constructors) {
159
161
  if (Array.isArray(constructors)) return constructors.map((c) => this.box.new(c));
160
162
  const result = {};
161
163
  for (const [key, constructor] of Object.entries(constructors)) result[key] = this.box.new(constructor);
162
164
  return result;
163
165
  }
166
+ get(constructors) {
167
+ if (Array.isArray(constructors)) return constructors.map((c) => this.box.get(c));
168
+ const result = {};
169
+ for (const [key, constructor] of Object.entries(constructors)) result[key] = this.box.get(constructor);
170
+ return result;
171
+ }
164
172
  };
165
173
  /** Builder for creating class instances with constructor dependencies resolved from a {@link Box}. */
166
174
  var Construct = class {
@@ -169,10 +177,10 @@ var Construct = class {
169
177
  this.construct = construct;
170
178
  }
171
179
  /**
172
- * Resolves each dependency as a new transient instance via {@link Box.new},
180
+ * Resolves each dependency as a new instance via {@link Box.new},
173
181
  * meaning dependencies are not cached or shared.
174
182
  *
175
- * The returned instance is cached or transient depending on whether the
183
+ * The returned instance is cached or new depending on whether the
176
184
  * class is retrieved via {@link Box.get} or {@link Box.new}.
177
185
  *
178
186
  * @example
@@ -193,7 +201,7 @@ var Construct = class {
193
201
  * Resolves each dependency as a cached instance via {@link Box.get},
194
202
  * meaning dependencies are shared across the box.
195
203
  *
196
- * The returned instance is cached or transient depending on whether the
204
+ * The returned instance is cached or new depending on whether the
197
205
  * class is retrieved via {@link Box.get} or {@link Box.new}.
198
206
  *
199
207
  * @example
@@ -220,11 +228,11 @@ var StaticConstruct = class {
220
228
  this.construct = construct;
221
229
  }
222
230
  /**
223
- * Resolves each dependency as a new transient instance via {@link Box.new},
231
+ * Resolves each dependency as a new instance via {@link Box.new},
224
232
  * meaning dependencies are not cached or shared.
225
233
  * Returns a function compatible with `static init` that can be assigned directly.
226
234
  *
227
- * The returned instance is cached or transient depending on whether the
235
+ * The returned instance is cached or new depending on whether the
228
236
  * class is retrieved via {@link Box.get} or {@link Box.new}.
229
237
  *
230
238
  * @example
@@ -246,7 +254,7 @@ var StaticConstruct = class {
246
254
  * meaning dependencies are shared across the box.
247
255
  * Returns a function compatible with `static init` that can be assigned directly.
248
256
  *
249
- * The returned instance is cached or transient depending on whether the
257
+ * The returned instance is cached or new depending on whether the
250
258
  * class is retrieved via {@link Box.get} or {@link Box.new}.
251
259
  *
252
260
  * @example
@@ -266,4 +274,4 @@ var StaticConstruct = class {
266
274
  };
267
275
 
268
276
  //#endregion
269
- export { Box, Construct, StaticConstruct, constant, factory, transient };
277
+ export { Box, Construct, StaticConstruct, constant, derive, factory, transient };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "getbox",
3
- "version": "1.3.1",
3
+ "version": "1.4.0",
4
4
  "description": "Lightweight dependency injection for TypeScript",
5
5
  "private": false,
6
6
  "main": "./dist/index.cjs",