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.
Files changed (53) hide show
  1. package/dist/chunks/{decorator-BXsign4Z.js → decorator-8qjFb7dw.js} +2 -2
  2. package/dist/chunks/decorator-8qjFb7dw.js.map +1 -0
  3. package/dist/chunks/{decorator-CPbZNnsX.esm.js → decorator-AbRkXM5O.esm.js} +2 -2
  4. package/dist/chunks/decorator-AbRkXM5O.esm.js.map +1 -0
  5. package/dist/decorator.d.ts +1 -1
  6. package/dist/decorator.esm.js +1 -1
  7. package/dist/decorator.js +1 -1
  8. package/dist/destroyable.esm.js +1 -1
  9. package/dist/destroyable.js +1 -1
  10. package/dist/index.d.ts +1 -1
  11. package/dist/index.esm.js +2 -2
  12. package/dist/index.js +2 -1
  13. package/dist/index.js.map +1 -1
  14. package/dist/mutts.umd.js +1 -1
  15. package/dist/mutts.umd.js.map +1 -1
  16. package/dist/mutts.umd.min.js +1 -1
  17. package/dist/mutts.umd.min.js.map +1 -1
  18. package/dist/reactive.d.ts +4 -3
  19. package/dist/reactive.esm.js +61 -57
  20. package/dist/reactive.esm.js.map +1 -1
  21. package/dist/reactive.js +61 -56
  22. package/dist/reactive.js.map +1 -1
  23. package/dist/std-decorators.esm.js +1 -1
  24. package/dist/std-decorators.js +1 -1
  25. package/docs/reactive.md +616 -0
  26. package/package.json +1 -2
  27. package/dist/chunks/decorator-BXsign4Z.js.map +0 -1
  28. package/dist/chunks/decorator-CPbZNnsX.esm.js.map +0 -1
  29. package/src/decorator.test.ts +0 -495
  30. package/src/decorator.ts +0 -205
  31. package/src/destroyable.test.ts +0 -155
  32. package/src/destroyable.ts +0 -158
  33. package/src/eventful.test.ts +0 -380
  34. package/src/eventful.ts +0 -69
  35. package/src/index.ts +0 -7
  36. package/src/indexable.test.ts +0 -388
  37. package/src/indexable.ts +0 -124
  38. package/src/promiseChain.test.ts +0 -201
  39. package/src/promiseChain.ts +0 -99
  40. package/src/reactive/array.test.ts +0 -923
  41. package/src/reactive/array.ts +0 -352
  42. package/src/reactive/core.test.ts +0 -1663
  43. package/src/reactive/core.ts +0 -866
  44. package/src/reactive/index.ts +0 -28
  45. package/src/reactive/interface.test.ts +0 -1477
  46. package/src/reactive/interface.ts +0 -231
  47. package/src/reactive/map.test.ts +0 -866
  48. package/src/reactive/map.ts +0 -162
  49. package/src/reactive/set.test.ts +0 -289
  50. package/src/reactive/set.ts +0 -142
  51. package/src/std-decorators.test.ts +0 -679
  52. package/src/std-decorators.ts +0 -182
  53. 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 })