@codefast/di 0.3.16-canary.2 → 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.
Files changed (65) hide show
  1. package/CHANGELOG.md +16 -0
  2. package/README.md +5 -17
  3. package/dist/binding.d.mts +24 -24
  4. package/dist/constraints.d.mts +3 -3
  5. package/dist/container.d.mts +3 -3
  6. package/dist/container.mjs +89 -157
  7. package/dist/decorators/inject.d.mts +3 -2
  8. package/dist/decorators/inject.mjs +14 -41
  9. package/dist/decorators/injectable.mjs +4 -12
  10. package/dist/decorators/lifecycle-decorators.mjs +13 -74
  11. package/dist/dependency-graph.d.mts +1 -1
  12. package/dist/dependency-graph.mjs +6 -4
  13. package/dist/graph-adapters/cytoscape.d.mts +12 -12
  14. package/dist/graph-adapters/cytoscape.mjs +7 -7
  15. package/dist/graph-adapters/reactflow.d.mts +15 -15
  16. package/dist/graph-adapters/reactflow.mjs +6 -9
  17. package/dist/index.d.mts +6 -6
  18. package/dist/index.mjs +1 -1
  19. package/dist/inspector.d.mts +3 -2
  20. package/dist/inspector.mjs +7 -10
  21. package/dist/lifecycle.mjs +2 -12
  22. package/dist/metadata/metadata-keys.d.mts +8 -33
  23. package/dist/metadata/metadata-keys.mjs +8 -21
  24. package/dist/metadata/metadata-types.d.mts +5 -0
  25. package/dist/metadata/symbol-metadata-reader.d.mts +1 -0
  26. package/dist/metadata/symbol-metadata-reader.mjs +11 -33
  27. package/dist/module.mjs +1 -1
  28. package/dist/registry.mjs +3 -22
  29. package/dist/resolve-options.d.mts +2 -2
  30. package/dist/resolve-options.mjs +10 -8
  31. package/dist/resolver.d.mts +6 -1
  32. package/dist/resolver.mjs +15 -21
  33. package/dist/types.d.mts +10 -4
  34. package/package.json +40 -14
  35. package/src/binding-scope.ts +26 -0
  36. package/src/binding-select.ts +158 -0
  37. package/src/binding.ts +277 -0
  38. package/src/constraints.ts +121 -0
  39. package/src/constructor-type.ts +19 -0
  40. package/src/container.ts +1135 -0
  41. package/src/decorators/inject.ts +222 -0
  42. package/src/decorators/injectable.ts +85 -0
  43. package/src/decorators/lifecycle-decorators.ts +51 -0
  44. package/src/dependency-graph.ts +116 -0
  45. package/src/environment.ts +207 -0
  46. package/src/errors.ts +260 -0
  47. package/src/graph-adapters/cytoscape.ts +64 -0
  48. package/src/graph-adapters/dot.ts +22 -0
  49. package/src/graph-adapters/reactflow.ts +58 -0
  50. package/src/index.ts +101 -0
  51. package/src/inspector.ts +125 -0
  52. package/src/lifecycle.ts +217 -0
  53. package/src/metadata/metadata-keys.ts +25 -0
  54. package/src/metadata/metadata-reader-token.ts +8 -0
  55. package/src/metadata/metadata-types.ts +51 -0
  56. package/src/metadata/symbol-metadata-reader.ts +45 -0
  57. package/src/module.ts +93 -0
  58. package/src/registry.ts +232 -0
  59. package/src/resolve-options.ts +42 -0
  60. package/src/resolver.ts +1609 -0
  61. package/src/scope.ts +77 -0
  62. package/src/token.ts +40 -0
  63. package/src/types.ts +123 -0
  64. package/dist/graph-adapters/types.d.mts +0 -2
  65. package/dist/graph-adapters/types.mjs +0 -1
@@ -1,7 +1,7 @@
1
1
  import { InternalError, MissingContainerContextError } from "../errors.mjs";
2
2
  import { getActiveContainer } from "../environment.mjs";
3
+ import { INJECT_ACCESSOR_KEY } from "../metadata/metadata-keys.mjs";
3
4
  import { injectionSlotToResolveOptions } from "../resolve-options.mjs";
4
- import { INJECT_ACCESSOR_KEY, accessorMetadataByMetadataObjectMap } from "../metadata/metadata-keys.mjs";
5
5
  //#region src/decorators/inject.ts
6
6
  /**
7
7
  * @since 0.3.16-canary.0
@@ -54,12 +54,7 @@ function materializeInjectionDescriptor(dependency) {
54
54
  };
55
55
  return base;
56
56
  }
57
- function buildInjectionDescriptor(token, options) {
58
- const base = {
59
- token,
60
- optional: false,
61
- multi: false
62
- };
57
+ function withOptions(base, options) {
63
58
  if (options?.name !== void 0 && options.tags !== void 0) return {
64
59
  ...base,
65
60
  name: options.name,
@@ -75,20 +70,26 @@ function buildInjectionDescriptor(token, options) {
75
70
  };
76
71
  return base;
77
72
  }
73
+ function buildInjectionDescriptor(token, options) {
74
+ return withOptions({
75
+ token,
76
+ optional: false,
77
+ multi: false
78
+ }, options);
79
+ }
78
80
  /**
79
81
  * @since 0.3.16-canary.0
80
82
  */
81
83
  function inject(token, options) {
82
84
  const descriptor = buildInjectionDescriptor(token, options);
83
85
  const decoratorFn = (_target, context) => {
84
- if (context.static === true) throw new InternalError("@inject() on static accessors is not supported; only instance accessors participate in runWithContainer-based property injection.");
86
+ if (context.static) throw new InternalError("@inject() on static accessors is not supported; only instance accessors participate in runWithContainer-based property injection.");
85
87
  const meta = context.metadata;
86
88
  if (!Array.isArray(meta[INJECT_ACCESSOR_KEY])) meta[INJECT_ACCESSOR_KEY] = [];
87
89
  meta[INJECT_ACCESSOR_KEY].push({
88
90
  key: context.name,
89
91
  descriptor
90
92
  });
91
- accessorMetadataByMetadataObjectMap.set(context.metadata, meta[INJECT_ACCESSOR_KEY]);
92
93
  context.addInitializer(function() {
93
94
  const container = getActiveContainer();
94
95
  if (container === void 0) throw new MissingContainerContextError(String(context.name));
@@ -115,49 +116,21 @@ function inject(token, options) {
115
116
  * @since 0.3.16-canary.0
116
117
  */
117
118
  function optional(token, options) {
118
- const base = {
119
+ return withOptions({
119
120
  token,
120
121
  optional: true,
121
122
  multi: false
122
- };
123
- if (options?.name !== void 0 && options.tags !== void 0) return {
124
- ...base,
125
- name: options.name,
126
- tags: options.tags
127
- };
128
- if (options?.name !== void 0) return {
129
- ...base,
130
- name: options.name
131
- };
132
- if (options?.tags !== void 0) return {
133
- ...base,
134
- tags: options.tags
135
- };
136
- return base;
123
+ }, options);
137
124
  }
138
125
  /**
139
126
  * @since 0.3.16-canary.0
140
127
  */
141
128
  function injectAll(token, options) {
142
- const base = {
129
+ return withOptions({
143
130
  token,
144
131
  optional: false,
145
132
  multi: true
146
- };
147
- if (options?.name !== void 0 && options.tags !== void 0) return {
148
- ...base,
149
- name: options.name,
150
- tags: options.tags
151
- };
152
- if (options?.name !== void 0) return {
153
- ...base,
154
- name: options.name
155
- };
156
- if (options?.tags !== void 0) return {
157
- ...base,
158
- tags: options.tags
159
- };
160
- return base;
133
+ }, options);
161
134
  }
162
135
  //#endregion
163
136
  export { inject, injectAll, isInjectionDescriptor, normalizeToDescriptor, optional };
@@ -1,4 +1,4 @@
1
- import { INJECTABLE_KEY, INJECT_ACCESSOR_KEY, accessorMetadataByConstructorMap, constructorMetadataMap } from "../metadata/metadata-keys.mjs";
1
+ import { INJECTABLE_KEY } from "../metadata/metadata-keys.mjs";
2
2
  import { normalizeToDescriptor } from "./inject.mjs";
3
3
  //#region src/decorators/injectable.ts
4
4
  /**
@@ -23,7 +23,7 @@ function createAutoRegisterRegistry() {
23
23
  */
24
24
  function injectable(deps, options) {
25
25
  return function(target, context) {
26
- const constructorMetadata = { params: (deps ?? []).map((dependency, index) => {
26
+ const parameterMetadataList = (deps ?? []).map((dependency, index) => {
27
27
  const descriptor = normalizeToDescriptor(dependency);
28
28
  const baseParameterMetadata = {
29
29
  index,
@@ -45,16 +45,8 @@ function injectable(deps, options) {
45
45
  tags: descriptor.tags
46
46
  };
47
47
  return baseParameterMetadata;
48
- }) };
49
- constructorMetadataMap.set(target, constructorMetadata);
50
- try {
51
- const metadata = context.metadata;
52
- if (metadata !== null && typeof metadata === "object") {
53
- const accessorList = metadata[INJECT_ACCESSOR_KEY];
54
- if (Array.isArray(accessorList) && accessorList.length > 0) accessorMetadataByConstructorMap.set(target, accessorList);
55
- metadata[INJECTABLE_KEY] = constructorMetadata;
56
- }
57
- } catch {}
48
+ });
49
+ context.metadata[INJECTABLE_KEY] = { params: parameterMetadataList };
58
50
  if (options?.autoRegister !== void 0) {
59
51
  const scope = options.scope ?? "transient";
60
52
  options.autoRegister.register(target, scope);
@@ -1,61 +1,22 @@
1
1
  import { InternalError } from "../errors.mjs";
2
- import { LIFECYCLE_KEY, lifecycleByConstructorMetadataMap, lifecycleMetadataMap } from "../metadata/metadata-keys.mjs";
2
+ import { LIFECYCLE_KEY } from "../metadata/metadata-keys.mjs";
3
3
  //#region src/decorators/lifecycle-decorators.ts
4
4
  function appendUniqueMethod(metadata, phase, methodName) {
5
5
  if (!metadata[phase].includes(methodName)) metadata[phase].push(methodName);
6
6
  }
7
- function resolveConstructorFromDecoratorTarget(target) {
8
- if (typeof target === "function") return target;
9
- if (typeof target === "object" && target !== null) {
10
- const ctor = target.constructor;
11
- if (typeof ctor === "function") return ctor;
12
- }
13
- }
14
- function registerByConstructor(target, phase, methodName) {
15
- const ctor = resolveConstructorFromDecoratorTarget(target);
16
- if (ctor === void 0) return;
17
- const ctorExisting = lifecycleByConstructorMetadataMap.get(ctor);
18
- if (ctorExisting !== void 0) appendUniqueMethod(ctorExisting, phase, methodName);
19
- else lifecycleByConstructorMetadataMap.set(ctor, {
20
- postConstruct: phase === "postConstruct" ? [methodName] : [],
21
- preDestroy: phase === "preDestroy" ? [methodName] : []
22
- });
23
- }
24
7
  /**
25
8
  * @since 0.3.16-canary.0
26
9
  */
27
10
  function postConstruct() {
28
11
  return function(target, context) {
29
- if (context.static === true) throw new InternalError("@postConstruct() applies to instance methods only; static methods are not invoked during instance lifecycle.");
12
+ if (context.static) throw new InternalError("@postConstruct() applies to instance methods only; static methods are not invoked during instance lifecycle.");
30
13
  const methodName = String(context.name);
31
- registerByConstructor(target, "postConstruct", methodName);
32
- const existing = lifecycleMetadataMap.get(context.metadata);
33
- if (existing !== void 0) appendUniqueMethod(existing, "postConstruct", methodName);
34
- else lifecycleMetadataMap.set(context.metadata, {
35
- postConstruct: [methodName],
14
+ const meta = context.metadata;
15
+ if (!meta[LIFECYCLE_KEY]) meta[LIFECYCLE_KEY] = {
16
+ postConstruct: [],
36
17
  preDestroy: []
37
- });
38
- context.addInitializer(function() {
39
- const targetOrInstance = this;
40
- const ctor = typeof targetOrInstance === "function" ? targetOrInstance : targetOrInstance.constructor;
41
- const ctorExisting = lifecycleByConstructorMetadataMap.get(ctor);
42
- if (ctorExisting !== void 0) appendUniqueMethod(ctorExisting, "postConstruct", methodName);
43
- else lifecycleByConstructorMetadataMap.set(ctor, {
44
- postConstruct: [methodName],
45
- preDestroy: []
46
- });
47
- });
48
- try {
49
- const meta = context.metadata;
50
- if (meta !== null && typeof meta === "object") {
51
- if (!meta[LIFECYCLE_KEY]) meta[LIFECYCLE_KEY] = {
52
- postConstruct: [],
53
- preDestroy: []
54
- };
55
- const lifecycle = meta[LIFECYCLE_KEY];
56
- appendUniqueMethod(lifecycle, "postConstruct", methodName);
57
- }
58
- } catch {}
18
+ };
19
+ appendUniqueMethod(meta[LIFECYCLE_KEY], "postConstruct", methodName);
59
20
  };
60
21
  }
61
22
  /**
@@ -63,36 +24,14 @@ function postConstruct() {
63
24
  */
64
25
  function preDestroy() {
65
26
  return function(target, context) {
66
- if (context.static === true) throw new InternalError("@preDestroy() applies to instance methods only; static methods are not invoked during instance teardown.");
27
+ if (context.static) throw new InternalError("@preDestroy() applies to instance methods only; static methods are not invoked during instance teardown.");
67
28
  const methodName = String(context.name);
68
- registerByConstructor(target, "preDestroy", methodName);
69
- const existing = lifecycleMetadataMap.get(context.metadata);
70
- if (existing !== void 0) appendUniqueMethod(existing, "preDestroy", methodName);
71
- else lifecycleMetadataMap.set(context.metadata, {
29
+ const meta = context.metadata;
30
+ if (!meta[LIFECYCLE_KEY]) meta[LIFECYCLE_KEY] = {
72
31
  postConstruct: [],
73
- preDestroy: [methodName]
74
- });
75
- context.addInitializer(function() {
76
- const targetOrInstance = this;
77
- const ctor = typeof targetOrInstance === "function" ? targetOrInstance : targetOrInstance.constructor;
78
- const ctorExisting = lifecycleByConstructorMetadataMap.get(ctor);
79
- if (ctorExisting !== void 0) appendUniqueMethod(ctorExisting, "preDestroy", methodName);
80
- else lifecycleByConstructorMetadataMap.set(ctor, {
81
- postConstruct: [],
82
- preDestroy: [methodName]
83
- });
84
- });
85
- try {
86
- const meta = context.metadata;
87
- if (meta !== null && typeof meta === "object") {
88
- if (!meta[LIFECYCLE_KEY]) meta[LIFECYCLE_KEY] = {
89
- postConstruct: [],
90
- preDestroy: []
91
- };
92
- const lifecycle = meta[LIFECYCLE_KEY];
93
- appendUniqueMethod(lifecycle, "preDestroy", methodName);
94
- }
95
- } catch {}
32
+ preDestroy: []
33
+ };
34
+ appendUniqueMethod(meta[LIFECYCLE_KEY], "preDestroy", methodName);
96
35
  };
97
36
  }
98
37
  //#endregion
@@ -1,6 +1,6 @@
1
1
  import { BindingScope } from "./types.mjs";
2
- import { BindingRegistry } from "./registry.mjs";
3
2
  import { MetadataReader } from "./metadata/metadata-types.mjs";
3
+ import { BindingRegistry } from "./registry.mjs";
4
4
 
5
5
  //#region src/dependency-graph.d.ts
6
6
  /**
@@ -20,15 +20,17 @@ function buildDependencyGraph(registry, metadataReader, options, parentRegistry)
20
20
  });
21
21
  if (binding.kind === "class") {
22
22
  const meta = metadataReader.getConstructorMetadata(binding.target);
23
- if (meta !== void 0) meta.params.forEach((param, index) => {
23
+ if (meta !== void 0) for (let index = 0; index < meta.params.length; index += 1) {
24
+ const param = meta.params[index];
24
25
  const dependencyBinding = sourceRegistry.getAll(param.token)[0];
25
26
  if (dependencyBinding !== void 0) edges.push({
26
27
  from: binding.id,
27
28
  to: dependencyBinding.id,
28
29
  label: `[${index}]`
29
30
  });
30
- });
31
- } else if (binding.kind === "resolved" || binding.kind === "resolved-async") binding.deps.forEach((dependency, index) => {
31
+ }
32
+ } else if (binding.kind === "resolved" || binding.kind === "resolved-async") for (let index = 0; index < binding.deps.length; index += 1) {
33
+ const dependency = binding.deps[index];
32
34
  const dependencyBindings = sourceRegistry.getAll(dependency.token);
33
35
  if (dependencyBindings.length > 0 && dependencyBindings[0] !== void 0) {
34
36
  const label = dependency.name !== void 0 ? `name:${dependency.name}` : dependency.tags !== void 0 && dependency.tags.length > 0 ? `tag:${dependency.tags[0]?.[0]}=${String(dependency.tags[0]?.[1])}` : `[${index}]`;
@@ -38,7 +40,7 @@ function buildDependencyGraph(registry, metadataReader, options, parentRegistry)
38
40
  label
39
41
  });
40
42
  }
41
- });
43
+ }
42
44
  else if (binding.kind === "alias") {
43
45
  const targetBindings = sourceRegistry.getAll(binding.target);
44
46
  if (targetBindings.length > 0 && targetBindings[0] !== void 0) edges.push({
@@ -5,29 +5,29 @@ import { ContainerGraphJson } from "../dependency-graph.mjs";
5
5
  * @since 0.3.16-canary.0
6
6
  */
7
7
  interface CytoscapeNode {
8
- data: {
9
- id: string;
10
- label: string;
11
- kind: string;
12
- scope: string;
13
- fromParent: boolean;
8
+ readonly data: {
9
+ readonly id: string;
10
+ readonly label: string;
11
+ readonly kind: string;
12
+ readonly scope: string;
13
+ readonly fromParent: boolean;
14
14
  };
15
15
  }
16
16
  /**
17
17
  * @since 0.3.16-canary.0
18
18
  */
19
19
  interface CytoscapeEdge {
20
- data: {
21
- id: string;
22
- source: string;
23
- target: string;
24
- label?: string;
20
+ readonly data: {
21
+ readonly id: string;
22
+ readonly source: string;
23
+ readonly target: string;
24
+ readonly label?: string;
25
25
  };
26
26
  }
27
27
  /**
28
28
  * @since 0.3.16-canary.0
29
29
  */
30
- type CytoscapeElements = Array<CytoscapeNode | CytoscapeEdge>;
30
+ type CytoscapeElements = ReadonlyArray<CytoscapeNode | CytoscapeEdge>;
31
31
  /**
32
32
  * @since 0.3.16-canary.0
33
33
  */
@@ -11,15 +11,15 @@ function toCytoscapeGraph(graph) {
11
11
  scope: node.scope,
12
12
  fromParent: node.fromParent
13
13
  } });
14
- graph.edges.forEach((edge, idx) => {
15
- const data = {
14
+ for (let idx = 0; idx < graph.edges.length; idx += 1) {
15
+ const edge = graph.edges[idx];
16
+ elements.push({ data: {
16
17
  id: `edge-${idx}`,
17
18
  source: edge.from,
18
- target: edge.to
19
- };
20
- if (edge.label !== void 0) data.label = edge.label;
21
- elements.push({ data });
22
- });
19
+ target: edge.to,
20
+ ...edge.label !== void 0 ? { label: edge.label } : {}
21
+ } });
22
+ }
23
23
  return elements;
24
24
  }
25
25
  //#endregion
@@ -5,33 +5,33 @@ import { ContainerGraphJson } from "../dependency-graph.mjs";
5
5
  * @since 0.3.16-canary.0
6
6
  */
7
7
  interface ReactFlowNode {
8
- id: string;
9
- data: {
10
- label: string;
11
- kind: string;
12
- scope: string;
13
- fromParent: boolean;
8
+ readonly id: string;
9
+ readonly data: {
10
+ readonly label: string;
11
+ readonly kind: string;
12
+ readonly scope: string;
13
+ readonly fromParent: boolean;
14
14
  };
15
- position: {
16
- x: number;
17
- y: number;
15
+ readonly position: {
16
+ readonly x: number;
17
+ readonly y: number;
18
18
  };
19
19
  }
20
20
  /**
21
21
  * @since 0.3.16-canary.0
22
22
  */
23
23
  interface ReactFlowEdge {
24
- id: string;
25
- source: string;
26
- target: string;
27
- label?: string;
24
+ readonly id: string;
25
+ readonly source: string;
26
+ readonly target: string;
27
+ readonly label?: string;
28
28
  }
29
29
  /**
30
30
  * @since 0.3.16-canary.0
31
31
  */
32
32
  interface ReactFlowGraph {
33
- nodes: Array<ReactFlowNode>;
34
- edges: Array<ReactFlowEdge>;
33
+ readonly nodes: ReadonlyArray<ReactFlowNode>;
34
+ readonly edges: ReadonlyArray<ReactFlowEdge>;
35
35
  }
36
36
  /**
37
37
  * @since 0.3.16-canary.0
@@ -17,15 +17,12 @@ function toReactFlowGraph(graph) {
17
17
  y: Math.floor(idx / 5) * 100
18
18
  }
19
19
  })),
20
- edges: graph.edges.map((edge, idx) => {
21
- const reactFlowEdge = {
22
- id: `edge-${idx}`,
23
- source: edge.from,
24
- target: edge.to
25
- };
26
- if (edge.label !== void 0) reactFlowEdge.label = edge.label;
27
- return reactFlowEdge;
28
- })
20
+ edges: graph.edges.map((edge, idx) => ({
21
+ id: `edge-${idx}`,
22
+ source: edge.from,
23
+ target: edge.to,
24
+ ...edge.label !== void 0 ? { label: edge.label } : {}
25
+ }))
29
26
  };
30
27
  }
31
28
  //#endregion
package/dist/index.d.mts CHANGED
@@ -1,18 +1,18 @@
1
1
  import { Constructor } from "./constructor-type.mjs";
2
2
  import { Token, isToken, token, tokenName } from "./token.mjs";
3
- import { ActivationHandler, BindingIdentifier, BindingKind, BindingScope, ConstraintContext, DeactivationHandler, DependencyKey, ResolutionContext, ResolutionFrame, ResolveOptions, TokenValue } from "./types.mjs";
3
+ import { ActivationHandler, BindingIdentifier, BindingKind, BindingScope, BindingTag, ConstraintContext, DeactivationHandler, DependencyKey, ResolutionContext, ResolutionFrame, ResolveOptions, TokenValue } from "./types.mjs";
4
4
  import { InjectOptions, InjectableDependency, InjectionDescriptor, inject, injectAll, isInjectionDescriptor, optional } from "./decorators/inject.mjs";
5
- import { AliasBindingBuilder, BindToBuilder, BindingBuilder, ConstantBindingBuilder, ScopedBindingBuilder, SingletonBindingBuilder, SingletonLifecycleBuilder, TransientBindingBuilder } from "./binding.mjs";
5
+ import { AliasBindingBuilder, BindToBuilder, BindingBuilder, ConstantBindingBuilder, ScopedBindingBuilder, SingletonBindingBuilder, SingletonLifecycleBuilder, SlotConstrainedBuilder, TransientBindingBuilder } from "./binding.mjs";
6
6
  import { effectiveBindingScope } from "./binding-scope.mjs";
7
7
  import { whenAnyAncestorIs, whenAnyAncestorNamed, whenAnyAncestorTagged, whenAnyAncestorTaggedAll, whenNoAncestorIs, whenNoParentIs, whenParentIs, whenParentNamed, whenParentTagged, whenParentTaggedAll } from "./constraints.mjs";
8
- import { AsyncModule, AsyncModuleBuilder, Module, ModuleBuilder, SyncModule, isSyncModule } from "./module.mjs";
9
- import { BindingSnapshot, ContainerSnapshot } from "./inspector.mjs";
8
+ import { AutoRegisterRegistry, InjectableOptions, createAutoRegisterRegistry, injectable } from "./decorators/injectable.mjs";
10
9
  import { MetadataReader, MutableLifecycleMetadata } from "./metadata/metadata-types.mjs";
11
10
  import { ContainerGraphJson, GraphEdge, GraphNode, GraphOptions } from "./dependency-graph.mjs";
12
- import { AutoRegisterRegistry, InjectableOptions, createAutoRegisterRegistry, injectable } from "./decorators/injectable.mjs";
11
+ import { BindingSnapshot, ContainerSnapshot } from "./inspector.mjs";
12
+ import { AsyncModule, AsyncModuleBuilder, Module, ModuleBuilder, SyncModule, isSyncModule } from "./module.mjs";
13
13
  import { Container, ContainerStatic } from "./container.mjs";
14
14
  import { postConstruct, preDestroy } from "./decorators/lifecycle-decorators.mjs";
15
15
  import { AmbiguousBindingError, AsyncActivationError, AsyncDeactivationError, AsyncModuleLoadError, AsyncResolutionError, CircularDependencyError, DiError, DisposedContainerError, InternalError, MissingContainerContextError, MissingMetadataError, MissingScopeContextError, NoMatchingBindingError, RebindUnboundTokenError, ScopeViolationDetails, ScopeViolationError, SyncDisposalNotSupportedError, TokenNotBoundError } from "./errors.mjs";
16
16
  import { bindingSlotToResolveOptions, injectionSlotToResolveOptions } from "./resolve-options.mjs";
17
17
  import { MetadataReaderToken } from "./metadata/metadata-reader-token.mjs";
18
- export { type ActivationHandler, type AliasBindingBuilder, AmbiguousBindingError, AsyncActivationError, AsyncDeactivationError, AsyncModule, type AsyncModuleBuilder, AsyncModuleLoadError, AsyncResolutionError, type AutoRegisterRegistry, type BindToBuilder, type BindingBuilder, type BindingIdentifier, type BindingKind, type BindingScope, type BindingSnapshot, CircularDependencyError, type ConstantBindingBuilder, type ConstraintContext, type Constructor, Container, type ContainerGraphJson, type Container as ContainerInterface, type ContainerSnapshot, type ContainerStatic, type DeactivationHandler, type DependencyKey, DiError, DisposedContainerError, type GraphEdge, type GraphNode, type GraphOptions, type InjectOptions, type InjectableDependency, type InjectableOptions, type InjectionDescriptor, InternalError, type MetadataReader, MetadataReaderToken, MissingContainerContextError, MissingMetadataError, MissingScopeContextError, Module, type ModuleBuilder, type MutableLifecycleMetadata, NoMatchingBindingError, RebindUnboundTokenError, type ResolutionContext, type ResolutionFrame, type ResolveOptions, type ScopeViolationDetails, ScopeViolationError, type ScopedBindingBuilder, type SingletonBindingBuilder, type SingletonLifecycleBuilder, SyncDisposalNotSupportedError, SyncModule, type Token, TokenNotBoundError, type TokenValue, type TransientBindingBuilder, bindingSlotToResolveOptions, createAutoRegisterRegistry, effectiveBindingScope, inject, injectAll, injectable, injectionSlotToResolveOptions, isInjectionDescriptor, isSyncModule, isToken, optional, postConstruct, preDestroy, token, tokenName, whenAnyAncestorIs, whenAnyAncestorNamed, whenAnyAncestorTagged, whenAnyAncestorTaggedAll, whenNoAncestorIs, whenNoParentIs, whenParentIs, whenParentNamed, whenParentTagged, whenParentTaggedAll };
18
+ export { type ActivationHandler, type AliasBindingBuilder, AmbiguousBindingError, AsyncActivationError, AsyncDeactivationError, AsyncModule, type AsyncModuleBuilder, AsyncModuleLoadError, AsyncResolutionError, type AutoRegisterRegistry, type BindToBuilder, type BindingBuilder, type BindingIdentifier, type BindingKind, type BindingScope, type BindingSnapshot, type BindingTag, CircularDependencyError, type ConstantBindingBuilder, type ConstraintContext, type Constructor, Container, type ContainerGraphJson, type Container as ContainerInterface, type ContainerSnapshot, type ContainerStatic, type DeactivationHandler, type DependencyKey, DiError, DisposedContainerError, type GraphEdge, type GraphNode, type GraphOptions, type InjectOptions, type InjectableDependency, type InjectableOptions, type InjectionDescriptor, InternalError, type MetadataReader, MetadataReaderToken, MissingContainerContextError, MissingMetadataError, MissingScopeContextError, Module, type ModuleBuilder, type MutableLifecycleMetadata, NoMatchingBindingError, RebindUnboundTokenError, type ResolutionContext, type ResolutionFrame, type ResolveOptions, type ScopeViolationDetails, ScopeViolationError, type ScopedBindingBuilder, type SingletonBindingBuilder, type SingletonLifecycleBuilder, type SlotConstrainedBuilder, SyncDisposalNotSupportedError, SyncModule, type Token, TokenNotBoundError, type TokenValue, type TransientBindingBuilder, bindingSlotToResolveOptions, createAutoRegisterRegistry, effectiveBindingScope, inject, injectAll, injectable, injectionSlotToResolveOptions, isInjectionDescriptor, isSyncModule, isToken, optional, postConstruct, preDestroy, token, tokenName, whenAnyAncestorIs, whenAnyAncestorNamed, whenAnyAncestorTagged, whenAnyAncestorTaggedAll, whenNoAncestorIs, whenNoParentIs, whenParentIs, whenParentNamed, whenParentTagged, whenParentTaggedAll };
package/dist/index.mjs CHANGED
@@ -3,8 +3,8 @@ import { AmbiguousBindingError, AsyncActivationError, AsyncDeactivationError, As
3
3
  import { isToken, token, tokenName } from "./token.mjs";
4
4
  import { whenAnyAncestorIs, whenAnyAncestorNamed, whenAnyAncestorTagged, whenAnyAncestorTaggedAll, whenNoAncestorIs, whenNoParentIs, whenParentIs, whenParentNamed, whenParentTagged, whenParentTaggedAll } from "./constraints.mjs";
5
5
  import { bindingSlotToResolveOptions, injectionSlotToResolveOptions } from "./resolve-options.mjs";
6
- import { MetadataReaderToken } from "./metadata/metadata-reader-token.mjs";
7
6
  import { inject, injectAll, isInjectionDescriptor, optional } from "./decorators/inject.mjs";
7
+ import { MetadataReaderToken } from "./metadata/metadata-reader-token.mjs";
8
8
  import { AsyncModule, Module, SyncModule, isSyncModule } from "./module.mjs";
9
9
  import { Container } from "./container.mjs";
10
10
  import { createAutoRegisterRegistry, injectable } from "./decorators/injectable.mjs";
@@ -1,6 +1,6 @@
1
1
  import { Constructor } from "./constructor-type.mjs";
2
2
  import { Token } from "./token.mjs";
3
- import { BindingIdentifier, BindingKind, BindingScope, ResolveOptions } from "./types.mjs";
3
+ import { BindingIdentifier, BindingKind, BindingScope, BindingTag, ResolveOptions } from "./types.mjs";
4
4
  import { BindingRegistry } from "./registry.mjs";
5
5
  import { ScopeManager } from "./scope.mjs";
6
6
 
@@ -14,7 +14,7 @@ interface BindingSnapshot {
14
14
  readonly scope: BindingScope;
15
15
  readonly slot: {
16
16
  readonly name?: string;
17
- readonly tags: ReadonlyArray<readonly [string, unknown]>;
17
+ readonly tags: ReadonlyArray<BindingTag>;
18
18
  };
19
19
  readonly id: BindingIdentifier;
20
20
  }
@@ -40,6 +40,7 @@ declare class Inspector {
40
40
  lookupBindings<Value>(token: Token<Value> | Constructor<Value>): ReadonlyArray<BindingSnapshot>;
41
41
  has(token: Token<unknown> | Constructor, hint?: ResolveOptions, parentHas?: () => boolean): boolean;
42
42
  hasOwn(token: Token<unknown> | Constructor, hint?: ResolveOptions): boolean;
43
+ private _makeHintContext;
43
44
  private allBindingSnapshots;
44
45
  private _toSnapshot;
45
46
  }
@@ -30,27 +30,24 @@ var Inspector = class {
30
30
  has(token, hint, parentHas) {
31
31
  const bindings = this._registry.getAll(token);
32
32
  if (bindings.length > 0) if (hint !== void 0) {
33
- if (selectBinding(bindings, hint, {
34
- resolutionPath: [],
35
- resolutionStack: [],
36
- parent: void 0,
37
- ancestors: [],
38
- currentResolveHint: hint
39
- }, tokenName(token)) !== void 0) return true;
33
+ if (selectBinding(bindings, hint, this._makeHintContext(hint), tokenName(token)) !== void 0) return true;
40
34
  } else return true;
41
35
  return parentHas?.() ?? false;
42
36
  }
43
37
  hasOwn(token, hint) {
44
38
  const bindings = this._registry.getAll(token);
45
39
  if (bindings.length === 0) return false;
46
- if (hint !== void 0) return selectBinding(bindings, hint, {
40
+ if (hint !== void 0) return selectBinding(bindings, hint, this._makeHintContext(hint), tokenName(token)) !== void 0;
41
+ return true;
42
+ }
43
+ _makeHintContext(hint) {
44
+ return {
47
45
  resolutionPath: [],
48
46
  resolutionStack: [],
49
47
  parent: void 0,
50
48
  ancestors: [],
51
49
  currentResolveHint: hint
52
- }, tokenName(token)) !== void 0;
53
- return true;
50
+ };
54
51
  }
55
52
  allBindingSnapshots() {
56
53
  return this._registry.allBindings().map((binding) => this._toSnapshot(binding));
@@ -10,12 +10,7 @@ var LifecycleManager = class {
10
10
  _activationVersion = 0;
11
11
  registerActivation(token, handler) {
12
12
  this._activationVersion += 1;
13
- let list = this._activationHooks.get(token);
14
- if (list === void 0) {
15
- list = [];
16
- this._activationHooks.set(token, list);
17
- }
18
- list.push(handler);
13
+ this._activationHooks.getOrInsert(token, []).push(handler);
19
14
  }
20
15
  hasActivationHandlers(token) {
21
16
  if (this._activationHooks.size === 0) return false;
@@ -26,12 +21,7 @@ var LifecycleManager = class {
26
21
  return this._activationVersion;
27
22
  }
28
23
  registerDeactivation(token, handler) {
29
- let list = this._deactivationHooks.get(token);
30
- if (list === void 0) {
31
- list = [];
32
- this._deactivationHooks.set(token, list);
33
- }
34
- list.push(handler);
24
+ this._deactivationHooks.getOrInsert(token, []).push(handler);
35
25
  }
36
26
  async runActivation(resolutionContext, binding, instance, metadataReader) {
37
27
  let activatedInstance = instance;
@@ -1,16 +1,4 @@
1
- import { ConstructorMetadata, MutableLifecycleMetadata } from "./metadata-types.mjs";
2
-
3
1
  //#region src/metadata/metadata-keys.d.ts
4
- /**
5
- * Accessor injection entries mirrored from `Symbol.metadata` for toolchains where
6
- * resolver reads stable metadata via the same object identity as `context.metadata`.
7
- *
8
- * @since 0.3.16-canary.0
9
- */
10
- type AccessorInjectionEntryList = Array<{
11
- key: string | symbol;
12
- descriptor: unknown;
13
- }>;
14
2
  /**
15
3
  * @since 0.3.16-canary.0
16
4
  */
@@ -24,29 +12,16 @@ declare const LIFECYCLE_KEY: unique symbol;
24
12
  */
25
13
  declare const INJECT_ACCESSOR_KEY: unique symbol;
26
14
  /**
27
- * @since 0.3.16-canary.0
28
- */
29
- declare const constructorMetadataMap: WeakMap<object, ConstructorMetadata>;
30
- /**
31
- * @since 0.3.16-canary.0
32
- */
33
- declare const lifecycleMetadataMap: WeakMap<object, MutableLifecycleMetadata>;
34
- /**
35
- * @since 0.3.16-canary.0
36
- */
37
- declare const lifecycleByConstructorMetadataMap: WeakMap<object, MutableLifecycleMetadata>;
38
- /**
39
- * Fallback keyed by the class metadata object (`context.metadata` / `ctor[Symbol.metadata]`).
15
+ * The well-known symbol used by TC39 Stage 3 decorator transforms to store class metadata.
40
16
  *
41
- * @since 0.3.16-canary.0
42
- */
43
- declare const accessorMetadataByMetadataObjectMap: WeakMap<object, AccessorInjectionEntryList>;
44
- /**
45
- * Populated from `@injectable()` after field decorators have written `INJECT_ACCESSOR_KEY`
46
- * onto `context.metadata` — same timing as {@link constructorMetadataMap}.
17
+ * `Symbol.metadata` is defined natively once the runtime ships the full TC39 decorator
18
+ * proposal. Until then (current Node.js / browsers), Babel and esbuild both fall back to
19
+ * `Symbol.for("Symbol.metadata")` — a global-registry symbol with the same string key.
20
+ * Resolving it here once keeps the reader and the decorator transforms in sync regardless
21
+ * of which path is taken.
47
22
  *
48
23
  * @since 0.3.16-canary.0
49
24
  */
50
- declare const accessorMetadataByConstructorMap: WeakMap<object, AccessorInjectionEntryList>;
25
+ declare const METADATA_SYMBOL: symbol;
51
26
  //#endregion
52
- export { AccessorInjectionEntryList, INJECTABLE_KEY, INJECT_ACCESSOR_KEY, LIFECYCLE_KEY, accessorMetadataByConstructorMap, accessorMetadataByMetadataObjectMap, constructorMetadataMap, lifecycleByConstructorMetadataMap, lifecycleMetadataMap };
27
+ export { INJECTABLE_KEY, INJECT_ACCESSOR_KEY, LIFECYCLE_KEY, METADATA_SYMBOL };
@@ -12,29 +12,16 @@ const LIFECYCLE_KEY = Symbol("di:lifecycle");
12
12
  */
13
13
  const INJECT_ACCESSOR_KEY = Symbol("di:inject-accessor");
14
14
  /**
15
- * @since 0.3.16-canary.0
16
- */
17
- const constructorMetadataMap = /* @__PURE__ */ new WeakMap();
18
- /**
19
- * @since 0.3.16-canary.0
20
- */
21
- const lifecycleMetadataMap = /* @__PURE__ */ new WeakMap();
22
- /**
23
- * @since 0.3.16-canary.0
24
- */
25
- const lifecycleByConstructorMetadataMap = /* @__PURE__ */ new WeakMap();
26
- /**
27
- * Fallback keyed by the class metadata object (`context.metadata` / `ctor[Symbol.metadata]`).
15
+ * The well-known symbol used by TC39 Stage 3 decorator transforms to store class metadata.
28
16
  *
29
- * @since 0.3.16-canary.0
30
- */
31
- const accessorMetadataByMetadataObjectMap = /* @__PURE__ */ new WeakMap();
32
- /**
33
- * Populated from `@injectable()` after field decorators have written `INJECT_ACCESSOR_KEY`
34
- * onto `context.metadata` — same timing as {@link constructorMetadataMap}.
17
+ * `Symbol.metadata` is defined natively once the runtime ships the full TC39 decorator
18
+ * proposal. Until then (current Node.js / browsers), Babel and esbuild both fall back to
19
+ * `Symbol.for("Symbol.metadata")` — a global-registry symbol with the same string key.
20
+ * Resolving it here once keeps the reader and the decorator transforms in sync regardless
21
+ * of which path is taken.
35
22
  *
36
23
  * @since 0.3.16-canary.0
37
24
  */
38
- const accessorMetadataByConstructorMap = /* @__PURE__ */ new WeakMap();
25
+ const METADATA_SYMBOL = Symbol.metadata ?? Symbol.for("Symbol.metadata");
39
26
  //#endregion
40
- export { INJECTABLE_KEY, INJECT_ACCESSOR_KEY, LIFECYCLE_KEY, accessorMetadataByConstructorMap, accessorMetadataByMetadataObjectMap, constructorMetadataMap, lifecycleByConstructorMetadataMap, lifecycleMetadataMap };
27
+ export { INJECTABLE_KEY, INJECT_ACCESSOR_KEY, LIFECYCLE_KEY, METADATA_SYMBOL };