@zeix/cause-effect 0.14.0 → 0.14.1
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 +68 -72
- package/index.d.ts +6 -8
- package/index.js +1 -1
- package/index.ts +17 -6
- package/package.json +1 -1
- package/src/computed.d.ts +10 -8
- package/src/computed.ts +135 -11
- package/src/effect.d.ts +2 -4
- package/src/effect.ts +33 -50
- package/src/scheduler.d.ts +13 -4
- package/src/scheduler.ts +36 -13
- package/src/signal.d.ts +5 -10
- package/src/signal.ts +7 -13
- package/src/state.d.ts +2 -1
- package/src/state.ts +1 -1
- package/src/util.d.ts +1 -5
- package/src/util.ts +2 -22
- package/test/batch.test.ts +3 -3
- package/test/benchmark.test.ts +2 -2
- package/test/computed.test.ts +47 -49
- package/test/effect.test.ts +6 -6
- package/src/memo.d.ts +0 -13
- package/src/memo.ts +0 -91
- package/src/task.d.ts +0 -17
- package/src/task.ts +0 -153
package/src/effect.ts
CHANGED
|
@@ -1,21 +1,12 @@
|
|
|
1
|
-
import { type Signal, UNSET } from './signal'
|
|
2
|
-
import {
|
|
3
|
-
|
|
4
|
-
isFunction,
|
|
5
|
-
toError,
|
|
6
|
-
isAbortError,
|
|
7
|
-
} from './util'
|
|
8
|
-
import { watch, type Cleanup, type Watcher } from './scheduler'
|
|
1
|
+
import { type Signal, type SignalValues, UNSET } from './signal'
|
|
2
|
+
import { CircularDependencyError, isFunction, toError } from './util'
|
|
3
|
+
import { type Cleanup, watch, observe } from './scheduler'
|
|
9
4
|
|
|
10
5
|
/* === Types === */
|
|
11
6
|
|
|
12
7
|
type EffectMatcher<S extends Signal<{}>[]> = {
|
|
13
8
|
signals: S
|
|
14
|
-
ok: (
|
|
15
|
-
...values: {
|
|
16
|
-
[K in keyof S]: S[K] extends Signal<infer T> ? T : never
|
|
17
|
-
}
|
|
18
|
-
) => void | Cleanup
|
|
9
|
+
ok: (...values: SignalValues<S>) => void | Cleanup
|
|
19
10
|
err?: (...errors: Error[]) => void | Cleanup
|
|
20
11
|
nil?: () => void | Cleanup
|
|
21
12
|
}
|
|
@@ -40,54 +31,46 @@ function effect<S extends Signal<{}>[]>(
|
|
|
40
31
|
} = isFunction(matcher)
|
|
41
32
|
? { signals: [] as unknown as S, ok: matcher }
|
|
42
33
|
: matcher
|
|
34
|
+
|
|
43
35
|
let running = false
|
|
44
|
-
const run = (() =>
|
|
45
|
-
|
|
36
|
+
const run = watch(() =>
|
|
37
|
+
observe(() => {
|
|
46
38
|
if (running) throw new CircularDependencyError('effect')
|
|
47
39
|
running = true
|
|
48
|
-
let cleanup: void | Cleanup = undefined
|
|
49
|
-
try {
|
|
50
|
-
const errors: Error[] = []
|
|
51
|
-
let suspense = false
|
|
52
|
-
const values = signals.map(signal => {
|
|
53
|
-
try {
|
|
54
|
-
const value = signal.get()
|
|
55
|
-
if (value === UNSET) suspense = true
|
|
56
|
-
return value
|
|
57
|
-
} catch (e) {
|
|
58
|
-
if (isAbortError(e)) throw e
|
|
59
|
-
errors.push(toError(e))
|
|
60
|
-
return UNSET
|
|
61
|
-
}
|
|
62
|
-
}) as {
|
|
63
|
-
[K in keyof S]: S[K] extends Signal<infer T extends {}>
|
|
64
|
-
? T
|
|
65
|
-
: never
|
|
66
|
-
}
|
|
67
40
|
|
|
41
|
+
// Pure part
|
|
42
|
+
const errors: Error[] = []
|
|
43
|
+
let pending = false
|
|
44
|
+
const values = signals.map(signal => {
|
|
68
45
|
try {
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
? err(...errors)
|
|
73
|
-
: ok(...values)
|
|
46
|
+
const value = signal.get()
|
|
47
|
+
if (value === UNSET) pending = true
|
|
48
|
+
return value
|
|
74
49
|
} catch (e) {
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
cleanup = err(error)
|
|
50
|
+
errors.push(toError(e))
|
|
51
|
+
return UNSET
|
|
78
52
|
}
|
|
53
|
+
}) as SignalValues<S>
|
|
54
|
+
|
|
55
|
+
// Effectful part
|
|
56
|
+
let cleanup: void | Cleanup = undefined
|
|
57
|
+
try {
|
|
58
|
+
cleanup = pending
|
|
59
|
+
? nil()
|
|
60
|
+
: errors.length
|
|
61
|
+
? err(...errors)
|
|
62
|
+
: ok(...values)
|
|
79
63
|
} catch (e) {
|
|
80
|
-
err(toError(e))
|
|
64
|
+
cleanup = err(toError(e))
|
|
65
|
+
} finally {
|
|
66
|
+
if (isFunction(cleanup)) run.off(cleanup)
|
|
81
67
|
}
|
|
82
|
-
|
|
68
|
+
|
|
83
69
|
running = false
|
|
84
|
-
}, run)
|
|
85
|
-
|
|
70
|
+
}, run),
|
|
71
|
+
)
|
|
86
72
|
run()
|
|
87
|
-
return () =>
|
|
88
|
-
run.cleanups.forEach(fn => fn())
|
|
89
|
-
run.cleanups.clear()
|
|
90
|
-
}
|
|
73
|
+
return () => run.cleanup()
|
|
91
74
|
}
|
|
92
75
|
|
|
93
76
|
/* === Exports === */
|
package/src/scheduler.d.ts
CHANGED
|
@@ -1,9 +1,18 @@
|
|
|
1
1
|
type Cleanup = () => void;
|
|
2
2
|
type Watcher = {
|
|
3
3
|
(): void;
|
|
4
|
-
|
|
4
|
+
off(cleanup: Cleanup): void;
|
|
5
|
+
cleanup(): void;
|
|
5
6
|
};
|
|
6
7
|
type Updater = <T>() => T | boolean | void;
|
|
8
|
+
/**
|
|
9
|
+
* Create a watcher that can be used to observe changes to a signal
|
|
10
|
+
*
|
|
11
|
+
* @since 0.14.1
|
|
12
|
+
* @param {() => void} notice - function to be called when the state changes
|
|
13
|
+
* @returns {Watcher} - watcher object with off and cleanup methods
|
|
14
|
+
*/
|
|
15
|
+
declare const watch: (notice: () => void) => Watcher;
|
|
7
16
|
/**
|
|
8
17
|
* Add active watcher to the Set of watchers
|
|
9
18
|
*
|
|
@@ -30,9 +39,9 @@ declare const batch: (fn: () => void) => void;
|
|
|
30
39
|
* Run a function in a reactive context
|
|
31
40
|
*
|
|
32
41
|
* @param {() => void} run - function to run the computation or effect
|
|
33
|
-
* @param {Watcher}
|
|
42
|
+
* @param {Watcher} watcher - function to be called when the state changes or undefined for temporary unwatching while inserting auto-hydrating DOM nodes that might read signals (e.g., web components)
|
|
34
43
|
*/
|
|
35
|
-
declare const
|
|
44
|
+
declare const observe: (run: () => void, watcher?: Watcher) => void;
|
|
36
45
|
/**
|
|
37
46
|
* Enqueue a function to be executed on the next animation frame
|
|
38
47
|
*
|
|
@@ -43,4 +52,4 @@ declare const watch: (run: () => void, mark?: Watcher) => void;
|
|
|
43
52
|
* @param {symbol} dedupe - Symbol for deduplication; if not provided, a unique Symbol is created ensuring the update is always executed
|
|
44
53
|
*/
|
|
45
54
|
declare const enqueue: <T>(fn: Updater, dedupe?: symbol) => Promise<boolean | void | T>;
|
|
46
|
-
export { type Cleanup, type Watcher, type Updater, subscribe, notify, flush, batch, watch, enqueue, };
|
|
55
|
+
export { type Cleanup, type Watcher, type Updater, subscribe, notify, flush, batch, watch, observe, enqueue, };
|
package/src/scheduler.ts
CHANGED
|
@@ -4,7 +4,8 @@ type Cleanup = () => void
|
|
|
4
4
|
|
|
5
5
|
type Watcher = {
|
|
6
6
|
(): void
|
|
7
|
-
|
|
7
|
+
off(cleanup: Cleanup): void
|
|
8
|
+
cleanup(): void
|
|
8
9
|
}
|
|
9
10
|
|
|
10
11
|
type Updater = <T>() => T | boolean | void
|
|
@@ -26,8 +27,8 @@ const updateDOM = () => {
|
|
|
26
27
|
requestId = undefined
|
|
27
28
|
const updates = Array.from(updateMap.values())
|
|
28
29
|
updateMap.clear()
|
|
29
|
-
for (const
|
|
30
|
-
|
|
30
|
+
for (const update of updates) {
|
|
31
|
+
update()
|
|
31
32
|
}
|
|
32
33
|
}
|
|
33
34
|
|
|
@@ -41,17 +42,38 @@ queueMicrotask(updateDOM)
|
|
|
41
42
|
|
|
42
43
|
/* === Functions === */
|
|
43
44
|
|
|
45
|
+
/**
|
|
46
|
+
* Create a watcher that can be used to observe changes to a signal
|
|
47
|
+
*
|
|
48
|
+
* @since 0.14.1
|
|
49
|
+
* @param {() => void} notice - function to be called when the state changes
|
|
50
|
+
* @returns {Watcher} - watcher object with off and cleanup methods
|
|
51
|
+
*/
|
|
52
|
+
const watch = (notice: () => void): Watcher => {
|
|
53
|
+
const cleanups = new Set<Cleanup>()
|
|
54
|
+
const w = notice as Partial<Watcher>
|
|
55
|
+
w.off = (on: Cleanup) => {
|
|
56
|
+
cleanups.add(on)
|
|
57
|
+
}
|
|
58
|
+
w.cleanup = () => {
|
|
59
|
+
for (const cleanup of cleanups) {
|
|
60
|
+
cleanup()
|
|
61
|
+
}
|
|
62
|
+
cleanups.clear()
|
|
63
|
+
}
|
|
64
|
+
return w as Watcher
|
|
65
|
+
}
|
|
66
|
+
|
|
44
67
|
/**
|
|
45
68
|
* Add active watcher to the Set of watchers
|
|
46
69
|
*
|
|
47
70
|
* @param {Set<Watcher>} watchers - watchers of the signal
|
|
48
71
|
*/
|
|
49
72
|
const subscribe = (watchers: Set<Watcher>) => {
|
|
50
|
-
// if (!active) console.warn('Calling .get() outside of a reactive context')
|
|
51
73
|
if (active && !watchers.has(active)) {
|
|
52
74
|
const watcher = active
|
|
53
75
|
watchers.add(watcher)
|
|
54
|
-
active.
|
|
76
|
+
active.off(() => {
|
|
55
77
|
watchers.delete(watcher)
|
|
56
78
|
})
|
|
57
79
|
}
|
|
@@ -63,9 +85,9 @@ const subscribe = (watchers: Set<Watcher>) => {
|
|
|
63
85
|
* @param {Set<Watcher>} watchers - watchers of the signal
|
|
64
86
|
*/
|
|
65
87
|
const notify = (watchers: Set<Watcher>) => {
|
|
66
|
-
for (const
|
|
67
|
-
if (batchDepth) pending.add(
|
|
68
|
-
else
|
|
88
|
+
for (const watcher of watchers) {
|
|
89
|
+
if (batchDepth) pending.add(watcher)
|
|
90
|
+
else watcher()
|
|
69
91
|
}
|
|
70
92
|
}
|
|
71
93
|
|
|
@@ -76,8 +98,8 @@ const flush = () => {
|
|
|
76
98
|
while (pending.size) {
|
|
77
99
|
const watchers = Array.from(pending)
|
|
78
100
|
pending.clear()
|
|
79
|
-
for (const
|
|
80
|
-
|
|
101
|
+
for (const watcher of watchers) {
|
|
102
|
+
watcher()
|
|
81
103
|
}
|
|
82
104
|
}
|
|
83
105
|
}
|
|
@@ -101,11 +123,11 @@ const batch = (fn: () => void) => {
|
|
|
101
123
|
* Run a function in a reactive context
|
|
102
124
|
*
|
|
103
125
|
* @param {() => void} run - function to run the computation or effect
|
|
104
|
-
* @param {Watcher}
|
|
126
|
+
* @param {Watcher} watcher - function to be called when the state changes or undefined for temporary unwatching while inserting auto-hydrating DOM nodes that might read signals (e.g., web components)
|
|
105
127
|
*/
|
|
106
|
-
const
|
|
128
|
+
const observe = (run: () => void, watcher?: Watcher): void => {
|
|
107
129
|
const prev = active
|
|
108
|
-
active =
|
|
130
|
+
active = watcher
|
|
109
131
|
try {
|
|
110
132
|
run()
|
|
111
133
|
} finally {
|
|
@@ -145,5 +167,6 @@ export {
|
|
|
145
167
|
flush,
|
|
146
168
|
batch,
|
|
147
169
|
watch,
|
|
170
|
+
observe,
|
|
148
171
|
enqueue,
|
|
149
172
|
}
|
package/src/signal.d.ts
CHANGED
|
@@ -1,8 +1,11 @@
|
|
|
1
|
-
import { type ComputedCallback } from './computed';
|
|
1
|
+
import { type ComputedCallback, isComputedCallback } from './computed';
|
|
2
2
|
type Signal<T extends {}> = {
|
|
3
3
|
get(): T;
|
|
4
4
|
};
|
|
5
5
|
type MaybeSignal<T extends {}> = T | Signal<T> | ComputedCallback<T>;
|
|
6
|
+
type SignalValues<S extends Signal<{}>[]> = {
|
|
7
|
+
[K in keyof S]: S[K] extends Signal<infer T> ? T : never;
|
|
8
|
+
};
|
|
6
9
|
declare const UNSET: any;
|
|
7
10
|
/**
|
|
8
11
|
* Check whether a value is a Signal or not
|
|
@@ -12,14 +15,6 @@ declare const UNSET: any;
|
|
|
12
15
|
* @returns {boolean} - true if value is a Signal, false otherwise
|
|
13
16
|
*/
|
|
14
17
|
declare const isSignal: <T extends {}>(value: unknown) => value is Signal<T>;
|
|
15
|
-
/**
|
|
16
|
-
* Check if the provided value is a callback that may be used as input for toSignal() to derive a computed state
|
|
17
|
-
*
|
|
18
|
-
* @since 0.12.0
|
|
19
|
-
* @param {unknown} value - value to check
|
|
20
|
-
* @returns {boolean} - true if value is a callback or callbacks object, false otherwise
|
|
21
|
-
*/
|
|
22
|
-
declare const isComputedCallback: <T extends {}>(value: unknown) => value is ComputedCallback<T>;
|
|
23
18
|
/**
|
|
24
19
|
* Convert a value to a Signal if it's not already a Signal
|
|
25
20
|
*
|
|
@@ -28,4 +23,4 @@ declare const isComputedCallback: <T extends {}>(value: unknown) => value is Com
|
|
|
28
23
|
* @returns {Signal<T>} - converted Signal
|
|
29
24
|
*/
|
|
30
25
|
declare const toSignal: <T extends {}>(value: MaybeSignal<T>) => Signal<T>;
|
|
31
|
-
export { type Signal, type MaybeSignal, UNSET, isSignal, isComputedCallback, toSignal, };
|
|
26
|
+
export { type Signal, type MaybeSignal, type SignalValues, UNSET, isSignal, isComputedCallback, toSignal, };
|
package/src/signal.ts
CHANGED
|
@@ -2,9 +2,9 @@ import { isState, state } from './state'
|
|
|
2
2
|
import {
|
|
3
3
|
type ComputedCallback,
|
|
4
4
|
isComputed,
|
|
5
|
+
isComputedCallback,
|
|
5
6
|
computed,
|
|
6
7
|
} from './computed'
|
|
7
|
-
import { isFunction } from './util'
|
|
8
8
|
|
|
9
9
|
/* === Types === */
|
|
10
10
|
|
|
@@ -13,11 +13,15 @@ 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<{}>[]> = {
|
|
17
|
+
[K in keyof S]: S[K] extends Signal<infer T> ? T : never
|
|
18
|
+
}
|
|
19
|
+
|
|
16
20
|
/* === Constants === */
|
|
17
21
|
|
|
18
22
|
const UNSET: any = Symbol()
|
|
19
23
|
|
|
20
|
-
/* ===
|
|
24
|
+
/* === Functions === */
|
|
21
25
|
|
|
22
26
|
/**
|
|
23
27
|
* Check whether a value is a Signal or not
|
|
@@ -30,17 +34,6 @@ const isSignal = /*#__PURE__*/ <T extends {}>(
|
|
|
30
34
|
value: unknown,
|
|
31
35
|
): value is Signal<T> => isState(value) || isComputed(value)
|
|
32
36
|
|
|
33
|
-
/**
|
|
34
|
-
* Check if the provided value is a callback that may be used as input for toSignal() to derive a computed state
|
|
35
|
-
*
|
|
36
|
-
* @since 0.12.0
|
|
37
|
-
* @param {unknown} value - value to check
|
|
38
|
-
* @returns {boolean} - true if value is a callback or callbacks object, false otherwise
|
|
39
|
-
*/
|
|
40
|
-
const isComputedCallback = /*#__PURE__*/ <T extends {}>(
|
|
41
|
-
value: unknown,
|
|
42
|
-
): value is ComputedCallback<T> => isFunction(value) && value.length < 2
|
|
43
|
-
|
|
44
37
|
/**
|
|
45
38
|
* Convert a value to a Signal if it's not already a Signal
|
|
46
39
|
*
|
|
@@ -62,6 +55,7 @@ const toSignal = /*#__PURE__*/ <T extends {}>(
|
|
|
62
55
|
export {
|
|
63
56
|
type Signal,
|
|
64
57
|
type MaybeSignal,
|
|
58
|
+
type SignalValues,
|
|
65
59
|
UNSET,
|
|
66
60
|
isSignal,
|
|
67
61
|
isComputedCallback,
|
package/src/state.d.ts
CHANGED
|
@@ -4,6 +4,7 @@ type State<T extends {}> = {
|
|
|
4
4
|
set(v: T): void;
|
|
5
5
|
update(fn: (v: T) => T): void;
|
|
6
6
|
};
|
|
7
|
+
declare const TYPE_STATE = "State";
|
|
7
8
|
/**
|
|
8
9
|
* Create a new state signal
|
|
9
10
|
*
|
|
@@ -20,4 +21,4 @@ declare const state: <T extends {}>(initialValue: T) => State<T>;
|
|
|
20
21
|
* @returns {boolean} - true if the value is a State instance, false otherwise
|
|
21
22
|
*/
|
|
22
23
|
declare const isState: <T extends {}>(value: unknown) => value is State<T>;
|
|
23
|
-
export { type State, state, isState };
|
|
24
|
+
export { type State, TYPE_STATE, state, isState };
|
package/src/state.ts
CHANGED
package/src/util.d.ts
CHANGED
|
@@ -1,11 +1,7 @@
|
|
|
1
1
|
declare const isFunction: <T>(value: unknown) => value is (...args: unknown[]) => T;
|
|
2
|
-
declare const isAsyncFunction: <T>(value: unknown) => value is (...args: unknown[]) => Promise<T>;
|
|
3
2
|
declare const isObjectOfType: <T>(value: unknown, type: string) => value is T;
|
|
4
|
-
declare const isError: (value: unknown) => value is Error;
|
|
5
|
-
declare const isAbortError: (value: unknown) => value is DOMException;
|
|
6
|
-
declare const isPromise: <T>(value: unknown) => value is Promise<T>;
|
|
7
3
|
declare const toError: (reason: unknown) => Error;
|
|
8
4
|
declare class CircularDependencyError extends Error {
|
|
9
5
|
constructor(where: string);
|
|
10
6
|
}
|
|
11
|
-
export { isFunction,
|
|
7
|
+
export { isFunction, isObjectOfType, toError, CircularDependencyError };
|
package/src/util.ts
CHANGED
|
@@ -4,24 +4,13 @@ const isFunction = /*#__PURE__*/ <T>(
|
|
|
4
4
|
value: unknown,
|
|
5
5
|
): value is (...args: unknown[]) => T => typeof value === 'function'
|
|
6
6
|
|
|
7
|
-
const isAsyncFunction = /*#__PURE__*/ <T>(
|
|
8
|
-
value: unknown,
|
|
9
|
-
): value is (...args: unknown[]) => Promise<T> =>
|
|
10
|
-
isFunction(value) && value.constructor.name === 'AsyncFunction'
|
|
11
|
-
|
|
12
7
|
const isObjectOfType = /*#__PURE__*/ <T>(
|
|
13
8
|
value: unknown,
|
|
14
9
|
type: string,
|
|
15
10
|
): value is T => Object.prototype.toString.call(value) === `[object ${type}]`
|
|
16
11
|
|
|
17
|
-
const isError = /*#__PURE__*/ (value: unknown): value is Error =>
|
|
18
|
-
value instanceof Error
|
|
19
|
-
const isAbortError = /*#__PURE__*/ (value: unknown): value is DOMException =>
|
|
20
|
-
value instanceof DOMException && value.name === 'AbortError'
|
|
21
|
-
const isPromise = /*#__PURE__*/ <T>(value: unknown): value is Promise<T> =>
|
|
22
|
-
value instanceof Promise
|
|
23
12
|
const toError = (reason: unknown): Error =>
|
|
24
|
-
|
|
13
|
+
reason instanceof Error ? reason : Error(String(reason))
|
|
25
14
|
|
|
26
15
|
class CircularDependencyError extends Error {
|
|
27
16
|
constructor(where: string) {
|
|
@@ -32,13 +21,4 @@ class CircularDependencyError extends Error {
|
|
|
32
21
|
|
|
33
22
|
/* === Exports === */
|
|
34
23
|
|
|
35
|
-
export {
|
|
36
|
-
isFunction,
|
|
37
|
-
isAsyncFunction,
|
|
38
|
-
isObjectOfType,
|
|
39
|
-
isError,
|
|
40
|
-
isAbortError,
|
|
41
|
-
isPromise,
|
|
42
|
-
toError,
|
|
43
|
-
CircularDependencyError,
|
|
44
|
-
}
|
|
24
|
+
export { isFunction, isObjectOfType, toError, CircularDependencyError }
|
package/test/batch.test.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { describe, test, expect } from 'bun:test'
|
|
2
|
-
import { state,
|
|
2
|
+
import { state, computed, batch, effect } from '../'
|
|
3
3
|
|
|
4
4
|
/* === Tests === */
|
|
5
5
|
|
|
@@ -25,7 +25,7 @@ describe('Batch', function () {
|
|
|
25
25
|
const a = state(3)
|
|
26
26
|
const b = state(4)
|
|
27
27
|
const c = state(5)
|
|
28
|
-
const sum =
|
|
28
|
+
const sum = computed(() => a.get() + b.get() + c.get())
|
|
29
29
|
let result = 0
|
|
30
30
|
let count = 0
|
|
31
31
|
effect({
|
|
@@ -50,7 +50,7 @@ describe('Batch', function () {
|
|
|
50
50
|
const signals = [state(2), state(3), state(5)]
|
|
51
51
|
|
|
52
52
|
// Computed: derive a calculation ...
|
|
53
|
-
const sum =
|
|
53
|
+
const sum = computed(() => {
|
|
54
54
|
const v = signals.reduce((total, v) => total + v.get(), 0)
|
|
55
55
|
if (!Number.isFinite(v)) throw new Error('Invalid value')
|
|
56
56
|
return v
|
package/test/benchmark.test.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { describe, test, expect, mock } from 'bun:test'
|
|
2
|
-
import { state,
|
|
2
|
+
import { state, computed, effect, batch } from '../'
|
|
3
3
|
import { makeGraph, runGraph, Counter } from './util/dependency-graph'
|
|
4
4
|
import {
|
|
5
5
|
type ReactiveFramework,
|
|
@@ -25,7 +25,7 @@ const framework = {
|
|
|
25
25
|
}
|
|
26
26
|
},
|
|
27
27
|
computed: <T extends {}>(fn: () => T) => {
|
|
28
|
-
const c =
|
|
28
|
+
const c = computed(fn)
|
|
29
29
|
return {
|
|
30
30
|
read: () => c.get(),
|
|
31
31
|
}
|