@zeix/cause-effect 0.14.1 → 0.14.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.
- package/README.md +1 -1
- package/biome.json +35 -0
- package/index.d.ts +6 -6
- package/index.dev.js +294 -0
- package/index.js +1 -1
- package/index.ts +21 -20
- package/package.json +5 -6
- package/src/computed.d.ts +2 -2
- package/src/computed.ts +15 -15
- package/src/effect.d.ts +7 -7
- package/src/effect.ts +13 -11
- package/src/scheduler.d.ts +2 -2
- package/src/scheduler.ts +3 -3
- package/src/signal.d.ts +1 -1
- package/src/signal.ts +4 -3
- package/src/util.ts +1 -1
- package/test/batch.test.ts +11 -11
- package/test/benchmark.test.ts +78 -42
- package/test/computed.test.ts +30 -30
- package/test/effect.test.ts +19 -19
- package/test/state.test.ts +33 -33
- package/test/util/framework-types.ts +2 -2
- package/test/util/perf-tests.ts +2 -2
- package/test/util/reactive-framework.ts +1 -1
package/src/signal.ts
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
import { isState, state } from './state'
|
|
2
1
|
import {
|
|
3
2
|
type ComputedCallback,
|
|
3
|
+
computed,
|
|
4
4
|
isComputed,
|
|
5
5
|
isComputedCallback,
|
|
6
|
-
computed,
|
|
7
6
|
} from './computed'
|
|
7
|
+
import { isState, state } from './state'
|
|
8
8
|
|
|
9
9
|
/* === Types === */
|
|
10
10
|
|
|
@@ -13,12 +13,13 @@ type Signal<T extends {}> = {
|
|
|
13
13
|
}
|
|
14
14
|
type MaybeSignal<T extends {}> = T | Signal<T> | ComputedCallback<T>
|
|
15
15
|
|
|
16
|
-
type SignalValues<S extends Signal<{}>[]> = {
|
|
16
|
+
type SignalValues<S extends Signal<unknown & {}>[]> = {
|
|
17
17
|
[K in keyof S]: S[K] extends Signal<infer T> ? T : never
|
|
18
18
|
}
|
|
19
19
|
|
|
20
20
|
/* === Constants === */
|
|
21
21
|
|
|
22
|
+
// biome-ignore lint/suspicious/noExplicitAny: Deliberately using any to be used as a placeholder value in any signal
|
|
22
23
|
const UNSET: any = Symbol()
|
|
23
24
|
|
|
24
25
|
/* === Functions === */
|
package/src/util.ts
CHANGED
package/test/batch.test.ts
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
|
-
import { describe,
|
|
2
|
-
import {
|
|
1
|
+
import { describe, expect, test } from 'bun:test'
|
|
2
|
+
import { batch, computed, effect, state } from '../'
|
|
3
3
|
|
|
4
4
|
/* === Tests === */
|
|
5
5
|
|
|
6
|
-
describe('Batch',
|
|
7
|
-
test('should be triggered only once after repeated state change',
|
|
6
|
+
describe('Batch', () => {
|
|
7
|
+
test('should be triggered only once after repeated state change', () => {
|
|
8
8
|
const cause = state(0)
|
|
9
9
|
let result = 0
|
|
10
10
|
let count = 0
|
|
11
|
-
effect(() => {
|
|
11
|
+
effect((): undefined => {
|
|
12
12
|
result = cause.get()
|
|
13
13
|
count++
|
|
14
14
|
})
|
|
@@ -21,7 +21,7 @@ describe('Batch', function () {
|
|
|
21
21
|
expect(count).toBe(2) // + 1 for effect initialization
|
|
22
22
|
})
|
|
23
23
|
|
|
24
|
-
test('should be triggered only once when multiple signals are set',
|
|
24
|
+
test('should be triggered only once when multiple signals are set', () => {
|
|
25
25
|
const a = state(3)
|
|
26
26
|
const b = state(4)
|
|
27
27
|
const c = state(5)
|
|
@@ -30,11 +30,11 @@ describe('Batch', function () {
|
|
|
30
30
|
let count = 0
|
|
31
31
|
effect({
|
|
32
32
|
signals: [sum],
|
|
33
|
-
ok: res => {
|
|
33
|
+
ok: (res): undefined => {
|
|
34
34
|
result = res
|
|
35
35
|
count++
|
|
36
36
|
},
|
|
37
|
-
err: () => {},
|
|
37
|
+
err: (): undefined => {},
|
|
38
38
|
})
|
|
39
39
|
batch(() => {
|
|
40
40
|
a.set(6)
|
|
@@ -45,7 +45,7 @@ describe('Batch', function () {
|
|
|
45
45
|
expect(count).toBe(2) // + 1 for effect initialization
|
|
46
46
|
})
|
|
47
47
|
|
|
48
|
-
test('should prove example from README works',
|
|
48
|
+
test('should prove example from README works', () => {
|
|
49
49
|
// State: define an array of Signal<number>
|
|
50
50
|
const signals = [state(2), state(3), state(5)]
|
|
51
51
|
|
|
@@ -63,12 +63,12 @@ describe('Batch', function () {
|
|
|
63
63
|
// Effect: switch cases for the result
|
|
64
64
|
effect({
|
|
65
65
|
signals: [sum],
|
|
66
|
-
ok: v => {
|
|
66
|
+
ok: (v): undefined => {
|
|
67
67
|
result = v
|
|
68
68
|
okCount++
|
|
69
69
|
// console.log('Sum:', v)
|
|
70
70
|
},
|
|
71
|
-
err: _error => {
|
|
71
|
+
err: (_error): undefined => {
|
|
72
72
|
errCount++
|
|
73
73
|
// console.error('Error:', error)
|
|
74
74
|
},
|
package/test/benchmark.test.ts
CHANGED
|
@@ -1,10 +1,7 @@
|
|
|
1
|
-
import { describe,
|
|
2
|
-
import {
|
|
3
|
-
import { makeGraph, runGraph
|
|
4
|
-
import {
|
|
5
|
-
type ReactiveFramework,
|
|
6
|
-
type Computed,
|
|
7
|
-
} from './util/reactive-framework'
|
|
1
|
+
import { describe, expect, mock, test } from 'bun:test'
|
|
2
|
+
import { batch, computed, effect, state } from '../'
|
|
3
|
+
import { Counter, makeGraph, runGraph } from './util/dependency-graph'
|
|
4
|
+
import type { Computed, ReactiveFramework } from './util/reactive-framework'
|
|
8
5
|
|
|
9
6
|
/* === Utility Functions === */
|
|
10
7
|
|
|
@@ -30,8 +27,8 @@ const framework = {
|
|
|
30
27
|
read: () => c.get(),
|
|
31
28
|
}
|
|
32
29
|
},
|
|
33
|
-
effect: (fn: () =>
|
|
34
|
-
withBatch: (fn: () =>
|
|
30
|
+
effect: (fn: () => undefined) => effect(fn),
|
|
31
|
+
withBatch: (fn: () => undefined) => batch(fn),
|
|
35
32
|
withBuild: <T>(fn: () => T) => fn(),
|
|
36
33
|
}
|
|
37
34
|
const testPullCounts = true
|
|
@@ -53,7 +50,7 @@ function makeConfig() {
|
|
|
53
50
|
/** some basic tests to validate the reactive framework
|
|
54
51
|
* wrapper works and can run performance tests.
|
|
55
52
|
*/
|
|
56
|
-
describe('Basic test',
|
|
53
|
+
describe('Basic test', () => {
|
|
57
54
|
const name = framework.name
|
|
58
55
|
test(`${name} | simple dependency executes`, () => {
|
|
59
56
|
framework.withBuild(() => {
|
|
@@ -145,11 +142,11 @@ describe('Basic test', function () {
|
|
|
145
142
|
})
|
|
146
143
|
|
|
147
144
|
test(`${name} | effect`, () => {
|
|
148
|
-
const spy = _v => {}
|
|
145
|
+
const spy = (_v: number) => {}
|
|
149
146
|
const spyMock = mock(spy)
|
|
150
147
|
|
|
151
148
|
const s = framework.signal(2)
|
|
152
|
-
let c:
|
|
149
|
+
let c: { read: () => number } = { read: () => 0 }
|
|
153
150
|
|
|
154
151
|
framework.withBuild(() => {
|
|
155
152
|
c = framework.computed(() => s.read() * 2)
|
|
@@ -169,18 +166,22 @@ describe('Basic test', function () {
|
|
|
169
166
|
})
|
|
170
167
|
})
|
|
171
168
|
|
|
172
|
-
describe('Kairo tests',
|
|
169
|
+
describe('Kairo tests', () => {
|
|
173
170
|
const name = framework.name
|
|
174
171
|
|
|
175
172
|
test(`${name} | avoidable propagation`, () => {
|
|
176
173
|
const head = framework.signal(0)
|
|
177
174
|
const computed1 = framework.computed(() => head.read())
|
|
178
|
-
const computed2 = framework.computed(() =>
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
)
|
|
182
|
-
const
|
|
183
|
-
|
|
175
|
+
const computed2 = framework.computed(() => {
|
|
176
|
+
computed1.read()
|
|
177
|
+
return 0
|
|
178
|
+
})
|
|
179
|
+
const computed3 = framework.computed(() => {
|
|
180
|
+
busy()
|
|
181
|
+
return computed2.read() + 1
|
|
182
|
+
}) // heavy computation
|
|
183
|
+
const computed4 = framework.computed(() => computed3.read() + 2)
|
|
184
|
+
const computed5 = framework.computed(() => computed4.read() + 3)
|
|
184
185
|
framework.effect(() => {
|
|
185
186
|
computed5.read()
|
|
186
187
|
busy() // heavy side effect
|
|
@@ -206,10 +207,10 @@ describe('Kairo tests', function () {
|
|
|
206
207
|
const callCounter = new Counter()
|
|
207
208
|
for (let i = 0; i < 50; i++) {
|
|
208
209
|
const current = framework.computed(() => {
|
|
209
|
-
return head.read()
|
|
210
|
+
return head.read() + i
|
|
210
211
|
})
|
|
211
212
|
const current2 = framework.computed(() => {
|
|
212
|
-
return current.read()
|
|
213
|
+
return current.read() + 1
|
|
213
214
|
})
|
|
214
215
|
framework.effect(() => {
|
|
215
216
|
current2.read()
|
|
@@ -267,7 +268,7 @@ describe('Kairo tests', function () {
|
|
|
267
268
|
}
|
|
268
269
|
})
|
|
269
270
|
|
|
270
|
-
test(`${name} | diamond`,
|
|
271
|
+
test(`${name} | diamond`, () => {
|
|
271
272
|
const width = 5
|
|
272
273
|
const head = framework.signal(0)
|
|
273
274
|
const current: { read(): number }[] = []
|
|
@@ -300,7 +301,7 @@ describe('Kairo tests', function () {
|
|
|
300
301
|
}
|
|
301
302
|
})
|
|
302
303
|
|
|
303
|
-
test(`${name} | mux`,
|
|
304
|
+
test(`${name} | mux`, () => {
|
|
304
305
|
const heads = new Array(100).fill(null).map(_ => framework.signal(0))
|
|
305
306
|
const mux = framework.computed(() => {
|
|
306
307
|
return Object.fromEntries(heads.map(h => h.read()).entries())
|
|
@@ -310,7 +311,9 @@ describe('Kairo tests', function () {
|
|
|
310
311
|
.map(x => framework.computed(() => x.read() + 1))
|
|
311
312
|
|
|
312
313
|
splited.forEach(x => {
|
|
313
|
-
framework.effect(() =>
|
|
314
|
+
framework.effect(() => {
|
|
315
|
+
x.read()
|
|
316
|
+
})
|
|
314
317
|
})
|
|
315
318
|
|
|
316
319
|
return () => {
|
|
@@ -329,7 +332,7 @@ describe('Kairo tests', function () {
|
|
|
329
332
|
}
|
|
330
333
|
})
|
|
331
334
|
|
|
332
|
-
test(`${name} | repeated observers`,
|
|
335
|
+
test(`${name} | repeated observers`, () => {
|
|
333
336
|
const size = 30
|
|
334
337
|
const head = framework.signal(0)
|
|
335
338
|
const current = framework.computed(() => {
|
|
@@ -362,7 +365,7 @@ describe('Kairo tests', function () {
|
|
|
362
365
|
}
|
|
363
366
|
})
|
|
364
367
|
|
|
365
|
-
test(`${name} | triangle`,
|
|
368
|
+
test(`${name} | triangle`, () => {
|
|
366
369
|
const width = 10
|
|
367
370
|
const head = framework.signal(0)
|
|
368
371
|
let current = head as { read: () => number }
|
|
@@ -407,7 +410,7 @@ describe('Kairo tests', function () {
|
|
|
407
410
|
}
|
|
408
411
|
})
|
|
409
412
|
|
|
410
|
-
test(`${name} | unstable`,
|
|
413
|
+
test(`${name} | unstable`, () => {
|
|
411
414
|
const head = framework.signal(0)
|
|
412
415
|
const double = framework.computed(() => head.read() * 2)
|
|
413
416
|
const inverse = framework.computed(() => -head.read())
|
|
@@ -442,10 +445,10 @@ describe('Kairo tests', function () {
|
|
|
442
445
|
})
|
|
443
446
|
})
|
|
444
447
|
|
|
445
|
-
describe('$mol_wire tests',
|
|
448
|
+
describe('$mol_wire tests', () => {
|
|
446
449
|
const name = framework.name
|
|
447
450
|
|
|
448
|
-
test(`${name} | $mol_wire benchmark`,
|
|
451
|
+
test(`${name} | $mol_wire benchmark`, () => {
|
|
449
452
|
const fib = (n: number) => {
|
|
450
453
|
if (n < 2) return 1
|
|
451
454
|
return fib(n - 1) + fib(n - 2)
|
|
@@ -454,7 +457,7 @@ describe('$mol_wire tests', function () {
|
|
|
454
457
|
return n + fib(16)
|
|
455
458
|
}
|
|
456
459
|
const numbers = Array.from({ length: 5 }, (_, i) => i)
|
|
457
|
-
const res: (() =>
|
|
460
|
+
const res: (() => unknown)[] = []
|
|
458
461
|
framework.withBuild(() => {
|
|
459
462
|
const A = framework.signal(0)
|
|
460
463
|
const B = framework.signal(0)
|
|
@@ -475,12 +478,24 @@ describe('$mol_wire tests', function () {
|
|
|
475
478
|
D.read()[4].x +
|
|
476
479
|
F.read(),
|
|
477
480
|
)
|
|
478
|
-
framework.effect(() =>
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
framework.effect(() =>
|
|
482
|
-
|
|
483
|
-
|
|
481
|
+
framework.effect(() => {
|
|
482
|
+
res.push(hard(G.read(), 'H'))
|
|
483
|
+
})
|
|
484
|
+
framework.effect(() => {
|
|
485
|
+
res.push(G.read())
|
|
486
|
+
}) // I
|
|
487
|
+
framework.effect(() => {
|
|
488
|
+
res.push(hard(F.read(), 'J'))
|
|
489
|
+
})
|
|
490
|
+
framework.effect(() => {
|
|
491
|
+
res[0] = hard(G.read(), 'H')
|
|
492
|
+
})
|
|
493
|
+
framework.effect(() => {
|
|
494
|
+
res[1] = G.read()
|
|
495
|
+
}) // I
|
|
496
|
+
framework.effect(() => {
|
|
497
|
+
res[2] = hard(F.read(), 'J')
|
|
498
|
+
})
|
|
484
499
|
|
|
485
500
|
return (i: number) => {
|
|
486
501
|
res.length = 0
|
|
@@ -499,10 +514,10 @@ describe('$mol_wire tests', function () {
|
|
|
499
514
|
})
|
|
500
515
|
})
|
|
501
516
|
|
|
502
|
-
describe('CellX tests',
|
|
517
|
+
describe('CellX tests', () => {
|
|
503
518
|
const name = framework.name
|
|
504
519
|
|
|
505
|
-
test(`${name} | CellX benchmark`,
|
|
520
|
+
test(`${name} | CellX benchmark`, () => {
|
|
506
521
|
const expected = {
|
|
507
522
|
10: [
|
|
508
523
|
[3, 6, 2, -2],
|
|
@@ -540,10 +555,31 @@ describe('CellX tests', function () {
|
|
|
540
555
|
prop4: framework.computed(() => m.prop3.read()),
|
|
541
556
|
}
|
|
542
557
|
|
|
543
|
-
framework.effect(() =>
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
framework.effect(() =>
|
|
558
|
+
framework.effect(() => {
|
|
559
|
+
s.prop1.read()
|
|
560
|
+
})
|
|
561
|
+
framework.effect(() => {
|
|
562
|
+
s.prop2.read()
|
|
563
|
+
})
|
|
564
|
+
framework.effect(() => {
|
|
565
|
+
s.prop3.read()
|
|
566
|
+
})
|
|
567
|
+
framework.effect(() => {
|
|
568
|
+
s.prop4.read()
|
|
569
|
+
})
|
|
570
|
+
|
|
571
|
+
framework.effect(() => {
|
|
572
|
+
s.prop1.read()
|
|
573
|
+
})
|
|
574
|
+
framework.effect(() => {
|
|
575
|
+
s.prop2.read()
|
|
576
|
+
})
|
|
577
|
+
framework.effect(() => {
|
|
578
|
+
s.prop3.read()
|
|
579
|
+
})
|
|
580
|
+
framework.effect(() => {
|
|
581
|
+
s.prop4.read()
|
|
582
|
+
})
|
|
547
583
|
|
|
548
584
|
s.prop1.read()
|
|
549
585
|
s.prop2.read()
|
package/test/computed.test.ts
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
import { describe,
|
|
1
|
+
import { describe, expect, test } from 'bun:test'
|
|
2
2
|
import {
|
|
3
|
-
state,
|
|
4
3
|
computed,
|
|
5
|
-
|
|
4
|
+
effect,
|
|
6
5
|
isComputed,
|
|
7
6
|
isState,
|
|
8
|
-
|
|
7
|
+
state,
|
|
8
|
+
UNSET,
|
|
9
9
|
} from '../index.ts'
|
|
10
10
|
|
|
11
11
|
/* === Utility Functions === */
|
|
@@ -15,7 +15,7 @@ const increment = (n: number) => (Number.isFinite(n) ? n + 1 : UNSET)
|
|
|
15
15
|
|
|
16
16
|
/* === Tests === */
|
|
17
17
|
|
|
18
|
-
describe('Computed',
|
|
18
|
+
describe('Computed', () => {
|
|
19
19
|
test('should identify computed signals with isComputed()', () => {
|
|
20
20
|
const count = state(42)
|
|
21
21
|
const doubled = computed(() => count.get() * 2)
|
|
@@ -23,25 +23,25 @@ describe('Computed', function () {
|
|
|
23
23
|
expect(isState(doubled)).toBe(false)
|
|
24
24
|
})
|
|
25
25
|
|
|
26
|
-
test('should compute a function',
|
|
26
|
+
test('should compute a function', () => {
|
|
27
27
|
const derived = computed(() => 1 + 2)
|
|
28
28
|
expect(derived.get()).toBe(3)
|
|
29
29
|
})
|
|
30
30
|
|
|
31
|
-
test('should compute function dependent on a signal',
|
|
31
|
+
test('should compute function dependent on a signal', () => {
|
|
32
32
|
const cause = state(42)
|
|
33
33
|
const derived = computed(() => cause.get() + 1)
|
|
34
34
|
expect(derived.get()).toBe(43)
|
|
35
35
|
})
|
|
36
36
|
|
|
37
|
-
test('should compute function dependent on an updated signal',
|
|
37
|
+
test('should compute function dependent on an updated signal', () => {
|
|
38
38
|
const cause = state(42)
|
|
39
39
|
const derived = computed(() => cause.get() + 1)
|
|
40
40
|
cause.set(24)
|
|
41
41
|
expect(derived.get()).toBe(25)
|
|
42
42
|
})
|
|
43
43
|
|
|
44
|
-
test('should compute function dependent on an async signal', async
|
|
44
|
+
test('should compute function dependent on an async signal', async () => {
|
|
45
45
|
const status = state('pending')
|
|
46
46
|
const promised = computed(async () => {
|
|
47
47
|
await wait(100)
|
|
@@ -56,7 +56,7 @@ describe('Computed', function () {
|
|
|
56
56
|
expect(status.get()).toBe('success')
|
|
57
57
|
})
|
|
58
58
|
|
|
59
|
-
test('should handle errors from an async signal gracefully', async
|
|
59
|
+
test('should handle errors from an async signal gracefully', async () => {
|
|
60
60
|
const status = state('pending')
|
|
61
61
|
const error = state('')
|
|
62
62
|
const promised = computed(async () => {
|
|
@@ -73,7 +73,7 @@ describe('Computed', function () {
|
|
|
73
73
|
expect(status.get()).toBe('error')
|
|
74
74
|
})
|
|
75
75
|
|
|
76
|
-
test('should compute task signals in parallel without waterfalls', async
|
|
76
|
+
test('should compute task signals in parallel without waterfalls', async () => {
|
|
77
77
|
const a = computed(async () => {
|
|
78
78
|
await wait(100)
|
|
79
79
|
return 10
|
|
@@ -94,7 +94,7 @@ describe('Computed', function () {
|
|
|
94
94
|
expect(c.get()).toBe(30)
|
|
95
95
|
})
|
|
96
96
|
|
|
97
|
-
test('should compute function dependent on a chain of computed states dependent on a signal',
|
|
97
|
+
test('should compute function dependent on a chain of computed states dependent on a signal', () => {
|
|
98
98
|
const x = state(42)
|
|
99
99
|
const a = computed(() => x.get() + 1)
|
|
100
100
|
const b = computed(() => a.get() * 2)
|
|
@@ -102,7 +102,7 @@ describe('Computed', function () {
|
|
|
102
102
|
expect(c.get()).toBe(87)
|
|
103
103
|
})
|
|
104
104
|
|
|
105
|
-
test('should compute function dependent on a chain of computed states dependent on an updated signal',
|
|
105
|
+
test('should compute function dependent on a chain of computed states dependent on an updated signal', () => {
|
|
106
106
|
const x = state(42)
|
|
107
107
|
const a = computed(() => x.get() + 1)
|
|
108
108
|
const b = computed(() => a.get() * 2)
|
|
@@ -111,14 +111,14 @@ describe('Computed', function () {
|
|
|
111
111
|
expect(c.get()).toBe(51)
|
|
112
112
|
})
|
|
113
113
|
|
|
114
|
-
test('should drop X->B->X updates',
|
|
114
|
+
test('should drop X->B->X updates', () => {
|
|
115
115
|
let count = 0
|
|
116
116
|
const x = state(2)
|
|
117
117
|
const a = computed(() => x.get() - 1)
|
|
118
118
|
const b = computed(() => x.get() + a.get())
|
|
119
119
|
const c = computed(() => {
|
|
120
120
|
count++
|
|
121
|
-
return
|
|
121
|
+
return `c: ${b.get()}`
|
|
122
122
|
})
|
|
123
123
|
expect(c.get()).toBe('c: 3')
|
|
124
124
|
expect(count).toBe(1)
|
|
@@ -127,7 +127,7 @@ describe('Computed', function () {
|
|
|
127
127
|
expect(count).toBe(2)
|
|
128
128
|
})
|
|
129
129
|
|
|
130
|
-
test('should only update every signal once (diamond graph)',
|
|
130
|
+
test('should only update every signal once (diamond graph)', () => {
|
|
131
131
|
let count = 0
|
|
132
132
|
const x = state('a')
|
|
133
133
|
const a = computed(() => x.get())
|
|
@@ -144,12 +144,12 @@ describe('Computed', function () {
|
|
|
144
144
|
expect(count).toBe(2)
|
|
145
145
|
})
|
|
146
146
|
|
|
147
|
-
test('should only update every signal once (diamond graph + tail)',
|
|
147
|
+
test('should only update every signal once (diamond graph + tail)', () => {
|
|
148
148
|
let count = 0
|
|
149
149
|
const x = state('a')
|
|
150
150
|
const a = computed(() => x.get())
|
|
151
151
|
const b = computed(() => x.get())
|
|
152
|
-
const c = computed(() => a.get()
|
|
152
|
+
const c = computed(() => `${a.get()} ${b.get()}`)
|
|
153
153
|
const d = computed(() => {
|
|
154
154
|
count++
|
|
155
155
|
return c.get()
|
|
@@ -161,7 +161,7 @@ describe('Computed', function () {
|
|
|
161
161
|
expect(count).toBe(2)
|
|
162
162
|
})
|
|
163
163
|
|
|
164
|
-
test('should update multiple times after multiple state changes',
|
|
164
|
+
test('should update multiple times after multiple state changes', () => {
|
|
165
165
|
const a = state(3)
|
|
166
166
|
const b = state(4)
|
|
167
167
|
let count = 0
|
|
@@ -185,7 +185,7 @@ describe('Computed', function () {
|
|
|
185
185
|
* one-time performance cost that allows for efficient memoization and
|
|
186
186
|
* error handling in most cases.
|
|
187
187
|
*/
|
|
188
|
-
test('should bail out if result is the same',
|
|
188
|
+
test('should bail out if result is the same', () => {
|
|
189
189
|
let count = 0
|
|
190
190
|
const x = state('a')
|
|
191
191
|
const a = computed(() => {
|
|
@@ -205,7 +205,7 @@ describe('Computed', function () {
|
|
|
205
205
|
expect(count).toBe(2)
|
|
206
206
|
})
|
|
207
207
|
|
|
208
|
-
test('should block if result remains unchanged',
|
|
208
|
+
test('should block if result remains unchanged', () => {
|
|
209
209
|
let count = 0
|
|
210
210
|
const x = state(42)
|
|
211
211
|
const a = computed(() => x.get() % 2)
|
|
@@ -223,7 +223,7 @@ describe('Computed', function () {
|
|
|
223
223
|
expect(count).toBe(2)
|
|
224
224
|
})
|
|
225
225
|
|
|
226
|
-
test('should detect and throw error for circular dependencies',
|
|
226
|
+
test('should detect and throw error for circular dependencies', () => {
|
|
227
227
|
const a = state(1)
|
|
228
228
|
const b = computed(() => c.get() + 1)
|
|
229
229
|
const c = computed(() => b.get() + a.get())
|
|
@@ -233,7 +233,7 @@ describe('Computed', function () {
|
|
|
233
233
|
expect(a.get()).toBe(1)
|
|
234
234
|
})
|
|
235
235
|
|
|
236
|
-
test('should propagate error if an error occurred',
|
|
236
|
+
test('should propagate error if an error occurred', () => {
|
|
237
237
|
let okCount = 0
|
|
238
238
|
let errCount = 0
|
|
239
239
|
const x = state(0)
|
|
@@ -273,7 +273,7 @@ describe('Computed', function () {
|
|
|
273
273
|
}
|
|
274
274
|
})
|
|
275
275
|
|
|
276
|
-
test('should create an effect that reacts on async computed changes', async
|
|
276
|
+
test('should create an effect that reacts on async computed changes', async () => {
|
|
277
277
|
const cause = state(42)
|
|
278
278
|
const derived = computed(async () => {
|
|
279
279
|
await wait(100)
|
|
@@ -284,11 +284,11 @@ describe('Computed', function () {
|
|
|
284
284
|
let result: number = 0
|
|
285
285
|
effect({
|
|
286
286
|
signals: [derived],
|
|
287
|
-
ok: v => {
|
|
287
|
+
ok: (v): undefined => {
|
|
288
288
|
result = v
|
|
289
289
|
okCount++
|
|
290
290
|
},
|
|
291
|
-
nil: () => {
|
|
291
|
+
nil: (): undefined => {
|
|
292
292
|
nilCount++
|
|
293
293
|
},
|
|
294
294
|
})
|
|
@@ -303,7 +303,7 @@ describe('Computed', function () {
|
|
|
303
303
|
expect(result).toBe(44)
|
|
304
304
|
})
|
|
305
305
|
|
|
306
|
-
test('should handle complex computed signal with error and async dependencies', async
|
|
306
|
+
test('should handle complex computed signal with error and async dependencies', async () => {
|
|
307
307
|
const toggleState = state(true)
|
|
308
308
|
const errorProne = computed(() => {
|
|
309
309
|
if (toggleState.get()) throw new Error('Intentional error')
|
|
@@ -350,7 +350,7 @@ describe('Computed', function () {
|
|
|
350
350
|
expect(errCount).toBeGreaterThan(0)
|
|
351
351
|
})
|
|
352
352
|
|
|
353
|
-
test('should handle signal changes during async computation', async
|
|
353
|
+
test('should handle signal changes during async computation', async () => {
|
|
354
354
|
const source = state(1)
|
|
355
355
|
let computationCount = 0
|
|
356
356
|
const derived = computed(async abort => {
|
|
@@ -371,7 +371,7 @@ describe('Computed', function () {
|
|
|
371
371
|
expect(computationCount).toBe(1)
|
|
372
372
|
})
|
|
373
373
|
|
|
374
|
-
test('should handle multiple rapid changes during async computation', async
|
|
374
|
+
test('should handle multiple rapid changes during async computation', async () => {
|
|
375
375
|
const source = state(1)
|
|
376
376
|
let computationCount = 0
|
|
377
377
|
const derived = computed(async abort => {
|
|
@@ -396,7 +396,7 @@ describe('Computed', function () {
|
|
|
396
396
|
expect(computationCount).toBe(1)
|
|
397
397
|
})
|
|
398
398
|
|
|
399
|
-
test('should handle errors in aborted computations', async
|
|
399
|
+
test('should handle errors in aborted computations', async () => {
|
|
400
400
|
const source = state(1)
|
|
401
401
|
const derived = computed(async () => {
|
|
402
402
|
await wait(100)
|