ts-ioc-container 57.4.0 → 59.0.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.
@@ -8,7 +8,6 @@ const AliasMap_1 = require("./AliasMap");
8
8
  const DependencyNotFoundError_1 = require("../errors/DependencyNotFoundError");
9
9
  const basic_1 = require("../utils/basic");
10
10
  const array_1 = require("../utils/array");
11
- const proxy_1 = require("../utils/proxy");
12
11
  class Container {
13
12
  isDisposed = false;
14
13
  parent;
@@ -147,7 +146,7 @@ class Container {
147
146
  return [...this.scopes];
148
147
  }
149
148
  hasInstance(instance) {
150
- return this.instances.has((0, proxy_1.unwrapProxyTarget)(instance));
149
+ return this.instances.has(instance);
151
150
  }
152
151
  getScopeByInstanceOrFail(instance) {
153
152
  this.validateContainer();
@@ -1,17 +1,16 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.createHookContextFactory = exports.createHookContext = exports.HookContext = void 0;
4
- const proxy_1 = require("../utils/proxy");
5
4
  const MetadataInjector_1 = require("../injector/MetadataInjector");
6
5
  class HookContext {
6
+ instance;
7
7
  scope;
8
8
  methodName;
9
- instance;
10
9
  initialArgs = [];
11
10
  constructor(instance, scope, methodName) {
11
+ this.instance = instance;
12
12
  this.scope = scope;
13
13
  this.methodName = methodName;
14
- this.instance = (0, proxy_1.isProxy)(instance) ? (0, proxy_1.getProxyTarget)(instance) : instance;
15
14
  }
16
15
  resolveArgs(...args) {
17
16
  return (0, MetadataInjector_1.resolveArgs)(this.instance.constructor, this.methodName)(this.scope, {
package/cjm/hooks/hook.js CHANGED
@@ -4,7 +4,6 @@ exports.hook = exports.toHookFn = exports.prepend = exports.append = exports.pre
4
4
  exports.getHooks = getHooks;
5
5
  exports.hasHooks = hasHooks;
6
6
  const basic_1 = require("../utils/basic");
7
- const proxy_1 = require("../utils/proxy");
8
7
  const appendHooks = (...fns) => (...prev) => [...prev, ...fns];
9
8
  exports.appendHooks = appendHooks;
10
9
  const prependHooks = (...fns) => (...prev) => [...fns, ...prev];
@@ -16,9 +15,6 @@ const isHookClassConstructor = (execute) => {
16
15
  };
17
16
  const toHookFn = (execute) => isHookClassConstructor(execute) ? (context) => context.scope.resolve(execute).execute(context) : execute;
18
17
  exports.toHookFn = toHookFn;
19
- const getReflectionTarget = (target) => {
20
- return (0, proxy_1.isProxy)(target) ? (0, proxy_1.getProxyTarget)(target) : target;
21
- };
22
18
  const getConstructorChain = (ctor) => {
23
19
  const chain = [];
24
20
  let current = ctor;
@@ -29,9 +25,8 @@ const getConstructorChain = (ctor) => {
29
25
  return chain;
30
26
  };
31
27
  function getHooks(target, key) {
32
- const reflectionTarget = getReflectionTarget(target);
33
28
  const merged = new Map();
34
- for (const ctor of getConstructorChain(reflectionTarget.constructor).reverse()) {
29
+ for (const ctor of getConstructorChain(target.constructor).reverse()) {
35
30
  const ownHooks = Reflect.getOwnMetadata(key, ctor);
36
31
  if (ownHooks) {
37
32
  for (const [methodName, fns] of ownHooks) {
@@ -42,8 +37,7 @@ function getHooks(target, key) {
42
37
  return merged;
43
38
  }
44
39
  function hasHooks(target, key) {
45
- const reflectionTarget = getReflectionTarget(target);
46
- return getConstructorChain(reflectionTarget.constructor).some((ctor) => Reflect.hasOwnMetadata(key, ctor));
40
+ return getConstructorChain(target.constructor).some((ctor) => Reflect.hasOwnMetadata(key, ctor));
47
41
  }
48
42
  const hook = (key, mapFn) => (target, propertyKey) => {
49
43
  const hooks = Reflect.hasOwnMetadata(key, target.constructor)
package/cjm/index.js CHANGED
@@ -2,7 +2,7 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.createHookContext = exports.createHookContextFactory = exports.HookContext = exports.prepend = exports.append = exports.prependHooks = exports.appendHooks = exports.hasHooks = exports.hook = exports.getHooks = exports.UnsupportedTokenTypeError = exports.CannonSingletonApplyTwiceError = exports.UnexpectedHookResultError = exports.ProviderDisposedError = exports.ContainerDisposedError = exports.MethodNotImplementedError = exports.DependencyMissingKeyError = exports.ContainerNotFoundError = exports.DependencyNotFoundError = exports.ContainerError = exports.Registration = exports.appendArgsFn = exports.appendArgs = exports.decorate = exports.singleton = exports.autoResolve = exports.lazy = exports.scopeAccess = exports.scope = exports.bindTo = exports.register = exports.toRegistrationFn = exports.toProviderFn = exports.toBindToken = exports.registerPipe = exports.isProviderPipe = exports.Provider = exports.ProxyInjector = exports.SimpleInjector = exports.resolveArgs = exports.argsFn = exports.args = exports.arg = exports.inject = exports.MetadataInjector = exports.Injector = exports.EmptyContainer = exports.AutoResolveModule = exports.Container = exports.isDependencyKey = void 0;
4
4
  exports.pipe = exports.select = exports.once = exports.shallowCache = exports.debounce = exports.throttle = exports.handleAsyncError = exports.handleError = exports.getMethodTags = exports.addMethodTag = exports.getMethodLabels = exports.addMethodLabel = exports.getMethodMeta = exports.addMethodMeta = exports.getParamTags = exports.addParamTag = exports.getParamLabels = exports.addParamLabel = exports.getParamMeta = exports.addParamMeta = exports.getClassTags = exports.addClassTag = exports.getClassLabels = exports.addClassLabel = exports.getClassMeta = exports.addClassMeta = exports.GroupInstanceToken = exports.ConstantToken = exports.FunctionToken = exports.SingleToken = exports.ClassToken = exports.toSingleAlias = exports.SingleAliasToken = exports.toGroupAlias = exports.GroupAliasToken = exports.argToToken = exports.toMappedToken = exports.toToken = exports.InjectionToken = exports.HooksRunner = exports.AddOnDisposeHookModule = exports.onContainerDisposed = exports.onContainerDisposedHooksRunner = exports.AddOnConstructAsyncHookModule = exports.onConstructAsync = exports.onConstructAsyncHooksRunner = exports.AddOnConstructHookModule = exports.onConstruct = exports.onConstructHooksRunner = exports.injectProp = void 0;
5
- exports.resolveConstructor = exports.Is = exports.isProxy = exports.getProxyTarget = exports.createProxy = void 0;
5
+ exports.resolveConstructor = exports.Is = exports.ProxyRegistry = void 0;
6
6
  var IContainer_1 = require("./container/IContainer");
7
7
  Object.defineProperty(exports, "isDependencyKey", { enumerable: true, get: function () { return IContainer_1.isDependencyKey; } });
8
8
  var Container_1 = require("./container/Container");
@@ -150,10 +150,8 @@ var select_1 = require("./select");
150
150
  Object.defineProperty(exports, "select", { enumerable: true, get: function () { return select_1.select; } });
151
151
  var fp_1 = require("./utils/fp");
152
152
  Object.defineProperty(exports, "pipe", { enumerable: true, get: function () { return fp_1.pipe; } });
153
- var proxy_1 = require("./utils/proxy");
154
- Object.defineProperty(exports, "createProxy", { enumerable: true, get: function () { return proxy_1.createProxy; } });
155
- Object.defineProperty(exports, "getProxyTarget", { enumerable: true, get: function () { return proxy_1.getProxyTarget; } });
156
- Object.defineProperty(exports, "isProxy", { enumerable: true, get: function () { return proxy_1.isProxy; } });
153
+ var ProxyRegistry_1 = require("./utils/ProxyRegistry");
154
+ Object.defineProperty(exports, "ProxyRegistry", { enumerable: true, get: function () { return ProxyRegistry_1.ProxyRegistry; } });
157
155
  var basic_1 = require("./utils/basic");
158
156
  Object.defineProperty(exports, "Is", { enumerable: true, get: function () { return basic_1.Is; } });
159
157
  Object.defineProperty(exports, "resolveConstructor", { enumerable: true, get: function () { return basic_1.resolveConstructor; } });
@@ -1,10 +1,14 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.Injector = void 0;
4
- const proxy_1 = require("../utils/proxy");
4
+ const ProxyRegistry_1 = require("../utils/ProxyRegistry");
5
5
  class Injector {
6
+ proxyRegistry;
7
+ constructor(proxyRegistry = ProxyRegistry_1.ProxyRegistry.getInstance()) {
8
+ this.proxyRegistry = proxyRegistry;
9
+ }
6
10
  resolve(scope, Target, { args, lazy } = {}) {
7
- return (0, proxy_1.toLazyIf)(() => {
11
+ return this.proxyRegistry.toLazyIf(() => {
8
12
  const instance = this.createInstance(scope, Target, { args });
9
13
  scope.addInstance(instance);
10
14
  return instance;
@@ -0,0 +1,55 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.ProxyRegistry = void 0;
4
+ class ProxyRegistry {
5
+ static instance;
6
+ states = new WeakMap();
7
+ constructor() { }
8
+ static getInstance() {
9
+ ProxyRegistry.instance ??= new ProxyRegistry();
10
+ return ProxyRegistry.instance;
11
+ }
12
+ unwrap(value) {
13
+ return this.isProxy(value) ? this.getTarget(value) : value;
14
+ }
15
+ createProxy(target, handler = {}) {
16
+ const proxy = new Proxy(target, handler);
17
+ return this.register(proxy, { getTarget: () => target });
18
+ }
19
+ createLazyProxy(resolveInstance) {
20
+ let instance;
21
+ const state = {
22
+ getTarget: () => {
23
+ instance = instance ?? this.unwrap(resolveInstance());
24
+ return instance;
25
+ },
26
+ };
27
+ const proxy = new Proxy({}, {
28
+ get: (_, prop) => {
29
+ const target = state.getTarget();
30
+ return target[prop];
31
+ },
32
+ set: (_, prop, value) => {
33
+ const target = state.getTarget();
34
+ target[prop] = value;
35
+ return true;
36
+ },
37
+ });
38
+ return this.register(proxy, state);
39
+ }
40
+ toLazyIf(resolveInstance, isLazy = false) {
41
+ return isLazy ? this.createLazyProxy(resolveInstance) : resolveInstance();
42
+ }
43
+ isProxy(value) {
44
+ return this.states.has(value);
45
+ }
46
+ getTarget(value) {
47
+ const target = this.states.get(value).getTarget();
48
+ return this.unwrap(target);
49
+ }
50
+ register(proxy, state) {
51
+ this.states.set(proxy, state);
52
+ return proxy;
53
+ }
54
+ }
55
+ exports.ProxyRegistry = ProxyRegistry;
@@ -5,7 +5,6 @@ import { AliasMap } from './AliasMap.js';
5
5
  import { DependencyNotFoundError } from '../errors/DependencyNotFoundError.js';
6
6
  import { Is } from '../utils/basic.js';
7
7
  import { Filter as F } from '../utils/array.js';
8
- import { unwrapProxyTarget } from '../utils/proxy.js';
9
8
  export class Container {
10
9
  isDisposed = false;
11
10
  parent;
@@ -144,7 +143,7 @@ export class Container {
144
143
  return [...this.scopes];
145
144
  }
146
145
  hasInstance(instance) {
147
- return this.instances.has(unwrapProxyTarget(instance));
146
+ return this.instances.has(instance);
148
147
  }
149
148
  getScopeByInstanceOrFail(instance) {
150
149
  this.validateContainer();
@@ -1,14 +1,13 @@
1
- import { getProxyTarget, isProxy } from '../utils/proxy.js';
2
1
  import { resolveArgs } from '../injector/MetadataInjector.js';
3
2
  export class HookContext {
3
+ instance;
4
4
  scope;
5
5
  methodName;
6
- instance;
7
6
  initialArgs = [];
8
7
  constructor(instance, scope, methodName) {
8
+ this.instance = instance;
9
9
  this.scope = scope;
10
10
  this.methodName = methodName;
11
- this.instance = isProxy(instance) ? getProxyTarget(instance) : instance;
12
11
  }
13
12
  resolveArgs(...args) {
14
13
  return resolveArgs(this.instance.constructor, this.methodName)(this.scope, {
package/esm/hooks/hook.js CHANGED
@@ -1,5 +1,4 @@
1
1
  import { Is } from '../utils/basic.js';
2
- import { getProxyTarget, isProxy } from '../utils/proxy.js';
3
2
  export const appendHooks = (...fns) => (...prev) => [...prev, ...fns];
4
3
  export const prependHooks = (...fns) => (...prev) => [...fns, ...prev];
5
4
  export const append = appendHooks;
@@ -8,9 +7,6 @@ const isHookClassConstructor = (execute) => {
8
7
  return Is.constructor(execute) && execute.prototype.execute;
9
8
  };
10
9
  export const toHookFn = (execute) => isHookClassConstructor(execute) ? (context) => context.scope.resolve(execute).execute(context) : execute;
11
- const getReflectionTarget = (target) => {
12
- return isProxy(target) ? getProxyTarget(target) : target;
13
- };
14
10
  const getConstructorChain = (ctor) => {
15
11
  const chain = [];
16
12
  let current = ctor;
@@ -21,9 +17,8 @@ const getConstructorChain = (ctor) => {
21
17
  return chain;
22
18
  };
23
19
  export function getHooks(target, key) {
24
- const reflectionTarget = getReflectionTarget(target);
25
20
  const merged = new Map();
26
- for (const ctor of getConstructorChain(reflectionTarget.constructor).reverse()) {
21
+ for (const ctor of getConstructorChain(target.constructor).reverse()) {
27
22
  const ownHooks = Reflect.getOwnMetadata(key, ctor);
28
23
  if (ownHooks) {
29
24
  for (const [methodName, fns] of ownHooks) {
@@ -34,8 +29,7 @@ export function getHooks(target, key) {
34
29
  return merged;
35
30
  }
36
31
  export function hasHooks(target, key) {
37
- const reflectionTarget = getReflectionTarget(target);
38
- return getConstructorChain(reflectionTarget.constructor).some((ctor) => Reflect.hasOwnMetadata(key, ctor));
32
+ return getConstructorChain(target.constructor).some((ctor) => Reflect.hasOwnMetadata(key, ctor));
39
33
  }
40
34
  export const hook = (key, mapFn) => (target, propertyKey) => {
41
35
  const hooks = Reflect.hasOwnMetadata(key, target.constructor)
package/esm/index.js CHANGED
@@ -45,5 +45,5 @@ export { shallowCache } from './utils/shallowCache.js';
45
45
  export { once } from './utils/once.js';
46
46
  export { select } from './select.js';
47
47
  export { pipe } from './utils/fp.js';
48
- export { createProxy, getProxyTarget, isProxy } from './utils/proxy.js';
48
+ export { ProxyRegistry } from './utils/ProxyRegistry.js';
49
49
  export { Is, resolveConstructor } from './utils/basic.js';
@@ -1,7 +1,11 @@
1
- import { toLazyIf } from '../utils/proxy.js';
1
+ import { ProxyRegistry } from '../utils/ProxyRegistry.js';
2
2
  export class Injector {
3
+ proxyRegistry;
4
+ constructor(proxyRegistry = ProxyRegistry.getInstance()) {
5
+ this.proxyRegistry = proxyRegistry;
6
+ }
3
7
  resolve(scope, Target, { args, lazy } = {}) {
4
- return toLazyIf(() => {
8
+ return this.proxyRegistry.toLazyIf(() => {
5
9
  const instance = this.createInstance(scope, Target, { args });
6
10
  scope.addInstance(instance);
7
11
  return instance;
@@ -0,0 +1,51 @@
1
+ export class ProxyRegistry {
2
+ static instance;
3
+ states = new WeakMap();
4
+ constructor() { }
5
+ static getInstance() {
6
+ ProxyRegistry.instance ??= new ProxyRegistry();
7
+ return ProxyRegistry.instance;
8
+ }
9
+ unwrap(value) {
10
+ return this.isProxy(value) ? this.getTarget(value) : value;
11
+ }
12
+ createProxy(target, handler = {}) {
13
+ const proxy = new Proxy(target, handler);
14
+ return this.register(proxy, { getTarget: () => target });
15
+ }
16
+ createLazyProxy(resolveInstance) {
17
+ let instance;
18
+ const state = {
19
+ getTarget: () => {
20
+ instance = instance ?? this.unwrap(resolveInstance());
21
+ return instance;
22
+ },
23
+ };
24
+ const proxy = new Proxy({}, {
25
+ get: (_, prop) => {
26
+ const target = state.getTarget();
27
+ return target[prop];
28
+ },
29
+ set: (_, prop, value) => {
30
+ const target = state.getTarget();
31
+ target[prop] = value;
32
+ return true;
33
+ },
34
+ });
35
+ return this.register(proxy, state);
36
+ }
37
+ toLazyIf(resolveInstance, isLazy = false) {
38
+ return isLazy ? this.createLazyProxy(resolveInstance) : resolveInstance();
39
+ }
40
+ isProxy(value) {
41
+ return this.states.has(value);
42
+ }
43
+ getTarget(value) {
44
+ const target = this.states.get(value).getTarget();
45
+ return this.unwrap(target);
46
+ }
47
+ register(proxy, state) {
48
+ this.states.set(proxy, state);
49
+ return proxy;
50
+ }
51
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ts-ioc-container",
3
- "version": "57.4.0",
3
+ "version": "59.0.0",
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
  "publishConfig": {
6
6
  "access": "public",
@@ -38,12 +38,12 @@ export declare class Container implements IContainer {
38
38
  addOnScopeCreatedHook(...hooks: OnScopeCreatedHook[]): this;
39
39
  addInstance(instance: Instance): void;
40
40
  getScopes(): IContainer[];
41
- hasInstance(instance: object): boolean;
42
- getScopeByInstanceOrFail(instance: object): IContainer;
41
+ hasInstance(instance: Instance): boolean;
42
+ getScopeByInstanceOrFail(instance: Instance): IContainer;
43
43
  removeScope(child: IContainer): void;
44
44
  useModule(module: IContainerModule): this;
45
45
  getParent(): IContainer;
46
- getInstances(cascade?: boolean): Instance<unknown>[];
46
+ getInstances(cascade?: boolean): Instance[];
47
47
  hasTag(tag: Tag): boolean;
48
48
  addTags(...tags: Tag[]): void;
49
49
  private validateContainer;
@@ -9,9 +9,9 @@ export declare class EmptyContainer implements IContainer {
9
9
  addInstance(instance: Instance): void;
10
10
  getParent(): undefined;
11
11
  getScopes(): never[];
12
- getScopeByInstanceOrFail(instance: object): IContainer;
12
+ getScopeByInstanceOrFail(instance: Instance): IContainer;
13
13
  getInstances(): never[];
14
- hasInstance(instance: object): boolean;
14
+ hasInstance(instance: Instance): boolean;
15
15
  createScope(): IContainer;
16
16
  autoResolve(options?: AutoResolveOptions): this;
17
17
  dispose(): void;
@@ -49,12 +49,12 @@ export interface IContainer extends Tagged {
49
49
  createScope(options?: CreateScopeOptions): IContainer;
50
50
  autoResolve(options?: AutoResolveOptions): this;
51
51
  getScopes(): IContainer[];
52
- getScopeByInstanceOrFail(instance: object): IContainer;
52
+ getScopeByInstanceOrFail(instance: Instance): IContainer;
53
53
  removeScope(child: IContainer): void;
54
54
  useModule(module: IContainerModule): this;
55
55
  getParent(): IContainer | undefined;
56
56
  getInstances(cascade?: boolean): Instance[];
57
- hasInstance(instance: object): boolean;
57
+ hasInstance(instance: Instance): boolean;
58
58
  dispose(): void;
59
59
  addInstance(instance: Instance): void;
60
60
  }
@@ -1,7 +1,8 @@
1
1
  import type { IContainer } from '../container/IContainer.js';
2
2
  import { InjectionToken } from '../token/InjectionToken.js';
3
+ import { type Instance } from '../utils/basic.js';
3
4
  export interface IHookContext {
4
- instance: object;
5
+ instance: Instance;
5
6
  scope: IContainer;
6
7
  methodName?: string;
7
8
  resolveArgs(...args: unknown[]): unknown[];
@@ -14,11 +15,11 @@ export interface IHookContext {
14
15
  getInitialArgs(): unknown[];
15
16
  }
16
17
  export declare class HookContext implements IHookContext {
17
- scope: IContainer;
18
- methodName?: string | undefined;
19
- readonly instance: object;
18
+ readonly instance: Instance;
19
+ readonly scope: IContainer;
20
+ readonly methodName?: string | undefined;
20
21
  private initialArgs;
21
- constructor(instance: object, scope: IContainer, methodName?: string | undefined);
22
+ constructor(instance: Instance, scope: IContainer, methodName?: string | undefined);
22
23
  resolveArgs(...args: unknown[]): unknown[];
23
24
  invokeMethod({ args }?: {
24
25
  args?: unknown[];
@@ -28,7 +29,7 @@ export declare class HookContext implements IHookContext {
28
29
  setInitialArgs(...args: unknown[]): this;
29
30
  getInitialArgs(): unknown[];
30
31
  }
31
- export type CreateHookContext = (Target: object, scope: IContainer, methodName?: string) => IHookContext;
32
+ export type CreateHookContext = (Target: Instance, scope: IContainer, methodName?: string) => IHookContext;
32
33
  export declare const createHookContext: CreateHookContext;
33
34
  export declare const createHookContextFactory: ({ args }?: {
34
35
  args?: unknown[];
@@ -1,5 +1,6 @@
1
1
  import { type CreateHookContext, type IHookContext } from './HookContext.js';
2
2
  import type { IContainer } from '../container/IContainer.js';
3
+ import { type Instance } from '../utils/basic.js';
3
4
  export type MapHookContext = (context: IHookContext) => IHookContext;
4
5
  export type HooksRunnerContext = {
5
6
  scope: IContainer;
@@ -10,7 +11,7 @@ export type HooksRunnerContext = {
10
11
  export declare class HooksRunner {
11
12
  private readonly key;
12
13
  constructor(key: string | symbol);
13
- hasHooks(target: object): boolean;
14
- execute(target: object, { scope, createContext, mapContext, predicate, }: HooksRunnerContext): void;
15
- executeAsync(target: object, { scope, createContext, mapContext, predicate, }: HooksRunnerContext): Promise<void[]>;
14
+ hasHooks(target: Instance): boolean;
15
+ execute(target: Instance, { scope, createContext, mapContext, predicate, }: HooksRunnerContext): void;
16
+ executeAsync(target: Instance, { scope, createContext, mapContext, predicate, }: HooksRunnerContext): Promise<void[]>;
16
17
  }
@@ -1,6 +1,6 @@
1
1
  import { type IHookContext } from './HookContext.js';
2
2
  import type { IContainer } from '../container/IContainer.js';
3
- import { type constructor } from '../utils/basic.js';
3
+ import { type constructor, type Instance } from '../utils/basic.js';
4
4
  import { ProviderOptions } from '../provider/IProvider.js';
5
5
  export type InjectFn<T = unknown> = (s: IContainer, options: ProviderOptions) => T;
6
6
  export type HookFn<T extends IHookContext = IHookContext> = (context: T) => void | Promise<void>;
@@ -15,6 +15,6 @@ export declare const prependHooks: (...fns: HookType[]) => MapHooksFn;
15
15
  export declare const append: (...fns: HookType[]) => MapHooksFn;
16
16
  export declare const prepend: (...fns: HookType[]) => MapHooksFn;
17
17
  export declare const toHookFn: <C extends IHookContext>(execute: HookFn<C> | constructor<HookClass<C>>) => HookFn<C>;
18
- export declare function getHooks(target: object, key: string | symbol): HooksOfClass;
19
- export declare function hasHooks(target: object, key: string | symbol): boolean;
18
+ export declare function getHooks(target: Instance, key: string | symbol): HooksOfClass;
19
+ export declare function hasHooks(target: Instance, key: string | symbol): boolean;
20
20
  export declare const hook: (key: string | symbol, mapFn: MapHooksFn) => (target: object, propertyKey: string | symbol) => void;
@@ -47,5 +47,5 @@ export { once } from './utils/once.js';
47
47
  export { type ExecutionContext } from './ExecutionContext.js';
48
48
  export { select } from './select.js';
49
49
  export { pipe, type MapFn } from './utils/fp.js';
50
- export { createProxy, getProxyTarget, isProxy } from './utils/proxy.js';
51
- export { type constructor, type Instance, Is, resolveConstructor } from './utils/basic.js';
50
+ export { ProxyRegistry, type IProxyRegistry } from './utils/ProxyRegistry.js';
51
+ export { type Branded, type constructor, type Instance, Is, resolveConstructor } from './utils/basic.js';
@@ -1,5 +1,6 @@
1
1
  import { type IContainer, ResolveOneOptions } from '../container/IContainer.js';
2
2
  import { ProviderOptions } from '../provider/IProvider.js';
3
+ import { type IProxyRegistry } from '../utils/ProxyRegistry.js';
3
4
  import { type constructor } from '../utils/basic.js';
4
5
  export type WithArgs = {
5
6
  args: unknown[];
@@ -12,6 +13,8 @@ export interface IInjectFnResolver<T> {
12
13
  resolve(s: IContainer, options?: ResolveOneOptions): T;
13
14
  }
14
15
  export declare abstract class Injector {
16
+ private readonly proxyRegistry;
17
+ constructor(proxyRegistry?: IProxyRegistry);
15
18
  resolve<T>(scope: IContainer, Target: constructor<T>, { args, lazy }?: ProviderOptions): T;
16
19
  protected abstract createInstance<T>(scope: IContainer, Target: constructor<T>, options?: InjectOptions): T;
17
20
  }
@@ -0,0 +1,19 @@
1
+ export interface IProxyRegistry {
2
+ unwrap<T extends object>(value: T): T;
3
+ createProxy<T extends object>(target: T, handler?: ProxyHandler<T>): T;
4
+ createLazyProxy<T extends object>(resolveInstance: () => T): T;
5
+ toLazyIf<T extends object>(resolveInstance: () => T, isLazy?: boolean): T;
6
+ }
7
+ export declare class ProxyRegistry implements IProxyRegistry {
8
+ private static instance?;
9
+ private readonly states;
10
+ private constructor();
11
+ static getInstance(): ProxyRegistry;
12
+ unwrap<T extends object>(value: T): T;
13
+ createProxy<T extends object>(target: T, handler?: ProxyHandler<T>): T;
14
+ createLazyProxy<T extends object>(resolveInstance: () => T): T;
15
+ toLazyIf<T extends object>(resolveInstance: () => T, isLazy?: boolean): T;
16
+ private isProxy;
17
+ private getTarget;
18
+ private register;
19
+ }
@@ -1,7 +1,8 @@
1
1
  export type constructor<T> = new (...args: any[]) => T;
2
- export interface Instance<T = unknown> {
3
- new (...args: unknown[]): T;
4
- }
2
+ export type Branded<TBrand extends string, T> = T & {
3
+ readonly __brand?: TBrand;
4
+ };
5
+ export type Instance = Branded<'Instance', object>;
5
6
  export declare const Is: {
6
7
  nullish: <T>(value: T | undefined | null) => value is null | undefined;
7
8
  object: (target: unknown) => target is object;
@@ -1,48 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.unwrapProxyTarget = void 0;
4
- exports.isProxy = isProxy;
5
- exports.getProxyTarget = getProxyTarget;
6
- exports.createProxy = createProxy;
7
- exports.lazyProxy = lazyProxy;
8
- exports.toLazyIf = toLazyIf;
9
- const proxyStateMap = new WeakMap();
10
- const unwrapProxyTarget = (value) => {
11
- return isProxy(value) ? getProxyTarget(value) : value;
12
- };
13
- exports.unwrapProxyTarget = unwrapProxyTarget;
14
- function isProxy(value) {
15
- return proxyStateMap.has(value);
16
- }
17
- function getProxyTarget(value) {
18
- const target = proxyStateMap.get(value).getTarget();
19
- return (0, exports.unwrapProxyTarget)(target);
20
- }
21
- function createProxy(target, handler = {}) {
22
- const proxy = new Proxy(target, handler);
23
- proxyStateMap.set(proxy, { getTarget: () => target });
24
- return proxy;
25
- }
26
- function lazyProxy(resolveInstance) {
27
- let instance;
28
- const state = {
29
- getTarget: () => {
30
- instance = instance ?? (0, exports.unwrapProxyTarget)(resolveInstance());
31
- return instance;
32
- },
33
- };
34
- const proxy = new Proxy({}, {
35
- get: (_, prop) => {
36
- const target = state.getTarget();
37
- return target[prop];
38
- },
39
- });
40
- proxyStateMap.set(proxy, state);
41
- return proxy;
42
- }
43
- function toLazyIf(resolveInstance, isLazy = false) {
44
- if (isLazy) {
45
- return lazyProxy(resolveInstance);
46
- }
47
- return resolveInstance();
48
- }
@@ -1,39 +0,0 @@
1
- const proxyStateMap = new WeakMap();
2
- export const unwrapProxyTarget = (value) => {
3
- return isProxy(value) ? getProxyTarget(value) : value;
4
- };
5
- export function isProxy(value) {
6
- return proxyStateMap.has(value);
7
- }
8
- export function getProxyTarget(value) {
9
- const target = proxyStateMap.get(value).getTarget();
10
- return unwrapProxyTarget(target);
11
- }
12
- export function createProxy(target, handler = {}) {
13
- const proxy = new Proxy(target, handler);
14
- proxyStateMap.set(proxy, { getTarget: () => target });
15
- return proxy;
16
- }
17
- export function lazyProxy(resolveInstance) {
18
- let instance;
19
- const state = {
20
- getTarget: () => {
21
- instance = instance ?? unwrapProxyTarget(resolveInstance());
22
- return instance;
23
- },
24
- };
25
- const proxy = new Proxy({}, {
26
- get: (_, prop) => {
27
- const target = state.getTarget();
28
- return target[prop];
29
- },
30
- });
31
- proxyStateMap.set(proxy, state);
32
- return proxy;
33
- }
34
- export function toLazyIf(resolveInstance, isLazy = false) {
35
- if (isLazy) {
36
- return lazyProxy(resolveInstance);
37
- }
38
- return resolveInstance();
39
- }
@@ -1,6 +0,0 @@
1
- export declare const unwrapProxyTarget: <T extends object>(value: T) => T;
2
- export declare function isProxy(value: object): boolean;
3
- export declare function getProxyTarget<T extends object>(value: T): T;
4
- export declare function createProxy<T extends object>(target: T, handler?: ProxyHandler<T>): T;
5
- export declare function lazyProxy<T extends object>(resolveInstance: () => T): T;
6
- export declare function toLazyIf<T extends object>(resolveInstance: () => T, isLazy?: boolean): T;