-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathpodium.ts
More file actions
67 lines (53 loc) · 1.21 KB
/
podium.ts
File metadata and controls
67 lines (53 loc) · 1.21 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
60
61
62
63
64
65
66
import {Pod, PodSelect} from "./types.js"
export const podium = {
status: (pod: Pod<any>) => pod[0],
value: <V>(pod: Pod<V>) => {
return pod[0] === "ready"
? pod[1]
: undefined
},
error: <V>(pod: Pod<V>) => {
return pod[0] === "error"
? pod[1]
: undefined
},
select: <V, R>(pod: Pod<V>, select: PodSelect<V, R>) => {
switch (pod[0]) {
case "loading": return select.loading()
case "error": return select.error(pod[1])
case "ready": return select.ready(pod[1])
default: throw new Error("unknown op status")
}
},
morph: <A, B>(pod: Pod<A>, fn: (a: A) => B): Pod<B> => {
return podium.select<A, Pod<B>>(pod, {
loading: () => ["loading"],
error: error => ["error", error],
ready: a => ["ready", fn(a)],
})
},
all: <V>(...pods: Pod<V>[]): Pod<V[]> => {
const values: V[] = []
const errors: any[] = []
let loading = 0
for (const pod of pods) {
switch (pod[0]) {
case "loading":
loading++
break
case "ready":
values.push(pod[1])
break
case "error":
errors.push(pod[1])
break
}
}
if (errors.length > 0)
return ["error", errors]
else if (loading === 0)
return ["ready", values]
else
return ["loading"]
}
}