mutts 1.0.9 → 1.0.10

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 (204) hide show
  1. package/README.md +58 -33
  2. package/dist/browser.cjs +1371 -1206
  3. package/dist/browser.cjs.map +1 -1
  4. package/dist/browser.d.ts +2 -1392
  5. package/dist/browser.dev.cjs +110 -0
  6. package/dist/browser.dev.cjs.map +1 -0
  7. package/dist/browser.dev.d.ts +2 -0
  8. package/dist/browser.dev.esm.js +5 -0
  9. package/dist/browser.dev.esm.js.map +1 -0
  10. package/dist/browser.esm.js +6 -87
  11. package/dist/browser.esm.js.map +1 -1
  12. package/dist/chunks/{async-browser-lvzLOCgk.cjs → async-browser-BU_IfxYD.cjs} +4 -85
  13. package/dist/chunks/async-browser-BU_IfxYD.cjs.map +1 -0
  14. package/dist/chunks/{async-node-C3DeIb0y.cjs → async-node-3PrbVAbB.cjs} +3 -1
  15. package/dist/chunks/async-node-3PrbVAbB.cjs.map +1 -0
  16. package/dist/chunks/{index-2vea86wD.esm.js → index-CaaQQlPJ.esm.js} +1116 -953
  17. package/dist/chunks/index-CaaQQlPJ.esm.js.map +1 -0
  18. package/dist/chunks/node-nKJBk8iJ.esm.js +96 -0
  19. package/dist/chunks/node-nKJBk8iJ.esm.js.map +1 -0
  20. package/dist/chunks/{index-VTO-b2vR.cjs → proxy-Dtg-bJ3T.cjs} +2285 -2983
  21. package/dist/chunks/proxy-Dtg-bJ3T.cjs.map +1 -0
  22. package/dist/chunks/{index-CtA2AWl3.esm.js → proxy-r7lARftl.esm.js} +2273 -2948
  23. package/dist/chunks/proxy-r7lARftl.esm.js.map +1 -0
  24. package/dist/debug.cjs +973 -28
  25. package/dist/debug.cjs.map +1 -1
  26. package/dist/debug.d.ts +36 -37
  27. package/dist/debug.esm.js +949 -1
  28. package/dist/debug.esm.js.map +1 -1
  29. package/dist/devtools/manifest.json +1 -1
  30. package/dist/devtools/panel.html +1 -1
  31. package/dist/devtools/panel.js +107 -94
  32. package/dist/devtools/panel.js.map +1 -1
  33. package/dist/index.d.ts +1447 -1
  34. package/dist/mutts.umd.js +7167 -1
  35. package/dist/mutts.umd.js.map +1 -1
  36. package/dist/mutts.umd.min.js +1 -1
  37. package/dist/mutts.umd.min.js.map +1 -1
  38. package/dist/node.cjs +62 -60
  39. package/dist/node.cjs.map +1 -1
  40. package/dist/node.d.ts +2 -2
  41. package/dist/node.dev.cjs +110 -0
  42. package/dist/node.dev.cjs.map +1 -0
  43. package/dist/node.dev.d.ts +2 -0
  44. package/dist/node.dev.esm.js +6 -0
  45. package/dist/node.dev.esm.js.map +1 -0
  46. package/dist/node.esm.js +4 -97
  47. package/dist/node.esm.js.map +1 -1
  48. package/dist/{types-DaHFfhlN.d.ts → types-W5vD6m2n.d.ts} +99 -44
  49. package/docs/ai/api-reference.md +11 -18
  50. package/docs/ai/manual.md +308 -230
  51. package/docs/reactive/advanced.md +312 -2
  52. package/docs/reactive/attend.md +1 -2
  53. package/docs/reactive/collections.md +21 -39
  54. package/docs/reactive/core.md +7 -37
  55. package/docs/reactive/debugging.md +117 -10
  56. package/docs/reactive/error-handling.md +10 -10
  57. package/docs/reactive/resource.md +125 -0
  58. package/docs/reactive/scan.md +32 -1
  59. package/docs/reactive.md +3 -2
  60. package/docs/utils.md +70 -0
  61. package/package.json +59 -30
  62. package/dist/chunks/async-browser-lvzLOCgk.cjs.map +0 -1
  63. package/dist/chunks/async-node-C3DeIb0y.cjs.map +0 -1
  64. package/dist/chunks/index-2vea86wD.esm.js.map +0 -1
  65. package/dist/chunks/index-CtA2AWl3.esm.js.map +0 -1
  66. package/dist/chunks/index-VTO-b2vR.cjs.map +0 -1
  67. package/dist/debug/debug.d.ts +0 -122
  68. package/dist/debug/debug.d.ts.map +0 -1
  69. package/dist/debug/index.d.ts +0 -4
  70. package/dist/debug/index.d.ts.map +0 -1
  71. package/dist/debug/lineage-panel.d.ts +0 -5
  72. package/dist/debug/lineage-panel.d.ts.map +0 -1
  73. package/dist/debug/lineage.d.ts +0 -79
  74. package/dist/debug/lineage.d.ts.map +0 -1
  75. package/dist/src/async/browser.d.ts +0 -2
  76. package/dist/src/async/browser.d.ts.map +0 -1
  77. package/dist/src/async/index.d.ts +0 -19
  78. package/dist/src/async/index.d.ts.map +0 -1
  79. package/dist/src/async/node.d.ts +0 -2
  80. package/dist/src/async/node.d.ts.map +0 -1
  81. package/dist/src/decorator.d.ts +0 -106
  82. package/dist/src/decorator.d.ts.map +0 -1
  83. package/dist/src/destroyable.d.ts +0 -87
  84. package/dist/src/destroyable.d.ts.map +0 -1
  85. package/dist/src/entry-browser.d.ts +0 -3
  86. package/dist/src/entry-browser.d.ts.map +0 -1
  87. package/dist/src/entry-node.d.ts +0 -3
  88. package/dist/src/entry-node.d.ts.map +0 -1
  89. package/dist/src/eventful.d.ts +0 -20
  90. package/dist/src/eventful.d.ts.map +0 -1
  91. package/dist/src/flavored.d.ts +0 -33
  92. package/dist/src/flavored.d.ts.map +0 -1
  93. package/dist/src/index.d.ts +0 -14
  94. package/dist/src/index.d.ts.map +0 -1
  95. package/dist/src/indexable.d.ts +0 -243
  96. package/dist/src/indexable.d.ts.map +0 -1
  97. package/dist/src/introspection.d.ts +0 -27
  98. package/dist/src/introspection.d.ts.map +0 -1
  99. package/dist/src/iterableWeak.d.ts +0 -53
  100. package/dist/src/iterableWeak.d.ts.map +0 -1
  101. package/dist/src/mixins.d.ts +0 -25
  102. package/dist/src/mixins.d.ts.map +0 -1
  103. package/dist/src/promiseChain.d.ts +0 -20
  104. package/dist/src/promiseChain.d.ts.map +0 -1
  105. package/dist/src/reactive/array.d.ts +0 -48
  106. package/dist/src/reactive/array.d.ts.map +0 -1
  107. package/dist/src/reactive/buffer.d.ts +0 -120
  108. package/dist/src/reactive/buffer.d.ts.map +0 -1
  109. package/dist/src/reactive/change.d.ts +0 -29
  110. package/dist/src/reactive/change.d.ts.map +0 -1
  111. package/dist/src/reactive/deep-touch.d.ts +0 -28
  112. package/dist/src/reactive/deep-touch.d.ts.map +0 -1
  113. package/dist/src/reactive/deep-watch-state.d.ts +0 -25
  114. package/dist/src/reactive/deep-watch-state.d.ts.map +0 -1
  115. package/dist/src/reactive/deep-watch.d.ts +0 -20
  116. package/dist/src/reactive/deep-watch.d.ts.map +0 -1
  117. package/dist/src/reactive/describe.d.ts +0 -12
  118. package/dist/src/reactive/describe.d.ts.map +0 -1
  119. package/dist/src/reactive/effect-context.d.ts +0 -34
  120. package/dist/src/reactive/effect-context.d.ts.map +0 -1
  121. package/dist/src/reactive/effects.d.ts +0 -164
  122. package/dist/src/reactive/effects.d.ts.map +0 -1
  123. package/dist/src/reactive/index.d.ts +0 -19
  124. package/dist/src/reactive/index.d.ts.map +0 -1
  125. package/dist/src/reactive/map.d.ts +0 -28
  126. package/dist/src/reactive/map.d.ts.map +0 -1
  127. package/dist/src/reactive/memoize.d.ts +0 -28
  128. package/dist/src/reactive/memoize.d.ts.map +0 -1
  129. package/dist/src/reactive/non-reactive-state.d.ts +0 -9
  130. package/dist/src/reactive/non-reactive-state.d.ts.map +0 -1
  131. package/dist/src/reactive/non-reactive.d.ts +0 -11
  132. package/dist/src/reactive/non-reactive.d.ts.map +0 -1
  133. package/dist/src/reactive/project.d.ts +0 -40
  134. package/dist/src/reactive/project.d.ts.map +0 -1
  135. package/dist/src/reactive/proxy-state.d.ts +0 -8
  136. package/dist/src/reactive/proxy-state.d.ts.map +0 -1
  137. package/dist/src/reactive/proxy.d.ts +0 -23
  138. package/dist/src/reactive/proxy.d.ts.map +0 -1
  139. package/dist/src/reactive/record.d.ts +0 -115
  140. package/dist/src/reactive/record.d.ts.map +0 -1
  141. package/dist/src/reactive/register.d.ts +0 -125
  142. package/dist/src/reactive/register.d.ts.map +0 -1
  143. package/dist/src/reactive/registry.d.ts +0 -21
  144. package/dist/src/reactive/registry.d.ts.map +0 -1
  145. package/dist/src/reactive/set.d.ts +0 -26
  146. package/dist/src/reactive/set.d.ts.map +0 -1
  147. package/dist/src/reactive/tracking.d.ts +0 -7
  148. package/dist/src/reactive/tracking.d.ts.map +0 -1
  149. package/dist/src/reactive/types.d.ts +0 -424
  150. package/dist/src/reactive/types.d.ts.map +0 -1
  151. package/dist/src/reactive/watch.d.ts +0 -48
  152. package/dist/src/reactive/watch.d.ts.map +0 -1
  153. package/dist/src/std-decorators.d.ts +0 -45
  154. package/dist/src/std-decorators.d.ts.map +0 -1
  155. package/dist/src/utils.d.ts +0 -49
  156. package/dist/src/utils.d.ts.map +0 -1
  157. package/dist/src/zone.d.ts +0 -40
  158. package/dist/src/zone.d.ts.map +0 -1
  159. package/docs/reactive/describe.md +0 -85
  160. package/docs/reactive/project.md +0 -93
  161. package/src/async/browser.ts +0 -323
  162. package/src/async/index.ts +0 -27
  163. package/src/async/node.ts +0 -92
  164. package/src/decorator.ts +0 -272
  165. package/src/destroyable.ts +0 -199
  166. package/src/entry-browser.ts +0 -5
  167. package/src/entry-node.ts +0 -5
  168. package/src/eventful.ts +0 -110
  169. package/src/flavored.ts +0 -106
  170. package/src/index.d.ts +0 -12
  171. package/src/index.ts +0 -64
  172. package/src/indexable.ts +0 -526
  173. package/src/introspection.ts +0 -59
  174. package/src/iterableWeak.ts +0 -233
  175. package/src/mixins.ts +0 -123
  176. package/src/promiseChain.ts +0 -110
  177. package/src/reactive/array.ts +0 -500
  178. package/src/reactive/buffer.ts +0 -328
  179. package/src/reactive/change.ts +0 -131
  180. package/src/reactive/deep-touch.ts +0 -273
  181. package/src/reactive/deep-watch-state.ts +0 -82
  182. package/src/reactive/deep-watch.ts +0 -171
  183. package/src/reactive/describe.ts +0 -39
  184. package/src/reactive/effect-context.ts +0 -83
  185. package/src/reactive/effects.ts +0 -1434
  186. package/src/reactive/index.ts +0 -72
  187. package/src/reactive/map.ts +0 -142
  188. package/src/reactive/memoize.ts +0 -186
  189. package/src/reactive/non-reactive-state.ts +0 -49
  190. package/src/reactive/non-reactive.ts +0 -43
  191. package/src/reactive/project.md +0 -107
  192. package/src/reactive/project.ts +0 -430
  193. package/src/reactive/proxy-state.ts +0 -27
  194. package/src/reactive/proxy.ts +0 -282
  195. package/src/reactive/record.ts +0 -181
  196. package/src/reactive/register.ts +0 -538
  197. package/src/reactive/registry.ts +0 -72
  198. package/src/reactive/set.ts +0 -117
  199. package/src/reactive/tracking.ts +0 -41
  200. package/src/reactive/types.ts +0 -520
  201. package/src/reactive/watch.ts +0 -180
  202. package/src/std-decorators.ts +0 -256
  203. package/src/utils.ts +0 -300
  204. package/src/zone.ts +0 -142
@@ -1,180 +0,0 @@
1
- import { decorator, type GenericClassDecorator } from '../decorator'
2
- import { deepWatch } from './deep-watch'
3
- import { effect } from './effects'
4
- import { isNonReactive, nonReactiveClass, nonReactiveObjects } from './non-reactive-state'
5
- import { unwrap } from './proxy-state'
6
- import { markWithRoot } from './registry'
7
- import { dependant } from './tracking'
8
- import {
9
- type EffectAccess,
10
- type EffectCleanup,
11
- nonReactiveMark,
12
- stopped,
13
- unreactiveProperties,
14
- } from './types'
15
-
16
- //#region watch
17
-
18
- const unsetYet = Symbol('unset-yet')
19
- /**
20
- * Options for the watch function
21
- */
22
- export interface WatchOptions {
23
- /** Whether to call the callback immediately */
24
- immediate?: boolean
25
- /** Whether to watch nested properties */
26
- deep?: boolean
27
- }
28
-
29
- /**
30
- * Watches a reactive value and calls a callback when it changes
31
- * @param value - Function that returns the value to watch
32
- * @param changed - Callback to call when the value changes
33
- * @param options - Watch options
34
- * @returns Cleanup function to stop watching
35
- */
36
- export function watch<T>(
37
- value: (dep: EffectAccess) => T,
38
- changed: (value: T, oldValue?: T) => void,
39
- options?: Omit<WatchOptions, 'deep'> & { deep?: false }
40
- ): EffectCleanup
41
- /**
42
- * Watches a reactive value with deep watching enabled
43
- * @param value - Function that returns the value to watch
44
- * @param changed - Callback to call when the value changes
45
- * @param options - Watch options with deep watching enabled
46
- * @returns Cleanup function to stop watching
47
- */
48
- export function watch<T extends object | any[]>(
49
- value: (dep: EffectAccess) => T,
50
- changed: (value: T, oldValue?: T) => void,
51
- options?: Omit<WatchOptions, 'deep'> & { deep: true }
52
- ): EffectCleanup
53
- /**
54
- * Watches a reactive object directly
55
- * @param value - The reactive object to watch
56
- * @param changed - Callback to call when the object changes
57
- * @param options - Watch options
58
- * @returns Cleanup function to stop watching
59
- */
60
- export function watch<T extends object | any[]>(
61
- value: T,
62
- changed: (value: T) => void,
63
- options?: WatchOptions
64
- ): EffectCleanup
65
-
66
- export function watch(
67
- value: any, //object | ((dep: DependencyAccess) => object),
68
- changed: (value?: object, oldValue?: object) => void,
69
- options: any = {}
70
- ) {
71
- return typeof value === 'function'
72
- ? watchCallBack(value, changed, options)
73
- : typeof value === 'object' && value !== null
74
- ? watchObject(value, changed, options)
75
- : (() => {
76
- throw new Error('watch: value must be a function or an object')
77
- })()
78
- }
79
-
80
- function watchObject(
81
- value: object,
82
- changed: (value: object) => void,
83
- { immediate = false, deep = false } = {}
84
- ): EffectCleanup {
85
- if (deep) return deepWatch(value, changed, { immediate })!
86
- return effect(function watchObjectEffect() {
87
- dependant(value)
88
- if (immediate) changed(value)
89
- immediate = true
90
- })
91
- }
92
-
93
- function watchCallBack<T>(
94
- value: (dep: EffectAccess) => T,
95
- changed: (value: T, oldValue?: T) => void,
96
- { immediate = false, deep = false } = {}
97
- ): EffectCleanup {
98
- let oldValue: T | typeof unsetYet = unsetYet
99
- let deepCleanup: EffectCleanup | undefined
100
- const cbCleanup = effect(
101
- markWithRoot(function watchCallBackEffect(access) {
102
- const newValue = value(access)
103
- if (oldValue !== newValue)
104
- if (oldValue === unsetYet) {
105
- if (immediate) changed(newValue)
106
- } else changed(newValue, oldValue)
107
- oldValue = newValue
108
- if (deep) {
109
- if (deepCleanup) deepCleanup()
110
- deepCleanup = deepWatch(newValue as object, (value) => changed(value as T, value as T))
111
- }
112
- }, value)
113
- )
114
- return Object.defineProperties(
115
- () => {
116
- cbCleanup()
117
- if (deepCleanup) deepCleanup()
118
- },
119
- {
120
- [stopped]: { get: () => cbCleanup[stopped] },
121
- }
122
- ) as EffectCleanup
123
- }
124
-
125
- //#endregion
126
-
127
- //#region nonReactive
128
-
129
- /**
130
- * Mark an object as non-reactive. This object and all its properties will never be made reactive.
131
- * @param obj - The object to mark as non-reactive
132
- */
133
- function shallowNonReactive<T>(obj: T): T {
134
- obj = unwrap(obj)
135
- if (isNonReactive(obj)) return obj
136
- try {
137
- Object.defineProperty(obj as object, nonReactiveMark, {
138
- value: true,
139
- writable: false,
140
- enumerable: false,
141
- configurable: true,
142
- })
143
- } catch {}
144
- if (!(nonReactiveMark in (obj as object))) nonReactiveObjects.add(obj as object)
145
- // Finally, not deep
146
- //for (const key in obj) deepNonReactive(obj[key])
147
- return obj
148
- }
149
- function unreactiveApplication<T extends object>(...args: (keyof T)[]): GenericClassDecorator<T>
150
- function unreactiveApplication<T extends object>(obj: T): T
151
- function unreactiveApplication<T extends object>(
152
- arg1: T | keyof T,
153
- ...args: (keyof T)[]
154
- ): GenericClassDecorator<T> | T {
155
- return typeof arg1 === 'object'
156
- ? shallowNonReactive(arg1)
157
- : (((original) => {
158
- // Copy the parent's unreactive properties if they exist
159
- original.prototype[unreactiveProperties] = new Set<PropertyKey>(
160
- original.prototype[unreactiveProperties] || []
161
- )
162
- // Add all arguments (including the first one)
163
- original.prototype[unreactiveProperties].add(arg1)
164
- for (const arg of args) original.prototype[unreactiveProperties].add(arg)
165
- return original // Return the class
166
- }) as GenericClassDecorator<T>)
167
- }
168
- /**
169
- * Decorator that marks classes or properties as non-reactive
170
- * Prevents objects from being made reactive
171
- */
172
- export const unreactive = decorator({
173
- class(original) {
174
- // Called without arguments, mark entire class as non-reactive
175
- nonReactiveClass(original)
176
- },
177
- default: unreactiveApplication,
178
- })
179
-
180
- //#endregion
@@ -1,256 +0,0 @@
1
- import { decorator, type GenericClassDecorator } from './decorator'
2
- import { flavored } from './flavored'
3
-
4
- // In order to avoid async re-entrance, we could use zone.js or something like that.
5
- const syncCalculating: { object: object; prop: PropertyKey }[] = []
6
- /**
7
- * Decorator that caches the result of a getter method and only recomputes when dependencies change
8
- * Prevents circular dependencies and provides automatic cache invalidation
9
- */
10
- export const cached = decorator({
11
- getter(original, _target, propertyKey) {
12
- return function (this: any) {
13
- const alreadyCalculating = syncCalculating.findIndex(
14
- (c) => c.object === this && c.prop === propertyKey
15
- )
16
- if (alreadyCalculating > -1)
17
- throw new Error(
18
- `Circular dependency detected: ${syncCalculating
19
- .slice(alreadyCalculating)
20
- .map((c) => `${c.object.constructor.name}.${String(c.prop)}`)
21
- .join(' -> ')} -> again`
22
- )
23
- syncCalculating.push({ object: this, prop: propertyKey })
24
- try {
25
- const rv = original.call(this)
26
- cache(this, propertyKey, rv)
27
- return rv
28
- } finally {
29
- syncCalculating.pop()
30
- }
31
- }
32
- },
33
- })
34
-
35
- /**
36
- * Checks if a property is cached (has a cached value)
37
- * @param object - The object to check
38
- * @param propertyKey - The property key to check
39
- * @returns True if the property has a cached value
40
- */
41
- export function isCached(object: Object, propertyKey: PropertyKey) {
42
- return !!Object.getOwnPropertyDescriptor(object, propertyKey)
43
- }
44
-
45
- /**
46
- * Caches a value for a property on an object
47
- * @param object - The object to cache the value on
48
- * @param propertyKey - The property key to cache
49
- * @param value - The value to cache
50
- */
51
- export function cache(object: Object, propertyKey: PropertyKey, value: any) {
52
- Object.defineProperty(object, propertyKey, { value })
53
- }
54
-
55
- /**
56
- * Creates a decorator that modifies property descriptors for specified properties
57
- * @param descriptor - The descriptor properties to apply
58
- * @returns A class decorator that applies the descriptor to specified properties
59
- */
60
- export const descriptor = flavored(
61
- function descriptor(descriptor: {
62
- enumerable?: boolean
63
- configurable?: boolean // Not modifiable once the property has been defined
64
- writable?: boolean
65
- }) {
66
- return <T>(...properties: (keyof T)[]): GenericClassDecorator<T> =>
67
- (Base) => {
68
- return class extends Base {
69
- constructor(...args: any[]) {
70
- super(...args)
71
- for (const key of properties) {
72
- const existing = Object.getOwnPropertyDescriptor(this, key)
73
- Object.defineProperty(this, key, Object.assign(existing || {}, descriptor))
74
- }
75
- }
76
- }
77
- }
78
- },
79
- {
80
- /**
81
- * enumerable: true
82
- */
83
- get enumerable() {
84
- return descriptor({ enumerable: true })
85
- },
86
- /**
87
- * enumerable: false
88
- */
89
- get hidden() {
90
- return descriptor({ enumerable: false })
91
- },
92
- /**
93
- * configurable: true
94
- */
95
- get configurable() {
96
- return descriptor({ configurable: true })
97
- },
98
- /**
99
- * configurable: false
100
- */
101
- get frozen() {
102
- return descriptor({ configurable: false })
103
- },
104
- /**
105
- * writable: true
106
- */
107
- get writable() {
108
- return descriptor({ writable: true })
109
- },
110
- /**
111
- * writable: false
112
- */
113
- get readonly() {
114
- return descriptor({ writable: false })
115
- },
116
- }
117
- )
118
-
119
- /**
120
- * Decorator that marks methods, properties, or classes as deprecated
121
- * Provides warning messages when deprecated items are used
122
- */
123
- export const deprecated = Object.assign(
124
- decorator({
125
- method(original, _target, propertyKey) {
126
- return function (this: any, ...args: any[]) {
127
- deprecated.warn(this, propertyKey)
128
- return original.apply(this, args)
129
- }
130
- },
131
- getter(original, _target, propertyKey) {
132
- return function (this: any) {
133
- deprecated.warn(this, propertyKey)
134
- return original.call(this)
135
- }
136
- },
137
- setter(original, _target, propertyKey) {
138
- return function (this: any, value: any) {
139
- deprecated.warn(this, propertyKey)
140
- return original.call(this, value)
141
- }
142
- },
143
- class(original) {
144
- return class extends original {
145
- constructor(...args: any[]) {
146
- super(...args)
147
- deprecated.warn(this, 'constructor')
148
- }
149
- }
150
- },
151
- default(message: string) {
152
- return decorator({
153
- method(original, _target, propertyKey) {
154
- return function (this: any, ...args: any[]) {
155
- deprecated.warn(this, propertyKey, message)
156
- return original.apply(this, args)
157
- }
158
- },
159
- getter(original, _target, propertyKey) {
160
- return function (this: any) {
161
- deprecated.warn(this, propertyKey, message)
162
- return original.call(this)
163
- }
164
- },
165
- setter(original, _target, propertyKey) {
166
- return function (this: any, value: any) {
167
- deprecated.warn(this, propertyKey, message)
168
- return original.call(this, value)
169
- }
170
- },
171
- class(original) {
172
- return class extends original {
173
- constructor(...args: any[]) {
174
- super(...args)
175
- deprecated.warn(this, 'constructor', message)
176
- }
177
- }
178
- },
179
- })
180
- },
181
- }),
182
- {
183
- warn: (target: any, propertyKey: PropertyKey, message?: string) => {
184
- // biome-ignore lint/suspicious/noConsole: To be overridden
185
- console.warn(
186
- `${target.constructor.name}.${String(propertyKey)} is deprecated${message ? `: ${message}` : ''}`
187
- )
188
- },
189
- }
190
- )
191
-
192
- /**
193
- * Creates a debounced method decorator that delays execution until after the delay period has passed
194
- * @param delay - The delay in milliseconds
195
- * @returns A method decorator that debounces method calls
196
- */
197
- export function debounce(delay: number) {
198
- return decorator({
199
- method(original, _target, _propertyKey) {
200
- let timeoutId: ReturnType<typeof setTimeout> | null = null
201
-
202
- return function (this: any, ...args: any[]) {
203
- // Clear existing timeout
204
- if (timeoutId) {
205
- clearTimeout(timeoutId)
206
- }
207
-
208
- // Set new timeout
209
- timeoutId = setTimeout(() => {
210
- original.apply(this, args)
211
- timeoutId = null
212
- }, delay)
213
- }
214
- },
215
- })
216
- }
217
-
218
- /**
219
- * Creates a throttled method decorator that limits execution to once per delay period
220
- * @param delay - The delay in milliseconds
221
- * @returns A method decorator that throttles method calls
222
- */
223
- export function throttle(delay: number) {
224
- return decorator({
225
- method(original, _target, _propertyKey) {
226
- let lastCallTime = 0
227
- let timeoutId: ReturnType<typeof setTimeout> | null = null
228
-
229
- return function (this: any, ...args: any[]) {
230
- const now = Date.now()
231
-
232
- // If enough time has passed since last call, execute immediately
233
- if (now - lastCallTime >= delay) {
234
- // Clear any pending timeout since we're executing now
235
- if (timeoutId) {
236
- clearTimeout(timeoutId)
237
- timeoutId = null
238
- }
239
- lastCallTime = now
240
- return original.apply(this, args)
241
- }
242
-
243
- // Otherwise, schedule execution for when the delay period ends
244
- if (!timeoutId) {
245
- const remainingTime = delay - (now - lastCallTime)
246
- const scheduledArgs = [...args] // Capture args at scheduling time
247
- timeoutId = setTimeout(() => {
248
- lastCallTime = Date.now()
249
- original.apply(this, scheduledArgs)
250
- timeoutId = null
251
- }, remainingTime)
252
- }
253
- }
254
- },
255
- })
256
- }