@codefast/di 0.5.0 → 0.6.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.
Files changed (266) hide show
  1. package/CHANGELOG.md +712 -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 +62 -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 +281 -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 +53 -0
  23. package/dist/core/constraint-requirement.d.ts.map +1 -0
  24. package/dist/core/constraint-requirement.js +62 -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 +96 -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} +9 -5
  128. package/dist/resolution/cache/binding-lookup-cache.d.ts.map +1 -0
  129. package/dist/resolution/{binding-lookup-cache.js → cache/binding-lookup-cache.js} +55 -0
  130. package/dist/resolution/cache/binding-lookup-cache.js.map +1 -0
  131. package/dist/resolution/cache/class-introspector.d.ts +66 -0
  132. package/dist/resolution/cache/class-introspector.d.ts.map +1 -0
  133. package/dist/resolution/cache/class-introspector.js +194 -0
  134. package/dist/resolution/cache/class-introspector.js.map +1 -0
  135. package/dist/resolution/context.d.ts +84 -0
  136. package/dist/resolution/context.d.ts.map +1 -0
  137. package/dist/resolution/{environment.js → context.js} +54 -80
  138. package/dist/resolution/context.js.map +1 -0
  139. package/dist/resolution/path/resolution-path.d.ts +94 -0
  140. package/dist/resolution/path/resolution-path.d.ts.map +1 -0
  141. package/dist/resolution/path/resolution-path.js +117 -0
  142. package/dist/resolution/path/resolution-path.js.map +1 -0
  143. package/dist/resolution/{instantiation-plan.d.ts → plan/instantiation-plan.d.ts} +37 -7
  144. package/dist/resolution/plan/instantiation-plan.d.ts.map +1 -0
  145. package/dist/resolution/plan/instantiation-plan.js +419 -0
  146. package/dist/resolution/plan/instantiation-plan.js.map +1 -0
  147. package/dist/resolution/resolver.d.ts +28 -28
  148. package/dist/resolution/resolver.d.ts.map +1 -1
  149. package/dist/resolution/resolver.js +581 -239
  150. package/dist/resolution/resolver.js.map +1 -1
  151. package/dist/resolution/select/binding-select.d.ts +34 -0
  152. package/dist/resolution/select/binding-select.d.ts.map +1 -0
  153. package/dist/resolution/select/binding-select.js +175 -0
  154. package/dist/resolution/select/binding-select.js.map +1 -0
  155. package/dist/resolution/{constraints.d.ts → select/constraints.d.ts} +13 -12
  156. package/dist/resolution/select/constraints.d.ts.map +1 -0
  157. package/dist/resolution/{constraints.js → select/constraints.js} +33 -22
  158. package/dist/resolution/select/constraints.js.map +1 -0
  159. package/package.json +160 -20
  160. package/src/ambient/active-container.ts +65 -0
  161. package/src/container/binding-builders.ts +79 -44
  162. package/src/container/container.ts +357 -170
  163. package/src/{resolution → core}/binding-scope.ts +2 -2
  164. package/src/{binding.ts → core/binding.ts} +101 -39
  165. package/src/core/constraint-requirement.ts +94 -0
  166. package/src/{constructor-type.ts → core/constructor-type.ts} +1 -1
  167. package/src/{module.ts → core/module.ts} +10 -10
  168. package/src/core/registry.ts +365 -0
  169. package/src/core/tag.ts +158 -0
  170. package/src/{token.ts → core/token.ts} +2 -14
  171. package/src/{types.ts → core/types.ts} +37 -34
  172. package/src/decorators/inject.ts +39 -175
  173. package/src/decorators/injectable.ts +40 -10
  174. package/src/decorators/lifecycle-decorators.ts +22 -34
  175. package/src/{resolution → errors}/diagnostics.ts +2 -0
  176. package/src/{errors.ts → errors/errors.ts} +152 -8
  177. package/src/index.ts +43 -15
  178. package/src/injection/descriptor.ts +206 -0
  179. package/src/injection/resolve-options.ts +144 -0
  180. package/src/introspection/dependency-graph.ts +223 -63
  181. package/src/introspection/graph-adapters/cytoscape.ts +9 -3
  182. package/src/introspection/graph-adapters/dot.ts +13 -5
  183. package/src/introspection/graph-adapters/mermaid.ts +61 -0
  184. package/src/introspection/graph-adapters/reactflow.ts +11 -4
  185. package/src/introspection/inspector.ts +16 -12
  186. package/src/{resolution/lifecycle.ts → lifecycle/lifecycle-manager.ts} +68 -32
  187. package/src/lifecycle/scope-manager.ts +156 -0
  188. package/src/metadata/metadata-reader-token.ts +2 -2
  189. package/src/metadata/metadata-types.ts +9 -9
  190. package/src/metadata/symbol-metadata-reader.ts +95 -18
  191. package/src/metadata/verifying-metadata-reader.ts +41 -0
  192. package/src/resolution/{activation-need.ts → cache/activation-need.ts} +8 -8
  193. package/src/resolution/{binding-lookup-cache.ts → cache/binding-lookup-cache.ts} +63 -5
  194. package/src/resolution/cache/class-introspector.ts +251 -0
  195. package/src/resolution/{environment.ts → context.ts} +84 -145
  196. package/src/resolution/path/resolution-path.ts +167 -0
  197. package/src/resolution/plan/instantiation-plan.ts +615 -0
  198. package/src/resolution/resolver.ts +663 -313
  199. package/src/resolution/select/binding-select.ts +210 -0
  200. package/src/resolution/select/constraints.ts +130 -0
  201. package/dist/binding.d.ts.map +0 -1
  202. package/dist/binding.js.map +0 -1
  203. package/dist/constructor-type.d.ts.map +0 -1
  204. package/dist/constructor-type.js.map +0 -1
  205. package/dist/errors.d.ts.map +0 -1
  206. package/dist/errors.js.map +0 -1
  207. package/dist/module.d.ts.map +0 -1
  208. package/dist/module.js.map +0 -1
  209. package/dist/registry.d.ts.map +0 -1
  210. package/dist/registry.js.map +0 -1
  211. package/dist/resolution/activation-need.d.ts.map +0 -1
  212. package/dist/resolution/activation-need.js.map +0 -1
  213. package/dist/resolution/binding-lookup-cache.d.ts.map +0 -1
  214. package/dist/resolution/binding-lookup-cache.js.map +0 -1
  215. package/dist/resolution/binding-scope.d.ts.map +0 -1
  216. package/dist/resolution/binding-scope.js.map +0 -1
  217. package/dist/resolution/binding-select.d.ts +0 -23
  218. package/dist/resolution/binding-select.d.ts.map +0 -1
  219. package/dist/resolution/binding-select.js +0 -121
  220. package/dist/resolution/binding-select.js.map +0 -1
  221. package/dist/resolution/class-introspector.d.ts +0 -27
  222. package/dist/resolution/class-introspector.d.ts.map +0 -1
  223. package/dist/resolution/class-introspector.js +0 -60
  224. package/dist/resolution/class-introspector.js.map +0 -1
  225. package/dist/resolution/constraints.d.ts.map +0 -1
  226. package/dist/resolution/constraints.js.map +0 -1
  227. package/dist/resolution/diagnostics.d.ts.map +0 -1
  228. package/dist/resolution/diagnostics.js.map +0 -1
  229. package/dist/resolution/environment.d.ts +0 -94
  230. package/dist/resolution/environment.d.ts.map +0 -1
  231. package/dist/resolution/environment.js.map +0 -1
  232. package/dist/resolution/instantiation-plan.d.ts.map +0 -1
  233. package/dist/resolution/instantiation-plan.js +0 -183
  234. package/dist/resolution/instantiation-plan.js.map +0 -1
  235. package/dist/resolution/lifecycle.d.ts +0 -23
  236. package/dist/resolution/lifecycle.d.ts.map +0 -1
  237. package/dist/resolution/lifecycle.js.map +0 -1
  238. package/dist/resolution/resolution-path.d.ts +0 -98
  239. package/dist/resolution/resolution-path.d.ts.map +0 -1
  240. package/dist/resolution/resolution-path.js +0 -98
  241. package/dist/resolution/resolution-path.js.map +0 -1
  242. package/dist/resolution/resolve-options.d.ts.map +0 -1
  243. package/dist/resolution/resolve-options.js +0 -56
  244. package/dist/resolution/resolve-options.js.map +0 -1
  245. package/dist/resolution/scope.d.ts +0 -28
  246. package/dist/resolution/scope.d.ts.map +0 -1
  247. package/dist/resolution/scope.js +0 -88
  248. package/dist/resolution/scope.js.map +0 -1
  249. package/dist/token.d.ts.map +0 -1
  250. package/dist/token.js +0 -22
  251. package/dist/token.js.map +0 -1
  252. package/dist/types.d.ts.map +0 -1
  253. package/dist/types.js.map +0 -1
  254. package/src/registry.ts +0 -282
  255. package/src/resolution/binding-select.ts +0 -154
  256. package/src/resolution/class-introspector.ts +0 -74
  257. package/src/resolution/constraints.ts +0 -121
  258. package/src/resolution/instantiation-plan.ts +0 -292
  259. package/src/resolution/resolution-path.ts +0 -156
  260. package/src/resolution/resolve-options.ts +0 -89
  261. package/src/resolution/scope.ts +0 -105
  262. /package/dist/{resolution → core}/binding-scope.js +0 -0
  263. /package/dist/{constructor-type.js → core/constructor-type.js} +0 -0
  264. /package/dist/{types.js → core/types.js} +0 -0
  265. /package/dist/{resolution → errors}/diagnostics.js +0 -0
  266. /package/dist/resolution/{activation-need.js → cache/activation-need.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.1",
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.1"
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,39 @@ 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 { mergingConstraintRequirements } from "#/core/constraint-requirement";
22
+ import type { BindingRegistry } from "#/core/registry";
23
+ import type { BindingTag } from "#/core/tag";
24
+ import { tagKeyMaskOf } from "#/core/tag";
25
+ import type { Token } from "#/core/token";
26
+ import { tokenName } from "#/core/token";
26
27
  import type {
27
28
  ActivationHandler,
29
+ BindingConstraint,
28
30
  BindingIdentifier,
29
31
  BindingScope,
30
- ConstraintContext,
31
32
  Constructor,
32
33
  DeactivationHandler,
33
34
  ResolutionContext,
34
- } from "#/types";
35
-
36
- function updateSlotTag(slot: BindingSlot, tag: string, value: unknown): BindingSlot {
35
+ } from "#/core/types";
36
+ import { ChainNotRegisteredError, SelfBindingRequiresClassError } from "#/errors/errors";
37
+ import type { InjectableDependency, ResolvedDependencyValue } from "#/injection/descriptor";
38
+ import { normalizeToDescriptor } from "#/injection/descriptor";
39
+ import type { ScopeManager } from "#/lifecycle/scope-manager";
40
+
41
+ /** One criterion per key: re-tagging the same key replaces it rather than asking for both values. */
42
+ function updateSlotTag(slot: BindingSlot, criterion: BindingTag): BindingSlot {
37
43
  const tags = [...slot.tags];
38
- const existingIndex = tags.findIndex(([key]) => key === tag);
44
+ const existingIndex = tags.findIndex((existing) => existing.key === criterion.key);
39
45
  if (existingIndex === -1) {
40
- tags.push([tag, value]);
46
+ tags.push(criterion);
41
47
  } else {
42
- tags[existingIndex] = [tag, value];
43
- }
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;
48
+ tags[existingIndex] = criterion;
54
49
  }
55
- return bindingSlotEquals(current.slot, restored.slot);
50
+ // Frozen like DEFAULT_BINDING_SLOT's list: frames and snapshots alias a slot's tags.
51
+ return { ...slot, tags: Object.freeze(tags), keyMask: tagKeyMaskOf(tags) };
56
52
  }
57
53
 
58
54
  /** Record a module's binding id, dropping the id the chain re-slotted away from. */
@@ -70,7 +66,7 @@ function trackBindingForModule(
70
66
  ids.push(id);
71
67
  }
72
68
 
73
- // ── Registration target ───────────────────────────────────────────────────────
69
+ // ── Registration target ──────────────────────────────────────────────────────────────────────────────────────────────
74
70
 
75
71
  /**
76
72
  * Where a chain registers, and on whose behalf.
@@ -82,10 +78,11 @@ function trackBindingForModule(
82
78
  */
83
79
  export interface BindingRegistration {
84
80
  readonly registry: BindingRegistry;
81
+ readonly scope: ScopeManager;
85
82
  readonly moduleBindingIds: Array<BindingIdentifier> | undefined;
86
83
  }
87
84
 
88
- // ── BindingChain ──────────────────────────────────────────────────────────────
85
+ // ── BindingChain ─────────────────────────────────────────────────────────────────────────────────────────────────────
89
86
 
90
87
  /**
91
88
  * The one builder behind `bind()` and every `to*()` return type. Each interface exposes only the
@@ -109,6 +106,8 @@ export class BindingChain<Value>
109
106
  #binding: Binding<Value> | undefined;
110
107
  // Allocated only by a chain that actually displaces something — most never do.
111
108
  #displacedByChain: Array<Binding> | undefined;
109
+ // Registry version after this chain's last write — a mismatch means someone else wrote in between.
110
+ #versionAfterLastWrite = -1;
112
111
  readonly #token: Token<Value> | Constructor<Value>;
113
112
  readonly #registration: BindingRegistration;
114
113
 
@@ -134,7 +133,7 @@ export class BindingChain<Value>
134
133
  return this;
135
134
  }
136
135
 
137
- // ── Registration ───────────────────────────────────────────────────────────
136
+ // ── Registration ───────────────────────────────────────────────────────────────────────────────────────────────────
138
137
 
139
138
  to(type: Constructor<Value>): BindingBuilder<Value> {
140
139
  return this.#register({ kind: "class", target: type, scope: "transient" });
@@ -187,37 +186,57 @@ export class BindingChain<Value>
187
186
  return this.#register({ kind: "alias", scope: "transient", target });
188
187
  }
189
188
 
190
- // ── Refinement ─────────────────────────────────────────────────────────────
189
+ // ── Refinement ─────────────────────────────────────────────────────────────────────────────────────────────────────
191
190
 
192
191
  // Slot and predicate are what the registry indexes on, so a re-slot rebuilds the binding and
193
192
  // re-registers it — under the original id, keeping `id()` stable for the whole chain.
194
- #reslot(slot: BindingSlot, predicate: ((ctx: ConstraintContext) => boolean) | undefined): this {
193
+ #reslot(slot: BindingSlot, predicate: BindingConstraint | undefined): this {
195
194
  const previous = this.#registered();
196
195
  this.#binding = createBinding(previous, previous.token, slot, predicate, previous.id);
197
196
  this.#commit(this.#binding, previous.id);
197
+ // The tracked-singleton list holds object references, and the re-slot just replaced the object.
198
+ this.#registration.scope.replaceSingleton(previous as Binding, this.#binding as Binding);
198
199
  return this;
199
200
  }
200
201
 
201
202
  #withScope(scope: BindingScope): this {
202
203
  const binding = this.#registered();
203
- refinableFields(binding).scope = scope;
204
+ if (binding.scope !== scope) {
205
+ // An instance cached under the old scope must not survive the change — a later flip back
206
+ // to that scope would resurrect it.
207
+ this.#registration.scope.deleteSingleton(binding);
208
+ this.#registration.scope.deleteScoped(binding.id);
209
+ refinableFields(binding).scope = scope;
210
+ }
204
211
  // The frame reports the scope, so a resolve before this call memoized the previous one.
205
212
  clearBindingFrame(binding);
206
213
  this.#registration.registry.touch();
214
+ this.#versionAfterLastWrite = this.#registration.registry.version;
207
215
  return this;
208
216
  }
209
217
 
210
- when(predicate: (ctx: ConstraintContext) => boolean): this {
211
- return this.#reslot(this.#registered().slot, predicate);
218
+ // SPEC calls a candidate a binding that passes *all* of a chain's predicates, and the chain type
219
+ // reads as refinement, so a second `when()` narrows rather than replaces.
220
+ when(predicate: BindingConstraint): this {
221
+ const binding = this.#registered();
222
+ const previous = binding.predicate;
223
+
224
+ if (previous === undefined) {
225
+ return this.#reslot(binding.slot, predicate);
226
+ }
227
+ // The composite carries both sides' requirements, so validate() still sees them.
228
+ const composed = mergingConstraintRequirements((ctx) => previous(ctx) && predicate(ctx), previous, predicate);
229
+
230
+ return this.#reslot(binding.slot, composed);
212
231
  }
213
232
 
214
233
  whenNamed(name: string): this {
215
234
  return this.#reslot({ ...this.#registered().slot, name }, this.#registered().predicate);
216
235
  }
217
236
 
218
- whenTagged(tag: string, value: unknown): this {
237
+ whenTagged(criterion: BindingTag): this {
219
238
  const binding = this.#registered();
220
- return this.#reslot(updateSlotTag(binding.slot, tag, value), binding.predicate);
239
+ return this.#reslot(updateSlotTag(binding.slot, criterion), binding.predicate);
221
240
  }
222
241
 
223
242
  whenDefault(): this {
@@ -242,12 +261,14 @@ export class BindingChain<Value>
242
261
  onActivation(fn: ActivationHandler<Value>): this {
243
262
  refinableFields(this.#registered()).onActivation = fn;
244
263
  this.#registration.registry.touch();
264
+ this.#versionAfterLastWrite = this.#registration.registry.version;
245
265
  return this;
246
266
  }
247
267
 
248
268
  onDeactivation(fn: DeactivationHandler<Value>): this {
249
269
  refinableFields(this.#registered()).onDeactivation = fn;
250
270
  this.#registration.registry.touch();
271
+ this.#versionAfterLastWrite = this.#registration.registry.version;
251
272
  return this;
252
273
  }
253
274
 
@@ -255,10 +276,10 @@ export class BindingChain<Value>
255
276
  return this.#registered().id;
256
277
  }
257
278
 
258
- // ── Registry ───────────────────────────────────────────────────────────────
279
+ // ── Registry ───────────────────────────────────────────────────────────────────────────────────────────────────────
259
280
 
260
281
  /**
261
- * Register `binding`, first removing `previousId` when the chain is re-slotting.
282
+ * Registers `binding`, first removing `previousId` when the chain is re-slotting.
262
283
  *
263
284
  * @remarks A `when*()` that follows `to*()` re-slots an already-live binding and can displace one
264
285
  * the final shape would never conflict with. Those stay parked in `#displacedByChain` until the
@@ -271,24 +292,38 @@ export class BindingChain<Value>
271
292
  const registered = binding as Binding;
272
293
 
273
294
  if (previousId !== undefined) {
274
- registry.removeById(previousId);
295
+ // A registry someone else wrote since this chain's last write invalidates the parked
296
+ // snapshot: restoring it could undo an unbind or shadow a newer binding.
297
+ if (registry.version !== this.#versionAfterLastWrite) {
298
+ this.#displacedByChain = undefined;
299
+ }
300
+ if (registry.removeById(previousId) === undefined) {
301
+ // The chain's binding is no longer live (unbound or displaced) — a refinement must not
302
+ // resurrect it, so the chain goes inert against the registry.
303
+ this.#displacedByChain = undefined;
304
+ this.#versionAfterLastWrite = registry.version;
305
+ return;
306
+ }
275
307
  }
276
308
  const displaced = registry.add(registered);
277
309
  if (displaced !== undefined) {
278
310
  (this.#displacedByChain ??= []).push(displaced);
279
311
  }
280
312
  if (previousId !== undefined && this.#displacedByChain !== undefined) {
281
- this.#restoreNonConflicting(registered, this.#displacedByChain);
313
+ this.#restoreNonConflicting(this.#displacedByChain);
282
314
  }
283
315
  if (moduleBindingIds !== undefined) {
284
316
  trackBindingForModule(moduleBindingIds, registered.id, previousId);
285
317
  }
318
+ this.#versionAfterLastWrite = registry.version;
286
319
  }
287
320
 
288
- #restoreNonConflicting(binding: Binding, displaced: Array<Binding>): void {
321
+ #restoreNonConflicting(displaced: Array<Binding>): void {
289
322
  for (let index = displaced.length - 1; index >= 0; index -= 1) {
290
323
  const candidate = displaced[index]!;
291
- if (!displacesRestoredBinding(binding, candidate)) {
324
+ // A restore must never displace: a slot that has been re-occupied keeps its occupant, and
325
+ // the candidate stays parked.
326
+ if (!this.#registration.registry.hasSlotOccupant(candidate)) {
292
327
  this.#registration.registry.add(candidate);
293
328
  displaced.splice(index, 1);
294
329
  }