ts-ioc-container 63.0.0 → 65.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.
Files changed (53) hide show
  1. package/README.md +110 -94
  2. package/cjm/container/AutoResolveModule.js +1 -1
  3. package/cjm/container/Container.js +20 -31
  4. package/cjm/container/EmptyContainer.js +6 -3
  5. package/cjm/errors/TypedEventDisposedError.js +17 -0
  6. package/cjm/hooks/AsyncHookExecutionStrategy.js +15 -0
  7. package/cjm/hooks/HookContext.js +4 -4
  8. package/cjm/hooks/HookExecutionStrategy.js +68 -0
  9. package/cjm/hooks/ParallelAsync.js +17 -0
  10. package/cjm/hooks/SequentialAsync.js +15 -0
  11. package/cjm/hooks/SequentialSync.js +14 -0
  12. package/cjm/hooks/onConstruct.js +7 -9
  13. package/cjm/hooks/onResolved.js +14 -10
  14. package/cjm/hooks/onScopeDisposed.js +6 -8
  15. package/cjm/hooks/resolveHooks.js +1 -18
  16. package/cjm/index.js +18 -11
  17. package/cjm/utils/TypedEvent.js +35 -0
  18. package/esm/container/AutoResolveModule.js +1 -1
  19. package/esm/container/Container.js +20 -31
  20. package/esm/container/EmptyContainer.js +6 -3
  21. package/esm/errors/TypedEventDisposedError.js +13 -0
  22. package/esm/hooks/AsyncHookExecutionStrategy.js +11 -0
  23. package/esm/hooks/HookContext.js +2 -2
  24. package/esm/hooks/HookExecutionStrategy.js +62 -0
  25. package/esm/hooks/ParallelAsync.js +13 -0
  26. package/esm/hooks/SequentialAsync.js +11 -0
  27. package/esm/hooks/SequentialSync.js +10 -0
  28. package/esm/hooks/onConstruct.js +6 -8
  29. package/esm/hooks/onResolved.js +12 -9
  30. package/esm/hooks/onScopeDisposed.js +5 -7
  31. package/esm/hooks/resolveHooks.js +1 -14
  32. package/esm/index.js +12 -6
  33. package/esm/utils/TypedEvent.js +31 -0
  34. package/package.json +1 -1
  35. package/typings/container/Container.d.ts +9 -7
  36. package/typings/container/EmptyContainer.d.ts +7 -4
  37. package/typings/container/IContainer.d.ts +6 -4
  38. package/typings/errors/TypedEventDisposedError.d.ts +6 -0
  39. package/typings/hooks/AsyncHookExecutionStrategy.d.ts +10 -0
  40. package/typings/hooks/HookContext.d.ts +3 -3
  41. package/typings/hooks/HookExecutionStrategy.d.ts +35 -0
  42. package/typings/hooks/ParallelAsync.d.ts +5 -0
  43. package/typings/hooks/SequentialAsync.d.ts +5 -0
  44. package/typings/hooks/SequentialSync.d.ts +4 -0
  45. package/typings/hooks/onConstruct.d.ts +7 -8
  46. package/typings/hooks/onResolved.d.ts +5 -5
  47. package/typings/hooks/onScopeDisposed.d.ts +4 -5
  48. package/typings/hooks/resolveHooks.d.ts +0 -6
  49. package/typings/index.d.ts +12 -6
  50. package/typings/utils/TypedEvent.d.ts +17 -0
  51. package/cjm/hooks/HooksRunner.js +0 -50
  52. package/esm/hooks/HooksRunner.js +0 -45
  53. package/typings/hooks/HooksRunner.d.ts +0 -19
package/esm/index.js CHANGED
@@ -18,14 +18,19 @@ export { ContainerDisposedError } from './errors/ContainerDisposedError.js';
18
18
  export { ProviderDisposedError } from './errors/ProviderDisposedError.js';
19
19
  export { CannonSingletonApplyTwiceError } from './errors/CannonSingletonApplyTwiceError.js';
20
20
  export { UnsupportedTokenTypeError } from './errors/UnsupportedTokenTypeError.js';
21
+ export { TypedEventDisposedError } from './errors/TypedEventDisposedError.js';
21
22
  export { getHooks, hook, hasHooks, appendHooks, prependHooks, append, prepend, } from './hooks/hook.js';
22
- export { HookContext, createHookContextFactory, createHookContext } from './hooks/HookContext.js';
23
+ export { HookContext, createHookContextFactory, createHookExecutionContext, } from './hooks/HookContext.js';
23
24
  export { injectProp } from './hooks/injectProp.js';
24
- export { onConstructHooksRunner, onConstruct, OnConstructModule } from './hooks/onConstruct.js';
25
- export { onScopeDisposedHooksRunner, onScopeDisposed, OnDisposeModule } from './hooks/onScopeDisposed.js';
26
- export { onResolvedHooksRunner, onResolved, OnResolvedModule, resolved } from './hooks/onResolved.js';
27
- export { invokeMethod, oncePerInstance } from './hooks/resolveHooks.js';
28
- export { HooksRunner, runHooks, } from './hooks/HooksRunner.js';
25
+ export { onConstruct, OnConstructModule } from './hooks/onConstruct.js';
26
+ export { onScopeDisposed, OnDisposeModule } from './hooks/onScopeDisposed.js';
27
+ export { onResolved, OnResolvedModule, resolved } from './hooks/onResolved.js';
28
+ export { oncePerInstance } from './hooks/resolveHooks.js';
29
+ export { HookExecutionStrategy, } from './hooks/HookExecutionStrategy.js';
30
+ export { AsyncHookExecutionStrategy, } from './hooks/AsyncHookExecutionStrategy.js';
31
+ export { SequentialSync } from './hooks/SequentialSync.js';
32
+ export { SequentialAsync } from './hooks/SequentialAsync.js';
33
+ export { ParallelAsync } from './hooks/ParallelAsync.js';
29
34
  export { InjectionToken } from './token/InjectionToken.js';
30
35
  export { toToken, toMappedToken, argToToken } from './token/toToken.js';
31
36
  export { GroupAliasToken, toGroupAlias } from './token/GroupAliasToken.js';
@@ -44,6 +49,7 @@ export { throttle } from './utils/throttle.js';
44
49
  export { debounce } from './utils/debounce.js';
45
50
  export { shallowCache } from './utils/shallowCache.js';
46
51
  export { once } from './utils/once.js';
52
+ export { TypedEvent } from './utils/TypedEvent.js';
47
53
  export { select } from './select.js';
48
54
  export { pipe } from './utils/fp.js';
49
55
  export { ProxyRegistry, unwrapProxy } from './utils/ProxyRegistry.js';
@@ -0,0 +1,31 @@
1
+ import { TypedEventDisposedError } from '../errors/TypedEventDisposedError.js';
2
+ export class TypedEvent {
3
+ listeners = new Set();
4
+ isDisposed = false;
5
+ subscribe(listener) {
6
+ this.validate();
7
+ this.listeners.add(listener);
8
+ return () => this.unsubscribe(listener);
9
+ }
10
+ unsubscribe(listener) {
11
+ this.listeners.delete(listener);
12
+ }
13
+ emit(...args) {
14
+ this.validate();
15
+ for (const listener of [...this.listeners]) {
16
+ if (this.listeners.has(listener)) {
17
+ listener(...args);
18
+ }
19
+ }
20
+ }
21
+ getListeners() {
22
+ return [...this.listeners];
23
+ }
24
+ dispose() {
25
+ this.listeners.clear();
26
+ this.isDisposed = true;
27
+ }
28
+ validate() {
29
+ TypedEventDisposedError.assert(!this.isDisposed, 'TypedEvent is already disposed');
30
+ }
31
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ts-ioc-container",
3
- "version": "63.0.0",
3
+ "version": "65.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",
@@ -1,8 +1,9 @@
1
- import { type AutoResolveOptions, type CreateScopeOptions, type DependencyKey, type IContainer, type IContainerModule, type RegisteredHook, type RegisterOptions, ResolveManyOptions, type ResolveOneOptions, type ScopeHook, type Tag } from './IContainer.js';
1
+ import { type AutoResolveOptions, type CreateScopeOptions, type DependencyKey, type IContainer, type IContainerModule, type RegisterOptions, ResolveManyOptions, type ResolveOneOptions, type Tag } from './IContainer.js';
2
2
  import { type IInjector } from '../injector/IInjector.js';
3
3
  import { type IProvider } from '../provider/IProvider.js';
4
4
  import { type IRegistration } from '../registration/IRegistration.js';
5
5
  import { constructor, Instance } from '../utils/basic.js';
6
+ import { type ITypedEvent } from '../utils/TypedEvent.js';
6
7
  export declare class Container implements IContainer {
7
8
  isDisposed: boolean;
8
9
  private parent;
@@ -13,9 +14,12 @@ export declare class Container implements IContainer {
13
14
  private readonly providers;
14
15
  private readonly aliases;
15
16
  private readonly injector;
16
- private readonly onScopeCreatedHookList;
17
- private readonly onScopeDisposedHookList;
18
- private readonly onRegisteredHookList;
17
+ private readonly scopeCreatedEvent;
18
+ private readonly scopeDisposedEvent;
19
+ private readonly registeredEvent;
20
+ readonly scopeCreated: ITypedEvent<[IContainer]>;
21
+ readonly scopeDisposed: ITypedEvent<[IContainer]>;
22
+ readonly registered: ITypedEvent<[IProvider, DependencyKey, IContainer]>;
19
23
  constructor(options?: {
20
24
  injector?: IInjector;
21
25
  parent?: IContainer;
@@ -30,10 +34,8 @@ export declare class Container implements IContainer {
30
34
  dispose(): void;
31
35
  addRegistration(registration: IRegistration): this;
32
36
  getRegistrations(): IRegistration[];
37
+ getInjector(): IInjector;
33
38
  hasRegistration(key: DependencyKey): boolean;
34
- onScopeCreated(...hooks: ScopeHook[]): this;
35
- onScopeDisposed(...hooks: ScopeHook[]): this;
36
- onRegistered(...hooks: RegisteredHook[]): this;
37
39
  addInstance(instance: Instance): void;
38
40
  getScopes(): IContainer[];
39
41
  hasInstance(instance: Instance): boolean;
@@ -1,7 +1,9 @@
1
- import { type AutoResolveOptions, type DependencyKey, type IContainer, type IContainerModule, type ScopeHook, type RegisteredHook, type ResolveManyOptions, type ResolveOneOptions, type Tag } from './IContainer.js';
1
+ import { type AutoResolveOptions, type DependencyKey, type IContainer, type IContainerModule, type ResolveManyOptions, type ResolveOneOptions, type Tag } from './IContainer.js';
2
2
  import { type IProvider } from '../provider/IProvider.js';
3
3
  import { type IRegistration } from '../registration/IRegistration.js';
4
4
  import { type constructor, type Instance } from '../utils/basic.js';
5
+ import { type IInjector } from '../injector/IInjector.js';
6
+ import { type ITypedEvent } from '../utils/TypedEvent.js';
5
7
  export declare class EmptyContainer implements IContainer {
6
8
  get isDisposed(): boolean;
7
9
  addInstance(instance: Instance): void;
@@ -10,6 +12,7 @@ export declare class EmptyContainer implements IContainer {
10
12
  getInstances(): never[];
11
13
  hasInstance(instance: Instance): boolean;
12
14
  createScope(): IContainer;
15
+ getInjector(): IInjector;
13
16
  autoResolve(options?: AutoResolveOptions): this;
14
17
  dispose(): void;
15
18
  register(key: DependencyKey, value: IProvider): this;
@@ -23,7 +26,7 @@ export declare class EmptyContainer implements IContainer {
23
26
  resolve<T>(key: constructor<T> | DependencyKey, options?: ResolveOneOptions): T;
24
27
  resolveByAlias<T>(alias: DependencyKey, options?: ResolveManyOptions): T[];
25
28
  resolveOneByAlias<T>(alias: DependencyKey, options?: ResolveOneOptions): T;
26
- onScopeCreated(...hooks: ScopeHook[]): this;
27
- onScopeDisposed(...hooks: ScopeHook[]): this;
28
- onRegistered(...hooks: RegisteredHook[]): this;
29
+ get scopeCreated(): ITypedEvent<[IContainer]>;
30
+ get scopeDisposed(): ITypedEvent<[IContainer]>;
31
+ get registered(): ITypedEvent<[IProvider, DependencyKey, IContainer]>;
29
32
  }
@@ -1,7 +1,8 @@
1
1
  import { type IProvider, ProviderOptions } from '../provider/IProvider.js';
2
2
  import { type IRegistration } from '../registration/IRegistration.js';
3
- import { type WithArgs } from '../injector/IInjector.js';
3
+ import { IInjector, type WithArgs } from '../injector/IInjector.js';
4
4
  import { type constructor, Instance } from '../utils/basic.js';
5
+ import { type ITypedEvent } from '../utils/TypedEvent.js';
5
6
  export type DependencyKey = string | symbol;
6
7
  export declare function isDependencyKey(target: unknown): target is DependencyKey;
7
8
  export type Tag = string;
@@ -35,9 +36,9 @@ export type ScopeHook = (scope: IContainer) => void;
35
36
  export type RegisteredHook = (provider: IProvider, key: DependencyKey, scope: IContainer) => void;
36
37
  export interface IContainer extends Tagged {
37
38
  readonly isDisposed: boolean;
38
- onScopeCreated(...hooks: ScopeHook[]): this;
39
- onScopeDisposed(...hooks: ScopeHook[]): this;
40
- onRegistered(...hooks: RegisteredHook[]): this;
39
+ readonly scopeCreated: ITypedEvent<[IContainer]>;
40
+ readonly scopeDisposed: ITypedEvent<[IContainer]>;
41
+ readonly registered: ITypedEvent<[IProvider, DependencyKey, IContainer]>;
41
42
  register(key: DependencyKey, value: IProvider, options?: RegisterOptions): this;
42
43
  addRegistration(registration: IRegistration): this;
43
44
  getRegistrations(): IRegistration[];
@@ -55,5 +56,6 @@ export interface IContainer extends Tagged {
55
56
  hasInstance(instance: Instance): boolean;
56
57
  dispose(): void;
57
58
  addInstance(instance: Instance): void;
59
+ getInjector(): IInjector;
58
60
  }
59
61
  export {};
@@ -0,0 +1,6 @@
1
+ import { ContainerError } from './ContainerError.js';
2
+ export declare class TypedEventDisposedError extends ContainerError {
3
+ name: string;
4
+ static assert(isTrue: boolean, failMessage: string): void;
5
+ constructor(message: string);
6
+ }
@@ -0,0 +1,10 @@
1
+ import { HookExecutionStrategy, type HookExecutionStrategyProps, type MemberHooks } from './HookExecutionStrategy.js';
2
+ export type MethodStrategy = 'sequential' | 'parallel';
3
+ export type AsyncHookExecutionStrategyProps = HookExecutionStrategyProps & {
4
+ methodStrategy?: MethodStrategy;
5
+ };
6
+ export declare abstract class AsyncHookExecutionStrategy extends HookExecutionStrategy {
7
+ private readonly methodStrategy;
8
+ constructor({ methodStrategy, ...props }: AsyncHookExecutionStrategyProps);
9
+ protected runMember({ hooks, context }: MemberHooks): void | Promise<void>;
10
+ }
@@ -29,8 +29,8 @@ export declare class HookContext implements IHookContext {
29
29
  setInitialArgs(...args: unknown[]): this;
30
30
  getInitialArgs(): unknown[];
31
31
  }
32
- export type CreateHookContext = (Target: Instance, scope: IContainer, methodName?: string) => IHookContext;
33
- export declare const createHookContext: CreateHookContext;
32
+ export type CreateHookExecutionContext = (Target: Instance, scope: IContainer, methodName?: string) => IHookContext;
33
+ export declare const createHookExecutionContext: CreateHookExecutionContext;
34
34
  export declare const createHookContextFactory: ({ args }?: {
35
35
  args?: unknown[];
36
- }) => CreateHookContext;
36
+ }) => CreateHookExecutionContext;
@@ -0,0 +1,35 @@
1
+ import type { IContainer } from '../container/IContainer.js';
2
+ import type { ExecutionContext } from '../ExecutionContext.js';
3
+ import { type Instance } from '../utils/basic.js';
4
+ import { type HookFn } from './hook.js';
5
+ import { type CreateHookExecutionContext, type IHookContext } from './HookContext.js';
6
+ export type MapHookExecutionContext = (context: IHookContext) => IHookContext;
7
+ export type OnErrorHandler = (scope: IContainer) => (error: unknown) => void;
8
+ export type HookExecutionOptions = {
9
+ createExecutionContext?: CreateHookExecutionContext;
10
+ mapExecutionContext?: MapHookExecutionContext;
11
+ predicate?: (methodName: string) => boolean;
12
+ };
13
+ export type HookExecutionContext = ExecutionContext & HookExecutionOptions;
14
+ export type HookExecutionStrategyProps = HookExecutionOptions & {
15
+ key: string | symbol;
16
+ onError?: OnErrorHandler;
17
+ };
18
+ export type MemberHooks = {
19
+ hooks: HookFn[];
20
+ context: IHookContext;
21
+ };
22
+ export declare const runInOrder: (hooks: HookFn[], context: IHookContext, from?: number) => void | Promise<void>;
23
+ export declare const runAtOnce: (hooks: HookFn[], context: IHookContext) => void | Promise<void>;
24
+ export declare abstract class HookExecutionStrategy {
25
+ private readonly key;
26
+ private readonly onError?;
27
+ private readonly options;
28
+ private readonly hooksByClass;
29
+ constructor({ key, onError, createExecutionContext, mapExecutionContext, predicate, }: HookExecutionStrategyProps);
30
+ hasHooks(target: Instance): boolean;
31
+ execute(target: Instance, { scope, ...overrides }: HookExecutionContext): void;
32
+ protected abstract processHooks(members: MemberHooks[]): void | Promise<void>;
33
+ private collect;
34
+ private hooksOf;
35
+ }
@@ -0,0 +1,5 @@
1
+ import { AsyncHookExecutionStrategy } from './AsyncHookExecutionStrategy.js';
2
+ import { type MemberHooks } from './HookExecutionStrategy.js';
3
+ export declare class ParallelAsync extends AsyncHookExecutionStrategy {
4
+ protected processHooks(members: MemberHooks[]): void | Promise<void>;
5
+ }
@@ -0,0 +1,5 @@
1
+ import { AsyncHookExecutionStrategy } from './AsyncHookExecutionStrategy.js';
2
+ import { type MemberHooks } from './HookExecutionStrategy.js';
3
+ export declare class SequentialAsync extends AsyncHookExecutionStrategy {
4
+ protected processHooks(members: MemberHooks[], from?: number): void | Promise<void>;
5
+ }
@@ -0,0 +1,4 @@
1
+ import { HookExecutionStrategy, type MemberHooks } from './HookExecutionStrategy.js';
2
+ export declare class SequentialSync extends HookExecutionStrategy {
3
+ protected processHooks(members: MemberHooks[]): void;
4
+ }
@@ -1,10 +1,9 @@
1
- import { HookType } from './hook.js';
2
- import type { IInjector, IInjectorModule } from '../injector/IInjector.js';
3
- import { HooksRunner, type OnExceptionHandler } from './HooksRunner.js';
4
- export declare const onConstructHooksRunner: HooksRunner;
1
+ import { type HookType } from './hook.js';
2
+ import type { IContainer, IContainerModule } from '../container/IContainer.js';
3
+ import { type HookExecutionStrategy } from './HookExecutionStrategy.js';
5
4
  export declare const onConstruct: (...fns: HookType[]) => (target: object, propertyKey: string | symbol) => void;
6
- export declare class OnConstructModule implements IInjectorModule {
7
- private readonly onException?;
8
- constructor(onException?: OnExceptionHandler | undefined);
9
- applyTo(injector: IInjector): void;
5
+ export declare class OnConstructModule implements IContainerModule {
6
+ private readonly strategy;
7
+ constructor(strategy: HookExecutionStrategy);
8
+ applyTo(container: IContainer): void;
10
9
  }
@@ -1,10 +1,10 @@
1
1
  import type { IContainer, IContainerModule } from '../container/IContainer.js';
2
- import { HooksRunner, type OnExceptionHandler } from './HooksRunner.js';
3
- export declare const onResolvedHooksRunner: HooksRunner;
4
- export declare const onResolved: (...hooks: import("./hook.js").HookType[]) => (target: object, propertyKey: string | symbol) => void;
2
+ import { type HookExecutionStrategy } from './HookExecutionStrategy.js';
3
+ import { type HookType } from './hook.js';
4
+ export declare const onResolved: (...hooks: HookType[]) => (target: object, propertyKey: string | symbol) => void;
5
5
  export declare class OnResolvedModule implements IContainerModule {
6
6
  private readonly runHooks;
7
- constructor(onException?: OnExceptionHandler);
7
+ constructor(strategy: HookExecutionStrategy);
8
8
  applyTo(container: IContainer): void;
9
9
  }
10
- export declare const resolved: <T = unknown>(onException?: OnExceptionHandler) => import("../registration/IRegistration.js").ProviderPipe<T>;
10
+ export declare const resolved: <T = unknown>(strategy: HookExecutionStrategy) => import("../registration/IRegistration.js").ProviderPipe<T>;
@@ -1,10 +1,9 @@
1
- import { HookType } from './hook.js';
1
+ import { type HookType } from './hook.js';
2
2
  import type { IContainer, IContainerModule } from '../container/IContainer.js';
3
- import { HooksRunner, type OnExceptionHandler } from './HooksRunner.js';
4
- export declare const onScopeDisposedHooksRunner: HooksRunner;
3
+ import { type HookExecutionStrategy } from './HookExecutionStrategy.js';
5
4
  export declare const onScopeDisposed: (...fns: HookType[]) => (target: object, propertyKey: string | symbol) => void;
6
5
  export declare class OnDisposeModule implements IContainerModule {
7
- private readonly onException?;
8
- constructor(onException?: OnExceptionHandler | undefined);
6
+ private readonly strategy;
7
+ constructor(strategy: HookExecutionStrategy);
9
8
  applyTo(container: IContainer): void;
10
9
  }
@@ -1,10 +1,4 @@
1
1
  import type { IContainer } from '../container/IContainer.js';
2
- import type { ProviderHook } from '../provider/IProvider.js';
3
- import { type HooksRunner, type OnExceptionHandler } from './HooksRunner.js';
4
2
  import { type HookFn, type HookType } from './hook.js';
5
3
  export type ResolvedObjectHook = (dependency: object, scope: IContainer) => void;
6
- export declare const invokeMethod: HookFn;
7
4
  export declare const oncePerInstance: (execute: HookType) => HookFn;
8
- export declare const resolvedHook: (key: string) => (...hooks: HookType[]) => (target: object, propertyKey: string | symbol) => void;
9
- export declare const forEachResolvedObject: (run: ResolvedObjectHook) => ProviderHook;
10
- export declare const executeHooks: (runner: HooksRunner, onException?: OnExceptionHandler) => ResolvedObjectHook;
@@ -19,14 +19,19 @@ export { ContainerDisposedError } from './errors/ContainerDisposedError.js';
19
19
  export { ProviderDisposedError } from './errors/ProviderDisposedError.js';
20
20
  export { CannonSingletonApplyTwiceError } from './errors/CannonSingletonApplyTwiceError.js';
21
21
  export { UnsupportedTokenTypeError } from './errors/UnsupportedTokenTypeError.js';
22
+ export { TypedEventDisposedError } from './errors/TypedEventDisposedError.js';
22
23
  export { getHooks, hook, hasHooks, appendHooks, prependHooks, append, prepend, type HookFn, type HookClass, type HookType, type MapHooksFn, type InjectFn, type HooksOfClass, } from './hooks/hook.js';
23
- export { HookContext, createHookContextFactory, createHookContext, type IHookContext } from './hooks/HookContext.js';
24
+ export { HookContext, createHookContextFactory, createHookExecutionContext, type CreateHookExecutionContext, type IHookContext, } from './hooks/HookContext.js';
24
25
  export { injectProp } from './hooks/injectProp.js';
25
- export { onConstructHooksRunner, onConstruct, OnConstructModule } from './hooks/onConstruct.js';
26
- export { onScopeDisposedHooksRunner, onScopeDisposed, OnDisposeModule } from './hooks/onScopeDisposed.js';
27
- export { onResolvedHooksRunner, onResolved, OnResolvedModule, resolved } from './hooks/onResolved.js';
28
- export { invokeMethod, oncePerInstance, type ResolvedObjectHook } from './hooks/resolveHooks.js';
29
- export { HooksRunner, runHooks, type HooksRunnerContext, type MapHookContext, type OnExceptionHandler, } from './hooks/HooksRunner.js';
26
+ export { onConstruct, OnConstructModule } from './hooks/onConstruct.js';
27
+ export { onScopeDisposed, OnDisposeModule } from './hooks/onScopeDisposed.js';
28
+ export { onResolved, OnResolvedModule, resolved } from './hooks/onResolved.js';
29
+ export { oncePerInstance, type ResolvedObjectHook } from './hooks/resolveHooks.js';
30
+ export { HookExecutionStrategy, type HookExecutionContext, type HookExecutionOptions, type HookExecutionStrategyProps, type MapHookExecutionContext, type MemberHooks, type OnErrorHandler, } from './hooks/HookExecutionStrategy.js';
31
+ export { AsyncHookExecutionStrategy, type AsyncHookExecutionStrategyProps, type MethodStrategy, } from './hooks/AsyncHookExecutionStrategy.js';
32
+ export { SequentialSync } from './hooks/SequentialSync.js';
33
+ export { SequentialAsync } from './hooks/SequentialAsync.js';
34
+ export { ParallelAsync } from './hooks/ParallelAsync.js';
30
35
  export { InjectionToken } from './token/InjectionToken.js';
31
36
  export { type Injectable, toToken, toMappedToken, argToToken } from './token/toToken.js';
32
37
  export { GroupAliasToken, toGroupAlias } from './token/GroupAliasToken.js';
@@ -45,6 +50,7 @@ export { throttle } from './utils/throttle.js';
45
50
  export { debounce } from './utils/debounce.js';
46
51
  export { shallowCache } from './utils/shallowCache.js';
47
52
  export { once } from './utils/once.js';
53
+ export { TypedEvent, type ITypedEvent, type TypedEventListener, type Unsubscribe } from './utils/TypedEvent.js';
48
54
  export { type ExecutionContext } from './ExecutionContext.js';
49
55
  export { select } from './select.js';
50
56
  export { pipe, type MapFn } from './utils/fp.js';
@@ -0,0 +1,17 @@
1
+ export type TypedEventListener<TArgs extends unknown[]> = (...args: TArgs) => void;
2
+ export type Unsubscribe = () => void;
3
+ export interface ITypedEvent<TArgs extends unknown[]> {
4
+ subscribe(listener: TypedEventListener<TArgs>): Unsubscribe;
5
+ unsubscribe(listener: TypedEventListener<TArgs>): void;
6
+ dispose(): void;
7
+ }
8
+ export declare class TypedEvent<TArgs extends unknown[] = []> implements ITypedEvent<TArgs> {
9
+ private readonly listeners;
10
+ private isDisposed;
11
+ subscribe(listener: TypedEventListener<TArgs>): Unsubscribe;
12
+ unsubscribe(listener: TypedEventListener<TArgs>): void;
13
+ emit(...args: TArgs): void;
14
+ getListeners(): TypedEventListener<TArgs>[];
15
+ dispose(): void;
16
+ private validate;
17
+ }
@@ -1,50 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.runHooks = exports.HooksRunner = void 0;
4
- const HookContext_1 = require("./HookContext");
5
- const hook_1 = require("./hook");
6
- const runFrom = (fns, index, context) => {
7
- for (let i = index; i < fns.length; i++) {
8
- const result = fns[i](context);
9
- if (result instanceof Promise) {
10
- return result.then(() => runFrom(fns, i + 1, context));
11
- }
12
- }
13
- };
14
- class HooksRunner {
15
- key;
16
- constructor(key) {
17
- this.key = key;
18
- }
19
- hasHooks(target) {
20
- return (0, hook_1.hasHooks)(target, this.key);
21
- }
22
- execute(target, { scope, createContext = HookContext_1.createHookContext, mapContext = (context) => context, predicate = () => true, }) {
23
- const hooks = Array.from((0, hook_1.getHooks)(target, this.key).entries()).filter(([methodName]) => predicate(methodName));
24
- const pending = [];
25
- for (const [methodName, executions] of hooks) {
26
- const context = mapContext(createContext(target, scope, methodName));
27
- const result = runFrom(executions.map(hook_1.toHookFn), 0, context);
28
- if (result) {
29
- pending.push(result);
30
- }
31
- }
32
- return pending.length > 0 ? Promise.all(pending).then(() => undefined) : undefined;
33
- }
34
- }
35
- exports.HooksRunner = HooksRunner;
36
- const runHooks = (runner, target, scope, onException) => {
37
- const report = (ex) => {
38
- if (!onException) {
39
- throw ex;
40
- }
41
- onException(ex, { scope });
42
- };
43
- try {
44
- runner.execute(target, { scope })?.catch(report);
45
- }
46
- catch (ex) {
47
- report(ex);
48
- }
49
- };
50
- exports.runHooks = runHooks;
@@ -1,45 +0,0 @@
1
- import { createHookContext } from './HookContext.js';
2
- import { getHooks, hasHooks, toHookFn } from './hook.js';
3
- const runFrom = (fns, index, context) => {
4
- for (let i = index; i < fns.length; i++) {
5
- const result = fns[i](context);
6
- if (result instanceof Promise) {
7
- return result.then(() => runFrom(fns, i + 1, context));
8
- }
9
- }
10
- };
11
- export class HooksRunner {
12
- key;
13
- constructor(key) {
14
- this.key = key;
15
- }
16
- hasHooks(target) {
17
- return hasHooks(target, this.key);
18
- }
19
- execute(target, { scope, createContext = createHookContext, mapContext = (context) => context, predicate = () => true, }) {
20
- const hooks = Array.from(getHooks(target, this.key).entries()).filter(([methodName]) => predicate(methodName));
21
- const pending = [];
22
- for (const [methodName, executions] of hooks) {
23
- const context = mapContext(createContext(target, scope, methodName));
24
- const result = runFrom(executions.map(toHookFn), 0, context);
25
- if (result) {
26
- pending.push(result);
27
- }
28
- }
29
- return pending.length > 0 ? Promise.all(pending).then(() => undefined) : undefined;
30
- }
31
- }
32
- export const runHooks = (runner, target, scope, onException) => {
33
- const report = (ex) => {
34
- if (!onException) {
35
- throw ex;
36
- }
37
- onException(ex, { scope });
38
- };
39
- try {
40
- runner.execute(target, { scope })?.catch(report);
41
- }
42
- catch (ex) {
43
- report(ex);
44
- }
45
- };
@@ -1,19 +0,0 @@
1
- import { type CreateHookContext, type IHookContext } from './HookContext.js';
2
- import type { IContainer } from '../container/IContainer.js';
3
- import { type Instance } from '../utils/basic.js';
4
- import type { ExecutionContext } from '../ExecutionContext.js';
5
- export type MapHookContext = (context: IHookContext) => IHookContext;
6
- export type OnExceptionHandler = (ex: unknown, context: ExecutionContext) => void;
7
- export type HooksRunnerContext = {
8
- scope: IContainer;
9
- createContext?: CreateHookContext;
10
- mapContext?: MapHookContext;
11
- predicate?: (methodName: string) => boolean;
12
- };
13
- export declare class HooksRunner {
14
- private readonly key;
15
- constructor(key: string | symbol);
16
- hasHooks(target: Instance): boolean;
17
- execute(target: Instance, { scope, createContext, mapContext, predicate, }: HooksRunnerContext): void | Promise<void>;
18
- }
19
- export declare const runHooks: (runner: HooksRunner, target: Instance, scope: IContainer, onException?: OnExceptionHandler) => void;