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.
- package/README.md +61 -23
- package/dist/async/browser.d.ts +2 -0
- package/dist/async/browser.d.ts.map +1 -0
- package/dist/async/index.d.ts +18 -0
- package/dist/async/index.d.ts.map +1 -0
- package/dist/async/node.d.ts +2 -0
- package/dist/async/node.d.ts.map +1 -0
- package/dist/{chunks/index-CDCOjzTy.js → browser.cjs} +5913 -4382
- package/dist/browser.cjs.map +1 -0
- package/dist/browser.d.ts +1655 -0
- package/dist/browser.esm.js +305 -0
- package/dist/browser.esm.js.map +1 -0
- package/dist/chunks/async-browser-CA0jPWIi.cjs +304 -0
- package/dist/chunks/async-browser-CA0jPWIi.cjs.map +1 -0
- package/dist/chunks/async-core-UqHzvJ-S.cjs +25 -0
- package/dist/chunks/async-core-UqHzvJ-S.cjs.map +1 -0
- package/dist/chunks/async-node-BYHuGTni.cjs +103 -0
- package/dist/chunks/async-node-BYHuGTni.cjs.map +1 -0
- package/dist/chunks/{index-DiP0RXoZ.esm.js → index-DhaOVusv.esm.js} +5851 -4345
- package/dist/chunks/index-DhaOVusv.esm.js.map +1 -0
- package/dist/decorator.d.ts +17 -18
- package/dist/decorator.d.ts.map +1 -0
- package/dist/destroyable.d.ts +12 -15
- package/dist/destroyable.d.ts.map +1 -0
- package/dist/devtools/devtool/devtools.d.ts +1 -0
- package/dist/devtools/devtool/devtools.d.ts.map +1 -0
- package/dist/devtools/devtool/panel.d.ts +2 -0
- package/dist/devtools/devtool/panel.d.ts.map +1 -0
- package/dist/devtools/panel.js.map +1 -1
- package/dist/entry-browser.d.ts +3 -0
- package/dist/entry-browser.d.ts.map +1 -0
- package/dist/entry-node.d.ts +3 -0
- package/dist/entry-node.d.ts.map +1 -0
- package/dist/eventful.d.ts +3 -5
- package/dist/eventful.d.ts.map +1 -0
- package/dist/index.d.ts +13 -19
- package/dist/index.d.ts.map +1 -0
- package/dist/indexable.d.ts +10 -10
- package/dist/indexable.d.ts.map +1 -0
- package/dist/introspection.d.ts +27 -0
- package/dist/introspection.d.ts.map +1 -0
- package/dist/iterableWeak.d.ts +53 -0
- package/dist/iterableWeak.d.ts.map +1 -0
- package/dist/mixins.d.ts +25 -0
- package/dist/mixins.d.ts.map +1 -0
- package/dist/mutts.umd.js +1 -1
- package/dist/mutts.umd.js.map +1 -1
- package/dist/mutts.umd.min.js +1 -1
- package/dist/mutts.umd.min.js.map +1 -1
- package/dist/node.cjs +105 -0
- package/dist/node.cjs.map +1 -0
- package/dist/node.d.ts +1 -0
- package/dist/node.esm.js +104 -0
- package/dist/node.esm.js.map +1 -0
- package/dist/promiseChain.d.ts +4 -5
- package/dist/promiseChain.d.ts.map +1 -0
- package/dist/reactive/array.d.ts +49 -0
- package/dist/reactive/array.d.ts.map +1 -0
- package/dist/reactive/buffer.d.ts +44 -0
- package/dist/reactive/buffer.d.ts.map +1 -0
- package/dist/reactive/change.d.ts +29 -0
- package/dist/reactive/change.d.ts.map +1 -0
- package/dist/reactive/debug.d.ts +111 -0
- package/dist/reactive/debug.d.ts.map +1 -0
- package/dist/reactive/deep-touch.d.ts +28 -0
- package/dist/reactive/deep-touch.d.ts.map +1 -0
- package/dist/reactive/deep-watch-state.d.ts +25 -0
- package/dist/reactive/deep-watch-state.d.ts.map +1 -0
- package/dist/reactive/deep-watch.d.ts +19 -0
- package/dist/reactive/deep-watch.d.ts.map +1 -0
- package/dist/reactive/effect-context.d.ts +7 -0
- package/dist/reactive/effect-context.d.ts.map +1 -0
- package/dist/reactive/effects.d.ts +151 -0
- package/dist/reactive/effects.d.ts.map +1 -0
- package/dist/reactive/index.d.ts +20 -0
- package/dist/reactive/index.d.ts.map +1 -0
- package/dist/reactive/interface.d.ts +64 -0
- package/dist/reactive/interface.d.ts.map +1 -0
- package/dist/reactive/map.d.ts +30 -0
- package/dist/reactive/map.d.ts.map +1 -0
- package/dist/reactive/memoize.d.ts +5 -0
- package/dist/reactive/memoize.d.ts.map +1 -0
- package/dist/reactive/non-reactive-state.d.ts +9 -0
- package/dist/reactive/non-reactive-state.d.ts.map +1 -0
- package/dist/reactive/non-reactive.d.ts +11 -0
- package/dist/reactive/non-reactive.d.ts.map +1 -0
- package/dist/reactive/project.d.ts +41 -0
- package/dist/reactive/project.d.ts.map +1 -0
- package/dist/reactive/proxy-state.d.ts +8 -0
- package/dist/reactive/proxy-state.d.ts.map +1 -0
- package/dist/reactive/proxy.d.ts +23 -0
- package/dist/reactive/proxy.d.ts.map +1 -0
- package/dist/reactive/record.d.ts +116 -0
- package/dist/reactive/record.d.ts.map +1 -0
- package/dist/reactive/register.d.ts +64 -0
- package/dist/reactive/register.d.ts.map +1 -0
- package/dist/reactive/registry.d.ts +20 -0
- package/dist/reactive/registry.d.ts.map +1 -0
- package/dist/reactive/set.d.ts +28 -0
- package/dist/reactive/set.d.ts.map +1 -0
- package/dist/reactive/tracking.d.ts +7 -0
- package/dist/reactive/tracking.d.ts.map +1 -0
- package/dist/reactive/types.d.ts +376 -0
- package/dist/reactive/types.d.ts.map +1 -0
- package/dist/std-decorators.d.ts +9 -11
- package/dist/std-decorators.d.ts.map +1 -0
- package/dist/utils.d.ts +49 -0
- package/dist/utils.d.ts.map +1 -0
- package/dist/zone.d.ts +40 -0
- package/dist/zone.d.ts.map +1 -0
- package/docs/ai/api-reference.md +0 -2
- package/docs/reactive/advanced.md +2 -5
- package/docs/reactive/collections.md +0 -125
- package/docs/reactive/core.md +27 -24
- package/docs/reactive/debugging.md +12 -2
- package/docs/reactive/project.md +1 -1
- package/docs/reactive/scan.md +78 -0
- package/docs/reactive.md +2 -1
- package/docs/std-decorators.md +69 -0
- package/docs/zone.md +95 -0
- package/package.json +67 -23
- package/src/async/browser.ts +319 -0
- package/src/async/index.ts +23 -0
- package/src/async/node.ts +104 -0
- package/src/decorator.ts +5 -1
- package/src/destroyable.ts +1 -1
- package/src/entry-browser.ts +5 -0
- package/src/entry-node.ts +5 -0
- package/src/index.d.ts +12 -9
- package/src/index.ts +23 -14
- package/src/indexable.ts +42 -0
- package/src/mixins.ts +2 -2
- package/src/reactive/array.ts +274 -179
- package/src/reactive/buffer.ts +168 -0
- package/src/reactive/change.ts +2 -2
- package/src/reactive/effect-context.ts +15 -91
- package/src/reactive/effects.ts +119 -179
- package/src/reactive/index.ts +11 -13
- package/src/reactive/interface.ts +19 -33
- package/src/reactive/map.ts +49 -62
- package/src/reactive/memoize.ts +19 -9
- package/src/reactive/project.ts +43 -22
- package/src/reactive/proxy.ts +16 -41
- package/src/reactive/record.ts +3 -3
- package/src/reactive/register.ts +5 -7
- package/src/reactive/registry.ts +9 -17
- package/src/reactive/set.ts +43 -57
- package/src/reactive/tracking.ts +1 -29
- package/src/reactive/types.ts +46 -23
- package/src/utils.ts +80 -37
- package/src/zone.ts +138 -0
- package/dist/chunks/_tslib-BgjropY9.js +0 -81
- package/dist/chunks/_tslib-BgjropY9.js.map +0 -1
- package/dist/chunks/_tslib-MCKDzsSq.esm.js +0 -75
- package/dist/chunks/_tslib-MCKDzsSq.esm.js.map +0 -1
- package/dist/chunks/decorator-BGILvPtN.esm.js +0 -627
- package/dist/chunks/decorator-BGILvPtN.esm.js.map +0 -1
- package/dist/chunks/decorator-BQ2eBTCj.js +0 -651
- package/dist/chunks/decorator-BQ2eBTCj.js.map +0 -1
- package/dist/chunks/index-CDCOjzTy.js.map +0 -1
- package/dist/chunks/index-DiP0RXoZ.esm.js.map +0 -1
- package/dist/decorator.esm.js +0 -2
- package/dist/decorator.esm.js.map +0 -1
- package/dist/decorator.js +0 -11
- package/dist/decorator.js.map +0 -1
- package/dist/destroyable.esm.js +0 -109
- package/dist/destroyable.esm.js.map +0 -1
- package/dist/destroyable.js +0 -116
- package/dist/destroyable.js.map +0 -1
- package/dist/eventful.esm.js +0 -66
- package/dist/eventful.esm.js.map +0 -1
- package/dist/eventful.js +0 -68
- package/dist/eventful.js.map +0 -1
- package/dist/index.esm.js +0 -53
- package/dist/index.esm.js.map +0 -1
- package/dist/index.js +0 -139
- package/dist/index.js.map +0 -1
- package/dist/indexable.esm.js +0 -285
- package/dist/indexable.esm.js.map +0 -1
- package/dist/indexable.js +0 -291
- package/dist/indexable.js.map +0 -1
- package/dist/promiseChain.esm.js +0 -78
- package/dist/promiseChain.esm.js.map +0 -1
- package/dist/promiseChain.js +0 -80
- package/dist/promiseChain.js.map +0 -1
- package/dist/reactive.d.ts +0 -910
- package/dist/reactive.esm.js +0 -5
- package/dist/reactive.esm.js.map +0 -1
- package/dist/reactive.js +0 -59
- package/dist/reactive.js.map +0 -1
- package/dist/std-decorators.esm.js +0 -196
- package/dist/std-decorators.esm.js.map +0 -1
- package/dist/std-decorators.js +0 -204
- package/dist/std-decorators.js.map +0 -1
- package/src/reactive/mapped.ts +0 -129
- package/src/reactive/zone.ts +0 -208
package/src/reactive/zone.ts
DELETED
|
@@ -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
|
-
}
|