@blac/core 2.0.19 → 2.0.21

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 (236) 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-CvBOhAT2.js → StateContainerRegistry-vWgsD-RP.js} +277 -392
  5. package/dist/StateContainerRegistry-vWgsD-RP.js.map +1 -0
  6. package/dist/config.d.cts +2 -2
  7. package/dist/config.d.ts +2 -2
  8. package/dist/constants.d.cts +11 -20
  9. package/dist/constants.d.ts +11 -20
  10. package/dist/core/Cubit.d.ts +14 -10
  11. package/dist/core/StateContainer.d.ts +61 -4
  12. package/dist/core/StateContainerRegistry.d.ts +119 -16
  13. package/dist/core/meta.d.ts +5 -11
  14. package/dist/core/symbols.d.ts +24 -1
  15. package/dist/decorators/blac.d.ts +28 -26
  16. package/dist/{ensure-CQimeD0I.cjs → ensure-ORVw-WRE.cjs} +234 -40
  17. package/dist/ensure-ORVw-WRE.cjs.map +1 -0
  18. package/dist/{ensure-DTTTd2h8.js → ensure-k-6q7O25.js} +203 -39
  19. package/dist/ensure-k-6q7O25.js.map +1 -0
  20. package/dist/index.cjs +213 -32
  21. package/dist/index.cjs.map +1 -1
  22. package/dist/index.d.cts +6 -8
  23. package/dist/index.d.ts +6 -8
  24. package/dist/index.js +192 -12
  25. package/dist/index.js.map +1 -1
  26. package/dist/plugin/BlacPlugin.d.ts +14 -0
  27. package/dist/plugin/PluginManager.d.ts +23 -7
  28. package/dist/plugins.cjs +400 -3
  29. package/dist/plugins.cjs.map +1 -0
  30. package/dist/plugins.d.cts +6 -2
  31. package/dist/plugins.d.ts +6 -2
  32. package/dist/plugins.js +398 -1
  33. package/dist/plugins.js.map +1 -0
  34. package/dist/registry/acquire.d.ts +2 -2
  35. package/dist/registry/config.d.ts +9 -0
  36. package/dist/registry/management.d.ts +3 -0
  37. package/dist/registry/queries.d.ts +15 -0
  38. package/dist/registry/release.d.ts +3 -3
  39. package/dist/testing.cjs +13 -15
  40. package/dist/testing.cjs.map +1 -1
  41. package/dist/testing.d.cts +1 -1
  42. package/dist/testing.d.ts +1 -1
  43. package/dist/testing.js +2 -4
  44. package/dist/testing.js.map +1 -1
  45. package/dist/types/branded.d.ts +3 -3
  46. package/dist/types/utilities.d.ts +45 -18
  47. package/dist/utils/idGenerator.d.ts +0 -36
  48. package/dist/utils/static-props.d.ts +25 -1
  49. package/dist/utils/structural-key.d.ts +0 -7
  50. package/dist/watch/index.d.ts +1 -1
  51. package/dist/watch/watch.d.ts +22 -3
  52. package/package.json +17 -55
  53. package/dist/StateContainerRegistry-4Ljd9EJx.js +0 -1018
  54. package/dist/StateContainerRegistry-4Ljd9EJx.js.map +0 -1
  55. package/dist/StateContainerRegistry-B1GYx9Xo.js +0 -975
  56. package/dist/StateContainerRegistry-B1GYx9Xo.js.map +0 -1
  57. package/dist/StateContainerRegistry-B_ViBLvJ.js +0 -975
  58. package/dist/StateContainerRegistry-B_ViBLvJ.js.map +0 -1
  59. package/dist/StateContainerRegistry-C0dCNlTF.js +0 -1005
  60. package/dist/StateContainerRegistry-C0dCNlTF.js.map +0 -1
  61. package/dist/StateContainerRegistry-CEWpc1bj.cjs +0 -1113
  62. package/dist/StateContainerRegistry-CEWpc1bj.cjs.map +0 -1
  63. package/dist/StateContainerRegistry-CSNm2Ws5.cjs.map +0 -1
  64. package/dist/StateContainerRegistry-CchRjnjX.cjs +0 -1094
  65. package/dist/StateContainerRegistry-CchRjnjX.cjs.map +0 -1
  66. package/dist/StateContainerRegistry-CvBOhAT2.js.map +0 -1
  67. package/dist/StateContainerRegistry-D9BIRjwv.cjs +0 -1088
  68. package/dist/StateContainerRegistry-D9BIRjwv.cjs.map +0 -1
  69. package/dist/StateContainerRegistry-DJQqLrli.cjs +0 -1046
  70. package/dist/StateContainerRegistry-DJQqLrli.cjs.map +0 -1
  71. package/dist/StateContainerRegistry-DVIBTxGZ.js +0 -999
  72. package/dist/StateContainerRegistry-DVIBTxGZ.js.map +0 -1
  73. package/dist/StateContainerRegistry-Dj77cok9.js +0 -1005
  74. package/dist/StateContainerRegistry-Dj77cok9.js.map +0 -1
  75. package/dist/StateContainerRegistry-FWKzPfS-.cjs +0 -1046
  76. package/dist/StateContainerRegistry-FWKzPfS-.cjs.map +0 -1
  77. package/dist/StateContainerRegistry-lIwo-0m3.cjs +0 -1094
  78. package/dist/StateContainerRegistry-lIwo-0m3.cjs.map +0 -1
  79. package/dist/acquire-B1Wuqla6.cjs +0 -46
  80. package/dist/acquire-B1Wuqla6.cjs.map +0 -1
  81. package/dist/acquire-BP-ZfUH2.js +0 -35
  82. package/dist/acquire-BP-ZfUH2.js.map +0 -1
  83. package/dist/acquire-BRIJVJaA.js +0 -35
  84. package/dist/acquire-BRIJVJaA.js.map +0 -1
  85. package/dist/acquire-BZIs6tpN.cjs +0 -46
  86. package/dist/acquire-BZIs6tpN.cjs.map +0 -1
  87. package/dist/acquire-C3nOb3XR.cjs +0 -46
  88. package/dist/acquire-C3nOb3XR.cjs.map +0 -1
  89. package/dist/acquire-C4WAS13G.cjs +0 -46
  90. package/dist/acquire-C4WAS13G.cjs.map +0 -1
  91. package/dist/acquire-C7beGI55.cjs +0 -46
  92. package/dist/acquire-C7beGI55.cjs.map +0 -1
  93. package/dist/acquire-CbMz7gWs.cjs +0 -46
  94. package/dist/acquire-CbMz7gWs.cjs.map +0 -1
  95. package/dist/acquire-CwB083au.js +0 -35
  96. package/dist/acquire-CwB083au.js.map +0 -1
  97. package/dist/acquire-DHEOEVcj.cjs +0 -46
  98. package/dist/acquire-DHEOEVcj.cjs.map +0 -1
  99. package/dist/acquire-DXEQDZGr.js +0 -35
  100. package/dist/acquire-DXEQDZGr.js.map +0 -1
  101. package/dist/acquire-Dg-uXwjF.js +0 -35
  102. package/dist/acquire-Dg-uXwjF.js.map +0 -1
  103. package/dist/acquire-Don7499S.js +0 -35
  104. package/dist/acquire-Don7499S.js.map +0 -1
  105. package/dist/acquire-G8aB3GAx.js +0 -35
  106. package/dist/acquire-G8aB3GAx.js.map +0 -1
  107. package/dist/branded-BybA0_xw.cjs +0 -18
  108. package/dist/branded-BybA0_xw.cjs.map +0 -1
  109. package/dist/branded-DkbUzncc.js +0 -13
  110. package/dist/branded-DkbUzncc.js.map +0 -1
  111. package/dist/config-8pyOC5gv.js +0 -16
  112. package/dist/config-8pyOC5gv.js.map +0 -1
  113. package/dist/config-B1l8ZGlU.cjs +0 -32
  114. package/dist/config-B1l8ZGlU.cjs.map +0 -1
  115. package/dist/config-C7Ktkjh2.cjs +0 -32
  116. package/dist/config-C7Ktkjh2.cjs.map +0 -1
  117. package/dist/config-COT4Xkbc.js +0 -16
  118. package/dist/config-COT4Xkbc.js.map +0 -1
  119. package/dist/config-CzcoAvBo.js +0 -16
  120. package/dist/config-CzcoAvBo.js.map +0 -1
  121. package/dist/config-D6BoWWPv.js +0 -16
  122. package/dist/config-D6BoWWPv.js.map +0 -1
  123. package/dist/config-DVM_ESQt.js +0 -16
  124. package/dist/config-DVM_ESQt.js.map +0 -1
  125. package/dist/config-DVMnlHLv.cjs +0 -32
  126. package/dist/config-DVMnlHLv.cjs.map +0 -1
  127. package/dist/config-Dk1FxfXj.js +0 -16
  128. package/dist/config-Dk1FxfXj.js.map +0 -1
  129. package/dist/config-b2z51Y_C.cjs +0 -32
  130. package/dist/config-b2z51Y_C.cjs.map +0 -1
  131. package/dist/config-buwpT7l3.js +0 -16
  132. package/dist/config-buwpT7l3.js.map +0 -1
  133. package/dist/config-d9_U58ef.cjs +0 -32
  134. package/dist/config-d9_U58ef.cjs.map +0 -1
  135. package/dist/config-hWTayX76.cjs +0 -32
  136. package/dist/config-hWTayX76.cjs.map +0 -1
  137. package/dist/config-sCPKPYxZ.cjs +0 -32
  138. package/dist/config-sCPKPYxZ.cjs.map +0 -1
  139. package/dist/debug.cjs +0 -14
  140. package/dist/debug.d.cts +0 -34
  141. package/dist/debug.d.ts +0 -34
  142. package/dist/debug.js +0 -4
  143. package/dist/ensure-B1dEDsZV.cjs +0 -559
  144. package/dist/ensure-B1dEDsZV.cjs.map +0 -1
  145. package/dist/ensure-B9oOqpOB.cjs +0 -558
  146. package/dist/ensure-B9oOqpOB.cjs.map +0 -1
  147. package/dist/ensure-BfYnvAsI.js +0 -709
  148. package/dist/ensure-BfYnvAsI.js.map +0 -1
  149. package/dist/ensure-Bm91o37h.js +0 -536
  150. package/dist/ensure-Bm91o37h.js.map +0 -1
  151. package/dist/ensure-C1a8IFWy.js +0 -535
  152. package/dist/ensure-C1a8IFWy.js.map +0 -1
  153. package/dist/ensure-CLQEx0Nn.cjs +0 -528
  154. package/dist/ensure-CLQEx0Nn.cjs.map +0 -1
  155. package/dist/ensure-CPMiGvov.js +0 -493
  156. package/dist/ensure-CPMiGvov.js.map +0 -1
  157. package/dist/ensure-CQimeD0I.cjs.map +0 -1
  158. package/dist/ensure-DEXSmA-N.js +0 -526
  159. package/dist/ensure-DEXSmA-N.js.map +0 -1
  160. package/dist/ensure-DTTTd2h8.js.map +0 -1
  161. package/dist/ensure-Dx86f80B.cjs +0 -567
  162. package/dist/ensure-Dx86f80B.cjs.map +0 -1
  163. package/dist/ensure-DzqGej43.js +0 -526
  164. package/dist/ensure-DzqGej43.js.map +0 -1
  165. package/dist/ensure-VuiNPccZ.cjs +0 -559
  166. package/dist/ensure-VuiNPccZ.cjs.map +0 -1
  167. package/dist/ensure-_Oh8XPm4.cjs +0 -732
  168. package/dist/ensure-_Oh8XPm4.cjs.map +0 -1
  169. package/dist/ensure-fsQMjaQL.cjs +0 -567
  170. package/dist/ensure-fsQMjaQL.cjs.map +0 -1
  171. package/dist/ensure-vxAGa2v3.js +0 -536
  172. package/dist/ensure-vxAGa2v3.js.map +0 -1
  173. package/dist/management-14vsHr4t.cjs +0 -85
  174. package/dist/management-14vsHr4t.cjs.map +0 -1
  175. package/dist/management-444tdCBG.js +0 -38
  176. package/dist/management-444tdCBG.js.map +0 -1
  177. package/dist/management-7jLjVHJd.js +0 -38
  178. package/dist/management-7jLjVHJd.js.map +0 -1
  179. package/dist/management-AFuqQEwz.js +0 -38
  180. package/dist/management-AFuqQEwz.js.map +0 -1
  181. package/dist/management-BodVLAfJ.cjs +0 -85
  182. package/dist/management-BodVLAfJ.cjs.map +0 -1
  183. package/dist/management-BqGBdL01.js +0 -38
  184. package/dist/management-BqGBdL01.js.map +0 -1
  185. package/dist/management-BvUAjril.js +0 -38
  186. package/dist/management-BvUAjril.js.map +0 -1
  187. package/dist/management-C2wv4vGS.cjs +0 -85
  188. package/dist/management-C2wv4vGS.cjs.map +0 -1
  189. package/dist/management-D2pjr38g.js +0 -38
  190. package/dist/management-D2pjr38g.js.map +0 -1
  191. package/dist/management-D5WsZoTV.js +0 -38
  192. package/dist/management-D5WsZoTV.js.map +0 -1
  193. package/dist/management-DAV9sN-k.cjs +0 -85
  194. package/dist/management-DAV9sN-k.cjs.map +0 -1
  195. package/dist/management-Df7Y2sF1.cjs +0 -85
  196. package/dist/management-Df7Y2sF1.cjs.map +0 -1
  197. package/dist/management-DwO0nBzL.cjs +0 -85
  198. package/dist/management-DwO0nBzL.cjs.map +0 -1
  199. package/dist/management-GcnNJjnm.cjs +0 -85
  200. package/dist/management-GcnNJjnm.cjs.map +0 -1
  201. package/dist/types.cjs +0 -3
  202. package/dist/types.d.cts +0 -8
  203. package/dist/types.d.ts +0 -8
  204. package/dist/types.js +0 -2
  205. package/dist/watch-B91opmva.cjs +0 -70
  206. package/dist/watch-B91opmva.cjs.map +0 -1
  207. package/dist/watch-BHfCtbn1.cjs +0 -119
  208. package/dist/watch-BHfCtbn1.cjs.map +0 -1
  209. package/dist/watch-BmC-Tyqg.js +0 -59
  210. package/dist/watch-BmC-Tyqg.js.map +0 -1
  211. package/dist/watch-CKWt788i.cjs +0 -70
  212. package/dist/watch-CKWt788i.cjs.map +0 -1
  213. package/dist/watch-CfrSSrRY.js +0 -59
  214. package/dist/watch-CfrSSrRY.js.map +0 -1
  215. package/dist/watch-Cnh3PtQA.cjs +0 -70
  216. package/dist/watch-Cnh3PtQA.cjs.map +0 -1
  217. package/dist/watch-D01MdwKy.js +0 -108
  218. package/dist/watch-D01MdwKy.js.map +0 -1
  219. package/dist/watch-D8hwbFU1.js +0 -59
  220. package/dist/watch-D8hwbFU1.js.map +0 -1
  221. package/dist/watch-DPVUwPUY.js +0 -59
  222. package/dist/watch-DPVUwPUY.js.map +0 -1
  223. package/dist/watch-DVmvZBMD.cjs +0 -70
  224. package/dist/watch-DVmvZBMD.cjs.map +0 -1
  225. package/dist/watch-DkDGmGAx.cjs +0 -119
  226. package/dist/watch-DkDGmGAx.cjs.map +0 -1
  227. package/dist/watch-DztcJuUy.cjs +0 -119
  228. package/dist/watch-DztcJuUy.cjs.map +0 -1
  229. package/dist/watch-IrR8G28N.js +0 -108
  230. package/dist/watch-IrR8G28N.js.map +0 -1
  231. package/dist/watch-entry.cjs +0 -4
  232. package/dist/watch-entry.d.cts +0 -24
  233. package/dist/watch-entry.d.ts +0 -24
  234. package/dist/watch-entry.js +0 -2
  235. package/dist/watch-hx0r92Zc.js +0 -108
  236. package/dist/watch-hx0r92Zc.js.map +0 -1
@@ -1,27 +1,35 @@
1
1
  import type { HydrationStatus, StateContainer } from './StateContainer';
2
- import { type PluginManager } from '../plugin/PluginManager';
3
2
  import { InstanceReadonlyState, StateContainerConstructor } from '../types/utilities';
4
3
  /**
5
4
  * Entry in the instance registry, tracking the instance and its named references
6
- * @template T - Instance type
5
+ * @typeParam T - Instance type
6
+ * @internal
7
7
  */
8
8
  export interface InstanceEntry<T = any> {
9
9
  /** The state container instance */
10
10
  instance: T;
11
+ /** The key this entry is stored under in its constructor's instances Map. */
12
+ key: string;
11
13
  /** Map of active reference IDs to their acquire count (supports paired acquire/release) */
12
14
  refs: Map<string, number>;
13
15
  /** The args used when this entry was first created; used for dev-warn on arg mismatch. */
14
16
  args?: unknown;
17
+ /** Memoized structuralKey(args) for the dev arg-mismatch warning. */
18
+ argsKey?: string;
19
+ /** `depend()`-owners currently holding this instance (see `acquire`'s `dependent` option). */
20
+ dependents?: Set<StateContainer<any, any, any>>;
15
21
  }
16
22
  /**
17
23
  * Lifecycle events emitted by the registry
24
+ * @public
18
25
  */
19
- export type LifecycleEvent = 'created' | 'stateChanged' | 'disposed' | 'refAcquired' | 'refReleased' | 'depsChanged' | 'hydrationChanged';
26
+ export type LifecycleEvent = 'created' | 'stateChanged' | 'disposed' | 'refAcquired' | 'refReleased' | 'depsChanged' | 'hydrationChanged' | 'activated' | 'deactivated';
20
27
  /**
21
28
  * Listener function type for each lifecycle event
22
- * @template E - The lifecycle event type
29
+ * @typeParam E - The lifecycle event type
30
+ * @public
23
31
  */
24
- export type LifecycleListener<E extends LifecycleEvent> = E extends 'created' ? (container: StateContainer<any, any, any>) => void : E extends 'stateChanged' ? (container: StateContainer<any, any, any>, previousState: any, currentState: any) => void : E extends 'disposed' ? (container: StateContainer<any, any, any>) => void : E extends 'refAcquired' ? (container: StateContainer<any, any, any>, refId: string) => void : E extends 'refReleased' ? (container: StateContainer<any, any, any>, refId: string) => void : E extends 'depsChanged' ? (container: StateContainer<any, any, any>, previousDeps: Readonly<Record<string, unknown>>, currentDeps: Readonly<Record<string, unknown>>) => void : E extends 'hydrationChanged' ? (container: StateContainer<any, any, any>, status: HydrationStatus, previousStatus: HydrationStatus) => void : never;
32
+ export type LifecycleListener<E extends LifecycleEvent> = E extends 'created' ? (container: StateContainer<any, any, any>) => void : E extends 'stateChanged' ? (container: StateContainer<any, any, any>, previousState: Readonly<Record<string, unknown>>, currentState: Readonly<Record<string, unknown>>) => void : E extends 'disposed' ? (container: StateContainer<any, any, any>) => void : E extends 'refAcquired' ? (container: StateContainer<any, any, any>, refId: string) => void : E extends 'refReleased' ? (container: StateContainer<any, any, any>, refId: string) => void : E extends 'depsChanged' ? (container: StateContainer<any, any, any>, previousDeps: Readonly<Record<string, unknown>>, currentDeps: Readonly<Record<string, unknown>>) => void : E extends 'hydrationChanged' ? (container: StateContainer<any, any, any>, status: HydrationStatus, previousStatus: HydrationStatus) => void : E extends 'activated' ? (container: StateContainer<any, any, any>, signal: AbortSignal) => void : E extends 'deactivated' ? (container: StateContainer<any, any, any>) => void : never;
25
33
  /**
26
34
  * Central registry for managing StateContainer instances.
27
35
  * Handles instance lifecycle, named ref tracking, and lifecycle event emission.
@@ -35,16 +43,80 @@ export type LifecycleListener<E extends LifecycleEvent> = E extends 'created' ?
35
43
  * console.log('State changed:', prev, '->', next);
36
44
  * });
37
45
  * ```
46
+ *
47
+ * `stateChanged` fires once per emit (microtask-deferred but uncoalesced), so
48
+ * listeners see every intermediate transition. Plugins' `onStateChange` fires
49
+ * once per channel flush with coalesced `prev`/`next` and a `PathSet`. Pick
50
+ * the transition log for devtools/time-travel, the plugin hook for
51
+ * change-driven work.
38
52
  */
39
53
  export declare class StateContainerRegistry {
40
54
  private readonly instancesByConstructor;
41
55
  private readonly types;
42
- private readonly registeredTypeNames;
56
+ /**
57
+ * `depend()`-owner to the (Type, key) entries it has resolved. Keyed per
58
+ * resolved key because one handle resolves a different key per `args`.
59
+ * Weak so a bare `new`'d owner that is never disposed cannot pin the map.
60
+ */
61
+ private readonly _dependentEdges;
62
+ /** Reverse lookup from instance to its entry, so `_pruneEntry` is O(1). */
63
+ private readonly _entryByInstance;
64
+ /** Reverse lookup from `$blac.id` to its entry, for `PluginContext.getRefIds`. */
65
+ private readonly _entryById;
43
66
  private readonly listeners;
44
67
  private _stateChangedListenerCount;
45
68
  get hasStateChangedListeners(): boolean;
46
69
  private _pendingStateChanges;
47
70
  private _autoRefIdCounter;
71
+ constructor();
72
+ /**
73
+ * Registry-internal reaction to any instance's `disposed` lifecycle event.
74
+ * If the disposing container is itself tracked in this registry (i.e. it
75
+ * was `acquire()`/`ensure()`'d, not a bare `new`), prune its Map entry and
76
+ * release its dependent edges on whatever it `depend()`'d on.
77
+ */
78
+ private _handleDisposed;
79
+ /**
80
+ * An entry may be disposed only when nothing owns it: no public refs, no
81
+ * `depend()` dependents, and not keepAlive. Every dispose decision goes
82
+ * through here so `release()` and `_releaseDependent` cannot disagree.
83
+ */
84
+ private _isUnowned;
85
+ /**
86
+ * Pure ownership: refs plus `depend()` dependents, with no keepAlive term.
87
+ * `_isUnowned` is "may be disposed"; this is "nothing is using it", which is
88
+ * what the activation lifecycle keys off — a keepAlive instance still
89
+ * deactivates when its last owner goes.
90
+ */
91
+ private _hasNoOwners;
92
+ /**
93
+ * Single funnel for the 0↔1 ownership transition. `SET_ACTIVE` is idempotent,
94
+ * so every acquire/release path can call this unconditionally rather than
95
+ * each computing the edge itself. Emits `activated`/`deactivated` for
96
+ * plugins to observe the same transition `onActivate`/`onDeactivate` expose
97
+ * to bloc authors — after `SET_ACTIVE` has already run the instance's own
98
+ * hook, so plugins always see a container that has finished reacting.
99
+ */
100
+ private _syncActivation;
101
+ /**
102
+ * Record that `dependent` resolved `Type` at `key`, so the edge can be
103
+ * released on the owner's disposal. Keyed per resolved key, not per type:
104
+ * one `depend()` handle resolves a distinct key for every `args` it is
105
+ * called with, and all of them must be swept.
106
+ */
107
+ private _recordDependentEdge;
108
+ /**
109
+ * Remove the Map entry for `container`, if this registry is tracking it.
110
+ * @returns true if an entry was found and removed
111
+ */
112
+ private _pruneEntry;
113
+ /**
114
+ * Drop `dependent`'s edge on the `Type`/`key` entry (a `depend()`-resolved
115
+ * instance). When that leaves the entry with no dependents AND no public
116
+ * refs AND it isn't keepAlive, dispose it — this recurses into the same
117
+ * `disposed` listener, so dep-of-dep chains unwind naturally.
118
+ */
119
+ private _releaseDependent;
48
120
  /**
49
121
  * Register a type for lifecycle event tracking
50
122
  * @param constructor - The StateContainer class constructor
@@ -60,7 +132,7 @@ export declare class StateContainerRegistry {
60
132
  /**
61
133
  * Get the instances Map for a specific class (public API for stats/debugging)
62
134
  */
63
- getInstancesMap<T extends StateContainerConstructor>(Type: T): Map<string, InstanceEntry>;
135
+ getInstancesMap<T extends StateContainerConstructor>(Type: T): ReadonlyMap<string, InstanceEntry>;
64
136
  /**
65
137
  * Directly insert an instance entry into the registry without going through
66
138
  * acquire/release. Creates the internal WeakMap bucket for the constructor if
@@ -79,7 +151,7 @@ export declare class StateContainerRegistry {
79
151
  * an args-derived key is never dropped (instance leaks).
80
152
  *
81
153
  * Resolution order (explicit beats derived):
82
- * explicit key > `static key(args)` > structural hash of args > default sentinel.
154
+ * explicit key \> `static key(args)` \> structural hash of args \> default sentinel.
83
155
  *
84
156
  * @param Type - The StateContainer class constructor
85
157
  * @param instanceKey - Explicit key, or undefined to derive from args
@@ -108,10 +180,13 @@ export declare class StateContainerRegistry {
108
180
  * wrapper; `useBloc` and `watch` address a pre-resolved key here.
109
181
  * @param Type - The StateContainer class constructor
110
182
  * @param instanceKey - Pre-resolved instance key (defaults to 'default')
111
- * @param options - Acquisition options
112
- * @param options.canCreate - Whether to create new instance if not found (default: true)
113
- * @param options.countRef - Whether to add a reference (default: true)
114
- * @param options.refId - Named reference ID for debugging; auto-generated if omitted
183
+ * @param options - Acquisition options: `canCreate` (create when absent,
184
+ * default true), `countRef` (add a reference, default true), `refId`
185
+ * (named reference for debugging, auto-generated when omitted),
186
+ * `dependent` — the `depend()`-owner resolving this instance, recorded so
187
+ * its dependent edge is released on the owner's disposal — and
188
+ * `sweepIfUnowned`, for callers that create speculatively and claim
189
+ * ownership later (see {@link _scheduleSweep}).
115
190
  * @returns The state container instance
116
191
  */
117
192
  acquire<T extends StateContainerConstructor = StateContainerConstructor>(Type: T, instanceKey?: string, options?: {
@@ -119,7 +194,20 @@ export declare class StateContainerRegistry {
119
194
  countRef?: boolean;
120
195
  refId?: string;
121
196
  args?: unknown;
197
+ dependent?: StateContainer<any, any, any>;
198
+ sweepIfUnowned?: boolean;
122
199
  }): InstanceType<T>;
200
+ /**
201
+ * Speculative creates (`useBloc`'s render-time create) leak forever when the
202
+ * render is discarded or never commits — SSR has no commit at all, so nothing
203
+ * ever claims ownership. Sweep at the end of the microtask unless the entry
204
+ * gained an owner or is keepAlive.
205
+ *
206
+ * Opt-in, not automatic: a bare `ensure()` hands the instance to a caller
207
+ * that legitimately holds it without a ref, and sweeping those would make
208
+ * `ensure` unusable across an `await`.
209
+ */
210
+ private _scheduleSweep;
123
211
  /**
124
212
  * Borrow an existing instance without adding a ref (borrowing semantics).
125
213
  * Tracks cross-bloc dependency for reactive updates.
@@ -211,6 +299,13 @@ export declare class StateContainerRegistry {
211
299
  * @returns Array of ref ID strings (empty if instance doesn't exist)
212
300
  */
213
301
  getRefIds<T extends StateContainerConstructor>(Type: T, instanceKey?: string): string[];
302
+ /**
303
+ * Get all active reference IDs for an instance by its `$blac.id`, without
304
+ * needing the owning Type. Used by `PluginContext.getRefIds`.
305
+ * @param instanceId - The instance's `$blac.id`
306
+ * @returns Array of ref ID strings (empty if instance doesn't exist)
307
+ */
308
+ getRefIdsById(instanceId: string): string[];
214
309
  /**
215
310
  * Check if an instance exists.
216
311
  *
@@ -259,19 +354,27 @@ export declare class StateContainerRegistry {
259
354
  emit(event: 'refReleased', container: StateContainer<any, any, any>, refId: string): void;
260
355
  emit(event: 'depsChanged', container: StateContainer<any, any, any>, previousDeps: Readonly<Record<string, unknown>>, currentDeps: Readonly<Record<string, unknown>>): void;
261
356
  emit(event: 'hydrationChanged', container: StateContainer<any, any, any>, status: HydrationStatus, previousStatus: HydrationStatus): void;
357
+ emit(event: 'activated', container: StateContainer<any, any, any>, signal: AbortSignal): void;
358
+ emit(event: 'deactivated', container: StateContainer<any, any, any>): void;
262
359
  /**
263
360
  * Schedule a deferred stateChanged notification via microtask.
264
361
  * Skips entirely when no stateChanged listeners are registered.
265
362
  * @internal - Called by StateContainer.applyState
266
363
  */
267
364
  notifyStateChanged(container: StateContainer<any, any, any>, previousState: any, newState: any): void;
365
+ /**
366
+ * Deliver one event per emit, in order — deliberately NOT coalesced.
367
+ *
368
+ * This is a transition log: devtools, time-travel debugging and perf
369
+ * monitoring need every intermediate `prev`/`next`, which coalescing would
370
+ * destroy. The plugin `onStateChange` bridge is the coalesced, `PathSet`-
371
+ * carrying lane (see `PluginManager.setupLifecycleHooks`); the two differ on
372
+ * purpose, so a listener picks the lane that matches what it needs.
373
+ */
268
374
  private flushStateChanged;
269
375
  }
270
376
  /**
271
377
  * Global default registry instance
378
+ * @public
272
379
  */
273
380
  export declare const globalRegistry: StateContainerRegistry;
274
- /**
275
- * Get the global plugin manager
276
- */
277
- export declare function getPluginManager(): PluginManager;
@@ -1,17 +1,11 @@
1
1
  /**
2
2
  * `$blac` meta namespace for `StateContainer`.
3
3
  *
4
- * ──────────────────────────────────────────────────────────────────────────
5
- * CONSTRAINT — NO ES `#private` FIELDS, ANYWHERE IN THIS FILE.
6
- *
7
- * `@blac/react`'s `buildTrackedProxy` invokes prototype getters with a
8
- * `Proxy(instance)` as the `this`-receiver. Accessing an ES `#private` field
9
- * through a proxy receiver throws (`#x` brand checks fail on the proxy). The
10
- * whole point of this meta object is to be proxy-safe: every getter/method
11
- * here closes over the *real* container instance captured at `createMeta`
12
- * time, NEVER over a `this`-receiver. Do not "modernize" the `_`-prefixed
13
- * TS-private reads below into `#private` access.
14
- * ──────────────────────────────────────────────────────────────────────────
4
+ * Getters/methods here close over the *real* container instance captured at
5
+ * `createMeta` time rather than reading a `this`-receiver. `buildTrackedProxy`
6
+ * no longer uses a `this`-Proxy (getters run with `this` = the real instance),
7
+ * so ES `#private` is safe here now; the closure style is kept because it also
8
+ * keeps this own, frozen property independent of the proxy entirely.
15
9
  */
16
10
  import type { HydrationStatus } from './StateContainer';
17
11
  import type { StateContainerConstructor } from '../types/utilities';
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * @internal Apply one owner's (consumer's) deps slice to an instance.
3
- * Called by framework adapters (e.g. @blac/react useBloc) — not public API.
3
+ * Called by framework adapters (e.g. `@blac/react` useBloc) — not public API.
4
4
  */
5
5
  export declare const APPLY_DEPS: unique symbol;
6
6
  /**
@@ -8,6 +8,12 @@ export declare const APPLY_DEPS: unique symbol;
8
8
  * Called by framework adapters — not public API.
9
9
  */
10
10
  export declare const REMOVE_DEPS_OWNER: unique symbol;
11
+ /**
12
+ * @internal Subscribe to this specific instance's own disposal, bypassing
13
+ * the global registry `'disposed'` event. Called by `watch()` — not public
14
+ * API.
15
+ */
16
+ export declare const ON_DISPOSE: unique symbol;
11
17
  /**
12
18
  * @internal Symbol-keyed configuration entry point on `StateContainer`.
13
19
  * Writes the instance's identity fields (`_name`/`_debug`/`_instanceId`),
@@ -18,3 +24,20 @@ export declare const REMOVE_DEPS_OWNER: unique symbol;
18
24
  * helpers are the sole callers, mirroring the `APPLY_DEPS` precedent.
19
25
  */
20
26
  export declare const INIT_CONFIG: unique symbol;
27
+ /**
28
+ * @internal Run `fn` with `state` temporarily reporting a render's tracking
29
+ * proxy, so getters record the paths they read. Called by `@blac/react`'s
30
+ * `buildTrackedProxy` — not public API.
31
+ *
32
+ * Replaces the old `this`-Proxy receiver: getters now run with `this` bound to
33
+ * the real instance, so ES `#private` works in user blocs.
34
+ */
35
+ export declare const WITH_TRACKED_STATE: unique symbol;
36
+ /**
37
+ * @internal Drive the activation lifecycle from the registry's 0↔1 ownership
38
+ * transition. Owns the per-instance AbortController so `onActivate`'s signal
39
+ * aborts on the matching deactivation and on dispose.
40
+ *
41
+ * Framework-only — `StateContainerRegistry` is the sole caller.
42
+ */
43
+ export declare const SET_ACTIVE: unique symbol;
@@ -1,33 +1,32 @@
1
1
  import type { EqualityFn } from '../config';
2
2
  /**
3
- * Configuration options for the @blac decorator.
4
- * Only one option can be specified at a time (union type).
3
+ * Configuration options for the `@blac` decorator. Any combination may be
4
+ * given at once.
5
5
  */
6
- export type BlacOptions =
7
- /** Mark bloc to never be auto-disposed when ref count reaches 0 */
8
- {
9
- keepAlive: true;
10
- }
11
- /** Exclude bloc from DevTools tracking (prevents infinite loops) */
12
- | {
13
- excludeFromDevTools: true;
14
- }
15
- /**
16
- * Override the global equality check for this bloc.
17
- * Return `true` to skip the emit (states considered equal).
18
- */
19
- | {
20
- equality: EqualityFn;
6
+ export interface BlacOptions {
7
+ /** Mark bloc to never be auto-disposed when ref count reaches 0 */
8
+ keepAlive?: true;
9
+ /** Exclude bloc from DevTools tracking (prevents infinite loops) */
10
+ excludeFromDevTools?: true;
11
+ /**
12
+ * Override the global equality check for this bloc.
13
+ * Return `true` to skip the emit (states considered equal).
14
+ */
15
+ equality?: EqualityFn;
16
+ /**
17
+ * Override the default structural-hash identity key.
18
+ * The function receives `args` and returns the instance key string.
19
+ * Distinct return values → distinct instances; identical values → shared instance.
20
+ * Non-identity fields can be excluded so they don't fork new instances.
21
+ */
22
+ key?: (args: any) => string;
23
+ /**
24
+ * Explicit, minification-safe identity for this bloc class. Falls back to
25
+ * `constructor.name` when unset, which collides across classes once a
26
+ * minifier shortens class names.
27
+ */
28
+ name?: string;
21
29
  }
22
- /**
23
- * Override the default structural-hash identity key.
24
- * The function receives `args` and returns the instance key string.
25
- * Distinct return values → distinct instances; identical values → shared instance.
26
- * Non-identity fields can be excluded so they don't fork new instances.
27
- */
28
- | {
29
- key: (args: any) => string;
30
- };
31
30
  /**
32
31
  * Decorator to configure StateContainer classes.
33
32
  *
@@ -38,6 +37,9 @@ export type BlacOptions =
38
37
  *
39
38
  * @blac({ excludeFromDevTools: true })
40
39
  * class InternalBloc extends Cubit<InternalState> {}
40
+ *
41
+ * @blac({ keepAlive: true, key: (args) => args.userId })
42
+ * class UserBloc extends Cubit<UserState> {}
41
43
  * ```
42
44
  *
43
45
  * @example Function syntax (no decorator support needed)