@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.
- package/application/application.js +0 -1
- package/browser/browser-context-controller.d.ts +2 -2
- package/browser/browser-context-controller.js +6 -7
- package/browser/browser-controller.js +6 -7
- package/core.d.ts +2 -4
- package/core.js +2 -9
- package/database/mongo/module.js +8 -8
- package/disposable/async-disposer.d.ts +8 -7
- package/disposable/async-disposer.js +49 -23
- package/disposable/disposable.d.ts +5 -4
- package/disposable/disposable.js +9 -5
- package/injector/injector.d.ts +5 -2
- package/injector/injector.js +59 -23
- package/injector/interfaces.d.ts +4 -3
- package/injector/provider.d.ts +12 -12
- package/injector/resolve.error.d.ts +1 -1
- package/injector/types.d.ts +16 -7
- package/logger/console/logger.js +2 -2
- package/module/modules/web-server.module.js +0 -2
- package/object-storage/object-storage-provider.d.ts +1 -1
- package/object-storage/s3/s3.object-storage-provider.d.ts +1 -6
- package/object-storage/s3/s3.object-storage-provider.js +2 -12
- package/object-storage/s3/s3.object-storage.js +4 -1
- package/package.json +7 -6
- package/polyfills.d.ts +159 -0
- package/polyfills.js +2 -0
- package/queue/mongo/mongo-job.repository.js +3 -4
- package/search-index/elastic/module.js +4 -4
- package/tsconfig.json +1 -1
- package/utils/cancellation-token.d.ts +19 -17
- package/utils/cancellation-token.js +20 -19
- package/_container/container.d.ts +0 -99
- package/_container/container.js +0 -443
- package/_container/decorators.d.ts +0 -76
- package/_container/decorators.js +0 -110
- package/_container/index.d.ts +0 -10
- package/_container/index.js +0 -27
- package/_container/interfaces.d.ts +0 -16
- package/_container/interfaces.js +0 -26
- package/_container/provider.d.ts +0 -35
- package/_container/provider.js +0 -60
- package/_container/resolve-chain.d.ts +0 -27
- package/_container/resolve-chain.js +0 -105
- package/_container/resolve.error.d.ts +0 -5
- package/_container/resolve.error.js +0 -36
- package/_container/token.d.ts +0 -18
- package/_container/token.js +0 -41
- package/_container/type-info.d.ts +0 -18
- package/_container/type-info.js +0 -16
- package/_container/types.d.ts +0 -9
- package/_container/types.js +0 -16
- package/_container/utils.d.ts +0 -3
- package/_container/utils.js +0 -44
- package/global-this.d.ts +0 -1
- 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 {
|
|
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 =
|
|
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
|
-
|
|
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 =
|
|
97
|
+
BrowserContextController = __decorate([
|
|
99
98
|
(0, import_decorators.Injectable)({
|
|
100
99
|
provider: {
|
|
101
100
|
useFactory: (_, context) => {
|
|
102
|
-
context.
|
|
103
|
-
return new
|
|
101
|
+
context.data.browserController = context.resolve(import_browser_controller.BrowserController);
|
|
102
|
+
return new BrowserContextController(null);
|
|
104
103
|
},
|
|
105
|
-
async afterResolve(value, argument,
|
|
106
|
-
const { context: browserContext, controllerOptions } = await
|
|
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
|
-
|
|
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 =
|
|
105
|
+
BrowserController = __decorate([
|
|
107
106
|
(0, import_decorators.Injectable)({
|
|
108
107
|
provider: {
|
|
109
108
|
useFactory: (_argument, context) => {
|
|
110
|
-
context.
|
|
111
|
-
return new
|
|
109
|
+
context.data.browserService = (0, import_inject.inject)(import_browser_service.BrowserService);
|
|
110
|
+
return new BrowserController(null);
|
|
112
111
|
},
|
|
113
|
-
async afterResolve(value, argument,
|
|
114
|
-
const { browser, controllerOptions } = await
|
|
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 &&
|
|
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) {
|
package/database/mongo/module.js
CHANGED
|
@@ -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.
|
|
49
|
-
context.
|
|
48
|
+
context.data.logger = logger;
|
|
49
|
+
context.data.url = url;
|
|
50
50
|
return client;
|
|
51
51
|
},
|
|
52
|
-
async afterResolve(client, _argument,
|
|
53
|
-
await (0, import_core.connect)(`mongo at ${
|
|
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.
|
|
74
|
+
context.data.database = database;
|
|
75
75
|
return database.collection(config.collection);
|
|
76
76
|
},
|
|
77
|
-
async afterResolve(_, config,
|
|
78
|
-
const existingCollections = await
|
|
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
|
|
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
|
|
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
|
-
[
|
|
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
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
30
|
+
#disposingToken;
|
|
31
|
+
#disposedToken;
|
|
32
|
+
#deferrers;
|
|
33
|
+
#tasks;
|
|
34
34
|
get disposingToken() {
|
|
35
|
-
return this
|
|
35
|
+
return this.#disposingToken;
|
|
36
36
|
}
|
|
37
37
|
get disposedToken() {
|
|
38
|
-
return this
|
|
38
|
+
return this.#disposedToken;
|
|
39
39
|
}
|
|
40
40
|
get disposing() {
|
|
41
|
-
return this.
|
|
41
|
+
return this.#disposingToken.isSet;
|
|
42
42
|
}
|
|
43
43
|
get disposed() {
|
|
44
|
-
return this.
|
|
44
|
+
return this.#disposedToken.isSet;
|
|
45
45
|
}
|
|
46
|
+
[Symbol.toStringTag] = "AsyncDisposable";
|
|
46
47
|
constructor() {
|
|
47
|
-
this
|
|
48
|
-
this
|
|
49
|
-
this
|
|
50
|
-
this
|
|
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
|
|
79
|
+
this.#deferrers.delete(deferrer);
|
|
58
80
|
}
|
|
59
81
|
};
|
|
60
|
-
this
|
|
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
|
|
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
|
|
107
|
+
return this.#disposedToken.$set;
|
|
83
108
|
}
|
|
84
|
-
this.
|
|
109
|
+
this.#disposingToken.set();
|
|
85
110
|
const errors = [];
|
|
86
|
-
for (const deferrer of this
|
|
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
|
|
118
|
+
for (let i = this.#tasks.length - 1; i >= 0; i--) {
|
|
94
119
|
try {
|
|
95
|
-
const task = this
|
|
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.
|
|
128
|
+
this.#disposedToken.error(error);
|
|
104
129
|
throw error;
|
|
105
130
|
}
|
|
106
|
-
this.
|
|
131
|
+
this.#disposedToken.set();
|
|
132
|
+
return void 0;
|
|
107
133
|
}
|
|
108
|
-
async [
|
|
134
|
+
async [Symbol.asyncDispose]() {
|
|
109
135
|
return this.dispose();
|
|
110
136
|
}
|
|
111
137
|
}
|
|
@@ -1,10 +1,11 @@
|
|
|
1
|
-
export declare const dispose:
|
|
2
|
-
export declare const disposeAsync:
|
|
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
|
-
[
|
|
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;
|
package/disposable/disposable.js
CHANGED
|
@@ -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
|
|
29
|
-
const disposeAsync = Symbol
|
|
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?.[
|
|
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
|
}
|
package/injector/injector.d.ts
CHANGED
|
@@ -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
|
-
[
|
|
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
|
}
|
package/injector/injector.js
CHANGED
|
@@ -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
|
-
#
|
|
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
|
-
|
|
96
|
+
this.#disposeToken.set();
|
|
97
|
+
await this.#disposableStack.disposeAsync();
|
|
82
98
|
}
|
|
83
|
-
async [
|
|
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.#
|
|
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 = {
|
|
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.#
|
|
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
|
-
|
|
367
|
-
|
|
368
|
-
|
|
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
|
-
|
|
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
|
|
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
|
|
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
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
}
|
package/injector/interfaces.d.ts
CHANGED
|
@@ -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,
|
|
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,
|
|
15
|
-
[afterResolve](argument: A, context:
|
|
15
|
+
export interface AfterResolve<A = unknown, D extends Record = Record> {
|
|
16
|
+
[afterResolve](argument: A, context: AfterResolveContext<D>): void | Promise<void>;
|
|
16
17
|
}
|