mutts 1.0.0 → 1.0.1
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/dist/chunks/{decorator-BXsign4Z.js → decorator-8qjFb7dw.js} +2 -2
- package/dist/chunks/decorator-8qjFb7dw.js.map +1 -0
- package/dist/chunks/{decorator-CPbZNnsX.esm.js → decorator-AbRkXM5O.esm.js} +2 -2
- package/dist/chunks/decorator-AbRkXM5O.esm.js.map +1 -0
- package/dist/decorator.d.ts +1 -1
- package/dist/decorator.esm.js +1 -1
- package/dist/decorator.js +1 -1
- package/dist/destroyable.esm.js +1 -1
- package/dist/destroyable.js +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.esm.js +2 -2
- package/dist/index.js +2 -1
- package/dist/index.js.map +1 -1
- 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/reactive.d.ts +4 -3
- package/dist/reactive.esm.js +61 -57
- package/dist/reactive.esm.js.map +1 -1
- package/dist/reactive.js +61 -56
- package/dist/reactive.js.map +1 -1
- package/dist/std-decorators.esm.js +1 -1
- package/dist/std-decorators.js +1 -1
- package/docs/reactive.md +616 -0
- package/package.json +1 -2
- package/dist/chunks/decorator-BXsign4Z.js.map +0 -1
- package/dist/chunks/decorator-CPbZNnsX.esm.js.map +0 -1
- package/src/decorator.test.ts +0 -495
- package/src/decorator.ts +0 -205
- package/src/destroyable.test.ts +0 -155
- package/src/destroyable.ts +0 -158
- package/src/eventful.test.ts +0 -380
- package/src/eventful.ts +0 -69
- package/src/index.ts +0 -7
- package/src/indexable.test.ts +0 -388
- package/src/indexable.ts +0 -124
- package/src/promiseChain.test.ts +0 -201
- package/src/promiseChain.ts +0 -99
- package/src/reactive/array.test.ts +0 -923
- package/src/reactive/array.ts +0 -352
- package/src/reactive/core.test.ts +0 -1663
- package/src/reactive/core.ts +0 -866
- package/src/reactive/index.ts +0 -28
- package/src/reactive/interface.test.ts +0 -1477
- package/src/reactive/interface.ts +0 -231
- package/src/reactive/map.test.ts +0 -866
- package/src/reactive/map.ts +0 -162
- package/src/reactive/set.test.ts +0 -289
- package/src/reactive/set.ts +0 -142
- package/src/std-decorators.test.ts +0 -679
- package/src/std-decorators.ts +0 -182
- package/src/utils.ts +0 -52
|
@@ -1,231 +0,0 @@
|
|
|
1
|
-
import { decorator, GenericClassDecorator } from '../decorator'
|
|
2
|
-
import { renamed } from '../utils'
|
|
3
|
-
import {
|
|
4
|
-
type DependencyFunction,
|
|
5
|
-
deepWatch,
|
|
6
|
-
dependant,
|
|
7
|
-
effect,
|
|
8
|
-
getRoot,
|
|
9
|
-
isNonReactive,
|
|
10
|
-
markWithRoot,
|
|
11
|
-
nonReactiveClass,
|
|
12
|
-
nonReactiveMark,
|
|
13
|
-
nonReactiveObjects,
|
|
14
|
-
options,
|
|
15
|
-
type ScopedCallback,
|
|
16
|
-
touched1,
|
|
17
|
-
unreactiveProperties,
|
|
18
|
-
untracked,
|
|
19
|
-
unwrap,
|
|
20
|
-
withEffect,
|
|
21
|
-
} from './core'
|
|
22
|
-
|
|
23
|
-
//#region computed
|
|
24
|
-
let computedInvalidations: (() => void)[] | undefined
|
|
25
|
-
/**
|
|
26
|
-
* When used in a computed property computation, it will register the callback to be called when the computed property is invalidated
|
|
27
|
-
* @param cb - The callback to register
|
|
28
|
-
* @param warn - Whether to warn if used outside of a computed property
|
|
29
|
-
*/
|
|
30
|
-
export function invalidateComputed(cb: () => void, warn = true) {
|
|
31
|
-
if (computedInvalidations) computedInvalidations.push(cb)
|
|
32
|
-
else if (warn) options.warn('Using `invalidateComputed` outside of a computed property')
|
|
33
|
-
}
|
|
34
|
-
type ComputedFunction<T> = (dep: DependencyFunction) => T
|
|
35
|
-
const computedCache = new WeakMap<ComputedFunction<any>, any>()
|
|
36
|
-
function computedFunction<T>(getter: ComputedFunction<T>): T {
|
|
37
|
-
const key = getRoot(getter)
|
|
38
|
-
let invalidations: (() => void)[] = []
|
|
39
|
-
dependant(computedCache, key)
|
|
40
|
-
if (computedCache.has(key)) return computedCache.get(key)
|
|
41
|
-
withEffect(undefined, () => {
|
|
42
|
-
const stop = effect(
|
|
43
|
-
markWithRoot((dep) => {
|
|
44
|
-
const oldCI = computedInvalidations
|
|
45
|
-
if (computedCache.has(key)) {
|
|
46
|
-
// This should *not* be called in the cleanup chain, as its effects would be lost and cleaned-up
|
|
47
|
-
for (const cb of invalidations) cb()
|
|
48
|
-
invalidations = []
|
|
49
|
-
computedCache.delete(key)
|
|
50
|
-
touched1(computedCache, { type: 'set', prop: key }, key)
|
|
51
|
-
stop()
|
|
52
|
-
} else
|
|
53
|
-
try {
|
|
54
|
-
computedInvalidations = invalidations
|
|
55
|
-
computedCache.set(key, getter(dep))
|
|
56
|
-
} finally {
|
|
57
|
-
computedInvalidations = oldCI
|
|
58
|
-
}
|
|
59
|
-
}, getter)
|
|
60
|
-
)
|
|
61
|
-
})
|
|
62
|
-
return computedCache.get(key)
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
/**
|
|
66
|
-
* Get the cached value of a computed function - cache is invalidated when the dependencies change
|
|
67
|
-
*/
|
|
68
|
-
export const computed = decorator({
|
|
69
|
-
getter(original, propertyKey) {
|
|
70
|
-
const computers = new WeakMap<any, () => any>()
|
|
71
|
-
return function (this: any) {
|
|
72
|
-
if (!computers.has(this)) {
|
|
73
|
-
computers.set(
|
|
74
|
-
this,
|
|
75
|
-
renamed(
|
|
76
|
-
() => original.call(this),
|
|
77
|
-
`${String(this.constructor.name)}.${String(propertyKey)}`
|
|
78
|
-
)
|
|
79
|
-
)
|
|
80
|
-
}
|
|
81
|
-
return computedFunction(computers.get(this)!)
|
|
82
|
-
}
|
|
83
|
-
},
|
|
84
|
-
default<T>(getter: ComputedFunction<T>): T {
|
|
85
|
-
return computedFunction(getter)
|
|
86
|
-
},
|
|
87
|
-
})
|
|
88
|
-
|
|
89
|
-
//#endregion
|
|
90
|
-
|
|
91
|
-
//#region watch
|
|
92
|
-
|
|
93
|
-
const unsetYet = Symbol('unset-yet')
|
|
94
|
-
export interface WatchOptions {
|
|
95
|
-
immediate?: boolean
|
|
96
|
-
deep?: boolean
|
|
97
|
-
}
|
|
98
|
-
export function watch<T>(
|
|
99
|
-
value: (dep: DependencyFunction) => T,
|
|
100
|
-
changed: (value: T, oldValue?: T) => void,
|
|
101
|
-
options?: Omit<WatchOptions, 'deep'> & { deep?: false }
|
|
102
|
-
): ScopedCallback
|
|
103
|
-
export function watch<T extends object | any[]>(
|
|
104
|
-
value: (dep: DependencyFunction) => T,
|
|
105
|
-
changed: (value: T, oldValue?: T) => void,
|
|
106
|
-
options?: Omit<WatchOptions, 'deep'> & { deep: true }
|
|
107
|
-
): ScopedCallback
|
|
108
|
-
export function watch<T extends object | any[]>(
|
|
109
|
-
value: T,
|
|
110
|
-
changed: (value: T) => void,
|
|
111
|
-
options?: WatchOptions
|
|
112
|
-
): ScopedCallback
|
|
113
|
-
|
|
114
|
-
export function watch(
|
|
115
|
-
value: any, //object | ((dep: DependencyFunction) => object),
|
|
116
|
-
changed: (value?: object, oldValue?: object) => void,
|
|
117
|
-
options: any = {}
|
|
118
|
-
) {
|
|
119
|
-
return typeof value === 'function'
|
|
120
|
-
? watchCallBack(value, changed, options)
|
|
121
|
-
: typeof value === 'object'
|
|
122
|
-
? watchObject(value, changed, options)
|
|
123
|
-
: (() => {
|
|
124
|
-
throw new Error('watch: value must be a function or an object')
|
|
125
|
-
})()
|
|
126
|
-
}
|
|
127
|
-
|
|
128
|
-
function watchObject(
|
|
129
|
-
value: object,
|
|
130
|
-
changed: (value: object) => void,
|
|
131
|
-
{ immediate = false, deep = false } = {}
|
|
132
|
-
): ScopedCallback {
|
|
133
|
-
if (deep) return deepWatch(value, changed, { immediate })
|
|
134
|
-
return effect(
|
|
135
|
-
markWithRoot(() => {
|
|
136
|
-
dependant(value)
|
|
137
|
-
if (immediate) untracked(() => changed(value))
|
|
138
|
-
immediate = true
|
|
139
|
-
}, changed)
|
|
140
|
-
)
|
|
141
|
-
}
|
|
142
|
-
|
|
143
|
-
function watchCallBack<T>(
|
|
144
|
-
value: (dep: DependencyFunction) => T,
|
|
145
|
-
changed: (value: T, oldValue?: T) => void,
|
|
146
|
-
{ immediate = false, deep = false } = {}
|
|
147
|
-
): ScopedCallback {
|
|
148
|
-
let oldValue: T | typeof unsetYet = unsetYet
|
|
149
|
-
let deepCleanup: ScopedCallback | undefined
|
|
150
|
-
const cbCleanup = effect(
|
|
151
|
-
markWithRoot((dep) => {
|
|
152
|
-
const newValue = value(dep)
|
|
153
|
-
if (oldValue !== newValue)
|
|
154
|
-
untracked(
|
|
155
|
-
markWithRoot(() => {
|
|
156
|
-
if (oldValue === unsetYet) {
|
|
157
|
-
if (immediate) changed(newValue)
|
|
158
|
-
} else changed(newValue, oldValue)
|
|
159
|
-
oldValue = newValue
|
|
160
|
-
if (deep) {
|
|
161
|
-
if (deepCleanup) deepCleanup()
|
|
162
|
-
deepCleanup = deepWatch(
|
|
163
|
-
newValue as object,
|
|
164
|
-
markWithRoot((value) => changed(value as T, value as T), changed)
|
|
165
|
-
)
|
|
166
|
-
}
|
|
167
|
-
}, changed)
|
|
168
|
-
)
|
|
169
|
-
}, value)
|
|
170
|
-
)
|
|
171
|
-
return () => {
|
|
172
|
-
cbCleanup()
|
|
173
|
-
if (deepCleanup) deepCleanup()
|
|
174
|
-
}
|
|
175
|
-
}
|
|
176
|
-
|
|
177
|
-
//#endregion
|
|
178
|
-
|
|
179
|
-
//#region nonReactive
|
|
180
|
-
|
|
181
|
-
/**
|
|
182
|
-
* Mark an object as non-reactive. This object and all its properties will never be made reactive.
|
|
183
|
-
* @param obj - The object to mark as non-reactive
|
|
184
|
-
*/
|
|
185
|
-
function deepNonReactive<T>(obj: T): T {
|
|
186
|
-
obj = unwrap(obj)
|
|
187
|
-
if (isNonReactive(obj)) return obj
|
|
188
|
-
try {
|
|
189
|
-
Object.defineProperty(obj as object, nonReactiveMark, {
|
|
190
|
-
value: true,
|
|
191
|
-
writable: false,
|
|
192
|
-
enumerable: false,
|
|
193
|
-
configurable: true,
|
|
194
|
-
})
|
|
195
|
-
} catch {}
|
|
196
|
-
if (!(nonReactiveMark in (obj as object))) nonReactiveObjects.add(obj as object)
|
|
197
|
-
for (const key in obj) deepNonReactive(obj[key])
|
|
198
|
-
return obj
|
|
199
|
-
}
|
|
200
|
-
function unreactiveApplication<T extends object>(...args: (keyof T)[]): GenericClassDecorator<T>
|
|
201
|
-
function unreactiveApplication<T extends object>(obj: T): T
|
|
202
|
-
function unreactiveApplication<T extends object>(
|
|
203
|
-
arg1: T | keyof T,
|
|
204
|
-
...args: (keyof T)[]
|
|
205
|
-
): GenericClassDecorator<T> | T {
|
|
206
|
-
return typeof arg1 === 'object'
|
|
207
|
-
? deepNonReactive(arg1)
|
|
208
|
-
: (((original) => {
|
|
209
|
-
// Copy the parent's unreactive properties if they exist
|
|
210
|
-
original.prototype[unreactiveProperties] = new Set<PropertyKey>(
|
|
211
|
-
original.prototype[unreactiveProperties] || []
|
|
212
|
-
)
|
|
213
|
-
// Add all arguments (including the first one)
|
|
214
|
-
original.prototype[unreactiveProperties].add(arg1)
|
|
215
|
-
for (const arg of args) original.prototype[unreactiveProperties].add(arg)
|
|
216
|
-
return original // Return the class
|
|
217
|
-
}) as GenericClassDecorator<T>)
|
|
218
|
-
}
|
|
219
|
-
export const unreactive = decorator({
|
|
220
|
-
class(original) {
|
|
221
|
-
// Called without arguments, mark entire class as non-reactive
|
|
222
|
-
nonReactiveClass(original)
|
|
223
|
-
},
|
|
224
|
-
default: unreactiveApplication,
|
|
225
|
-
})
|
|
226
|
-
|
|
227
|
-
//#endregion
|
|
228
|
-
|
|
229
|
-
import { profileInfo } from './core'
|
|
230
|
-
|
|
231
|
-
Object.assign(profileInfo, { computedCache })
|