@bquery/bquery 1.7.0 → 1.8.2

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 (262) hide show
  1. package/README.md +760 -716
  2. package/dist/{a11y-C5QOVvRn.js → a11y-DVBCy09c.js} +3 -3
  3. package/dist/a11y-DVBCy09c.js.map +1 -0
  4. package/dist/a11y.es.mjs +1 -1
  5. package/dist/component/library.d.ts.map +1 -1
  6. package/dist/{component-CuuTijA6.js → component-L3-JfOFz.js} +5 -5
  7. package/dist/component-L3-JfOFz.js.map +1 -0
  8. package/dist/component.es.mjs +1 -1
  9. package/dist/{config-BW35FKuA.js → config-DhT9auRm.js} +1 -1
  10. package/dist/{config-BW35FKuA.js.map → config-DhT9auRm.js.map} +1 -1
  11. package/dist/{constraints-3lV9yyBw.js → constraints-D5RHQLmP.js} +1 -1
  12. package/dist/constraints-D5RHQLmP.js.map +1 -0
  13. package/dist/core/collection.d.ts +86 -0
  14. package/dist/core/collection.d.ts.map +1 -1
  15. package/dist/core/element.d.ts +28 -0
  16. package/dist/core/element.d.ts.map +1 -1
  17. package/dist/core/shared.d.ts +6 -0
  18. package/dist/core/shared.d.ts.map +1 -1
  19. package/dist/core-DdtZHzsS.js +168 -0
  20. package/dist/core-DdtZHzsS.js.map +1 -0
  21. package/dist/{core-Cjl7GUu8.js → core-EMYSLzaT.js} +289 -259
  22. package/dist/core-EMYSLzaT.js.map +1 -0
  23. package/dist/core.es.mjs +48 -47
  24. package/dist/{custom-directives-7wAShnnd.js → custom-directives-Dr4C5lVV.js} +1 -1
  25. package/dist/custom-directives-Dr4C5lVV.js.map +1 -0
  26. package/dist/{devtools-D2fQLhDN.js → devtools-BhB2iDPT.js} +2 -2
  27. package/dist/devtools-BhB2iDPT.js.map +1 -0
  28. package/dist/devtools.es.mjs +1 -1
  29. package/dist/{dnd-B8EgyzaI.js → dnd-NwZBYh4l.js} +1 -1
  30. package/dist/dnd-NwZBYh4l.js.map +1 -0
  31. package/dist/dnd.es.mjs +1 -1
  32. package/dist/{env-NeVmr4Gf.js → env-CTdvLaH2.js} +1 -1
  33. package/dist/env-CTdvLaH2.js.map +1 -0
  34. package/dist/forms/create-form.d.ts.map +1 -1
  35. package/dist/forms/index.d.ts +3 -2
  36. package/dist/forms/index.d.ts.map +1 -1
  37. package/dist/forms/types.d.ts +46 -0
  38. package/dist/forms/types.d.ts.map +1 -1
  39. package/dist/forms/use-field.d.ts +34 -0
  40. package/dist/forms/use-field.d.ts.map +1 -0
  41. package/dist/forms/validators.d.ts +25 -0
  42. package/dist/forms/validators.d.ts.map +1 -1
  43. package/dist/forms-UcRHsYxC.js +227 -0
  44. package/dist/forms-UcRHsYxC.js.map +1 -0
  45. package/dist/forms.es.mjs +14 -12
  46. package/dist/full.d.ts +17 -26
  47. package/dist/full.d.ts.map +1 -1
  48. package/dist/full.es.mjs +206 -181
  49. package/dist/full.iife.js +33 -33
  50. package/dist/full.iife.js.map +1 -1
  51. package/dist/full.umd.js +33 -33
  52. package/dist/full.umd.js.map +1 -1
  53. package/dist/function-Cybd57JV.js +33 -0
  54. package/dist/function-Cybd57JV.js.map +1 -0
  55. package/dist/{i18n-BnnhTFOS.js → i18n-kuF6Ekj6.js} +3 -3
  56. package/dist/i18n-kuF6Ekj6.js.map +1 -0
  57. package/dist/i18n.es.mjs +1 -1
  58. package/dist/index.es.mjs +251 -228
  59. package/dist/media/breakpoints.d.ts.map +1 -1
  60. package/dist/media/types.d.ts +2 -2
  61. package/dist/media/types.d.ts.map +1 -1
  62. package/dist/{media-Di2Ta22s.js → media-i-fB5WxI.js} +3 -3
  63. package/dist/media-i-fB5WxI.js.map +1 -0
  64. package/dist/media.es.mjs +1 -1
  65. package/dist/{motion-qPj_TYGv.js → motion-BJsAuULb.js} +2 -2
  66. package/dist/motion-BJsAuULb.js.map +1 -0
  67. package/dist/motion.es.mjs +1 -1
  68. package/dist/{mount-SM07RUa6.js → mount-B4Y8bk8Z.js} +5 -5
  69. package/dist/mount-B4Y8bk8Z.js.map +1 -0
  70. package/dist/{platform-CPbCprb6.js → platform-Dw2gE3zI.js} +3 -3
  71. package/dist/{platform-CPbCprb6.js.map → platform-Dw2gE3zI.js.map} +1 -1
  72. package/dist/platform.es.mjs +2 -2
  73. package/dist/plugin/registry.d.ts.map +1 -1
  74. package/dist/{plugin-cPoOHFLY.js → plugin-C2WuC8SF.js} +20 -18
  75. package/dist/plugin-C2WuC8SF.js.map +1 -0
  76. package/dist/plugin.es.mjs +1 -1
  77. package/dist/reactive/async-data.d.ts +28 -3
  78. package/dist/reactive/async-data.d.ts.map +1 -1
  79. package/dist/reactive/computed.d.ts +3 -0
  80. package/dist/reactive/computed.d.ts.map +1 -1
  81. package/dist/reactive/effect.d.ts +3 -0
  82. package/dist/reactive/effect.d.ts.map +1 -1
  83. package/dist/reactive/http.d.ts +194 -0
  84. package/dist/reactive/http.d.ts.map +1 -0
  85. package/dist/reactive/index.d.ts +2 -2
  86. package/dist/reactive/index.d.ts.map +1 -1
  87. package/dist/reactive/pagination.d.ts +126 -0
  88. package/dist/reactive/pagination.d.ts.map +1 -0
  89. package/dist/reactive/polling.d.ts +55 -0
  90. package/dist/reactive/polling.d.ts.map +1 -0
  91. package/dist/reactive/readonly.d.ts +20 -1
  92. package/dist/reactive/readonly.d.ts.map +1 -1
  93. package/dist/reactive/rest.d.ts +293 -0
  94. package/dist/reactive/rest.d.ts.map +1 -0
  95. package/dist/reactive/scope.d.ts +140 -0
  96. package/dist/reactive/scope.d.ts.map +1 -0
  97. package/dist/reactive/signal.d.ts +16 -2
  98. package/dist/reactive/signal.d.ts.map +1 -1
  99. package/dist/reactive/to-value.d.ts +57 -0
  100. package/dist/reactive/to-value.d.ts.map +1 -0
  101. package/dist/reactive/websocket.d.ts +285 -0
  102. package/dist/reactive/websocket.d.ts.map +1 -0
  103. package/dist/reactive-DwkhUJfP.js +1148 -0
  104. package/dist/reactive-DwkhUJfP.js.map +1 -0
  105. package/dist/reactive.es.mjs +38 -19
  106. package/dist/{registry-CWf368tT.js → registry-B08iilIh.js} +1 -1
  107. package/dist/{registry-CWf368tT.js.map → registry-B08iilIh.js.map} +1 -1
  108. package/dist/router/constraints.d.ts.map +1 -1
  109. package/dist/router/index.d.ts +1 -1
  110. package/dist/router/index.d.ts.map +1 -1
  111. package/dist/router/router.d.ts.map +1 -1
  112. package/dist/router/state.d.ts +25 -2
  113. package/dist/router/state.d.ts.map +1 -1
  114. package/dist/router-CQikC9Ed.js +492 -0
  115. package/dist/router-CQikC9Ed.js.map +1 -0
  116. package/dist/router.es.mjs +9 -8
  117. package/dist/ssr/hydrate.d.ts.map +1 -1
  118. package/dist/{ssr-B2qd_WBB.js → ssr-_dAcGdzu.js} +4 -4
  119. package/dist/ssr-_dAcGdzu.js.map +1 -0
  120. package/dist/ssr.es.mjs +1 -1
  121. package/dist/store/persisted.d.ts.map +1 -1
  122. package/dist/{store-DWpyH6p5.js → store-Cb3gPRve.js} +7 -7
  123. package/dist/store-Cb3gPRve.js.map +1 -0
  124. package/dist/store.es.mjs +2 -2
  125. package/dist/storybook.es.mjs.map +1 -1
  126. package/dist/{testing-CsqjNUyy.js → testing-C5Sjfsna.js} +8 -8
  127. package/dist/testing-C5Sjfsna.js.map +1 -0
  128. package/dist/testing.es.mjs +1 -1
  129. package/dist/{type-guards-Do9DWgNp.js → type-guards-BMX2c0LP.js} +1 -1
  130. package/dist/{type-guards-Do9DWgNp.js.map → type-guards-BMX2c0LP.js.map} +1 -1
  131. package/dist/untrack-D0fnO5k2.js +36 -0
  132. package/dist/untrack-D0fnO5k2.js.map +1 -0
  133. package/dist/view/custom-directives.d.ts.map +1 -1
  134. package/dist/view.es.mjs +4 -4
  135. package/package.json +178 -177
  136. package/src/a11y/announce.ts +131 -131
  137. package/src/a11y/audit.ts +314 -314
  138. package/src/a11y/index.ts +68 -68
  139. package/src/a11y/media-preferences.ts +255 -255
  140. package/src/a11y/roving-tab-index.ts +164 -164
  141. package/src/a11y/skip-link.ts +255 -255
  142. package/src/a11y/trap-focus.ts +184 -184
  143. package/src/a11y/types.ts +183 -183
  144. package/src/component/component.ts +599 -599
  145. package/src/component/html.ts +153 -153
  146. package/src/component/index.ts +52 -52
  147. package/src/component/library.ts +540 -542
  148. package/src/component/scope.ts +212 -212
  149. package/src/component/types.ts +310 -310
  150. package/src/core/collection.ts +876 -707
  151. package/src/core/element.ts +1015 -981
  152. package/src/core/env.ts +60 -60
  153. package/src/core/index.ts +49 -49
  154. package/src/core/shared.ts +77 -62
  155. package/src/core/utils/index.ts +148 -148
  156. package/src/devtools/devtools.ts +410 -410
  157. package/src/devtools/index.ts +48 -48
  158. package/src/devtools/types.ts +104 -104
  159. package/src/dnd/draggable.ts +296 -296
  160. package/src/dnd/droppable.ts +228 -228
  161. package/src/dnd/index.ts +62 -62
  162. package/src/dnd/sortable.ts +307 -307
  163. package/src/dnd/types.ts +293 -293
  164. package/src/forms/create-form.ts +320 -278
  165. package/src/forms/index.ts +70 -65
  166. package/src/forms/types.ts +203 -154
  167. package/src/forms/use-field.ts +231 -0
  168. package/src/forms/validators.ts +294 -265
  169. package/src/full.ts +554 -480
  170. package/src/i18n/formatting.ts +67 -67
  171. package/src/i18n/i18n.ts +200 -200
  172. package/src/i18n/index.ts +67 -67
  173. package/src/i18n/translate.ts +182 -182
  174. package/src/i18n/types.ts +171 -171
  175. package/src/index.ts +108 -108
  176. package/src/media/battery.ts +116 -116
  177. package/src/media/breakpoints.ts +129 -131
  178. package/src/media/clipboard.ts +80 -80
  179. package/src/media/device-sensors.ts +158 -158
  180. package/src/media/geolocation.ts +119 -119
  181. package/src/media/index.ts +76 -76
  182. package/src/media/media-query.ts +92 -92
  183. package/src/media/network.ts +115 -115
  184. package/src/media/types.ts +177 -177
  185. package/src/media/viewport.ts +84 -84
  186. package/src/motion/index.ts +57 -57
  187. package/src/motion/morph.ts +151 -151
  188. package/src/motion/parallax.ts +120 -120
  189. package/src/motion/reduced-motion.ts +66 -66
  190. package/src/motion/types.ts +271 -271
  191. package/src/motion/typewriter.ts +164 -164
  192. package/src/plugin/index.ts +37 -37
  193. package/src/plugin/registry.ts +284 -269
  194. package/src/plugin/types.ts +137 -137
  195. package/src/reactive/async-data.ts +250 -29
  196. package/src/reactive/computed.ts +144 -130
  197. package/src/reactive/effect.ts +29 -6
  198. package/src/reactive/http.ts +790 -0
  199. package/src/reactive/index.ts +60 -0
  200. package/src/reactive/pagination.ts +317 -0
  201. package/src/reactive/polling.ts +179 -0
  202. package/src/reactive/readonly.ts +52 -8
  203. package/src/reactive/rest.ts +859 -0
  204. package/src/reactive/scope.ts +276 -0
  205. package/src/reactive/signal.ts +61 -1
  206. package/src/reactive/to-value.ts +71 -0
  207. package/src/reactive/websocket.ts +849 -0
  208. package/src/router/bq-link.ts +279 -279
  209. package/src/router/constraints.ts +204 -201
  210. package/src/router/index.ts +49 -49
  211. package/src/router/match.ts +312 -312
  212. package/src/router/path-pattern.ts +52 -52
  213. package/src/router/query.ts +38 -38
  214. package/src/router/router.ts +421 -402
  215. package/src/router/state.ts +51 -3
  216. package/src/router/types.ts +139 -139
  217. package/src/router/use-route.ts +68 -68
  218. package/src/router/utils.ts +157 -157
  219. package/src/security/index.ts +12 -12
  220. package/src/ssr/hydrate.ts +84 -82
  221. package/src/ssr/index.ts +70 -70
  222. package/src/ssr/render.ts +508 -508
  223. package/src/ssr/serialize.ts +296 -296
  224. package/src/ssr/types.ts +81 -81
  225. package/src/store/create-store.ts +467 -467
  226. package/src/store/index.ts +27 -27
  227. package/src/store/persisted.ts +245 -249
  228. package/src/store/types.ts +247 -247
  229. package/src/store/utils.ts +135 -135
  230. package/src/storybook/index.ts +480 -480
  231. package/src/testing/index.ts +42 -42
  232. package/src/testing/testing.ts +593 -593
  233. package/src/testing/types.ts +170 -170
  234. package/src/view/custom-directives.ts +28 -30
  235. package/src/view/evaluate.ts +292 -292
  236. package/src/view/process.ts +108 -108
  237. package/dist/a11y-C5QOVvRn.js.map +0 -1
  238. package/dist/component-CuuTijA6.js.map +0 -1
  239. package/dist/constraints-3lV9yyBw.js.map +0 -1
  240. package/dist/core-Cjl7GUu8.js.map +0 -1
  241. package/dist/core-DnlyjbF2.js +0 -112
  242. package/dist/core-DnlyjbF2.js.map +0 -1
  243. package/dist/custom-directives-7wAShnnd.js.map +0 -1
  244. package/dist/devtools-D2fQLhDN.js.map +0 -1
  245. package/dist/dnd-B8EgyzaI.js.map +0 -1
  246. package/dist/env-NeVmr4Gf.js.map +0 -1
  247. package/dist/forms-C3yovgH9.js +0 -141
  248. package/dist/forms-C3yovgH9.js.map +0 -1
  249. package/dist/i18n-BnnhTFOS.js.map +0 -1
  250. package/dist/media-Di2Ta22s.js.map +0 -1
  251. package/dist/motion-qPj_TYGv.js.map +0 -1
  252. package/dist/mount-SM07RUa6.js.map +0 -1
  253. package/dist/plugin-cPoOHFLY.js.map +0 -1
  254. package/dist/reactive-Cfv0RK6x.js +0 -233
  255. package/dist/reactive-Cfv0RK6x.js.map +0 -1
  256. package/dist/router-BrthaP_z.js +0 -473
  257. package/dist/router-BrthaP_z.js.map +0 -1
  258. package/dist/ssr-B2qd_WBB.js.map +0 -1
  259. package/dist/store-DWpyH6p5.js.map +0 -1
  260. package/dist/testing-CsqjNUyy.js.map +0 -1
  261. package/dist/untrack-DJVQQ2WM.js +0 -33
  262. package/dist/untrack-DJVQQ2WM.js.map +0 -1
@@ -1,130 +1,144 @@
1
- /**
2
- * Computed reactive values.
3
- */
4
-
5
- import {
6
- clearDependencies,
7
- getCurrentObserver,
8
- registerDependency,
9
- scheduleObserver,
10
- track,
11
- withoutCurrentObserver,
12
- type ReactiveSource,
13
- } from './internals';
14
-
15
- /**
16
- * A computed value that derives from other reactive sources.
17
- *
18
- * Computed values are lazily evaluated and cached. They only
19
- * recompute when their dependencies change.
20
- *
21
- * @template T - The type of the computed value
22
- */
23
- export class Computed<T> implements ReactiveSource {
24
- private cachedValue!: T;
25
- private hasCachedValue = false;
26
- private dirty = true;
27
- private disposed = false;
28
- private subscribers = new Set<() => void>();
29
- private readonly markDirty = () => {
30
- if (this.disposed) {
31
- return;
32
- }
33
- this.dirty = true;
34
- // Create snapshot to avoid issues with subscribers modifying the set during iteration
35
- const subscribersSnapshot = Array.from(this.subscribers);
36
- for (const subscriber of subscribersSnapshot) {
37
- scheduleObserver(subscriber);
38
- }
39
- };
40
-
41
- /**
42
- * Creates a new computed value.
43
- * @param compute - Function that computes the value
44
- */
45
- constructor(private readonly compute: () => T) {}
46
-
47
- /**
48
- * Gets the computed value, recomputing if dependencies changed.
49
- * During untrack calls, getCurrentObserver returns undefined, preventing dependency tracking.
50
- */
51
- get value(): T {
52
- if (this.disposed) {
53
- if (!this.hasCachedValue) {
54
- this.cachedValue = withoutCurrentObserver(() => this.compute());
55
- this.hasCachedValue = true;
56
- }
57
- return this.cachedValue;
58
- }
59
-
60
- const current = getCurrentObserver();
61
- if (current) {
62
- this.subscribers.add(current);
63
- registerDependency(current, this);
64
- }
65
- if (this.dirty) {
66
- this.dirty = false;
67
- // Clear old dependencies before recomputing
68
- clearDependencies(this.markDirty);
69
- this.cachedValue = track(this.markDirty, this.compute);
70
- this.hasCachedValue = true;
71
- }
72
- return this.cachedValue;
73
- }
74
-
75
- /**
76
- * Reads the current computed value without tracking.
77
- * Useful when you need the value but don't want to create a dependency.
78
- *
79
- * @returns The current cached value (recomputes if dirty)
80
- */
81
- peek(): T {
82
- if (this.disposed) {
83
- if (!this.hasCachedValue) {
84
- this.cachedValue = withoutCurrentObserver(() => this.compute());
85
- this.hasCachedValue = true;
86
- }
87
- return this.cachedValue;
88
- }
89
-
90
- if (this.dirty) {
91
- this.dirty = false;
92
- // Clear old dependencies before recomputing
93
- clearDependencies(this.markDirty);
94
- this.cachedValue = track(this.markDirty, this.compute);
95
- this.hasCachedValue = true;
96
- }
97
- return this.cachedValue;
98
- }
99
-
100
- /**
101
- * Removes an observer from this computed's subscriber set.
102
- * @internal
103
- */
104
- unsubscribe(observer: () => void): void {
105
- this.subscribers.delete(observer);
106
- }
107
-
108
- /**
109
- * Disposes the computed value by unsubscribing its internal observer
110
- * from all upstream dependencies and clearing subscribers.
111
- */
112
- dispose(): void {
113
- this.disposed = true;
114
- if (this.dirty) {
115
- this.hasCachedValue = false;
116
- }
117
- this.dirty = false;
118
- clearDependencies(this.markDirty);
119
- this.subscribers.clear();
120
- }
121
- }
122
-
123
- /**
124
- * Creates a new computed value.
125
- *
126
- * @template T - The type of the computed value
127
- * @param fn - Function that computes the value from reactive sources
128
- * @returns A new Computed instance
129
- */
130
- export const computed = <T>(fn: () => T): Computed<T> => new Computed(fn);
1
+ /**
2
+ * Computed reactive values.
3
+ */
4
+
5
+ import {
6
+ clearDependencies,
7
+ getCurrentObserver,
8
+ registerDependency,
9
+ scheduleObserver,
10
+ track,
11
+ withoutCurrentObserver,
12
+ type ReactiveSource,
13
+ } from './internals';
14
+ import { getActiveScope, hasScopeDisposer } from './scope';
15
+
16
+ /**
17
+ * A computed value that derives from other reactive sources.
18
+ *
19
+ * Computed values are lazily evaluated and cached. They only
20
+ * recompute when their dependencies change.
21
+ *
22
+ * @template T - The type of the computed value
23
+ */
24
+ export class Computed<T> implements ReactiveSource {
25
+ private cachedValue!: T;
26
+ private hasCachedValue = false;
27
+ private dirty = true;
28
+ private disposed = false;
29
+ private subscribers = new Set<() => void>();
30
+ private readonly markDirty = () => {
31
+ if (this.disposed) {
32
+ return;
33
+ }
34
+ this.dirty = true;
35
+ // Create snapshot to avoid issues with subscribers modifying the set during iteration
36
+ const subscribersSnapshot = Array.from(this.subscribers);
37
+ for (const subscriber of subscribersSnapshot) {
38
+ scheduleObserver(subscriber);
39
+ }
40
+ };
41
+
42
+ /**
43
+ * Creates a new computed value.
44
+ * @param compute - Function that computes the value
45
+ */
46
+ constructor(private readonly compute: () => T) {}
47
+
48
+ /**
49
+ * Gets the computed value, recomputing if dependencies changed.
50
+ * During untrack calls, getCurrentObserver returns undefined, preventing dependency tracking.
51
+ */
52
+ get value(): T {
53
+ if (this.disposed) {
54
+ if (!this.hasCachedValue) {
55
+ this.cachedValue = withoutCurrentObserver(() => this.compute());
56
+ this.hasCachedValue = true;
57
+ }
58
+ return this.cachedValue;
59
+ }
60
+
61
+ const current = getCurrentObserver();
62
+ if (current) {
63
+ this.subscribers.add(current);
64
+ registerDependency(current, this);
65
+ }
66
+ if (this.dirty) {
67
+ this.dirty = false;
68
+ // Clear old dependencies before recomputing
69
+ clearDependencies(this.markDirty);
70
+ this.cachedValue = track(this.markDirty, this.compute);
71
+ this.hasCachedValue = true;
72
+ }
73
+ return this.cachedValue;
74
+ }
75
+
76
+ /**
77
+ * Reads the current computed value without tracking.
78
+ * Useful when you need the value but don't want to create a dependency.
79
+ *
80
+ * @returns The current cached value (recomputes if dirty)
81
+ */
82
+ peek(): T {
83
+ if (this.disposed) {
84
+ if (!this.hasCachedValue) {
85
+ this.cachedValue = withoutCurrentObserver(() => this.compute());
86
+ this.hasCachedValue = true;
87
+ }
88
+ return this.cachedValue;
89
+ }
90
+
91
+ if (this.dirty) {
92
+ this.dirty = false;
93
+ // Clear old dependencies before recomputing
94
+ clearDependencies(this.markDirty);
95
+ this.cachedValue = track(this.markDirty, this.compute);
96
+ this.hasCachedValue = true;
97
+ }
98
+ return this.cachedValue;
99
+ }
100
+
101
+ /**
102
+ * Removes an observer from this computed's subscriber set.
103
+ * @internal
104
+ */
105
+ unsubscribe(observer: () => void): void {
106
+ this.subscribers.delete(observer);
107
+ }
108
+
109
+ /**
110
+ * Disposes the computed value by unsubscribing its internal observer
111
+ * from all upstream dependencies and clearing subscribers.
112
+ */
113
+ dispose(): void {
114
+ this.disposed = true;
115
+ if (this.dirty) {
116
+ this.hasCachedValue = false;
117
+ }
118
+ this.dirty = false;
119
+ clearDependencies(this.markDirty);
120
+ this.subscribers.clear();
121
+ }
122
+ }
123
+
124
+ /**
125
+ * Creates a new computed value.
126
+ *
127
+ * If created inside an {@link effectScope}, the computed value is automatically
128
+ * collected and will be disposed when the scope stops.
129
+ *
130
+ * @template T - The type of the computed value
131
+ * @param fn - Function that computes the value from reactive sources
132
+ * @returns A new Computed instance
133
+ */
134
+ export const computed = <T>(fn: () => T): Computed<T> => {
135
+ const c = new Computed(fn);
136
+
137
+ // Auto-register with the current scope so scope.stop() disposes this computed
138
+ const scope = getActiveScope();
139
+ if (hasScopeDisposer(scope)) {
140
+ scope._addDisposer(() => c.dispose());
141
+ }
142
+
143
+ return c;
144
+ };
@@ -3,6 +3,7 @@
3
3
  */
4
4
 
5
5
  import { CleanupFn, Observer, track, clearDependencies } from './internals';
6
+ import { getActiveScope, hasScopeDisposer } from './scope';
6
7
 
7
8
  /**
8
9
  * Creates a side effect that automatically re-runs when dependencies change.
@@ -10,12 +11,16 @@ import { CleanupFn, Observer, track, clearDependencies } from './internals';
10
11
  * The effect runs immediately upon creation and then re-runs whenever
11
12
  * any signal or computed value read inside it changes.
12
13
  *
14
+ * If created inside an {@link effectScope}, the effect is automatically
15
+ * collected and will be disposed when the scope stops.
16
+ *
13
17
  * @param fn - The effect function to run
14
18
  * @returns A cleanup function to stop the effect
15
19
  */
16
20
  export const effect = (fn: () => void | CleanupFn): CleanupFn => {
17
21
  let cleanupFn: CleanupFn | void;
18
22
  let isDisposed = false;
23
+ const scope = getActiveScope();
19
24
 
20
25
  const runCleanup = (): void => {
21
26
  if (cleanupFn) {
@@ -28,6 +33,25 @@ export const effect = (fn: () => void | CleanupFn): CleanupFn => {
28
33
  }
29
34
  };
30
35
 
36
+ const clearEffectState = (): void => {
37
+ runCleanup();
38
+ // Clean up all dependencies when effect is disposed
39
+ clearDependencies(observer);
40
+ };
41
+
42
+ const dispose: CleanupFn = () => {
43
+ if (isDisposed) {
44
+ return;
45
+ }
46
+
47
+ isDisposed = true;
48
+ clearEffectState();
49
+ };
50
+
51
+ if (hasScopeDisposer(scope)) {
52
+ scope._addDisposer(dispose);
53
+ }
54
+
31
55
  const observer: Observer = () => {
32
56
  if (isDisposed) return;
33
57
 
@@ -41,14 +65,13 @@ export const effect = (fn: () => void | CleanupFn): CleanupFn => {
41
65
  } catch (error) {
42
66
  console.error('bQuery reactive: Error in effect', error);
43
67
  }
68
+
69
+ if (isDisposed) {
70
+ clearEffectState();
71
+ }
44
72
  };
45
73
 
46
74
  observer();
47
75
 
48
- return () => {
49
- isDisposed = true;
50
- runCleanup();
51
- // Clean up all dependencies when effect is disposed
52
- clearDependencies(observer);
53
- };
76
+ return dispose;
54
77
  };