@codefast/di 0.3.16-canary.3 → 0.4.0-canary.4
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/CHANGELOG.md +8 -0
- package/README.md +5 -17
- package/dist/container.d.mts +3 -3
- package/dist/container.mjs +7 -7
- package/dist/decorators/inject.mjs +2 -2
- package/dist/decorators/lifecycle-decorators.mjs +2 -2
- package/dist/dependency-graph.d.mts +1 -1
- package/dist/index.d.mts +3 -3
- package/dist/index.mjs +1 -1
- package/dist/module.mjs +1 -1
- package/dist/resolver.d.mts +1 -1
- package/package.json +8 -8
- package/src/binding-select.ts +4 -13
- package/src/binding.ts +3 -7
- package/src/constraints.ts +16 -44
- package/src/container.ts +63 -141
- package/src/decorators/inject.ts +11 -22
- package/src/decorators/injectable.ts +2 -2
- package/src/decorators/lifecycle-decorators.ts +4 -8
- package/src/dependency-graph.ts +3 -3
- package/src/environment.ts +9 -34
- package/src/errors.ts +1 -3
- package/src/inspector.ts +9 -17
- package/src/lifecycle.ts +9 -30
- package/src/metadata/metadata-reader-token.ts +1 -1
- package/src/metadata/metadata-types.ts +3 -5
- package/src/metadata/symbol-metadata-reader.ts +4 -16
- package/src/module.ts +2 -2
- package/src/registry.ts +5 -14
- package/src/resolver.ts +76 -304
- package/src/scope.ts +1 -1
- package/src/types.ts +7 -29
package/src/inspector.ts
CHANGED
|
@@ -1,4 +1,10 @@
|
|
|
1
1
|
import type { Binding } from "#/binding";
|
|
2
|
+
import { effectiveBindingScope } from "#/binding-scope";
|
|
3
|
+
import { selectBinding } from "#/binding-select";
|
|
4
|
+
import type { BindingRegistry } from "#/registry";
|
|
5
|
+
import type { ScopeManager } from "#/scope";
|
|
6
|
+
import type { Token } from "#/token";
|
|
7
|
+
import { tokenName } from "#/token";
|
|
2
8
|
import type {
|
|
3
9
|
BindingIdentifier,
|
|
4
10
|
BindingKind,
|
|
@@ -8,12 +14,6 @@ import type {
|
|
|
8
14
|
Constructor,
|
|
9
15
|
ResolveOptions,
|
|
10
16
|
} from "#/types";
|
|
11
|
-
import type { Token } from "#/token";
|
|
12
|
-
import type { BindingRegistry } from "#/registry";
|
|
13
|
-
import type { ScopeManager } from "#/scope";
|
|
14
|
-
import { tokenName } from "#/token";
|
|
15
|
-
import { selectBinding } from "#/binding-select";
|
|
16
|
-
import { effectiveBindingScope } from "#/binding-scope";
|
|
17
17
|
|
|
18
18
|
// ── Public types ──────────────────────────────────────────────────────────────
|
|
19
19
|
|
|
@@ -69,17 +69,11 @@ export class Inspector {
|
|
|
69
69
|
return bindings.map((binding) => this._toSnapshot(binding));
|
|
70
70
|
}
|
|
71
71
|
|
|
72
|
-
has(
|
|
73
|
-
token: Token<unknown> | Constructor,
|
|
74
|
-
hint?: ResolveOptions,
|
|
75
|
-
parentHas?: () => boolean,
|
|
76
|
-
): boolean {
|
|
72
|
+
has(token: Token<unknown> | Constructor, hint?: ResolveOptions, parentHas?: () => boolean): boolean {
|
|
77
73
|
const bindings = this._registry.getAll(token);
|
|
78
74
|
if (bindings.length > 0) {
|
|
79
75
|
if (hint !== undefined) {
|
|
80
|
-
if (
|
|
81
|
-
selectBinding(bindings, hint, this._makeHintContext(hint), tokenName(token)) !== undefined
|
|
82
|
-
) {
|
|
76
|
+
if (selectBinding(bindings, hint, this._makeHintContext(hint), tokenName(token)) !== undefined) {
|
|
83
77
|
return true;
|
|
84
78
|
}
|
|
85
79
|
} else {
|
|
@@ -95,9 +89,7 @@ export class Inspector {
|
|
|
95
89
|
return false;
|
|
96
90
|
}
|
|
97
91
|
if (hint !== undefined) {
|
|
98
|
-
return (
|
|
99
|
-
selectBinding(bindings, hint, this._makeHintContext(hint), tokenName(token)) !== undefined
|
|
100
|
-
);
|
|
92
|
+
return selectBinding(bindings, hint, this._makeHintContext(hint), tokenName(token)) !== undefined;
|
|
101
93
|
}
|
|
102
94
|
return true;
|
|
103
95
|
}
|
package/src/lifecycle.ts
CHANGED
|
@@ -1,34 +1,20 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
ActivationHandler,
|
|
3
|
-
Constructor,
|
|
4
|
-
DeactivationHandler,
|
|
5
|
-
ResolutionContext,
|
|
6
|
-
} from "#/types";
|
|
7
|
-
import type { Token } from "#/token";
|
|
8
1
|
import type { Binding } from "#/binding";
|
|
9
|
-
import type { MetadataReader } from "#/metadata/metadata-types";
|
|
10
2
|
import { AsyncActivationError, AsyncDeactivationError } from "#/errors";
|
|
3
|
+
import type { MetadataReader } from "#/metadata/metadata-types";
|
|
4
|
+
import type { Token } from "#/token";
|
|
11
5
|
import { tokenName } from "#/token";
|
|
6
|
+
import type { ActivationHandler, Constructor, DeactivationHandler, ResolutionContext } from "#/types";
|
|
12
7
|
|
|
13
8
|
/**
|
|
14
9
|
* @since 0.3.16-canary.0
|
|
15
10
|
*/
|
|
16
11
|
export class LifecycleManager {
|
|
17
12
|
// Container-level activation/deactivation hooks per token
|
|
18
|
-
private readonly _activationHooks = new Map<
|
|
19
|
-
|
|
20
|
-
Array<ActivationHandler<unknown>>
|
|
21
|
-
>();
|
|
22
|
-
private readonly _deactivationHooks = new Map<
|
|
23
|
-
Token<unknown> | Constructor,
|
|
24
|
-
Array<DeactivationHandler<unknown>>
|
|
25
|
-
>();
|
|
13
|
+
private readonly _activationHooks = new Map<Token<unknown> | Constructor, Array<ActivationHandler<unknown>>>();
|
|
14
|
+
private readonly _deactivationHooks = new Map<Token<unknown> | Constructor, Array<DeactivationHandler<unknown>>>();
|
|
26
15
|
private _activationVersion = 0;
|
|
27
16
|
|
|
28
|
-
registerActivation<const Value>(
|
|
29
|
-
token: Token<Value> | Constructor<Value>,
|
|
30
|
-
handler: ActivationHandler<Value>,
|
|
31
|
-
): void {
|
|
17
|
+
registerActivation<const Value>(token: Token<Value> | Constructor<Value>, handler: ActivationHandler<Value>): void {
|
|
32
18
|
this._activationVersion += 1;
|
|
33
19
|
// ✓ TS6.0: Map.getOrInsert (ES2025)
|
|
34
20
|
const list = this._activationHooks.getOrInsert(token as Token<unknown> | Constructor, []);
|
|
@@ -82,8 +68,7 @@ export class LifecycleManager {
|
|
|
82
68
|
// 2. per-binding onActivation
|
|
83
69
|
if (binding.kind !== "alias" && binding.onActivation !== undefined) {
|
|
84
70
|
const activationResult = binding.onActivation(resolutionContext, activatedInstance);
|
|
85
|
-
activatedInstance =
|
|
86
|
-
activationResult instanceof Promise ? await activationResult : activationResult;
|
|
71
|
+
activatedInstance = activationResult instanceof Promise ? await activationResult : activationResult;
|
|
87
72
|
}
|
|
88
73
|
|
|
89
74
|
// 3. container-level onActivation
|
|
@@ -91,9 +76,7 @@ export class LifecycleManager {
|
|
|
91
76
|
if (containerHooks !== undefined) {
|
|
92
77
|
for (const hook of containerHooks) {
|
|
93
78
|
const activationResult = hook(resolutionContext, activatedInstance);
|
|
94
|
-
activatedInstance = (
|
|
95
|
-
activationResult instanceof Promise ? await activationResult : activationResult
|
|
96
|
-
) as Value;
|
|
79
|
+
activatedInstance = (activationResult instanceof Promise ? await activationResult : activationResult) as Value;
|
|
97
80
|
}
|
|
98
81
|
}
|
|
99
82
|
|
|
@@ -192,11 +175,7 @@ export class LifecycleManager {
|
|
|
192
175
|
}
|
|
193
176
|
}
|
|
194
177
|
|
|
195
|
-
runDeactivationSync<const Value>(
|
|
196
|
-
binding: Binding<Value>,
|
|
197
|
-
instance: Value,
|
|
198
|
-
metadataReader: MetadataReader,
|
|
199
|
-
): void {
|
|
178
|
+
runDeactivationSync<const Value>(binding: Binding<Value>, instance: Value, metadataReader: MetadataReader): void {
|
|
200
179
|
const tokenDisplayName = tokenName(binding.token);
|
|
201
180
|
const tokenKey = binding.token as Token<unknown> | Constructor;
|
|
202
181
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import type { Constructor } from "#/types";
|
|
2
|
-
import type { Token } from "#/token";
|
|
3
1
|
import type { InjectionDescriptor } from "#/decorators/inject";
|
|
2
|
+
import type { Token } from "#/token";
|
|
3
|
+
import type { Constructor } from "#/types";
|
|
4
4
|
|
|
5
5
|
/**
|
|
6
6
|
* @since 0.3.16-canary.0
|
|
@@ -47,7 +47,5 @@ export interface MetadataReader {
|
|
|
47
47
|
getLifecycleMetadata(target: Constructor): LifecycleMetadata | undefined;
|
|
48
48
|
getAccessorMetadata?(
|
|
49
49
|
target: Constructor,
|
|
50
|
-
):
|
|
51
|
-
| ReadonlyArray<{ readonly key: string | symbol; readonly descriptor: InjectionDescriptor }>
|
|
52
|
-
| undefined;
|
|
50
|
+
): ReadonlyArray<{ readonly key: string | symbol; readonly descriptor: InjectionDescriptor }> | undefined;
|
|
53
51
|
}
|
|
@@ -1,25 +1,13 @@
|
|
|
1
|
-
import type { Constructor } from "#/types";
|
|
2
|
-
import type {
|
|
3
|
-
ConstructorMetadata,
|
|
4
|
-
LifecycleMetadata,
|
|
5
|
-
MetadataReader,
|
|
6
|
-
} from "#/metadata/metadata-types";
|
|
7
1
|
import type { InjectionDescriptor } from "#/decorators/inject";
|
|
8
|
-
import {
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
LIFECYCLE_KEY,
|
|
12
|
-
METADATA_SYMBOL,
|
|
13
|
-
} from "#/metadata/metadata-keys";
|
|
2
|
+
import { INJECT_ACCESSOR_KEY, INJECTABLE_KEY, LIFECYCLE_KEY, METADATA_SYMBOL } from "#/metadata/metadata-keys";
|
|
3
|
+
import type { ConstructorMetadata, LifecycleMetadata, MetadataReader } from "#/metadata/metadata-types";
|
|
4
|
+
import type { Constructor } from "#/types";
|
|
14
5
|
|
|
15
6
|
/**
|
|
16
7
|
* @since 0.3.16-canary.0
|
|
17
8
|
*/
|
|
18
9
|
export class SymbolMetadataReader implements MetadataReader {
|
|
19
|
-
private _getMetadataRecord(
|
|
20
|
-
target: Constructor,
|
|
21
|
-
key: string | symbol,
|
|
22
|
-
): Record<string | symbol, unknown> | undefined {
|
|
10
|
+
private _getMetadataRecord(target: Constructor, key: string | symbol): Record<string | symbol, unknown> | undefined {
|
|
23
11
|
const descriptor = Object.getOwnPropertyDescriptor(target, METADATA_SYMBOL);
|
|
24
12
|
if (descriptor === undefined) {
|
|
25
13
|
return undefined;
|
package/src/module.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { BindToBuilder } from "#/binding";
|
|
2
|
-
import type { Constructor } from "#/types";
|
|
3
2
|
import type { Token } from "#/token";
|
|
3
|
+
import type { Constructor } from "#/types";
|
|
4
4
|
|
|
5
5
|
// ── Branded types (runtime symbols for branding) ─────────────────────────────
|
|
6
6
|
|
|
@@ -89,5 +89,5 @@ export const Module = {
|
|
|
89
89
|
* @since 0.3.16-canary.0
|
|
90
90
|
*/
|
|
91
91
|
export function isSyncModule(module: SyncModule | AsyncModule): module is SyncModule {
|
|
92
|
-
return (module as SyncModule)[SYNC_MODULE_BRAND]
|
|
92
|
+
return (module as SyncModule)[SYNC_MODULE_BRAND];
|
|
93
93
|
}
|
package/src/registry.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type { Binding } from "#/binding";
|
|
2
|
-
import type { BindingIdentifier, Constructor, DependencyKey } from "#/types";
|
|
3
|
-
import type { Token } from "#/token";
|
|
4
2
|
import { bindingSlotEquals, bindingSlotToString } from "#/binding";
|
|
3
|
+
import type { Token } from "#/token";
|
|
4
|
+
import type { BindingIdentifier, Constructor, DependencyKey } from "#/types";
|
|
5
5
|
|
|
6
6
|
/**
|
|
7
7
|
* @since 0.3.16-canary.0
|
|
@@ -27,9 +27,7 @@ export class BindingRegistry {
|
|
|
27
27
|
// Only apply last-wins for slot-based bindings (not predicate-only)
|
|
28
28
|
if (!this._isPurePredicateBinding(binding)) {
|
|
29
29
|
const existingIndex = bindingsForToken.findIndex(
|
|
30
|
-
(candidate) =>
|
|
31
|
-
!this._isPurePredicateBinding(candidate) &&
|
|
32
|
-
bindingSlotEquals(candidate.slot, binding.slot),
|
|
30
|
+
(candidate) => !this._isPurePredicateBinding(candidate) && bindingSlotEquals(candidate.slot, binding.slot),
|
|
33
31
|
);
|
|
34
32
|
if (existingIndex !== -1) {
|
|
35
33
|
const replacedBinding = bindingsForToken[existingIndex]!;
|
|
@@ -128,11 +126,7 @@ export class BindingRegistry {
|
|
|
128
126
|
return this._simpleNamed.get(token as DependencyKey)?.get(name);
|
|
129
127
|
}
|
|
130
128
|
|
|
131
|
-
getSimpleTagged(
|
|
132
|
-
token: Token<unknown> | Constructor,
|
|
133
|
-
tagKey: string,
|
|
134
|
-
tagValue: unknown,
|
|
135
|
-
): Binding | undefined {
|
|
129
|
+
getSimpleTagged(token: Token<unknown> | Constructor, tagKey: string, tagValue: unknown): Binding | undefined {
|
|
136
130
|
return this._simpleTagged
|
|
137
131
|
.get(token as DependencyKey)
|
|
138
132
|
?.get(tagKey)
|
|
@@ -155,10 +149,7 @@ export class BindingRegistry {
|
|
|
155
149
|
return;
|
|
156
150
|
}
|
|
157
151
|
const [tagKey, tagValue] = slot.tags[0]!;
|
|
158
|
-
const byTagKey = this._simpleTagged.getOrInsert(
|
|
159
|
-
tokenKey,
|
|
160
|
-
new Map<string, Map<unknown, Binding>>(),
|
|
161
|
-
);
|
|
152
|
+
const byTagKey = this._simpleTagged.getOrInsert(tokenKey, new Map<string, Map<unknown, Binding>>());
|
|
162
153
|
const byTagValue = byTagKey.getOrInsert(tagKey, new Map<unknown, Binding>());
|
|
163
154
|
byTagValue.set(tagValue, binding);
|
|
164
155
|
}
|