@blac/core 2.0.20 → 2.0.22

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 (295) hide show
  1. package/README.md +19 -29
  2. package/dist/{StateContainerRegistry-CSNm2Ws5.cjs → StateContainerRegistry-141uHhtF.cjs} +300 -397
  3. package/dist/StateContainerRegistry-141uHhtF.cjs.map +1 -0
  4. package/dist/{StateContainerRegistry-DVIBTxGZ.js → StateContainerRegistry-BH7aOMWV.js} +299 -406
  5. package/dist/StateContainerRegistry-BH7aOMWV.js.map +1 -0
  6. package/dist/{StateContainerRegistry-Dj77cok9.js → StateContainerRegistry-BsH_s0pJ.js} +303 -413
  7. package/dist/StateContainerRegistry-BsH_s0pJ.js.map +1 -0
  8. package/dist/{StateContainerRegistry-lIwo-0m3.cjs → StateContainerRegistry-CBLeHObO.cjs} +326 -418
  9. package/dist/StateContainerRegistry-CBLeHObO.cjs.map +1 -0
  10. package/dist/{StateContainerRegistry-D9BIRjwv.cjs → StateContainerRegistry-MkT0W4C2.cjs} +322 -411
  11. package/dist/StateContainerRegistry-MkT0W4C2.cjs.map +1 -0
  12. package/dist/{StateContainerRegistry-CvBOhAT2.js → StateContainerRegistry-vWgsD-RP.js} +277 -392
  13. package/dist/StateContainerRegistry-vWgsD-RP.js.map +1 -0
  14. package/dist/config.d.cts +2 -2
  15. package/dist/config.d.ts +2 -2
  16. package/dist/constants.d.cts +4 -20
  17. package/dist/constants.d.ts +4 -20
  18. package/dist/core/Cubit.d.ts +14 -10
  19. package/dist/core/StateContainer.d.ts +68 -8
  20. package/dist/core/StateContainerRegistry.d.ts +100 -19
  21. package/dist/core/meta.d.ts +34 -47
  22. package/dist/core/symbols.d.ts +18 -1
  23. package/dist/decorators/blac.d.ts +28 -26
  24. package/dist/{ensure-BKdq5xsY.cjs → ensure-BjhbDW8Z.cjs} +223 -40
  25. package/dist/ensure-BjhbDW8Z.cjs.map +1 -0
  26. package/dist/ensure-BnVyd6s4.js +730 -0
  27. package/dist/ensure-BnVyd6s4.js.map +1 -0
  28. package/dist/ensure-CneMkpbI.js +731 -0
  29. package/dist/ensure-CneMkpbI.js.map +1 -0
  30. package/dist/{ensure-CQimeD0I.cjs → ensure-D15vGnk5.cjs} +348 -124
  31. package/dist/ensure-D15vGnk5.cjs.map +1 -0
  32. package/dist/{ensure-B1dEDsZV.cjs → ensure-D3w6YGp9.cjs} +349 -124
  33. package/dist/ensure-D3w6YGp9.cjs.map +1 -0
  34. package/dist/{ensure-B2DYCbbI.cjs → ensure-ORVw-WRE.cjs} +214 -39
  35. package/dist/ensure-ORVw-WRE.cjs.map +1 -0
  36. package/dist/{ensure-B59ri8oo.js → ensure-dsqWhIuO.js} +192 -39
  37. package/dist/ensure-dsqWhIuO.js.map +1 -0
  38. package/dist/{ensure-BSJHkUNX.js → ensure-k-6q7O25.js} +183 -38
  39. package/dist/ensure-k-6q7O25.js.map +1 -0
  40. package/dist/index.cjs +212 -32
  41. package/dist/index.cjs.map +1 -1
  42. package/dist/index.d.cts +4 -6
  43. package/dist/index.d.ts +4 -6
  44. package/dist/index.js +192 -12
  45. package/dist/index.js.map +1 -1
  46. package/dist/plugin/BlacPlugin.d.ts +14 -0
  47. package/dist/plugin/PluginManager.d.ts +21 -11
  48. package/dist/plugins.cjs +403 -3
  49. package/dist/plugins.cjs.map +1 -0
  50. package/dist/plugins.d.cts +6 -2
  51. package/dist/plugins.d.ts +6 -2
  52. package/dist/plugins.js +401 -1
  53. package/dist/plugins.js.map +1 -0
  54. package/dist/registry/acquire.d.ts +2 -2
  55. package/dist/registry/config.d.ts +9 -0
  56. package/dist/registry/management.d.ts +3 -0
  57. package/dist/registry/queries.d.ts +15 -0
  58. package/dist/registry/release.d.ts +3 -3
  59. package/dist/testing.cjs +13 -15
  60. package/dist/testing.cjs.map +1 -1
  61. package/dist/testing.d.cts +1 -1
  62. package/dist/testing.d.ts +1 -1
  63. package/dist/testing.js +2 -4
  64. package/dist/testing.js.map +1 -1
  65. package/dist/types/branded.d.ts +3 -3
  66. package/dist/types/utilities.d.ts +45 -18
  67. package/dist/utils/static-props.d.ts +25 -1
  68. package/dist/utils/structural-key.d.ts +0 -7
  69. package/dist/watch/index.d.ts +1 -1
  70. package/dist/watch/watch.d.ts +22 -3
  71. package/package.json +16 -55
  72. package/dist/StateContainerRegistry-4Ljd9EJx.js +0 -1018
  73. package/dist/StateContainerRegistry-4Ljd9EJx.js.map +0 -1
  74. package/dist/StateContainerRegistry-8zNFMAf7.js +0 -1067
  75. package/dist/StateContainerRegistry-8zNFMAf7.js.map +0 -1
  76. package/dist/StateContainerRegistry-B1GYx9Xo.js +0 -975
  77. package/dist/StateContainerRegistry-B1GYx9Xo.js.map +0 -1
  78. package/dist/StateContainerRegistry-B_ViBLvJ.js +0 -975
  79. package/dist/StateContainerRegistry-B_ViBLvJ.js.map +0 -1
  80. package/dist/StateContainerRegistry-Bx2ly-ba.cjs +0 -1162
  81. package/dist/StateContainerRegistry-Bx2ly-ba.cjs.map +0 -1
  82. package/dist/StateContainerRegistry-C0dCNlTF.js +0 -1005
  83. package/dist/StateContainerRegistry-C0dCNlTF.js.map +0 -1
  84. package/dist/StateContainerRegistry-CEWpc1bj.cjs +0 -1113
  85. package/dist/StateContainerRegistry-CEWpc1bj.cjs.map +0 -1
  86. package/dist/StateContainerRegistry-CS18y4au.cjs +0 -1163
  87. package/dist/StateContainerRegistry-CS18y4au.cjs.map +0 -1
  88. package/dist/StateContainerRegistry-CSNm2Ws5.cjs.map +0 -1
  89. package/dist/StateContainerRegistry-CchRjnjX.cjs +0 -1094
  90. package/dist/StateContainerRegistry-CchRjnjX.cjs.map +0 -1
  91. package/dist/StateContainerRegistry-CvBOhAT2.js.map +0 -1
  92. package/dist/StateContainerRegistry-D8nu7Z0T.js +0 -1068
  93. package/dist/StateContainerRegistry-D8nu7Z0T.js.map +0 -1
  94. package/dist/StateContainerRegistry-D9BIRjwv.cjs.map +0 -1
  95. package/dist/StateContainerRegistry-DJQqLrli.cjs +0 -1046
  96. package/dist/StateContainerRegistry-DJQqLrli.cjs.map +0 -1
  97. package/dist/StateContainerRegistry-DVIBTxGZ.js.map +0 -1
  98. package/dist/StateContainerRegistry-Dj77cok9.js.map +0 -1
  99. package/dist/StateContainerRegistry-FWKzPfS-.cjs +0 -1046
  100. package/dist/StateContainerRegistry-FWKzPfS-.cjs.map +0 -1
  101. package/dist/StateContainerRegistry-lIwo-0m3.cjs.map +0 -1
  102. package/dist/acquire-B1LYXSGj.js +0 -35
  103. package/dist/acquire-B1LYXSGj.js.map +0 -1
  104. package/dist/acquire-B1Wuqla6.cjs +0 -46
  105. package/dist/acquire-B1Wuqla6.cjs.map +0 -1
  106. package/dist/acquire-BJ3xUEmh.cjs +0 -46
  107. package/dist/acquire-BJ3xUEmh.cjs.map +0 -1
  108. package/dist/acquire-BP-ZfUH2.js +0 -35
  109. package/dist/acquire-BP-ZfUH2.js.map +0 -1
  110. package/dist/acquire-BRIJVJaA.js +0 -35
  111. package/dist/acquire-BRIJVJaA.js.map +0 -1
  112. package/dist/acquire-BZIs6tpN.cjs +0 -46
  113. package/dist/acquire-BZIs6tpN.cjs.map +0 -1
  114. package/dist/acquire-B_p1fNEh.cjs +0 -46
  115. package/dist/acquire-B_p1fNEh.cjs.map +0 -1
  116. package/dist/acquire-BdsVZBSe.js +0 -35
  117. package/dist/acquire-BdsVZBSe.js.map +0 -1
  118. package/dist/acquire-C3nOb3XR.cjs +0 -46
  119. package/dist/acquire-C3nOb3XR.cjs.map +0 -1
  120. package/dist/acquire-C4WAS13G.cjs +0 -46
  121. package/dist/acquire-C4WAS13G.cjs.map +0 -1
  122. package/dist/acquire-C7beGI55.cjs +0 -46
  123. package/dist/acquire-C7beGI55.cjs.map +0 -1
  124. package/dist/acquire-CbMz7gWs.cjs +0 -46
  125. package/dist/acquire-CbMz7gWs.cjs.map +0 -1
  126. package/dist/acquire-CwB083au.js +0 -35
  127. package/dist/acquire-CwB083au.js.map +0 -1
  128. package/dist/acquire-DHEOEVcj.cjs +0 -46
  129. package/dist/acquire-DHEOEVcj.cjs.map +0 -1
  130. package/dist/acquire-DXEQDZGr.js +0 -35
  131. package/dist/acquire-DXEQDZGr.js.map +0 -1
  132. package/dist/acquire-Dg-uXwjF.js +0 -35
  133. package/dist/acquire-Dg-uXwjF.js.map +0 -1
  134. package/dist/acquire-Don7499S.js +0 -35
  135. package/dist/acquire-Don7499S.js.map +0 -1
  136. package/dist/acquire-G8aB3GAx.js +0 -35
  137. package/dist/acquire-G8aB3GAx.js.map +0 -1
  138. package/dist/branded-BybA0_xw.cjs +0 -18
  139. package/dist/branded-BybA0_xw.cjs.map +0 -1
  140. package/dist/branded-DkbUzncc.js +0 -13
  141. package/dist/branded-DkbUzncc.js.map +0 -1
  142. package/dist/config-8pyOC5gv.js +0 -16
  143. package/dist/config-8pyOC5gv.js.map +0 -1
  144. package/dist/config-B1l8ZGlU.cjs +0 -32
  145. package/dist/config-B1l8ZGlU.cjs.map +0 -1
  146. package/dist/config-C7Ktkjh2.cjs +0 -32
  147. package/dist/config-C7Ktkjh2.cjs.map +0 -1
  148. package/dist/config-COT4Xkbc.js +0 -16
  149. package/dist/config-COT4Xkbc.js.map +0 -1
  150. package/dist/config-CzcoAvBo.js +0 -16
  151. package/dist/config-CzcoAvBo.js.map +0 -1
  152. package/dist/config-D6BoWWPv.js +0 -16
  153. package/dist/config-D6BoWWPv.js.map +0 -1
  154. package/dist/config-DOO82lbZ.js +0 -16
  155. package/dist/config-DOO82lbZ.js.map +0 -1
  156. package/dist/config-DVM_ESQt.js +0 -16
  157. package/dist/config-DVM_ESQt.js.map +0 -1
  158. package/dist/config-DVMnlHLv.cjs +0 -32
  159. package/dist/config-DVMnlHLv.cjs.map +0 -1
  160. package/dist/config-DWUq7zEQ.cjs +0 -32
  161. package/dist/config-DWUq7zEQ.cjs.map +0 -1
  162. package/dist/config-DXI3kzmA.js +0 -16
  163. package/dist/config-DXI3kzmA.js.map +0 -1
  164. package/dist/config-Dk1FxfXj.js +0 -16
  165. package/dist/config-Dk1FxfXj.js.map +0 -1
  166. package/dist/config-b2z51Y_C.cjs +0 -32
  167. package/dist/config-b2z51Y_C.cjs.map +0 -1
  168. package/dist/config-buwpT7l3.js +0 -16
  169. package/dist/config-buwpT7l3.js.map +0 -1
  170. package/dist/config-cwaTn5oy.cjs +0 -32
  171. package/dist/config-cwaTn5oy.cjs.map +0 -1
  172. package/dist/config-d9_U58ef.cjs +0 -32
  173. package/dist/config-d9_U58ef.cjs.map +0 -1
  174. package/dist/config-hWTayX76.cjs +0 -32
  175. package/dist/config-hWTayX76.cjs.map +0 -1
  176. package/dist/config-sCPKPYxZ.cjs +0 -32
  177. package/dist/config-sCPKPYxZ.cjs.map +0 -1
  178. package/dist/debug.cjs +0 -14
  179. package/dist/debug.d.cts +0 -34
  180. package/dist/debug.d.ts +0 -34
  181. package/dist/debug.js +0 -4
  182. package/dist/ensure-B1dEDsZV.cjs.map +0 -1
  183. package/dist/ensure-B2DYCbbI.cjs.map +0 -1
  184. package/dist/ensure-B59ri8oo.js.map +0 -1
  185. package/dist/ensure-B9oOqpOB.cjs +0 -558
  186. package/dist/ensure-B9oOqpOB.cjs.map +0 -1
  187. package/dist/ensure-BKdq5xsY.cjs.map +0 -1
  188. package/dist/ensure-BSJHkUNX.js.map +0 -1
  189. package/dist/ensure-BfYnvAsI.js +0 -709
  190. package/dist/ensure-BfYnvAsI.js.map +0 -1
  191. package/dist/ensure-Bm91o37h.js +0 -536
  192. package/dist/ensure-Bm91o37h.js.map +0 -1
  193. package/dist/ensure-C1a8IFWy.js +0 -535
  194. package/dist/ensure-C1a8IFWy.js.map +0 -1
  195. package/dist/ensure-CLQEx0Nn.cjs +0 -528
  196. package/dist/ensure-CLQEx0Nn.cjs.map +0 -1
  197. package/dist/ensure-CPMiGvov.js +0 -493
  198. package/dist/ensure-CPMiGvov.js.map +0 -1
  199. package/dist/ensure-CQimeD0I.cjs.map +0 -1
  200. package/dist/ensure-DEXSmA-N.js +0 -526
  201. package/dist/ensure-DEXSmA-N.js.map +0 -1
  202. package/dist/ensure-DTTTd2h8.js +0 -536
  203. package/dist/ensure-DTTTd2h8.js.map +0 -1
  204. package/dist/ensure-Dx86f80B.cjs +0 -567
  205. package/dist/ensure-Dx86f80B.cjs.map +0 -1
  206. package/dist/ensure-DzqGej43.js +0 -526
  207. package/dist/ensure-DzqGej43.js.map +0 -1
  208. package/dist/ensure-VuiNPccZ.cjs +0 -559
  209. package/dist/ensure-VuiNPccZ.cjs.map +0 -1
  210. package/dist/ensure-_Oh8XPm4.cjs +0 -732
  211. package/dist/ensure-_Oh8XPm4.cjs.map +0 -1
  212. package/dist/ensure-fsQMjaQL.cjs +0 -567
  213. package/dist/ensure-fsQMjaQL.cjs.map +0 -1
  214. package/dist/ensure-vxAGa2v3.js +0 -536
  215. package/dist/ensure-vxAGa2v3.js.map +0 -1
  216. package/dist/management-14vsHr4t.cjs +0 -85
  217. package/dist/management-14vsHr4t.cjs.map +0 -1
  218. package/dist/management-444tdCBG.js +0 -38
  219. package/dist/management-444tdCBG.js.map +0 -1
  220. package/dist/management-7jLjVHJd.js +0 -38
  221. package/dist/management-7jLjVHJd.js.map +0 -1
  222. package/dist/management-AFuqQEwz.js +0 -38
  223. package/dist/management-AFuqQEwz.js.map +0 -1
  224. package/dist/management-BodVLAfJ.cjs +0 -85
  225. package/dist/management-BodVLAfJ.cjs.map +0 -1
  226. package/dist/management-BqGBdL01.js +0 -38
  227. package/dist/management-BqGBdL01.js.map +0 -1
  228. package/dist/management-BvUAjril.js +0 -38
  229. package/dist/management-BvUAjril.js.map +0 -1
  230. package/dist/management-C-WGcwPD.js +0 -38
  231. package/dist/management-C-WGcwPD.js.map +0 -1
  232. package/dist/management-C2wv4vGS.cjs +0 -85
  233. package/dist/management-C2wv4vGS.cjs.map +0 -1
  234. package/dist/management-D2pjr38g.js +0 -38
  235. package/dist/management-D2pjr38g.js.map +0 -1
  236. package/dist/management-D5WsZoTV.js +0 -38
  237. package/dist/management-D5WsZoTV.js.map +0 -1
  238. package/dist/management-DAV9sN-k.cjs +0 -85
  239. package/dist/management-DAV9sN-k.cjs.map +0 -1
  240. package/dist/management-Df7Y2sF1.cjs +0 -85
  241. package/dist/management-Df7Y2sF1.cjs.map +0 -1
  242. package/dist/management-DwO0nBzL.cjs +0 -85
  243. package/dist/management-DwO0nBzL.cjs.map +0 -1
  244. package/dist/management-GcnNJjnm.cjs +0 -85
  245. package/dist/management-GcnNJjnm.cjs.map +0 -1
  246. package/dist/management-P_Vi_cvw.js +0 -38
  247. package/dist/management-P_Vi_cvw.js.map +0 -1
  248. package/dist/management-QWLpbXlW.cjs +0 -85
  249. package/dist/management-QWLpbXlW.cjs.map +0 -1
  250. package/dist/management-iE4x6IQY.cjs +0 -85
  251. package/dist/management-iE4x6IQY.cjs.map +0 -1
  252. package/dist/types.cjs +0 -3
  253. package/dist/types.d.cts +0 -8
  254. package/dist/types.d.ts +0 -8
  255. package/dist/types.js +0 -2
  256. package/dist/watch-B0pUfh-v.cjs +0 -119
  257. package/dist/watch-B0pUfh-v.cjs.map +0 -1
  258. package/dist/watch-B91opmva.cjs +0 -70
  259. package/dist/watch-B91opmva.cjs.map +0 -1
  260. package/dist/watch-BHfCtbn1.cjs +0 -119
  261. package/dist/watch-BHfCtbn1.cjs.map +0 -1
  262. package/dist/watch-BmC-Tyqg.js +0 -59
  263. package/dist/watch-BmC-Tyqg.js.map +0 -1
  264. package/dist/watch-Bx0y-Kcc.js +0 -108
  265. package/dist/watch-Bx0y-Kcc.js.map +0 -1
  266. package/dist/watch-CKWt788i.cjs +0 -70
  267. package/dist/watch-CKWt788i.cjs.map +0 -1
  268. package/dist/watch-CfrSSrRY.js +0 -59
  269. package/dist/watch-CfrSSrRY.js.map +0 -1
  270. package/dist/watch-Cnh3PtQA.cjs +0 -70
  271. package/dist/watch-Cnh3PtQA.cjs.map +0 -1
  272. package/dist/watch-D01MdwKy.js +0 -108
  273. package/dist/watch-D01MdwKy.js.map +0 -1
  274. package/dist/watch-D8hwbFU1.js +0 -59
  275. package/dist/watch-D8hwbFU1.js.map +0 -1
  276. package/dist/watch-DPVUwPUY.js +0 -59
  277. package/dist/watch-DPVUwPUY.js.map +0 -1
  278. package/dist/watch-DVmvZBMD.cjs +0 -70
  279. package/dist/watch-DVmvZBMD.cjs.map +0 -1
  280. package/dist/watch-DkDGmGAx.cjs +0 -119
  281. package/dist/watch-DkDGmGAx.cjs.map +0 -1
  282. package/dist/watch-DttHqefn.js +0 -108
  283. package/dist/watch-DttHqefn.js.map +0 -1
  284. package/dist/watch-DxdIZjpt.cjs +0 -119
  285. package/dist/watch-DxdIZjpt.cjs.map +0 -1
  286. package/dist/watch-DztcJuUy.cjs +0 -119
  287. package/dist/watch-DztcJuUy.cjs.map +0 -1
  288. package/dist/watch-IrR8G28N.js +0 -108
  289. package/dist/watch-IrR8G28N.js.map +0 -1
  290. package/dist/watch-entry.cjs +0 -4
  291. package/dist/watch-entry.d.cts +0 -24
  292. package/dist/watch-entry.d.ts +0 -24
  293. package/dist/watch-entry.js +0 -2
  294. package/dist/watch-hx0r92Zc.js +0 -108
  295. package/dist/watch-hx0r92Zc.js.map +0 -1
package/dist/index.cjs CHANGED
@@ -1,21 +1,16 @@
1
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
- const require_StateContainerRegistry = require("./StateContainerRegistry-CS18y4au.cjs");
3
- const require_ensure = require("./ensure-B2DYCbbI.cjs");
4
- const require_config = require("./config-DWUq7zEQ.cjs");
5
- const require_acquire = require("./acquire-BJ3xUEmh.cjs");
6
- const require_management = require("./management-QWLpbXlW.cjs");
7
- const require_watch = require("./watch-DxdIZjpt.cjs");
8
- const require_branded = require("./branded-BybA0_xw.cjs");
2
+ const require_StateContainerRegistry = require("./StateContainerRegistry-CBLeHObO.cjs");
3
+ const require_ensure = require("./ensure-D3w6YGp9.cjs");
9
4
  let _dirtytalk_structural = require("@dirtytalk/structural");
10
5
  //#region src/registry/borrow.ts
11
6
  function resolveBorrowKey(BlocClass, target) {
12
- return require_config.getRegistry().resolveKey(BlocClass, void 0, target?.args);
7
+ return require_ensure.getRegistry().resolveKey(BlocClass, void 0, target?.args);
13
8
  }
14
9
  function borrow(BlocClass, target) {
15
- return require_config.getRegistry().borrow(BlocClass, resolveBorrowKey(BlocClass, target));
10
+ return require_ensure.getRegistry().borrow(BlocClass, resolveBorrowKey(BlocClass, target));
16
11
  }
17
12
  function borrowSafe(BlocClass, target) {
18
- return require_config.getRegistry().borrowSafe(BlocClass, resolveBorrowKey(BlocClass, target));
13
+ return require_ensure.getRegistry().borrowSafe(BlocClass, resolveBorrowKey(BlocClass, target));
19
14
  }
20
15
  //#endregion
21
16
  //#region src/registry/release.ts
@@ -23,16 +18,68 @@ function borrowSafe(BlocClass, target) {
23
18
  * Release a reference to an instance. Instance identity is derived purely from
24
19
  * `args` (must match the `args` it was acquired with).
25
20
  *
26
- * @param opts.args - Construction/identity args; derives the instance key
27
- * @param opts.refId - The specific ref to drop; drops one arbitrary ref if omitted
28
- * @param opts.forceDispose - Force immediate disposal regardless of refs
21
+ * @param opts - `args` derives the instance key (must match acquire);
22
+ * `refId` picks the ref to drop, otherwise one arbitrary ref goes;
23
+ * `forceDispose` disposes immediately regardless of remaining refs.
29
24
  */
30
25
  function release(BlocClass, opts) {
31
- const registry = require_config.getRegistry();
26
+ const registry = require_ensure.getRegistry();
32
27
  const key = registry.resolveKey(BlocClass, void 0, opts?.args);
33
28
  registry.release(BlocClass, key, opts?.forceDispose ?? false, opts?.refId);
34
29
  }
35
30
  //#endregion
31
+ //#region src/registry/queries.ts
32
+ /**
33
+ * @public
34
+ */
35
+ function hasInstance(BlocClass, opts) {
36
+ const registry = require_ensure.getRegistry();
37
+ const key = registry.resolveKey(BlocClass, void 0, opts?.args);
38
+ return registry.hasInstance(BlocClass, key);
39
+ }
40
+ /**
41
+ * @public
42
+ */
43
+ function getRefCount(BlocClass, opts) {
44
+ const registry = require_ensure.getRegistry();
45
+ const key = registry.resolveKey(BlocClass, void 0, opts?.args);
46
+ return registry.getRefCount(BlocClass, key);
47
+ }
48
+ /**
49
+ * @public
50
+ */
51
+ function getRefIds(BlocClass, opts) {
52
+ const registry = require_ensure.getRegistry();
53
+ const key = registry.resolveKey(BlocClass, void 0, opts?.args);
54
+ return registry.getRefIds(BlocClass, key);
55
+ }
56
+ /**
57
+ * @public
58
+ */
59
+ function getAll(BlocClass) {
60
+ return require_ensure.getRegistry().getAll(BlocClass);
61
+ }
62
+ /**
63
+ * @public
64
+ */
65
+ function forEach(BlocClass, callback) {
66
+ require_ensure.getRegistry().forEach(BlocClass, callback);
67
+ }
68
+ //#endregion
69
+ //#region src/registry/management.ts
70
+ function clear(BlocClass) {
71
+ require_ensure.getRegistry().clear(BlocClass);
72
+ }
73
+ function clearAll() {
74
+ require_ensure.getRegistry().clearAll();
75
+ }
76
+ /**
77
+ * @public
78
+ */
79
+ function register(BlocClass) {
80
+ require_ensure.getRegistry().register(BlocClass);
81
+ }
82
+ //#endregion
36
83
  //#region src/decorators/blac.ts
37
84
  /**
38
85
  * Decorator to configure StateContainer classes.
@@ -44,6 +91,9 @@ function release(BlocClass, opts) {
44
91
  *
45
92
  * @blac({ excludeFromDevTools: true })
46
93
  * class InternalBloc extends Cubit<InternalState> {}
94
+ *
95
+ * @blac({ keepAlive: true, key: (args) => args.userId })
96
+ * class UserBloc extends Cubit<UserState> {}
47
97
  * ```
48
98
  *
49
99
  * @example Function syntax (no decorator support needed)
@@ -59,10 +109,140 @@ function blac(options) {
59
109
  if ("excludeFromDevTools" in options && options.excludeFromDevTools) target[require_StateContainerRegistry.BLAC_STATIC_PROPS.EXCLUDE_FROM_DEVTOOLS] = true;
60
110
  if ("equality" in options && typeof options.equality === "function") target[require_StateContainerRegistry.BLAC_STATIC_PROPS.EQUALITY] = options.equality;
61
111
  if ("key" in options && typeof options.key === "function") target[require_StateContainerRegistry.BLAC_STATIC_PROPS.KEY] = options.key;
112
+ if ("name" in options && typeof options.name === "string") target[require_StateContainerRegistry.BLAC_STATIC_PROPS.BLAC_NAME] = options.name;
62
113
  return target;
63
114
  };
64
115
  }
65
116
  //#endregion
117
+ //#region src/watch/watch.ts
118
+ const STOP = Symbol("watch.STOP");
119
+ const BLOC_REF_MARKER = Symbol("BlocRef");
120
+ /**
121
+ * Create a reference to a specific bloc instance, identified by its `args`.
122
+ * The key is derived the same way `useBloc`/`acquire` derive it.
123
+ *
124
+ * @example
125
+ * ```ts
126
+ * watch(instance(UserBloc, { userId: 'user-123' }), (userBloc) => {
127
+ * console.log(userBloc.state.name);
128
+ * });
129
+ * ```
130
+ */
131
+ function instance(BlocClass, args) {
132
+ return {
133
+ [BLOC_REF_MARKER]: true,
134
+ blocClass: BlocClass,
135
+ instanceId: require_ensure.resolveInstanceKey(BlocClass, args),
136
+ args
137
+ };
138
+ }
139
+ function isBlocRef(input) {
140
+ return typeof input === "object" && input !== null && BLOC_REF_MARKER in input;
141
+ }
142
+ function toWatchTarget(input) {
143
+ const registry = require_ensure.getRegistry();
144
+ if (isBlocRef(input)) return {
145
+ blocClass: input.blocClass,
146
+ key: input.instanceId,
147
+ args: input.args
148
+ };
149
+ return {
150
+ blocClass: input,
151
+ key: registry.resolveKey(input, void 0, void 0),
152
+ args: void 0
153
+ };
154
+ }
155
+ let watchRefSeq = 0;
156
+ /**
157
+ * Acquire a real ref (countRef: true) for the target, carrying its `args`
158
+ * through so a not-yet-created instance is initialized correctly. The
159
+ * caller is responsible for releasing `refId` in cleanup.
160
+ */
161
+ function resolveBloc(target, refId) {
162
+ return require_ensure.getRegistry().acquire(target.blocClass, target.key, {
163
+ countRef: true,
164
+ refId,
165
+ args: target.args
166
+ });
167
+ }
168
+ /**
169
+ * Passive lookup for `{ create: false }`: never creates the instance and
170
+ * never takes a ref. Returns `undefined` when no instance currently exists.
171
+ */
172
+ function resolveBlocPassive(target) {
173
+ const registry = require_ensure.getRegistry();
174
+ try {
175
+ return registry.acquire(target.blocClass, target.key, {
176
+ canCreate: false,
177
+ countRef: false,
178
+ args: target.args
179
+ });
180
+ } catch {
181
+ return;
182
+ }
183
+ }
184
+ function isArray(input) {
185
+ return Array.isArray(input);
186
+ }
187
+ function watchImpl(blocsOrBloc, callback, options) {
188
+ const isSingle = !isArray(blocsOrBloc);
189
+ const inputs = isSingle ? [blocsOrBloc] : blocsOrBloc;
190
+ const registry = require_ensure.getRegistry();
191
+ const create = options?.create ?? true;
192
+ const targets = inputs.map(toWatchTarget);
193
+ const refIds = targets.map(() => `_watch_${watchRefSeq++}`);
194
+ let disposed = false;
195
+ const instances = targets.map((target, i) => create ? resolveBloc(target, refIds[i]) : resolveBlocPassive(target));
196
+ const channelUnsubs = [];
197
+ const disposedUnsubs = [];
198
+ const cleanup = () => {
199
+ if (disposed) return;
200
+ disposed = true;
201
+ for (const unsub of channelUnsubs) unsub?.();
202
+ for (const unsub of disposedUnsubs) unsub?.();
203
+ channelUnsubs.length = 0;
204
+ disposedUnsubs.length = 0;
205
+ if (create) for (let i = 0; i < targets.length; i++) registry.release(targets[i].blocClass, targets[i].key, false, refIds[i]);
206
+ };
207
+ const runCallback = () => {
208
+ if (disposed) return;
209
+ if (instances.some((i) => i === void 0)) return;
210
+ if (callback(isSingle ? instances[0] : instances) === STOP) cleanup();
211
+ };
212
+ const subscribeAt = (index) => {
213
+ channelUnsubs[index] = instances[index]?.channel.subscribe(() => _dirtytalk_structural.ALL_PATHS, runCallback);
214
+ };
215
+ const resubscribeAt = (index) => {
216
+ if (disposed) return;
217
+ instances[index] = create ? resolveBloc(targets[index], refIds[index]) : resolveBlocPassive(targets[index]);
218
+ subscribeAt(index);
219
+ subscribeDisposeAt(index);
220
+ runCallback();
221
+ };
222
+ const subscribeDisposeAt = (index) => {
223
+ disposedUnsubs[index] = instances[index]?.[require_StateContainerRegistry.ON_DISPOSE](() => {
224
+ channelUnsubs[index]?.();
225
+ channelUnsubs[index] = void 0;
226
+ queueMicrotask(() => resubscribeAt(index));
227
+ });
228
+ };
229
+ for (let i = 0; i < instances.length; i++) subscribeAt(i);
230
+ for (let i = 0; i < instances.length; i++) subscribeDisposeAt(i);
231
+ runCallback();
232
+ return cleanup;
233
+ }
234
+ const watch = Object.assign(watchImpl, { STOP });
235
+ //#endregion
236
+ //#region src/types/branded.ts
237
+ /**
238
+ * Create a branded InstanceId from a string
239
+ * @param id - The string ID to brand
240
+ * @returns Branded InstanceId
241
+ */
242
+ function instanceId(id) {
243
+ return id;
244
+ }
245
+ //#endregion
66
246
  Object.defineProperty(exports, "ALL_PATHS", {
67
247
  enumerable: true,
68
248
  get: function() {
@@ -74,38 +254,38 @@ exports.Cubit = require_ensure.Cubit;
74
254
  exports.DEP_BRAND = require_ensure.DEP_BRAND;
75
255
  exports.INIT_CONFIG = require_StateContainerRegistry.INIT_CONFIG;
76
256
  exports.ON_DISPOSE = require_StateContainerRegistry.ON_DISPOSE;
77
- exports.PluginManager = require_StateContainerRegistry.PluginManager;
78
257
  exports.REMOVE_DEPS_OWNER = require_StateContainerRegistry.REMOVE_DEPS_OWNER;
79
258
  exports.StateContainer = require_ensure.StateContainer;
80
259
  exports.StateContainerRegistry = require_StateContainerRegistry.StateContainerRegistry;
81
- exports.acquire = require_acquire.acquire;
260
+ exports.WITH_TRACKED_STATE = require_StateContainerRegistry.WITH_TRACKED_STATE;
261
+ exports.acquire = require_ensure.acquire;
82
262
  exports.blac = blac;
83
263
  exports.borrow = borrow;
84
264
  exports.borrowSafe = borrowSafe;
85
- exports.clear = require_management.clear;
86
- exports.clearAll = require_management.clearAll;
265
+ exports.clear = clear;
266
+ exports.clearAll = clearAll;
87
267
  exports.configureBlac = require_StateContainerRegistry.configureBlac;
88
268
  exports.ensure = require_ensure.ensure;
89
- exports.forEach = require_management.forEach;
90
- exports.getAll = require_management.getAll;
269
+ exports.forEach = forEach;
270
+ exports.getAll = getAll;
91
271
  exports.getBlacConfig = require_StateContainerRegistry.getBlacConfig;
92
- exports.getPluginManager = require_StateContainerRegistry.getPluginManager;
93
- exports.getRefCount = require_management.getRefCount;
94
- exports.getRefIds = require_management.getRefIds;
95
- exports.getRegistry = require_config.getRegistry;
96
- exports.getStats = require_config.getStats;
272
+ exports.getBlacName = require_StateContainerRegistry.getBlacName;
273
+ exports.getRefCount = getRefCount;
274
+ exports.getRefIds = getRefIds;
275
+ exports.getRegistry = require_ensure.getRegistry;
276
+ exports.getStats = require_ensure.getStats;
97
277
  exports.globalRegistry = require_StateContainerRegistry.globalRegistry;
98
- exports.hasInstance = require_management.hasInstance;
99
- exports.instance = require_watch.instance;
100
- exports.instanceId = require_branded.instanceId;
278
+ exports.hasInstance = hasInstance;
279
+ exports.instance = instance;
280
+ exports.instanceId = instanceId;
101
281
  exports.isExcludedFromDevTools = require_StateContainerRegistry.isExcludedFromDevTools;
102
282
  exports.isKeepAliveClass = require_StateContainerRegistry.isKeepAliveClass;
103
- exports.register = require_management.register;
283
+ exports.register = register;
104
284
  exports.release = release;
105
285
  exports.resetBlacConfig = require_StateContainerRegistry.resetBlacConfig;
106
- exports.resolveInstanceKey = require_acquire.resolveInstanceKey;
107
- exports.setRegistry = require_config.setRegistry;
286
+ exports.resolveInstanceKey = require_ensure.resolveInstanceKey;
287
+ exports.setRegistry = require_ensure.setRegistry;
108
288
  exports.shallowEqualState = require_StateContainerRegistry.shallowEqualState;
109
- exports.watch = require_watch.watch;
289
+ exports.watch = watch;
110
290
 
111
291
  //# sourceMappingURL=index.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.cjs","names":["getRegistry","getRegistry","BLAC_STATIC_PROPS"],"sources":["../src/registry/borrow.ts","../src/registry/release.ts","../src/decorators/blac.ts"],"sourcesContent":["import { getRegistry } from './config';\nimport type {\n ExtractArgs,\n StateContainerConstructor,\n} from '../types/utilities';\n\n/**\n * How to identify the instance to borrow: the same `args` shape `useBloc`\n * accepts, resolved through the class's `static key(args)` so call sites use\n * the *same* shape they pass to `useBloc` instead of hand-deriving the key.\n *\n * `borrowSafe(ChannelBloc, { args: { channelId } })` and\n * `useBloc(ChannelBloc, { args: { channelId } })` therefore always agree.\n */\nexport type BorrowTarget<T extends StateContainerConstructor> = {\n args?: ExtractArgs<T>;\n};\n\nfunction resolveBorrowKey<T extends StateContainerConstructor>(\n BlocClass: T,\n target: BorrowTarget<T> | undefined,\n): string {\n return getRegistry().resolveKey(BlocClass, undefined, target?.args);\n}\n\nexport function borrow<T extends StateContainerConstructor>(\n BlocClass: T,\n target?: BorrowTarget<T>,\n): InstanceType<T> {\n return getRegistry().borrow(BlocClass, resolveBorrowKey(BlocClass, target));\n}\n\nexport function borrowSafe<T extends StateContainerConstructor>(\n BlocClass: T,\n target?: BorrowTarget<T>,\n):\n | { error: Error; instance: null }\n | { error: null; instance: InstanceType<T> } {\n return getRegistry().borrowSafe(\n BlocClass,\n resolveBorrowKey(BlocClass, target),\n );\n}\n","import { getRegistry } from './config';\nimport type {\n ExtractArgs,\n StateContainerConstructor,\n} from '../types/utilities';\n\n/**\n * Release a reference to an instance. Instance identity is derived purely from\n * `args` (must match the `args` it was acquired with).\n *\n * @param opts.args - Construction/identity args; derives the instance key\n * @param opts.refId - The specific ref to drop; drops one arbitrary ref if omitted\n * @param opts.forceDispose - Force immediate disposal regardless of refs\n */\nexport function release<T extends StateContainerConstructor>(\n BlocClass: T,\n opts?: { args?: ExtractArgs<T>; refId?: string; forceDispose?: boolean },\n): void {\n const registry = getRegistry();\n const key = registry.resolveKey(BlocClass, undefined, opts?.args);\n registry.release(BlocClass, key, opts?.forceDispose ?? false, opts?.refId);\n}\n","import { BLAC_STATIC_PROPS } from '../constants';\nimport type { EqualityFn } from '../config';\n\n/**\n * Configuration options for the @blac decorator.\n * Only one option can be specified at a time (union type).\n */\nexport type BlacOptions =\n /** Mark bloc to never be auto-disposed when ref count reaches 0 */\n | { keepAlive: true }\n /** Exclude bloc from DevTools tracking (prevents infinite loops) */\n | { excludeFromDevTools: true }\n /**\n * Override the global equality check for this bloc.\n * Return `true` to skip the emit (states considered equal).\n */\n | { equality: EqualityFn }\n /**\n * Override the default structural-hash identity key.\n * The function receives `args` and returns the instance key string.\n * Distinct return values → distinct instances; identical values → shared instance.\n * Non-identity fields can be excluded so they don't fork new instances.\n */\n | { key: (args: any) => string };\n\n/**\n * Decorator to configure StateContainer classes.\n *\n * @example Decorator syntax (requires experimentalDecorators or TC39 decorators)\n * ```ts\n * @blac({ keepAlive: true })\n * class AuthBloc extends Cubit<AuthState> {}\n *\n * @blac({ excludeFromDevTools: true })\n * class InternalBloc extends Cubit<InternalState> {}\n * ```\n *\n * @example Function syntax (no decorator support needed)\n * ```ts\n * const AuthBloc = blac({ keepAlive: true })(\n * class extends Cubit<AuthState> {}\n * );\n * ```\n */\nexport function blac(options: BlacOptions) {\n return function <T extends new (...args: any[]) => any>(\n target: T,\n _context?: ClassDecoratorContext,\n ): T {\n if ('keepAlive' in options && options.keepAlive) {\n (target as any)[BLAC_STATIC_PROPS.KEEP_ALIVE] = true;\n }\n if ('excludeFromDevTools' in options && options.excludeFromDevTools) {\n (target as any)[BLAC_STATIC_PROPS.EXCLUDE_FROM_DEVTOOLS] = true;\n }\n if ('equality' in options && typeof options.equality === 'function') {\n (target as any)[BLAC_STATIC_PROPS.EQUALITY] = options.equality;\n }\n if ('key' in options && typeof options.key === 'function') {\n (target as any)[BLAC_STATIC_PROPS.KEY] = options.key;\n }\n return target;\n };\n}\n"],"mappings":";;;;;;;;;;AAkBA,SAAS,iBACP,WACA,QACQ;CACR,OAAOA,eAAAA,YAAY,EAAE,WAAW,WAAW,KAAA,GAAW,QAAQ,IAAI;AACpE;AAEA,SAAgB,OACd,WACA,QACiB;CACjB,OAAOA,eAAAA,YAAY,EAAE,OAAO,WAAW,iBAAiB,WAAW,MAAM,CAAC;AAC5E;AAEA,SAAgB,WACd,WACA,QAG6C;CAC7C,OAAOA,eAAAA,YAAY,EAAE,WACnB,WACA,iBAAiB,WAAW,MAAM,CACpC;AACF;;;;;;;;;;;AC5BA,SAAgB,QACd,WACA,MACM;CACN,MAAM,WAAWC,eAAAA,YAAY;CAC7B,MAAM,MAAM,SAAS,WAAW,WAAW,KAAA,GAAW,MAAM,IAAI;CAChE,SAAS,QAAQ,WAAW,KAAK,MAAM,gBAAgB,OAAO,MAAM,KAAK;AAC3E;;;;;;;;;;;;;;;;;;;;;;ACuBA,SAAgB,KAAK,SAAsB;CACzC,OAAO,SACL,QACA,UACG;EACH,IAAI,eAAe,WAAW,QAAQ,WACpC,OAAgBC,+BAAAA,kBAAkB,cAAc;EAElD,IAAI,yBAAyB,WAAW,QAAQ,qBAC9C,OAAgBA,+BAAAA,kBAAkB,yBAAyB;EAE7D,IAAI,cAAc,WAAW,OAAO,QAAQ,aAAa,YACvD,OAAgBA,+BAAAA,kBAAkB,YAAY,QAAQ;EAExD,IAAI,SAAS,WAAW,OAAO,QAAQ,QAAQ,YAC7C,OAAgBA,+BAAAA,kBAAkB,OAAO,QAAQ;EAEnD,OAAO;CACT;AACF"}
1
+ {"version":3,"file":"index.cjs","names":["getRegistry","getRegistry","getRegistry","BLAC_STATIC_PROPS","resolveInstanceKey","getRegistry","ALL_PATHS","ON_DISPOSE"],"sources":["../src/registry/borrow.ts","../src/registry/release.ts","../src/registry/queries.ts","../src/registry/management.ts","../src/decorators/blac.ts","../src/watch/watch.ts","../src/types/branded.ts"],"sourcesContent":["import { getRegistry } from './config';\nimport type {\n ExtractArgs,\n StateContainerConstructor,\n} from '../types/utilities';\n\n/**\n * How to identify the instance to borrow: the same `args` shape `useBloc`\n * accepts, resolved through the class's `static key(args)` so call sites use\n * the *same* shape they pass to `useBloc` instead of hand-deriving the key.\n *\n * `borrowSafe(ChannelBloc, { args: { channelId } })` and\n * `useBloc(ChannelBloc, { args: { channelId } })` therefore always agree.\n */\nexport type BorrowTarget<T extends StateContainerConstructor> = {\n args?: ExtractArgs<T>;\n};\n\nfunction resolveBorrowKey<T extends StateContainerConstructor>(\n BlocClass: T,\n target: BorrowTarget<T> | undefined,\n): string {\n return getRegistry().resolveKey(BlocClass, undefined, target?.args);\n}\n\nexport function borrow<T extends StateContainerConstructor>(\n BlocClass: T,\n target?: BorrowTarget<T>,\n): InstanceType<T> {\n return getRegistry().borrow(BlocClass, resolveBorrowKey(BlocClass, target));\n}\n\nexport function borrowSafe<T extends StateContainerConstructor>(\n BlocClass: T,\n target?: BorrowTarget<T>,\n):\n | { error: Error; instance: null }\n | { error: null; instance: InstanceType<T> } {\n return getRegistry().borrowSafe(\n BlocClass,\n resolveBorrowKey(BlocClass, target),\n );\n}\n","import { getRegistry } from './config';\nimport type {\n ExtractArgs,\n StateContainerConstructor,\n} from '../types/utilities';\n\n/**\n * Release a reference to an instance. Instance identity is derived purely from\n * `args` (must match the `args` it was acquired with).\n *\n * @param opts - `args` derives the instance key (must match acquire);\n * `refId` picks the ref to drop, otherwise one arbitrary ref goes;\n * `forceDispose` disposes immediately regardless of remaining refs.\n */\nexport function release<T extends StateContainerConstructor>(\n BlocClass: T,\n opts?: { args?: ExtractArgs<T>; refId?: string; forceDispose?: boolean },\n): void {\n const registry = getRegistry();\n const key = registry.resolveKey(BlocClass, undefined, opts?.args);\n registry.release(BlocClass, key, opts?.forceDispose ?? false, opts?.refId);\n}\n","import { getRegistry } from './config';\nimport type {\n ExtractArgs,\n StateContainerConstructor,\n InstanceReadonlyState,\n} from '../types/utilities';\n\n/**\n * @public\n */\nexport function hasInstance<T extends StateContainerConstructor>(\n BlocClass: T,\n opts?: { args?: ExtractArgs<T> },\n): boolean {\n const registry = getRegistry();\n const key = registry.resolveKey(BlocClass, undefined, opts?.args);\n return registry.hasInstance(BlocClass, key);\n}\n\n/**\n * @public\n */\nexport function getRefCount<T extends StateContainerConstructor>(\n BlocClass: T,\n opts?: { args?: ExtractArgs<T> },\n): number {\n const registry = getRegistry();\n const key = registry.resolveKey(BlocClass, undefined, opts?.args);\n return registry.getRefCount(BlocClass, key);\n}\n\n/**\n * @public\n */\nexport function getRefIds<T extends StateContainerConstructor>(\n BlocClass: T,\n opts?: { args?: ExtractArgs<T> },\n): string[] {\n const registry = getRegistry();\n const key = registry.resolveKey(BlocClass, undefined, opts?.args);\n return registry.getRefIds(BlocClass, key);\n}\n\n/**\n * @public\n */\nexport function getAll<T extends StateContainerConstructor>(\n BlocClass: T,\n): InstanceReadonlyState<T>[] {\n return getRegistry().getAll(BlocClass);\n}\n\n/**\n * @public\n */\nexport function forEach<T extends StateContainerConstructor>(\n BlocClass: T,\n callback: (instance: InstanceReadonlyState<T>) => void,\n): void {\n getRegistry().forEach(BlocClass, callback);\n}\n","import { getRegistry } from './config';\nimport type { StateContainerConstructor } from '../types/utilities';\n\nexport function clear<T extends StateContainerConstructor>(BlocClass: T): void {\n getRegistry().clear(BlocClass);\n}\n\nexport function clearAll(): void {\n getRegistry().clearAll();\n}\n\n/**\n * @public\n */\nexport function register<T extends StateContainerConstructor>(\n BlocClass: T,\n): void {\n getRegistry().register(BlocClass);\n}\n","import { BLAC_STATIC_PROPS } from '../constants';\nimport type { EqualityFn } from '../config';\n\n/**\n * Configuration options for the `@blac` decorator. Any combination may be\n * given at once.\n */\nexport interface BlacOptions {\n /** Mark bloc to never be auto-disposed when ref count reaches 0 */\n keepAlive?: true;\n /** Exclude bloc from DevTools tracking (prevents infinite loops) */\n excludeFromDevTools?: true;\n /**\n * Override the global equality check for this bloc.\n * Return `true` to skip the emit (states considered equal).\n */\n equality?: EqualityFn;\n /**\n * Override the default structural-hash identity key.\n * The function receives `args` and returns the instance key string.\n * Distinct return values → distinct instances; identical values → shared instance.\n * Non-identity fields can be excluded so they don't fork new instances.\n */\n key?: (args: any) => string;\n /**\n * Explicit, minification-safe identity for this bloc class. Falls back to\n * `constructor.name` when unset, which collides across classes once a\n * minifier shortens class names.\n */\n name?: string;\n}\n\n/**\n * Decorator to configure StateContainer classes.\n *\n * @example Decorator syntax (requires experimentalDecorators or TC39 decorators)\n * ```ts\n * @blac({ keepAlive: true })\n * class AuthBloc extends Cubit<AuthState> {}\n *\n * @blac({ excludeFromDevTools: true })\n * class InternalBloc extends Cubit<InternalState> {}\n *\n * @blac({ keepAlive: true, key: (args) => args.userId })\n * class UserBloc extends Cubit<UserState> {}\n * ```\n *\n * @example Function syntax (no decorator support needed)\n * ```ts\n * const AuthBloc = blac({ keepAlive: true })(\n * class extends Cubit<AuthState> {}\n * );\n * ```\n */\nexport function blac(options: BlacOptions) {\n return function <T extends new (...args: any[]) => any>(\n target: T,\n _context?: ClassDecoratorContext,\n ): T {\n if ('keepAlive' in options && options.keepAlive) {\n (target as any)[BLAC_STATIC_PROPS.KEEP_ALIVE] = true;\n }\n if ('excludeFromDevTools' in options && options.excludeFromDevTools) {\n (target as any)[BLAC_STATIC_PROPS.EXCLUDE_FROM_DEVTOOLS] = true;\n }\n if ('equality' in options && typeof options.equality === 'function') {\n (target as any)[BLAC_STATIC_PROPS.EQUALITY] = options.equality;\n }\n if ('key' in options && typeof options.key === 'function') {\n (target as any)[BLAC_STATIC_PROPS.KEY] = options.key;\n }\n if ('name' in options && typeof options.name === 'string') {\n (target as any)[BLAC_STATIC_PROPS.BLAC_NAME] = options.name;\n }\n return target;\n };\n}\n","import { ALL_PATHS } from '@dirtytalk/structural';\nimport { ON_DISPOSE } from '../core/symbols';\nimport { getRegistry } from '../registry';\nimport { resolveInstanceKey } from '../registry/acquire';\nimport type {\n ExtractArgs,\n StateContainerConstructor,\n StateContainerInstance,\n} from '../types/utilities';\n\nconst STOP: unique symbol = Symbol('watch.STOP');\ntype StopSymbol = typeof STOP;\n\nconst BLOC_REF_MARKER = Symbol('BlocRef');\n\n/**\n * Reference to a specific bloc instance, identified by class + the resolved\n * key derived from its `args`.\n */\nexport interface BlocRef<T extends StateContainerConstructor> {\n [BLOC_REF_MARKER]: true;\n blocClass: T;\n /** @internal The resolved instance key (derived from `args`). */\n instanceId: string;\n /**\n * @internal The `args` used to derive `instanceId`. Forwarded to\n * `registry.acquire` so a not-yet-created instance is initialized with\n * these args instead of `undefined`.\n */\n args?: unknown;\n}\n\n/**\n * Create a reference to a specific bloc instance, identified by its `args`.\n * The key is derived the same way `useBloc`/`acquire` derive it.\n *\n * @example\n * ```ts\n * watch(instance(UserBloc, { userId: 'user-123' }), (userBloc) => {\n * console.log(userBloc.state.name);\n * });\n * ```\n */\nexport function instance<T extends StateContainerConstructor>(\n BlocClass: T,\n args?: ExtractArgs<T>,\n): BlocRef<T> {\n return {\n [BLOC_REF_MARKER]: true,\n blocClass: BlocClass,\n instanceId: resolveInstanceKey(BlocClass, args),\n args,\n };\n}\n\nfunction isBlocRef(\n input: unknown,\n): input is BlocRef<StateContainerConstructor> {\n return (\n typeof input === 'object' && input !== null && BLOC_REF_MARKER in input\n );\n}\n\ntype BlocInput = StateContainerConstructor | BlocRef<StateContainerConstructor>;\n\n/**\n * Options for `watch`.\n */\nexport interface WatchOptions {\n /**\n * When `false`, `watch` observes passively instead of owning the instance:\n * it does not create a missing instance, and it does not take a real\n * ownership ref on an existing one (so it never keeps an otherwise-\n * unreferenced instance alive).\n *\n * If the instance does not exist yet when `watch` is called, the callback\n * simply never fires for it — `watch` does not poll or wait for a later\n * creation. Call `watch` again once the instance is known to exist (e.g.\n * after some other owner has acquired it).\n *\n * Defaults to `true`.\n */\n create?: boolean;\n}\n\ntype ExtractInstance<T> =\n T extends BlocRef<infer C>\n ? InstanceType<C>\n : T extends StateContainerConstructor\n ? InstanceType<T>\n : never;\n\ntype ExtractInstances<T extends readonly BlocInput[]> = {\n [K in keyof T]: ExtractInstance<T[K]>;\n};\n\n/**\n * Watch function signature for single bloc.\n */\nexport interface WatchSingleFn {\n <T extends StateContainerConstructor>(\n bloc: T | BlocRef<T>,\n callback: (bloc: InstanceType<T>) => void | StopSymbol,\n options?: WatchOptions,\n ): () => void;\n\n STOP: StopSymbol;\n}\n\n/**\n * Watch function signature for multiple blocs.\n */\nexport interface WatchMultipleFn {\n <T extends readonly BlocInput[]>(\n blocs: T,\n callback: (blocs: ExtractInstances<T>) => void | StopSymbol,\n options?: WatchOptions,\n ): () => void;\n\n STOP: StopSymbol;\n}\n\n/**\n * Combined watch function type.\n */\nexport interface WatchFn extends WatchSingleFn {\n <T extends readonly BlocInput[]>(\n blocs: T,\n callback: (blocs: ExtractInstances<T>) => void | StopSymbol,\n options?: WatchOptions,\n ): () => void;\n}\n\n/**\n * Class + resolved key + args needed to (re-)acquire a specific instance.\n * `watch` keeps this around per input so it can re-acquire the same logical\n * instance if the underlying container is disposed elsewhere.\n */\ninterface WatchTarget {\n blocClass: StateContainerConstructor;\n key: string;\n args: unknown;\n}\n\nfunction toWatchTarget(input: BlocInput): WatchTarget {\n const registry = getRegistry();\n if (isBlocRef(input)) {\n return {\n blocClass: input.blocClass,\n key: input.instanceId,\n args: input.args,\n };\n }\n return {\n blocClass: input,\n key: registry.resolveKey(input, undefined, undefined),\n args: undefined,\n };\n}\n\nlet watchRefSeq = 0;\n\n/**\n * Acquire a real ref (countRef: true) for the target, carrying its `args`\n * through so a not-yet-created instance is initialized correctly. The\n * caller is responsible for releasing `refId` in cleanup.\n */\nfunction resolveBloc(\n target: WatchTarget,\n refId: string,\n): StateContainerInstance {\n const registry = getRegistry();\n return registry.acquire(target.blocClass, target.key, {\n countRef: true,\n refId,\n args: target.args,\n });\n}\n\n/**\n * Passive lookup for `{ create: false }`: never creates the instance and\n * never takes a ref. Returns `undefined` when no instance currently exists.\n */\nfunction resolveBlocPassive(\n target: WatchTarget,\n): StateContainerInstance | undefined {\n const registry = getRegistry();\n try {\n return registry.acquire(target.blocClass, target.key, {\n canCreate: false,\n countRef: false,\n args: target.args,\n });\n } catch {\n return undefined;\n }\n}\n\nfunction isArray(input: unknown): input is readonly BlocInput[] {\n return Array.isArray(input);\n}\n\n/**\n * Watch one or more blocs for state changes.\n *\n * Thin wrapper around `container.channel.subscribe(ALL_PATHS, ...)`. The\n * callback fires once immediately, then on every state change of any of the\n * passed blocs. Returning `watch.STOP` from the callback tears down all\n * subscriptions.\n *\n * Note: subscriptions are microtask-deferred (per the DirtyChannel default\n * scheduler), so callbacks land asynchronously after `emit()`.\n *\n * By default `watch` creates the instance if it does not exist and holds a\n * real ownership ref until `unwatch`, matching `acquire`. Pass\n * `{ create: false }` to observe passively instead — see `WatchOptions`.\n *\n * @example Single bloc\n * ```ts\n * const unwatch = watch(UserBloc, (userBloc) => {\n * console.log(userBloc.state.name);\n * });\n * ```\n *\n * @example Multiple blocs\n * ```ts\n * const unwatch = watch(\n * [UserBloc, SettingsBloc] as const,\n * ([userBloc, settingsBloc]) => {\n * console.log(userBloc.state.name, settingsBloc.state.theme);\n * }\n * );\n * ```\n *\n * @example With specific instance\n * ```ts\n * const unwatch = watch(\n * instance(UserBloc, { userId: 'user-123' }),\n * (userBloc) => {\n * console.log(userBloc.state.name);\n * }\n * );\n * ```\n *\n * @example Stop watching from callback\n * ```ts\n * const unwatch = watch(UserBloc, (userBloc) => {\n * if (userBloc.state.done) {\n * return watch.STOP;\n * }\n * });\n * ```\n */\nfunction watchImpl<T extends StateContainerConstructor>(\n bloc: T | BlocRef<T>,\n callback: (bloc: InstanceType<T>) => void | StopSymbol,\n options?: WatchOptions,\n): () => void;\n\nfunction watchImpl<T extends readonly BlocInput[]>(\n blocs: T,\n callback: (blocs: ExtractInstances<T>) => void | StopSymbol,\n options?: WatchOptions,\n): () => void;\n\nfunction watchImpl(\n blocsOrBloc: BlocInput | readonly BlocInput[],\n callback: (blocsOrBloc: any) => void | StopSymbol,\n options?: WatchOptions,\n): () => void {\n const isSingle = !isArray(blocsOrBloc);\n const inputs = isSingle ? [blocsOrBloc] : blocsOrBloc;\n const registry = getRegistry();\n const create = options?.create ?? true;\n\n const targets = inputs.map(toWatchTarget);\n const refIds = targets.map(() => `_watch_${watchRefSeq++}`);\n\n let disposed = false;\n const instances: Array<StateContainerInstance | undefined> = targets.map(\n (target, i) =>\n create ? resolveBloc(target, refIds[i]) : resolveBlocPassive(target),\n );\n const channelUnsubs: Array<(() => void) | undefined> = [];\n const disposedUnsubs: Array<(() => void) | undefined> = [];\n\n const cleanup = () => {\n if (disposed) return;\n disposed = true;\n for (const unsub of channelUnsubs) unsub?.();\n for (const unsub of disposedUnsubs) unsub?.();\n channelUnsubs.length = 0;\n disposedUnsubs.length = 0;\n if (create) {\n for (let i = 0; i < targets.length; i++) {\n registry.release(\n targets[i].blocClass,\n targets[i].key,\n false,\n refIds[i],\n );\n }\n }\n };\n\n const runCallback = () => {\n if (disposed) return;\n if (instances.some((i) => i === undefined)) return;\n const arg = isSingle ? instances[0] : instances;\n const result = callback(arg);\n if (result === STOP) cleanup();\n };\n\n const subscribeAt = (index: number) => {\n channelUnsubs[index] = instances[index]?.channel.subscribe(\n () => ALL_PATHS,\n runCallback,\n );\n };\n\n // On external dispose, tear down the stale subscription and re-acquire +\n // resubscribe (microtask-deferred, so it never runs mid-mutation of the\n // registry that triggered the dispose, e.g. `clearAll()`), then notify.\n const resubscribeAt = (index: number) => {\n if (disposed) return;\n instances[index] = create\n ? resolveBloc(targets[index], refIds[index])\n : resolveBlocPassive(targets[index]);\n subscribeAt(index);\n subscribeDisposeAt(index);\n runCallback();\n };\n\n const subscribeDisposeAt = (index: number) => {\n disposedUnsubs[index] = instances[index]?.[ON_DISPOSE](() => {\n channelUnsubs[index]?.();\n channelUnsubs[index] = undefined;\n queueMicrotask(() => resubscribeAt(index));\n });\n };\n\n for (let i = 0; i < instances.length; i++) {\n subscribeAt(i);\n }\n\n for (let i = 0; i < instances.length; i++) {\n subscribeDisposeAt(i);\n }\n\n // Fire once immediately so the consumer sees the current state.\n runCallback();\n\n return cleanup;\n}\n\nexport const watch: WatchFn = Object.assign(watchImpl, { STOP }) as WatchFn;\n","declare const brand: unique symbol;\n\n/**\n * Utility type for creating branded/nominal types.\n * Prevents accidental type confusion between similar primitive types.\n * @typeParam T - The base type\n * @typeParam B - The brand identifier\n */\nexport type Brand<T, B> = T & { [brand]: B };\n\n/**\n * Branded string type for type-safe IDs.\n * @typeParam B - The brand identifier\n */\nexport type BrandedId<B> = Brand<string, B>;\n\n/**\n * Branded string type for state container instance IDs\n */\nexport type InstanceId = Brand<string, 'InstanceId'>;\n\n/**\n * Create a branded InstanceId from a string\n * @param id - The string ID to brand\n * @returns Branded InstanceId\n */\nexport function instanceId(id: string): InstanceId {\n return id as InstanceId;\n}\n"],"mappings":"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"}
package/dist/index.d.cts CHANGED
@@ -6,7 +6,7 @@ export { Cubit } from './core/Cubit';
6
6
  * @internal symbols — read by `@blac/react` (APPLY_DEPS / REMOVE_DEPS_OWNER),
7
7
  * in-package tests (INIT_CONFIG), and `watch()` (ON_DISPOSE).
8
8
  */
9
- export { APPLY_DEPS, REMOVE_DEPS_OWNER, INIT_CONFIG, ON_DISPOSE, } from './core/symbols';
9
+ export { APPLY_DEPS, REMOVE_DEPS_OWNER, INIT_CONFIG, ON_DISPOSE, WITH_TRACKED_STATE, } from './core/symbols';
10
10
  export type { BlacMeta, BlacHydration } from './core/meta';
11
11
  export { ALL_PATHS } from '@dirtytalk/structural';
12
12
  export type { PathSet } from '@dirtytalk/structural';
@@ -15,11 +15,9 @@ export type { BorrowTarget } from './registry';
15
15
  export { globalRegistry, StateContainerRegistry, } from './core/StateContainerRegistry';
16
16
  export type { LifecycleEvent, LifecycleListener, InstanceEntry, } from './core/StateContainerRegistry';
17
17
  export { blac, type BlacOptions } from './decorators';
18
- export { isKeepAliveClass, isExcludedFromDevTools } from './utils/static-props';
19
- export { getPluginManager } from './core/StateContainerRegistry';
18
+ export { isKeepAliveClass, isExcludedFromDevTools, getBlacName, } from './utils/static-props';
20
19
  export type { BlacPlugin, BlacPluginWithInit, PluginContext, PluginConfig, InstanceMetadata, } from './plugin/BlacPlugin';
21
- export { PluginManager } from './plugin/PluginManager';
22
- export { watch, instance, type WatchFn, type BlocRef } from './watch';
23
- export type { StateContainerConstructor, ExtractState, ExtractStateMutable, ExtractConstructorArgs, ExtractArgs, ExtractDeps, BlocInstanceType, BlocConstructor, InstanceReadonlyState, InstanceState, StateContainerInstance, } from './types/utilities';
20
+ export { watch, instance, type WatchFn, type WatchOptions, type BlocRef, } from './watch';
21
+ export type { StateContainerConstructor, DeepReadonly, ExtractState, ExtractStateMutable, ExtractConstructorArgs, ExtractArgs, ExtractDeps, BlocInstanceType, BlocConstructor, InstanceReadonlyState, WithState, InstanceState, StateContainerInstance, } from './types/utilities';
24
22
  export type { Brand, BrandedId, InstanceId } from './types/branded';
25
23
  export { instanceId } from './types/branded';
package/dist/index.d.ts CHANGED
@@ -6,7 +6,7 @@ export { Cubit } from './core/Cubit';
6
6
  * @internal symbols — read by `@blac/react` (APPLY_DEPS / REMOVE_DEPS_OWNER),
7
7
  * in-package tests (INIT_CONFIG), and `watch()` (ON_DISPOSE).
8
8
  */
9
- export { APPLY_DEPS, REMOVE_DEPS_OWNER, INIT_CONFIG, ON_DISPOSE, } from './core/symbols';
9
+ export { APPLY_DEPS, REMOVE_DEPS_OWNER, INIT_CONFIG, ON_DISPOSE, WITH_TRACKED_STATE, } from './core/symbols';
10
10
  export type { BlacMeta, BlacHydration } from './core/meta';
11
11
  export { ALL_PATHS } from '@dirtytalk/structural';
12
12
  export type { PathSet } from '@dirtytalk/structural';
@@ -15,11 +15,9 @@ export type { BorrowTarget } from './registry';
15
15
  export { globalRegistry, StateContainerRegistry, } from './core/StateContainerRegistry';
16
16
  export type { LifecycleEvent, LifecycleListener, InstanceEntry, } from './core/StateContainerRegistry';
17
17
  export { blac, type BlacOptions } from './decorators';
18
- export { isKeepAliveClass, isExcludedFromDevTools } from './utils/static-props';
19
- export { getPluginManager } from './core/StateContainerRegistry';
18
+ export { isKeepAliveClass, isExcludedFromDevTools, getBlacName, } from './utils/static-props';
20
19
  export type { BlacPlugin, BlacPluginWithInit, PluginContext, PluginConfig, InstanceMetadata, } from './plugin/BlacPlugin';
21
- export { PluginManager } from './plugin/PluginManager';
22
- export { watch, instance, type WatchFn, type BlocRef } from './watch';
23
- export type { StateContainerConstructor, ExtractState, ExtractStateMutable, ExtractConstructorArgs, ExtractArgs, ExtractDeps, BlocInstanceType, BlocConstructor, InstanceReadonlyState, InstanceState, StateContainerInstance, } from './types/utilities';
20
+ export { watch, instance, type WatchFn, type WatchOptions, type BlocRef, } from './watch';
21
+ export type { StateContainerConstructor, DeepReadonly, ExtractState, ExtractStateMutable, ExtractConstructorArgs, ExtractArgs, ExtractDeps, BlocInstanceType, BlocConstructor, InstanceReadonlyState, WithState, InstanceState, StateContainerInstance, } from './types/utilities';
24
22
  export type { Brand, BrandedId, InstanceId } from './types/branded';
25
23
  export { instanceId } from './types/branded';
package/dist/index.js CHANGED
@@ -1,11 +1,6 @@
1
- import { a as INIT_CONFIG, d as BLAC_STATIC_PROPS, f as PluginManager, g as shallowEqualState, h as resetBlacConfig, i as APPLY_DEPS, l as isExcludedFromDevTools, m as getBlacConfig, n as getPluginManager, o as ON_DISPOSE, p as configureBlac, r as globalRegistry, s as REMOVE_DEPS_OWNER, t as StateContainerRegistry, u as isKeepAliveClass } from "./StateContainerRegistry-D8nu7Z0T.js";
2
- import { i as StateContainer, n as Cubit, r as DEP_BRAND, t as ensure } from "./ensure-BSJHkUNX.js";
3
- import { n as getStats, r as setRegistry, t as getRegistry } from "./config-DXI3kzmA.js";
4
- import { n as resolveInstanceKey, t as acquire } from "./acquire-B1LYXSGj.js";
5
- import { a as getAll, c as hasInstance, i as forEach, n as clearAll, o as getRefCount, r as register, s as getRefIds, t as clear } from "./management-C-WGcwPD.js";
6
- import { n as watch, t as instance } from "./watch-DttHqefn.js";
7
- import { t as instanceId } from "./branded-DkbUzncc.js";
8
- import { ALL_PATHS } from "@dirtytalk/structural";
1
+ import { _ as resetBlacConfig, a as ON_DISPOSE, c as WITH_TRACKED_STATE, d as isExcludedFromDevTools, f as isKeepAliveClass, g as getBlacConfig, h as configureBlac, i as INIT_CONFIG, l as getBlacName, n as globalRegistry, o as REMOVE_DEPS_OWNER, p as BLAC_STATIC_PROPS, r as APPLY_DEPS, t as StateContainerRegistry, v as shallowEqualState } from "./StateContainerRegistry-BsH_s0pJ.js";
2
+ import { a as DEP_BRAND, c as getStats, i as Cubit, l as setRegistry, n as acquire, o as StateContainer, r as resolveInstanceKey, s as getRegistry, t as ensure } from "./ensure-CneMkpbI.js";
3
+ import { ALL_PATHS, ALL_PATHS as ALL_PATHS$1 } from "@dirtytalk/structural";
9
4
  //#region src/registry/borrow.ts
10
5
  function resolveBorrowKey(BlocClass, target) {
11
6
  return getRegistry().resolveKey(BlocClass, void 0, target?.args);
@@ -22,9 +17,9 @@ function borrowSafe(BlocClass, target) {
22
17
  * Release a reference to an instance. Instance identity is derived purely from
23
18
  * `args` (must match the `args` it was acquired with).
24
19
  *
25
- * @param opts.args - Construction/identity args; derives the instance key
26
- * @param opts.refId - The specific ref to drop; drops one arbitrary ref if omitted
27
- * @param opts.forceDispose - Force immediate disposal regardless of refs
20
+ * @param opts - `args` derives the instance key (must match acquire);
21
+ * `refId` picks the ref to drop, otherwise one arbitrary ref goes;
22
+ * `forceDispose` disposes immediately regardless of remaining refs.
28
23
  */
29
24
  function release(BlocClass, opts) {
30
25
  const registry = getRegistry();
@@ -32,6 +27,58 @@ function release(BlocClass, opts) {
32
27
  registry.release(BlocClass, key, opts?.forceDispose ?? false, opts?.refId);
33
28
  }
34
29
  //#endregion
30
+ //#region src/registry/queries.ts
31
+ /**
32
+ * @public
33
+ */
34
+ function hasInstance(BlocClass, opts) {
35
+ const registry = getRegistry();
36
+ const key = registry.resolveKey(BlocClass, void 0, opts?.args);
37
+ return registry.hasInstance(BlocClass, key);
38
+ }
39
+ /**
40
+ * @public
41
+ */
42
+ function getRefCount(BlocClass, opts) {
43
+ const registry = getRegistry();
44
+ const key = registry.resolveKey(BlocClass, void 0, opts?.args);
45
+ return registry.getRefCount(BlocClass, key);
46
+ }
47
+ /**
48
+ * @public
49
+ */
50
+ function getRefIds(BlocClass, opts) {
51
+ const registry = getRegistry();
52
+ const key = registry.resolveKey(BlocClass, void 0, opts?.args);
53
+ return registry.getRefIds(BlocClass, key);
54
+ }
55
+ /**
56
+ * @public
57
+ */
58
+ function getAll(BlocClass) {
59
+ return getRegistry().getAll(BlocClass);
60
+ }
61
+ /**
62
+ * @public
63
+ */
64
+ function forEach(BlocClass, callback) {
65
+ getRegistry().forEach(BlocClass, callback);
66
+ }
67
+ //#endregion
68
+ //#region src/registry/management.ts
69
+ function clear(BlocClass) {
70
+ getRegistry().clear(BlocClass);
71
+ }
72
+ function clearAll() {
73
+ getRegistry().clearAll();
74
+ }
75
+ /**
76
+ * @public
77
+ */
78
+ function register(BlocClass) {
79
+ getRegistry().register(BlocClass);
80
+ }
81
+ //#endregion
35
82
  //#region src/decorators/blac.ts
36
83
  /**
37
84
  * Decorator to configure StateContainer classes.
@@ -43,6 +90,9 @@ function release(BlocClass, opts) {
43
90
  *
44
91
  * @blac({ excludeFromDevTools: true })
45
92
  * class InternalBloc extends Cubit<InternalState> {}
93
+ *
94
+ * @blac({ keepAlive: true, key: (args) => args.userId })
95
+ * class UserBloc extends Cubit<UserState> {}
46
96
  * ```
47
97
  *
48
98
  * @example Function syntax (no decorator support needed)
@@ -58,10 +108,140 @@ function blac(options) {
58
108
  if ("excludeFromDevTools" in options && options.excludeFromDevTools) target[BLAC_STATIC_PROPS.EXCLUDE_FROM_DEVTOOLS] = true;
59
109
  if ("equality" in options && typeof options.equality === "function") target[BLAC_STATIC_PROPS.EQUALITY] = options.equality;
60
110
  if ("key" in options && typeof options.key === "function") target[BLAC_STATIC_PROPS.KEY] = options.key;
111
+ if ("name" in options && typeof options.name === "string") target[BLAC_STATIC_PROPS.BLAC_NAME] = options.name;
61
112
  return target;
62
113
  };
63
114
  }
64
115
  //#endregion
65
- export { ALL_PATHS, APPLY_DEPS, Cubit, DEP_BRAND, INIT_CONFIG, ON_DISPOSE, PluginManager, REMOVE_DEPS_OWNER, StateContainer, StateContainerRegistry, acquire, blac, borrow, borrowSafe, clear, clearAll, configureBlac, ensure, forEach, getAll, getBlacConfig, getPluginManager, getRefCount, getRefIds, getRegistry, getStats, globalRegistry, hasInstance, instance, instanceId, isExcludedFromDevTools, isKeepAliveClass, register, release, resetBlacConfig, resolveInstanceKey, setRegistry, shallowEqualState, watch };
116
+ //#region src/watch/watch.ts
117
+ const STOP = Symbol("watch.STOP");
118
+ const BLOC_REF_MARKER = Symbol("BlocRef");
119
+ /**
120
+ * Create a reference to a specific bloc instance, identified by its `args`.
121
+ * The key is derived the same way `useBloc`/`acquire` derive it.
122
+ *
123
+ * @example
124
+ * ```ts
125
+ * watch(instance(UserBloc, { userId: 'user-123' }), (userBloc) => {
126
+ * console.log(userBloc.state.name);
127
+ * });
128
+ * ```
129
+ */
130
+ function instance(BlocClass, args) {
131
+ return {
132
+ [BLOC_REF_MARKER]: true,
133
+ blocClass: BlocClass,
134
+ instanceId: resolveInstanceKey(BlocClass, args),
135
+ args
136
+ };
137
+ }
138
+ function isBlocRef(input) {
139
+ return typeof input === "object" && input !== null && BLOC_REF_MARKER in input;
140
+ }
141
+ function toWatchTarget(input) {
142
+ const registry = getRegistry();
143
+ if (isBlocRef(input)) return {
144
+ blocClass: input.blocClass,
145
+ key: input.instanceId,
146
+ args: input.args
147
+ };
148
+ return {
149
+ blocClass: input,
150
+ key: registry.resolveKey(input, void 0, void 0),
151
+ args: void 0
152
+ };
153
+ }
154
+ let watchRefSeq = 0;
155
+ /**
156
+ * Acquire a real ref (countRef: true) for the target, carrying its `args`
157
+ * through so a not-yet-created instance is initialized correctly. The
158
+ * caller is responsible for releasing `refId` in cleanup.
159
+ */
160
+ function resolveBloc(target, refId) {
161
+ return getRegistry().acquire(target.blocClass, target.key, {
162
+ countRef: true,
163
+ refId,
164
+ args: target.args
165
+ });
166
+ }
167
+ /**
168
+ * Passive lookup for `{ create: false }`: never creates the instance and
169
+ * never takes a ref. Returns `undefined` when no instance currently exists.
170
+ */
171
+ function resolveBlocPassive(target) {
172
+ const registry = getRegistry();
173
+ try {
174
+ return registry.acquire(target.blocClass, target.key, {
175
+ canCreate: false,
176
+ countRef: false,
177
+ args: target.args
178
+ });
179
+ } catch {
180
+ return;
181
+ }
182
+ }
183
+ function isArray(input) {
184
+ return Array.isArray(input);
185
+ }
186
+ function watchImpl(blocsOrBloc, callback, options) {
187
+ const isSingle = !isArray(blocsOrBloc);
188
+ const inputs = isSingle ? [blocsOrBloc] : blocsOrBloc;
189
+ const registry = getRegistry();
190
+ const create = options?.create ?? true;
191
+ const targets = inputs.map(toWatchTarget);
192
+ const refIds = targets.map(() => `_watch_${watchRefSeq++}`);
193
+ let disposed = false;
194
+ const instances = targets.map((target, i) => create ? resolveBloc(target, refIds[i]) : resolveBlocPassive(target));
195
+ const channelUnsubs = [];
196
+ const disposedUnsubs = [];
197
+ const cleanup = () => {
198
+ if (disposed) return;
199
+ disposed = true;
200
+ for (const unsub of channelUnsubs) unsub?.();
201
+ for (const unsub of disposedUnsubs) unsub?.();
202
+ channelUnsubs.length = 0;
203
+ disposedUnsubs.length = 0;
204
+ if (create) for (let i = 0; i < targets.length; i++) registry.release(targets[i].blocClass, targets[i].key, false, refIds[i]);
205
+ };
206
+ const runCallback = () => {
207
+ if (disposed) return;
208
+ if (instances.some((i) => i === void 0)) return;
209
+ if (callback(isSingle ? instances[0] : instances) === STOP) cleanup();
210
+ };
211
+ const subscribeAt = (index) => {
212
+ channelUnsubs[index] = instances[index]?.channel.subscribe(() => ALL_PATHS$1, runCallback);
213
+ };
214
+ const resubscribeAt = (index) => {
215
+ if (disposed) return;
216
+ instances[index] = create ? resolveBloc(targets[index], refIds[index]) : resolveBlocPassive(targets[index]);
217
+ subscribeAt(index);
218
+ subscribeDisposeAt(index);
219
+ runCallback();
220
+ };
221
+ const subscribeDisposeAt = (index) => {
222
+ disposedUnsubs[index] = instances[index]?.[ON_DISPOSE](() => {
223
+ channelUnsubs[index]?.();
224
+ channelUnsubs[index] = void 0;
225
+ queueMicrotask(() => resubscribeAt(index));
226
+ });
227
+ };
228
+ for (let i = 0; i < instances.length; i++) subscribeAt(i);
229
+ for (let i = 0; i < instances.length; i++) subscribeDisposeAt(i);
230
+ runCallback();
231
+ return cleanup;
232
+ }
233
+ const watch = Object.assign(watchImpl, { STOP });
234
+ //#endregion
235
+ //#region src/types/branded.ts
236
+ /**
237
+ * Create a branded InstanceId from a string
238
+ * @param id - The string ID to brand
239
+ * @returns Branded InstanceId
240
+ */
241
+ function instanceId(id) {
242
+ return id;
243
+ }
244
+ //#endregion
245
+ export { ALL_PATHS, APPLY_DEPS, Cubit, DEP_BRAND, INIT_CONFIG, ON_DISPOSE, REMOVE_DEPS_OWNER, StateContainer, StateContainerRegistry, WITH_TRACKED_STATE, acquire, blac, borrow, borrowSafe, clear, clearAll, configureBlac, ensure, forEach, getAll, getBlacConfig, getBlacName, getRefCount, getRefIds, getRegistry, getStats, globalRegistry, hasInstance, instance, instanceId, isExcludedFromDevTools, isKeepAliveClass, register, release, resetBlacConfig, resolveInstanceKey, setRegistry, shallowEqualState, watch };
66
246
 
67
247
  //# sourceMappingURL=index.js.map