mutts 1.0.9 → 1.0.11

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 (206) hide show
  1. package/README.md +60 -35
  2. package/dist/browser.cjs +1333 -1760
  3. package/dist/browser.cjs.map +1 -1
  4. package/dist/browser.d.ts +2 -1392
  5. package/dist/browser.dev.cjs +114 -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 +18 -97
  11. package/dist/browser.esm.js.map +1 -1
  12. package/dist/chunks/{async-browser-lvzLOCgk.cjs → async-browser-Dgr5CreQ.cjs} +16 -95
  13. package/dist/chunks/async-browser-Dgr5CreQ.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-Sf74wXTV.esm.js +2577 -0
  17. package/dist/chunks/index-Sf74wXTV.esm.js.map +1 -0
  18. package/dist/chunks/node-Bo7WU5S2.esm.js +96 -0
  19. package/dist/chunks/node-Bo7WU5S2.esm.js.map +1 -0
  20. package/dist/chunks/{index-VTO-b2vR.cjs → proxy-Cc79Lrzj.cjs} +2593 -3216
  21. package/dist/chunks/proxy-Cc79Lrzj.cjs.map +1 -0
  22. package/dist/chunks/{index-CtA2AWl3.esm.js → proxy-D2C49sXH.esm.js} +2570 -3174
  23. package/dist/chunks/proxy-D2C49sXH.esm.js.map +1 -0
  24. package/dist/debug.cjs +987 -28
  25. package/dist/debug.cjs.map +1 -1
  26. package/dist/debug.d.ts +37 -38
  27. package/dist/debug.esm.js +963 -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 +1322 -1
  34. package/dist/mutts.umd.js +6647 -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 +69 -63
  39. package/dist/node.cjs.map +1 -1
  40. package/dist/node.d.ts +2 -2
  41. package/dist/node.dev.cjs +114 -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-Bx2PhORg.d.ts} +134 -88
  49. package/docs/ai/api-reference.md +11 -32
  50. package/docs/ai/manual.md +297 -239
  51. package/docs/reactive/advanced.md +318 -9
  52. package/docs/reactive/attend.md +2 -4
  53. package/docs/reactive/collections.md +22 -187
  54. package/docs/reactive/core.md +223 -131
  55. package/docs/reactive/debugging.md +119 -12
  56. package/docs/reactive/error-handling.md +10 -10
  57. package/docs/reactive/resource.md +125 -0
  58. package/docs/reactive.md +3 -4
  59. package/docs/utils.md +70 -0
  60. package/docs/zone.md +1 -1
  61. package/package.json +76 -38
  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 +0 -3011
  65. package/dist/chunks/index-2vea86wD.esm.js.map +0 -1
  66. package/dist/chunks/index-CtA2AWl3.esm.js.map +0 -1
  67. package/dist/chunks/index-VTO-b2vR.cjs.map +0 -1
  68. package/dist/debug/debug.d.ts +0 -122
  69. package/dist/debug/debug.d.ts.map +0 -1
  70. package/dist/debug/index.d.ts +0 -4
  71. package/dist/debug/index.d.ts.map +0 -1
  72. package/dist/debug/lineage-panel.d.ts +0 -5
  73. package/dist/debug/lineage-panel.d.ts.map +0 -1
  74. package/dist/debug/lineage.d.ts +0 -79
  75. package/dist/debug/lineage.d.ts.map +0 -1
  76. package/dist/src/async/browser.d.ts +0 -2
  77. package/dist/src/async/browser.d.ts.map +0 -1
  78. package/dist/src/async/index.d.ts +0 -19
  79. package/dist/src/async/index.d.ts.map +0 -1
  80. package/dist/src/async/node.d.ts +0 -2
  81. package/dist/src/async/node.d.ts.map +0 -1
  82. package/dist/src/decorator.d.ts +0 -106
  83. package/dist/src/decorator.d.ts.map +0 -1
  84. package/dist/src/destroyable.d.ts +0 -87
  85. package/dist/src/destroyable.d.ts.map +0 -1
  86. package/dist/src/entry-browser.d.ts +0 -3
  87. package/dist/src/entry-browser.d.ts.map +0 -1
  88. package/dist/src/entry-node.d.ts +0 -3
  89. package/dist/src/entry-node.d.ts.map +0 -1
  90. package/dist/src/eventful.d.ts +0 -20
  91. package/dist/src/eventful.d.ts.map +0 -1
  92. package/dist/src/flavored.d.ts +0 -33
  93. package/dist/src/flavored.d.ts.map +0 -1
  94. package/dist/src/index.d.ts +0 -14
  95. package/dist/src/index.d.ts.map +0 -1
  96. package/dist/src/indexable.d.ts +0 -243
  97. package/dist/src/indexable.d.ts.map +0 -1
  98. package/dist/src/introspection.d.ts +0 -27
  99. package/dist/src/introspection.d.ts.map +0 -1
  100. package/dist/src/iterableWeak.d.ts +0 -53
  101. package/dist/src/iterableWeak.d.ts.map +0 -1
  102. package/dist/src/mixins.d.ts +0 -25
  103. package/dist/src/mixins.d.ts.map +0 -1
  104. package/dist/src/promiseChain.d.ts +0 -20
  105. package/dist/src/promiseChain.d.ts.map +0 -1
  106. package/dist/src/reactive/array.d.ts +0 -48
  107. package/dist/src/reactive/array.d.ts.map +0 -1
  108. package/dist/src/reactive/buffer.d.ts +0 -120
  109. package/dist/src/reactive/buffer.d.ts.map +0 -1
  110. package/dist/src/reactive/change.d.ts +0 -29
  111. package/dist/src/reactive/change.d.ts.map +0 -1
  112. package/dist/src/reactive/deep-touch.d.ts +0 -28
  113. package/dist/src/reactive/deep-touch.d.ts.map +0 -1
  114. package/dist/src/reactive/deep-watch-state.d.ts +0 -25
  115. package/dist/src/reactive/deep-watch-state.d.ts.map +0 -1
  116. package/dist/src/reactive/deep-watch.d.ts +0 -20
  117. package/dist/src/reactive/deep-watch.d.ts.map +0 -1
  118. package/dist/src/reactive/describe.d.ts +0 -12
  119. package/dist/src/reactive/describe.d.ts.map +0 -1
  120. package/dist/src/reactive/effect-context.d.ts +0 -34
  121. package/dist/src/reactive/effect-context.d.ts.map +0 -1
  122. package/dist/src/reactive/effects.d.ts +0 -164
  123. package/dist/src/reactive/effects.d.ts.map +0 -1
  124. package/dist/src/reactive/index.d.ts +0 -19
  125. package/dist/src/reactive/index.d.ts.map +0 -1
  126. package/dist/src/reactive/map.d.ts +0 -28
  127. package/dist/src/reactive/map.d.ts.map +0 -1
  128. package/dist/src/reactive/memoize.d.ts +0 -28
  129. package/dist/src/reactive/memoize.d.ts.map +0 -1
  130. package/dist/src/reactive/non-reactive-state.d.ts +0 -9
  131. package/dist/src/reactive/non-reactive-state.d.ts.map +0 -1
  132. package/dist/src/reactive/non-reactive.d.ts +0 -11
  133. package/dist/src/reactive/non-reactive.d.ts.map +0 -1
  134. package/dist/src/reactive/project.d.ts +0 -40
  135. package/dist/src/reactive/project.d.ts.map +0 -1
  136. package/dist/src/reactive/proxy-state.d.ts +0 -8
  137. package/dist/src/reactive/proxy-state.d.ts.map +0 -1
  138. package/dist/src/reactive/proxy.d.ts +0 -23
  139. package/dist/src/reactive/proxy.d.ts.map +0 -1
  140. package/dist/src/reactive/record.d.ts +0 -115
  141. package/dist/src/reactive/record.d.ts.map +0 -1
  142. package/dist/src/reactive/register.d.ts +0 -125
  143. package/dist/src/reactive/register.d.ts.map +0 -1
  144. package/dist/src/reactive/registry.d.ts +0 -21
  145. package/dist/src/reactive/registry.d.ts.map +0 -1
  146. package/dist/src/reactive/set.d.ts +0 -26
  147. package/dist/src/reactive/set.d.ts.map +0 -1
  148. package/dist/src/reactive/tracking.d.ts +0 -7
  149. package/dist/src/reactive/tracking.d.ts.map +0 -1
  150. package/dist/src/reactive/types.d.ts +0 -424
  151. package/dist/src/reactive/types.d.ts.map +0 -1
  152. package/dist/src/reactive/watch.d.ts +0 -48
  153. package/dist/src/reactive/watch.d.ts.map +0 -1
  154. package/dist/src/std-decorators.d.ts +0 -45
  155. package/dist/src/std-decorators.d.ts.map +0 -1
  156. package/dist/src/utils.d.ts +0 -49
  157. package/dist/src/utils.d.ts.map +0 -1
  158. package/dist/src/zone.d.ts +0 -40
  159. package/dist/src/zone.d.ts.map +0 -1
  160. package/docs/reactive/describe.md +0 -85
  161. package/docs/reactive/project.md +0 -93
  162. package/docs/reactive/scan.md +0 -293
  163. package/src/async/browser.ts +0 -323
  164. package/src/async/index.ts +0 -27
  165. package/src/async/node.ts +0 -92
  166. package/src/decorator.ts +0 -272
  167. package/src/destroyable.ts +0 -199
  168. package/src/entry-browser.ts +0 -5
  169. package/src/entry-node.ts +0 -5
  170. package/src/eventful.ts +0 -110
  171. package/src/flavored.ts +0 -106
  172. package/src/index.d.ts +0 -12
  173. package/src/index.ts +0 -64
  174. package/src/indexable.ts +0 -526
  175. package/src/introspection.ts +0 -59
  176. package/src/iterableWeak.ts +0 -233
  177. package/src/mixins.ts +0 -123
  178. package/src/promiseChain.ts +0 -110
  179. package/src/reactive/array.ts +0 -500
  180. package/src/reactive/buffer.ts +0 -328
  181. package/src/reactive/change.ts +0 -131
  182. package/src/reactive/deep-touch.ts +0 -273
  183. package/src/reactive/deep-watch-state.ts +0 -82
  184. package/src/reactive/deep-watch.ts +0 -171
  185. package/src/reactive/describe.ts +0 -39
  186. package/src/reactive/effect-context.ts +0 -83
  187. package/src/reactive/effects.ts +0 -1434
  188. package/src/reactive/index.ts +0 -72
  189. package/src/reactive/map.ts +0 -142
  190. package/src/reactive/memoize.ts +0 -186
  191. package/src/reactive/non-reactive-state.ts +0 -49
  192. package/src/reactive/non-reactive.ts +0 -43
  193. package/src/reactive/project.md +0 -107
  194. package/src/reactive/project.ts +0 -430
  195. package/src/reactive/proxy-state.ts +0 -27
  196. package/src/reactive/proxy.ts +0 -282
  197. package/src/reactive/record.ts +0 -181
  198. package/src/reactive/register.ts +0 -538
  199. package/src/reactive/registry.ts +0 -72
  200. package/src/reactive/set.ts +0 -117
  201. package/src/reactive/tracking.ts +0 -41
  202. package/src/reactive/types.ts +0 -520
  203. package/src/reactive/watch.ts +0 -180
  204. package/src/std-decorators.ts +0 -256
  205. package/src/utils.ts +0 -300
  206. 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
- }