@blac/core 2.0.19 → 2.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (129) hide show
  1. package/dist/StateContainerRegistry-8zNFMAf7.js +1067 -0
  2. package/dist/StateContainerRegistry-8zNFMAf7.js.map +1 -0
  3. package/dist/StateContainerRegistry-Bx2ly-ba.cjs +1162 -0
  4. package/dist/StateContainerRegistry-Bx2ly-ba.cjs.map +1 -0
  5. package/dist/StateContainerRegistry-C75QpeaO.cjs +1260 -0
  6. package/dist/StateContainerRegistry-C75QpeaO.cjs.map +1 -0
  7. package/dist/StateContainerRegistry-CS18y4au.cjs +1163 -0
  8. package/dist/StateContainerRegistry-CS18y4au.cjs.map +1 -0
  9. package/dist/StateContainerRegistry-D8nu7Z0T.js +1068 -0
  10. package/dist/StateContainerRegistry-D8nu7Z0T.js.map +1 -0
  11. package/dist/StateContainerRegistry-DL5Ai7wh.js +1153 -0
  12. package/dist/StateContainerRegistry-DL5Ai7wh.js.map +1 -0
  13. package/dist/StateContainerRegistry-DWOzx7Gd.js +1154 -0
  14. package/dist/StateContainerRegistry-DWOzx7Gd.js.map +1 -0
  15. package/dist/StateContainerRegistry-G81GcCRm.cjs +1261 -0
  16. package/dist/StateContainerRegistry-G81GcCRm.cjs.map +1 -0
  17. package/dist/acquire-B1LYXSGj.js +35 -0
  18. package/dist/acquire-B1LYXSGj.js.map +1 -0
  19. package/dist/acquire-BJ3xUEmh.cjs +46 -0
  20. package/dist/acquire-BJ3xUEmh.cjs.map +1 -0
  21. package/dist/acquire-B_p1fNEh.cjs +46 -0
  22. package/dist/acquire-B_p1fNEh.cjs.map +1 -0
  23. package/dist/acquire-BdsVZBSe.js +35 -0
  24. package/dist/acquire-BdsVZBSe.js.map +1 -0
  25. package/dist/acquire-CE0uq0Dx.cjs +46 -0
  26. package/dist/acquire-CE0uq0Dx.cjs.map +1 -0
  27. package/dist/acquire-CU0u8BMn.js +35 -0
  28. package/dist/acquire-CU0u8BMn.js.map +1 -0
  29. package/dist/acquire-CkgLJ8WL.cjs +46 -0
  30. package/dist/acquire-CkgLJ8WL.cjs.map +1 -0
  31. package/dist/acquire-DTvfYJ0y.js +35 -0
  32. package/dist/acquire-DTvfYJ0y.js.map +1 -0
  33. package/dist/config-C1T6Jw7n.cjs +32 -0
  34. package/dist/config-C1T6Jw7n.cjs.map +1 -0
  35. package/dist/config-D2A8ZYRM.js +16 -0
  36. package/dist/config-D2A8ZYRM.js.map +1 -0
  37. package/dist/config-D34BkraU.cjs +32 -0
  38. package/dist/config-D34BkraU.cjs.map +1 -0
  39. package/dist/config-DOO82lbZ.js +16 -0
  40. package/dist/config-DOO82lbZ.js.map +1 -0
  41. package/dist/config-DWUq7zEQ.cjs +32 -0
  42. package/dist/config-DWUq7zEQ.cjs.map +1 -0
  43. package/dist/config-DXI3kzmA.js +16 -0
  44. package/dist/config-DXI3kzmA.js.map +1 -0
  45. package/dist/config-ZVy_yFZ3.js +16 -0
  46. package/dist/config-ZVy_yFZ3.js.map +1 -0
  47. package/dist/config-cwaTn5oy.cjs +32 -0
  48. package/dist/config-cwaTn5oy.cjs.map +1 -0
  49. package/dist/config.d.cts +7 -3
  50. package/dist/config.d.ts +7 -3
  51. package/dist/constants.d.cts +2 -13
  52. package/dist/constants.d.ts +2 -13
  53. package/dist/core/StateContainer.d.ts +28 -1
  54. package/dist/core/StateContainerRegistry.d.ts +72 -2
  55. package/dist/core/symbols.d.ts +6 -0
  56. package/dist/debug.cjs +3 -3
  57. package/dist/debug.js +3 -3
  58. package/dist/decorators/blac.d.ts +2 -0
  59. package/dist/ensure-11-asM1e.js +677 -0
  60. package/dist/ensure-11-asM1e.js.map +1 -0
  61. package/dist/ensure-B2DYCbbI.cjs +578 -0
  62. package/dist/ensure-B2DYCbbI.cjs.map +1 -0
  63. package/dist/ensure-B59ri8oo.js +555 -0
  64. package/dist/ensure-B59ri8oo.js.map +1 -0
  65. package/dist/ensure-BEeY5Ab7.js +673 -0
  66. package/dist/ensure-BEeY5Ab7.js.map +1 -0
  67. package/dist/ensure-BKdq5xsY.cjs +578 -0
  68. package/dist/ensure-BKdq5xsY.cjs.map +1 -0
  69. package/dist/ensure-BSJHkUNX.js +555 -0
  70. package/dist/ensure-BSJHkUNX.js.map +1 -0
  71. package/dist/ensure-D3WWWwMo.cjs +714 -0
  72. package/dist/ensure-D3WWWwMo.cjs.map +1 -0
  73. package/dist/ensure-r1C_7K6_.cjs +718 -0
  74. package/dist/ensure-r1C_7K6_.cjs.map +1 -0
  75. package/dist/events.d.cts +42 -0
  76. package/dist/events.d.ts +42 -0
  77. package/dist/index.cjs +61 -6
  78. package/dist/index.cjs.map +1 -1
  79. package/dist/index.d.cts +7 -6
  80. package/dist/index.d.ts +7 -6
  81. package/dist/index.js +56 -8
  82. package/dist/index.js.map +1 -1
  83. package/dist/management-8x1OVMi6.js +38 -0
  84. package/dist/management-8x1OVMi6.js.map +1 -0
  85. package/dist/management-BZgsi29F.js +38 -0
  86. package/dist/management-BZgsi29F.js.map +1 -0
  87. package/dist/management-C-WGcwPD.js +38 -0
  88. package/dist/management-C-WGcwPD.js.map +1 -0
  89. package/dist/management-Dg2SxUb6.cjs +85 -0
  90. package/dist/management-Dg2SxUb6.cjs.map +1 -0
  91. package/dist/management-P_Vi_cvw.js +38 -0
  92. package/dist/management-P_Vi_cvw.js.map +1 -0
  93. package/dist/management-QWLpbXlW.cjs +85 -0
  94. package/dist/management-QWLpbXlW.cjs.map +1 -0
  95. package/dist/management-hkY13log.cjs +85 -0
  96. package/dist/management-hkY13log.cjs.map +1 -0
  97. package/dist/management-iE4x6IQY.cjs +85 -0
  98. package/dist/management-iE4x6IQY.cjs.map +1 -0
  99. package/dist/plugin/PluginManager.d.ts +11 -0
  100. package/dist/plugins.cjs +1 -1
  101. package/dist/plugins.js +1 -1
  102. package/dist/registry/index.d.ts +1 -1
  103. package/dist/registry/release.d.ts +17 -1
  104. package/dist/testing.cjs +4 -4
  105. package/dist/testing.js +4 -4
  106. package/dist/utils/idGenerator.d.ts +0 -36
  107. package/dist/utils/static-props.d.ts +5 -0
  108. package/dist/utils/structural-key.d.ts +11 -1
  109. package/dist/watch/index.d.ts +1 -0
  110. package/dist/watch/observe.d.ts +13 -0
  111. package/dist/watch-B0pUfh-v.cjs +119 -0
  112. package/dist/watch-B0pUfh-v.cjs.map +1 -0
  113. package/dist/watch-BDiwCPmb.js +108 -0
  114. package/dist/watch-BDiwCPmb.js.map +1 -0
  115. package/dist/watch-BW7gYiDf.js +108 -0
  116. package/dist/watch-BW7gYiDf.js.map +1 -0
  117. package/dist/watch-Bx0y-Kcc.js +108 -0
  118. package/dist/watch-Bx0y-Kcc.js.map +1 -0
  119. package/dist/watch-DttHqefn.js +108 -0
  120. package/dist/watch-DttHqefn.js.map +1 -0
  121. package/dist/watch-DxdIZjpt.cjs +119 -0
  122. package/dist/watch-DxdIZjpt.cjs.map +1 -0
  123. package/dist/watch-aoNLQAXp.cjs +119 -0
  124. package/dist/watch-aoNLQAXp.cjs.map +1 -0
  125. package/dist/watch-entry.cjs +1 -1
  126. package/dist/watch-entry.js +1 -1
  127. package/dist/watch-lEco5Tbl.cjs +119 -0
  128. package/dist/watch-lEco5Tbl.cjs.map +1 -0
  129. package/package.json +3 -3
@@ -0,0 +1,16 @@
1
+ import { r as globalRegistry } from "./StateContainerRegistry-DWOzx7Gd.js";
2
+ //#region src/registry/config.ts
3
+ let _registry = globalRegistry;
4
+ function getRegistry() {
5
+ return _registry;
6
+ }
7
+ function setRegistry(registry) {
8
+ _registry = registry;
9
+ }
10
+ function getStats() {
11
+ return _registry.getStats();
12
+ }
13
+ //#endregion
14
+ export { getStats as n, setRegistry as r, getRegistry as t };
15
+
16
+ //# sourceMappingURL=config-D2A8ZYRM.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config-D2A8ZYRM.js","names":[],"sources":["../src/registry/config.ts"],"sourcesContent":["import {\n globalRegistry,\n StateContainerRegistry,\n} from '../core/StateContainerRegistry';\n\nlet _registry = globalRegistry;\n\nexport function getRegistry(): StateContainerRegistry {\n return _registry;\n}\n\nexport function setRegistry(registry: StateContainerRegistry): void {\n _registry = registry;\n}\n\nexport function getStats(): {\n registeredTypes: number;\n totalInstances: number;\n typeBreakdown: Record<string, number>;\n} {\n return _registry.getStats();\n}\n"],"mappings":";;AAKA,IAAI,YAAY;AAEhB,SAAgB,cAAsC;CACpD,OAAO;AACT;AAEA,SAAgB,YAAY,UAAwC;CAClE,YAAY;AACd;AAEA,SAAgB,WAId;CACA,OAAO,UAAU,SAAS;AAC5B"}
@@ -0,0 +1,32 @@
1
+ //#region src/registry/config.ts
2
+ let _registry = require("./StateContainerRegistry-C75QpeaO.cjs").globalRegistry;
3
+ function getRegistry() {
4
+ return _registry;
5
+ }
6
+ function setRegistry(registry) {
7
+ _registry = registry;
8
+ }
9
+ function getStats() {
10
+ return _registry.getStats();
11
+ }
12
+ //#endregion
13
+ Object.defineProperty(exports, "getRegistry", {
14
+ enumerable: true,
15
+ get: function() {
16
+ return getRegistry;
17
+ }
18
+ });
19
+ Object.defineProperty(exports, "getStats", {
20
+ enumerable: true,
21
+ get: function() {
22
+ return getStats;
23
+ }
24
+ });
25
+ Object.defineProperty(exports, "setRegistry", {
26
+ enumerable: true,
27
+ get: function() {
28
+ return setRegistry;
29
+ }
30
+ });
31
+
32
+ //# sourceMappingURL=config-D34BkraU.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config-D34BkraU.cjs","names":["globalRegistry"],"sources":["../src/registry/config.ts"],"sourcesContent":["import {\n globalRegistry,\n StateContainerRegistry,\n} from '../core/StateContainerRegistry';\n\nlet _registry = globalRegistry;\n\nexport function getRegistry(): StateContainerRegistry {\n return _registry;\n}\n\nexport function setRegistry(registry: StateContainerRegistry): void {\n _registry = registry;\n}\n\nexport function getStats(): {\n registeredTypes: number;\n totalInstances: number;\n typeBreakdown: Record<string, number>;\n} {\n return _registry.getStats();\n}\n"],"mappings":";AAKA,IAAI,2DAAYA,EAAAA;AAEhB,SAAgB,cAAsC;CACpD,OAAO;AACT;AAEA,SAAgB,YAAY,UAAwC;CAClE,YAAY;AACd;AAEA,SAAgB,WAId;CACA,OAAO,UAAU,SAAS;AAC5B"}
@@ -0,0 +1,16 @@
1
+ import { r as globalRegistry } from "./StateContainerRegistry-8zNFMAf7.js";
2
+ //#region src/registry/config.ts
3
+ let _registry = globalRegistry;
4
+ function getRegistry() {
5
+ return _registry;
6
+ }
7
+ function setRegistry(registry) {
8
+ _registry = registry;
9
+ }
10
+ function getStats() {
11
+ return _registry.getStats();
12
+ }
13
+ //#endregion
14
+ export { getStats as n, setRegistry as r, getRegistry as t };
15
+
16
+ //# sourceMappingURL=config-DOO82lbZ.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config-DOO82lbZ.js","names":[],"sources":["../src/registry/config.ts"],"sourcesContent":["import {\n globalRegistry,\n StateContainerRegistry,\n} from '../core/StateContainerRegistry';\n\nlet _registry = globalRegistry;\n\nexport function getRegistry(): StateContainerRegistry {\n return _registry;\n}\n\nexport function setRegistry(registry: StateContainerRegistry): void {\n _registry = registry;\n}\n\nexport function getStats(): {\n registeredTypes: number;\n totalInstances: number;\n typeBreakdown: Record<string, number>;\n} {\n return _registry.getStats();\n}\n"],"mappings":";;AAKA,IAAI,YAAY;AAEhB,SAAgB,cAAsC;CACpD,OAAO;AACT;AAEA,SAAgB,YAAY,UAAwC;CAClE,YAAY;AACd;AAEA,SAAgB,WAId;CACA,OAAO,UAAU,SAAS;AAC5B"}
@@ -0,0 +1,32 @@
1
+ //#region src/registry/config.ts
2
+ let _registry = require("./StateContainerRegistry-CS18y4au.cjs").globalRegistry;
3
+ function getRegistry() {
4
+ return _registry;
5
+ }
6
+ function setRegistry(registry) {
7
+ _registry = registry;
8
+ }
9
+ function getStats() {
10
+ return _registry.getStats();
11
+ }
12
+ //#endregion
13
+ Object.defineProperty(exports, "getRegistry", {
14
+ enumerable: true,
15
+ get: function() {
16
+ return getRegistry;
17
+ }
18
+ });
19
+ Object.defineProperty(exports, "getStats", {
20
+ enumerable: true,
21
+ get: function() {
22
+ return getStats;
23
+ }
24
+ });
25
+ Object.defineProperty(exports, "setRegistry", {
26
+ enumerable: true,
27
+ get: function() {
28
+ return setRegistry;
29
+ }
30
+ });
31
+
32
+ //# sourceMappingURL=config-DWUq7zEQ.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config-DWUq7zEQ.cjs","names":["globalRegistry"],"sources":["../src/registry/config.ts"],"sourcesContent":["import {\n globalRegistry,\n StateContainerRegistry,\n} from '../core/StateContainerRegistry';\n\nlet _registry = globalRegistry;\n\nexport function getRegistry(): StateContainerRegistry {\n return _registry;\n}\n\nexport function setRegistry(registry: StateContainerRegistry): void {\n _registry = registry;\n}\n\nexport function getStats(): {\n registeredTypes: number;\n totalInstances: number;\n typeBreakdown: Record<string, number>;\n} {\n return _registry.getStats();\n}\n"],"mappings":";AAKA,IAAI,2DAAYA,EAAAA;AAEhB,SAAgB,cAAsC;CACpD,OAAO;AACT;AAEA,SAAgB,YAAY,UAAwC;CAClE,YAAY;AACd;AAEA,SAAgB,WAId;CACA,OAAO,UAAU,SAAS;AAC5B"}
@@ -0,0 +1,16 @@
1
+ import { r as globalRegistry } from "./StateContainerRegistry-D8nu7Z0T.js";
2
+ //#region src/registry/config.ts
3
+ let _registry = globalRegistry;
4
+ function getRegistry() {
5
+ return _registry;
6
+ }
7
+ function setRegistry(registry) {
8
+ _registry = registry;
9
+ }
10
+ function getStats() {
11
+ return _registry.getStats();
12
+ }
13
+ //#endregion
14
+ export { getStats as n, setRegistry as r, getRegistry as t };
15
+
16
+ //# sourceMappingURL=config-DXI3kzmA.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config-DXI3kzmA.js","names":[],"sources":["../src/registry/config.ts"],"sourcesContent":["import {\n globalRegistry,\n StateContainerRegistry,\n} from '../core/StateContainerRegistry';\n\nlet _registry = globalRegistry;\n\nexport function getRegistry(): StateContainerRegistry {\n return _registry;\n}\n\nexport function setRegistry(registry: StateContainerRegistry): void {\n _registry = registry;\n}\n\nexport function getStats(): {\n registeredTypes: number;\n totalInstances: number;\n typeBreakdown: Record<string, number>;\n} {\n return _registry.getStats();\n}\n"],"mappings":";;AAKA,IAAI,YAAY;AAEhB,SAAgB,cAAsC;CACpD,OAAO;AACT;AAEA,SAAgB,YAAY,UAAwC;CAClE,YAAY;AACd;AAEA,SAAgB,WAId;CACA,OAAO,UAAU,SAAS;AAC5B"}
@@ -0,0 +1,16 @@
1
+ import { r as globalRegistry } from "./StateContainerRegistry-DL5Ai7wh.js";
2
+ //#region src/registry/config.ts
3
+ let _registry = globalRegistry;
4
+ function getRegistry() {
5
+ return _registry;
6
+ }
7
+ function setRegistry(registry) {
8
+ _registry = registry;
9
+ }
10
+ function getStats() {
11
+ return _registry.getStats();
12
+ }
13
+ //#endregion
14
+ export { getStats as n, setRegistry as r, getRegistry as t };
15
+
16
+ //# sourceMappingURL=config-ZVy_yFZ3.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config-ZVy_yFZ3.js","names":[],"sources":["../src/registry/config.ts"],"sourcesContent":["import {\n globalRegistry,\n StateContainerRegistry,\n} from '../core/StateContainerRegistry';\n\nlet _registry = globalRegistry;\n\nexport function getRegistry(): StateContainerRegistry {\n return _registry;\n}\n\nexport function setRegistry(registry: StateContainerRegistry): void {\n _registry = registry;\n}\n\nexport function getStats(): {\n registeredTypes: number;\n totalInstances: number;\n typeBreakdown: Record<string, number>;\n} {\n return _registry.getStats();\n}\n"],"mappings":";;AAKA,IAAI,YAAY;AAEhB,SAAgB,cAAsC;CACpD,OAAO;AACT;AAEA,SAAgB,YAAY,UAAwC;CAClE,YAAY;AACd;AAEA,SAAgB,WAId;CACA,OAAO,UAAU,SAAS;AAC5B"}
@@ -0,0 +1,32 @@
1
+ //#region src/registry/config.ts
2
+ let _registry = require("./StateContainerRegistry-Bx2ly-ba.cjs").globalRegistry;
3
+ function getRegistry() {
4
+ return _registry;
5
+ }
6
+ function setRegistry(registry) {
7
+ _registry = registry;
8
+ }
9
+ function getStats() {
10
+ return _registry.getStats();
11
+ }
12
+ //#endregion
13
+ Object.defineProperty(exports, "getRegistry", {
14
+ enumerable: true,
15
+ get: function() {
16
+ return getRegistry;
17
+ }
18
+ });
19
+ Object.defineProperty(exports, "getStats", {
20
+ enumerable: true,
21
+ get: function() {
22
+ return getStats;
23
+ }
24
+ });
25
+ Object.defineProperty(exports, "setRegistry", {
26
+ enumerable: true,
27
+ get: function() {
28
+ return setRegistry;
29
+ }
30
+ });
31
+
32
+ //# sourceMappingURL=config-cwaTn5oy.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config-cwaTn5oy.cjs","names":["globalRegistry"],"sources":["../src/registry/config.ts"],"sourcesContent":["import {\n globalRegistry,\n StateContainerRegistry,\n} from '../core/StateContainerRegistry';\n\nlet _registry = globalRegistry;\n\nexport function getRegistry(): StateContainerRegistry {\n return _registry;\n}\n\nexport function setRegistry(registry: StateContainerRegistry): void {\n _registry = registry;\n}\n\nexport function getStats(): {\n registeredTypes: number;\n totalInstances: number;\n typeBreakdown: Record<string, number>;\n} {\n return _registry.getStats();\n}\n"],"mappings":";AAKA,IAAI,2DAAYA,EAAAA;AAEhB,SAAgB,cAAsC;CACpD,OAAO;AACT;AAEA,SAAgB,YAAY,UAAwC;CAClE,YAAY;AACd;AAEA,SAAgB,WAId;CACA,OAAO,UAAU,SAAS;AAC5B"}
package/dist/config.d.cts CHANGED
@@ -8,6 +8,10 @@ export interface BlacConfig {
8
8
  * `prev` and `next` are structurally equal. Default: `shallowEqualState`.
9
9
  *
10
10
  * Return `true` to skip the emit (states considered equal).
11
+ *
12
+ * Applies to `emit`/`update` only — `patch` does not consult this fn; it
13
+ * relies on its own per-key `Object.is` pre-check plus structural no-op
14
+ * detection to skip redundant notifications.
11
15
  */
12
16
  equality: EqualityFn;
13
17
  /**
@@ -16,7 +20,7 @@ export interface BlacConfig {
16
20
  * creation — typically an unstable/args-derived key churning out instances
17
21
  * that are never disposed (a memory leak that eventually freezes the app).
18
22
  *
19
- * Default: `1000`. Set to `Infinity` (or any non-positive value) to disable.
23
+ * Default: `100000`. Set to `Infinity` (or any non-positive value) to disable.
20
24
  */
21
25
  maxInstancesPerType: number;
22
26
  /**
@@ -25,7 +29,7 @@ export interface BlacConfig {
25
29
  * other leak shape — consumer cleanup (e.g. `useBloc` unmount `release`)
26
30
  * never firing, so refs accumulate without bound on one instance.
27
31
  *
28
- * Default: `1000`. Set to `Infinity` (or any non-positive value) to disable.
32
+ * Default: `100000`. Set to `Infinity` (or any non-positive value) to disable.
29
33
  */
30
34
  maxRefsPerInstance: number;
31
35
  /**
@@ -37,7 +41,7 @@ export interface BlacConfig {
37
41
  * plugins (logging/devtools), and the main thread.
38
42
  *
39
43
  * Heuristic by nature — warns, never throws, since high-frequency state can
40
- * occasionally be legitimate. No-op in production. Default: `100`. Set to
44
+ * occasionally be legitimate. No-op in production. Default: `1000`. Set to
41
45
  * `Infinity` (or any non-positive value) to disable.
42
46
  */
43
47
  maxEmitsPerSecond: number;
package/dist/config.d.ts CHANGED
@@ -8,6 +8,10 @@ export interface BlacConfig {
8
8
  * `prev` and `next` are structurally equal. Default: `shallowEqualState`.
9
9
  *
10
10
  * Return `true` to skip the emit (states considered equal).
11
+ *
12
+ * Applies to `emit`/`update` only — `patch` does not consult this fn; it
13
+ * relies on its own per-key `Object.is` pre-check plus structural no-op
14
+ * detection to skip redundant notifications.
11
15
  */
12
16
  equality: EqualityFn;
13
17
  /**
@@ -16,7 +20,7 @@ export interface BlacConfig {
16
20
  * creation — typically an unstable/args-derived key churning out instances
17
21
  * that are never disposed (a memory leak that eventually freezes the app).
18
22
  *
19
- * Default: `1000`. Set to `Infinity` (or any non-positive value) to disable.
23
+ * Default: `100000`. Set to `Infinity` (or any non-positive value) to disable.
20
24
  */
21
25
  maxInstancesPerType: number;
22
26
  /**
@@ -25,7 +29,7 @@ export interface BlacConfig {
25
29
  * other leak shape — consumer cleanup (e.g. `useBloc` unmount `release`)
26
30
  * never firing, so refs accumulate without bound on one instance.
27
31
  *
28
- * Default: `1000`. Set to `Infinity` (or any non-positive value) to disable.
32
+ * Default: `100000`. Set to `Infinity` (or any non-positive value) to disable.
29
33
  */
30
34
  maxRefsPerInstance: number;
31
35
  /**
@@ -37,7 +41,7 @@ export interface BlacConfig {
37
41
  * plugins (logging/devtools), and the main thread.
38
42
  *
39
43
  * Heuristic by nature — warns, never throws, since high-frequency state can
40
- * occasionally be legitimate. No-op in production. Default: `100`. Set to
44
+ * occasionally be legitimate. No-op in production. Default: `1000`. Set to
41
45
  * `Infinity` (or any non-positive value) to disable.
42
46
  */
43
47
  maxEmitsPerSecond: number;
@@ -11,10 +11,6 @@ export declare const BLAC_DEFAULTS: {
11
11
  * Default instance key for shared instances
12
12
  */
13
13
  readonly DEFAULT_INSTANCE_KEY: "default";
14
- /**
15
- * Maximum getter nesting depth (prevents infinite recursion)
16
- */
17
- readonly MAX_GETTER_DEPTH: 10;
18
14
  };
19
15
  /**
20
16
  * Static property names for StateContainer classes
@@ -42,15 +38,8 @@ export declare const BLAC_STATIC_PROPS: {
42
38
  * non-identity fields (e.g., `readonly` flags) while still keying by id.
43
39
  */
44
40
  readonly KEY: "key";
45
- };
46
- /**
47
- * ID generation patterns and constants
48
- */
49
- export declare const BLAC_ID_PATTERNS: {
50
- /**
51
- * Length of generated ID portion (9 characters from base36)
52
- */
53
- readonly ID_LENGTH: 9;
41
+ /** Mark a bloc as always per-mount: `static isolated = true`. */
42
+ readonly ISOLATED: "isolated";
54
43
  };
55
44
  /**
56
45
  * Standard error message prefix
@@ -11,10 +11,6 @@ export declare const BLAC_DEFAULTS: {
11
11
  * Default instance key for shared instances
12
12
  */
13
13
  readonly DEFAULT_INSTANCE_KEY: "default";
14
- /**
15
- * Maximum getter nesting depth (prevents infinite recursion)
16
- */
17
- readonly MAX_GETTER_DEPTH: 10;
18
14
  };
19
15
  /**
20
16
  * Static property names for StateContainer classes
@@ -42,15 +38,8 @@ export declare const BLAC_STATIC_PROPS: {
42
38
  * non-identity fields (e.g., `readonly` flags) while still keying by id.
43
39
  */
44
40
  readonly KEY: "key";
45
- };
46
- /**
47
- * ID generation patterns and constants
48
- */
49
- export declare const BLAC_ID_PATTERNS: {
50
- /**
51
- * Length of generated ID portion (9 characters from base36)
52
- */
53
- readonly ID_LENGTH: 9;
41
+ /** Mark a bloc as always per-mount: `static isolated = true`. */
42
+ readonly ISOLATED: "isolated";
54
43
  };
55
44
  /**
56
45
  * Standard error message prefix
@@ -1,6 +1,7 @@
1
1
  import { StructuralContainer, type DeepPartial, type StructuralContainerOptions } from '@dirtytalk/structural';
2
+ import { type EventToken } from '../events';
2
3
  import type { ExtractArgs, ExtractState, StateContainerConstructor } from '../types/utilities';
3
- import { APPLY_DEPS, INIT_CONFIG, REMOVE_DEPS_OWNER } from './symbols';
4
+ import { APPLY_DEPS, INIT_CONFIG, ON_DISPOSE, REMOVE_DEPS_OWNER } from './symbols';
4
5
  import { type BlacMeta } from './meta';
5
6
  /**
6
7
  * Brand symbol carried (non-enumerable) on every handle returned by
@@ -104,6 +105,12 @@ export declare abstract class StateContainer<S extends object = any, Args = void
104
105
  * @internal Withdraw an owner's entire deps slice (consumer unmounted).
105
106
  */
106
107
  [REMOVE_DEPS_OWNER](ownerId: string): void;
108
+ /**
109
+ * @internal Subscribe to this instance's own disposal. Delegates to the
110
+ * per-instance `'dispose'` system event — used by `watch()` in place of
111
+ * filtering the global registry `'disposed'` event.
112
+ */
113
+ [ON_DISPOSE](handler: () => void): () => void;
107
114
  private reconcileDeps;
108
115
  protected onDepsChanged(_next: Readonly<Deps>, _prev: Readonly<Deps>): void;
109
116
  private _disposed;
@@ -121,6 +128,7 @@ export declare abstract class StateContainer<S extends object = any, Args = void
121
128
  private _emitRateWarned;
122
129
  private readonly _systemEventHandlers;
123
130
  private _dependencies;
131
+ private _depEdges;
124
132
  private _pendingChange;
125
133
  private _bridgeUnsub;
126
134
  private _registry;
@@ -156,6 +164,15 @@ export declare abstract class StateContainer<S extends object = any, Args = void
156
164
  */
157
165
  protected depend<T extends StateContainerConstructor>(Type: T, defaultArgs?: ExtractArgs<T>): DepHandle<T>;
158
166
  constructor(initialState: S, options?: StructuralContainerOptions);
167
+ /**
168
+ * @internal Subscribe the channel bridge that turns flushes into
169
+ * 'stateChanged' system events. Interest is ALL_PATHS so we wake on every
170
+ * flush. Coalesced via `_pendingChange`: if no emit happened (e.g. a no-op
171
+ * patch), the bridge sees null and skips. Lazy: only subscribed while at
172
+ * least one 'stateChanged' handler exists.
173
+ */
174
+ private _subscribeBridge;
175
+ private _hasStateChangedHandlers;
159
176
  /**
160
177
  * Called once after construction with the args passed at acquire time, before the first
161
178
  * state snapshot is read by any consumer. Override to seed args-derived state (via
@@ -198,6 +215,16 @@ export declare abstract class StateContainer<S extends object = any, Args = void
198
215
  private resolveHydration;
199
216
  private rejectHydration;
200
217
  protected onSystemEvent: <E extends SystemEvent>(event: E, handler: SystemEventHandler<S, E>) => (() => void);
218
+ /**
219
+ * Subscribe to a cross-cutting application event for this container's
220
+ * lifetime. The subscription is torn down automatically on `dispose()` — no
221
+ * manual `off` in consumer code (requirements AC3).
222
+ *
223
+ * Uses THIS container's registry (`_registry`, captured at construction), not
224
+ * the ambient one, so a container always listens on the bus of the registry it
225
+ * belongs to.
226
+ */
227
+ protected on: <P>(token: EventToken<P>, handler: (payload: P) => void) => (() => void);
201
228
  private emitSystemEvent;
202
229
  /**
203
230
  * Dev-only soft circuit breaker. Counts real state changes in a rolling 1s
@@ -1,6 +1,6 @@
1
1
  import type { HydrationStatus, StateContainer } from './StateContainer';
2
2
  import { type PluginManager } from '../plugin/PluginManager';
3
- import { InstanceReadonlyState, StateContainerConstructor } from '../types/utilities';
3
+ import { InstanceReadonlyState, StateContainerConstructor, StateContainerInstance } from '../types/utilities';
4
4
  /**
5
5
  * Entry in the instance registry, tracking the instance and its named references
6
6
  * @template T - Instance type
@@ -12,6 +12,17 @@ export interface InstanceEntry<T = any> {
12
12
  refs: Map<string, number>;
13
13
  /** The args used when this entry was first created; used for dev-warn on arg mismatch. */
14
14
  args?: unknown;
15
+ /** Memoized structuralKey(args) for the dev arg-mismatch warning. */
16
+ argsKey?: string;
17
+ /** `depend()`-owners currently holding this instance (see `acquire`'s `dependent` option). */
18
+ dependents?: Set<StateContainer<any, any, any>>;
19
+ /**
20
+ * `$blac.id` this entry is indexed under in `_byId`, captured at index time.
21
+ * Removal always keys off THIS stored id (never a fresh `$blac.id` read),
22
+ * so an id that changes later (e.g. `INIT_CONFIG` running after insertion)
23
+ * can never orphan the index.
24
+ */
25
+ id?: string;
15
26
  }
16
27
  /**
17
28
  * Lifecycle events emitted by the registry
@@ -38,13 +49,69 @@ export type LifecycleListener<E extends LifecycleEvent> = E extends 'created' ?
38
49
  */
39
50
  export declare class StateContainerRegistry {
40
51
  private readonly instancesByConstructor;
52
+ /**
53
+ * Known storage key for each live instance, so disposal can delete its
54
+ * Map entry directly instead of scanning every entry for identity (P3).
55
+ */
56
+ private readonly _keyByInstance;
57
+ /** Id index for O(1) `findEntryById` lookups (P6, used by devtools' `getRefIds`). */
58
+ private readonly _byId;
41
59
  private readonly types;
42
- private readonly registeredTypeNames;
60
+ private _registeredTypes;
43
61
  private readonly listeners;
44
62
  private _stateChangedListenerCount;
45
63
  get hasStateChangedListeners(): boolean;
46
64
  private _pendingStateChanges;
47
65
  private _autoRefIdCounter;
66
+ constructor();
67
+ /**
68
+ * Registry-internal reaction to any instance's `disposed` lifecycle event.
69
+ * Prunes its Map entry, if this registry was tracking it (i.e. it was
70
+ * `acquire()`/`ensure()`'d, not a bare `new`), and always releases its
71
+ * dependent edges on whatever it `depend()`'d on.
72
+ */
73
+ private _handleDisposed;
74
+ /**
75
+ * Remove the Map entry for `container`, if this registry is tracking it.
76
+ * O(1): looks up the entry's key via `_keyByInstance` instead of scanning
77
+ * every entry for identity. Keeps an identity guard so a recreated entry
78
+ * under the same key (a fresh instance under a reused/derived key) is
79
+ * never deleted by a stale container's disposal.
80
+ * @returns true if an entry was found and removed
81
+ */
82
+ private _pruneEntry;
83
+ /**
84
+ * Single removal point for the `_byId` index (P6). Every path that drops
85
+ * an `InstanceEntry` from the registry MUST route through this so the
86
+ * index can never leak a stale id -> entry mapping.
87
+ */
88
+ private _forgetEntry;
89
+ /**
90
+ * O(1) entry lookup by `$blac.id`, used by `PluginContext.getRefIds`
91
+ * instead of a nested scan over every type x every instance.
92
+ */
93
+ findEntryById(id: string): InstanceEntry | undefined;
94
+ /**
95
+ * Storage key `container` is CURRENTLY indexed under, or `undefined` if this
96
+ * registry never tracked it (bare `new`) or no longer does (disposed/pruned,
97
+ * or its key was taken over by a newer instance). Lets callers that hold only
98
+ * an instance address it without knowing the `args` it was acquired with.
99
+ */
100
+ keyOf(instance: StateContainerInstance): string | undefined;
101
+ /**
102
+ * Drop `Type` from `types` once its instances map is empty, so constructors
103
+ * (and anything keyed on them, e.g. a per-class PathInterner) aren't held
104
+ * alive forever. Deliberate consequence: `getStats()`/`getTypes()` no
105
+ * longer list types with zero live instances.
106
+ */
107
+ private _maybeDropType;
108
+ /**
109
+ * Drop `dependent`'s edge on the `Type`/`key` entry (a `depend()`-resolved
110
+ * instance). When that leaves the entry with no dependents AND no public
111
+ * refs AND it isn't keepAlive, dispose it — this recurses into the same
112
+ * `disposed` listener, so dep-of-dep chains unwind naturally.
113
+ */
114
+ private _releaseDependent;
48
115
  /**
49
116
  * Register a type for lifecycle event tracking
50
117
  * @param constructor - The StateContainer class constructor
@@ -112,6 +179,8 @@ export declare class StateContainerRegistry {
112
179
  * @param options.canCreate - Whether to create new instance if not found (default: true)
113
180
  * @param options.countRef - Whether to add a reference (default: true)
114
181
  * @param options.refId - Named reference ID for debugging; auto-generated if omitted
182
+ * @param options.dependent - The `depend()`-owner resolving this instance, if any;
183
+ * recorded so its dependent edge can be released on the owner's disposal.
115
184
  * @returns The state container instance
116
185
  */
117
186
  acquire<T extends StateContainerConstructor = StateContainerConstructor>(Type: T, instanceKey?: string, options?: {
@@ -119,6 +188,7 @@ export declare class StateContainerRegistry {
119
188
  countRef?: boolean;
120
189
  refId?: string;
121
190
  args?: unknown;
191
+ dependent?: StateContainer<any, any, any>;
122
192
  }): InstanceType<T>;
123
193
  /**
124
194
  * Borrow an existing instance without adding a ref (borrowing semantics).
@@ -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`),
package/dist/debug.cjs CHANGED
@@ -1,7 +1,7 @@
1
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
- const require_StateContainerRegistry = require("./StateContainerRegistry-lIwo-0m3.cjs");
3
- const require_config = require("./config-B1l8ZGlU.cjs");
4
- const require_management = require("./management-DwO0nBzL.cjs");
2
+ const require_StateContainerRegistry = require("./StateContainerRegistry-G81GcCRm.cjs");
3
+ const require_config = require("./config-C1T6Jw7n.cjs");
4
+ const require_management = require("./management-hkY13log.cjs");
5
5
  exports.forEach = require_management.forEach;
6
6
  exports.getAll = require_management.getAll;
7
7
  exports.getRefCount = require_management.getRefCount;
package/dist/debug.js CHANGED
@@ -1,4 +1,4 @@
1
- import { r as globalRegistry } from "./StateContainerRegistry-Dj77cok9.js";
2
- import { n as getStats, r as setRegistry, t as getRegistry } from "./config-CzcoAvBo.js";
3
- import { a as getAll, c as hasInstance, i as forEach, o as getRefCount, r as register, s as getRefIds } from "./management-AFuqQEwz.js";
1
+ import { r as globalRegistry } from "./StateContainerRegistry-DWOzx7Gd.js";
2
+ import { n as getStats, r as setRegistry, t as getRegistry } from "./config-D2A8ZYRM.js";
3
+ import { a as getAll, c as hasInstance, i as forEach, o as getRefCount, r as register, s as getRefIds } from "./management-8x1OVMi6.js";
4
4
  export { forEach, getAll, getRefCount, getRefIds, getRegistry, getStats, globalRegistry, hasInstance, register, setRegistry };
@@ -15,6 +15,8 @@ export type BlacOptions =
15
15
  /**
16
16
  * Override the global equality check for this bloc.
17
17
  * Return `true` to skip the emit (states considered equal).
18
+ * Applies to `emit`/`update` only — `patch` does not consult this fn; it
19
+ * still skips structural no-ops on its own.
18
20
  */
19
21
  | {
20
22
  equality: EqualityFn;