@codefast/di 0.5.0 → 0.6.0

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 (266) hide show
  1. package/CHANGELOG.md +615 -0
  2. package/README.md +119 -30
  3. package/dist/ambient/active-container.d.ts +37 -0
  4. package/dist/ambient/active-container.d.ts.map +1 -0
  5. package/dist/ambient/active-container.js +41 -0
  6. package/dist/ambient/active-container.js.map +1 -0
  7. package/dist/container/binding-builders.d.ts +12 -8
  8. package/dist/container/binding-builders.d.ts.map +1 -1
  9. package/dist/container/binding-builders.js +56 -31
  10. package/dist/container/binding-builders.js.map +1 -1
  11. package/dist/container/container.d.ts +33 -19
  12. package/dist/container/container.d.ts.map +1 -1
  13. package/dist/container/container.js +279 -118
  14. package/dist/container/container.js.map +1 -1
  15. package/dist/{resolution → core}/binding-scope.d.ts +2 -2
  16. package/dist/core/binding-scope.d.ts.map +1 -0
  17. package/dist/core/binding-scope.js.map +1 -0
  18. package/dist/{binding.d.ts → core/binding.d.ts} +70 -15
  19. package/dist/core/binding.d.ts.map +1 -0
  20. package/dist/{binding.js → core/binding.js} +27 -12
  21. package/dist/core/binding.js.map +1 -0
  22. package/dist/core/constraint-requirement.d.ts +38 -0
  23. package/dist/core/constraint-requirement.d.ts.map +1 -0
  24. package/dist/core/constraint-requirement.js +28 -0
  25. package/dist/core/constraint-requirement.js.map +1 -0
  26. package/dist/{constructor-type.d.ts → core/constructor-type.d.ts} +1 -1
  27. package/dist/core/constructor-type.d.ts.map +1 -0
  28. package/dist/core/constructor-type.js.map +1 -0
  29. package/dist/{module.d.ts → core/module.d.ts} +5 -5
  30. package/dist/core/module.d.ts.map +1 -0
  31. package/dist/{module.js → core/module.js} +4 -4
  32. package/dist/core/module.js.map +1 -0
  33. package/dist/{registry.d.ts → core/registry.d.ts} +27 -7
  34. package/dist/core/registry.d.ts.map +1 -0
  35. package/dist/{registry.js → core/registry.js} +125 -52
  36. package/dist/core/registry.js.map +1 -0
  37. package/dist/core/tag.d.ts +80 -0
  38. package/dist/core/tag.d.ts.map +1 -0
  39. package/dist/core/tag.js +84 -0
  40. package/dist/core/tag.js.map +1 -0
  41. package/dist/{token.d.ts → core/token.d.ts} +2 -6
  42. package/dist/core/token.d.ts.map +1 -0
  43. package/dist/core/token.js +13 -0
  44. package/dist/core/token.js.map +1 -0
  45. package/dist/{types.d.ts → core/types.d.ts} +27 -21
  46. package/dist/core/types.d.ts.map +1 -0
  47. package/dist/core/types.js.map +1 -0
  48. package/dist/decorators/inject.d.ts +5 -49
  49. package/dist/decorators/inject.d.ts.map +1 -1
  50. package/dist/decorators/inject.js +34 -104
  51. package/dist/decorators/inject.js.map +1 -1
  52. package/dist/decorators/injectable.d.ts +25 -5
  53. package/dist/decorators/injectable.d.ts.map +1 -1
  54. package/dist/decorators/injectable.js +2 -3
  55. package/dist/decorators/injectable.js.map +1 -1
  56. package/dist/decorators/lifecycle-decorators.d.ts +4 -2
  57. package/dist/decorators/lifecycle-decorators.d.ts.map +1 -1
  58. package/dist/decorators/lifecycle-decorators.js +19 -25
  59. package/dist/decorators/lifecycle-decorators.js.map +1 -1
  60. package/dist/{resolution → errors}/diagnostics.d.ts +2 -0
  61. package/dist/errors/diagnostics.d.ts.map +1 -0
  62. package/dist/errors/diagnostics.js.map +1 -0
  63. package/dist/{errors.d.ts → errors/errors.d.ts} +89 -4
  64. package/dist/errors/errors.d.ts.map +1 -0
  65. package/dist/{errors.js → errors/errors.js} +129 -7
  66. package/dist/errors/errors.js.map +1 -0
  67. package/dist/index.d.ts +21 -14
  68. package/dist/index.d.ts.map +1 -1
  69. package/dist/index.js +15 -7
  70. package/dist/index.js.map +1 -1
  71. package/dist/injection/descriptor.d.ts +79 -0
  72. package/dist/injection/descriptor.d.ts.map +1 -0
  73. package/dist/injection/descriptor.js +118 -0
  74. package/dist/injection/descriptor.js.map +1 -0
  75. package/dist/{resolution → injection}/resolve-options.d.ts +21 -11
  76. package/dist/injection/resolve-options.d.ts.map +1 -0
  77. package/dist/injection/resolve-options.js +101 -0
  78. package/dist/injection/resolve-options.js.map +1 -0
  79. package/dist/introspection/dependency-graph.d.ts +16 -5
  80. package/dist/introspection/dependency-graph.d.ts.map +1 -1
  81. package/dist/introspection/dependency-graph.js +138 -57
  82. package/dist/introspection/dependency-graph.js.map +1 -1
  83. package/dist/introspection/graph-adapters/cytoscape.d.ts +6 -3
  84. package/dist/introspection/graph-adapters/cytoscape.d.ts.map +1 -1
  85. package/dist/introspection/graph-adapters/cytoscape.js +3 -0
  86. package/dist/introspection/graph-adapters/cytoscape.js.map +1 -1
  87. package/dist/introspection/graph-adapters/dot.d.ts.map +1 -1
  88. package/dist/introspection/graph-adapters/dot.js +12 -5
  89. package/dist/introspection/graph-adapters/dot.js.map +1 -1
  90. package/dist/introspection/graph-adapters/mermaid.d.ts +9 -0
  91. package/dist/introspection/graph-adapters/mermaid.d.ts.map +1 -0
  92. package/dist/introspection/graph-adapters/mermaid.js +47 -0
  93. package/dist/introspection/graph-adapters/mermaid.js.map +1 -0
  94. package/dist/introspection/graph-adapters/reactflow.d.ts +6 -3
  95. package/dist/introspection/graph-adapters/reactflow.d.ts.map +1 -1
  96. package/dist/introspection/graph-adapters/reactflow.js +5 -1
  97. package/dist/introspection/graph-adapters/reactflow.js.map +1 -1
  98. package/dist/introspection/inspector.d.ts +4 -4
  99. package/dist/introspection/inspector.d.ts.map +1 -1
  100. package/dist/introspection/inspector.js +10 -6
  101. package/dist/introspection/inspector.js.map +1 -1
  102. package/dist/lifecycle/lifecycle-manager.d.ts +27 -0
  103. package/dist/lifecycle/lifecycle-manager.d.ts.map +1 -0
  104. package/dist/{resolution/lifecycle.js → lifecycle/lifecycle-manager.js} +39 -9
  105. package/dist/lifecycle/lifecycle-manager.js.map +1 -0
  106. package/dist/lifecycle/scope-manager.d.ts +48 -0
  107. package/dist/lifecycle/scope-manager.d.ts.map +1 -0
  108. package/dist/lifecycle/scope-manager.js +135 -0
  109. package/dist/lifecycle/scope-manager.js.map +1 -0
  110. package/dist/metadata/metadata-reader-token.d.ts +1 -1
  111. package/dist/metadata/metadata-reader-token.d.ts.map +1 -1
  112. package/dist/metadata/metadata-reader-token.js +1 -1
  113. package/dist/metadata/metadata-reader-token.js.map +1 -1
  114. package/dist/metadata/metadata-types.d.ts +9 -9
  115. package/dist/metadata/metadata-types.d.ts.map +1 -1
  116. package/dist/metadata/symbol-metadata-reader.d.ts +19 -6
  117. package/dist/metadata/symbol-metadata-reader.d.ts.map +1 -1
  118. package/dist/metadata/symbol-metadata-reader.js +89 -9
  119. package/dist/metadata/symbol-metadata-reader.js.map +1 -1
  120. package/dist/metadata/verifying-metadata-reader.d.ts +16 -0
  121. package/dist/metadata/verifying-metadata-reader.d.ts.map +1 -0
  122. package/dist/metadata/verifying-metadata-reader.js +32 -0
  123. package/dist/metadata/verifying-metadata-reader.js.map +1 -0
  124. package/dist/resolution/{activation-need.d.ts → cache/activation-need.d.ts} +5 -5
  125. package/dist/resolution/cache/activation-need.d.ts.map +1 -0
  126. package/dist/resolution/cache/activation-need.js.map +1 -0
  127. package/dist/resolution/{binding-lookup-cache.d.ts → cache/binding-lookup-cache.d.ts} +6 -5
  128. package/dist/resolution/cache/binding-lookup-cache.d.ts.map +1 -0
  129. package/dist/resolution/cache/binding-lookup-cache.js.map +1 -0
  130. package/dist/resolution/cache/class-introspector.d.ts +66 -0
  131. package/dist/resolution/cache/class-introspector.d.ts.map +1 -0
  132. package/dist/resolution/cache/class-introspector.js +194 -0
  133. package/dist/resolution/cache/class-introspector.js.map +1 -0
  134. package/dist/resolution/context.d.ts +84 -0
  135. package/dist/resolution/context.d.ts.map +1 -0
  136. package/dist/resolution/{environment.js → context.js} +54 -80
  137. package/dist/resolution/context.js.map +1 -0
  138. package/dist/resolution/path/resolution-path.d.ts +94 -0
  139. package/dist/resolution/path/resolution-path.d.ts.map +1 -0
  140. package/dist/resolution/path/resolution-path.js +117 -0
  141. package/dist/resolution/path/resolution-path.js.map +1 -0
  142. package/dist/resolution/{instantiation-plan.d.ts → plan/instantiation-plan.d.ts} +30 -7
  143. package/dist/resolution/plan/instantiation-plan.d.ts.map +1 -0
  144. package/dist/resolution/plan/instantiation-plan.js +390 -0
  145. package/dist/resolution/plan/instantiation-plan.js.map +1 -0
  146. package/dist/resolution/resolver.d.ts +28 -28
  147. package/dist/resolution/resolver.d.ts.map +1 -1
  148. package/dist/resolution/resolver.js +552 -239
  149. package/dist/resolution/resolver.js.map +1 -1
  150. package/dist/resolution/select/binding-select.d.ts +34 -0
  151. package/dist/resolution/select/binding-select.d.ts.map +1 -0
  152. package/dist/resolution/select/binding-select.js +175 -0
  153. package/dist/resolution/select/binding-select.js.map +1 -0
  154. package/dist/resolution/{constraints.d.ts → select/constraints.d.ts} +13 -12
  155. package/dist/resolution/select/constraints.d.ts.map +1 -0
  156. package/dist/resolution/{constraints.js → select/constraints.js} +33 -22
  157. package/dist/resolution/select/constraints.js.map +1 -0
  158. package/package.json +160 -20
  159. package/src/ambient/active-container.ts +65 -0
  160. package/src/container/binding-builders.ts +72 -44
  161. package/src/container/container.ts +355 -170
  162. package/src/{resolution → core}/binding-scope.ts +2 -2
  163. package/src/{binding.ts → core/binding.ts} +101 -39
  164. package/src/core/constraint-requirement.ts +51 -0
  165. package/src/{constructor-type.ts → core/constructor-type.ts} +1 -1
  166. package/src/{module.ts → core/module.ts} +10 -10
  167. package/src/core/registry.ts +365 -0
  168. package/src/core/tag.ts +144 -0
  169. package/src/{token.ts → core/token.ts} +2 -14
  170. package/src/{types.ts → core/types.ts} +37 -34
  171. package/src/decorators/inject.ts +39 -175
  172. package/src/decorators/injectable.ts +40 -10
  173. package/src/decorators/lifecycle-decorators.ts +22 -34
  174. package/src/{resolution → errors}/diagnostics.ts +2 -0
  175. package/src/{errors.ts → errors/errors.ts} +152 -8
  176. package/src/index.ts +43 -15
  177. package/src/injection/descriptor.ts +206 -0
  178. package/src/injection/resolve-options.ts +144 -0
  179. package/src/introspection/dependency-graph.ts +223 -63
  180. package/src/introspection/graph-adapters/cytoscape.ts +9 -3
  181. package/src/introspection/graph-adapters/dot.ts +13 -5
  182. package/src/introspection/graph-adapters/mermaid.ts +61 -0
  183. package/src/introspection/graph-adapters/reactflow.ts +11 -4
  184. package/src/introspection/inspector.ts +16 -12
  185. package/src/{resolution/lifecycle.ts → lifecycle/lifecycle-manager.ts} +68 -32
  186. package/src/lifecycle/scope-manager.ts +156 -0
  187. package/src/metadata/metadata-reader-token.ts +2 -2
  188. package/src/metadata/metadata-types.ts +9 -9
  189. package/src/metadata/symbol-metadata-reader.ts +95 -18
  190. package/src/metadata/verifying-metadata-reader.ts +41 -0
  191. package/src/resolution/{activation-need.ts → cache/activation-need.ts} +8 -8
  192. package/src/resolution/{binding-lookup-cache.ts → cache/binding-lookup-cache.ts} +6 -5
  193. package/src/resolution/cache/class-introspector.ts +251 -0
  194. package/src/resolution/{environment.ts → context.ts} +84 -145
  195. package/src/resolution/path/resolution-path.ts +167 -0
  196. package/src/resolution/plan/instantiation-plan.ts +579 -0
  197. package/src/resolution/resolver.ts +635 -313
  198. package/src/resolution/select/binding-select.ts +210 -0
  199. package/src/resolution/select/constraints.ts +130 -0
  200. package/dist/binding.d.ts.map +0 -1
  201. package/dist/binding.js.map +0 -1
  202. package/dist/constructor-type.d.ts.map +0 -1
  203. package/dist/constructor-type.js.map +0 -1
  204. package/dist/errors.d.ts.map +0 -1
  205. package/dist/errors.js.map +0 -1
  206. package/dist/module.d.ts.map +0 -1
  207. package/dist/module.js.map +0 -1
  208. package/dist/registry.d.ts.map +0 -1
  209. package/dist/registry.js.map +0 -1
  210. package/dist/resolution/activation-need.d.ts.map +0 -1
  211. package/dist/resolution/activation-need.js.map +0 -1
  212. package/dist/resolution/binding-lookup-cache.d.ts.map +0 -1
  213. package/dist/resolution/binding-lookup-cache.js.map +0 -1
  214. package/dist/resolution/binding-scope.d.ts.map +0 -1
  215. package/dist/resolution/binding-scope.js.map +0 -1
  216. package/dist/resolution/binding-select.d.ts +0 -23
  217. package/dist/resolution/binding-select.d.ts.map +0 -1
  218. package/dist/resolution/binding-select.js +0 -121
  219. package/dist/resolution/binding-select.js.map +0 -1
  220. package/dist/resolution/class-introspector.d.ts +0 -27
  221. package/dist/resolution/class-introspector.d.ts.map +0 -1
  222. package/dist/resolution/class-introspector.js +0 -60
  223. package/dist/resolution/class-introspector.js.map +0 -1
  224. package/dist/resolution/constraints.d.ts.map +0 -1
  225. package/dist/resolution/constraints.js.map +0 -1
  226. package/dist/resolution/diagnostics.d.ts.map +0 -1
  227. package/dist/resolution/diagnostics.js.map +0 -1
  228. package/dist/resolution/environment.d.ts +0 -94
  229. package/dist/resolution/environment.d.ts.map +0 -1
  230. package/dist/resolution/environment.js.map +0 -1
  231. package/dist/resolution/instantiation-plan.d.ts.map +0 -1
  232. package/dist/resolution/instantiation-plan.js +0 -183
  233. package/dist/resolution/instantiation-plan.js.map +0 -1
  234. package/dist/resolution/lifecycle.d.ts +0 -23
  235. package/dist/resolution/lifecycle.d.ts.map +0 -1
  236. package/dist/resolution/lifecycle.js.map +0 -1
  237. package/dist/resolution/resolution-path.d.ts +0 -98
  238. package/dist/resolution/resolution-path.d.ts.map +0 -1
  239. package/dist/resolution/resolution-path.js +0 -98
  240. package/dist/resolution/resolution-path.js.map +0 -1
  241. package/dist/resolution/resolve-options.d.ts.map +0 -1
  242. package/dist/resolution/resolve-options.js +0 -56
  243. package/dist/resolution/resolve-options.js.map +0 -1
  244. package/dist/resolution/scope.d.ts +0 -28
  245. package/dist/resolution/scope.d.ts.map +0 -1
  246. package/dist/resolution/scope.js +0 -88
  247. package/dist/resolution/scope.js.map +0 -1
  248. package/dist/token.d.ts.map +0 -1
  249. package/dist/token.js +0 -22
  250. package/dist/token.js.map +0 -1
  251. package/dist/types.d.ts.map +0 -1
  252. package/dist/types.js.map +0 -1
  253. package/src/registry.ts +0 -282
  254. package/src/resolution/binding-select.ts +0 -154
  255. package/src/resolution/class-introspector.ts +0 -74
  256. package/src/resolution/constraints.ts +0 -121
  257. package/src/resolution/instantiation-plan.ts +0 -292
  258. package/src/resolution/resolution-path.ts +0 -156
  259. package/src/resolution/resolve-options.ts +0 -89
  260. package/src/resolution/scope.ts +0 -105
  261. /package/dist/{resolution → core}/binding-scope.js +0 -0
  262. /package/dist/{constructor-type.js → core/constructor-type.js} +0 -0
  263. /package/dist/{types.js → core/types.js} +0 -0
  264. /package/dist/{resolution → errors}/diagnostics.js +0 -0
  265. /package/dist/resolution/{activation-need.js → cache/activation-need.js} +0 -0
  266. /package/dist/resolution/{binding-lookup-cache.js → cache/binding-lookup-cache.js} +0 -0
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@codefast/di",
3
- "version": "0.5.0",
3
+ "version": "0.6.0",
4
4
  "description": "Lightweight dependency injection primitives for Codefast",
5
5
  "keywords": [
6
6
  "codefast",
@@ -54,6 +54,66 @@
54
54
  "types": "./dist/index.d.ts",
55
55
  "import": "./dist/index.js"
56
56
  },
57
+ "./ambient/active-container": {
58
+ "source": "./src/ambient/active-container.ts",
59
+ "types": "./dist/ambient/active-container.d.ts",
60
+ "import": "./dist/ambient/active-container.js"
61
+ },
62
+ "./container/binding-builders": {
63
+ "source": "./src/container/binding-builders.ts",
64
+ "types": "./dist/container/binding-builders.d.ts",
65
+ "import": "./dist/container/binding-builders.js"
66
+ },
67
+ "./container/container": {
68
+ "source": "./src/container/container.ts",
69
+ "types": "./dist/container/container.d.ts",
70
+ "import": "./dist/container/container.js"
71
+ },
72
+ "./core/binding": {
73
+ "source": "./src/core/binding.ts",
74
+ "types": "./dist/core/binding.d.ts",
75
+ "import": "./dist/core/binding.js"
76
+ },
77
+ "./core/binding-scope": {
78
+ "source": "./src/core/binding-scope.ts",
79
+ "types": "./dist/core/binding-scope.d.ts",
80
+ "import": "./dist/core/binding-scope.js"
81
+ },
82
+ "./core/constraint-requirement": {
83
+ "source": "./src/core/constraint-requirement.ts",
84
+ "types": "./dist/core/constraint-requirement.d.ts",
85
+ "import": "./dist/core/constraint-requirement.js"
86
+ },
87
+ "./core/constructor-type": {
88
+ "source": "./src/core/constructor-type.ts",
89
+ "types": "./dist/core/constructor-type.d.ts",
90
+ "import": "./dist/core/constructor-type.js"
91
+ },
92
+ "./core/module": {
93
+ "source": "./src/core/module.ts",
94
+ "types": "./dist/core/module.d.ts",
95
+ "import": "./dist/core/module.js"
96
+ },
97
+ "./core/registry": {
98
+ "source": "./src/core/registry.ts",
99
+ "types": "./dist/core/registry.d.ts",
100
+ "import": "./dist/core/registry.js"
101
+ },
102
+ "./core/tag": {
103
+ "source": "./src/core/tag.ts",
104
+ "types": "./dist/core/tag.d.ts",
105
+ "import": "./dist/core/tag.js"
106
+ },
107
+ "./core/token": {
108
+ "source": "./src/core/token.ts",
109
+ "types": "./dist/core/token.d.ts",
110
+ "import": "./dist/core/token.js"
111
+ },
112
+ "./core/types": {
113
+ "source": "./src/core/types.ts",
114
+ "types": "./dist/core/types.d.ts",
115
+ "import": "./dist/core/types.js"
116
+ },
57
117
  "./decorators/inject": {
58
118
  "source": "./src/decorators/inject.ts",
59
119
  "types": "./dist/decorators/inject.d.ts",
@@ -69,10 +129,25 @@
69
129
  "types": "./dist/decorators/lifecycle-decorators.d.ts",
70
130
  "import": "./dist/decorators/lifecycle-decorators.js"
71
131
  },
72
- "./errors": {
73
- "source": "./src/errors.ts",
74
- "types": "./dist/errors.d.ts",
75
- "import": "./dist/errors.js"
132
+ "./errors/diagnostics": {
133
+ "source": "./src/errors/diagnostics.ts",
134
+ "types": "./dist/errors/diagnostics.d.ts",
135
+ "import": "./dist/errors/diagnostics.js"
136
+ },
137
+ "./errors/errors": {
138
+ "source": "./src/errors/errors.ts",
139
+ "types": "./dist/errors/errors.d.ts",
140
+ "import": "./dist/errors/errors.js"
141
+ },
142
+ "./injection/descriptor": {
143
+ "source": "./src/injection/descriptor.ts",
144
+ "types": "./dist/injection/descriptor.d.ts",
145
+ "import": "./dist/injection/descriptor.js"
146
+ },
147
+ "./injection/resolve-options": {
148
+ "source": "./src/injection/resolve-options.ts",
149
+ "types": "./dist/injection/resolve-options.d.ts",
150
+ "import": "./dist/injection/resolve-options.js"
76
151
  },
77
152
  "./dependency-graph": {
78
153
  "source": "./src/introspection/dependency-graph.ts",
@@ -89,6 +164,11 @@
89
164
  "types": "./dist/introspection/graph-adapters/dot.d.ts",
90
165
  "import": "./dist/introspection/graph-adapters/dot.js"
91
166
  },
167
+ "./graph-adapters/mermaid": {
168
+ "source": "./src/introspection/graph-adapters/mermaid.ts",
169
+ "types": "./dist/introspection/graph-adapters/mermaid.d.ts",
170
+ "import": "./dist/introspection/graph-adapters/mermaid.js"
171
+ },
92
172
  "./graph-adapters/reactflow": {
93
173
  "source": "./src/introspection/graph-adapters/reactflow.ts",
94
174
  "types": "./dist/introspection/graph-adapters/reactflow.d.ts",
@@ -99,25 +179,85 @@
99
179
  "types": "./dist/introspection/inspector.d.ts",
100
180
  "import": "./dist/introspection/inspector.js"
101
181
  },
182
+ "./lifecycle/lifecycle-manager": {
183
+ "source": "./src/lifecycle/lifecycle-manager.ts",
184
+ "types": "./dist/lifecycle/lifecycle-manager.d.ts",
185
+ "import": "./dist/lifecycle/lifecycle-manager.js"
186
+ },
187
+ "./lifecycle/scope-manager": {
188
+ "source": "./src/lifecycle/scope-manager.ts",
189
+ "types": "./dist/lifecycle/scope-manager.d.ts",
190
+ "import": "./dist/lifecycle/scope-manager.js"
191
+ },
192
+ "./metadata/metadata-keys": {
193
+ "source": "./src/metadata/metadata-keys.ts",
194
+ "types": "./dist/metadata/metadata-keys.d.ts",
195
+ "import": "./dist/metadata/metadata-keys.js"
196
+ },
102
197
  "./metadata/metadata-reader-token": {
103
198
  "source": "./src/metadata/metadata-reader-token.ts",
104
199
  "types": "./dist/metadata/metadata-reader-token.d.ts",
105
200
  "import": "./dist/metadata/metadata-reader-token.js"
106
201
  },
107
- "./module": {
108
- "source": "./src/module.ts",
109
- "types": "./dist/module.d.ts",
110
- "import": "./dist/module.js"
202
+ "./metadata/metadata-types": {
203
+ "source": "./src/metadata/metadata-types.ts",
204
+ "types": "./dist/metadata/metadata-types.d.ts",
205
+ "import": "./dist/metadata/metadata-types.js"
206
+ },
207
+ "./metadata/symbol-metadata-reader": {
208
+ "source": "./src/metadata/symbol-metadata-reader.ts",
209
+ "types": "./dist/metadata/symbol-metadata-reader.d.ts",
210
+ "import": "./dist/metadata/symbol-metadata-reader.js"
211
+ },
212
+ "./metadata/verifying-metadata-reader": {
213
+ "source": "./src/metadata/verifying-metadata-reader.ts",
214
+ "types": "./dist/metadata/verifying-metadata-reader.d.ts",
215
+ "import": "./dist/metadata/verifying-metadata-reader.js"
216
+ },
217
+ "./resolution/cache/activation-need": {
218
+ "source": "./src/resolution/cache/activation-need.ts",
219
+ "types": "./dist/resolution/cache/activation-need.d.ts",
220
+ "import": "./dist/resolution/cache/activation-need.js"
221
+ },
222
+ "./resolution/cache/binding-lookup-cache": {
223
+ "source": "./src/resolution/cache/binding-lookup-cache.ts",
224
+ "types": "./dist/resolution/cache/binding-lookup-cache.d.ts",
225
+ "import": "./dist/resolution/cache/binding-lookup-cache.js"
226
+ },
227
+ "./resolution/cache/class-introspector": {
228
+ "source": "./src/resolution/cache/class-introspector.ts",
229
+ "types": "./dist/resolution/cache/class-introspector.d.ts",
230
+ "import": "./dist/resolution/cache/class-introspector.js"
231
+ },
232
+ "./resolution/context": {
233
+ "source": "./src/resolution/context.ts",
234
+ "types": "./dist/resolution/context.d.ts",
235
+ "import": "./dist/resolution/context.js"
236
+ },
237
+ "./resolution/path/resolution-path": {
238
+ "source": "./src/resolution/path/resolution-path.ts",
239
+ "types": "./dist/resolution/path/resolution-path.d.ts",
240
+ "import": "./dist/resolution/path/resolution-path.js"
241
+ },
242
+ "./resolution/plan/instantiation-plan": {
243
+ "source": "./src/resolution/plan/instantiation-plan.ts",
244
+ "types": "./dist/resolution/plan/instantiation-plan.d.ts",
245
+ "import": "./dist/resolution/plan/instantiation-plan.js"
246
+ },
247
+ "./resolution/resolver": {
248
+ "source": "./src/resolution/resolver.ts",
249
+ "types": "./dist/resolution/resolver.d.ts",
250
+ "import": "./dist/resolution/resolver.js"
111
251
  },
112
- "./token": {
113
- "source": "./src/token.ts",
114
- "types": "./dist/token.d.ts",
115
- "import": "./dist/token.js"
252
+ "./resolution/select/binding-select": {
253
+ "source": "./src/resolution/select/binding-select.ts",
254
+ "types": "./dist/resolution/select/binding-select.d.ts",
255
+ "import": "./dist/resolution/select/binding-select.js"
116
256
  },
117
- "./types": {
118
- "source": "./src/types.ts",
119
- "types": "./dist/types.d.ts",
120
- "import": "./dist/types.js"
257
+ "./resolution/select/constraints": {
258
+ "source": "./src/resolution/select/constraints.ts",
259
+ "types": "./dist/resolution/select/constraints.d.ts",
260
+ "import": "./dist/resolution/select/constraints.js"
121
261
  },
122
262
  "./package.json": "./package.json"
123
263
  },
@@ -128,13 +268,13 @@
128
268
  "@babel/core": "^8.0.1",
129
269
  "@babel/plugin-proposal-decorators": "8.0.2",
130
270
  "@rolldown/plugin-babel": "^0.2.3",
131
- "@types/node": "^26.1.2",
271
+ "@types/node": "^26.2.0",
132
272
  "@vitest/coverage-v8": "^4.1.10",
133
273
  "expect-type": "^1.4.0",
134
- "tsx": "^4.23.1",
274
+ "tsx": "^4.23.12",
135
275
  "typescript": "^7.0.2",
136
276
  "vitest": "^4.1.10",
137
- "@codefast/typescript-config": "0.5.0"
277
+ "@codefast/typescript-config": "0.6.0"
138
278
  },
139
279
  "engines": {
140
280
  "node": ">=26.0.0"
@@ -0,0 +1,65 @@
1
+ /** The container an `@inject` accessor initializer resolves from when it has no other handle. */
2
+ import type { Container } from "#/container/container";
3
+ import type { Token } from "#/core/token";
4
+ import type { Constructor, ResolveOptions } from "#/core/types";
5
+
6
+ /**
7
+ * Path-continuing resolution the engine installs while constructing a class with `@inject` accessors.
8
+ *
9
+ * @remarks Resolving through this keeps an accessor's dependencies on the live resolution path, so a
10
+ * cycle through an accessor surfaces as `CircularDependencyError` instead of unbounded recursion.
11
+ *
12
+ * @since 0.6.0
13
+ */
14
+ export interface AmbientResolution {
15
+ resolve<Value>(token: Token<Value> | Constructor<Value>, options?: ResolveOptions): Value;
16
+ resolveOptional<Value>(token: Token<Value> | Constructor<Value>, options?: ResolveOptions): Value | undefined;
17
+ }
18
+
19
+ let activeContainer: Container | undefined;
20
+ let activeResolution: AmbientResolution | undefined;
21
+
22
+ /**
23
+ * @since 0.3.16-canary.0
24
+ */
25
+ export function runWithContainer<Result>(container: Container, fn: () => Result): Result {
26
+ return runWithAmbientResolution(container, undefined, fn);
27
+ }
28
+
29
+ /**
30
+ * Engine-internal variant of {@link runWithContainer} that also installs a path-continuing resolver.
31
+ *
32
+ * @since 0.6.0
33
+ */
34
+ export function runWithAmbientResolution<Result>(
35
+ container: Container,
36
+ resolution: AmbientResolution | undefined,
37
+ fn: () => Result,
38
+ ): Result {
39
+ const previousContainer = activeContainer;
40
+ const previousResolution = activeResolution;
41
+ activeContainer = container;
42
+ activeResolution = resolution;
43
+ try {
44
+ return fn();
45
+ } finally {
46
+ activeContainer = previousContainer;
47
+ activeResolution = previousResolution;
48
+ }
49
+ }
50
+
51
+ /**
52
+ * @since 0.3.16-canary.0
53
+ */
54
+ export function getActiveContainer(): Container | undefined {
55
+ return activeContainer;
56
+ }
57
+
58
+ /**
59
+ * The path-continuing resolution for the construction in flight, when the engine installed one.
60
+ *
61
+ * @since 0.6.0
62
+ */
63
+ export function getAmbientResolution(): AmbientResolution | undefined {
64
+ return activeResolution;
65
+ }
@@ -1,7 +1,8 @@
1
1
  /**
2
2
  * The fluent chain `bind()` returns: it registers the binding and refines it in place.
3
3
  *
4
- * @see `ARCHITECTURE.md` — why one object plays every role, and what pins the ordering.
4
+ * @remarks One object plays every role in the chain; the return type of each step is what pins the
5
+ * order, so no runtime check has to.
5
6
  */
6
7
  import type {
7
8
  AliasBindingBuilder,
@@ -15,44 +16,38 @@ import type {
15
16
  SingletonBindingBuilder,
16
17
  SingletonLifecycleBuilder,
17
18
  TransientBindingBuilder,
18
- } from "#/binding";
19
- import { bindingSlotEquals, clearBindingFrame, createBinding, DEFAULT_BINDING_SLOT, refinableFields } from "#/binding";
20
- import type { InjectableDependency, ResolvedDependencyValue } from "#/decorators/inject";
21
- import { normalizeToDescriptor } from "#/decorators/inject";
22
- import { ChainNotRegisteredError, SelfBindingRequiresClassError } from "#/errors";
23
- import type { BindingRegistry } from "#/registry";
24
- import type { Token } from "#/token";
25
- import { tokenName } from "#/token";
19
+ } from "#/core/binding";
20
+ import { clearBindingFrame, createBinding, DEFAULT_BINDING_SLOT, refinableFields } from "#/core/binding";
21
+ import type { BindingRegistry } from "#/core/registry";
22
+ import type { BindingTag } from "#/core/tag";
23
+ import { tagKeyMaskOf } from "#/core/tag";
24
+ import type { Token } from "#/core/token";
25
+ import { tokenName } from "#/core/token";
26
26
  import type {
27
27
  ActivationHandler,
28
+ BindingConstraint,
28
29
  BindingIdentifier,
29
30
  BindingScope,
30
- ConstraintContext,
31
31
  Constructor,
32
32
  DeactivationHandler,
33
33
  ResolutionContext,
34
- } from "#/types";
35
-
36
- function updateSlotTag(slot: BindingSlot, tag: string, value: unknown): BindingSlot {
34
+ } from "#/core/types";
35
+ import { ChainNotRegisteredError, SelfBindingRequiresClassError } from "#/errors/errors";
36
+ import type { InjectableDependency, ResolvedDependencyValue } from "#/injection/descriptor";
37
+ import { normalizeToDescriptor } from "#/injection/descriptor";
38
+ import type { ScopeManager } from "#/lifecycle/scope-manager";
39
+
40
+ /** One criterion per key: re-tagging the same key replaces it rather than asking for both values. */
41
+ function updateSlotTag(slot: BindingSlot, criterion: BindingTag): BindingSlot {
37
42
  const tags = [...slot.tags];
38
- const existingIndex = tags.findIndex(([key]) => key === tag);
43
+ const existingIndex = tags.findIndex((existing) => existing.key === criterion.key);
39
44
  if (existingIndex === -1) {
40
- tags.push([tag, value]);
45
+ tags.push(criterion);
41
46
  } else {
42
- tags[existingIndex] = [tag, value];
47
+ tags[existingIndex] = criterion;
43
48
  }
44
- return { ...slot, tags };
45
- }
46
-
47
- // True when re-adding `restored` would immediately be displaced again by `current`
48
- // (both slot-based with equal slots) — in that case the replacement was legitimate.
49
- function displacesRestoredBinding(current: Binding, restored: Binding): boolean {
50
- const currentIsPurePredicate =
51
- current.predicate !== undefined && current.slot.name === undefined && current.slot.tags.length === 0;
52
- if (currentIsPurePredicate) {
53
- return false;
54
- }
55
- return bindingSlotEquals(current.slot, restored.slot);
49
+ // Frozen like DEFAULT_BINDING_SLOT's list: frames and snapshots alias a slot's tags.
50
+ return { ...slot, tags: Object.freeze(tags), keyMask: tagKeyMaskOf(tags) };
56
51
  }
57
52
 
58
53
  /** Record a module's binding id, dropping the id the chain re-slotted away from. */
@@ -70,7 +65,7 @@ function trackBindingForModule(
70
65
  ids.push(id);
71
66
  }
72
67
 
73
- // ── Registration target ───────────────────────────────────────────────────────
68
+ // ── Registration target ──────────────────────────────────────────────────────────────────────────────────────────────
74
69
 
75
70
  /**
76
71
  * Where a chain registers, and on whose behalf.
@@ -82,10 +77,11 @@ function trackBindingForModule(
82
77
  */
83
78
  export interface BindingRegistration {
84
79
  readonly registry: BindingRegistry;
80
+ readonly scope: ScopeManager;
85
81
  readonly moduleBindingIds: Array<BindingIdentifier> | undefined;
86
82
  }
87
83
 
88
- // ── BindingChain ──────────────────────────────────────────────────────────────
84
+ // ── BindingChain ─────────────────────────────────────────────────────────────────────────────────────────────────────
89
85
 
90
86
  /**
91
87
  * The one builder behind `bind()` and every `to*()` return type. Each interface exposes only the
@@ -109,6 +105,8 @@ export class BindingChain<Value>
109
105
  #binding: Binding<Value> | undefined;
110
106
  // Allocated only by a chain that actually displaces something — most never do.
111
107
  #displacedByChain: Array<Binding> | undefined;
108
+ // Registry version after this chain's last write — a mismatch means someone else wrote in between.
109
+ #versionAfterLastWrite = -1;
112
110
  readonly #token: Token<Value> | Constructor<Value>;
113
111
  readonly #registration: BindingRegistration;
114
112
 
@@ -134,7 +132,7 @@ export class BindingChain<Value>
134
132
  return this;
135
133
  }
136
134
 
137
- // ── Registration ───────────────────────────────────────────────────────────
135
+ // ── Registration ───────────────────────────────────────────────────────────────────────────────────────────────────
138
136
 
139
137
  to(type: Constructor<Value>): BindingBuilder<Value> {
140
138
  return this.#register({ kind: "class", target: type, scope: "transient" });
@@ -187,37 +185,51 @@ export class BindingChain<Value>
187
185
  return this.#register({ kind: "alias", scope: "transient", target });
188
186
  }
189
187
 
190
- // ── Refinement ─────────────────────────────────────────────────────────────
188
+ // ── Refinement ─────────────────────────────────────────────────────────────────────────────────────────────────────
191
189
 
192
190
  // Slot and predicate are what the registry indexes on, so a re-slot rebuilds the binding and
193
191
  // re-registers it — under the original id, keeping `id()` stable for the whole chain.
194
- #reslot(slot: BindingSlot, predicate: ((ctx: ConstraintContext) => boolean) | undefined): this {
192
+ #reslot(slot: BindingSlot, predicate: BindingConstraint | undefined): this {
195
193
  const previous = this.#registered();
196
194
  this.#binding = createBinding(previous, previous.token, slot, predicate, previous.id);
197
195
  this.#commit(this.#binding, previous.id);
196
+ // The tracked-singleton list holds object references, and the re-slot just replaced the object.
197
+ this.#registration.scope.replaceSingleton(previous as Binding, this.#binding as Binding);
198
198
  return this;
199
199
  }
200
200
 
201
201
  #withScope(scope: BindingScope): this {
202
202
  const binding = this.#registered();
203
- refinableFields(binding).scope = scope;
203
+ if (binding.scope !== scope) {
204
+ // An instance cached under the old scope must not survive the change — a later flip back
205
+ // to that scope would resurrect it.
206
+ this.#registration.scope.deleteSingleton(binding);
207
+ this.#registration.scope.deleteScoped(binding.id);
208
+ refinableFields(binding).scope = scope;
209
+ }
204
210
  // The frame reports the scope, so a resolve before this call memoized the previous one.
205
211
  clearBindingFrame(binding);
206
212
  this.#registration.registry.touch();
213
+ this.#versionAfterLastWrite = this.#registration.registry.version;
207
214
  return this;
208
215
  }
209
216
 
210
- when(predicate: (ctx: ConstraintContext) => boolean): this {
211
- return this.#reslot(this.#registered().slot, predicate);
217
+ // SPEC calls a candidate a binding that passes *all* of a chain's predicates, and the chain type
218
+ // reads as refinement, so a second `when()` narrows rather than replaces.
219
+ when(predicate: BindingConstraint): this {
220
+ const binding = this.#registered();
221
+ const previous = binding.predicate;
222
+
223
+ return this.#reslot(binding.slot, previous === undefined ? predicate : (ctx) => previous(ctx) && predicate(ctx));
212
224
  }
213
225
 
214
226
  whenNamed(name: string): this {
215
227
  return this.#reslot({ ...this.#registered().slot, name }, this.#registered().predicate);
216
228
  }
217
229
 
218
- whenTagged(tag: string, value: unknown): this {
230
+ whenTagged(criterion: BindingTag): this {
219
231
  const binding = this.#registered();
220
- return this.#reslot(updateSlotTag(binding.slot, tag, value), binding.predicate);
232
+ return this.#reslot(updateSlotTag(binding.slot, criterion), binding.predicate);
221
233
  }
222
234
 
223
235
  whenDefault(): this {
@@ -242,12 +254,14 @@ export class BindingChain<Value>
242
254
  onActivation(fn: ActivationHandler<Value>): this {
243
255
  refinableFields(this.#registered()).onActivation = fn;
244
256
  this.#registration.registry.touch();
257
+ this.#versionAfterLastWrite = this.#registration.registry.version;
245
258
  return this;
246
259
  }
247
260
 
248
261
  onDeactivation(fn: DeactivationHandler<Value>): this {
249
262
  refinableFields(this.#registered()).onDeactivation = fn;
250
263
  this.#registration.registry.touch();
264
+ this.#versionAfterLastWrite = this.#registration.registry.version;
251
265
  return this;
252
266
  }
253
267
 
@@ -255,10 +269,10 @@ export class BindingChain<Value>
255
269
  return this.#registered().id;
256
270
  }
257
271
 
258
- // ── Registry ───────────────────────────────────────────────────────────────
272
+ // ── Registry ───────────────────────────────────────────────────────────────────────────────────────────────────────
259
273
 
260
274
  /**
261
- * Register `binding`, first removing `previousId` when the chain is re-slotting.
275
+ * Registers `binding`, first removing `previousId` when the chain is re-slotting.
262
276
  *
263
277
  * @remarks A `when*()` that follows `to*()` re-slots an already-live binding and can displace one
264
278
  * the final shape would never conflict with. Those stay parked in `#displacedByChain` until the
@@ -271,24 +285,38 @@ export class BindingChain<Value>
271
285
  const registered = binding as Binding;
272
286
 
273
287
  if (previousId !== undefined) {
274
- registry.removeById(previousId);
288
+ // A registry someone else wrote since this chain's last write invalidates the parked
289
+ // snapshot: restoring it could undo an unbind or shadow a newer binding.
290
+ if (registry.version !== this.#versionAfterLastWrite) {
291
+ this.#displacedByChain = undefined;
292
+ }
293
+ if (registry.removeById(previousId) === undefined) {
294
+ // The chain's binding is no longer live (unbound or displaced) — a refinement must not
295
+ // resurrect it, so the chain goes inert against the registry.
296
+ this.#displacedByChain = undefined;
297
+ this.#versionAfterLastWrite = registry.version;
298
+ return;
299
+ }
275
300
  }
276
301
  const displaced = registry.add(registered);
277
302
  if (displaced !== undefined) {
278
303
  (this.#displacedByChain ??= []).push(displaced);
279
304
  }
280
305
  if (previousId !== undefined && this.#displacedByChain !== undefined) {
281
- this.#restoreNonConflicting(registered, this.#displacedByChain);
306
+ this.#restoreNonConflicting(this.#displacedByChain);
282
307
  }
283
308
  if (moduleBindingIds !== undefined) {
284
309
  trackBindingForModule(moduleBindingIds, registered.id, previousId);
285
310
  }
311
+ this.#versionAfterLastWrite = registry.version;
286
312
  }
287
313
 
288
- #restoreNonConflicting(binding: Binding, displaced: Array<Binding>): void {
314
+ #restoreNonConflicting(displaced: Array<Binding>): void {
289
315
  for (let index = displaced.length - 1; index >= 0; index -= 1) {
290
316
  const candidate = displaced[index]!;
291
- if (!displacesRestoredBinding(binding, candidate)) {
317
+ // A restore must never displace: a slot that has been re-occupied keeps its occupant, and
318
+ // the candidate stays parked.
319
+ if (!this.#registration.registry.hasSlotOccupant(candidate)) {
292
320
  this.#registration.registry.add(candidate);
293
321
  displaced.splice(index, 1);
294
322
  }