mutts 1.0.0 → 1.0.2

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 (85) hide show
  1. package/README.md +24 -2
  2. package/dist/chunks/_tslib-C-cuVLvZ.js +73 -0
  3. package/dist/chunks/_tslib-C-cuVLvZ.js.map +1 -0
  4. package/dist/chunks/_tslib-CMEnd0VE.esm.js +68 -0
  5. package/dist/chunks/_tslib-CMEnd0VE.esm.js.map +1 -0
  6. package/dist/chunks/{decorator-BXsign4Z.js → decorator-D4DU97Zg.js} +70 -4
  7. package/dist/chunks/decorator-D4DU97Zg.js.map +1 -0
  8. package/dist/chunks/{decorator-CPbZNnsX.esm.js → decorator-GnHw1Az7.esm.js} +67 -5
  9. package/dist/chunks/decorator-GnHw1Az7.esm.js.map +1 -0
  10. package/dist/chunks/index-DBScoeCX.esm.js +1960 -0
  11. package/dist/chunks/index-DBScoeCX.esm.js.map +1 -0
  12. package/dist/chunks/index-DOTmXL89.js +1983 -0
  13. package/dist/chunks/index-DOTmXL89.js.map +1 -0
  14. package/dist/decorator.d.ts +58 -1
  15. package/dist/decorator.esm.js +1 -1
  16. package/dist/decorator.js +1 -1
  17. package/dist/destroyable.d.ts +42 -0
  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/eventful.d.ts +10 -1
  23. package/dist/eventful.esm.js +5 -27
  24. package/dist/eventful.esm.js.map +1 -1
  25. package/dist/eventful.js +15 -37
  26. package/dist/eventful.js.map +1 -1
  27. package/dist/index.d.ts +52 -3
  28. package/dist/index.esm.js +3 -2
  29. package/dist/index.esm.js.map +1 -1
  30. package/dist/index.js +18 -3
  31. package/dist/index.js.map +1 -1
  32. package/dist/indexable.d.ts +26 -0
  33. package/dist/indexable.esm.js +6 -0
  34. package/dist/indexable.esm.js.map +1 -1
  35. package/dist/indexable.js +6 -0
  36. package/dist/indexable.js.map +1 -1
  37. package/dist/mutts.umd.js +1 -1
  38. package/dist/mutts.umd.js.map +1 -1
  39. package/dist/mutts.umd.min.js +1 -1
  40. package/dist/mutts.umd.min.js.map +1 -1
  41. package/dist/promiseChain.d.ts +10 -0
  42. package/dist/promiseChain.esm.js +6 -0
  43. package/dist/promiseChain.esm.js.map +1 -1
  44. package/dist/promiseChain.js +6 -0
  45. package/dist/promiseChain.js.map +1 -1
  46. package/dist/reactive.d.ts +258 -20
  47. package/dist/reactive.esm.js +4 -1454
  48. package/dist/reactive.esm.js.map +1 -1
  49. package/dist/reactive.js +29 -1466
  50. package/dist/reactive.js.map +1 -1
  51. package/dist/std-decorators.d.ts +35 -0
  52. package/dist/std-decorators.esm.js +36 -1
  53. package/dist/std-decorators.esm.js.map +1 -1
  54. package/dist/std-decorators.js +36 -1
  55. package/dist/std-decorators.js.map +1 -1
  56. package/docs/mixin.md +229 -0
  57. package/docs/reactive.md +7931 -458
  58. package/package.json +1 -2
  59. package/dist/chunks/decorator-BXsign4Z.js.map +0 -1
  60. package/dist/chunks/decorator-CPbZNnsX.esm.js.map +0 -1
  61. package/src/decorator.test.ts +0 -495
  62. package/src/decorator.ts +0 -205
  63. package/src/destroyable.test.ts +0 -155
  64. package/src/destroyable.ts +0 -158
  65. package/src/eventful.test.ts +0 -380
  66. package/src/eventful.ts +0 -69
  67. package/src/index.ts +0 -7
  68. package/src/indexable.test.ts +0 -388
  69. package/src/indexable.ts +0 -124
  70. package/src/promiseChain.test.ts +0 -201
  71. package/src/promiseChain.ts +0 -99
  72. package/src/reactive/array.test.ts +0 -923
  73. package/src/reactive/array.ts +0 -352
  74. package/src/reactive/core.test.ts +0 -1663
  75. package/src/reactive/core.ts +0 -866
  76. package/src/reactive/index.ts +0 -28
  77. package/src/reactive/interface.test.ts +0 -1477
  78. package/src/reactive/interface.ts +0 -231
  79. package/src/reactive/map.test.ts +0 -866
  80. package/src/reactive/map.ts +0 -162
  81. package/src/reactive/set.test.ts +0 -289
  82. package/src/reactive/set.ts +0 -142
  83. package/src/std-decorators.test.ts +0 -679
  84. package/src/std-decorators.ts +0 -182
  85. package/src/utils.ts +0 -52
@@ -1,923 +0,0 @@
1
- import { effect, reactive, unwrap } from './index'
2
-
3
- describe('ReactiveArray', () => {
4
- describe('numeric index reactivity', () => {
5
- it('should track dependencies when accessing numeric indexes', () => {
6
- const array = [1, 2, 3]
7
- const reactiveArray = reactive(array)
8
-
9
- let effectCount = 0
10
- effect(() => {
11
- effectCount++
12
- reactiveArray[0] // Access first element
13
- })
14
-
15
- expect(effectCount).toBe(1)
16
-
17
- // Changing the value should trigger the effect
18
- reactiveArray[0] = 100
19
- expect(effectCount).toBe(2)
20
- })
21
-
22
- it('should track dependencies when accessing multiple indexes', () => {
23
- const array = [1, 2, 3]
24
- const reactiveArray = reactive(array)
25
-
26
- let effectCount = 0
27
- effect(() => {
28
- effectCount++
29
- reactiveArray[1] // Access second element
30
- reactiveArray[2] // Access third element
31
- })
32
-
33
- expect(effectCount).toBe(1)
34
-
35
- // Changing either index should trigger the effect
36
- reactiveArray[1] = 200
37
- expect(effectCount).toBe(2)
38
-
39
- reactiveArray[2] = 300
40
- expect(effectCount).toBe(3)
41
- })
42
-
43
- it('should handle out-of-bounds index access', () => {
44
- const array = [1, 2, 3]
45
- const reactiveArray = reactive(array)
46
-
47
- let effectCount = 0
48
- effect(() => {
49
- effectCount++
50
- reactiveArray[5] // Access out-of-bounds index
51
- })
52
-
53
- expect(effectCount).toBe(1)
54
-
55
- // Setting an out-of-bounds index should trigger the effect
56
- reactiveArray[5] = 999
57
- expect(effectCount).toBe(2)
58
- })
59
- })
60
-
61
- describe('length reactivity', () => {
62
- it('should track dependencies when pushing', () => {
63
- const array = [1, 2, 3]
64
- const reactiveArray = reactive(array)
65
-
66
- let effectCount = 0
67
- effect(() => {
68
- effectCount++
69
- reactiveArray[4]
70
- })
71
-
72
- expect(effectCount).toBe(1)
73
- // Adding an element should not trigger the effect
74
- reactiveArray.push(4)
75
- expect(effectCount).toBe(1)
76
- // Adding another element should trigger the effect
77
- reactiveArray.push(5)
78
- expect(effectCount).toBe(2)
79
- })
80
-
81
- it('should track dependencies when length changes due to index assignment', () => {
82
- const array = [1, 2, 3]
83
- const reactiveArray = reactive(array)
84
-
85
- let effectCount = 0
86
- effect(() => {
87
- effectCount++
88
- reactiveArray.length
89
- })
90
-
91
- expect(effectCount).toBe(1)
92
-
93
- // Setting an index beyond current length should trigger the effect
94
- reactiveArray[5] = 999
95
- expect(effectCount).toBe(2)
96
- expect(reactiveArray.length).toBe(6)
97
- })
98
-
99
- it('should track dependencies when length changes due to push', () => {
100
- const array = [1, 2, 3]
101
- const reactiveArray = reactive(array)
102
-
103
- let effectCount = 0
104
- effect(() => {
105
- effectCount++
106
- reactiveArray.length
107
- })
108
-
109
- expect(effectCount).toBe(1)
110
-
111
- // Push should trigger the effect
112
- reactiveArray.push(4, 5)
113
- expect(effectCount).toBe(2)
114
- expect(reactiveArray.length).toBe(5)
115
- })
116
-
117
- it('should track dependencies when length changes due to pop', () => {
118
- const array = [1, 2, 3]
119
- const reactiveArray = reactive(array)
120
-
121
- let effectCount = 0
122
- effect(() => {
123
- effectCount++
124
- reactiveArray.length
125
- })
126
-
127
- expect(effectCount).toBe(1)
128
-
129
- // Pop should trigger the effect
130
- reactiveArray.pop()
131
- expect(effectCount).toBe(2)
132
- expect(reactiveArray.length).toBe(2)
133
- })
134
- })
135
-
136
- describe('push and pop methods', () => {
137
- it('should handle push with reactivity', () => {
138
- const array = [1, 2, 3]
139
- const reactiveArray = reactive(array)
140
-
141
- let effectCount = 0
142
- effect(() => {
143
- effectCount++
144
- reactiveArray[3] // Access index that will be created
145
- })
146
-
147
- expect(effectCount).toBe(1)
148
- expect(reactiveArray.length).toBe(3)
149
-
150
- reactiveArray.push(4)
151
- expect(effectCount).toBe(2)
152
- expect(reactiveArray.length).toBe(4)
153
- expect(reactiveArray[3]).toBe(4)
154
- })
155
-
156
- it('should handle pop with reactivity', () => {
157
- const array = [1, 2, 3]
158
- const reactiveArray = reactive(array)
159
-
160
- let effectCount = 0
161
- effect(() => {
162
- effectCount++
163
- reactiveArray[2] // Access last element
164
- })
165
-
166
- expect(effectCount).toBe(1)
167
- expect(reactiveArray.length).toBe(3)
168
-
169
- const popped = reactiveArray.pop()
170
- expect(effectCount).toBe(2)
171
- expect(reactiveArray.length).toBe(2)
172
- expect(popped).toBe(3)
173
- })
174
- })
175
-
176
- describe('shift and unshift methods', () => {
177
- it('should handle shift with reactivity', () => {
178
- const array = [1, 2, 3]
179
- const reactiveArray = reactive(array)
180
-
181
- let effectCount = 0
182
- effect(() => {
183
- effectCount++
184
- reactiveArray[0] // Access first element
185
- reactiveArray[1] // Access second element
186
- })
187
-
188
- expect(effectCount).toBe(1)
189
-
190
- const shifted = reactiveArray.shift()
191
- expect(effectCount).toBe(2)
192
- expect(shifted).toBe(1)
193
- expect(reactiveArray[0]).toBe(2)
194
- expect(reactiveArray[1]).toBe(3)
195
- expect(reactiveArray.length).toBe(2)
196
- })
197
-
198
- it('should handle unshift with reactivity', () => {
199
- const array = [1, 2, 3]
200
- const reactiveArray = reactive(array)
201
-
202
- let effectCount = 0
203
- effect(() => {
204
- effectCount++
205
- reactiveArray[0] // Access first element
206
- reactiveArray[2] // Access third element
207
- })
208
-
209
- expect(effectCount).toBe(1)
210
-
211
- reactiveArray.unshift(0)
212
- expect(effectCount).toBe(2)
213
- expect(reactiveArray[0]).toBe(0)
214
- expect(reactiveArray[1]).toBe(1)
215
- expect(reactiveArray[3]).toBe(3)
216
- expect(reactiveArray.length).toBe(4)
217
- })
218
- })
219
-
220
- describe('splice method', () => {
221
- it('should handle splice with deletion only', () => {
222
- const array = [1, 2, 3, 4, 5]
223
- const reactiveArray = reactive(array)
224
-
225
- let effectCount = 0
226
- effect(() => {
227
- effectCount++
228
- reactiveArray[1] // Access second element
229
- reactiveArray[3] // Access fourth element
230
- })
231
-
232
- expect(effectCount).toBe(1)
233
-
234
- const removed = reactiveArray.splice(1, 2)
235
- expect(effectCount).toBe(2)
236
- expect(unwrap(removed)).toEqual([2, 3])
237
- expect(reactiveArray[1]).toBe(4)
238
- expect(reactiveArray[2]).toBe(5)
239
- expect(reactiveArray.length).toBe(3)
240
- })
241
-
242
- it('should handle splice with insertion only', () => {
243
- const array = [1, 2, 3]
244
- const reactiveArray = reactive(array)
245
-
246
- let effectCount = 0
247
- effect(() => {
248
- effectCount++
249
- reactiveArray[1] // Access second element
250
- reactiveArray[3] // Access index that will be created
251
- })
252
-
253
- expect(effectCount).toBe(1)
254
-
255
- reactiveArray.splice(1, 0, 10, 20)
256
- expect(effectCount).toBe(2)
257
- expect(reactiveArray[1]).toBe(10)
258
- expect(reactiveArray[2]).toBe(20)
259
- expect(reactiveArray[3]).toBe(2)
260
- expect(reactiveArray.length).toBe(5)
261
- })
262
-
263
- it('should handle splice with replacement', () => {
264
- const array = [1, 2, 3, 4]
265
- const reactiveArray = reactive(array)
266
-
267
- let effectCount = 0
268
- effect(() => {
269
- effectCount++
270
- reactiveArray[1] // Access second element
271
- reactiveArray[2] // Access third element
272
- })
273
-
274
- expect(effectCount).toBe(1)
275
-
276
- const removed = reactiveArray.splice(1, 2, 10, 20)
277
- expect(effectCount).toBe(2)
278
- expect(unwrap(removed)).toEqual([2, 3])
279
- expect(reactiveArray[1]).toBe(10)
280
- expect(reactiveArray[2]).toBe(20)
281
- expect(reactiveArray.length).toBe(4)
282
- })
283
-
284
- it('should handle splice with negative start index', () => {
285
- const array = [1, 2, 3, 4, 5]
286
- const reactiveArray = reactive(array)
287
-
288
- let effectCount = 0
289
- effect(() => {
290
- effectCount++
291
- reactiveArray[3] // Access fourth element
292
- })
293
-
294
- expect(effectCount).toBe(1)
295
-
296
- reactiveArray.splice(-2, 1)
297
- expect(effectCount).toBe(2)
298
- expect(reactiveArray[3]).toBe(5)
299
- expect(reactiveArray.length).toBe(4)
300
- })
301
-
302
- it('should handle splice without deleteCount parameter', () => {
303
- const array = [1, 2, 3, 4, 5]
304
- const reactiveArray = reactive(array)
305
-
306
- let effectCount = 0
307
- effect(() => {
308
- effectCount++
309
- reactiveArray[1] // Access second element
310
- })
311
-
312
- expect(effectCount).toBe(1)
313
-
314
- const removed = reactiveArray.splice(1)
315
- expect(effectCount).toBe(2)
316
- expect(unwrap(removed)).toEqual([2, 3, 4, 5])
317
- expect(reactiveArray.length).toBe(1)
318
- })
319
- })
320
-
321
- describe('reverse method', () => {
322
- it('should handle reverse with reactivity', () => {
323
- const array = [1, 2, 3, 4]
324
- const reactiveArray = reactive(array)
325
-
326
- let effectCount = 0
327
- effect(() => {
328
- effectCount++
329
- reactiveArray[0] // Access first element
330
- reactiveArray[3] // Access last element
331
- })
332
-
333
- expect(effectCount).toBe(1)
334
-
335
- reactiveArray.reverse()
336
- expect(effectCount).toBe(2)
337
- expect(reactiveArray[0]).toBe(4)
338
- expect(reactiveArray[3]).toBe(1)
339
- })
340
- })
341
-
342
- describe('sort method', () => {
343
- it('should handle sort with reactivity', () => {
344
- const array = [3, 1, 4, 2]
345
- const reactiveArray = reactive(array)
346
-
347
- let effectCount = 0
348
- effect(() => {
349
- effectCount++
350
- reactiveArray[0] // Access first element
351
- reactiveArray[2] // Access third element
352
- })
353
-
354
- expect(effectCount).toBe(1)
355
-
356
- reactiveArray.sort()
357
- expect(effectCount).toBe(2)
358
- expect(reactiveArray[0]).toBe(1)
359
- expect(reactiveArray[2]).toBe(3)
360
- })
361
-
362
- it('should handle sort with compare function', () => {
363
- const array = [3, 1, 4, 2]
364
- const reactiveArray = reactive(array)
365
-
366
- let effectCount = 0
367
- effect(() => {
368
- effectCount++
369
- reactiveArray[0] // Access first element
370
- })
371
-
372
- expect(effectCount).toBe(1)
373
-
374
- reactiveArray.sort((a, b) => b - a) // Descending order
375
- expect(effectCount).toBe(2)
376
- expect(reactiveArray[0]).toBe(4)
377
- })
378
- })
379
-
380
- describe('fill method', () => {
381
- it('should handle fill with reactivity', () => {
382
- const array = [1, 2, 3, 4, 5]
383
- const reactiveArray = reactive(array)
384
-
385
- let effectCount = 0
386
- effect(() => {
387
- effectCount++
388
- reactiveArray[1] // Access second element
389
- reactiveArray[3] // Access fourth element
390
- })
391
-
392
- expect(effectCount).toBe(1)
393
-
394
- reactiveArray.fill(0, 1, 4)
395
- expect(effectCount).toBe(2)
396
- expect(reactiveArray[1]).toBe(0)
397
- expect(reactiveArray[3]).toBe(0)
398
- expect(reactiveArray[0]).toBe(1) // Should not change
399
- expect(reactiveArray[4]).toBe(5) // Should not change
400
- })
401
-
402
- it('should handle fill without start and end parameters', () => {
403
- const array = [1, 2, 3, 4, 5]
404
- const reactiveArray = reactive(array)
405
-
406
- let effectCount = 0
407
- effect(() => {
408
- effectCount++
409
- reactiveArray[0] // Access first element
410
- reactiveArray[4] // Access last element
411
- })
412
-
413
- expect(effectCount).toBe(1)
414
-
415
- reactiveArray.fill(0)
416
- expect(effectCount).toBe(2)
417
- expect(reactiveArray[0]).toBe(0)
418
- expect(reactiveArray[4]).toBe(0)
419
- })
420
-
421
- it('should handle fill with only start parameter', () => {
422
- const array = [1, 2, 3, 4, 5]
423
- const reactiveArray = reactive(array)
424
-
425
- let effectCount = 0
426
- effect(() => {
427
- effectCount++
428
- reactiveArray[2] // Access third element
429
- reactiveArray[4] // Access last element
430
- })
431
-
432
- expect(effectCount).toBe(1)
433
-
434
- reactiveArray.fill(0, 2)
435
- expect(effectCount).toBe(2)
436
- expect(reactiveArray[2]).toBe(0)
437
- expect(reactiveArray[4]).toBe(0)
438
- expect(reactiveArray[1]).toBe(2) // Should not change
439
- })
440
- })
441
-
442
- describe('copyWithin method', () => {
443
- it('should handle copyWithin with reactivity', () => {
444
- const array = [1, 2, 3, 4, 5]
445
- const reactiveArray = reactive(array)
446
-
447
- let effectCount = 0
448
- effect(() => {
449
- effectCount++
450
- reactiveArray[0] // Access first element
451
- reactiveArray[1] // Access second element
452
- })
453
-
454
- expect(effectCount).toBe(1)
455
-
456
- reactiveArray.copyWithin(0, 3, 5)
457
- expect(effectCount).toBe(2)
458
- expect(reactiveArray[0]).toBe(4)
459
- expect(reactiveArray[1]).toBe(5)
460
- })
461
-
462
- it('should handle copyWithin without end parameter', () => {
463
- const array = [1, 2, 3, 4, 5]
464
- const reactiveArray = reactive(array)
465
-
466
- let effectCount = 0
467
- effect(() => {
468
- effectCount++
469
- reactiveArray[0] // Access first element
470
- })
471
-
472
- expect(effectCount).toBe(1)
473
-
474
- reactiveArray.copyWithin(0, 2)
475
- expect(effectCount).toBe(2)
476
- expect(reactiveArray[0]).toBe(3)
477
- expect(reactiveArray[1]).toBe(4)
478
- expect(reactiveArray[2]).toBe(5)
479
- })
480
- })
481
-
482
- describe('mixed index and length reactivity', () => {
483
- it('should track both index and length changes in same effect', () => {
484
- const array = [1, 2, 3]
485
- const reactiveArray = reactive(array)
486
-
487
- let effectCount = 0
488
- effect(() => {
489
- effectCount++
490
- reactiveArray[0] // Access first element
491
- reactiveArray.length // Access length
492
- })
493
-
494
- expect(effectCount).toBe(1)
495
-
496
- // Changing an element should trigger the effect
497
- reactiveArray[0] = 100
498
- expect(effectCount).toBe(2)
499
-
500
- // Adding an element should trigger the effect
501
- reactiveArray.push(4)
502
- expect(effectCount).toBe(3)
503
- })
504
-
505
- it('should handle array expansion correctly', () => {
506
- const array = [1, 2, 3]
507
- const reactiveArray = reactive(array)
508
-
509
- let effectCount = 0
510
- effect(() => {
511
- effectCount++
512
- reactiveArray.length // Access length
513
- })
514
-
515
- expect(effectCount).toBe(1)
516
-
517
- // Setting the index should expand the array and trigger the effect
518
- reactiveArray[4] = 999
519
- expect(effectCount).toBe(2)
520
- expect(reactiveArray.length).toBe(5)
521
- expect(reactiveArray[4]).toBe(999)
522
- })
523
- })
524
-
525
- describe('iterator methods', () => {
526
- it('should track allProps for entries()', () => {
527
- const array = [1, 2, 3]
528
- const reactiveArray = reactive(array)
529
-
530
- let effectCount = 0
531
- effect(() => {
532
- effectCount++
533
- reactiveArray.entries()
534
- })
535
-
536
- expect(effectCount).toBe(1)
537
-
538
- // Any change should trigger the effect since entries() depends on allProps
539
- reactiveArray[0] = 100
540
- expect(effectCount).toBe(2)
541
-
542
- reactiveArray.push(4)
543
- expect(effectCount).toBe(3)
544
- })
545
-
546
- it('should track allProps for keys()', () => {
547
- const array = [1, 2, 3]
548
- const reactiveArray = reactive(array)
549
-
550
- let effectCount = 0
551
- effect(() => {
552
- effectCount++
553
- reactiveArray.keys()
554
- })
555
-
556
- expect(effectCount).toBe(1)
557
-
558
- // Any change should trigger the effect since keys() depends on allProps
559
- reactiveArray[0] = 100
560
- expect(effectCount).toBe(2)
561
-
562
- reactiveArray.push(4)
563
- expect(effectCount).toBe(3)
564
- })
565
-
566
- it('should track allProps for values()', () => {
567
- const array = [1, 2, 3]
568
- const reactiveArray = reactive(array)
569
-
570
- let effectCount = 0
571
- effect(() => {
572
- effectCount++
573
- reactiveArray.values()
574
- })
575
-
576
- expect(effectCount).toBe(1)
577
-
578
- // Any change should trigger the effect since values() depends on allProps
579
- reactiveArray[0] = 100
580
- expect(effectCount).toBe(2)
581
-
582
- reactiveArray.push(4)
583
- expect(effectCount).toBe(3)
584
- })
585
-
586
- it('should track allProps for Symbol.iterator', () => {
587
- const array = [1, 2, 3]
588
- const reactiveArray = reactive(array)
589
-
590
- let effectCount = 0
591
- effect(() => {
592
- effectCount++
593
- for (const _value of reactiveArray) {
594
- // Just iterate to trigger the Symbol.iterator
595
- }
596
- })
597
-
598
- expect(effectCount).toBe(1)
599
-
600
- // Any change should trigger the effect since Symbol.iterator depends on allProps
601
- reactiveArray[0] = 100
602
- expect(effectCount).toBe(2)
603
-
604
- reactiveArray.push(4)
605
- expect(effectCount).toBe(3)
606
- })
607
-
608
- it('should work with for...of loops', () => {
609
- const array = [1, 2, 3]
610
- const reactiveArray = reactive(array)
611
-
612
- const values: number[] = []
613
- let effectCount = 0
614
- effect(() => {
615
- effectCount++
616
- values.length = 0 // Clear previous values
617
- for (const value of reactiveArray) {
618
- values.push(value)
619
- }
620
- })
621
-
622
- expect(effectCount).toBe(1)
623
- expect(unwrap(values)).toEqual([1, 2, 3])
624
-
625
- // Modifying an element should trigger the effect
626
- reactiveArray[0] = 100
627
- expect(effectCount).toBe(2)
628
- expect(unwrap(values)).toEqual([100, 2, 3])
629
-
630
- // Adding an element should trigger the effect
631
- reactiveArray.push(4)
632
- expect(effectCount).toBe(3)
633
- expect(unwrap(values)).toEqual([100, 2, 3, 4])
634
- })
635
- })
636
-
637
- describe('basic functionality', () => {
638
- it('should handle empty arrays', () => {
639
- const array: number[] = []
640
- const reactiveArray = reactive(array)
641
-
642
- expect(reactiveArray.length).toBe(0)
643
-
644
- let effectCount = 0
645
- effect(() => {
646
- effectCount++
647
- reactiveArray.length
648
- })
649
-
650
- expect(effectCount).toBe(1)
651
-
652
- reactiveArray.push(1)
653
- expect(effectCount).toBe(2)
654
- })
655
-
656
- describe('query methods', () => {
657
- it('should track anyProps for indexOf()', () => {
658
- const array = [1, 2, 3]
659
- const ra = reactive(array)
660
- let found = -1
661
-
662
- let runs = 0
663
- effect(() => {
664
- runs++
665
- found = ra.indexOf(2)
666
- })
667
-
668
- expect(runs).toBe(1)
669
- expect(found).toBe(1)
670
-
671
- ra[1] = 20
672
- expect(runs).toBe(2)
673
- expect(found).toBe(-1)
674
-
675
- ra.push(2)
676
- expect(runs).toBe(3)
677
- expect(found).toBe(3)
678
- })
679
-
680
- it('should track anyProps for find()', () => {
681
- const array = [1, 2, 3]
682
- const ra = reactive(array)
683
- let found: number | undefined
684
- let runs = 0
685
- effect(() => {
686
- runs++
687
- found = ra.find((v) => v === 9)
688
- })
689
-
690
- expect(runs).toBe(1)
691
- expect(found).toBeUndefined()
692
-
693
- ra[0] = 9
694
- expect(runs).toBe(2)
695
- expect(found).toBe(9)
696
-
697
- ra[0] = 1
698
- expect(runs).toBe(3)
699
- expect(found).toBeUndefined()
700
- })
701
-
702
- it('should track anyProps for every()', () => {
703
- const array = [1, 2, 3]
704
- const ra = reactive(array)
705
- let allTrue = false
706
- let runs = 0
707
- effect(() => {
708
- runs++
709
- allTrue = ra.every((v) => v > 0)
710
- })
711
-
712
- expect(runs).toBe(1)
713
- expect(allTrue).toBe(true)
714
-
715
- ra[1] = -1
716
- expect(runs).toBe(2)
717
- expect(allTrue).toBe(false)
718
-
719
- ra.splice(1, 1, 2)
720
- expect(runs).toBe(3)
721
- expect(allTrue).toBe(true)
722
- })
723
-
724
- it('should track anyProps for filter()', () => {
725
- const array = [1, 2, 3, 4]
726
- const ra = reactive(array)
727
-
728
- let filtered: number[] = []
729
- let runs = 0
730
- effect(() => {
731
- runs++
732
- filtered = ra.filter((v) => v % 2 === 0)
733
- })
734
-
735
- expect(runs).toBe(1)
736
- expect(unwrap(filtered)).toEqual([2, 4])
737
-
738
- ra[1] = 5
739
- expect(runs).toBe(2)
740
- expect(unwrap(filtered)).toEqual([4])
741
-
742
- ra.unshift(6)
743
- expect(runs).toBe(3)
744
- expect(unwrap(filtered)).toEqual([6, 4])
745
- })
746
-
747
- it('should track anyProps for map()', () => {
748
- const array = [1, 2, 3]
749
- const ra = reactive(array)
750
-
751
- let mapped: number[] = []
752
- let runs = 0
753
- effect(() => {
754
- runs++
755
- mapped = ra.map((v) => v * 2)
756
- })
757
-
758
- expect(runs).toBe(1)
759
- expect(unwrap(mapped)).toEqual([2, 4, 6])
760
-
761
- ra[1] = 5
762
- expect(runs).toBe(2)
763
- expect(unwrap(mapped)).toEqual([2, 10, 6])
764
-
765
- ra.push(4)
766
- expect(runs).toBe(3)
767
- expect(unwrap(mapped)).toEqual([2, 10, 6, 8])
768
- })
769
-
770
- it('should track anyProps for reduce()', () => {
771
- const array = [1, 2, 3]
772
- const ra = reactive(array)
773
-
774
- let sum = 0
775
- let runs = 0
776
- effect(() => {
777
- runs++
778
- sum = ra.reduce((a, b) => a + b, 0)
779
- })
780
-
781
- expect(runs).toBe(1)
782
- expect(sum).toBe(6)
783
-
784
- ra[0] = 10
785
- expect(runs).toBe(2)
786
- expect(sum).toBe(15)
787
-
788
- ra.push(4)
789
- expect(runs).toBe(3)
790
- expect(sum).toBe(19)
791
- })
792
-
793
- it('should track anyProps for reduceRight()', () => {
794
- const array = [1, 2, 3]
795
- const ra = reactive(array)
796
-
797
- let concat = ''
798
- let runs = 0
799
- effect(() => {
800
- runs++
801
- concat = ra.reduceRight((acc, v) => acc + String(v), '')
802
- })
803
-
804
- expect(runs).toBe(1)
805
- expect(concat).toBe('321')
806
-
807
- ra[0] = 9
808
- expect(runs).toBe(2)
809
- expect(concat).toBe('329')
810
-
811
- ra.unshift(0)
812
- expect(runs).toBe(3)
813
- expect(concat).toBe('3290')
814
- })
815
-
816
- it('should track anyProps for slice()', () => {
817
- const array = [1, 2, 3, 4]
818
- const ra = reactive(array)
819
-
820
- let sliced: number[] = []
821
- let runs = 0
822
- effect(() => {
823
- runs++
824
- sliced = ra.slice(1, 3)
825
- })
826
-
827
- expect(runs).toBe(1)
828
- expect(unwrap(sliced)).toEqual([2, 3])
829
-
830
- ra[2] = 9
831
- expect(runs).toBe(2)
832
- expect(unwrap(sliced)).toEqual([2, 9])
833
-
834
- ra.unshift(0)
835
- expect(runs).toBe(3)
836
- expect(unwrap(sliced)).toEqual([1, 2])
837
- })
838
-
839
- it('should track anyProps for concat()', () => {
840
- const array = [1, 2]
841
- const ra = reactive(array)
842
-
843
- let concatenated: number[] = []
844
- let runs = 0
845
- const extra = [3]
846
- effect(() => {
847
- runs++
848
- concatenated = unwrap(ra.concat(extra))
849
- })
850
-
851
- expect(runs).toBe(1)
852
- expect(concatenated).toEqual([1, 2, 3])
853
-
854
- ra[1] = 20
855
- expect(runs).toBe(2)
856
- expect(concatenated).toEqual([1, 20, 3])
857
-
858
- ra.push(4)
859
- expect(runs).toBe(3)
860
- expect(concatenated).toEqual([1, 20, 4, 3])
861
- })
862
-
863
- it('should track anyProps for join()', () => {
864
- const array = [1, 2, 3]
865
- const ra = reactive(array)
866
-
867
- let joined = ''
868
- let runs = 0
869
- effect(() => {
870
- runs++
871
- joined = ra.join('-')
872
- })
873
-
874
- expect(runs).toBe(1)
875
- expect(joined).toBe('1-2-3')
876
-
877
- ra[1] = 9
878
- expect(runs).toBe(2)
879
- expect(joined).toBe('1-9-3')
880
-
881
- ra.push(4)
882
- expect(runs).toBe(3)
883
- expect(joined).toBe('1-9-3-4')
884
- })
885
-
886
- it('should track anyProps for forEach()', () => {
887
- const array = [1, 2, 3]
888
- const ra = reactive(array)
889
-
890
- let sum = 0
891
- let runs = 0
892
- effect(() => {
893
- runs++
894
- sum = 0
895
- ra.forEach((v) => {
896
- sum += v
897
- })
898
- })
899
-
900
- expect(runs).toBe(1)
901
- expect(sum).toBe(6)
902
-
903
- ra[0] = 10
904
- expect(runs).toBe(2)
905
- expect(sum).toBe(15)
906
-
907
- ra.push(4)
908
- expect(runs).toBe(3)
909
- expect(sum).toBe(19)
910
- })
911
- })
912
- it('should work with reactive() function', () => {
913
- const array = [1, 2, 3]
914
- const reactiveArray = reactive(array)
915
-
916
- expect(reactiveArray).toBeInstanceOf(Array)
917
- expect(reactiveArray[0]).toBe(1)
918
- expect(reactiveArray[1]).toBe(2)
919
- expect(reactiveArray[2]).toBe(3)
920
- expect(reactiveArray.length).toBe(3)
921
- })
922
- })
923
- })