mutts 1.0.6 → 1.0.8

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 (196) hide show
  1. package/README.md +61 -23
  2. package/dist/async/browser.d.ts +2 -0
  3. package/dist/async/browser.d.ts.map +1 -0
  4. package/dist/async/index.d.ts +18 -0
  5. package/dist/async/index.d.ts.map +1 -0
  6. package/dist/async/node.d.ts +2 -0
  7. package/dist/async/node.d.ts.map +1 -0
  8. package/dist/{chunks/index-CDCOjzTy.js → browser.cjs} +5913 -4382
  9. package/dist/browser.cjs.map +1 -0
  10. package/dist/browser.d.ts +1655 -0
  11. package/dist/browser.esm.js +305 -0
  12. package/dist/browser.esm.js.map +1 -0
  13. package/dist/chunks/async-browser-CA0jPWIi.cjs +304 -0
  14. package/dist/chunks/async-browser-CA0jPWIi.cjs.map +1 -0
  15. package/dist/chunks/async-core-UqHzvJ-S.cjs +25 -0
  16. package/dist/chunks/async-core-UqHzvJ-S.cjs.map +1 -0
  17. package/dist/chunks/async-node-BYHuGTni.cjs +103 -0
  18. package/dist/chunks/async-node-BYHuGTni.cjs.map +1 -0
  19. package/dist/chunks/{index-DiP0RXoZ.esm.js → index-DhaOVusv.esm.js} +5851 -4345
  20. package/dist/chunks/index-DhaOVusv.esm.js.map +1 -0
  21. package/dist/decorator.d.ts +17 -18
  22. package/dist/decorator.d.ts.map +1 -0
  23. package/dist/destroyable.d.ts +12 -15
  24. package/dist/destroyable.d.ts.map +1 -0
  25. package/dist/devtools/devtool/devtools.d.ts +1 -0
  26. package/dist/devtools/devtool/devtools.d.ts.map +1 -0
  27. package/dist/devtools/devtool/panel.d.ts +2 -0
  28. package/dist/devtools/devtool/panel.d.ts.map +1 -0
  29. package/dist/devtools/panel.js.map +1 -1
  30. package/dist/entry-browser.d.ts +3 -0
  31. package/dist/entry-browser.d.ts.map +1 -0
  32. package/dist/entry-node.d.ts +3 -0
  33. package/dist/entry-node.d.ts.map +1 -0
  34. package/dist/eventful.d.ts +3 -5
  35. package/dist/eventful.d.ts.map +1 -0
  36. package/dist/index.d.ts +13 -19
  37. package/dist/index.d.ts.map +1 -0
  38. package/dist/indexable.d.ts +10 -10
  39. package/dist/indexable.d.ts.map +1 -0
  40. package/dist/introspection.d.ts +27 -0
  41. package/dist/introspection.d.ts.map +1 -0
  42. package/dist/iterableWeak.d.ts +53 -0
  43. package/dist/iterableWeak.d.ts.map +1 -0
  44. package/dist/mixins.d.ts +25 -0
  45. package/dist/mixins.d.ts.map +1 -0
  46. package/dist/mutts.umd.js +1 -1
  47. package/dist/mutts.umd.js.map +1 -1
  48. package/dist/mutts.umd.min.js +1 -1
  49. package/dist/mutts.umd.min.js.map +1 -1
  50. package/dist/node.cjs +105 -0
  51. package/dist/node.cjs.map +1 -0
  52. package/dist/node.d.ts +1 -0
  53. package/dist/node.esm.js +104 -0
  54. package/dist/node.esm.js.map +1 -0
  55. package/dist/promiseChain.d.ts +4 -5
  56. package/dist/promiseChain.d.ts.map +1 -0
  57. package/dist/reactive/array.d.ts +49 -0
  58. package/dist/reactive/array.d.ts.map +1 -0
  59. package/dist/reactive/buffer.d.ts +44 -0
  60. package/dist/reactive/buffer.d.ts.map +1 -0
  61. package/dist/reactive/change.d.ts +29 -0
  62. package/dist/reactive/change.d.ts.map +1 -0
  63. package/dist/reactive/debug.d.ts +111 -0
  64. package/dist/reactive/debug.d.ts.map +1 -0
  65. package/dist/reactive/deep-touch.d.ts +28 -0
  66. package/dist/reactive/deep-touch.d.ts.map +1 -0
  67. package/dist/reactive/deep-watch-state.d.ts +25 -0
  68. package/dist/reactive/deep-watch-state.d.ts.map +1 -0
  69. package/dist/reactive/deep-watch.d.ts +19 -0
  70. package/dist/reactive/deep-watch.d.ts.map +1 -0
  71. package/dist/reactive/effect-context.d.ts +7 -0
  72. package/dist/reactive/effect-context.d.ts.map +1 -0
  73. package/dist/reactive/effects.d.ts +151 -0
  74. package/dist/reactive/effects.d.ts.map +1 -0
  75. package/dist/reactive/index.d.ts +20 -0
  76. package/dist/reactive/index.d.ts.map +1 -0
  77. package/dist/reactive/interface.d.ts +64 -0
  78. package/dist/reactive/interface.d.ts.map +1 -0
  79. package/dist/reactive/map.d.ts +30 -0
  80. package/dist/reactive/map.d.ts.map +1 -0
  81. package/dist/reactive/memoize.d.ts +5 -0
  82. package/dist/reactive/memoize.d.ts.map +1 -0
  83. package/dist/reactive/non-reactive-state.d.ts +9 -0
  84. package/dist/reactive/non-reactive-state.d.ts.map +1 -0
  85. package/dist/reactive/non-reactive.d.ts +11 -0
  86. package/dist/reactive/non-reactive.d.ts.map +1 -0
  87. package/dist/reactive/project.d.ts +41 -0
  88. package/dist/reactive/project.d.ts.map +1 -0
  89. package/dist/reactive/proxy-state.d.ts +8 -0
  90. package/dist/reactive/proxy-state.d.ts.map +1 -0
  91. package/dist/reactive/proxy.d.ts +23 -0
  92. package/dist/reactive/proxy.d.ts.map +1 -0
  93. package/dist/reactive/record.d.ts +116 -0
  94. package/dist/reactive/record.d.ts.map +1 -0
  95. package/dist/reactive/register.d.ts +64 -0
  96. package/dist/reactive/register.d.ts.map +1 -0
  97. package/dist/reactive/registry.d.ts +20 -0
  98. package/dist/reactive/registry.d.ts.map +1 -0
  99. package/dist/reactive/set.d.ts +28 -0
  100. package/dist/reactive/set.d.ts.map +1 -0
  101. package/dist/reactive/tracking.d.ts +7 -0
  102. package/dist/reactive/tracking.d.ts.map +1 -0
  103. package/dist/reactive/types.d.ts +376 -0
  104. package/dist/reactive/types.d.ts.map +1 -0
  105. package/dist/std-decorators.d.ts +9 -11
  106. package/dist/std-decorators.d.ts.map +1 -0
  107. package/dist/utils.d.ts +49 -0
  108. package/dist/utils.d.ts.map +1 -0
  109. package/dist/zone.d.ts +40 -0
  110. package/dist/zone.d.ts.map +1 -0
  111. package/docs/ai/api-reference.md +0 -2
  112. package/docs/reactive/advanced.md +2 -5
  113. package/docs/reactive/collections.md +0 -125
  114. package/docs/reactive/core.md +27 -24
  115. package/docs/reactive/debugging.md +12 -2
  116. package/docs/reactive/project.md +1 -1
  117. package/docs/reactive/scan.md +78 -0
  118. package/docs/reactive.md +2 -1
  119. package/docs/std-decorators.md +69 -0
  120. package/docs/zone.md +95 -0
  121. package/package.json +67 -23
  122. package/src/async/browser.ts +319 -0
  123. package/src/async/index.ts +23 -0
  124. package/src/async/node.ts +104 -0
  125. package/src/decorator.ts +5 -1
  126. package/src/destroyable.ts +1 -1
  127. package/src/entry-browser.ts +5 -0
  128. package/src/entry-node.ts +5 -0
  129. package/src/index.d.ts +12 -9
  130. package/src/index.ts +23 -14
  131. package/src/indexable.ts +42 -0
  132. package/src/mixins.ts +2 -2
  133. package/src/reactive/array.ts +274 -179
  134. package/src/reactive/buffer.ts +168 -0
  135. package/src/reactive/change.ts +2 -2
  136. package/src/reactive/effect-context.ts +15 -91
  137. package/src/reactive/effects.ts +119 -179
  138. package/src/reactive/index.ts +11 -13
  139. package/src/reactive/interface.ts +19 -33
  140. package/src/reactive/map.ts +49 -62
  141. package/src/reactive/memoize.ts +19 -9
  142. package/src/reactive/project.ts +43 -22
  143. package/src/reactive/proxy.ts +16 -41
  144. package/src/reactive/record.ts +3 -3
  145. package/src/reactive/register.ts +5 -7
  146. package/src/reactive/registry.ts +9 -17
  147. package/src/reactive/set.ts +43 -57
  148. package/src/reactive/tracking.ts +1 -29
  149. package/src/reactive/types.ts +46 -23
  150. package/src/utils.ts +80 -37
  151. package/src/zone.ts +138 -0
  152. package/dist/chunks/_tslib-BgjropY9.js +0 -81
  153. package/dist/chunks/_tslib-BgjropY9.js.map +0 -1
  154. package/dist/chunks/_tslib-MCKDzsSq.esm.js +0 -75
  155. package/dist/chunks/_tslib-MCKDzsSq.esm.js.map +0 -1
  156. package/dist/chunks/decorator-BGILvPtN.esm.js +0 -627
  157. package/dist/chunks/decorator-BGILvPtN.esm.js.map +0 -1
  158. package/dist/chunks/decorator-BQ2eBTCj.js +0 -651
  159. package/dist/chunks/decorator-BQ2eBTCj.js.map +0 -1
  160. package/dist/chunks/index-CDCOjzTy.js.map +0 -1
  161. package/dist/chunks/index-DiP0RXoZ.esm.js.map +0 -1
  162. package/dist/decorator.esm.js +0 -2
  163. package/dist/decorator.esm.js.map +0 -1
  164. package/dist/decorator.js +0 -11
  165. package/dist/decorator.js.map +0 -1
  166. package/dist/destroyable.esm.js +0 -109
  167. package/dist/destroyable.esm.js.map +0 -1
  168. package/dist/destroyable.js +0 -116
  169. package/dist/destroyable.js.map +0 -1
  170. package/dist/eventful.esm.js +0 -66
  171. package/dist/eventful.esm.js.map +0 -1
  172. package/dist/eventful.js +0 -68
  173. package/dist/eventful.js.map +0 -1
  174. package/dist/index.esm.js +0 -53
  175. package/dist/index.esm.js.map +0 -1
  176. package/dist/index.js +0 -139
  177. package/dist/index.js.map +0 -1
  178. package/dist/indexable.esm.js +0 -285
  179. package/dist/indexable.esm.js.map +0 -1
  180. package/dist/indexable.js +0 -291
  181. package/dist/indexable.js.map +0 -1
  182. package/dist/promiseChain.esm.js +0 -78
  183. package/dist/promiseChain.esm.js.map +0 -1
  184. package/dist/promiseChain.js +0 -80
  185. package/dist/promiseChain.js.map +0 -1
  186. package/dist/reactive.d.ts +0 -910
  187. package/dist/reactive.esm.js +0 -5
  188. package/dist/reactive.esm.js.map +0 -1
  189. package/dist/reactive.js +0 -59
  190. package/dist/reactive.js.map +0 -1
  191. package/dist/std-decorators.esm.js +0 -196
  192. package/dist/std-decorators.esm.js.map +0 -1
  193. package/dist/std-decorators.js +0 -204
  194. package/dist/std-decorators.js.map +0 -1
  195. package/src/reactive/mapped.ts +0 -129
  196. package/src/reactive/zone.ts +0 -208
@@ -1,208 +0,0 @@
1
- /**
2
- * Zone-like async context preservation for reactive effects
3
- *
4
- * Automatically preserves effect context across async boundaries:
5
- * - Promise methods: .then(), .catch(), .finally()
6
- * - Timers: setTimeout(), setInterval()
7
- * - Animation: requestAnimationFrame() (if available) - runs in untracked context
8
- * - Microtasks: queueMicrotask() (if available)
9
- *
10
- * **IMPORTANT:** This module is opt-in via `reactiveOptions.asyncMode` (truthy = enabled, false = disabled).
11
- * By default, async zone is ENABLED with 'cancel' mode.
12
- *
13
- * When disabled (asyncMode = false), use `tracked()` manually in async callbacks.
14
- * When enabled (asyncMode = 'cancel' | 'queue' | 'ignore'), async entry points are wrapped ONCE.
15
- */
16
-
17
- import { captureEffectStack, withEffectStack } from './effect-context'
18
- import { options, type ScopedCallback } from './types'
19
-
20
- let zoneHooked = false
21
-
22
- // Store original Promise methods at module load time (before any wrapping)
23
- // This ensures we always have the true originals, even if wrapping happens multiple times
24
- const originalPromiseThen =
25
- Object.getOwnPropertyDescriptor(Promise.prototype, 'then')?.value || Promise.prototype.then
26
- const originalPromiseCatch =
27
- Object.getOwnPropertyDescriptor(Promise.prototype, 'catch')?.value || Promise.prototype.catch
28
- const originalPromiseFinally =
29
- Object.getOwnPropertyDescriptor(Promise.prototype, 'finally')?.value || Promise.prototype.finally
30
-
31
- // Store original timer functions at module load time
32
- const originalSetTimeout = globalThis.setTimeout
33
- const originalSetInterval = globalThis.setInterval
34
- const originalRequestAnimationFrame =
35
- typeof globalThis.requestAnimationFrame !== 'undefined'
36
- ? globalThis.requestAnimationFrame
37
- : undefined
38
- const originalQueueMicrotask =
39
- typeof globalThis.queueMicrotask !== 'undefined' ? globalThis.queueMicrotask : undefined
40
-
41
- // Store batch function to avoid circular dependency
42
- let batchFn: ((cb: () => any, type: 'immediate') => any) | undefined
43
-
44
- /**
45
- * Check the asyncMode option and hook Promise.prototype once if enabled
46
- * Called lazily on first effect creation
47
- * asyncMode being truthy enables async zone, false disables it
48
- *
49
- * @param batch - Optional batch function injection from effects.ts to avoid circular dependency
50
- */
51
- export function ensureZoneHooked(batch?: (cb: () => any, type: 'immediate') => any) {
52
- if (batch) batchFn = batch
53
- if (zoneHooked || !options.asyncMode) return
54
- hookZone()
55
- zoneHooked = true
56
- }
57
-
58
- /**
59
- * Hook Promise.prototype methods to preserve effect context
60
- */
61
- function hookZone() {
62
- // biome-ignore lint/suspicious/noThenProperty: Intentional wrapping for zone functionality
63
- Promise.prototype.then = function <T, R1, R2>(
64
- this: Promise<T>,
65
- onFulfilled?: ((value: T) => R1 | PromiseLike<R1>) | null,
66
- onRejected?: ((reason: any) => R2 | PromiseLike<R2>) | null
67
- ): Promise<R1 | R2> {
68
- const capturedStack = captureEffectStack()
69
- return originalPromiseThen.call(
70
- this,
71
- wrapCallback(onFulfilled, capturedStack),
72
- wrapCallback(onRejected, capturedStack)
73
- )
74
- }
75
-
76
- Promise.prototype.catch = function <T>(
77
- this: Promise<T>,
78
- onRejected?: ((reason: any) => T | PromiseLike<T>) | null
79
- ): Promise<T> {
80
- const capturedStack = captureEffectStack()
81
- return originalPromiseCatch.call(this, wrapCallback(onRejected, capturedStack))
82
- }
83
-
84
- Promise.prototype.finally = function <T>(
85
- this: Promise<T>,
86
- onFinally?: (() => void) | null
87
- ): Promise<T> {
88
- const capturedStack = captureEffectStack()
89
- return originalPromiseFinally.call(this, wrapCallback(onFinally, capturedStack))
90
- }
91
-
92
- // Hook setTimeout - preserve original function properties for Node.js compatibility
93
- const wrappedSetTimeout = (<TArgs extends any[]>(
94
- callback: (...args: TArgs) => void,
95
- delay?: number,
96
- ...args: TArgs
97
- ): ReturnType<typeof originalSetTimeout> => {
98
- const capturedStack = options.zones.setTimeout ? captureEffectStack() : undefined
99
- return originalSetTimeout.apply(globalThis, [
100
- wrapCallback(callback, capturedStack) as (...args: any[]) => void,
101
- delay,
102
- ...args,
103
- ] as any)
104
- }) as typeof originalSetTimeout
105
- Object.assign(wrappedSetTimeout, originalSetTimeout)
106
- globalThis.setTimeout = wrappedSetTimeout
107
-
108
- // Hook setInterval - preserve original function properties for Node.js compatibility
109
- const wrappedSetInterval = (<TArgs extends any[]>(
110
- callback: (...args: TArgs) => void,
111
- delay?: number,
112
- ...args: TArgs
113
- ): ReturnType<typeof originalSetInterval> => {
114
- const capturedStack = options.zones.setInterval ? captureEffectStack() : undefined
115
- return originalSetInterval.apply(globalThis, [
116
- wrapCallback(callback, capturedStack) as (...args: any[]) => void,
117
- delay,
118
- ...args,
119
- ] as any)
120
- }) as typeof originalSetInterval
121
- Object.assign(wrappedSetInterval, originalSetInterval)
122
- globalThis.setInterval = wrappedSetInterval
123
-
124
- // Hook requestAnimationFrame if available
125
- if (originalRequestAnimationFrame) {
126
- globalThis.requestAnimationFrame = ((
127
- callback: FrameRequestCallback
128
- ): ReturnType<typeof originalRequestAnimationFrame> => {
129
- const capturedStack = options.zones.requestAnimationFrame ? captureEffectStack() : undefined
130
- return originalRequestAnimationFrame.call(
131
- globalThis,
132
- wrapCallback(callback as any, capturedStack) as FrameRequestCallback
133
- )
134
- }) as typeof originalRequestAnimationFrame
135
- }
136
-
137
- // Hook queueMicrotask if available
138
- if (originalQueueMicrotask) {
139
- globalThis.queueMicrotask = ((callback: () => void): void => {
140
- const capturedStack = options.zones.queueMicrotask ? captureEffectStack() : undefined
141
- originalQueueMicrotask.call(globalThis, wrapCallback(callback, capturedStack) as () => void)
142
- }) as typeof originalQueueMicrotask
143
- }
144
- }
145
-
146
- /**
147
- * Wraps a callback to restore effect context and ensure batching
148
- */
149
- function wrapCallback<T extends (...args: any[]) => any>(
150
- callback: T | null | undefined,
151
- capturedStack: (ScopedCallback | undefined)[] | undefined
152
- ): T | undefined {
153
- if (!callback) return undefined
154
-
155
- // If no stack to restore and no batch function, direct call (optimization)
156
- if ((!capturedStack || !capturedStack.length) && !batchFn) {
157
- return callback
158
- }
159
-
160
- return ((...args: any[]) => {
161
- const execute = () => {
162
- if (capturedStack?.length) {
163
- return withEffectStack(capturedStack, () => callback(...args))
164
- }
165
- return callback(...args)
166
- }
167
-
168
- if (batchFn) {
169
- return batchFn(execute, 'immediate')
170
- }
171
- return execute()
172
- }) as T
173
- }
174
-
175
- /**
176
- * Manually enable/disable the zone (for testing)
177
- */
178
- export function setZoneEnabled(enabled: boolean) {
179
- if (enabled && !zoneHooked) {
180
- hookZone()
181
- zoneHooked = true
182
- } else if (!enabled && zoneHooked) {
183
- // Restore original Promise methods
184
- // biome-ignore lint/suspicious/noThenProperty: Restoring original methods
185
- Promise.prototype.then = originalPromiseThen
186
- Promise.prototype.catch = originalPromiseCatch
187
- Promise.prototype.finally = originalPromiseFinally
188
-
189
- // Restore original timer functions
190
- globalThis.setTimeout = originalSetTimeout
191
- globalThis.setInterval = originalSetInterval
192
- if (originalRequestAnimationFrame) {
193
- globalThis.requestAnimationFrame = originalRequestAnimationFrame
194
- }
195
- if (originalQueueMicrotask) {
196
- globalThis.queueMicrotask = originalQueueMicrotask
197
- }
198
-
199
- zoneHooked = false
200
- }
201
- }
202
-
203
- /**
204
- * Check if zone is currently hooked
205
- */
206
- export function isZoneEnabled(): boolean {
207
- return zoneHooked
208
- }