ts-ioc-container 53.0.0 → 54.0.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/cjm/hooks/hook.js +26 -7
- package/cjm/utils/once.js +4 -1
- package/esm/hooks/hook.js +26 -7
- package/esm/utils/once.js +4 -1
- package/package.json +1 -1
- package/typings/utils/once.d.ts +8 -1
package/cjm/hooks/hook.js
CHANGED
|
@@ -13,21 +13,40 @@ exports.toHookFn = toHookFn;
|
|
|
13
13
|
const getReflectionTarget = (target) => {
|
|
14
14
|
return (0, proxy_1.isProxy)(target) ? (0, proxy_1.getProxyTarget)(target) : target;
|
|
15
15
|
};
|
|
16
|
-
//
|
|
16
|
+
// Walk the constructor's prototype chain (most-derived first) collecting each class.
|
|
17
|
+
const getConstructorChain = (ctor) => {
|
|
18
|
+
const chain = [];
|
|
19
|
+
let current = ctor;
|
|
20
|
+
while (typeof current === 'function' && current !== Function.prototype) {
|
|
21
|
+
chain.push(current);
|
|
22
|
+
current = Object.getPrototypeOf(current);
|
|
23
|
+
}
|
|
24
|
+
return chain;
|
|
25
|
+
};
|
|
26
|
+
// Get hooks metadata, merging hooks declared on parent (extended-from) classes.
|
|
27
|
+
// Hooks are collected from base to derived so a derived class's hooks for the same
|
|
28
|
+
// method name take precedence over (replace) the parent's.
|
|
17
29
|
function getHooks(target, key) {
|
|
18
30
|
const reflectionTarget = getReflectionTarget(target);
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
31
|
+
const merged = new Map();
|
|
32
|
+
for (const ctor of getConstructorChain(reflectionTarget.constructor).reverse()) {
|
|
33
|
+
const ownHooks = Reflect.getOwnMetadata(key, ctor);
|
|
34
|
+
if (ownHooks) {
|
|
35
|
+
for (const [methodName, fns] of ownHooks) {
|
|
36
|
+
merged.set(methodName, fns);
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
return merged;
|
|
22
41
|
}
|
|
23
42
|
function hasHooks(target, key) {
|
|
24
43
|
const reflectionTarget = getReflectionTarget(target);
|
|
25
|
-
return Reflect.
|
|
44
|
+
return getConstructorChain(reflectionTarget.constructor).some((ctor) => Reflect.hasOwnMetadata(key, ctor));
|
|
26
45
|
}
|
|
27
46
|
// Hook decorator
|
|
28
47
|
const hook = (key, ...fns) => (target, propertyKey) => {
|
|
29
|
-
const hooks = Reflect.
|
|
30
|
-
? Reflect.
|
|
48
|
+
const hooks = Reflect.hasOwnMetadata(key, target.constructor)
|
|
49
|
+
? Reflect.getOwnMetadata(key, target.constructor)
|
|
31
50
|
: new Map();
|
|
32
51
|
hooks.set(propertyKey, (hooks.get(propertyKey) ?? []).concat(fns));
|
|
33
52
|
Reflect.defineMetadata(key, hooks, target.constructor);
|
package/cjm/utils/once.js
CHANGED
|
@@ -1,11 +1,14 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.once = void 0;
|
|
4
|
-
const once = (target, propertyKey, descriptor) => {
|
|
4
|
+
const once = ({ onRepeat } = {}) => (target, propertyKey, descriptor) => {
|
|
5
5
|
const originalMethod = descriptor.value;
|
|
6
6
|
const cacheMap = new WeakMap();
|
|
7
|
+
let index = 0;
|
|
7
8
|
descriptor.value = function (...args) {
|
|
9
|
+
index++;
|
|
8
10
|
if (cacheMap.has(this)) {
|
|
11
|
+
onRepeat?.({ index: index - 1, args });
|
|
9
12
|
return cacheMap.get(this);
|
|
10
13
|
}
|
|
11
14
|
const result = originalMethod.apply(this, args);
|
package/esm/hooks/hook.js
CHANGED
|
@@ -7,21 +7,40 @@ export const toHookFn = (execute) => isHookClassConstructor(execute) ? (context)
|
|
|
7
7
|
const getReflectionTarget = (target) => {
|
|
8
8
|
return isProxy(target) ? getProxyTarget(target) : target;
|
|
9
9
|
};
|
|
10
|
-
//
|
|
10
|
+
// Walk the constructor's prototype chain (most-derived first) collecting each class.
|
|
11
|
+
const getConstructorChain = (ctor) => {
|
|
12
|
+
const chain = [];
|
|
13
|
+
let current = ctor;
|
|
14
|
+
while (typeof current === 'function' && current !== Function.prototype) {
|
|
15
|
+
chain.push(current);
|
|
16
|
+
current = Object.getPrototypeOf(current);
|
|
17
|
+
}
|
|
18
|
+
return chain;
|
|
19
|
+
};
|
|
20
|
+
// Get hooks metadata, merging hooks declared on parent (extended-from) classes.
|
|
21
|
+
// Hooks are collected from base to derived so a derived class's hooks for the same
|
|
22
|
+
// method name take precedence over (replace) the parent's.
|
|
11
23
|
export function getHooks(target, key) {
|
|
12
24
|
const reflectionTarget = getReflectionTarget(target);
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
25
|
+
const merged = new Map();
|
|
26
|
+
for (const ctor of getConstructorChain(reflectionTarget.constructor).reverse()) {
|
|
27
|
+
const ownHooks = Reflect.getOwnMetadata(key, ctor);
|
|
28
|
+
if (ownHooks) {
|
|
29
|
+
for (const [methodName, fns] of ownHooks) {
|
|
30
|
+
merged.set(methodName, fns);
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
return merged;
|
|
16
35
|
}
|
|
17
36
|
export function hasHooks(target, key) {
|
|
18
37
|
const reflectionTarget = getReflectionTarget(target);
|
|
19
|
-
return Reflect.
|
|
38
|
+
return getConstructorChain(reflectionTarget.constructor).some((ctor) => Reflect.hasOwnMetadata(key, ctor));
|
|
20
39
|
}
|
|
21
40
|
// Hook decorator
|
|
22
41
|
export const hook = (key, ...fns) => (target, propertyKey) => {
|
|
23
|
-
const hooks = Reflect.
|
|
24
|
-
? Reflect.
|
|
42
|
+
const hooks = Reflect.hasOwnMetadata(key, target.constructor)
|
|
43
|
+
? Reflect.getOwnMetadata(key, target.constructor)
|
|
25
44
|
: new Map();
|
|
26
45
|
hooks.set(propertyKey, (hooks.get(propertyKey) ?? []).concat(fns));
|
|
27
46
|
Reflect.defineMetadata(key, hooks, target.constructor);
|
package/esm/utils/once.js
CHANGED
|
@@ -1,8 +1,11 @@
|
|
|
1
|
-
export const once = (target, propertyKey, descriptor) => {
|
|
1
|
+
export const once = ({ onRepeat } = {}) => (target, propertyKey, descriptor) => {
|
|
2
2
|
const originalMethod = descriptor.value;
|
|
3
3
|
const cacheMap = new WeakMap();
|
|
4
|
+
let index = 0;
|
|
4
5
|
descriptor.value = function (...args) {
|
|
6
|
+
index++;
|
|
5
7
|
if (cacheMap.has(this)) {
|
|
8
|
+
onRepeat?.({ index: index - 1, args });
|
|
6
9
|
return cacheMap.get(this);
|
|
7
10
|
}
|
|
8
11
|
const result = originalMethod.apply(this, args);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "ts-ioc-container",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "54.0.1",
|
|
4
4
|
"description": "Fast, lightweight TypeScript dependency injection container with a clean API, scoped lifecycles, decorators, tokens, hooks, lazy injection, customizable providers, and no global container objects.",
|
|
5
5
|
"workspaces": [
|
|
6
6
|
"docs"
|
package/typings/utils/once.d.ts
CHANGED