ts-ioc-container 57.3.0 → 58.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.
@@ -12,7 +12,7 @@ class Container {
12
12
  isDisposed = false;
13
13
  parent;
14
14
  scopes = [];
15
- instances = [];
15
+ instances = new Set();
16
16
  registrations = [];
17
17
  tags;
18
18
  providers = new Map();
@@ -108,7 +108,7 @@ class Container {
108
108
  }
109
109
  this.providers.clear();
110
110
  this.aliases.destroy();
111
- this.instances = [];
111
+ this.instances.clear();
112
112
  this.registrations = [];
113
113
  this.onConstructHookList.length = 0;
114
114
  this.onScopeCreatedHookList.length = 0;
@@ -137,7 +137,7 @@ class Container {
137
137
  return this;
138
138
  }
139
139
  addInstance(instance) {
140
- this.instances.push(instance);
140
+ this.instances.add(instance);
141
141
  for (const onConstruct of this.onConstructHookList) {
142
142
  onConstruct(instance, this);
143
143
  }
@@ -146,7 +146,7 @@ class Container {
146
146
  return [...this.scopes];
147
147
  }
148
148
  hasInstance(instance) {
149
- return this.instances.includes(instance);
149
+ return this.instances.has(instance);
150
150
  }
151
151
  getScopeByInstanceOrFail(instance) {
152
152
  this.validateContainer();
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 = void 0;
5
+ exports.resolveConstructor = exports.Is = exports.unwrapProxyTarget = exports.createProxy = 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,6 +150,9 @@ 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, "unwrapProxyTarget", { enumerable: true, get: function () { return proxy_1.unwrapProxyTarget; } });
153
156
  var basic_1 = require("./utils/basic");
154
157
  Object.defineProperty(exports, "Is", { enumerable: true, get: function () { return basic_1.Is; } });
155
158
  Object.defineProperty(exports, "resolveConstructor", { enumerable: true, get: function () { return basic_1.resolveConstructor; } });
@@ -1,24 +1,33 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.unwrapProxyTarget = void 0;
3
4
  exports.isProxy = isProxy;
4
5
  exports.getProxyTarget = getProxyTarget;
6
+ exports.createProxy = createProxy;
5
7
  exports.lazyProxy = lazyProxy;
6
8
  exports.toLazyIf = toLazyIf;
7
9
  const proxyStateMap = new WeakMap();
8
10
  const unwrapProxyTarget = (value) => {
9
11
  return isProxy(value) ? getProxyTarget(value) : value;
10
12
  };
13
+ exports.unwrapProxyTarget = unwrapProxyTarget;
11
14
  function isProxy(value) {
12
15
  return proxyStateMap.has(value);
13
16
  }
14
17
  function getProxyTarget(value) {
15
- return proxyStateMap.get(value).getTarget();
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;
16
25
  }
17
26
  function lazyProxy(resolveInstance) {
18
27
  let instance;
19
28
  const state = {
20
29
  getTarget: () => {
21
- instance = instance ?? unwrapProxyTarget(resolveInstance());
30
+ instance = instance ?? (0, exports.unwrapProxyTarget)(resolveInstance());
22
31
  return instance;
23
32
  },
24
33
  };
@@ -9,7 +9,7 @@ export class Container {
9
9
  isDisposed = false;
10
10
  parent;
11
11
  scopes = [];
12
- instances = [];
12
+ instances = new Set();
13
13
  registrations = [];
14
14
  tags;
15
15
  providers = new Map();
@@ -105,7 +105,7 @@ export class Container {
105
105
  }
106
106
  this.providers.clear();
107
107
  this.aliases.destroy();
108
- this.instances = [];
108
+ this.instances.clear();
109
109
  this.registrations = [];
110
110
  this.onConstructHookList.length = 0;
111
111
  this.onScopeCreatedHookList.length = 0;
@@ -134,7 +134,7 @@ export class Container {
134
134
  return this;
135
135
  }
136
136
  addInstance(instance) {
137
- this.instances.push(instance);
137
+ this.instances.add(instance);
138
138
  for (const onConstruct of this.onConstructHookList) {
139
139
  onConstruct(instance, this);
140
140
  }
@@ -143,7 +143,7 @@ export class Container {
143
143
  return [...this.scopes];
144
144
  }
145
145
  hasInstance(instance) {
146
- return this.instances.includes(instance);
146
+ return this.instances.has(instance);
147
147
  }
148
148
  getScopeByInstanceOrFail(instance) {
149
149
  this.validateContainer();
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,4 +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, unwrapProxyTarget } from './utils/proxy.js';
48
49
  export { Is, resolveConstructor } from './utils/basic.js';
@@ -1,12 +1,18 @@
1
1
  const proxyStateMap = new WeakMap();
2
- const unwrapProxyTarget = (value) => {
2
+ export const unwrapProxyTarget = (value) => {
3
3
  return isProxy(value) ? getProxyTarget(value) : value;
4
4
  };
5
5
  export function isProxy(value) {
6
6
  return proxyStateMap.has(value);
7
7
  }
8
8
  export function getProxyTarget(value) {
9
- return proxyStateMap.get(value).getTarget();
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;
10
16
  }
11
17
  export function lazyProxy(resolveInstance) {
12
18
  let instance;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ts-ioc-container",
3
- "version": "57.3.0",
3
+ "version": "58.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",
@@ -9,7 +9,7 @@ export declare class Container implements IContainer {
9
9
  isDisposed: boolean;
10
10
  private parent;
11
11
  private scopes;
12
- private instances;
12
+ private readonly instances;
13
13
  private registrations;
14
14
  private readonly tags;
15
15
  private readonly providers;
@@ -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[];
@@ -16,9 +17,9 @@ export interface IHookContext {
16
17
  export declare class HookContext implements IHookContext {
17
18
  scope: IContainer;
18
19
  methodName?: string | undefined;
19
- readonly instance: object;
20
+ readonly instance: Instance;
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,4 +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 { type constructor, type Instance, Is, resolveConstructor } from './utils/basic.js';
50
+ export { createProxy, unwrapProxyTarget } from './utils/proxy.js';
51
+ export { type Branded, type constructor, type Instance, Is, resolveConstructor } from './utils/basic.js';
@@ -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,4 +1,6 @@
1
+ export declare const unwrapProxyTarget: <T extends object>(value: T) => T;
1
2
  export declare function isProxy(value: object): boolean;
2
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;
3
5
  export declare function lazyProxy<T extends object>(resolveInstance: () => T): T;
4
6
  export declare function toLazyIf<T extends object>(resolveInstance: () => T, isLazy?: boolean): T;