@codefast/di 0.10.0 → 0.10.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/CHANGELOG.md +28 -0
- package/README.md +3 -2
- package/dist/ambient/active-container.d.ts +6 -9
- package/dist/ambient/active-container.js +2 -5
- package/dist/container/binding-builders.d.ts +7 -7
- package/dist/container/binding-builders.js +36 -27
- package/dist/container/container.d.ts +8 -8
- package/dist/container/container.js +20 -20
- package/dist/core/binding-scope.d.ts +2 -2
- package/dist/core/binding.d.ts +6 -6
- package/dist/core/binding.js +1 -1
- package/dist/core/constraint-requirement.d.ts +1 -1
- package/dist/core/module.d.ts +3 -3
- package/dist/core/registry.d.ts +6 -6
- package/dist/core/registry.js +36 -24
- package/dist/core/token.d.ts +1 -1
- package/dist/core/types.d.ts +5 -5
- package/dist/decorators/inject.d.ts +3 -3
- package/dist/decorators/inject.js +5 -5
- package/dist/decorators/injectable.d.ts +2 -2
- package/dist/decorators/injectable.js +2 -2
- package/dist/decorators/lifecycle-decorators.js +2 -2
- package/dist/errors/errors.d.ts +8 -11
- package/dist/errors/errors.js +7 -10
- package/dist/index.d.ts +35 -35
- package/dist/index.js +19 -19
- package/dist/injection/descriptor.d.ts +3 -3
- package/dist/injection/resolve-options.d.ts +3 -3
- package/dist/injection/resolve-options.js +1 -1
- package/dist/introspection/dependency-graph.d.ts +3 -3
- package/dist/introspection/dependency-graph.js +5 -5
- package/dist/introspection/graph-adapters/cytoscape.d.ts +1 -1
- package/dist/introspection/graph-adapters/dot.d.ts +1 -1
- package/dist/introspection/graph-adapters/mermaid.d.ts +1 -1
- package/dist/introspection/graph-adapters/reactflow.d.ts +1 -1
- package/dist/introspection/inspector.d.ts +4 -4
- package/dist/introspection/inspector.js +3 -3
- package/dist/lifecycle/lifecycle-manager.d.ts +4 -4
- package/dist/lifecycle/lifecycle-manager.js +4 -4
- package/dist/lifecycle/scope-manager.d.ts +2 -2
- package/dist/lifecycle/scope-manager.js +3 -3
- package/dist/metadata/metadata-reader-token.d.ts +2 -2
- package/dist/metadata/metadata-reader-token.js +1 -1
- package/dist/metadata/metadata-types.d.ts +3 -3
- package/dist/metadata/symbol-metadata-reader.d.ts +3 -3
- package/dist/metadata/symbol-metadata-reader.js +1 -1
- package/dist/metadata/verifying-metadata-reader.d.ts +1 -1
- package/dist/metadata/verifying-metadata-reader.js +2 -2
- package/dist/resolution/cache/activation-need.d.ts +4 -4
- package/dist/resolution/cache/binding-lookup-cache.d.ts +5 -5
- package/dist/resolution/cache/binding-lookup-cache.js +2 -2
- package/dist/resolution/cache/class-introspector.d.ts +5 -5
- package/dist/resolution/cache/class-introspector.js +55 -56
- package/dist/resolution/context.d.ts +3 -3
- package/dist/resolution/context.js +1 -1
- package/dist/resolution/path/resolution-path.d.ts +1 -1
- package/dist/resolution/path/resolution-path.js +1 -1
- package/dist/resolution/plan/instantiation-plan.d.ts +5 -5
- package/dist/resolution/plan/instantiation-plan.js +5 -5
- package/dist/resolution/plan/plan-codegen.d.ts +3 -3
- package/dist/resolution/plan/plan-codegen.js +2 -2
- package/dist/resolution/resolver.d.ts +12 -12
- package/dist/resolution/resolver.js +33 -20
- package/dist/resolution/select/binding-select.d.ts +6 -5
- package/dist/resolution/select/binding-select.js +5 -4
- package/dist/resolution/select/constraints.d.ts +3 -3
- package/dist/resolution/select/constraints.js +4 -4
- package/package.json +3 -3
package/dist/errors/errors.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { slotName } from "
|
|
1
|
+
import { slotName } from "#core/tag";
|
|
2
2
|
/**
|
|
3
3
|
* Base class for every error the library throws, each carrying a machine-readable `code`.
|
|
4
4
|
*
|
|
@@ -316,15 +316,6 @@ export class MissingContainerContextError extends DiError {
|
|
|
316
316
|
this.accessorName = accessorName;
|
|
317
317
|
}
|
|
318
318
|
}
|
|
319
|
-
/**
|
|
320
|
-
* A fluent chain was refined before a `to*()` call gave it a binding to refine.
|
|
321
|
-
*
|
|
322
|
-
* @remarks The builder types make this unreachable from TypeScript — `bind()` returns
|
|
323
|
-
* `BindToBuilder`, which exposes only `to*()`. It exists for JavaScript callers and for anyone who
|
|
324
|
-
* casts past the types, so the misuse fails loudly instead of mutating nothing.
|
|
325
|
-
*
|
|
326
|
-
* @since 0.5.0-canary.8
|
|
327
|
-
*/
|
|
328
319
|
/**
|
|
329
320
|
* A second `to*()` on a chain that already registered its binding.
|
|
330
321
|
*
|
|
@@ -358,6 +349,12 @@ export class ManyBindingSlotError extends DiError {
|
|
|
358
349
|
}
|
|
359
350
|
}
|
|
360
351
|
/**
|
|
352
|
+
* A fluent chain was refined before a `to*()` call gave it a binding to refine.
|
|
353
|
+
*
|
|
354
|
+
* @remarks The builder types make this unreachable from TypeScript — `bind()` returns
|
|
355
|
+
* `BindToBuilder`, which exposes only `to*()`. It exists for JavaScript callers and for anyone who
|
|
356
|
+
* casts past the types, so the misuse fails loudly instead of mutating nothing.
|
|
357
|
+
*
|
|
361
358
|
* @since 0.10.0
|
|
362
359
|
*/
|
|
363
360
|
export class ChainNotRegisteredError extends DiError {
|
package/dist/index.d.ts
CHANGED
|
@@ -1,35 +1,35 @@
|
|
|
1
|
-
export type { ActivationHandler, BindingConstraint, BindingIdentifier, BindingKind, BindingScope, BindingTag, ConstraintContext, Constructor, DependencyKey, DeactivationHandler, ResolutionFrame, ResolveOptions, ResolutionContext, TokenValue, } from "
|
|
2
|
-
export { token, tokenName } from "
|
|
3
|
-
export type { SlotNamesOf, Token } from "
|
|
4
|
-
export { coversTagKeys, NO_TAG_KEYS, slotName, tag, tagKeyMaskOf } from "
|
|
5
|
-
export type { TagKey, TagKeyMask } from "
|
|
6
|
-
export type { AliasBindingBuilder, BindToBuilder, BindingBuilder, ConstantBindingBuilder, ScopedBindingBuilder, SingletonBindingBuilder, SingletonLifecycleBuilder, SlotConstrainedBuilder, TransientBindingBuilder, } from "
|
|
7
|
-
export { Container } from "
|
|
8
|
-
export type { Container as ContainerInterface, ContainerOptions, ContainerStatic } from "
|
|
9
|
-
export { getActiveContainer, runWithContainer } from "
|
|
10
|
-
export { bindingSlotToResolveOptions, injectionSlotToResolveOptions, resolveOptionsForSlot, } from "
|
|
11
|
-
export type { DependencySlot } from "
|
|
12
|
-
export type { BindingSnapshot, ContainerSnapshot } from "
|
|
13
|
-
export type { ContainerGraphJson, GraphEdge, GraphNode, GraphOptions } from "
|
|
14
|
-
export { AsyncModule, isSyncModule, Module, SyncModule } from "
|
|
15
|
-
export type { AsyncModuleBuilder, ModuleBuilder } from "
|
|
16
|
-
export { inject } from "
|
|
17
|
-
export { injectAll, isInjectionDescriptor, optional } from "
|
|
18
|
-
export type { InjectionDescriptor, InjectOptions } from "
|
|
19
|
-
export { injectable } from "
|
|
20
|
-
export type { InjectableDependency, InjectableOptions } from "
|
|
21
|
-
export { postConstruct, preDestroy } from "
|
|
22
|
-
export { createAutoRegisterRegistry } from "
|
|
23
|
-
export type { AutoRegisterRegistry } from "
|
|
24
|
-
export { MetadataReaderToken } from "
|
|
25
|
-
export type { ConstructorMetadata, LifecycleMetadata, MetadataReader, MutableLifecycleMetadata, ParamMetadata, } from "
|
|
26
|
-
export { defaultMetadataReader, SymbolMetadataReader } from "
|
|
27
|
-
export { whenAnyAncestorIs, whenAnyAncestorNamed, whenAnyAncestorTagged, whenAnyAncestorTaggedAll, whenNoAncestorIs, whenNoParentIs, whenParentIs, whenParentNamed, whenParentTagged, whenParentTaggedAll, } from "
|
|
28
|
-
export { AmbiguousBindingError, AsyncActivationError, AsyncDeactivationError, AsyncModuleLoadError, AsyncResolutionError, ChainAlreadyRegisteredError, ChainNotRegisteredError, ManyBindingSlotError, CircularDependencyError, DiError, DisposedContainerError, InternalError, InvalidMetadataError, MissingContainerContextError, MissingMetadataError, MissingScopeContextError, NoMatchingBindingError, RebindUnboundTokenError, ScopeViolationError, SelfBindingRequiresClassError, StaticMemberDecoratorError, SyncDisposalNotSupportedError, EmptyTagCriteriaError, TokenNotBoundError, UnreachableConstraintError, UnreachableLifecycleHookError, } from "
|
|
29
|
-
export type { ScopeViolationDetails } from "
|
|
30
|
-
export { toDotGraph } from "
|
|
31
|
-
export { toCytoscapeGraph } from "
|
|
32
|
-
export type { CytoscapeEdge, CytoscapeElements, CytoscapeNode } from "
|
|
33
|
-
export { toReactFlowGraph } from "
|
|
34
|
-
export type { ReactFlowEdge, ReactFlowGraph, ReactFlowNode } from "
|
|
35
|
-
export { toMermaidGraph } from "
|
|
1
|
+
export type { ActivationHandler, BindingConstraint, BindingIdentifier, BindingKind, BindingScope, BindingTag, ConstraintContext, Constructor, DependencyKey, DeactivationHandler, ResolutionFrame, ResolveOptions, ResolutionContext, TokenValue, } from "#core/types";
|
|
2
|
+
export { token, tokenName } from "#core/token";
|
|
3
|
+
export type { SlotNamesOf, Token } from "#core/token";
|
|
4
|
+
export { coversTagKeys, NO_TAG_KEYS, slotName, tag, tagKeyMaskOf } from "#core/tag";
|
|
5
|
+
export type { TagKey, TagKeyMask } from "#core/tag";
|
|
6
|
+
export type { AliasBindingBuilder, BindToBuilder, BindingBuilder, ConstantBindingBuilder, ScopedBindingBuilder, SingletonBindingBuilder, SingletonLifecycleBuilder, SlotConstrainedBuilder, TransientBindingBuilder, } from "#core/binding";
|
|
7
|
+
export { Container } from "#container/container";
|
|
8
|
+
export type { Container as ContainerInterface, ContainerOptions, ContainerStatic } from "#container/container";
|
|
9
|
+
export { getActiveContainer, runWithContainer } from "#ambient/active-container";
|
|
10
|
+
export { bindingSlotToResolveOptions, injectionSlotToResolveOptions, resolveOptionsForSlot, } from "#injection/resolve-options";
|
|
11
|
+
export type { DependencySlot } from "#injection/resolve-options";
|
|
12
|
+
export type { BindingSnapshot, ContainerSnapshot } from "#introspection/inspector";
|
|
13
|
+
export type { ContainerGraphJson, GraphEdge, GraphNode, GraphOptions } from "#introspection/dependency-graph";
|
|
14
|
+
export { AsyncModule, isSyncModule, Module, SyncModule } from "#core/module";
|
|
15
|
+
export type { AsyncModuleBuilder, ModuleBuilder } from "#core/module";
|
|
16
|
+
export { inject } from "#decorators/inject";
|
|
17
|
+
export { injectAll, isInjectionDescriptor, optional } from "#injection/descriptor";
|
|
18
|
+
export type { InjectionDescriptor, InjectOptions } from "#injection/descriptor";
|
|
19
|
+
export { injectable } from "#decorators/injectable";
|
|
20
|
+
export type { InjectableDependency, InjectableOptions } from "#decorators/injectable";
|
|
21
|
+
export { postConstruct, preDestroy } from "#decorators/lifecycle-decorators";
|
|
22
|
+
export { createAutoRegisterRegistry } from "#decorators/injectable";
|
|
23
|
+
export type { AutoRegisterRegistry } from "#decorators/injectable";
|
|
24
|
+
export { MetadataReaderToken } from "#metadata/metadata-reader-token";
|
|
25
|
+
export type { ConstructorMetadata, LifecycleMetadata, MetadataReader, MutableLifecycleMetadata, ParamMetadata, } from "#metadata/metadata-types";
|
|
26
|
+
export { defaultMetadataReader, SymbolMetadataReader } from "#metadata/symbol-metadata-reader";
|
|
27
|
+
export { whenAnyAncestorIs, whenAnyAncestorNamed, whenAnyAncestorTagged, whenAnyAncestorTaggedAll, whenNoAncestorIs, whenNoParentIs, whenParentIs, whenParentNamed, whenParentTagged, whenParentTaggedAll, } from "#resolution/select/constraints";
|
|
28
|
+
export { AmbiguousBindingError, AsyncActivationError, AsyncDeactivationError, AsyncModuleLoadError, AsyncResolutionError, ChainAlreadyRegisteredError, ChainNotRegisteredError, ManyBindingSlotError, CircularDependencyError, DiError, DisposedContainerError, InternalError, InvalidMetadataError, MissingContainerContextError, MissingMetadataError, MissingScopeContextError, NoMatchingBindingError, RebindUnboundTokenError, ScopeViolationError, SelfBindingRequiresClassError, StaticMemberDecoratorError, SyncDisposalNotSupportedError, EmptyTagCriteriaError, TokenNotBoundError, UnreachableConstraintError, UnreachableLifecycleHookError, } from "#errors/errors";
|
|
29
|
+
export type { ScopeViolationDetails } from "#errors/errors";
|
|
30
|
+
export { toDotGraph } from "#introspection/graph-adapters/dot";
|
|
31
|
+
export { toCytoscapeGraph } from "#introspection/graph-adapters/cytoscape";
|
|
32
|
+
export type { CytoscapeEdge, CytoscapeElements, CytoscapeNode } from "#introspection/graph-adapters/cytoscape";
|
|
33
|
+
export { toReactFlowGraph } from "#introspection/graph-adapters/reactflow";
|
|
34
|
+
export type { ReactFlowEdge, ReactFlowGraph, ReactFlowNode } from "#introspection/graph-adapters/reactflow";
|
|
35
|
+
export { toMermaidGraph } from "#introspection/graph-adapters/mermaid";
|
package/dist/index.js
CHANGED
|
@@ -1,33 +1,33 @@
|
|
|
1
1
|
// Token
|
|
2
|
-
export { token, tokenName } from "
|
|
2
|
+
export { token, tokenName } from "#core/token";
|
|
3
3
|
// Tag — the interned slot criteria a `whenTagged` and a resolve both take
|
|
4
|
-
export { coversTagKeys, NO_TAG_KEYS, slotName, tag, tagKeyMaskOf } from "
|
|
4
|
+
export { coversTagKeys, NO_TAG_KEYS, slotName, tag, tagKeyMaskOf } from "#core/tag";
|
|
5
5
|
// Container
|
|
6
|
-
export { Container } from "
|
|
6
|
+
export { Container } from "#container/container";
|
|
7
7
|
// Ambient container — the context an `@inject` accessor initializer resolves from. `resolution/context`
|
|
8
8
|
// stays internal: it hands out resolver callbacks, not public values.
|
|
9
|
-
export { getActiveContainer, runWithContainer } from "
|
|
9
|
+
export { getActiveContainer, runWithContainer } from "#ambient/active-container";
|
|
10
10
|
// `effectiveBindingScope` is deliberately absent: it reads a `Binding`, which is internal, and no
|
|
11
11
|
// public API hands one out. `BindingSnapshot.scope` and `GraphNode.scope` are the public answers.
|
|
12
|
-
export { bindingSlotToResolveOptions, injectionSlotToResolveOptions, resolveOptionsForSlot, } from "
|
|
12
|
+
export { bindingSlotToResolveOptions, injectionSlotToResolveOptions, resolveOptionsForSlot, } from "#injection/resolve-options";
|
|
13
13
|
// Module
|
|
14
|
-
export { AsyncModule, isSyncModule, Module, SyncModule } from "
|
|
14
|
+
export { AsyncModule, isSyncModule, Module, SyncModule } from "#core/module";
|
|
15
15
|
// Decorators
|
|
16
|
-
export { inject } from "
|
|
17
|
-
export { injectAll, isInjectionDescriptor, optional } from "
|
|
18
|
-
export { injectable } from "
|
|
19
|
-
export { postConstruct, preDestroy } from "
|
|
16
|
+
export { inject } from "#decorators/inject";
|
|
17
|
+
export { injectAll, isInjectionDescriptor, optional } from "#injection/descriptor";
|
|
18
|
+
export { injectable } from "#decorators/injectable";
|
|
19
|
+
export { postConstruct, preDestroy } from "#decorators/lifecycle-decorators";
|
|
20
20
|
// Auto-register
|
|
21
|
-
export { createAutoRegisterRegistry } from "
|
|
21
|
+
export { createAutoRegisterRegistry } from "#decorators/injectable";
|
|
22
22
|
// MetadataReader — everything a consumer needs to write one and pass it to Container.create()
|
|
23
|
-
export { MetadataReaderToken } from "
|
|
24
|
-
export { defaultMetadataReader, SymbolMetadataReader } from "
|
|
23
|
+
export { MetadataReaderToken } from "#metadata/metadata-reader-token";
|
|
24
|
+
export { defaultMetadataReader, SymbolMetadataReader } from "#metadata/symbol-metadata-reader";
|
|
25
25
|
// Constraints — contextual injection predicates for .when()
|
|
26
|
-
export { whenAnyAncestorIs, whenAnyAncestorNamed, whenAnyAncestorTagged, whenAnyAncestorTaggedAll, whenNoAncestorIs, whenNoParentIs, whenParentIs, whenParentNamed, whenParentTagged, whenParentTaggedAll, } from "
|
|
26
|
+
export { whenAnyAncestorIs, whenAnyAncestorNamed, whenAnyAncestorTagged, whenAnyAncestorTaggedAll, whenNoAncestorIs, whenNoParentIs, whenParentIs, whenParentNamed, whenParentTagged, whenParentTaggedAll, } from "#resolution/select/constraints";
|
|
27
27
|
// Errors
|
|
28
|
-
export { AmbiguousBindingError, AsyncActivationError, AsyncDeactivationError, AsyncModuleLoadError, AsyncResolutionError, ChainAlreadyRegisteredError, ChainNotRegisteredError, ManyBindingSlotError, CircularDependencyError, DiError, DisposedContainerError, InternalError, InvalidMetadataError, MissingContainerContextError, MissingMetadataError, MissingScopeContextError, NoMatchingBindingError, RebindUnboundTokenError, ScopeViolationError, SelfBindingRequiresClassError, StaticMemberDecoratorError, SyncDisposalNotSupportedError, EmptyTagCriteriaError, TokenNotBoundError, UnreachableConstraintError, UnreachableLifecycleHookError, } from "
|
|
28
|
+
export { AmbiguousBindingError, AsyncActivationError, AsyncDeactivationError, AsyncModuleLoadError, AsyncResolutionError, ChainAlreadyRegisteredError, ChainNotRegisteredError, ManyBindingSlotError, CircularDependencyError, DiError, DisposedContainerError, InternalError, InvalidMetadataError, MissingContainerContextError, MissingMetadataError, MissingScopeContextError, NoMatchingBindingError, RebindUnboundTokenError, ScopeViolationError, SelfBindingRequiresClassError, StaticMemberDecoratorError, SyncDisposalNotSupportedError, EmptyTagCriteriaError, TokenNotBoundError, UnreachableConstraintError, UnreachableLifecycleHookError, } from "#errors/errors";
|
|
29
29
|
// Graph adapters — render `generateDependencyGraph()` output for common viewers
|
|
30
|
-
export { toDotGraph } from "
|
|
31
|
-
export { toCytoscapeGraph } from "
|
|
32
|
-
export { toReactFlowGraph } from "
|
|
33
|
-
export { toMermaidGraph } from "
|
|
30
|
+
export { toDotGraph } from "#introspection/graph-adapters/dot";
|
|
31
|
+
export { toCytoscapeGraph } from "#introspection/graph-adapters/cytoscape";
|
|
32
|
+
export { toReactFlowGraph } from "#introspection/graph-adapters/reactflow";
|
|
33
|
+
export { toMermaidGraph } from "#introspection/graph-adapters/mermaid";
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/** The one shape every declared dependency is normalised to, whatever channel declared it. */
|
|
2
|
-
import type { Token } from "
|
|
3
|
-
import type { BindingTag, Constructor, TokenValue } from "
|
|
4
|
-
import type { DependencySlot } from "
|
|
2
|
+
import type { Token } from "#core/token";
|
|
3
|
+
import type { BindingTag, Constructor, TokenValue } from "#core/types";
|
|
4
|
+
import type { DependencySlot } from "#injection/resolve-options";
|
|
5
5
|
/**
|
|
6
6
|
* Slot-selection options — a name and tags — a declared dependency narrows its binding with.
|
|
7
7
|
*
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import type { BindingTag } from "
|
|
2
|
-
import type { Token } from "
|
|
3
|
-
import type { Constructor, ResolveOptions } from "
|
|
1
|
+
import type { BindingTag } from "#core/tag";
|
|
2
|
+
import type { Token } from "#core/token";
|
|
3
|
+
import type { Constructor, ResolveOptions } from "#core/types";
|
|
4
4
|
/**
|
|
5
5
|
* What one resolvable dependency declares.
|
|
6
6
|
*
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import type { BindingRegistry } from "
|
|
2
|
-
import type { BindingKind, BindingScope } from "
|
|
3
|
-
import type { MetadataReader } from "
|
|
1
|
+
import type { BindingRegistry } from "#core/registry";
|
|
2
|
+
import type { BindingKind, BindingScope } from "#core/types";
|
|
3
|
+
import type { MetadataReader } from "#metadata/metadata-types";
|
|
4
4
|
/**
|
|
5
5
|
* @remarks `kind`/`scope` are `"unbound"` for the placeholder node an optional, currently
|
|
6
6
|
* unsatisfied dependency points at.
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import { effectiveBindingScope } from "
|
|
2
|
-
import { slotName } from "
|
|
3
|
-
import { tokenName } from "
|
|
4
|
-
import { bindingSlotToResolveOptions } from "
|
|
5
|
-
import { matchesSlot } from "
|
|
1
|
+
import { effectiveBindingScope } from "#core/binding-scope";
|
|
2
|
+
import { slotName } from "#core/tag";
|
|
3
|
+
import { tokenName } from "#core/token";
|
|
4
|
+
import { bindingSlotToResolveOptions } from "#injection/resolve-options";
|
|
5
|
+
import { matchesSlot } from "#resolution/select/binding-select";
|
|
6
6
|
// ── Builder ──────────────────────────────────────────────────────────────────────────────────────────────────────────
|
|
7
7
|
// Tokens are compared by object identity, and a name is free to repeat, so the graph mints its
|
|
8
8
|
// own per-process key. Weakly held: a discarded token takes its key with it.
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { ContainerGraphJson } from "
|
|
1
|
+
import type { ContainerGraphJson } from "#introspection/dependency-graph";
|
|
2
2
|
/**
|
|
3
3
|
* Mermaid `flowchart TD` source for a container graph — renders anywhere Mermaid does
|
|
4
4
|
* (GitHub markdown, docs tooling, mermaid.live) with no extra library.
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import type { BindingRegistry } from "
|
|
2
|
-
import type { Token } from "
|
|
3
|
-
import type { BindingIdentifier, BindingKind, BindingScope, BindingTag, Constructor, ResolveOptions } from "
|
|
4
|
-
import type { ScopeManager } from "
|
|
1
|
+
import type { BindingRegistry } from "#core/registry";
|
|
2
|
+
import type { Token } from "#core/token";
|
|
3
|
+
import type { BindingIdentifier, BindingKind, BindingScope, BindingTag, Constructor, ResolveOptions } from "#core/types";
|
|
4
|
+
import type { ScopeManager } from "#lifecycle/scope-manager";
|
|
5
5
|
/**
|
|
6
6
|
* A read-only view of one binding: token, kind, scope, slot, and id.
|
|
7
7
|
*
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { effectiveBindingScope } from "
|
|
2
|
-
import { tokenName } from "
|
|
3
|
-
import { selectAllBindings } from "
|
|
1
|
+
import { effectiveBindingScope } from "#core/binding-scope";
|
|
2
|
+
import { tokenName } from "#core/token";
|
|
3
|
+
import { selectAllBindings } from "#resolution/select/binding-select";
|
|
4
4
|
// ── Inspector ────────────────────────────────────────────────────────────────────────────────────────────────────────
|
|
5
5
|
/**
|
|
6
6
|
* The read-only introspection surface behind a container's `inspect()`.
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import type { Binding } from "
|
|
2
|
-
import type { Token } from "
|
|
3
|
-
import type { ActivationHandler, Constructor, DeactivationHandler, DependencyKey, ResolutionContext } from "
|
|
4
|
-
import type { MetadataReader } from "
|
|
1
|
+
import type { Binding } from "#core/binding";
|
|
2
|
+
import type { Token } from "#core/token";
|
|
3
|
+
import type { ActivationHandler, Constructor, DeactivationHandler, DependencyKey, ResolutionContext } from "#core/types";
|
|
4
|
+
import type { MetadataReader } from "#metadata/metadata-types";
|
|
5
5
|
/**
|
|
6
6
|
* One container's registry of container-level activation and deactivation hooks, keyed by token.
|
|
7
7
|
*
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { getOrInsert } from "
|
|
2
|
-
import { advanceStateEpoch } from "
|
|
3
|
-
import { tokenName } from "
|
|
4
|
-
import { AsyncActivationError, AsyncDeactivationError, InvalidMetadataError } from "
|
|
1
|
+
import { getOrInsert } from "#core/map-upsert";
|
|
2
|
+
import { advanceStateEpoch } from "#core/state-epoch";
|
|
3
|
+
import { tokenName } from "#core/token";
|
|
4
|
+
import { AsyncActivationError, AsyncDeactivationError, InvalidMetadataError } from "#errors/errors";
|
|
5
5
|
/**
|
|
6
6
|
* One container's registry of container-level activation and deactivation hooks, keyed by token.
|
|
7
7
|
*
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import type { Binding } from "
|
|
2
|
-
import type { BindingIdentifier } from "
|
|
1
|
+
import type { Binding } from "#core/binding";
|
|
2
|
+
import type { BindingIdentifier } from "#core/types";
|
|
3
3
|
/**
|
|
4
4
|
* One container's instance caches — singletons, in-flight async creations, and the scoped cache.
|
|
5
5
|
*
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { NO_INSTANCE } from "
|
|
2
|
-
import { tokenName } from "
|
|
3
|
-
import { MissingScopeContextError } from "
|
|
1
|
+
import { NO_INSTANCE } from "#core/binding";
|
|
2
|
+
import { tokenName } from "#core/token";
|
|
3
|
+
import { MissingScopeContextError } from "#errors/errors";
|
|
4
4
|
/**
|
|
5
5
|
* One container's instance caches — singletons, in-flight async creations, and the scoped cache.
|
|
6
6
|
*
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import type { Token } from "
|
|
2
|
-
import type { MetadataReader } from "
|
|
1
|
+
import type { Token } from "#core/token";
|
|
2
|
+
import type { MetadataReader } from "#metadata/metadata-types";
|
|
3
3
|
/**
|
|
4
4
|
* The token a custom `MetadataReader` is bound to for a container to pick up.
|
|
5
5
|
*
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import type { Constructor } from "
|
|
2
|
-
import type { InjectionDescriptor } from "
|
|
3
|
-
import type { DependencySlot } from "
|
|
1
|
+
import type { Constructor } from "#core/types";
|
|
2
|
+
import type { InjectionDescriptor } from "#injection/descriptor";
|
|
3
|
+
import type { DependencySlot } from "#injection/resolve-options";
|
|
4
4
|
/**
|
|
5
5
|
* One constructor parameter's declaration.
|
|
6
6
|
*
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import type { Constructor } from "
|
|
2
|
-
import type { InjectionDescriptor } from "
|
|
3
|
-
import type { ConstructorMetadata, LifecycleMetadata, MetadataReader } from "
|
|
1
|
+
import type { Constructor } from "#core/types";
|
|
2
|
+
import type { InjectionDescriptor } from "#injection/descriptor";
|
|
3
|
+
import type { ConstructorMetadata, LifecycleMetadata, MetadataReader } from "#metadata/metadata-types";
|
|
4
4
|
type AccessorEntry = {
|
|
5
5
|
readonly key: string | symbol;
|
|
6
6
|
readonly descriptor: InjectionDescriptor;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { INJECT_ACCESSOR_KEY, INJECTABLE_KEY, LIFECYCLE_KEY, METADATA_SYMBOL } from "
|
|
1
|
+
import { INJECT_ACCESSOR_KEY, INJECTABLE_KEY, LIFECYCLE_KEY, METADATA_SYMBOL } from "#metadata/metadata-keys";
|
|
2
2
|
/**
|
|
3
3
|
* The default `MetadataReader`, reading decorator metadata stored under `Symbol.metadata`.
|
|
4
4
|
*
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
* Wraps a foreign {@link MetadataReader} so its answers are verified before anything dereferences
|
|
3
3
|
* them.
|
|
4
4
|
*/
|
|
5
|
-
import type { MetadataReader } from "
|
|
5
|
+
import type { MetadataReader } from "#metadata/metadata-types";
|
|
6
6
|
/**
|
|
7
7
|
* The reader a container should hand its resolver: verified when it came from outside.
|
|
8
8
|
*
|
|
@@ -2,8 +2,8 @@
|
|
|
2
2
|
* Wraps a foreign {@link MetadataReader} so its answers are verified before anything dereferences
|
|
3
3
|
* them.
|
|
4
4
|
*/
|
|
5
|
-
import { defaultMetadataReader } from "
|
|
6
|
-
import { verifyAccessorMetadata, verifyConstructorMetadata, verifyLifecycleMetadata, } from "
|
|
5
|
+
import { defaultMetadataReader } from "#metadata/symbol-metadata-reader";
|
|
6
|
+
import { verifyAccessorMetadata, verifyConstructorMetadata, verifyLifecycleMetadata, } from "#resolution/cache/class-introspector";
|
|
7
7
|
// Wrapping a wrapper would stack a layer per child container, so each one is remembered.
|
|
8
8
|
const verifyingReaders = new WeakSet();
|
|
9
9
|
/**
|
|
@@ -4,10 +4,10 @@
|
|
|
4
4
|
* @remarks Versioned on the lifecycle manager plus the own registry, since `onActivation` can be
|
|
5
5
|
* registered at any time and a rebind mints binding ids the memo must not keep forever.
|
|
6
6
|
*/
|
|
7
|
-
import type { Binding } from "
|
|
8
|
-
import type { BindingRegistry } from "
|
|
9
|
-
import type { LifecycleManager } from "
|
|
10
|
-
import type { ClassIntrospector } from "
|
|
7
|
+
import type { Binding } from "#core/binding";
|
|
8
|
+
import type { BindingRegistry } from "#core/registry";
|
|
9
|
+
import type { LifecycleManager } from "#lifecycle/lifecycle-manager";
|
|
10
|
+
import type { ClassIntrospector } from "#resolution/cache/class-introspector";
|
|
11
11
|
/**
|
|
12
12
|
* A per-binding cache of whether activation work — hooks or `@postConstruct` — is needed on resolve.
|
|
13
13
|
*
|
|
@@ -4,11 +4,11 @@
|
|
|
4
4
|
* @remarks Each cache links to its parent's, so a child answers from its own chain without walking
|
|
5
5
|
* the container hierarchy again.
|
|
6
6
|
*/
|
|
7
|
-
import type { Binding } from "
|
|
8
|
-
import type { BindingRegistry } from "
|
|
9
|
-
import type { BindingTag } from "
|
|
10
|
-
import type { Token } from "
|
|
11
|
-
import type { Constructor } from "
|
|
7
|
+
import type { Binding } from "#core/binding";
|
|
8
|
+
import type { BindingRegistry } from "#core/registry";
|
|
9
|
+
import type { BindingTag } from "#core/tag";
|
|
10
|
+
import type { Token } from "#core/token";
|
|
11
|
+
import type { Constructor } from "#core/types";
|
|
12
12
|
/**
|
|
13
13
|
* A token's terminal binding with alias hops already folded, plus the container that owns it.
|
|
14
14
|
*
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { getOrInsertComputed } from "
|
|
2
|
-
import { stateEpoch } from "
|
|
1
|
+
import { getOrInsertComputed } from "#core/map-upsert";
|
|
2
|
+
import { stateEpoch } from "#core/state-epoch";
|
|
3
3
|
/**
|
|
4
4
|
* Alias folding gives up past this many hops and defers to the full resolve loop, whose
|
|
5
5
|
* Set-based traversal detects genuine cycles exactly rather than by an arbitrary cap.
|
|
@@ -3,11 +3,11 @@
|
|
|
3
3
|
*
|
|
4
4
|
* @remarks Metadata cannot change once a class is defined, so nothing here needs version stamping.
|
|
5
5
|
*/
|
|
6
|
-
import type { AmbientResolution } from "
|
|
7
|
-
import type { Container } from "
|
|
8
|
-
import type { Constructor } from "
|
|
9
|
-
import type { InjectionDescriptor } from "
|
|
10
|
-
import type { ConstructorMetadata, LifecycleMetadata, MetadataReader } from "
|
|
6
|
+
import type { AmbientResolution } from "#ambient/active-container";
|
|
7
|
+
import type { Container } from "#container/container";
|
|
8
|
+
import type { Constructor } from "#core/types";
|
|
9
|
+
import type { InjectionDescriptor } from "#injection/descriptor";
|
|
10
|
+
import type { ConstructorMetadata, LifecycleMetadata, MetadataReader } from "#metadata/metadata-types";
|
|
11
11
|
/**
|
|
12
12
|
* A reader's constructor metadata for a class, verified the first time this process asks.
|
|
13
13
|
*
|
|
@@ -3,8 +3,8 @@
|
|
|
3
3
|
*
|
|
4
4
|
* @remarks Metadata cannot change once a class is defined, so nothing here needs version stamping.
|
|
5
5
|
*/
|
|
6
|
-
import { constructWithAmbientResolution, runWithAmbientResolution } from "
|
|
7
|
-
import { InvalidMetadataError } from "
|
|
6
|
+
import { constructWithAmbientResolution, runWithAmbientResolution } from "#ambient/active-container";
|
|
7
|
+
import { InvalidMetadataError } from "#errors/errors";
|
|
8
8
|
// Verified pairs, not verified classes: two readers may disagree about the same class, and a reader
|
|
9
9
|
// that goes out of scope takes its record with it.
|
|
10
10
|
const verifiedTargets = new WeakMap();
|
|
@@ -21,6 +21,20 @@ function markVerified(cache, reader, target) {
|
|
|
21
21
|
}
|
|
22
22
|
verified.add(target);
|
|
23
23
|
}
|
|
24
|
+
/**
|
|
25
|
+
* Runs `validate` against a reader's metadata the first time this process sees the pair, then remembers it.
|
|
26
|
+
*
|
|
27
|
+
* @remarks An absent metadata answer needs no check; a verified pair is returned untouched, so the
|
|
28
|
+
* shape assertion runs once per `(reader, target)` rather than per container.
|
|
29
|
+
*/
|
|
30
|
+
function verifyOnce(cache, reader, target, metadata, validate) {
|
|
31
|
+
if (metadata === undefined || isVerified(cache, reader, target)) {
|
|
32
|
+
return metadata;
|
|
33
|
+
}
|
|
34
|
+
validate(metadata);
|
|
35
|
+
markVerified(cache, reader, target);
|
|
36
|
+
return metadata;
|
|
37
|
+
}
|
|
24
38
|
/**
|
|
25
39
|
* A reader's constructor metadata for a class, verified the first time this process asks.
|
|
26
40
|
*
|
|
@@ -31,16 +45,9 @@ function markVerified(cache, reader, target) {
|
|
|
31
45
|
* @since 0.6.0
|
|
32
46
|
*/
|
|
33
47
|
export function verifyConstructorMetadata(reader, target) {
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
}
|
|
38
|
-
if (isVerified(verifiedTargets, reader, target)) {
|
|
39
|
-
return metadata;
|
|
40
|
-
}
|
|
41
|
-
assertConstructorMetadata(metadata, target);
|
|
42
|
-
markVerified(verifiedTargets, reader, target);
|
|
43
|
-
return metadata;
|
|
48
|
+
return verifyOnce(verifiedTargets, reader, target, reader.getConstructorMetadata(target), (metadata) => {
|
|
49
|
+
assertConstructorMetadata(metadata, target);
|
|
50
|
+
});
|
|
44
51
|
}
|
|
45
52
|
/**
|
|
46
53
|
* Verifies what a reader claims about a class, since a `MetadataReader` is a public seam.
|
|
@@ -81,29 +88,25 @@ export function assertConstructorMetadata(metadata, target) {
|
|
|
81
88
|
* @since 0.6.0
|
|
82
89
|
*/
|
|
83
90
|
export function verifyLifecycleMetadata(reader, target) {
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
}
|
|
88
|
-
if (typeof metadata !== "object" || metadata === null) {
|
|
89
|
-
throw new InvalidMetadataError(target.name, `lifecycle metadata: expected an object, received ${typeof metadata}`);
|
|
90
|
-
}
|
|
91
|
-
for (const phase of ["postConstruct", "preDestroy"]) {
|
|
92
|
-
const methods = Reflect.get(metadata, phase);
|
|
93
|
-
if (methods === undefined) {
|
|
94
|
-
continue;
|
|
91
|
+
return verifyOnce(verifiedLifecycleTargets, reader, target, reader.getLifecycleMetadata(target), (metadata) => {
|
|
92
|
+
if (typeof metadata !== "object" || metadata === null) {
|
|
93
|
+
throw new InvalidMetadataError(target.name, `lifecycle metadata: expected an object, received ${typeof metadata}`);
|
|
95
94
|
}
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
95
|
+
for (const phase of ["postConstruct", "preDestroy"]) {
|
|
96
|
+
const methods = Reflect.get(metadata, phase);
|
|
97
|
+
if (methods === undefined) {
|
|
98
|
+
continue;
|
|
99
|
+
}
|
|
100
|
+
if (!Array.isArray(methods)) {
|
|
101
|
+
throw new InvalidMetadataError(target.name, `lifecycle metadata: ${phase} is not an array`);
|
|
102
|
+
}
|
|
103
|
+
for (const [position, name] of methods.entries()) {
|
|
104
|
+
if (typeof name !== "string") {
|
|
105
|
+
throw new InvalidMetadataError(target.name, `lifecycle metadata: ${phase}[${String(position)}] is not a string`);
|
|
106
|
+
}
|
|
102
107
|
}
|
|
103
108
|
}
|
|
104
|
-
}
|
|
105
|
-
markVerified(verifiedLifecycleTargets, reader, target);
|
|
106
|
-
return metadata;
|
|
109
|
+
});
|
|
107
110
|
}
|
|
108
111
|
/**
|
|
109
112
|
* A reader's accessor metadata for a class, verified the first time this process asks.
|
|
@@ -111,32 +114,28 @@ export function verifyLifecycleMetadata(reader, target) {
|
|
|
111
114
|
* @since 0.6.0
|
|
112
115
|
*/
|
|
113
116
|
export function verifyAccessorMetadata(reader, target) {
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
}
|
|
118
|
-
if (!Array.isArray(metadata)) {
|
|
119
|
-
throw new InvalidMetadataError(target.name, "accessor metadata: expected an array");
|
|
120
|
-
}
|
|
121
|
-
for (const [position, entry] of metadata.entries()) {
|
|
122
|
-
if (typeof entry !== "object" || entry === null) {
|
|
123
|
-
throw new InvalidMetadataError(target.name, `accessor metadata: [${String(position)}] is not an object`);
|
|
124
|
-
}
|
|
125
|
-
const key = Reflect.get(entry, "key");
|
|
126
|
-
if (typeof key !== "string" && typeof key !== "symbol") {
|
|
127
|
-
throw new InvalidMetadataError(target.name, `accessor metadata: [${String(position)}].key is not a string or symbol`);
|
|
117
|
+
return verifyOnce(verifiedAccessorTargets, reader, target, reader.getAccessorMetadata?.(target), (metadata) => {
|
|
118
|
+
if (!Array.isArray(metadata)) {
|
|
119
|
+
throw new InvalidMetadataError(target.name, "accessor metadata: expected an array");
|
|
128
120
|
}
|
|
129
|
-
const
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
121
|
+
for (const [position, entry] of metadata.entries()) {
|
|
122
|
+
if (typeof entry !== "object" || entry === null) {
|
|
123
|
+
throw new InvalidMetadataError(target.name, `accessor metadata: [${String(position)}] is not an object`);
|
|
124
|
+
}
|
|
125
|
+
const key = Reflect.get(entry, "key");
|
|
126
|
+
if (typeof key !== "string" && typeof key !== "symbol") {
|
|
127
|
+
throw new InvalidMetadataError(target.name, `accessor metadata: [${String(position)}].key is not a string or symbol`);
|
|
128
|
+
}
|
|
129
|
+
const descriptor = Reflect.get(entry, "descriptor");
|
|
130
|
+
if (typeof descriptor !== "object" || descriptor === null) {
|
|
131
|
+
throw new InvalidMetadataError(target.name, `accessor metadata: [${String(position)}].descriptor is not an object`);
|
|
132
|
+
}
|
|
133
|
+
const dependency = Reflect.get(descriptor, "token");
|
|
134
|
+
if (typeof dependency !== "object" && typeof dependency !== "function") {
|
|
135
|
+
throw new InvalidMetadataError(target.name, `accessor metadata: [${String(position)}].descriptor.token is not a token or a class`);
|
|
136
|
+
}
|
|
136
137
|
}
|
|
137
|
-
}
|
|
138
|
-
markVerified(verifiedAccessorTargets, reader, target);
|
|
139
|
-
return metadata;
|
|
138
|
+
});
|
|
140
139
|
}
|
|
141
140
|
const cachesByReader = new WeakMap();
|
|
142
141
|
function cachesFor(reader) {
|