@tstdl/base 0.93.125 → 0.93.126
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/ai/genkit/tests/multi-region.test.js +6 -6
- package/ai/index.d.ts +2 -6
- package/ai/index.js +2 -6
- package/ai/parser/index.d.ts +1 -0
- package/ai/parser/index.js +1 -0
- package/ai/parser/parser.d.ts +12 -0
- package/ai/parser/parser.js +28 -0
- package/ai/prompts/build.d.ts +21 -0
- package/ai/prompts/build.js +25 -0
- package/ai/prompts/index.d.ts +2 -0
- package/ai/prompts/index.js +2 -0
- package/ai/prompts/instructions-formatter.d.ts +9 -22
- package/ai/prompts/instructions-formatter.js +20 -7
- package/ai/prompts/instructions.js +1 -1
- package/ai/prompts/steering.d.ts +27 -0
- package/ai/prompts/steering.js +54 -0
- package/ai/tests/instructions-formatter.test.js +115 -0
- package/ai/tests/steering.test.js +37 -0
- package/application/application.d.ts +2 -1
- package/application/application.js +3 -0
- package/authentication/client/module.d.ts +1 -1
- package/authentication/client/module.js +4 -5
- package/authentication/tests/authentication-ancillary.service.test.js +1 -1
- package/authentication/tests/authentication.api-controller.test.js +3 -1
- package/authentication/tests/authentication.api-request-token.provider.test.js +1 -1
- package/authentication/tests/authentication.client-service.test.js +1 -1
- package/authentication/tests/authentication.service.test.js +1 -1
- package/authentication/tests/subject.service.test.js +1 -1
- package/circuit-breaker/tests/circuit-breaker.test.js +1 -1
- package/document-management/api/document-management.api.d.ts +16 -16
- package/document-management/api/document-management.api.js +12 -12
- package/document-management/models/ai-configuration.d.ts +59 -0
- package/document-management/models/ai-configuration.js +1 -0
- package/document-management/models/document-assignment-scope.model.js +2 -4
- package/document-management/models/document-assignment-task.model.js +2 -4
- package/document-management/models/document-collection-assignment.model.js +2 -4
- package/document-management/models/document-collection.model.js +2 -3
- package/document-management/models/document-content.model.d.ts +6 -0
- package/document-management/models/document-content.model.js +32 -0
- package/document-management/models/document-property-value.model.js +1 -2
- package/document-management/models/document-request-collection-assignment.model.js +2 -4
- package/document-management/models/document-request.model.js +2 -4
- package/document-management/models/document-tag-assignment.model.js +2 -3
- package/document-management/models/document-validation-execution-related-document.model.js +2 -4
- package/document-management/models/document-validation-execution.model.js +2 -5
- package/document-management/models/document-workflow.model.d.ts +2 -1
- package/document-management/models/document-workflow.model.js +4 -5
- package/document-management/models/document.model.js +2 -3
- package/document-management/models/index.d.ts +2 -0
- package/document-management/models/index.js +2 -0
- package/document-management/server/api/document-management.api.d.ts +7 -7
- package/document-management/server/api/document-management.api.js +9 -9
- package/document-management/server/configure.d.ts +4 -1
- package/document-management/server/configure.js +9 -4
- package/document-management/server/drizzle/{0000_complex_black_bird.sql → 0000_curious_nighthawk.sql} +7 -27
- package/document-management/server/drizzle/meta/0000_snapshot.json +12 -284
- package/document-management/server/drizzle/meta/_journal.json +2 -2
- package/document-management/server/module.d.ts +2 -0
- package/document-management/server/module.js +1 -0
- package/document-management/server/schemas.d.ts +2 -1
- package/document-management/server/services/document-file.service.d.ts +6 -6
- package/document-management/server/services/document-file.service.js +7 -81
- package/document-management/server/services/document-management-ai-provider.service.d.ts +66 -0
- package/document-management/server/services/document-management-ai-provider.service.js +2 -0
- package/document-management/server/services/document-management-ai.service.d.ts +44 -7
- package/document-management/server/services/document-management-ai.service.js +332 -329
- package/document-management/server/services/document-validation.service.d.ts +1 -1
- package/document-management/server/services/document-workflow.service.d.ts +4 -3
- package/document-management/server/services/document-workflow.service.js +26 -9
- package/document-management/server/services/document.service.d.ts +7 -3
- package/document-management/server/services/document.service.js +13 -4
- package/document-management/server/services/index.d.ts +1 -0
- package/document-management/server/services/index.js +1 -0
- package/document-management/server/validators/ai-validation-executor.d.ts +419 -12
- package/document-management/server/validators/ai-validation-executor.js +51 -46
- package/document-management/server/validators/single-document-validation-executor.d.ts +1 -3
- package/document-management/server/validators/single-document-validation-executor.js +2 -4
- package/document-management/service-models/document.service-model.d.ts +3 -3
- package/document-management/service-models/document.service-model.js +1 -1
- package/document-management/tests/ai-config-hierarchy.test.d.ts +1 -0
- package/document-management/tests/ai-config-hierarchy.test.js +64 -0
- package/document-management/tests/ai-config-integration.test.d.ts +1 -0
- package/document-management/tests/ai-config-integration.test.js +125 -0
- package/document-management/tests/ai-config-merge.test.d.ts +1 -0
- package/document-management/tests/ai-config-merge.test.js +38 -0
- package/document-management/tests/document-management-ai-overrides.test.d.ts +1 -0
- package/document-management/tests/document-management-ai-overrides.test.js +64 -0
- package/document-management/tests/document-management-core.test.js +6 -6
- package/document-management/tests/document-management.api.test.js +5 -5
- package/document-management/tests/document-statistics.service.test.js +10 -6
- package/document-management/tests/document-validation-ai-overrides.test.d.ts +1 -0
- package/document-management/tests/document-validation-ai-overrides.test.js +85 -0
- package/document-management/tests/document.service.test.js +15 -11
- package/document-management/tests/enum-helpers.test.js +5 -5
- package/examples/document-management/ai-provider.d.ts +20 -0
- package/examples/document-management/ai-provider.js +74 -0
- package/examples/document-management/main.js +9 -6
- package/examples/injector/graph-example.d.ts +1 -0
- package/examples/injector/graph-example.js +340 -0
- package/injector/decorators.d.ts +4 -4
- package/injector/decorators.js +5 -6
- package/injector/forward-ref.d.ts +15 -0
- package/injector/forward-ref.js +20 -0
- package/injector/graph.d.ts +113 -0
- package/injector/graph.js +631 -0
- package/injector/index.d.ts +2 -0
- package/injector/index.js +2 -0
- package/injector/inject.d.ts +15 -15
- package/injector/injector.d.ts +101 -13
- package/injector/injector.js +103 -59
- package/injector/resolve-chain.d.ts +20 -6
- package/injector/resolve-chain.js +39 -14
- package/injector/tests/advanced.test.d.ts +1 -0
- package/injector/tests/advanced.test.js +116 -0
- package/injector/tests/async-init.test.d.ts +1 -0
- package/injector/tests/async-init.test.js +77 -0
- package/injector/tests/basic.test.d.ts +1 -0
- package/injector/tests/basic.test.js +114 -0
- package/injector/tests/hierarchical.test.d.ts +1 -0
- package/injector/tests/hierarchical.test.js +59 -0
- package/injector/tests/lifecycles.test.d.ts +1 -0
- package/injector/tests/lifecycles.test.js +109 -0
- package/injector/token.d.ts +2 -1
- package/injector/token.js +4 -1
- package/injector/type-info.d.ts +1 -5
- package/injector/types.d.ts +4 -10
- package/logger/tests/pretty-print.test.d.ts +1 -0
- package/logger/{formatters → tests}/pretty-print.test.js +1 -1
- package/logger/transports/console.d.ts +3 -2
- package/logger/transports/console.js +4 -3
- package/notification/tests/notification-api.test.js +8 -5
- package/notification/tests/notification-client.test.d.ts +1 -0
- package/notification/tests/{unit/notification-client.test.js → notification-client.test.js} +5 -5
- package/notification/tests/notification-flow.test.js +6 -5
- package/notification/tests/notification-sse.service.test.js +1 -1
- package/notification/tests/notification-type.service.test.js +1 -1
- package/object-storage/s3/s3.object-storage.js +3 -0
- package/object-storage/s3/tests/s3.object-storage.integration.test.js +1 -1
- package/orm/tests/repository-attributes.test.js +10 -17
- package/orm/tests/repository-cti-mapping.test.js +2 -2
- package/orm/tests/repository-cti-soft-delete.test.js +1 -1
- package/orm/tests/repository-cti.test.js +19 -33
- package/orm/tests/repository-extra-coverage.test.js +1 -1
- package/orm/tests/repository-search.test.js +5 -2
- package/orm/tests/transaction-safety.test.js +1 -1
- package/package.json +7 -9
- package/rate-limit/tests/postgres-rate-limiter.test.js +6 -16
- package/renderer/d2.d.ts +77 -0
- package/renderer/d2.js +68 -0
- package/renderer/graphviz.d.ts +47 -0
- package/renderer/graphviz.js +58 -0
- package/renderer/index.d.ts +4 -0
- package/renderer/index.js +4 -0
- package/renderer/typst.d.ts +57 -0
- package/renderer/typst.js +62 -0
- package/rpc/adapters/readable-stream.adapter.d.ts +3 -0
- package/rpc/adapters/readable-stream.adapter.js +5 -1
- package/rpc/rpc.js +28 -3
- package/rpc/tests/rpc.integration.test.js +3 -1
- package/schema/schemas/nullable.js +1 -1
- package/task-queue/task-queue.d.ts +2 -0
- package/task-queue/task-queue.js +6 -2
- package/task-queue/tests/complex.test.js +1 -1
- package/task-queue/tests/dependencies.test.js +3 -3
- package/task-queue/tests/extensive-dependencies.test.js +1 -1
- package/task-queue/tests/queue.test.js +1 -1
- package/task-queue/tests/worker.test.js +4 -7
- package/test5.js +52 -8
- package/{unit-test → testing}/integration-setup.d.ts +1 -0
- package/{unit-test → testing}/integration-setup.js +13 -0
- package/utils/base64.d.ts +7 -0
- package/utils/base64.js +10 -1
- package/utils/noop.d.ts +7 -1
- package/utils/noop.js +7 -1
- package/ai/ai-file.service.d.ts +0 -57
- package/ai/ai-file.service.js +0 -233
- package/ai/ai-session.d.ts +0 -38
- package/ai/ai-session.js +0 -50
- package/ai/ai.service.d.ts +0 -126
- package/ai/ai.service.js +0 -481
- package/ai/functions.d.ts +0 -9
- package/ai/functions.js +0 -38
- package/ai/module.d.ts +0 -26
- package/ai/module.js +0 -25
- package/ai/types.d.ts +0 -229
- package/ai/types.js +0 -33
- package/latex/index.d.ts +0 -1
- package/latex/index.js +0 -1
- package/typst/index.d.ts +0 -1
- package/typst/index.js +0 -1
- package/typst/render.d.ts +0 -23
- package/typst/render.js +0 -32
- /package/{logger/formatters/pretty-print.test.d.ts → ai/tests/instructions-formatter.test.d.ts} +0 -0
- /package/{notification/tests/unit/notification-client.test.d.ts → ai/tests/steering.test.d.ts} +0 -0
- /package/{latex/render.d.ts → renderer/latex.d.ts} +0 -0
- /package/{latex/render.js → renderer/latex.js} +0 -0
- /package/{unit-test → testing}/index.d.ts +0 -0
- /package/{unit-test → testing}/index.js +0 -0
|
@@ -1,10 +1,16 @@
|
|
|
1
1
|
import type { AbstractConstructor } from '../types/index.js';
|
|
2
|
-
import type { Injector } from './injector.js';
|
|
2
|
+
import type { Injector, Registration } from './injector.js';
|
|
3
3
|
import type { InjectionToken } from './token.js';
|
|
4
4
|
export type ResolveChainNodeBase<Type extends string> = {
|
|
5
5
|
injector: Injector;
|
|
6
|
+
resolvedBy?: Injector;
|
|
6
7
|
type: Type;
|
|
7
8
|
forwardRef?: true;
|
|
9
|
+
optional?: boolean;
|
|
10
|
+
multi?: boolean;
|
|
11
|
+
argument?: any;
|
|
12
|
+
registration?: Registration;
|
|
13
|
+
isCached?: boolean;
|
|
8
14
|
};
|
|
9
15
|
export type ResolveChainNode = {
|
|
10
16
|
type: 'ellipsis';
|
|
@@ -22,17 +28,25 @@ export type ResolveChainNode = {
|
|
|
22
28
|
property: PropertyKey;
|
|
23
29
|
token: InjectionToken;
|
|
24
30
|
};
|
|
31
|
+
export type ResolveChainNodeOptions = {
|
|
32
|
+
optional?: boolean;
|
|
33
|
+
multi?: boolean;
|
|
34
|
+
argument?: any;
|
|
35
|
+
};
|
|
25
36
|
export declare class ResolveChain {
|
|
26
37
|
readonly nodes: readonly ResolveChainNode[];
|
|
27
38
|
get length(): number;
|
|
28
39
|
/** @deprecated for internal use only */
|
|
29
40
|
constructor(nodes: ResolveChainNode[]);
|
|
30
|
-
static startWith(injector: Injector, token: InjectionToken): ResolveChain;
|
|
31
|
-
addToken(injector: Injector, token: InjectionToken): ResolveChain;
|
|
32
|
-
addInject(injector: Injector, token: InjectionToken, index: number): ResolveChain;
|
|
33
|
-
addParameter(injector: Injector, constructor: AbstractConstructor, index: number, token: InjectionToken): ResolveChain;
|
|
34
|
-
addProperty(injector: Injector, constructor: AbstractConstructor, property: PropertyKey, token: InjectionToken): ResolveChain;
|
|
41
|
+
static startWith(injector: Injector, token: InjectionToken, options?: ResolveChainNodeOptions): ResolveChain;
|
|
42
|
+
addToken(injector: Injector, token: InjectionToken, options?: ResolveChainNodeOptions): ResolveChain;
|
|
43
|
+
addInject(injector: Injector, token: InjectionToken, index: number, options?: ResolveChainNodeOptions): ResolveChain;
|
|
44
|
+
addParameter(injector: Injector, constructor: AbstractConstructor, index: number, token: InjectionToken, options?: ResolveChainNodeOptions): ResolveChain;
|
|
45
|
+
addProperty(injector: Injector, constructor: AbstractConstructor, property: PropertyKey, token: InjectionToken, options?: ResolveChainNodeOptions): ResolveChain;
|
|
35
46
|
markAsForwardRef(forwardToken: InjectionToken): ResolveChain;
|
|
47
|
+
withArgument(argument: any): ResolveChain;
|
|
48
|
+
withResolvedBy(resolvedBy: Injector): ResolveChain;
|
|
49
|
+
withMetadata(metadata: Pick<ResolveChainNodeBase<any>, 'registration' | 'isCached'>): ResolveChain;
|
|
36
50
|
format(truncate?: number): string;
|
|
37
51
|
truncate(tokenCount: number): ResolveChain;
|
|
38
52
|
}
|
|
@@ -10,24 +10,24 @@ export class ResolveChain {
|
|
|
10
10
|
constructor(nodes) {
|
|
11
11
|
this.nodes = nodes;
|
|
12
12
|
}
|
|
13
|
-
static startWith(injector, token) {
|
|
13
|
+
static startWith(injector, token, options) {
|
|
14
14
|
const chain = new ResolveChain([]);
|
|
15
|
-
return chain.addToken(injector, token);
|
|
15
|
+
return chain.addToken(injector, token, options);
|
|
16
16
|
}
|
|
17
|
-
addToken(injector, token) {
|
|
18
|
-
const node = { injector, type: 'token', token };
|
|
17
|
+
addToken(injector, token, options) {
|
|
18
|
+
const node = { injector, type: 'token', token, ...options };
|
|
19
19
|
return new ResolveChain([...this.nodes, node]);
|
|
20
20
|
}
|
|
21
|
-
addInject(injector, token, index) {
|
|
22
|
-
const node = { injector, type: 'inject', token, index };
|
|
21
|
+
addInject(injector, token, index, options) {
|
|
22
|
+
const node = { injector, type: 'inject', token, index, ...options };
|
|
23
23
|
return new ResolveChain([...this.nodes, node]);
|
|
24
24
|
}
|
|
25
|
-
addParameter(injector, constructor, index, token) {
|
|
26
|
-
const node = { injector, type: 'parameter', constructor, index, token };
|
|
25
|
+
addParameter(injector, constructor, index, token, options) {
|
|
26
|
+
const node = { injector, type: 'parameter', constructor, index, token, ...options };
|
|
27
27
|
return new ResolveChain([...this.nodes, node]);
|
|
28
28
|
}
|
|
29
|
-
addProperty(injector, constructor, property, token) {
|
|
30
|
-
const node = { injector, type: 'property', constructor, property, token };
|
|
29
|
+
addProperty(injector, constructor, property, token, options) {
|
|
30
|
+
const node = { injector, type: 'property', constructor, property, token, ...options };
|
|
31
31
|
return new ResolveChain([...this.nodes, node]);
|
|
32
32
|
}
|
|
33
33
|
markAsForwardRef(forwardToken) {
|
|
@@ -35,6 +35,30 @@ export class ResolveChain {
|
|
|
35
35
|
nodes.push({ ...nodes.pop(), token: forwardToken, forwardRef: true });
|
|
36
36
|
return new ResolveChain(nodes);
|
|
37
37
|
}
|
|
38
|
+
withArgument(argument) {
|
|
39
|
+
const nodes = [...this.nodes];
|
|
40
|
+
const lastNode = nodes.pop();
|
|
41
|
+
if (isDefined(lastNode) && (lastNode.type !== 'ellipsis')) {
|
|
42
|
+
nodes.push({ ...lastNode, argument });
|
|
43
|
+
}
|
|
44
|
+
return new ResolveChain(nodes);
|
|
45
|
+
}
|
|
46
|
+
withResolvedBy(resolvedBy) {
|
|
47
|
+
const nodes = [...this.nodes];
|
|
48
|
+
const lastNode = nodes.pop();
|
|
49
|
+
if (isDefined(lastNode) && (lastNode.type !== 'ellipsis')) {
|
|
50
|
+
nodes.push({ ...lastNode, resolvedBy });
|
|
51
|
+
}
|
|
52
|
+
return new ResolveChain(nodes);
|
|
53
|
+
}
|
|
54
|
+
withMetadata(metadata) {
|
|
55
|
+
const nodes = [...this.nodes];
|
|
56
|
+
const lastNode = nodes.pop();
|
|
57
|
+
if (isDefined(lastNode) && (lastNode.type !== 'ellipsis')) {
|
|
58
|
+
nodes.push({ ...lastNode, ...metadata });
|
|
59
|
+
}
|
|
60
|
+
return new ResolveChain(nodes);
|
|
61
|
+
}
|
|
38
62
|
format(truncate) {
|
|
39
63
|
let chainString = '';
|
|
40
64
|
const chain = isDefined(truncate) ? this.truncate(truncate) : this;
|
|
@@ -50,26 +74,27 @@ export class ResolveChain {
|
|
|
50
74
|
const paddedInjectorName = `${node.injector.name}#${node.injector.id}`.padStart(longestInjectorName);
|
|
51
75
|
const tokenName = getTokenName(node.token);
|
|
52
76
|
const forwardRefPrefix = node.forwardRef ? 'ForwardRef::' : '';
|
|
77
|
+
const resolvedBySuffix = isDefined(node.resolvedBy) && (node.resolvedBy.id != node.injector.id) ? ` (via ${node.resolvedBy.name}#${node.resolvedBy.id})` : '';
|
|
53
78
|
switch (node.type) {
|
|
54
79
|
case 'token':
|
|
55
|
-
chainString += `\n ${paddedInjectorName} -> ${forwardRefPrefix}${tokenName}`;
|
|
80
|
+
chainString += `\n ${paddedInjectorName} -> ${forwardRefPrefix}${tokenName}${resolvedBySuffix}`;
|
|
56
81
|
break;
|
|
57
82
|
case 'inject':
|
|
58
|
-
chainString += ` => inject(${forwardRefPrefix}${tokenName}) [${node.index + 1}]`;
|
|
83
|
+
chainString += ` => inject(${forwardRefPrefix}${tokenName}) [${node.index + 1}]${resolvedBySuffix}`;
|
|
59
84
|
chainString += `\n ${paddedInjectorName} -> ${tokenName}`;
|
|
60
85
|
break;
|
|
61
86
|
case 'parameter':
|
|
62
87
|
const metadata = reflectionRegistry.getMetadata(node.constructor);
|
|
63
88
|
const prefix = '_, '.repeat(node.index);
|
|
64
89
|
const suffix = ', _'.repeat(assertDefinedPass(metadata?.parameters, `missing parameters metadata for ${node.constructor.name}`).length - node.index - 1);
|
|
65
|
-
chainString += `(${prefix}${forwardRefPrefix}${tokenName}${suffix})`;
|
|
90
|
+
chainString += `(${prefix}${forwardRefPrefix}${tokenName}${suffix})${resolvedBySuffix}`;
|
|
66
91
|
// chainString += `\n ${' '.repeat(1 + node.constructor.name.length + forwardRefPrefix.length + prefix.length + (tokenName.length / 2))}↓`;
|
|
67
92
|
chainString += `\n ${paddedInjectorName} -> ${tokenName}`;
|
|
68
93
|
break;
|
|
69
94
|
case 'property':
|
|
70
95
|
const constructorName = getTokenName(node.constructor);
|
|
71
96
|
const key = getPropertyKeyString(node.property);
|
|
72
|
-
chainString += `\n ${paddedInjectorName} -> ${constructorName}[${key}]: ${forwardRefPrefix}${tokenName}`;
|
|
97
|
+
chainString += `\n ${paddedInjectorName} -> ${constructorName}[${key}]: ${forwardRefPrefix}${tokenName}${resolvedBySuffix}`;
|
|
73
98
|
break;
|
|
74
99
|
default:
|
|
75
100
|
throw new Error(`unknown chain node type ${node.type}`);
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import '../../polyfills.js';
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
2
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
3
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
4
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
5
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
6
|
+
};
|
|
7
|
+
import { describe, expect, test } from 'vitest';
|
|
8
|
+
import '../../polyfills.js';
|
|
9
|
+
import { afterResolve, forwardRef, inject, injectAll, injectArgument, Injectable, injectionToken, Injector, Singleton } from '../index.js';
|
|
10
|
+
describe('Injector Advanced', () => {
|
|
11
|
+
test('forwardRef for circular dependencies', () => {
|
|
12
|
+
let ServiceB = class ServiceB {
|
|
13
|
+
a = inject(forwardRef(() => ServiceA));
|
|
14
|
+
};
|
|
15
|
+
ServiceB = __decorate([
|
|
16
|
+
Singleton()
|
|
17
|
+
], ServiceB);
|
|
18
|
+
let ServiceA = class ServiceA {
|
|
19
|
+
b = inject(ServiceB);
|
|
20
|
+
};
|
|
21
|
+
ServiceA = __decorate([
|
|
22
|
+
Singleton()
|
|
23
|
+
], ServiceA);
|
|
24
|
+
const injector = new Injector('test');
|
|
25
|
+
const a = injector.resolve(ServiceA);
|
|
26
|
+
const b = injector.resolve(ServiceB);
|
|
27
|
+
expect(a.b).toBe(b);
|
|
28
|
+
expect(b.a).toBe(a);
|
|
29
|
+
});
|
|
30
|
+
test('multi-providers and injectAll', () => {
|
|
31
|
+
const PLUGIN = injectionToken('PLUGIN');
|
|
32
|
+
const injector = new Injector('test');
|
|
33
|
+
injector.register(PLUGIN, { useValue: 'plugin1' }, { multi: true });
|
|
34
|
+
injector.register(PLUGIN, { useValue: 'plugin2' }, { multi: true });
|
|
35
|
+
let Consumer = class Consumer {
|
|
36
|
+
plugins = injectAll(PLUGIN);
|
|
37
|
+
};
|
|
38
|
+
Consumer = __decorate([
|
|
39
|
+
Injectable()
|
|
40
|
+
], Consumer);
|
|
41
|
+
const consumer = injector.resolve(Consumer);
|
|
42
|
+
expect(consumer.plugins).toEqual(['plugin1', 'plugin2']);
|
|
43
|
+
});
|
|
44
|
+
test('resolution arguments and injectArgument', () => {
|
|
45
|
+
let Target = class Target {
|
|
46
|
+
arg = injectArgument();
|
|
47
|
+
};
|
|
48
|
+
Target = __decorate([
|
|
49
|
+
Injectable()
|
|
50
|
+
], Target);
|
|
51
|
+
const injector = new Injector('test');
|
|
52
|
+
const instance = injector.resolve(Target, { value: 'test-arg' });
|
|
53
|
+
expect(instance.arg.value).toBe('test-arg');
|
|
54
|
+
});
|
|
55
|
+
test('optional dependencies', () => {
|
|
56
|
+
const MISSING = injectionToken('MISSING');
|
|
57
|
+
let Consumer = class Consumer {
|
|
58
|
+
missing = inject(MISSING, undefined, { optional: true });
|
|
59
|
+
};
|
|
60
|
+
Consumer = __decorate([
|
|
61
|
+
Injectable()
|
|
62
|
+
], Consumer);
|
|
63
|
+
const injector = new Injector('test');
|
|
64
|
+
const consumer = injector.resolve(Consumer);
|
|
65
|
+
expect(consumer.missing).toBeUndefined();
|
|
66
|
+
});
|
|
67
|
+
test('automatic cleanup on injector disposal', async () => {
|
|
68
|
+
let disposed = false;
|
|
69
|
+
let DisposableService = class DisposableService {
|
|
70
|
+
async [Symbol.asyncDispose]() {
|
|
71
|
+
disposed = true;
|
|
72
|
+
}
|
|
73
|
+
};
|
|
74
|
+
DisposableService = __decorate([
|
|
75
|
+
Singleton()
|
|
76
|
+
], DisposableService);
|
|
77
|
+
const injector = new Injector('test');
|
|
78
|
+
injector.resolve(DisposableService);
|
|
79
|
+
expect(disposed).toBe(false);
|
|
80
|
+
await injector.dispose();
|
|
81
|
+
expect(disposed).toBe(true);
|
|
82
|
+
});
|
|
83
|
+
test('addDisposeHandler in afterResolve', async () => {
|
|
84
|
+
let disposed = false;
|
|
85
|
+
let ManualService = class ManualService {
|
|
86
|
+
async [afterResolve](_arg, { addDisposeHandler }) {
|
|
87
|
+
addDisposeHandler(() => { disposed = true; });
|
|
88
|
+
}
|
|
89
|
+
};
|
|
90
|
+
ManualService = __decorate([
|
|
91
|
+
Singleton()
|
|
92
|
+
], ManualService);
|
|
93
|
+
const injector = new Injector('test');
|
|
94
|
+
await injector.resolveAsync(ManualService);
|
|
95
|
+
expect(disposed).toBe(false);
|
|
96
|
+
await injector.dispose();
|
|
97
|
+
expect(disposed).toBe(true);
|
|
98
|
+
});
|
|
99
|
+
test('factory using inject', () => {
|
|
100
|
+
const VAL = injectionToken('VAL');
|
|
101
|
+
let Dep = class Dep {
|
|
102
|
+
value = 42;
|
|
103
|
+
};
|
|
104
|
+
Dep = __decorate([
|
|
105
|
+
Singleton()
|
|
106
|
+
], Dep);
|
|
107
|
+
const injector = new Injector('test');
|
|
108
|
+
injector.register(VAL, {
|
|
109
|
+
useFactory: () => {
|
|
110
|
+
const dep = inject(Dep);
|
|
111
|
+
return dep.value * 2;
|
|
112
|
+
}
|
|
113
|
+
});
|
|
114
|
+
expect(injector.resolve(VAL)).toBe(84);
|
|
115
|
+
});
|
|
116
|
+
});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import '../../polyfills.js';
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
2
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
3
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
4
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
5
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
6
|
+
};
|
|
7
|
+
import { describe, expect, test } from 'vitest';
|
|
8
|
+
import '../../polyfills.js';
|
|
9
|
+
import { afterResolve, inject, Injector, runInInjectionContext, Singleton, injectAsync } from '../index.js';
|
|
10
|
+
describe('Injector Async Initialization', () => {
|
|
11
|
+
test('should call [afterResolve] and wait for it with resolveAsync', async () => {
|
|
12
|
+
let AsyncService = class AsyncService {
|
|
13
|
+
initialized = false;
|
|
14
|
+
async [afterResolve]() {
|
|
15
|
+
await new Promise((resolve) => setTimeout(resolve, 10));
|
|
16
|
+
this.initialized = true;
|
|
17
|
+
}
|
|
18
|
+
};
|
|
19
|
+
AsyncService = __decorate([
|
|
20
|
+
Singleton()
|
|
21
|
+
], AsyncService);
|
|
22
|
+
const injector = new Injector('test');
|
|
23
|
+
const instance = await injector.resolveAsync(AsyncService);
|
|
24
|
+
expect(instance.initialized).toBe(true);
|
|
25
|
+
});
|
|
26
|
+
test('should use injectAsync in [afterResolve] to await dependency', async () => {
|
|
27
|
+
let Dependency = class Dependency {
|
|
28
|
+
initialized = false;
|
|
29
|
+
async [afterResolve]() {
|
|
30
|
+
await new Promise((resolve) => setTimeout(resolve, 10));
|
|
31
|
+
this.initialized = true;
|
|
32
|
+
}
|
|
33
|
+
};
|
|
34
|
+
Dependency = __decorate([
|
|
35
|
+
Singleton()
|
|
36
|
+
], Dependency);
|
|
37
|
+
let Consumer = class Consumer {
|
|
38
|
+
dependency;
|
|
39
|
+
async [afterResolve]() {
|
|
40
|
+
this.dependency = await injectAsync(Dependency);
|
|
41
|
+
}
|
|
42
|
+
};
|
|
43
|
+
Consumer = __decorate([
|
|
44
|
+
Singleton()
|
|
45
|
+
], Consumer);
|
|
46
|
+
const injector = new Injector('test');
|
|
47
|
+
const consumer = await runInInjectionContext(injector, () => injector.resolveAsync(Consumer));
|
|
48
|
+
expect(consumer.dependency?.initialized).toBe(true);
|
|
49
|
+
});
|
|
50
|
+
test('should support multiple async dependencies', async () => {
|
|
51
|
+
let Dep1 = class Dep1 {
|
|
52
|
+
done = false;
|
|
53
|
+
async [afterResolve]() { this.done = true; }
|
|
54
|
+
};
|
|
55
|
+
Dep1 = __decorate([
|
|
56
|
+
Singleton()
|
|
57
|
+
], Dep1);
|
|
58
|
+
let Dep2 = class Dep2 {
|
|
59
|
+
done = false;
|
|
60
|
+
async [afterResolve]() { this.done = true; }
|
|
61
|
+
};
|
|
62
|
+
Dep2 = __decorate([
|
|
63
|
+
Singleton()
|
|
64
|
+
], Dep2);
|
|
65
|
+
let Consumer = class Consumer {
|
|
66
|
+
d1 = inject(Dep1);
|
|
67
|
+
d2 = inject(Dep2);
|
|
68
|
+
};
|
|
69
|
+
Consumer = __decorate([
|
|
70
|
+
Singleton()
|
|
71
|
+
], Consumer);
|
|
72
|
+
const injector = new Injector('test');
|
|
73
|
+
const consumer = await injector.resolveAsync(Consumer);
|
|
74
|
+
expect(consumer.d1.done).toBe(true);
|
|
75
|
+
expect(consumer.d2.done).toBe(true);
|
|
76
|
+
});
|
|
77
|
+
});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import '../../polyfills.js';
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
2
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
3
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
4
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
5
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
6
|
+
};
|
|
7
|
+
import { describe, expect, test } from 'vitest';
|
|
8
|
+
import '../../polyfills.js';
|
|
9
|
+
import { inject, Inject, Injectable, injectionToken, Injector, Singleton } from '../index.js';
|
|
10
|
+
describe('Injector Basic', () => {
|
|
11
|
+
test('should resolve a singleton class', () => {
|
|
12
|
+
let TestService = class TestService {
|
|
13
|
+
id = Math.random();
|
|
14
|
+
};
|
|
15
|
+
TestService = __decorate([
|
|
16
|
+
Singleton()
|
|
17
|
+
], TestService);
|
|
18
|
+
const injector = new Injector('test');
|
|
19
|
+
const instance1 = injector.resolve(TestService);
|
|
20
|
+
const instance2 = injector.resolve(TestService);
|
|
21
|
+
expect(instance1).toBeInstanceOf(TestService);
|
|
22
|
+
expect(instance1.id).toBe(instance2.id);
|
|
23
|
+
});
|
|
24
|
+
test('should resolve a transient class', () => {
|
|
25
|
+
let TestService = class TestService {
|
|
26
|
+
id = Math.random();
|
|
27
|
+
};
|
|
28
|
+
TestService = __decorate([
|
|
29
|
+
Injectable()
|
|
30
|
+
], TestService);
|
|
31
|
+
const injector = new Injector('test');
|
|
32
|
+
const instance1 = injector.resolve(TestService);
|
|
33
|
+
const instance2 = injector.resolve(TestService);
|
|
34
|
+
expect(instance1).toBeInstanceOf(TestService);
|
|
35
|
+
expect(instance1.id).not.toBe(instance2.id);
|
|
36
|
+
});
|
|
37
|
+
test('should use property injection with inject()', () => {
|
|
38
|
+
let Dependency = class Dependency {
|
|
39
|
+
value = 'dependency';
|
|
40
|
+
};
|
|
41
|
+
Dependency = __decorate([
|
|
42
|
+
Singleton()
|
|
43
|
+
], Dependency);
|
|
44
|
+
let Consumer = class Consumer {
|
|
45
|
+
dependency = inject(Dependency);
|
|
46
|
+
};
|
|
47
|
+
Consumer = __decorate([
|
|
48
|
+
Singleton()
|
|
49
|
+
], Consumer);
|
|
50
|
+
const injector = new Injector('test');
|
|
51
|
+
const consumer = injector.resolve(Consumer);
|
|
52
|
+
expect(consumer.dependency).toBeInstanceOf(Dependency);
|
|
53
|
+
expect(consumer.dependency.value).toBe('dependency');
|
|
54
|
+
});
|
|
55
|
+
test('should support manual registration with useValue', () => {
|
|
56
|
+
const TOKEN = injectionToken('TOKEN');
|
|
57
|
+
const injector = new Injector('test');
|
|
58
|
+
injector.register(TOKEN, { useValue: 'manual-value' });
|
|
59
|
+
const value = injector.resolve(TOKEN);
|
|
60
|
+
expect(value).toBe('manual-value');
|
|
61
|
+
});
|
|
62
|
+
test('should support manual registration with useClass', () => {
|
|
63
|
+
class AbstractService {
|
|
64
|
+
}
|
|
65
|
+
let Implementation = class Implementation extends AbstractService {
|
|
66
|
+
getValue() { return 'impl'; }
|
|
67
|
+
};
|
|
68
|
+
Implementation = __decorate([
|
|
69
|
+
Injectable()
|
|
70
|
+
], Implementation);
|
|
71
|
+
const injector = new Injector('test');
|
|
72
|
+
injector.register(AbstractService, { useClass: Implementation });
|
|
73
|
+
const instance = injector.resolve(AbstractService);
|
|
74
|
+
expect(instance).toBeInstanceOf(Implementation);
|
|
75
|
+
expect(instance.getValue()).toBe('impl');
|
|
76
|
+
});
|
|
77
|
+
test('should support manual registration with useFactory', () => {
|
|
78
|
+
const TOKEN = injectionToken('TOKEN');
|
|
79
|
+
const injector = new Injector('test');
|
|
80
|
+
let counter = 0;
|
|
81
|
+
injector.register(TOKEN, { useFactory: () => ++counter });
|
|
82
|
+
expect(injector.resolve(TOKEN)).toBe(1);
|
|
83
|
+
expect(injector.resolve(TOKEN)).toBe(2);
|
|
84
|
+
});
|
|
85
|
+
test('should support global registration', () => {
|
|
86
|
+
const GLOBAL_TOKEN = injectionToken('GLOBAL_TOKEN');
|
|
87
|
+
Injector.register(GLOBAL_TOKEN, { useValue: 'global' });
|
|
88
|
+
const injector = new Injector('test');
|
|
89
|
+
expect(injector.resolve(GLOBAL_TOKEN)).toBe('global');
|
|
90
|
+
});
|
|
91
|
+
test('should support nested dependency injection', () => {
|
|
92
|
+
let Level3 = class Level3 {
|
|
93
|
+
value = 'l3';
|
|
94
|
+
};
|
|
95
|
+
Level3 = __decorate([
|
|
96
|
+
Singleton()
|
|
97
|
+
], Level3);
|
|
98
|
+
let Level2 = class Level2 {
|
|
99
|
+
l3 = inject(Level3);
|
|
100
|
+
};
|
|
101
|
+
Level2 = __decorate([
|
|
102
|
+
Singleton()
|
|
103
|
+
], Level2);
|
|
104
|
+
let Level1 = class Level1 {
|
|
105
|
+
l2 = inject(Level2);
|
|
106
|
+
};
|
|
107
|
+
Level1 = __decorate([
|
|
108
|
+
Singleton()
|
|
109
|
+
], Level1);
|
|
110
|
+
const injector = new Injector('test');
|
|
111
|
+
const l1 = injector.resolve(Level1);
|
|
112
|
+
expect(l1.l2.l3.value).toBe('l3');
|
|
113
|
+
});
|
|
114
|
+
});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import '../../polyfills.js';
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
2
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
3
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
4
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
5
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
6
|
+
};
|
|
7
|
+
import { describe, expect, test } from 'vitest';
|
|
8
|
+
import '../../polyfills.js';
|
|
9
|
+
import { Injectable, injectionToken, Injector, Singleton } from '../index.js';
|
|
10
|
+
describe('Injector Hierarchical', () => {
|
|
11
|
+
test('child should resolve from parent', () => {
|
|
12
|
+
const TOKEN = injectionToken('TOKEN');
|
|
13
|
+
const parent = new Injector('parent');
|
|
14
|
+
parent.register(TOKEN, { useValue: 'parent-value' });
|
|
15
|
+
const child = parent.fork('child');
|
|
16
|
+
expect(child.resolve(TOKEN)).toBe('parent-value');
|
|
17
|
+
});
|
|
18
|
+
test('child should override parent provider', () => {
|
|
19
|
+
const TOKEN = injectionToken('TOKEN');
|
|
20
|
+
const parent = new Injector('parent');
|
|
21
|
+
parent.register(TOKEN, { useValue: 'parent-value' });
|
|
22
|
+
const child = parent.fork('child');
|
|
23
|
+
child.register(TOKEN, { useValue: 'child-value' });
|
|
24
|
+
expect(child.resolve(TOKEN)).toBe('child-value');
|
|
25
|
+
expect(parent.resolve(TOKEN)).toBe('parent-value');
|
|
26
|
+
});
|
|
27
|
+
test('onlySelf should not resolve from parent', () => {
|
|
28
|
+
const TOKEN = injectionToken('TOKEN');
|
|
29
|
+
const parent = new Injector('parent');
|
|
30
|
+
parent.register(TOKEN, { useValue: 'parent-value' });
|
|
31
|
+
const child = parent.fork('child');
|
|
32
|
+
expect(() => child.resolve(TOKEN, undefined, { onlySelf: true })).toThrow(/No provider for .*TOKEN.* registered\./);
|
|
33
|
+
});
|
|
34
|
+
test('skipSelf should skip child and resolve from parent', () => {
|
|
35
|
+
const TOKEN = injectionToken('TOKEN');
|
|
36
|
+
const parent = new Injector('parent');
|
|
37
|
+
parent.register(TOKEN, { useValue: 'parent-value' });
|
|
38
|
+
const child = parent.fork('child');
|
|
39
|
+
child.register(TOKEN, { useValue: 'child-value' });
|
|
40
|
+
expect(child.resolve(TOKEN, undefined, { skipSelf: true })).toBe('parent-value');
|
|
41
|
+
});
|
|
42
|
+
test('injector scoped service should be unique per child', () => {
|
|
43
|
+
let ScopedService = class ScopedService {
|
|
44
|
+
id = Math.random();
|
|
45
|
+
};
|
|
46
|
+
ScopedService = __decorate([
|
|
47
|
+
Injectable()
|
|
48
|
+
], ScopedService);
|
|
49
|
+
const parent = new Injector('parent');
|
|
50
|
+
parent.register(ScopedService, { useClass: ScopedService }, { lifecycle: 'injector' });
|
|
51
|
+
const child1 = parent.fork('child1');
|
|
52
|
+
const child2 = parent.fork('child2');
|
|
53
|
+
const s1 = child1.resolve(ScopedService);
|
|
54
|
+
const s2 = child1.resolve(ScopedService);
|
|
55
|
+
const s3 = child2.resolve(ScopedService);
|
|
56
|
+
expect(s1.id).toBe(s2.id);
|
|
57
|
+
expect(s1.id).not.toBe(s3.id);
|
|
58
|
+
});
|
|
59
|
+
});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import '../../polyfills.js';
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
2
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
3
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
4
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
5
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
6
|
+
};
|
|
7
|
+
import '../../polyfills.js';
|
|
8
|
+
import { describe, expect, test } from 'vitest';
|
|
9
|
+
import { inject, Injectable, Injector, Scoped, Singleton } from '../index.js';
|
|
10
|
+
describe('Injector Lifecycles', () => {
|
|
11
|
+
test('transient lifecycle', () => {
|
|
12
|
+
let TransientService = class TransientService {
|
|
13
|
+
id = Math.random();
|
|
14
|
+
};
|
|
15
|
+
TransientService = __decorate([
|
|
16
|
+
Injectable()
|
|
17
|
+
], TransientService);
|
|
18
|
+
const injector = new Injector('test');
|
|
19
|
+
const instance1 = injector.resolve(TransientService);
|
|
20
|
+
const instance2 = injector.resolve(TransientService);
|
|
21
|
+
expect(instance1.id).not.toBe(instance2.id);
|
|
22
|
+
});
|
|
23
|
+
test('singleton lifecycle', () => {
|
|
24
|
+
let SingletonService = class SingletonService {
|
|
25
|
+
id = Math.random();
|
|
26
|
+
};
|
|
27
|
+
SingletonService = __decorate([
|
|
28
|
+
Singleton()
|
|
29
|
+
], SingletonService);
|
|
30
|
+
const injector = new Injector('test');
|
|
31
|
+
const instance1 = injector.resolve(SingletonService);
|
|
32
|
+
const instance2 = injector.resolve(SingletonService);
|
|
33
|
+
expect(instance1.id).toBe(instance2.id);
|
|
34
|
+
const child = injector.fork('child');
|
|
35
|
+
const instance3 = child.resolve(SingletonService);
|
|
36
|
+
expect(instance3.id).toBe(instance1.id);
|
|
37
|
+
});
|
|
38
|
+
test('injector lifecycle', () => {
|
|
39
|
+
let InjectorScopedService = class InjectorScopedService {
|
|
40
|
+
id = Math.random();
|
|
41
|
+
};
|
|
42
|
+
InjectorScopedService = __decorate([
|
|
43
|
+
Scoped('injector')
|
|
44
|
+
], InjectorScopedService);
|
|
45
|
+
const injector = new Injector('test');
|
|
46
|
+
const instance1 = injector.resolve(InjectorScopedService);
|
|
47
|
+
const instance2 = injector.resolve(InjectorScopedService);
|
|
48
|
+
expect(instance1.id).toBe(instance2.id);
|
|
49
|
+
const child = injector.fork('child');
|
|
50
|
+
const instance3 = child.resolve(InjectorScopedService);
|
|
51
|
+
expect(instance3.id).not.toBe(instance1.id);
|
|
52
|
+
const instance4 = child.resolve(InjectorScopedService);
|
|
53
|
+
expect(instance4.id).toBe(instance3.id);
|
|
54
|
+
});
|
|
55
|
+
test('resolution lifecycle', () => {
|
|
56
|
+
let ResolutionScopedService = class ResolutionScopedService {
|
|
57
|
+
id = Math.random();
|
|
58
|
+
};
|
|
59
|
+
ResolutionScopedService = __decorate([
|
|
60
|
+
Scoped('resolution')
|
|
61
|
+
], ResolutionScopedService);
|
|
62
|
+
let Consumer = class Consumer {
|
|
63
|
+
service1 = inject(ResolutionScopedService);
|
|
64
|
+
service2 = inject(ResolutionScopedService);
|
|
65
|
+
};
|
|
66
|
+
Consumer = __decorate([
|
|
67
|
+
Injectable()
|
|
68
|
+
], Consumer);
|
|
69
|
+
const injector = new Injector('test');
|
|
70
|
+
// Inside one .resolve() call, it should be the same instance
|
|
71
|
+
const consumer = injector.resolve(Consumer);
|
|
72
|
+
expect(consumer.service1.id).toBe(consumer.service2.id);
|
|
73
|
+
// Across different .resolve() calls, it should be different
|
|
74
|
+
const consumer2 = injector.resolve(Consumer);
|
|
75
|
+
expect(consumer2.service1.id).not.toBe(consumer.service1.id);
|
|
76
|
+
});
|
|
77
|
+
test('nested resolution lifecycle', () => {
|
|
78
|
+
let Shared = class Shared {
|
|
79
|
+
id = Math.random();
|
|
80
|
+
};
|
|
81
|
+
Shared = __decorate([
|
|
82
|
+
Scoped('resolution')
|
|
83
|
+
], Shared);
|
|
84
|
+
let Dep1 = class Dep1 {
|
|
85
|
+
shared = inject(Shared);
|
|
86
|
+
};
|
|
87
|
+
Dep1 = __decorate([
|
|
88
|
+
Injectable()
|
|
89
|
+
], Dep1);
|
|
90
|
+
let Dep2 = class Dep2 {
|
|
91
|
+
shared = inject(Shared);
|
|
92
|
+
};
|
|
93
|
+
Dep2 = __decorate([
|
|
94
|
+
Injectable()
|
|
95
|
+
], Dep2);
|
|
96
|
+
let Root = class Root {
|
|
97
|
+
dep1 = inject(Dep1);
|
|
98
|
+
dep2 = inject(Dep2);
|
|
99
|
+
shared = inject(Shared);
|
|
100
|
+
};
|
|
101
|
+
Root = __decorate([
|
|
102
|
+
Injectable()
|
|
103
|
+
], Root);
|
|
104
|
+
const injector = new Injector('test');
|
|
105
|
+
const root = injector.resolve(Root);
|
|
106
|
+
expect(root.shared.id).toBe(root.dep1.shared.id);
|
|
107
|
+
expect(root.shared.id).toBe(root.dep2.shared.id);
|
|
108
|
+
});
|
|
109
|
+
});
|
package/injector/token.d.ts
CHANGED
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
import type { AbstractConstructor } from '../types/index.js';
|
|
2
|
+
import { ForwardRefToken } from './forward-ref.js';
|
|
2
3
|
declare const type: unique symbol;
|
|
3
4
|
declare const argument: unique symbol;
|
|
4
5
|
export type SimpleInjectionToken<T> = AbstractConstructor<T>;
|
|
5
6
|
export type ArgumentedInjectionToken<T, A> = SimpleInjectionToken<T> & {
|
|
6
7
|
[argument]: A;
|
|
7
8
|
};
|
|
8
|
-
export type InjectionToken<T = any, A = any> = SimpleInjectionToken<T> | ArgumentedInjectionToken<T, A> | ReifyingInjectionToken<T, A>;
|
|
9
|
+
export type InjectionToken<T = any, A = any> = SimpleInjectionToken<T> | ArgumentedInjectionToken<T, A> | ReifyingInjectionToken<T, A> | ForwardRefToken<T, A>;
|
|
9
10
|
export type InjectionTokenArgument<T extends ArgumentedInjectionToken<any, any> | ReifyingInjectionToken> = T[typeof argument];
|
|
10
11
|
export declare class ReifyingInjectionToken<T = any, A = any> {
|
|
11
12
|
/**
|
package/injector/token.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { isFunction } from '../utils/type-guards.js';
|
|
2
|
+
import { ForwardRefToken } from './forward-ref.js';
|
|
2
3
|
export class ReifyingInjectionToken {
|
|
3
4
|
description;
|
|
4
5
|
constructor(description) {
|
|
@@ -23,5 +24,7 @@ export function getTokenName(token) {
|
|
|
23
24
|
? token.name
|
|
24
25
|
: token instanceof ReifyingInjectionToken
|
|
25
26
|
? token.toString()
|
|
26
|
-
:
|
|
27
|
+
: token instanceof ForwardRefToken
|
|
28
|
+
? `ForwardRef[${getTokenName(token.tokenFactory())}]`
|
|
29
|
+
: String(token);
|
|
27
30
|
}
|