@tstdl/base 0.86.0-beta9 → 0.86.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.
Files changed (55) hide show
  1. package/application/application.js +0 -1
  2. package/browser/browser-context-controller.d.ts +2 -2
  3. package/browser/browser-context-controller.js +6 -7
  4. package/browser/browser-controller.js +6 -7
  5. package/core.d.ts +2 -4
  6. package/core.js +2 -9
  7. package/database/mongo/module.js +8 -8
  8. package/disposable/async-disposer.d.ts +8 -7
  9. package/disposable/async-disposer.js +49 -23
  10. package/disposable/disposable.d.ts +5 -4
  11. package/disposable/disposable.js +9 -5
  12. package/injector/injector.d.ts +5 -2
  13. package/injector/injector.js +59 -23
  14. package/injector/interfaces.d.ts +4 -3
  15. package/injector/provider.d.ts +12 -12
  16. package/injector/resolve.error.d.ts +1 -1
  17. package/injector/types.d.ts +16 -7
  18. package/logger/console/logger.js +2 -2
  19. package/module/modules/web-server.module.js +0 -2
  20. package/object-storage/object-storage-provider.d.ts +1 -1
  21. package/object-storage/s3/s3.object-storage-provider.d.ts +1 -6
  22. package/object-storage/s3/s3.object-storage-provider.js +2 -12
  23. package/object-storage/s3/s3.object-storage.js +4 -1
  24. package/package.json +7 -6
  25. package/polyfills.d.ts +159 -0
  26. package/polyfills.js +2 -0
  27. package/queue/mongo/mongo-job.repository.js +3 -4
  28. package/search-index/elastic/module.js +4 -4
  29. package/tsconfig.json +1 -1
  30. package/utils/cancellation-token.d.ts +19 -17
  31. package/utils/cancellation-token.js +20 -19
  32. package/_container/container.d.ts +0 -99
  33. package/_container/container.js +0 -443
  34. package/_container/decorators.d.ts +0 -76
  35. package/_container/decorators.js +0 -110
  36. package/_container/index.d.ts +0 -10
  37. package/_container/index.js +0 -27
  38. package/_container/interfaces.d.ts +0 -16
  39. package/_container/interfaces.js +0 -26
  40. package/_container/provider.d.ts +0 -35
  41. package/_container/provider.js +0 -60
  42. package/_container/resolve-chain.d.ts +0 -27
  43. package/_container/resolve-chain.js +0 -105
  44. package/_container/resolve.error.d.ts +0 -5
  45. package/_container/resolve.error.js +0 -36
  46. package/_container/token.d.ts +0 -18
  47. package/_container/token.js +0 -41
  48. package/_container/type-info.d.ts +0 -18
  49. package/_container/type-info.js +0 -16
  50. package/_container/types.d.ts +0 -9
  51. package/_container/types.js +0 -16
  52. package/_container/utils.d.ts +0 -3
  53. package/_container/utils.js +0 -44
  54. package/global-this.d.ts +0 -1
  55. package/global-this.js +0 -37
@@ -137,7 +137,6 @@ let Application = class Application2 {
137
137
  this.#logger.info("Shutting down");
138
138
  await this.stopModules(modules);
139
139
  await this.#injector.dispose();
140
- await (0, import_core.disposeInstances)();
141
140
  this.#logger.info("Bye");
142
141
  }
143
142
  this.#shutdownPromise.resolve();
@@ -5,7 +5,7 @@ import type { Resolvable } from '../injector/interfaces.js';
5
5
  import { resolveArgumentType } from '../injector/interfaces.js';
6
6
  import type { Logger } from '../logger/logger.js';
7
7
  import type { Record } from '../types.js';
8
- import type { Opaque } from 'type-fest';
8
+ import type { Tagged } from 'type-fest';
9
9
  import type { NewBrowserContextOptions } from './browser-controller.js';
10
10
  import type { PageControllerOptions } from './page-controller.js';
11
11
  import { PageController } from './page-controller.js';
@@ -16,7 +16,7 @@ export type NewPageOptions = {
16
16
  extraHttpHeaders?: Record<string, string>;
17
17
  controllerOptions?: PageControllerOptions;
18
18
  };
19
- export type BrowserContextState = Opaque<Record<string | number, unknown>, 'BrowserContextState'>;
19
+ export type BrowserContextState = Tagged<Record<string | number, unknown>, 'BrowserContextState'>;
20
20
  export type BrowserContextControllerArgument = NewBrowserContextOptions;
21
21
  export declare class BrowserContextController implements AsyncDisposable, Resolvable<BrowserContextControllerArgument> {
22
22
  /** @deprecated should be avoided */
@@ -43,8 +43,7 @@ var __metadata = function(k, v) {
43
43
  if (typeof Reflect === "object" && typeof Reflect.metadata === "function")
44
44
  return Reflect.metadata(k, v);
45
45
  };
46
- var BrowserContextController_1;
47
- let BrowserContextController = BrowserContextController_1 = class BrowserContextController2 {
46
+ let BrowserContextController = class BrowserContextController2 {
48
47
  /** @deprecated should be avoided */
49
48
  context;
50
49
  options;
@@ -95,15 +94,15 @@ let BrowserContextController = BrowserContextController_1 = class BrowserContext
95
94
  (0, import_utils.attachLogger)(this.context, logger);
96
95
  }
97
96
  };
98
- BrowserContextController = BrowserContextController_1 = __decorate([
97
+ BrowserContextController = __decorate([
99
98
  (0, import_decorators.Injectable)({
100
99
  provider: {
101
100
  useFactory: (_, context) => {
102
- context.context.browserController = context.resolve(import_browser_controller.BrowserController);
103
- return new BrowserContextController_1(null);
101
+ context.data.browserController = context.resolve(import_browser_controller.BrowserController);
102
+ return new BrowserContextController(null);
104
103
  },
105
- async afterResolve(value, argument, context) {
106
- const { context: browserContext, controllerOptions } = await context.browserController.newRawContext(argument);
104
+ async afterResolve(value, argument, { data: { browserController } }) {
105
+ const { context: browserContext, controllerOptions } = await browserController.newRawContext(argument);
107
106
  value.context = browserContext;
108
107
  value.options = controllerOptions;
109
108
  }
@@ -44,8 +44,7 @@ var __metadata = function(k, v) {
44
44
  if (typeof Reflect === "object" && typeof Reflect.metadata === "function")
45
45
  return Reflect.metadata(k, v);
46
46
  };
47
- var BrowserController_1;
48
- let BrowserController = BrowserController_1 = class BrowserController2 {
47
+ let BrowserController = class BrowserController2 {
49
48
  /** @deprecated should be avoided */
50
49
  browser;
51
50
  options;
@@ -103,15 +102,15 @@ let BrowserController = BrowserController_1 = class BrowserController2 {
103
102
  });
104
103
  }
105
104
  };
106
- BrowserController = BrowserController_1 = __decorate([
105
+ BrowserController = __decorate([
107
106
  (0, import_decorators.Injectable)({
108
107
  provider: {
109
108
  useFactory: (_argument, context) => {
110
- context.context.browserService = (0, import_inject.inject)(import_browser_service.BrowserService);
111
- return new BrowserController_1(null);
109
+ context.data.browserService = (0, import_inject.inject)(import_browser_service.BrowserService);
110
+ return new BrowserController(null);
112
111
  },
113
- async afterResolve(value, argument, context) {
114
- const { browser, controllerOptions } = await context.browserService.newRawBrowser(argument);
112
+ async afterResolve(value, argument, { data: { browserService } }) {
113
+ const { browser, controllerOptions } = await browserService.newRawBrowser(argument);
115
114
  value.browser = browser;
116
115
  value.options = controllerOptions;
117
116
  }
package/core.d.ts CHANGED
@@ -1,16 +1,14 @@
1
- import { AsyncDisposer } from './disposable/async-disposer.js';
2
1
  import { Injector } from './injector/injector.js';
3
2
  import type { InjectionToken } from './injector/token.js';
4
3
  import type { LoggerArgument } from './logger/index.js';
5
4
  import { LogLevel, Logger } from './logger/index.js';
5
+ import type { ReadonlyCancellationToken } from './utils/cancellation-token.js';
6
6
  export declare const CORE_LOGGER: InjectionToken<Logger, never>;
7
7
  export declare const rootInjector: Injector;
8
- export declare const disposer: AsyncDisposer;
9
8
  export declare function isDevMode(): boolean;
10
9
  export declare function isProdMode(): boolean;
11
10
  export declare function enableProdMode(): void;
12
- export declare function connect(name: string, connectFunction: (() => Promise<any>), logger: Logger, maxTries?: number): Promise<void>;
13
- export declare function disposeInstances(): Promise<void>;
11
+ export declare function connect(name: string, connectFunction: (() => Promise<any>), logger: Logger, cancellationToken: ReadonlyCancellationToken, maxTries?: number): Promise<void>;
14
12
  export type CoreConfiguration = {
15
13
  production?: boolean;
16
14
  logger?: InjectionToken<Logger, LoggerArgument>;
package/core.js CHANGED
@@ -21,15 +21,12 @@ __export(core_exports, {
21
21
  CORE_LOGGER: () => CORE_LOGGER,
22
22
  configureTstdl: () => configureTstdl,
23
23
  connect: () => connect,
24
- disposeInstances: () => disposeInstances,
25
- disposer: () => disposer,
26
24
  enableProdMode: () => enableProdMode,
27
25
  isDevMode: () => isDevMode,
28
26
  isProdMode: () => isProdMode,
29
27
  rootInjector: () => rootInjector
30
28
  });
31
29
  module.exports = __toCommonJS(core_exports);
32
- var import_async_disposer = require("./disposable/async-disposer.js");
33
30
  var import_injector = require("./injector/injector.js");
34
31
  var import_token = require("./injector/token.js");
35
32
  var import_logger = require("./logger/console/logger.js");
@@ -39,7 +36,6 @@ var import_timing = require("./utils/timing.js");
39
36
  var import_type_guards = require("./utils/type-guards.js");
40
37
  const CORE_LOGGER = (0, import_token.injectionToken)("core logger");
41
38
  const rootInjector = new import_injector.Injector("RootInjector");
42
- const disposer = new import_async_disposer.AsyncDisposer();
43
39
  let _isDevMode = true;
44
40
  function isDevMode() {
45
41
  return _isDevMode;
@@ -50,10 +46,10 @@ function isProdMode() {
50
46
  function enableProdMode() {
51
47
  _isDevMode = false;
52
48
  }
53
- async function connect(name, connectFunction, logger, maxTries = 5) {
49
+ async function connect(name, connectFunction, logger, cancellationToken, maxTries = 5) {
54
50
  let triesLeft = maxTries;
55
51
  let success = false;
56
- while (!success && !disposer.disposing && triesLeft-- > 0) {
52
+ while (!success && cancellationToken.isUnset && triesLeft-- > 0) {
57
53
  try {
58
54
  logger.verbose(`connecting to ${name}...`);
59
55
  await connectFunction();
@@ -69,9 +65,6 @@ async function connect(name, connectFunction, logger, maxTries = 5) {
69
65
  }
70
66
  }
71
67
  }
72
- async function disposeInstances() {
73
- await disposer.dispose();
74
- }
75
68
  let coreLogPrefix;
76
69
  function configureTstdl(config = {}) {
77
70
  if (config.production == true) {
@@ -45,12 +45,12 @@ import_injector.Injector.registerSingleton(import_classes.MongoClient, {
45
45
  const client = new import_classes.MongoClient(url, options);
46
46
  client.on("fullsetup", () => logger.verbose("connection setup")).on("reconnect", () => logger.warn("reconnected")).on("timeout", () => logger.warn("connection timed out")).on("close", () => logger.verbose("connection closed"));
47
47
  context.addDisposeHandler(async () => client.close());
48
- context.context.logger = logger;
49
- context.context.url = url;
48
+ context.data.logger = logger;
49
+ context.data.url = url;
50
50
  return client;
51
51
  },
52
- async afterResolve(client, _argument, context) {
53
- await (0, import_core.connect)(`mongo at ${context.url}`, async () => client.connect(), context.logger);
52
+ async afterResolve(client, _argument, { cancellationToken, data: { url, logger } }) {
53
+ await (0, import_core.connect)(`mongo at ${url}`, async () => client.connect(), logger, cancellationToken);
54
54
  }
55
55
  }, {
56
56
  defaultArgumentProvider: () => mongoModuleConfig.defaultConnection,
@@ -71,17 +71,17 @@ import_injector.Injector.registerSingleton(import_classes.Collection, {
71
71
  useFactory: (config, context) => {
72
72
  (0, import_type_guards.assertDefined)(config, "mongo repository config resolve argument missing");
73
73
  const database = context.resolve(import_classes.Database, config);
74
- context.context.database = database;
74
+ context.data.database = database;
75
75
  return database.collection(config.collection);
76
76
  },
77
- async afterResolve(_, config, context) {
78
- const existingCollections = await context.database.collections();
77
+ async afterResolve(_, config, { data: { database } }) {
78
+ const existingCollections = await database.collections();
79
79
  for (const collection of existingCollections) {
80
80
  if (collection.collectionName == config.collection) {
81
81
  return;
82
82
  }
83
83
  }
84
- await context.database.createCollection(config.collection);
84
+ await database.createCollection(config.collection);
85
85
  }
86
86
  }, {
87
87
  argumentIdentityProvider: JSON.stringify
@@ -1,7 +1,6 @@
1
1
  import type { ReadonlyCancellationToken } from '../utils/cancellation-token.js';
2
2
  import { CancellationToken } from '../utils/cancellation-token.js';
3
3
  import type { AsyncDisposable, Disposable } from './disposable.js';
4
- import { disposeAsync } from './disposable.js';
5
4
  declare const deferrerToken: unique symbol;
6
5
  export type AsyncDisposeTaskFunction = () => any;
7
6
  export type AsyncDisposeHandler = AsyncDisposeTaskFunction | Disposable | AsyncDisposable;
@@ -12,16 +11,17 @@ export type Deferrer = {
12
11
  [deferrerToken]: CancellationToken;
13
12
  yield(): void;
14
13
  };
15
- export declare class AsyncDisposer implements AsyncDisposable {
16
- private readonly deferrers;
17
- private readonly tasks;
18
- readonly _disposingToken: CancellationToken;
19
- readonly _disposedToken: CancellationToken;
14
+ export declare class AsyncDisposer implements AsyncDisposable, AsyncDisposableStack {
15
+ #private;
20
16
  get disposingToken(): ReadonlyCancellationToken;
21
17
  get disposedToken(): ReadonlyCancellationToken;
22
18
  get disposing(): boolean;
23
19
  get disposed(): boolean;
20
+ readonly [Symbol.toStringTag] = "AsyncDisposable";
24
21
  constructor();
22
+ use<T extends globalThis.AsyncDisposable | globalThis.Disposable | null | undefined>(value: T): T;
23
+ adopt<T>(value: T, onDisposeAsync: (value: T) => void | PromiseLike<void>): T;
24
+ move(): AsyncDisposableStack;
25
25
  getDeferrer(): Deferrer;
26
26
  defer<T>(func: () => Promise<T>): Promise<T>;
27
27
  /**
@@ -29,7 +29,8 @@ export declare class AsyncDisposer implements AsyncDisposable {
29
29
  * @param fnOrDisposable
30
30
  */
31
31
  add(fnOrDisposable: AsyncDisposeHandler): void;
32
+ disposeAsync(): Promise<void>;
32
33
  dispose(): Promise<void>;
33
- [disposeAsync](): Promise<void>;
34
+ [Symbol.asyncDispose](): Promise<void>;
34
35
  }
35
36
  export {};
@@ -27,37 +27,59 @@ var import_cancellation_token = require("../utils/cancellation-token.js");
27
27
  var import_disposable = require("./disposable.js");
28
28
  const deferrerToken = Symbol("DeferrerToken");
29
29
  class AsyncDisposer {
30
- deferrers;
31
- tasks;
32
- _disposingToken;
33
- _disposedToken;
30
+ #disposingToken;
31
+ #disposedToken;
32
+ #deferrers;
33
+ #tasks;
34
34
  get disposingToken() {
35
- return this._disposingToken;
35
+ return this.#disposingToken;
36
36
  }
37
37
  get disposedToken() {
38
- return this._disposedToken;
38
+ return this.#disposedToken;
39
39
  }
40
40
  get disposing() {
41
- return this._disposingToken.isSet;
41
+ return this.#disposingToken.isSet;
42
42
  }
43
43
  get disposed() {
44
- return this._disposedToken.isSet;
44
+ return this.#disposedToken.isSet;
45
45
  }
46
+ [Symbol.toStringTag] = "AsyncDisposable";
46
47
  constructor() {
47
- this.deferrers = /* @__PURE__ */ new Set();
48
- this.tasks = [];
49
- this._disposingToken = new import_cancellation_token.CancellationToken();
50
- this._disposedToken = new import_cancellation_token.CancellationToken();
48
+ this.#deferrers = /* @__PURE__ */ new Set();
49
+ this.#tasks = [];
50
+ this.#disposingToken = new import_cancellation_token.CancellationToken();
51
+ this.#disposedToken = new import_cancellation_token.CancellationToken();
52
+ }
53
+ use(value) {
54
+ if ((0, import_type_guards.isNullOrUndefined)(value)) {
55
+ return value;
56
+ }
57
+ this.add(value);
58
+ return value;
59
+ }
60
+ adopt(value, onDisposeAsync) {
61
+ this.add(async () => onDisposeAsync(value));
62
+ return value;
63
+ }
64
+ move() {
65
+ const disposer = new AsyncDisposer();
66
+ disposer.#tasks = this.#tasks;
67
+ disposer.#deferrers = this.#deferrers;
68
+ this.#tasks = [];
69
+ this.#deferrers = /* @__PURE__ */ new Set();
70
+ this.#disposingToken.set();
71
+ this.#disposedToken.set();
72
+ return disposer;
51
73
  }
52
74
  getDeferrer() {
53
75
  const deferrer = {
54
76
  [deferrerToken]: new import_cancellation_token.CancellationToken(),
55
77
  yield: () => {
56
78
  deferrer[deferrerToken].set();
57
- this.deferrers.delete(deferrer);
79
+ this.#deferrers.delete(deferrer);
58
80
  }
59
81
  };
60
- this.deferrers.add(deferrer);
82
+ this.#deferrers.add(deferrer);
61
83
  return deferrer;
62
84
  }
63
85
  async defer(func) {
@@ -75,24 +97,27 @@ class AsyncDisposer {
75
97
  */
76
98
  add(fnOrDisposable) {
77
99
  const fn = (0, import_disposable.isAsyncDisposable)(fnOrDisposable) ? async () => fnOrDisposable[import_disposable.disposeAsync]() : (0, import_disposable.isDisposable)(fnOrDisposable) ? () => fnOrDisposable[import_disposable.dispose]() : fnOrDisposable;
78
- this.tasks.push({ taskFunction: fn });
100
+ this.#tasks.push({ taskFunction: fn });
101
+ }
102
+ async disposeAsync() {
103
+ await this.dispose();
79
104
  }
80
105
  async dispose() {
81
106
  if (this.disposing) {
82
- return this._disposedToken.$set;
107
+ return this.#disposedToken.$set;
83
108
  }
84
- this._disposingToken.set();
109
+ this.#disposingToken.set();
85
110
  const errors = [];
86
- for (const deferrer of this.deferrers) {
111
+ for (const deferrer of this.#deferrers) {
87
112
  try {
88
113
  await deferrer[deferrerToken];
89
114
  } catch (error2) {
90
115
  errors.push(error2);
91
116
  }
92
117
  }
93
- for (let i = this.tasks.length - 1; i >= 0; i--) {
118
+ for (let i = this.#tasks.length - 1; i >= 0; i--) {
94
119
  try {
95
- const task = this.tasks[i];
120
+ const task = this.#tasks[i];
96
121
  await task.taskFunction();
97
122
  } catch (error2) {
98
123
  errors.push(error2);
@@ -100,12 +125,13 @@ class AsyncDisposer {
100
125
  }
101
126
  const error = errors.length == 1 ? errors[0] : errors.length > 1 ? new import_multi_error.MultiError(errors, "dispose errors") : void 0;
102
127
  if ((0, import_type_guards.isDefined)(error)) {
103
- this._disposedToken.error(error);
128
+ this.#disposedToken.error(error);
104
129
  throw error;
105
130
  }
106
- this._disposedToken.set();
131
+ this.#disposedToken.set();
132
+ return void 0;
107
133
  }
108
- async [import_disposable.disposeAsync]() {
134
+ async [Symbol.asyncDispose]() {
109
135
  return this.dispose();
110
136
  }
111
137
  }
@@ -1,10 +1,11 @@
1
- export declare const dispose: unique symbol;
2
- export declare const disposeAsync: unique symbol;
1
+ export declare const dispose: typeof Symbol.dispose;
2
+ export declare const disposeAsync: typeof Symbol.asyncDispose;
3
3
  export interface Disposable {
4
- [dispose](): void;
4
+ [Symbol.dispose](): void;
5
5
  }
6
6
  export interface AsyncDisposable {
7
- [disposeAsync](): Promise<void>;
7
+ [Symbol.asyncDispose](): PromiseLike<void>;
8
8
  }
9
9
  export declare function isDisposable(object: any): object is Disposable;
10
10
  export declare function isAsyncDisposable(object: any): object is AsyncDisposable;
11
+ export declare function isSyncOrAsyncDisposable(object: any): object is Disposable | AsyncDisposable;
@@ -21,15 +21,19 @@ __export(disposable_exports, {
21
21
  dispose: () => dispose,
22
22
  disposeAsync: () => disposeAsync,
23
23
  isAsyncDisposable: () => isAsyncDisposable,
24
- isDisposable: () => isDisposable
24
+ isDisposable: () => isDisposable,
25
+ isSyncOrAsyncDisposable: () => isSyncOrAsyncDisposable
25
26
  });
26
27
  module.exports = __toCommonJS(disposable_exports);
27
28
  var import_type_guards = require("../utils/type-guards.js");
28
- const dispose = Symbol("dispose");
29
- const disposeAsync = Symbol("disposeAsync");
29
+ const dispose = Symbol.dispose;
30
+ const disposeAsync = Symbol.asyncDispose;
30
31
  function isDisposable(object) {
31
- return (0, import_type_guards.isFunction)(object?.[dispose]);
32
+ return (0, import_type_guards.isFunction)(object?.[Symbol.dispose]);
32
33
  }
33
34
  function isAsyncDisposable(object) {
34
- return (0, import_type_guards.isFunction)(object?.[disposeAsync]);
35
+ return (0, import_type_guards.isFunction)(object?.[Symbol.asyncDispose]);
36
+ }
37
+ function isSyncOrAsyncDisposable(object) {
38
+ return (0, import_type_guards.isFunction)(object?.[Symbol.dispose] ?? object?.[Symbol.asyncDispose]);
35
39
  }
@@ -1,5 +1,4 @@
1
1
  import type { AsyncDisposable } from '../disposable/disposable.js';
2
- import { disposeAsync } from '../disposable/disposable.js';
3
2
  import type { OneOrMany, Record, TypedOmit } from '../types.js';
4
3
  import type { ResolveArgument } from './interfaces.js';
5
4
  import { type Provider } from './provider.js';
@@ -17,9 +16,11 @@ export type GetRegistrationOptions = {
17
16
  skipSelf?: boolean;
18
17
  onlySelf?: boolean;
19
18
  };
19
+ export type AddDisposeHandler = (handler: Disposable | AsyncDisposable | (() => any)) => void;
20
20
  export declare class Injector implements AsyncDisposable {
21
21
  #private;
22
22
  readonly name: string;
23
+ get disposed(): boolean;
23
24
  constructor(name: string, parent?: Injector | null);
24
25
  /**
25
26
  * Globally register a provider for a token
@@ -36,7 +37,7 @@ export declare class Injector implements AsyncDisposable {
36
37
  */
37
38
  static registerSingleton<T, A = any, C extends Record = Record>(token: InjectionToken<T, A>, providers: OneOrMany<Provider<T, A, C>>, options?: TypedOmit<RegistrationOptions<T, A, C>, 'lifecycle'>): void;
38
39
  dispose(): Promise<void>;
39
- [disposeAsync](): Promise<void>;
40
+ [Symbol.asyncDispose](): Promise<void>;
40
41
  fork(name: string): Injector;
41
42
  /**
42
43
  * Register a provider for a token
@@ -87,5 +88,7 @@ export declare class Injector implements AsyncDisposable {
87
88
  private resolveInjectionAll;
88
89
  private resolveInjectionAllAsync;
89
90
  private getResolveContext;
91
+ private getAfterResolveContext;
90
92
  private getInjectionContext;
93
+ private assertNotDisposed;
91
94
  }
@@ -23,11 +23,11 @@ __export(injector_exports, {
23
23
  module.exports = __toCommonJS(injector_exports);
24
24
  var import_circular_buffer = require("../data-structures/circular-buffer.js");
25
25
  var import_multi_key_map = require("../data-structures/multi-key-map.js");
26
- var import_async_disposer = require("../disposable/async-disposer.js");
27
26
  var import_disposable = require("../disposable/disposable.js");
28
27
  var import_deferred_promise = require("../promise/deferred-promise.js");
29
28
  var import_registry = require("../reflection/registry.js");
30
29
  var import_array = require("../utils/array/array.js");
30
+ var import_cancellation_token = require("../utils/cancellation-token.js");
31
31
  var import_factory_map = require("../utils/factory-map.js");
32
32
  var import_forward_ref = require("../utils/object/forward-ref.js");
33
33
  var import_object = require("../utils/object/object.js");
@@ -43,14 +43,29 @@ class Injector {
43
43
  static #globalRegistrations = /* @__PURE__ */ new Map();
44
44
  #parent;
45
45
  #children = [];
46
- #disposer = new import_async_disposer.AsyncDisposer();
46
+ #disposeToken = new import_cancellation_token.CancellationToken();
47
+ #disposableStack = new AsyncDisposableStack();
47
48
  #registrations = /* @__PURE__ */ new Map();
48
49
  #injectorScopedResolutions = new import_multi_key_map.MultiKeyMap();
50
+ #addDisposeHandler;
49
51
  name;
52
+ get disposed() {
53
+ return this.#disposableStack.disposed;
54
+ }
50
55
  constructor(name, parent = null) {
51
56
  this.name = name;
52
57
  this.#parent = parent;
53
58
  this.register(Injector, { useValue: this });
59
+ this.register(import_cancellation_token.CancellationToken, { useValue: this.#disposeToken });
60
+ this.#addDisposeHandler = (handler) => {
61
+ if ((0, import_disposable.isSyncOrAsyncDisposable)(handler)) {
62
+ this.#disposableStack.use(handler);
63
+ } else {
64
+ this.#disposableStack.defer(handler);
65
+ }
66
+ };
67
+ this.#disposableStack.defer(() => this.#registrations.clear());
68
+ this.#disposableStack.defer(() => this.#injectorScopedResolutions.clear());
54
69
  }
55
70
  /**
56
71
  * Globally register a provider for a token
@@ -78,15 +93,16 @@ class Injector {
78
93
  Injector.register(token, providers, { ...options, lifecycle: "singleton" });
79
94
  }
80
95
  async dispose() {
81
- await this.#disposer.dispose();
96
+ this.#disposeToken.set();
97
+ await this.#disposableStack.disposeAsync();
82
98
  }
83
- async [import_disposable.disposeAsync]() {
99
+ async [Symbol.asyncDispose]() {
84
100
  await this.dispose();
85
101
  }
86
102
  fork(name) {
87
103
  const child = new Injector(name, this);
88
104
  this.#children.push(child);
89
- this.#disposer.add(child);
105
+ this.#disposableStack.use(child);
90
106
  return child;
91
107
  }
92
108
  /**
@@ -96,6 +112,7 @@ class Injector {
96
112
  * @param options registration options
97
113
  */
98
114
  register(token, providers, options = {}) {
115
+ this.assertNotDisposed();
99
116
  for (const provider of (0, import_array.toArray)(providers)) {
100
117
  const registration = {
101
118
  token,
@@ -184,6 +201,7 @@ class Injector {
184
201
  return values;
185
202
  }
186
203
  _resolve(token, argument, options, context, chain) {
204
+ this.assertNotDisposed();
187
205
  if ((0, import_type_guards.isUndefined)(token)) {
188
206
  throw new import_resolve_error.ResolveError("Token is undefined - this might be because of circular dependencies, use alias or forwardRef in this case.", chain);
189
207
  }
@@ -201,6 +219,7 @@ class Injector {
201
219
  return this._resolveRegistration(singleRegistration, argument, options, context, chain);
202
220
  }
203
221
  _resolveAll(token, argument, options, context, chain) {
222
+ this.assertNotDisposed();
204
223
  if ((0, import_type_guards.isUndefined)(token)) {
205
224
  throw new import_resolve_error.ResolveError("Token is undefined - this might be because of circular dependencies, use alias or forwardRef in this case.", chain);
206
225
  }
@@ -237,7 +256,14 @@ class Injector {
237
256
  return registration.resolutions.get(argumentIdentity);
238
257
  }
239
258
  const value = this._resolveProvider(resolutionTag, registration, resolveArgument, options, context, injectionContext, chain);
240
- const resolution = { tag: resolutionTag, registration, value, argument, chain };
259
+ const resolution = {
260
+ tag: resolutionTag,
261
+ registration,
262
+ value,
263
+ argument: injectionContext.argument,
264
+ afterResolveContext: this.getAfterResolveContext(resolutionTag, context),
265
+ chain
266
+ };
241
267
  context.resolutions.push(resolution);
242
268
  if (resolutionScoped) {
243
269
  context.resolutionScopedResolutions.setFlat(token, argumentIdentity, resolution);
@@ -293,7 +319,7 @@ class Injector {
293
319
  throw new Error("Unsupported provider.");
294
320
  }
295
321
  if ((0, import_disposable.isDisposable)(result.value) || (0, import_disposable.isAsyncDisposable)(result.value)) {
296
- this.#disposer.add(result.value);
322
+ this.#disposableStack.use(result.value);
297
323
  }
298
324
  return result.value;
299
325
  } finally {
@@ -363,9 +389,20 @@ class Injector {
363
389
  const context = {
364
390
  resolve: (token, argument, options) => this._resolve(token, argument, options ?? {}, resolveContext, chain.addToken(token)),
365
391
  resolveAll: (token, argument, options) => this._resolveAll(token, argument, options ?? {}, resolveContext, chain.addToken(token)),
366
- addDisposeHandler: (handler) => this.#disposer.add(handler),
367
- get context() {
368
- return resolveContext.resolutionContexts.get(resolutionTag);
392
+ cancellationToken: this.#disposeToken,
393
+ addDisposeHandler: this.#addDisposeHandler,
394
+ get data() {
395
+ return resolveContext.resolutionContextData.get(resolutionTag);
396
+ }
397
+ };
398
+ return context;
399
+ }
400
+ getAfterResolveContext(resolutionTag, resolveContext) {
401
+ const context = {
402
+ cancellationToken: this.#disposeToken,
403
+ addDisposeHandler: this.#addDisposeHandler,
404
+ get data() {
405
+ return resolveContext.resolutionContextData.get(resolutionTag);
369
406
  }
370
407
  };
371
408
  return context;
@@ -381,6 +418,11 @@ class Injector {
381
418
  };
382
419
  return context;
383
420
  }
421
+ assertNotDisposed() {
422
+ if (this.disposed) {
423
+ throw new Error("Injector is disposed.");
424
+ }
425
+ }
384
426
  }
385
427
  function addRegistration(registrations, registration) {
386
428
  if ((0, import_provider.isClassProvider)(registration.provider)) {
@@ -408,7 +450,7 @@ function newInternalResolveContext() {
408
450
  resolving: /* @__PURE__ */ new Set(),
409
451
  resolutionScopedResolutions: new import_multi_key_map.MultiKeyMap(),
410
452
  resolutions: [],
411
- resolutionContexts: new import_factory_map.FactoryMap(() => ({})),
453
+ resolutionContextData: new import_factory_map.FactoryMap(() => ({})),
412
454
  forwardRefQueue: new import_circular_buffer.CircularBuffer(),
413
455
  forwardRefs: /* @__PURE__ */ new Set(),
414
456
  $done: new import_deferred_promise.DeferredPromise()
@@ -421,18 +463,15 @@ function postProcess(context) {
421
463
  derefForwardRefs(context);
422
464
  for (const resolution of context.resolutions) {
423
465
  if ((0, import_type_guards.isFunction)(resolution.value?.[import_interfaces.afterResolve])) {
424
- const resolutionContext = context.resolutionContexts.get(resolution.tag);
425
- const returnValue = resolution.value[import_interfaces.afterResolve](resolution.argument, resolutionContext);
466
+ const returnValue = resolution.value[import_interfaces.afterResolve](resolution.argument, resolution.afterResolveContext);
426
467
  throwOnPromise(returnValue, "[afterResolve]", resolution.chain);
427
468
  }
428
469
  if ((0, import_provider.isProviderWithInitializer)(resolution.registration.provider)) {
429
- const resolutionContext = context.resolutionContexts.get(resolution.tag);
430
- const returnValue = resolution.registration.provider.afterResolve?.(resolution.value, resolution.argument, resolutionContext);
470
+ const returnValue = resolution.registration.provider.afterResolve?.(resolution.value, resolution.argument, resolution.afterResolveContext);
431
471
  throwOnPromise(returnValue, "provider afterResolve handler", resolution.chain);
432
472
  }
433
473
  if ((0, import_type_guards.isDefined)(resolution.registration.options.afterResolve)) {
434
- const resolutionContext = context.resolutionContexts.get(resolution.tag);
435
- const returnValue = resolution.registration.options.afterResolve(resolution.value, resolution.argument, resolutionContext);
474
+ const returnValue = resolution.registration.options.afterResolve(resolution.value, resolution.argument, resolution.afterResolveContext);
436
475
  throwOnPromise(returnValue, "registration afterResolve handler", resolution.chain);
437
476
  }
438
477
  }
@@ -444,16 +483,13 @@ async function postProcessAsync(context) {
444
483
  derefForwardRefs(context);
445
484
  for (const resolution of context.resolutions) {
446
485
  if ((0, import_type_guards.isFunction)(resolution.value?.[import_interfaces.afterResolve])) {
447
- const resolutionContext = context.resolutionContexts.get(resolution.tag);
448
- await resolution.value[import_interfaces.afterResolve](resolution.argument, resolutionContext);
486
+ await resolution.value[import_interfaces.afterResolve](resolution.argument, resolution.afterResolveContext);
449
487
  }
450
488
  if ((0, import_provider.isProviderWithInitializer)(resolution.registration.provider)) {
451
- const resolutionContext = context.resolutionContexts.get(resolution.tag);
452
- await resolution.registration.provider.afterResolve?.(resolution.value, resolution.argument, resolutionContext);
489
+ await resolution.registration.provider.afterResolve?.(resolution.value, resolution.argument, resolution.afterResolveContext);
453
490
  }
454
491
  if ((0, import_type_guards.isDefined)(resolution.registration.options.afterResolve)) {
455
- const resolutionContext = context.resolutionContexts.get(resolution.tag);
456
- await resolution.registration.options.afterResolve(resolution.value, resolution.argument, resolutionContext);
492
+ await resolution.registration.options.afterResolve(resolution.value, resolution.argument, resolution.afterResolveContext);
457
493
  }
458
494
  }
459
495
  }
@@ -1,16 +1,17 @@
1
1
  import type { Record, Type } from '../types.js';
2
2
  import type { ArgumentedInjectionToken, InjectionTokenArgument, ReifyingInjectionToken } from './token.js';
3
+ import type { AfterResolveContext } from './types.js';
3
4
  export declare const resolveArgumentType: unique symbol;
4
5
  export declare const afterResolve: unique symbol;
5
6
  export type ResolveArgumentType = typeof resolveArgumentType;
6
7
  export type ResolveArgument<T, Fallback = undefined> = undefined | (T extends Resolvable<infer U> ? U : T extends Type<Resolvable<infer U>> ? U : T extends (ArgumentedInjectionToken<any, any> | ReifyingInjectionToken) ? InjectionTokenArgument<T> : Fallback);
7
- export interface Resolvable<A = unknown, C extends Record = Record> extends Partial<AfterResolve<A, C>> {
8
+ export interface Resolvable<A = unknown, D extends Record = Record> extends Partial<AfterResolve<A, D>> {
8
9
  /**
9
10
  * type of resolve argument
10
11
  * @deprecated only used for type inference
11
12
  */
12
13
  readonly [resolveArgumentType]: A;
13
14
  }
14
- export interface AfterResolve<A = unknown, C extends Record = Record> {
15
- [afterResolve](argument: A, context: C): void | Promise<void>;
15
+ export interface AfterResolve<A = unknown, D extends Record = Record> {
16
+ [afterResolve](argument: A, context: AfterResolveContext<D>): void | Promise<void>;
16
17
  }