mutts 1.0.1 → 1.0.3

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 (111) hide show
  1. package/README.md +36 -6
  2. package/dist/chunks/_tslib-BgjropY9.js +81 -0
  3. package/dist/chunks/_tslib-BgjropY9.js.map +1 -0
  4. package/dist/chunks/_tslib-Mzh1rNsX.esm.js +75 -0
  5. package/dist/chunks/_tslib-Mzh1rNsX.esm.js.map +1 -0
  6. package/dist/chunks/{decorator-8qjFb7dw.js → decorator-DLvrD0UF.js} +103 -14
  7. package/dist/chunks/decorator-DLvrD0UF.js.map +1 -0
  8. package/dist/chunks/{decorator-AbRkXM5O.esm.js → decorator-DqiszP7i.esm.js} +100 -15
  9. package/dist/chunks/decorator-DqiszP7i.esm.js.map +1 -0
  10. package/dist/chunks/index-DzUDtFc7.esm.js +4841 -0
  11. package/dist/chunks/index-DzUDtFc7.esm.js.map +1 -0
  12. package/dist/chunks/index-HNVqPzjz.js +4891 -0
  13. package/dist/chunks/index-HNVqPzjz.js.map +1 -0
  14. package/dist/decorator.d.ts +57 -0
  15. package/dist/decorator.esm.js +1 -1
  16. package/dist/decorator.js +1 -1
  17. package/dist/destroyable.d.ts +43 -1
  18. package/dist/destroyable.esm.js +19 -1
  19. package/dist/destroyable.esm.js.map +1 -1
  20. package/dist/destroyable.js +19 -1
  21. package/dist/destroyable.js.map +1 -1
  22. package/dist/devtools/devtools.html +9 -0
  23. package/dist/devtools/devtools.js +5 -0
  24. package/dist/devtools/devtools.js.map +1 -0
  25. package/dist/devtools/manifest.json +8 -0
  26. package/dist/devtools/panel.css +72 -0
  27. package/dist/devtools/panel.html +31 -0
  28. package/dist/devtools/panel.js +13048 -0
  29. package/dist/devtools/panel.js.map +1 -0
  30. package/dist/eventful.d.ts +10 -1
  31. package/dist/eventful.esm.js +5 -27
  32. package/dist/eventful.esm.js.map +1 -1
  33. package/dist/eventful.js +15 -37
  34. package/dist/eventful.js.map +1 -1
  35. package/dist/index.d.ts +18 -14
  36. package/dist/index.esm.js +4 -3
  37. package/dist/index.esm.js.map +1 -1
  38. package/dist/index.js +44 -5
  39. package/dist/index.js.map +1 -1
  40. package/dist/indexable.d.ts +213 -1
  41. package/dist/indexable.esm.js +203 -3
  42. package/dist/indexable.esm.js.map +1 -1
  43. package/dist/indexable.js +204 -2
  44. package/dist/indexable.js.map +1 -1
  45. package/dist/mutts.umd.js +1 -1
  46. package/dist/mutts.umd.js.map +1 -1
  47. package/dist/mutts.umd.min.js +1 -1
  48. package/dist/mutts.umd.min.js.map +1 -1
  49. package/dist/promiseChain.d.ts +10 -0
  50. package/dist/promiseChain.esm.js +6 -0
  51. package/dist/promiseChain.esm.js.map +1 -1
  52. package/dist/promiseChain.js +6 -0
  53. package/dist/promiseChain.js.map +1 -1
  54. package/dist/reactive.d.ts +774 -33
  55. package/dist/reactive.esm.js +4 -1458
  56. package/dist/reactive.esm.js.map +1 -1
  57. package/dist/reactive.js +53 -1474
  58. package/dist/reactive.js.map +1 -1
  59. package/dist/std-decorators.d.ts +35 -0
  60. package/dist/std-decorators.esm.js +36 -1
  61. package/dist/std-decorators.esm.js.map +1 -1
  62. package/dist/std-decorators.js +36 -1
  63. package/dist/std-decorators.js.map +1 -1
  64. package/docs/ai/api-reference.md +133 -0
  65. package/docs/ai/manual.md +105 -0
  66. package/docs/iterableWeak.md +646 -0
  67. package/docs/mixin.md +229 -0
  68. package/docs/reactive/advanced.md +1280 -0
  69. package/docs/reactive/collections.md +767 -0
  70. package/docs/reactive/core.md +973 -0
  71. package/docs/reactive.md +21 -2688
  72. package/package.json +18 -5
  73. package/src/decorator.ts +266 -0
  74. package/src/destroyable.ts +199 -0
  75. package/src/eventful.ts +77 -0
  76. package/src/index.d.ts +9 -0
  77. package/src/index.ts +9 -0
  78. package/src/indexable.ts +484 -0
  79. package/src/introspection.ts +59 -0
  80. package/src/iterableWeak.ts +233 -0
  81. package/src/mixins.ts +123 -0
  82. package/src/promiseChain.ts +110 -0
  83. package/src/reactive/array.ts +414 -0
  84. package/src/reactive/change.ts +134 -0
  85. package/src/reactive/debug.ts +517 -0
  86. package/src/reactive/deep-touch.ts +268 -0
  87. package/src/reactive/deep-watch-state.ts +82 -0
  88. package/src/reactive/deep-watch.ts +168 -0
  89. package/src/reactive/effect-context.ts +94 -0
  90. package/src/reactive/effects.ts +1333 -0
  91. package/src/reactive/index.ts +75 -0
  92. package/src/reactive/interface.ts +223 -0
  93. package/src/reactive/map.ts +171 -0
  94. package/src/reactive/mapped.ts +130 -0
  95. package/src/reactive/memoize.ts +107 -0
  96. package/src/reactive/non-reactive-state.ts +49 -0
  97. package/src/reactive/non-reactive.ts +43 -0
  98. package/src/reactive/project.project.md +93 -0
  99. package/src/reactive/project.ts +335 -0
  100. package/src/reactive/proxy-state.ts +27 -0
  101. package/src/reactive/proxy.ts +285 -0
  102. package/src/reactive/record.ts +196 -0
  103. package/src/reactive/register.ts +421 -0
  104. package/src/reactive/set.ts +144 -0
  105. package/src/reactive/tracking.ts +101 -0
  106. package/src/reactive/types.ts +358 -0
  107. package/src/reactive/zone.ts +208 -0
  108. package/src/std-decorators.ts +217 -0
  109. package/src/utils.ts +117 -0
  110. package/dist/chunks/decorator-8qjFb7dw.js.map +0 -1
  111. package/dist/chunks/decorator-AbRkXM5O.esm.js.map +0 -1
@@ -0,0 +1,484 @@
1
+ /**
2
+ * Symbol for defining custom getter logic for numeric index access
3
+ */
4
+ export const getAt = Symbol('getAt')
5
+ /**
6
+ * Symbol for defining custom setter logic for numeric index access
7
+ */
8
+ export const setAt = Symbol('setAt')
9
+
10
+ interface IndexingAt<Items = any> {
11
+ [getAt](index: number): Items
12
+ }
13
+
14
+ interface Accessor<T, Items> {
15
+ get(this: T, index: number): Items
16
+ set?(this: T, index: number, value: Items): void
17
+ getLength?(this: T): number
18
+ setLength?(this: T, value: number): void
19
+ }
20
+
21
+ abstract class AbstractGetAt<Items = any> {
22
+ abstract [getAt](index: number): Items
23
+ }
24
+
25
+ /**
26
+ * Creates an indexable class with a base class and accessor object
27
+ * @param base - The base class to extend
28
+ * @param accessor - Object containing get/set methods for numeric index access
29
+ * @returns A class that supports numeric index access
30
+ */
31
+ export function Indexable<Items, Base extends abstract new (...args: any[]) => any>(
32
+ base: Base,
33
+ accessor: Accessor<InstanceType<Base>, Items>
34
+ ): new (
35
+ ...args: ConstructorParameters<Base>
36
+ ) => InstanceType<Base> & { [x: number]: Items }
37
+
38
+ /**
39
+ * Creates an indexable class with only an accessor object (no base class)
40
+ * @param accessor - Object containing get/set methods for numeric index access
41
+ * @returns A class that supports numeric index access
42
+ */
43
+ export function Indexable<Items>(accessor: Accessor<any, Items>): new () => { [x: number]: Items }
44
+
45
+ /**
46
+ * Creates an indexable class with a base class that has [getAt] method
47
+ * @param base - The base class that implements [getAt] method
48
+ * @returns A class that supports numeric index access using the base class's [getAt] method
49
+ */
50
+ export function Indexable<Base extends new (...args: any[]) => IndexingAt>(
51
+ base: Base
52
+ ): new (
53
+ ...args: ConstructorParameters<Base>
54
+ ) => InstanceType<Base> & { [x: number]: AtReturnType<InstanceType<Base>> }
55
+
56
+ /**
57
+ * Creates an abstract indexable base class
58
+ * @returns An abstract class that supports numeric index access
59
+ */
60
+ export function Indexable<Items>(): abstract new (
61
+ ...args: any[]
62
+ ) => AbstractGetAt & { [x: number]: Items }
63
+
64
+ export function Indexable<Items, Base extends abstract new (...args: any[]) => any>(
65
+ base?: Base | Accessor<Base, Items>,
66
+ accessor?: Accessor<Base, Items>
67
+ ) {
68
+ if (base && typeof base !== 'function') {
69
+ accessor = base as Accessor<Base, Items>
70
+ base = undefined
71
+ }
72
+ if (!base) {
73
+ //@ts-expect-error
74
+ base = class {} as Base
75
+ }
76
+ if (!accessor) {
77
+ accessor = {
78
+ get(this: any, index: number) {
79
+ if (typeof this[getAt] !== 'function') {
80
+ throw new Error('Indexable class must have an [getAt] method')
81
+ }
82
+ return this[getAt](index)
83
+ },
84
+ set(this: any, index: number, value: Items) {
85
+ if (typeof this[setAt] !== 'function') {
86
+ throw new Error('Indexable class has read-only numeric index access')
87
+ }
88
+ this[setAt](index, value)
89
+ },
90
+ }
91
+ }
92
+
93
+ abstract class Indexable extends (base as Base) {
94
+ [x: number]: Items
95
+ }
96
+
97
+ Object.setPrototypeOf(
98
+ Indexable.prototype,
99
+ new Proxy((base as Base).prototype, {
100
+ //@ts-expect-error
101
+ [Symbol.toStringTag]: 'MutTs Indexable',
102
+ get(target, prop, receiver) {
103
+ if (prop in target) {
104
+ const getter = Object.getOwnPropertyDescriptor(target, prop)?.get
105
+ return getter ? getter.call(receiver) : target[prop]
106
+ }
107
+ if (typeof prop === 'string') {
108
+ if (prop === 'length' && accessor.getLength) return accessor.getLength.call(receiver)
109
+ const numProp = Number(prop)
110
+ if (!Number.isNaN(numProp)) {
111
+ return accessor.get!.call(receiver, numProp) as Items
112
+ }
113
+ }
114
+ return undefined
115
+ },
116
+ set(target, prop, value, receiver) {
117
+ if (prop in target) {
118
+ const setter = Object.getOwnPropertyDescriptor(target, prop)?.set
119
+ if (setter) setter.call(receiver, value)
120
+ else target[prop] = value
121
+ return true
122
+ }
123
+ if (typeof prop === 'string') {
124
+ if (prop === 'length' && accessor.setLength) {
125
+ accessor.setLength.call(receiver, value)
126
+ return true
127
+ }
128
+ const numProp = Number(prop)
129
+ if (!Number.isNaN(numProp)) {
130
+ if (!accessor.set) throw new Error('Indexable class has read-only numeric index access')
131
+ accessor.set!.call(receiver, numProp, value)
132
+ return true
133
+ }
134
+ }
135
+ Object.defineProperty(receiver, prop, {
136
+ value,
137
+ writable: true,
138
+ enumerable: true,
139
+ configurable: true,
140
+ })
141
+ return true
142
+ },
143
+ })
144
+ )
145
+ return Indexable
146
+ }
147
+
148
+ type AtReturnType<T> = T extends { [getAt](index: number): infer R } ? R : never
149
+
150
+ /**
151
+ * Symbol for accessing the forwarded array in ArrayReadForward
152
+ */
153
+ export const forwardArray = Symbol('forwardArray')
154
+
155
+ /**
156
+ * A read-only array forwarder that implements all reading/iterating methods of Array
157
+ * but does not implement modification methods.
158
+ *
159
+ * The constructor takes a callback that returns an array, and all methods forward
160
+ * their behavior to the result of that callback.
161
+ */
162
+ export class ArrayReadForward<T> {
163
+ protected get [forwardArray](): readonly T[] {
164
+ throw new Error('ArrayReadForward is not implemented')
165
+ }
166
+
167
+ /**
168
+ * Get the length of the array
169
+ */
170
+ get length(): number {
171
+ return this[forwardArray].length
172
+ }
173
+
174
+ /**
175
+ * Get an element at a specific index
176
+ */
177
+ [index: number]: T | undefined
178
+
179
+ /**
180
+ * Iterator protocol support
181
+ */
182
+ [Symbol.iterator](): Iterator<T> {
183
+ return this[forwardArray][Symbol.iterator]()
184
+ }
185
+
186
+ // Reading/Iterating methods
187
+
188
+ /**
189
+ * Creates a new array with the results of calling a provided function on every element
190
+ */
191
+ map<U>(callbackfn: (value: T, index: number, array: readonly T[]) => U, thisArg?: any): U[] {
192
+ return this[forwardArray].map(callbackfn, thisArg)
193
+ }
194
+
195
+ /**
196
+ * Creates a new array with all elements that pass the test implemented by the provided function
197
+ */
198
+ filter<S extends T>(
199
+ predicate: (value: T, index: number, array: readonly T[]) => value is S,
200
+ thisArg?: any
201
+ ): S[]
202
+ filter(predicate: (value: T, index: number, array: readonly T[]) => unknown, thisArg?: any): T[]
203
+ filter(predicate: (value: T, index: number, array: readonly T[]) => unknown, thisArg?: any): T[] {
204
+ return this[forwardArray].filter(predicate, thisArg)
205
+ }
206
+
207
+ /**
208
+ * Executes a reducer function on each element of the array, resulting in a single output value
209
+ */
210
+ reduce(
211
+ callbackfn: (previousValue: T, currentValue: T, currentIndex: number, array: readonly T[]) => T
212
+ ): T
213
+ reduce(
214
+ callbackfn: (previousValue: T, currentValue: T, currentIndex: number, array: readonly T[]) => T,
215
+ initialValue: T
216
+ ): T
217
+ reduce<U>(
218
+ callbackfn: (previousValue: U, currentValue: T, currentIndex: number, array: readonly T[]) => U,
219
+ initialValue: U
220
+ ): U
221
+ reduce(
222
+ callbackfn: (
223
+ previousValue: any,
224
+ currentValue: T,
225
+ currentIndex: number,
226
+ array: readonly T[]
227
+ ) => any,
228
+ initialValue?: any
229
+ ): any {
230
+ return initialValue !== undefined
231
+ ? this[forwardArray].reduce(callbackfn, initialValue)
232
+ : this[forwardArray].reduce(callbackfn)
233
+ }
234
+
235
+ /**
236
+ * Executes a reducer function on each element of the array (right-to-left), resulting in a single output value
237
+ */
238
+ reduceRight(
239
+ callbackfn: (previousValue: T, currentValue: T, currentIndex: number, array: readonly T[]) => T
240
+ ): T
241
+ reduceRight(
242
+ callbackfn: (previousValue: T, currentValue: T, currentIndex: number, array: readonly T[]) => T,
243
+ initialValue: T
244
+ ): T
245
+ reduceRight<U>(
246
+ callbackfn: (previousValue: U, currentValue: T, currentIndex: number, array: readonly T[]) => U,
247
+ initialValue: U
248
+ ): U
249
+ reduceRight(
250
+ callbackfn: (
251
+ previousValue: any,
252
+ currentValue: T,
253
+ currentIndex: number,
254
+ array: readonly T[]
255
+ ) => any,
256
+ initialValue?: any
257
+ ): any {
258
+ return initialValue !== undefined
259
+ ? this[forwardArray].reduceRight(callbackfn, initialValue)
260
+ : this[forwardArray].reduceRight(callbackfn)
261
+ }
262
+
263
+ /**
264
+ * Executes a provided function once for each array element
265
+ */
266
+ forEach(callbackfn: (value: T, index: number, array: readonly T[]) => void, thisArg?: any): void {
267
+ this[forwardArray].forEach(callbackfn, thisArg)
268
+ }
269
+
270
+ /**
271
+ * Returns the value of the first element in the array that satisfies the provided testing function
272
+ */
273
+ find<S extends T>(
274
+ predicate: (value: T, index: number, array: readonly T[]) => value is S,
275
+ thisArg?: any
276
+ ): S | undefined
277
+ find(
278
+ predicate: (value: T, index: number, array: readonly T[]) => unknown,
279
+ thisArg?: any
280
+ ): T | undefined
281
+ find(
282
+ predicate: (value: T, index: number, array: readonly T[]) => unknown,
283
+ thisArg?: any
284
+ ): T | undefined {
285
+ return this[forwardArray].find(predicate, thisArg)
286
+ }
287
+
288
+ /**
289
+ * Returns the index of the first element in the array that satisfies the provided testing function
290
+ */
291
+ findIndex(
292
+ predicate: (value: T, index: number, array: readonly T[]) => unknown,
293
+ thisArg?: any
294
+ ): number {
295
+ return this[forwardArray].findIndex(predicate, thisArg)
296
+ }
297
+
298
+ /**
299
+ * Returns the value of the last element in the array that satisfies the provided testing function
300
+ */
301
+ findLast<S extends T>(
302
+ predicate: (value: T, index: number, array: readonly T[]) => value is S,
303
+ thisArg?: any
304
+ ): S | undefined
305
+ findLast(
306
+ predicate: (value: T, index: number, array: readonly T[]) => unknown,
307
+ thisArg?: any
308
+ ): T | undefined
309
+ findLast(
310
+ predicate: (value: T, index: number, array: readonly T[]) => unknown,
311
+ thisArg?: any
312
+ ): T | undefined {
313
+ return this[forwardArray].findLast(predicate, thisArg)
314
+ }
315
+
316
+ /**
317
+ * Returns the index of the last element in the array that satisfies the provided testing function
318
+ */
319
+ findLastIndex(
320
+ predicate: (value: T, index: number, array: readonly T[]) => unknown,
321
+ thisArg?: any
322
+ ): number {
323
+ return this[forwardArray].findLastIndex(predicate, thisArg)
324
+ }
325
+
326
+ /**
327
+ * Determines whether an array includes a certain value among its entries
328
+ */
329
+ includes(searchElement: T, fromIndex?: number): boolean {
330
+ return this[forwardArray].includes(searchElement, fromIndex)
331
+ }
332
+
333
+ /**
334
+ * Returns the first index at which a given element can be found in the array
335
+ */
336
+ indexOf(searchElement: T, fromIndex?: number): number {
337
+ return this[forwardArray].indexOf(searchElement, fromIndex)
338
+ }
339
+
340
+ /**
341
+ * Returns the last index at which a given element can be found in the array
342
+ */
343
+ lastIndexOf(searchElement: T, fromIndex?: number): number {
344
+ return this[forwardArray].lastIndexOf(searchElement, fromIndex)
345
+ }
346
+
347
+ /**
348
+ * Returns a shallow copy of a portion of an array into a new array object
349
+ */
350
+ slice(start?: number, end?: number): T[] {
351
+ return this[forwardArray].slice(start, end)
352
+ }
353
+
354
+ /**
355
+ * Returns a new array comprised of this array joined with other array(s) and/or value(s)
356
+ */
357
+ concat(...items: ConcatArray<T>[]): T[]
358
+ concat(...items: (T | ConcatArray<T>)[]): T[]
359
+ concat(...items: (T | ConcatArray<T>)[]): T[] {
360
+ return this[forwardArray].concat(...items)
361
+ }
362
+
363
+ /**
364
+ * Tests whether all elements in the array pass the test implemented by the provided function
365
+ */
366
+ every(
367
+ predicate: (value: T, index: number, array: readonly T[]) => unknown,
368
+ thisArg?: any
369
+ ): boolean {
370
+ return this[forwardArray].every(predicate, thisArg)
371
+ }
372
+
373
+ /**
374
+ * Tests whether at least one element in the array passes the test implemented by the provided function
375
+ */
376
+ some(
377
+ predicate: (value: T, index: number, array: readonly T[]) => unknown,
378
+ thisArg?: any
379
+ ): boolean {
380
+ return this[forwardArray].some(predicate, thisArg)
381
+ }
382
+
383
+ /**
384
+ * Joins all elements of an array into a string
385
+ */
386
+ join(separator?: string): string {
387
+ return this[forwardArray].join(separator)
388
+ }
389
+
390
+ /**
391
+ * Returns a new array iterator that contains the keys for each index in the array
392
+ */
393
+ keys(): IterableIterator<number> {
394
+ return this[forwardArray].keys()
395
+ }
396
+
397
+ /**
398
+ * Returns a new array iterator that contains the values for each index in the array
399
+ */
400
+ values(): IterableIterator<T> {
401
+ return this[forwardArray].values()
402
+ }
403
+
404
+ /**
405
+ * Returns a new array iterator that contains the key/value pairs for each index in the array
406
+ */
407
+ entries(): IterableIterator<[number, T]> {
408
+ return this[forwardArray].entries()
409
+ }
410
+
411
+ /**
412
+ * Returns a string representation of the array
413
+ */
414
+ toString(): string {
415
+ return this[forwardArray].toString()
416
+ }
417
+
418
+ /**
419
+ * Returns a localized string representing the array
420
+ */
421
+ toLocaleString(
422
+ locales?: string | string[],
423
+ options?: Intl.NumberFormatOptions | Intl.DateTimeFormatOptions
424
+ ): string {
425
+ return this[forwardArray].toLocaleString(locales as string | string[], options)
426
+ }
427
+
428
+ /**
429
+ * Returns the element at the specified index, or undefined if the index is out of bounds
430
+ */
431
+ at(index: number): T | undefined {
432
+ return this[forwardArray].at(index)
433
+ }
434
+
435
+ /**
436
+ * Returns a new array with all sub-array elements concatenated into it recursively up to the specified depth
437
+ */
438
+ flat(depth?: number): T[] {
439
+ return this[forwardArray].flat(depth) as T[]
440
+ }
441
+
442
+ /**
443
+ * Returns a new array formed by applying a given callback function to each element of the array,
444
+ * and then flattening the result by one level
445
+ */
446
+ flatMap<U, This = undefined>(
447
+ callback: (this: This, value: T, index: number, array: readonly T[]) => U | ReadonlyArray<U>,
448
+ thisArg?: This
449
+ ): U[] {
450
+ return this[forwardArray].flatMap(callback as any, thisArg)
451
+ }
452
+
453
+ /**
454
+ * Returns a new array with elements in reversed order (ES2023)
455
+ */
456
+ toReversed(): T[] {
457
+ return this[forwardArray].toReversed?.() ?? [...this[forwardArray]].reverse()
458
+ }
459
+
460
+ /**
461
+ * Returns a new array with elements sorted (ES2023)
462
+ */
463
+ toSorted(compareFn?: ((a: T, b: T) => number) | undefined): T[] {
464
+ return this[forwardArray].toSorted?.(compareFn) ?? [...this[forwardArray]].sort(compareFn)
465
+ }
466
+
467
+ /**
468
+ * Returns a new array with some elements removed and/or replaced at a given index (ES2023)
469
+ */
470
+ toSpliced(start: number, deleteCount?: number, ...items: T[]): T[] {
471
+ if (deleteCount === undefined) return this[forwardArray].toSpliced(start)
472
+ return this[forwardArray].toSpliced(start, deleteCount, ...items)
473
+ }
474
+
475
+ /**
476
+ * Returns a new array with the element at the given index replaced with the given value (ES2023)
477
+ */
478
+ with(index: number, value: T): T[] {
479
+ return this[forwardArray].with(index, value)
480
+ }
481
+ get [Symbol.unscopables]() {
482
+ return this[forwardArray][Symbol.unscopables]
483
+ }
484
+ }
@@ -0,0 +1,59 @@
1
+ /**
2
+ * Introspection API for Mutts
3
+ * Designed for AI agents and advanced debugging tools to programmatically analyze the reactive system.
4
+ */
5
+
6
+ import {
7
+ type EffectNode,
8
+ forceEnableGraphTracking,
9
+ type GraphEdge,
10
+ getDependencies,
11
+ getDependencyGraph,
12
+ getDependents,
13
+ getMutationHistory,
14
+ type MutationRecord,
15
+ type ObjectNode,
16
+ type ReactivityGraph,
17
+ } from './reactive/debug'
18
+ import { options, type ReactiveDebugInfo, ReactiveErrorCode } from './reactive/types'
19
+
20
+ export {
21
+ getDependencyGraph,
22
+ getDependents,
23
+ getDependencies,
24
+ getMutationHistory,
25
+ options,
26
+ ReactiveErrorCode,
27
+ }
28
+
29
+ export type {
30
+ MutationRecord,
31
+ ReactivityGraph,
32
+ EffectNode,
33
+ ObjectNode,
34
+ GraphEdge,
35
+ ReactiveDebugInfo,
36
+ }
37
+
38
+ /**
39
+ * Enable introspection features (history recording, etc.)
40
+ * @param config Configuration options
41
+ */
42
+ export function enableIntrospection(config: { historySize?: number } = {}) {
43
+ options.introspection.enableHistory = true
44
+ forceEnableGraphTracking()
45
+ if (config.historySize) {
46
+ options.introspection.historySize = config.historySize
47
+ }
48
+ }
49
+
50
+ /**
51
+ * Capture a complete snapshot of the current reactive state
52
+ */
53
+ export function snapshot() {
54
+ return {
55
+ graph: getDependencyGraph(),
56
+ history: getMutationHistory(),
57
+ timestamp: Date.now(),
58
+ }
59
+ }