proxydi 0.0.11 → 0.0.12
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/CHANGELOG.md +8 -2
- package/README.md +1 -0
- package/dist/ProxyDiContainer.d.ts +1 -6
- package/dist/index.cjs +93 -23
- package/dist/index.d.ts +2 -0
- package/dist/index.js +93 -24
- package/dist/index.umd.js +93 -23
- package/dist/middleware/MiddlewareListener.d.ts +29 -0
- package/dist/middleware/middleware.d.ts +3 -0
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -5,11 +5,17 @@ All notable changes to this project will be documented in this file.
|
|
|
5
5
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
|
|
6
6
|
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
7
|
|
|
8
|
-
## [[0.0.
|
|
8
|
+
## [[0.0.12](https://www.npmjs.com/package/proxydi/v/0.0.12)] - 2025-03-04
|
|
9
9
|
|
|
10
10
|
### Added
|
|
11
11
|
|
|
12
|
-
-
|
|
12
|
+
- Experimental @middleware [#14](https://github.com/proxy-di/proxydi/pull/14)
|
|
13
|
+
|
|
14
|
+
## [[0.0.11](https://www.npmjs.com/package/proxydi/v/0.0.11)] - 2025-03-03
|
|
15
|
+
|
|
16
|
+
### Added
|
|
17
|
+
|
|
18
|
+
- resolveInjectables() method [#13](https://github.com/proxy-di/proxydi/pull/13)
|
|
13
19
|
|
|
14
20
|
## [[0.0.10](https://www.npmjs.com/package/proxydi/v/0.0.10)] - 2025-03-02
|
|
15
21
|
|
package/README.md
CHANGED
|
@@ -17,6 +17,7 @@ Core features:
|
|
|
17
17
|
Eperimemntal features:
|
|
18
18
|
|
|
19
19
|
- Construtor injections (see unit tests for examples)
|
|
20
|
+
- Middleware listeners (see unit tests for examples)
|
|
20
21
|
- Matches dependencies by unique identifiers or automatically using class names and property names
|
|
21
22
|
|
|
22
23
|
## Quick start
|
|
@@ -29,6 +29,7 @@ export declare class ProxyDiContainer implements IProxyDiContainer {
|
|
|
29
29
|
* Settings that control the behavior of the container and it's children
|
|
30
30
|
*/
|
|
31
31
|
readonly settings: Required<ContainerSettings>;
|
|
32
|
+
private middlewareListener;
|
|
32
33
|
/**
|
|
33
34
|
* Creates a new instance of ProxyDiContainer.
|
|
34
35
|
* @param settings Optional container settings to override defaults.
|
|
@@ -47,12 +48,6 @@ export declare class ProxyDiContainer implements IProxyDiContainer {
|
|
|
47
48
|
register<T>(DependencyClass: DependencyClass<T>, dependencyId: DependencyId): T & ContainerizedDependency;
|
|
48
49
|
register<T>(dependency: T extends new (...args: any[]) => any ? never : T, dependencyId: DependencyId): T & ContainerizedDependency;
|
|
49
50
|
private createInstance;
|
|
50
|
-
/**
|
|
51
|
-
* Internal method that implements registeration of dependency and prepare it for injection.
|
|
52
|
-
* @param dependencyId The unique identifier of the dependency.
|
|
53
|
-
* @param dependency The dependency instance.
|
|
54
|
-
*/
|
|
55
|
-
private registerImpl;
|
|
56
51
|
/**
|
|
57
52
|
* Checks if a dependency with the given ID is known to the container or its ancestors which means that it can be resolved by this container
|
|
58
53
|
* @param dependencyId The identifier of the dependency.
|
package/dist/index.cjs
CHANGED
|
@@ -190,6 +190,72 @@ function makeConstructorDependencyProxy(container, dependencyId) {
|
|
|
190
190
|
});
|
|
191
191
|
}
|
|
192
192
|
|
|
193
|
+
const middlewaresClasses = {};
|
|
194
|
+
function middleware() {
|
|
195
|
+
return function (value, context) {
|
|
196
|
+
if ((context === null || context === undefined ? undefined : context.kind) !== 'class') {
|
|
197
|
+
throw new Error('@middleware decorator should decorate classes');
|
|
198
|
+
}
|
|
199
|
+
const name = context.name;
|
|
200
|
+
if (middlewaresClasses[name]) {
|
|
201
|
+
throw new Error(`ProxyDi has already regisered middleware ${String(name)} by @middleware`);
|
|
202
|
+
}
|
|
203
|
+
middlewaresClasses[name] = value;
|
|
204
|
+
};
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
class MiddlewareListener {
|
|
208
|
+
constructor(parent) {
|
|
209
|
+
this.parent = parent;
|
|
210
|
+
this.listeners = {
|
|
211
|
+
register: [],
|
|
212
|
+
remove: [],
|
|
213
|
+
};
|
|
214
|
+
}
|
|
215
|
+
add(middleware) {
|
|
216
|
+
if (isRegistingMiddleware(middleware)) {
|
|
217
|
+
middleware.onRegister && this.on('register', middleware.onRegister);
|
|
218
|
+
}
|
|
219
|
+
if (isRemovingMiddleware(middleware)) {
|
|
220
|
+
middleware.onRemove && this.on('remove', middleware.onRemove);
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
remove(middleware) {
|
|
224
|
+
if (isRegistingMiddleware(middleware)) {
|
|
225
|
+
middleware.onRegister &&
|
|
226
|
+
this.off('register', middleware.onRegister);
|
|
227
|
+
}
|
|
228
|
+
if (isRemovingMiddleware(middleware)) {
|
|
229
|
+
middleware.onRemove && this.off('remove', middleware.onRemove);
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
on(event, listener) {
|
|
233
|
+
this.listeners[event].push(listener);
|
|
234
|
+
}
|
|
235
|
+
onRegister(container, dependencyId, dependency) {
|
|
236
|
+
var _a;
|
|
237
|
+
this.listeners.register.forEach((listener) => listener(container, dependencyId, dependency));
|
|
238
|
+
(_a = this.parent) === null || _a === undefined ? undefined : _a.onRegister(container, dependencyId, dependency);
|
|
239
|
+
}
|
|
240
|
+
onRemove(container, dependencyId) {
|
|
241
|
+
var _a;
|
|
242
|
+
this.listeners.remove.forEach((listener) => listener(container, dependencyId));
|
|
243
|
+
(_a = this.parent) === null || _a === undefined ? undefined : _a.onRemove(container, dependencyId);
|
|
244
|
+
}
|
|
245
|
+
off(event, listener) {
|
|
246
|
+
const index = this.listeners[event].indexOf(listener);
|
|
247
|
+
if (index !== -1) {
|
|
248
|
+
this.listeners[event].splice(index, 1);
|
|
249
|
+
}
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
function isRegistingMiddleware(middleware) {
|
|
253
|
+
return middleware.onRegister;
|
|
254
|
+
}
|
|
255
|
+
function isRemovingMiddleware(middleware) {
|
|
256
|
+
return middleware.onRemove;
|
|
257
|
+
}
|
|
258
|
+
|
|
193
259
|
/**
|
|
194
260
|
* A dependency injection container
|
|
195
261
|
*/
|
|
@@ -210,6 +276,7 @@ class ProxyDiContainer {
|
|
|
210
276
|
*/
|
|
211
277
|
this.parentDependencyProxies = {};
|
|
212
278
|
this.id = ProxyDiContainer.idCounter++;
|
|
279
|
+
this.middlewareListener = new MiddlewareListener(parent === null || parent === undefined ? undefined : parent.middlewareListener);
|
|
213
280
|
if (parent) {
|
|
214
281
|
this.parent = parent;
|
|
215
282
|
this.parent.addChild(this);
|
|
@@ -217,28 +284,36 @@ class ProxyDiContainer {
|
|
|
217
284
|
this.settings = Object.assign(Object.assign({}, DEFAULT_SETTINGS), settings);
|
|
218
285
|
}
|
|
219
286
|
register(dependency, dependencyId) {
|
|
287
|
+
var _a;
|
|
220
288
|
if (this.dependencies[dependencyId]) {
|
|
221
289
|
if (!this.settings.allowRewriteDependencies) {
|
|
222
290
|
throw new Error(`ProxyDi already has dependency for ${String(dependencyId)}`);
|
|
223
291
|
}
|
|
224
292
|
}
|
|
225
|
-
let
|
|
293
|
+
let instance;
|
|
226
294
|
const isClass = typeof dependency === 'function';
|
|
227
295
|
if (isClass) {
|
|
228
|
-
|
|
296
|
+
instance = this.createInstance(dependency, dependencyId);
|
|
229
297
|
}
|
|
230
298
|
else {
|
|
231
|
-
|
|
232
|
-
if (!(typeof dependencyInstance === 'object') &&
|
|
233
|
-
!this.settings.allowRegisterAnything) {
|
|
234
|
-
throw new Error(`Can't register as dependency (allowRegisterAnything is off for this contatiner): ${dependencyInstance}`);
|
|
235
|
-
}
|
|
299
|
+
instance = dependency;
|
|
236
300
|
}
|
|
237
|
-
|
|
238
|
-
|
|
301
|
+
const isObject = typeof instance === 'object';
|
|
302
|
+
if (!isObject && !this.settings.allowRegisterAnything) {
|
|
303
|
+
throw new Error(`Can't register as dependency (allowRegisterAnything is off for this contatiner): ${instance}`);
|
|
239
304
|
}
|
|
240
|
-
|
|
241
|
-
|
|
305
|
+
if (isObject) {
|
|
306
|
+
instance[PROXYDI_CONTAINER] = this;
|
|
307
|
+
instance[DEPENDENCY_ID] = dependencyId;
|
|
308
|
+
}
|
|
309
|
+
this.injectDependenciesTo(instance);
|
|
310
|
+
this.dependencies[dependencyId] = instance;
|
|
311
|
+
const constructorName = (_a = instance.constructor) === null || _a === undefined ? undefined : _a.name;
|
|
312
|
+
if (constructorName && middlewaresClasses[constructorName]) {
|
|
313
|
+
this.middlewareListener.add(instance);
|
|
314
|
+
}
|
|
315
|
+
this.middlewareListener.onRegister(this, dependencyId, instance);
|
|
316
|
+
return instance;
|
|
242
317
|
}
|
|
243
318
|
createInstance(Dependency, dependencyId) {
|
|
244
319
|
const paramIds = constructorInjections[dependencyId] || [];
|
|
@@ -249,18 +324,6 @@ class ProxyDiContainer {
|
|
|
249
324
|
}
|
|
250
325
|
return new Dependency(...params);
|
|
251
326
|
}
|
|
252
|
-
/**
|
|
253
|
-
* Internal method that implements registeration of dependency and prepare it for injection.
|
|
254
|
-
* @param dependencyId The unique identifier of the dependency.
|
|
255
|
-
* @param dependency The dependency instance.
|
|
256
|
-
*/
|
|
257
|
-
registerImpl(dependency, dependencyId) {
|
|
258
|
-
this.injectDependenciesTo(dependency);
|
|
259
|
-
if (typeof dependency === 'object') {
|
|
260
|
-
dependency[DEPENDENCY_ID] = dependencyId;
|
|
261
|
-
}
|
|
262
|
-
this.dependencies[dependencyId] = dependency;
|
|
263
|
-
}
|
|
264
327
|
/**
|
|
265
328
|
* Checks if a dependency with the given ID is known to the container or its ancestors which means that it can be resolved by this container
|
|
266
329
|
* @param dependencyId The identifier of the dependency.
|
|
@@ -349,11 +412,16 @@ class ProxyDiContainer {
|
|
|
349
412
|
* @param dependencyOrId The dependency instance or dependency identifier to remove.
|
|
350
413
|
*/
|
|
351
414
|
remove(dependencyOrId) {
|
|
415
|
+
var _a;
|
|
352
416
|
const id = isDependency(dependencyOrId)
|
|
353
417
|
? dependencyOrId[DEPENDENCY_ID]
|
|
354
418
|
: dependencyOrId;
|
|
355
419
|
const dependency = this.dependencies[id];
|
|
356
420
|
if (dependency) {
|
|
421
|
+
const constructorName = (_a = dependency.constructor) === null || _a === undefined ? undefined : _a.name;
|
|
422
|
+
if (constructorName && middlewaresClasses[constructorName]) {
|
|
423
|
+
this.middlewareListener.remove(dependency);
|
|
424
|
+
}
|
|
357
425
|
const dependencyInjects = dependency[INJECTIONS]
|
|
358
426
|
? dependency[INJECTIONS]
|
|
359
427
|
: {};
|
|
@@ -362,6 +430,7 @@ class ProxyDiContainer {
|
|
|
362
430
|
});
|
|
363
431
|
delete dependency[DEPENDENCY_ID];
|
|
364
432
|
delete this.dependencies[id];
|
|
433
|
+
this.middlewareListener.onRemove(this, id);
|
|
365
434
|
}
|
|
366
435
|
}
|
|
367
436
|
/**
|
|
@@ -477,4 +546,5 @@ exports.PROXYDI_CONTAINER = PROXYDI_CONTAINER;
|
|
|
477
546
|
exports.ProxyDiContainer = ProxyDiContainer;
|
|
478
547
|
exports.inject = inject;
|
|
479
548
|
exports.injectable = injectable;
|
|
549
|
+
exports.middleware = middleware;
|
|
480
550
|
exports.resolveAll = resolveAll;
|
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
export { inject } from './inject';
|
|
2
2
|
export { ProxyDiContainer } from './ProxyDiContainer';
|
|
3
3
|
export { injectable } from './injectable';
|
|
4
|
+
export { middleware } from './middleware/middleware';
|
|
5
|
+
export { MiddlewareRegisteringListener, MiddlewareRemovingListener, } from './middleware/MiddlewareListener';
|
|
4
6
|
export { Injection, DependencyId, DependencyClass, ContainerSettings, PROXYDI_CONTAINER, DEPENDENCY_ID, } from './types';
|
|
5
7
|
export { resolveAll } from './resolveAll';
|
package/dist/index.js
CHANGED
|
@@ -188,6 +188,72 @@ function makeConstructorDependencyProxy(container, dependencyId) {
|
|
|
188
188
|
});
|
|
189
189
|
}
|
|
190
190
|
|
|
191
|
+
const middlewaresClasses = {};
|
|
192
|
+
function middleware() {
|
|
193
|
+
return function (value, context) {
|
|
194
|
+
if ((context === null || context === undefined ? undefined : context.kind) !== 'class') {
|
|
195
|
+
throw new Error('@middleware decorator should decorate classes');
|
|
196
|
+
}
|
|
197
|
+
const name = context.name;
|
|
198
|
+
if (middlewaresClasses[name]) {
|
|
199
|
+
throw new Error(`ProxyDi has already regisered middleware ${String(name)} by @middleware`);
|
|
200
|
+
}
|
|
201
|
+
middlewaresClasses[name] = value;
|
|
202
|
+
};
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
class MiddlewareListener {
|
|
206
|
+
constructor(parent) {
|
|
207
|
+
this.parent = parent;
|
|
208
|
+
this.listeners = {
|
|
209
|
+
register: [],
|
|
210
|
+
remove: [],
|
|
211
|
+
};
|
|
212
|
+
}
|
|
213
|
+
add(middleware) {
|
|
214
|
+
if (isRegistingMiddleware(middleware)) {
|
|
215
|
+
middleware.onRegister && this.on('register', middleware.onRegister);
|
|
216
|
+
}
|
|
217
|
+
if (isRemovingMiddleware(middleware)) {
|
|
218
|
+
middleware.onRemove && this.on('remove', middleware.onRemove);
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
remove(middleware) {
|
|
222
|
+
if (isRegistingMiddleware(middleware)) {
|
|
223
|
+
middleware.onRegister &&
|
|
224
|
+
this.off('register', middleware.onRegister);
|
|
225
|
+
}
|
|
226
|
+
if (isRemovingMiddleware(middleware)) {
|
|
227
|
+
middleware.onRemove && this.off('remove', middleware.onRemove);
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
on(event, listener) {
|
|
231
|
+
this.listeners[event].push(listener);
|
|
232
|
+
}
|
|
233
|
+
onRegister(container, dependencyId, dependency) {
|
|
234
|
+
var _a;
|
|
235
|
+
this.listeners.register.forEach((listener) => listener(container, dependencyId, dependency));
|
|
236
|
+
(_a = this.parent) === null || _a === undefined ? undefined : _a.onRegister(container, dependencyId, dependency);
|
|
237
|
+
}
|
|
238
|
+
onRemove(container, dependencyId) {
|
|
239
|
+
var _a;
|
|
240
|
+
this.listeners.remove.forEach((listener) => listener(container, dependencyId));
|
|
241
|
+
(_a = this.parent) === null || _a === undefined ? undefined : _a.onRemove(container, dependencyId);
|
|
242
|
+
}
|
|
243
|
+
off(event, listener) {
|
|
244
|
+
const index = this.listeners[event].indexOf(listener);
|
|
245
|
+
if (index !== -1) {
|
|
246
|
+
this.listeners[event].splice(index, 1);
|
|
247
|
+
}
|
|
248
|
+
}
|
|
249
|
+
}
|
|
250
|
+
function isRegistingMiddleware(middleware) {
|
|
251
|
+
return middleware.onRegister;
|
|
252
|
+
}
|
|
253
|
+
function isRemovingMiddleware(middleware) {
|
|
254
|
+
return middleware.onRemove;
|
|
255
|
+
}
|
|
256
|
+
|
|
191
257
|
/**
|
|
192
258
|
* A dependency injection container
|
|
193
259
|
*/
|
|
@@ -208,6 +274,7 @@ class ProxyDiContainer {
|
|
|
208
274
|
*/
|
|
209
275
|
this.parentDependencyProxies = {};
|
|
210
276
|
this.id = ProxyDiContainer.idCounter++;
|
|
277
|
+
this.middlewareListener = new MiddlewareListener(parent === null || parent === undefined ? undefined : parent.middlewareListener);
|
|
211
278
|
if (parent) {
|
|
212
279
|
this.parent = parent;
|
|
213
280
|
this.parent.addChild(this);
|
|
@@ -215,28 +282,36 @@ class ProxyDiContainer {
|
|
|
215
282
|
this.settings = Object.assign(Object.assign({}, DEFAULT_SETTINGS), settings);
|
|
216
283
|
}
|
|
217
284
|
register(dependency, dependencyId) {
|
|
285
|
+
var _a;
|
|
218
286
|
if (this.dependencies[dependencyId]) {
|
|
219
287
|
if (!this.settings.allowRewriteDependencies) {
|
|
220
288
|
throw new Error(`ProxyDi already has dependency for ${String(dependencyId)}`);
|
|
221
289
|
}
|
|
222
290
|
}
|
|
223
|
-
let
|
|
291
|
+
let instance;
|
|
224
292
|
const isClass = typeof dependency === 'function';
|
|
225
293
|
if (isClass) {
|
|
226
|
-
|
|
294
|
+
instance = this.createInstance(dependency, dependencyId);
|
|
227
295
|
}
|
|
228
296
|
else {
|
|
229
|
-
|
|
230
|
-
if (!(typeof dependencyInstance === 'object') &&
|
|
231
|
-
!this.settings.allowRegisterAnything) {
|
|
232
|
-
throw new Error(`Can't register as dependency (allowRegisterAnything is off for this contatiner): ${dependencyInstance}`);
|
|
233
|
-
}
|
|
297
|
+
instance = dependency;
|
|
234
298
|
}
|
|
235
|
-
|
|
236
|
-
|
|
299
|
+
const isObject = typeof instance === 'object';
|
|
300
|
+
if (!isObject && !this.settings.allowRegisterAnything) {
|
|
301
|
+
throw new Error(`Can't register as dependency (allowRegisterAnything is off for this contatiner): ${instance}`);
|
|
237
302
|
}
|
|
238
|
-
|
|
239
|
-
|
|
303
|
+
if (isObject) {
|
|
304
|
+
instance[PROXYDI_CONTAINER] = this;
|
|
305
|
+
instance[DEPENDENCY_ID] = dependencyId;
|
|
306
|
+
}
|
|
307
|
+
this.injectDependenciesTo(instance);
|
|
308
|
+
this.dependencies[dependencyId] = instance;
|
|
309
|
+
const constructorName = (_a = instance.constructor) === null || _a === undefined ? undefined : _a.name;
|
|
310
|
+
if (constructorName && middlewaresClasses[constructorName]) {
|
|
311
|
+
this.middlewareListener.add(instance);
|
|
312
|
+
}
|
|
313
|
+
this.middlewareListener.onRegister(this, dependencyId, instance);
|
|
314
|
+
return instance;
|
|
240
315
|
}
|
|
241
316
|
createInstance(Dependency, dependencyId) {
|
|
242
317
|
const paramIds = constructorInjections[dependencyId] || [];
|
|
@@ -247,18 +322,6 @@ class ProxyDiContainer {
|
|
|
247
322
|
}
|
|
248
323
|
return new Dependency(...params);
|
|
249
324
|
}
|
|
250
|
-
/**
|
|
251
|
-
* Internal method that implements registeration of dependency and prepare it for injection.
|
|
252
|
-
* @param dependencyId The unique identifier of the dependency.
|
|
253
|
-
* @param dependency The dependency instance.
|
|
254
|
-
*/
|
|
255
|
-
registerImpl(dependency, dependencyId) {
|
|
256
|
-
this.injectDependenciesTo(dependency);
|
|
257
|
-
if (typeof dependency === 'object') {
|
|
258
|
-
dependency[DEPENDENCY_ID] = dependencyId;
|
|
259
|
-
}
|
|
260
|
-
this.dependencies[dependencyId] = dependency;
|
|
261
|
-
}
|
|
262
325
|
/**
|
|
263
326
|
* Checks if a dependency with the given ID is known to the container or its ancestors which means that it can be resolved by this container
|
|
264
327
|
* @param dependencyId The identifier of the dependency.
|
|
@@ -347,11 +410,16 @@ class ProxyDiContainer {
|
|
|
347
410
|
* @param dependencyOrId The dependency instance or dependency identifier to remove.
|
|
348
411
|
*/
|
|
349
412
|
remove(dependencyOrId) {
|
|
413
|
+
var _a;
|
|
350
414
|
const id = isDependency(dependencyOrId)
|
|
351
415
|
? dependencyOrId[DEPENDENCY_ID]
|
|
352
416
|
: dependencyOrId;
|
|
353
417
|
const dependency = this.dependencies[id];
|
|
354
418
|
if (dependency) {
|
|
419
|
+
const constructorName = (_a = dependency.constructor) === null || _a === undefined ? undefined : _a.name;
|
|
420
|
+
if (constructorName && middlewaresClasses[constructorName]) {
|
|
421
|
+
this.middlewareListener.remove(dependency);
|
|
422
|
+
}
|
|
355
423
|
const dependencyInjects = dependency[INJECTIONS]
|
|
356
424
|
? dependency[INJECTIONS]
|
|
357
425
|
: {};
|
|
@@ -360,6 +428,7 @@ class ProxyDiContainer {
|
|
|
360
428
|
});
|
|
361
429
|
delete dependency[DEPENDENCY_ID];
|
|
362
430
|
delete this.dependencies[id];
|
|
431
|
+
this.middlewareListener.onRemove(this, id);
|
|
363
432
|
}
|
|
364
433
|
}
|
|
365
434
|
/**
|
|
@@ -470,4 +539,4 @@ function recursiveResolveAll(container, dependencyId) {
|
|
|
470
539
|
return all;
|
|
471
540
|
}
|
|
472
541
|
|
|
473
|
-
export { DEPENDENCY_ID, PROXYDI_CONTAINER, ProxyDiContainer, inject, injectable, resolveAll };
|
|
542
|
+
export { DEPENDENCY_ID, PROXYDI_CONTAINER, ProxyDiContainer, inject, injectable, middleware, resolveAll };
|
package/dist/index.umd.js
CHANGED
|
@@ -194,6 +194,72 @@
|
|
|
194
194
|
});
|
|
195
195
|
}
|
|
196
196
|
|
|
197
|
+
const middlewaresClasses = {};
|
|
198
|
+
function middleware() {
|
|
199
|
+
return function (value, context) {
|
|
200
|
+
if ((context === null || context === undefined ? undefined : context.kind) !== 'class') {
|
|
201
|
+
throw new Error('@middleware decorator should decorate classes');
|
|
202
|
+
}
|
|
203
|
+
const name = context.name;
|
|
204
|
+
if (middlewaresClasses[name]) {
|
|
205
|
+
throw new Error(`ProxyDi has already regisered middleware ${String(name)} by @middleware`);
|
|
206
|
+
}
|
|
207
|
+
middlewaresClasses[name] = value;
|
|
208
|
+
};
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
class MiddlewareListener {
|
|
212
|
+
constructor(parent) {
|
|
213
|
+
this.parent = parent;
|
|
214
|
+
this.listeners = {
|
|
215
|
+
register: [],
|
|
216
|
+
remove: [],
|
|
217
|
+
};
|
|
218
|
+
}
|
|
219
|
+
add(middleware) {
|
|
220
|
+
if (isRegistingMiddleware(middleware)) {
|
|
221
|
+
middleware.onRegister && this.on('register', middleware.onRegister);
|
|
222
|
+
}
|
|
223
|
+
if (isRemovingMiddleware(middleware)) {
|
|
224
|
+
middleware.onRemove && this.on('remove', middleware.onRemove);
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
remove(middleware) {
|
|
228
|
+
if (isRegistingMiddleware(middleware)) {
|
|
229
|
+
middleware.onRegister &&
|
|
230
|
+
this.off('register', middleware.onRegister);
|
|
231
|
+
}
|
|
232
|
+
if (isRemovingMiddleware(middleware)) {
|
|
233
|
+
middleware.onRemove && this.off('remove', middleware.onRemove);
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
on(event, listener) {
|
|
237
|
+
this.listeners[event].push(listener);
|
|
238
|
+
}
|
|
239
|
+
onRegister(container, dependencyId, dependency) {
|
|
240
|
+
var _a;
|
|
241
|
+
this.listeners.register.forEach((listener) => listener(container, dependencyId, dependency));
|
|
242
|
+
(_a = this.parent) === null || _a === undefined ? undefined : _a.onRegister(container, dependencyId, dependency);
|
|
243
|
+
}
|
|
244
|
+
onRemove(container, dependencyId) {
|
|
245
|
+
var _a;
|
|
246
|
+
this.listeners.remove.forEach((listener) => listener(container, dependencyId));
|
|
247
|
+
(_a = this.parent) === null || _a === undefined ? undefined : _a.onRemove(container, dependencyId);
|
|
248
|
+
}
|
|
249
|
+
off(event, listener) {
|
|
250
|
+
const index = this.listeners[event].indexOf(listener);
|
|
251
|
+
if (index !== -1) {
|
|
252
|
+
this.listeners[event].splice(index, 1);
|
|
253
|
+
}
|
|
254
|
+
}
|
|
255
|
+
}
|
|
256
|
+
function isRegistingMiddleware(middleware) {
|
|
257
|
+
return middleware.onRegister;
|
|
258
|
+
}
|
|
259
|
+
function isRemovingMiddleware(middleware) {
|
|
260
|
+
return middleware.onRemove;
|
|
261
|
+
}
|
|
262
|
+
|
|
197
263
|
/**
|
|
198
264
|
* A dependency injection container
|
|
199
265
|
*/
|
|
@@ -214,6 +280,7 @@
|
|
|
214
280
|
*/
|
|
215
281
|
this.parentDependencyProxies = {};
|
|
216
282
|
this.id = ProxyDiContainer.idCounter++;
|
|
283
|
+
this.middlewareListener = new MiddlewareListener(parent === null || parent === undefined ? undefined : parent.middlewareListener);
|
|
217
284
|
if (parent) {
|
|
218
285
|
this.parent = parent;
|
|
219
286
|
this.parent.addChild(this);
|
|
@@ -221,28 +288,36 @@
|
|
|
221
288
|
this.settings = Object.assign(Object.assign({}, DEFAULT_SETTINGS), settings);
|
|
222
289
|
}
|
|
223
290
|
register(dependency, dependencyId) {
|
|
291
|
+
var _a;
|
|
224
292
|
if (this.dependencies[dependencyId]) {
|
|
225
293
|
if (!this.settings.allowRewriteDependencies) {
|
|
226
294
|
throw new Error(`ProxyDi already has dependency for ${String(dependencyId)}`);
|
|
227
295
|
}
|
|
228
296
|
}
|
|
229
|
-
let
|
|
297
|
+
let instance;
|
|
230
298
|
const isClass = typeof dependency === 'function';
|
|
231
299
|
if (isClass) {
|
|
232
|
-
|
|
300
|
+
instance = this.createInstance(dependency, dependencyId);
|
|
233
301
|
}
|
|
234
302
|
else {
|
|
235
|
-
|
|
236
|
-
if (!(typeof dependencyInstance === 'object') &&
|
|
237
|
-
!this.settings.allowRegisterAnything) {
|
|
238
|
-
throw new Error(`Can't register as dependency (allowRegisterAnything is off for this contatiner): ${dependencyInstance}`);
|
|
239
|
-
}
|
|
303
|
+
instance = dependency;
|
|
240
304
|
}
|
|
241
|
-
|
|
242
|
-
|
|
305
|
+
const isObject = typeof instance === 'object';
|
|
306
|
+
if (!isObject && !this.settings.allowRegisterAnything) {
|
|
307
|
+
throw new Error(`Can't register as dependency (allowRegisterAnything is off for this contatiner): ${instance}`);
|
|
243
308
|
}
|
|
244
|
-
|
|
245
|
-
|
|
309
|
+
if (isObject) {
|
|
310
|
+
instance[PROXYDI_CONTAINER] = this;
|
|
311
|
+
instance[DEPENDENCY_ID] = dependencyId;
|
|
312
|
+
}
|
|
313
|
+
this.injectDependenciesTo(instance);
|
|
314
|
+
this.dependencies[dependencyId] = instance;
|
|
315
|
+
const constructorName = (_a = instance.constructor) === null || _a === undefined ? undefined : _a.name;
|
|
316
|
+
if (constructorName && middlewaresClasses[constructorName]) {
|
|
317
|
+
this.middlewareListener.add(instance);
|
|
318
|
+
}
|
|
319
|
+
this.middlewareListener.onRegister(this, dependencyId, instance);
|
|
320
|
+
return instance;
|
|
246
321
|
}
|
|
247
322
|
createInstance(Dependency, dependencyId) {
|
|
248
323
|
const paramIds = constructorInjections[dependencyId] || [];
|
|
@@ -253,18 +328,6 @@
|
|
|
253
328
|
}
|
|
254
329
|
return new Dependency(...params);
|
|
255
330
|
}
|
|
256
|
-
/**
|
|
257
|
-
* Internal method that implements registeration of dependency and prepare it for injection.
|
|
258
|
-
* @param dependencyId The unique identifier of the dependency.
|
|
259
|
-
* @param dependency The dependency instance.
|
|
260
|
-
*/
|
|
261
|
-
registerImpl(dependency, dependencyId) {
|
|
262
|
-
this.injectDependenciesTo(dependency);
|
|
263
|
-
if (typeof dependency === 'object') {
|
|
264
|
-
dependency[DEPENDENCY_ID] = dependencyId;
|
|
265
|
-
}
|
|
266
|
-
this.dependencies[dependencyId] = dependency;
|
|
267
|
-
}
|
|
268
331
|
/**
|
|
269
332
|
* Checks if a dependency with the given ID is known to the container or its ancestors which means that it can be resolved by this container
|
|
270
333
|
* @param dependencyId The identifier of the dependency.
|
|
@@ -353,11 +416,16 @@
|
|
|
353
416
|
* @param dependencyOrId The dependency instance or dependency identifier to remove.
|
|
354
417
|
*/
|
|
355
418
|
remove(dependencyOrId) {
|
|
419
|
+
var _a;
|
|
356
420
|
const id = isDependency(dependencyOrId)
|
|
357
421
|
? dependencyOrId[DEPENDENCY_ID]
|
|
358
422
|
: dependencyOrId;
|
|
359
423
|
const dependency = this.dependencies[id];
|
|
360
424
|
if (dependency) {
|
|
425
|
+
const constructorName = (_a = dependency.constructor) === null || _a === undefined ? undefined : _a.name;
|
|
426
|
+
if (constructorName && middlewaresClasses[constructorName]) {
|
|
427
|
+
this.middlewareListener.remove(dependency);
|
|
428
|
+
}
|
|
361
429
|
const dependencyInjects = dependency[INJECTIONS]
|
|
362
430
|
? dependency[INJECTIONS]
|
|
363
431
|
: {};
|
|
@@ -366,6 +434,7 @@
|
|
|
366
434
|
});
|
|
367
435
|
delete dependency[DEPENDENCY_ID];
|
|
368
436
|
delete this.dependencies[id];
|
|
437
|
+
this.middlewareListener.onRemove(this, id);
|
|
369
438
|
}
|
|
370
439
|
}
|
|
371
440
|
/**
|
|
@@ -481,6 +550,7 @@
|
|
|
481
550
|
exports.ProxyDiContainer = ProxyDiContainer;
|
|
482
551
|
exports.inject = inject;
|
|
483
552
|
exports.injectable = injectable;
|
|
553
|
+
exports.middleware = middleware;
|
|
484
554
|
exports.resolveAll = resolveAll;
|
|
485
555
|
|
|
486
556
|
}));
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { ProxyDiContainer } from '../ProxyDiContainer';
|
|
2
|
+
import { DependencyId } from '../types';
|
|
3
|
+
export interface MiddlewareListenerEvent {
|
|
4
|
+
register: (container: ProxyDiContainer, dependencyId: DependencyId, dependency: any) => void;
|
|
5
|
+
remove: (container: ProxyDiContainer, dependencyId: DependencyId) => void;
|
|
6
|
+
}
|
|
7
|
+
/**
|
|
8
|
+
* Describe the middleware that able to listen to the registering of a dependency in containers hierarchy
|
|
9
|
+
*/
|
|
10
|
+
export interface MiddlewareRegisteringListener {
|
|
11
|
+
onRegister(container: ProxyDiContainer, dependencyId: DependencyId, dependency: any): void;
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* Describe the middleware that able to listen to the removing of a dependency in containers hierarchy
|
|
15
|
+
*/
|
|
16
|
+
export interface MiddlewareRemovingListener {
|
|
17
|
+
onRemove(container: ProxyDiContainer, dependencyId: DependencyId): void;
|
|
18
|
+
}
|
|
19
|
+
export declare class MiddlewareListener {
|
|
20
|
+
private parent?;
|
|
21
|
+
private listeners;
|
|
22
|
+
constructor(parent?: MiddlewareListener | undefined);
|
|
23
|
+
add(middleware: any): void;
|
|
24
|
+
remove(middleware: any): void;
|
|
25
|
+
private on;
|
|
26
|
+
onRegister(container: ProxyDiContainer, dependencyId: DependencyId, dependency: any): void;
|
|
27
|
+
onRemove(container: ProxyDiContainer, dependencyId: DependencyId): void;
|
|
28
|
+
private off;
|
|
29
|
+
}
|