-
Notifications
You must be signed in to change notification settings - Fork 2
Expand file tree
/
Copy path07-reactive-js.ts
More file actions
59 lines (49 loc) · 1.2 KB
/
07-reactive-js.ts
File metadata and controls
59 lines (49 loc) · 1.2 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
// A library with reactive primitives
import { cooked } from "../../string-cooked.js"
let currentEffect: (() => void) | undefined
export function createEffect(fn: () => void) {
try {
var parentEffect = currentEffect
currentEffect = fn
fn()
} finally {
currentEffect = parentEffect
}
}
export function createSignal<T>(
value: T,
): [get: () => T, set: (value: T) => void] {
const listeners = new Set<() => void>()
return [
() => {
if (currentEffect) {
listeners.add(currentEffect)
}
return value
},
(val) => {
value = val
listeners.forEach((fn) => fn())
},
]
}
export function createMemo<T>(fn: () => T): () => T {
const [get, set] = (createSignal as any)() as ReturnType<
typeof createSignal<T>
>
createEffect(() => set(fn()))
return get
}
export function string(
strings: readonly string[],
...values: readonly unknown[]
) {
return createMemo(() =>
cooked(
strings,
values.map((value) =>
typeof value == "function" ? value() : value,
),
),
)
}