@e280/sly 0.0.0-3 → 0.0.0-5
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 +108 -87
- package/package.json +3 -3
- package/s/demo/demo.bundle.ts +3 -47
- package/s/demo/demo.css +13 -6
- package/s/demo/views/counter.ts +42 -0
- package/s/demo/views/demo.ts +25 -0
- package/s/demo/views/loaders.ts +58 -0
- package/s/features/dom/dollar.ts +13 -9
- package/s/features/op/loaders/make-loader.ts +18 -0
- package/s/features/op/loaders/parts/anims.ts +277 -0
- package/s/features/op/loaders/parts/ascii-anim.ts +38 -0
- package/s/features/{loady → op/loaders}/parts/error-display.ts +10 -10
- package/s/features/op/op.ts +42 -20
- package/s/features/op/podium.ts +67 -0
- package/s/features/views/types.ts +9 -2
- package/s/features/views/use.ts +20 -9
- package/s/features/views/view.ts +15 -8
- package/s/index.html.ts +3 -3
- package/s/index.ts +4 -3
- package/x/demo/demo.bundle.js +2 -36
- package/x/demo/demo.bundle.js.map +1 -1
- package/x/demo/demo.bundle.min.js +61 -12
- package/x/demo/demo.bundle.min.js.map +4 -4
- package/x/demo/demo.css +13 -6
- package/x/demo/views/counter.d.ts +1 -0
- package/x/demo/views/counter.js +34 -0
- package/x/demo/views/counter.js.map +1 -0
- package/x/demo/views/demo.d.ts +1 -0
- package/x/demo/views/demo.js +21 -0
- package/x/demo/views/demo.js.map +1 -0
- package/x/demo/views/loaders.d.ts +1 -0
- package/x/demo/views/loaders.js +50 -0
- package/x/demo/views/loaders.js.map +1 -0
- package/x/features/dom/dollar.d.ts +6 -5
- package/x/features/dom/dollar.js +8 -7
- package/x/features/dom/dollar.js.map +1 -1
- package/x/features/op/loaders/make-loader.d.ts +5 -0
- package/x/features/op/loaders/make-loader.js +7 -0
- package/x/features/op/loaders/make-loader.js.map +1 -0
- package/x/features/op/loaders/parts/anims.d.ts +24 -0
- package/x/features/op/loaders/parts/anims.js +251 -0
- package/x/features/op/loaders/parts/anims.js.map +1 -0
- package/x/features/op/loaders/parts/ascii-anim.d.ts +6 -0
- package/x/features/op/loaders/parts/ascii-anim.js +26 -0
- package/x/features/op/loaders/parts/ascii-anim.js.map +1 -0
- package/x/features/op/loaders/parts/error-display.d.ts +1 -0
- package/x/features/{loady → op/loaders}/parts/error-display.js +9 -9
- package/x/features/op/loaders/parts/error-display.js.map +1 -0
- package/x/features/op/op.d.ts +12 -3
- package/x/features/op/op.js +33 -17
- package/x/features/op/op.js.map +1 -1
- package/x/features/op/podium.d.ts +9 -0
- package/x/features/op/podium.js +53 -0
- package/x/features/op/podium.js.map +1 -0
- package/x/features/views/types.d.ts +9 -2
- package/x/features/views/use.d.ts +8 -6
- package/x/features/views/use.js +21 -10
- package/x/features/views/use.js.map +1 -1
- package/x/features/views/view.d.ts +2 -10
- package/x/features/views/view.js +12 -6
- package/x/features/views/view.js.map +1 -1
- package/x/index.d.ts +4 -3
- package/x/index.html +18 -11
- package/x/index.html.js +3 -3
- package/x/index.html.js.map +1 -1
- package/x/index.js +4 -3
- package/x/index.js.map +1 -1
- package/s/features/loady/ascii-loader.ts +0 -38
- package/s/features/loady/parts/ascii-anim.ts +0 -27
- package/s/features/loady/parts/ascii-loader.ts +0 -14
- package/s/features/op/pod.ts +0 -19
- package/x/features/loady/ascii-loader.d.ts +0 -5
- package/x/features/loady/ascii-loader.js +0 -33
- package/x/features/loady/ascii-loader.js.map +0 -1
- package/x/features/loady/parts/ascii-anim.d.ts +0 -8
- package/x/features/loady/parts/ascii-anim.js +0 -21
- package/x/features/loady/parts/ascii-anim.js.map +0 -1
- package/x/features/loady/parts/ascii-loader.d.ts +0 -3
- package/x/features/loady/parts/ascii-loader.js +0 -10
- package/x/features/loady/parts/ascii-loader.js.map +0 -1
- package/x/features/loady/parts/error-display.d.ts +0 -8
- package/x/features/loady/parts/error-display.js.map +0 -1
- package/x/features/op/pod.d.ts +0 -5
- package/x/features/op/pod.js +0 -16
- package/x/features/op/pod.js.map +0 -1
|
@@ -0,0 +1,277 @@
|
|
|
1
|
+
|
|
2
|
+
import {makeAsciiAnim} from "./ascii-anim.js"
|
|
3
|
+
import {Content} from "../../../views/types.js"
|
|
4
|
+
|
|
5
|
+
const hz = 20
|
|
6
|
+
|
|
7
|
+
export const spinner = makeAsciiAnim(hz, [
|
|
8
|
+
"|",
|
|
9
|
+
"/",
|
|
10
|
+
"-",
|
|
11
|
+
"\\",
|
|
12
|
+
])
|
|
13
|
+
|
|
14
|
+
export const braille = makeAsciiAnim(hz, [
|
|
15
|
+
"⠈",
|
|
16
|
+
"⠐",
|
|
17
|
+
"⠠",
|
|
18
|
+
"⢀",
|
|
19
|
+
"⡀",
|
|
20
|
+
"⠄",
|
|
21
|
+
"⠂",
|
|
22
|
+
"⠁",
|
|
23
|
+
])
|
|
24
|
+
|
|
25
|
+
export const arrow = makeAsciiAnim(hz, [
|
|
26
|
+
"←",
|
|
27
|
+
"↖",
|
|
28
|
+
"↑",
|
|
29
|
+
"↗",
|
|
30
|
+
"→",
|
|
31
|
+
"↘",
|
|
32
|
+
"↓",
|
|
33
|
+
"↙",
|
|
34
|
+
])
|
|
35
|
+
|
|
36
|
+
export const arrow2 = makeAsciiAnim(hz, [
|
|
37
|
+
"⬆️",
|
|
38
|
+
"↗️",
|
|
39
|
+
"➡️",
|
|
40
|
+
"↘️",
|
|
41
|
+
"⬇️",
|
|
42
|
+
"↙️",
|
|
43
|
+
"⬅️",
|
|
44
|
+
"↖️",
|
|
45
|
+
])
|
|
46
|
+
|
|
47
|
+
export const bar = makeAsciiAnim(hz, [
|
|
48
|
+
"▰▱▱▱▱",
|
|
49
|
+
"▰▱▱▱▱",
|
|
50
|
+
"▱▰▱▱▱",
|
|
51
|
+
"▱▱▰▱▱",
|
|
52
|
+
"▱▱▱▰▱",
|
|
53
|
+
"▱▱▱▱▰",
|
|
54
|
+
"▱▱▱▱▰",
|
|
55
|
+
"▱▱▱▰▱",
|
|
56
|
+
"▱▱▰▱▱",
|
|
57
|
+
"▱▰▱▱▱",
|
|
58
|
+
])
|
|
59
|
+
|
|
60
|
+
export const bar2 = makeAsciiAnim(hz, [
|
|
61
|
+
"▱▱▰▱▱",
|
|
62
|
+
"▱▱▱▰▱",
|
|
63
|
+
"▱▱▱▰▰",
|
|
64
|
+
"▱▱▱▰▰",
|
|
65
|
+
"▱▱▱▱▰",
|
|
66
|
+
"▱▱▱▱▰",
|
|
67
|
+
"▱▱▱▱▰",
|
|
68
|
+
"▱▱▱▰▰",
|
|
69
|
+
"▱▱▱▰▰",
|
|
70
|
+
"▱▱▱▰▱",
|
|
71
|
+
"▱▱▰▱▱",
|
|
72
|
+
"▱▰▱▱▱",
|
|
73
|
+
"▰▰▱▱▱",
|
|
74
|
+
"▰▰▱▱▱",
|
|
75
|
+
"▰▱▱▱▱",
|
|
76
|
+
"▰▱▱▱▱",
|
|
77
|
+
"▰▱▱▱▱",
|
|
78
|
+
"▰▰▱▱▱",
|
|
79
|
+
"▰▰▱▱▱",
|
|
80
|
+
"▱▰▱▱▱",
|
|
81
|
+
])
|
|
82
|
+
|
|
83
|
+
export const bar3 = makeAsciiAnim(hz, [
|
|
84
|
+
"▰▱▱▱▱",
|
|
85
|
+
"▰▱▱▱▱",
|
|
86
|
+
"▰▰▱▱▱",
|
|
87
|
+
"▰▰▰▱▱",
|
|
88
|
+
"▱▰▰▰▱",
|
|
89
|
+
"▱▱▰▰▰",
|
|
90
|
+
"▱▱▱▰▰",
|
|
91
|
+
"▱▱▱▱▰",
|
|
92
|
+
"▱▱▱▱▰",
|
|
93
|
+
"▱▱▱▰▰",
|
|
94
|
+
"▱▱▰▰▰",
|
|
95
|
+
"▱▰▰▰▱",
|
|
96
|
+
"▰▰▰▱▱",
|
|
97
|
+
"▰▰▱▱▱",
|
|
98
|
+
])
|
|
99
|
+
|
|
100
|
+
export const bar4 = makeAsciiAnim(hz, [
|
|
101
|
+
"▱▱▱▱▱",
|
|
102
|
+
"▰▱▱▱▱",
|
|
103
|
+
"▰▰▱▱▱",
|
|
104
|
+
"▰▰▰▱▱",
|
|
105
|
+
"▰▰▰▰▱",
|
|
106
|
+
"▰▰▰▰▰",
|
|
107
|
+
"▰▰▰▰▰",
|
|
108
|
+
"▱▰▰▰▰",
|
|
109
|
+
"▱▱▰▰▰",
|
|
110
|
+
"▱▱▱▰▰",
|
|
111
|
+
"▱▱▱▱▰",
|
|
112
|
+
])
|
|
113
|
+
|
|
114
|
+
export const pie = makeAsciiAnim(hz, [
|
|
115
|
+
"◷",
|
|
116
|
+
"◶",
|
|
117
|
+
"◵",
|
|
118
|
+
"◴",
|
|
119
|
+
])
|
|
120
|
+
|
|
121
|
+
export const cylon = makeAsciiAnim(hz, [
|
|
122
|
+
"=----",
|
|
123
|
+
"-=---",
|
|
124
|
+
"--=--",
|
|
125
|
+
"---=-",
|
|
126
|
+
"----=",
|
|
127
|
+
"----=",
|
|
128
|
+
"---=-",
|
|
129
|
+
"--=--",
|
|
130
|
+
"-=---",
|
|
131
|
+
"=----",
|
|
132
|
+
])
|
|
133
|
+
|
|
134
|
+
export const slider = makeAsciiAnim(hz, [
|
|
135
|
+
"o----",
|
|
136
|
+
"-o---",
|
|
137
|
+
"--o--",
|
|
138
|
+
"---o-",
|
|
139
|
+
"----o",
|
|
140
|
+
"----o",
|
|
141
|
+
"---o-",
|
|
142
|
+
"--o--",
|
|
143
|
+
"-o---",
|
|
144
|
+
"o----",
|
|
145
|
+
])
|
|
146
|
+
|
|
147
|
+
export const scrubber = makeAsciiAnim(hz, [
|
|
148
|
+
":....",
|
|
149
|
+
":....",
|
|
150
|
+
"::...",
|
|
151
|
+
".::..",
|
|
152
|
+
"..::.",
|
|
153
|
+
"...::",
|
|
154
|
+
"....:",
|
|
155
|
+
"....:",
|
|
156
|
+
"...::",
|
|
157
|
+
"..::.",
|
|
158
|
+
".::..",
|
|
159
|
+
"::...",
|
|
160
|
+
])
|
|
161
|
+
|
|
162
|
+
export const pulse = makeAsciiAnim(hz, [
|
|
163
|
+
".....",
|
|
164
|
+
".....",
|
|
165
|
+
"..:..",
|
|
166
|
+
".:::.",
|
|
167
|
+
".:::.",
|
|
168
|
+
":::::",
|
|
169
|
+
":::::",
|
|
170
|
+
"::.::",
|
|
171
|
+
":...:",
|
|
172
|
+
])
|
|
173
|
+
|
|
174
|
+
export const bin = makeAsciiAnim(hz, [
|
|
175
|
+
"000",
|
|
176
|
+
"100",
|
|
177
|
+
"110",
|
|
178
|
+
"111",
|
|
179
|
+
"011",
|
|
180
|
+
"001",
|
|
181
|
+
])
|
|
182
|
+
|
|
183
|
+
export const binary = makeAsciiAnim(hz, [
|
|
184
|
+
"11111",
|
|
185
|
+
"01111",
|
|
186
|
+
"00111",
|
|
187
|
+
"10011",
|
|
188
|
+
"11001",
|
|
189
|
+
"01100",
|
|
190
|
+
"00110",
|
|
191
|
+
"10011",
|
|
192
|
+
"11001",
|
|
193
|
+
"11100",
|
|
194
|
+
"11110",
|
|
195
|
+
])
|
|
196
|
+
|
|
197
|
+
export const binary2 = makeAsciiAnim(hz, [
|
|
198
|
+
"11111",
|
|
199
|
+
"01111",
|
|
200
|
+
"10111",
|
|
201
|
+
"11011",
|
|
202
|
+
"11101",
|
|
203
|
+
"11110",
|
|
204
|
+
"11111",
|
|
205
|
+
"11110",
|
|
206
|
+
"11101",
|
|
207
|
+
"11011",
|
|
208
|
+
"10111",
|
|
209
|
+
"01111",
|
|
210
|
+
])
|
|
211
|
+
|
|
212
|
+
export const clock = makeAsciiAnim(hz, [
|
|
213
|
+
"🕐",
|
|
214
|
+
"🕑",
|
|
215
|
+
"🕒",
|
|
216
|
+
"🕓",
|
|
217
|
+
"🕔",
|
|
218
|
+
"🕕",
|
|
219
|
+
"🕖",
|
|
220
|
+
"🕗",
|
|
221
|
+
"🕘",
|
|
222
|
+
"🕙",
|
|
223
|
+
"🕚",
|
|
224
|
+
"🕛",
|
|
225
|
+
])
|
|
226
|
+
|
|
227
|
+
export const fistbump = makeAsciiAnim(hz, [
|
|
228
|
+
"🤜 🤛",
|
|
229
|
+
"🤜 🤛",
|
|
230
|
+
"🤜 🤛",
|
|
231
|
+
" 🤜 🤛 ",
|
|
232
|
+
" 🤜🤛 ",
|
|
233
|
+
" 🤜🤛 ",
|
|
234
|
+
" 🤜💥🤛 ",
|
|
235
|
+
"🤜 💥 🤛",
|
|
236
|
+
"🤜 ✨ 🤛",
|
|
237
|
+
"🤜 ✨ 🤛",
|
|
238
|
+
])
|
|
239
|
+
|
|
240
|
+
export const earth = makeAsciiAnim(4, [
|
|
241
|
+
"🌎",
|
|
242
|
+
"🌏",
|
|
243
|
+
"🌍",
|
|
244
|
+
])
|
|
245
|
+
|
|
246
|
+
export const lock = makeAsciiAnim(4, [
|
|
247
|
+
"🔓",
|
|
248
|
+
"🔒",
|
|
249
|
+
])
|
|
250
|
+
|
|
251
|
+
export const bright = makeAsciiAnim(4, [
|
|
252
|
+
"🔅",
|
|
253
|
+
"🔆",
|
|
254
|
+
])
|
|
255
|
+
|
|
256
|
+
export const speaker = makeAsciiAnim(4, [
|
|
257
|
+
"🔈",
|
|
258
|
+
"🔈",
|
|
259
|
+
"🔉",
|
|
260
|
+
"🔊",
|
|
261
|
+
"🔊",
|
|
262
|
+
"🔉",
|
|
263
|
+
])
|
|
264
|
+
|
|
265
|
+
export const moon = makeAsciiAnim(10, [
|
|
266
|
+
"🌑",
|
|
267
|
+
"🌑",
|
|
268
|
+
"🌑",
|
|
269
|
+
"🌘",
|
|
270
|
+
"🌗",
|
|
271
|
+
"🌖",
|
|
272
|
+
"🌕",
|
|
273
|
+
"🌔",
|
|
274
|
+
"🌓",
|
|
275
|
+
"🌒",
|
|
276
|
+
])
|
|
277
|
+
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
|
|
2
|
+
import {css} from "lit"
|
|
3
|
+
import {nap, repeat} from "@e280/stz"
|
|
4
|
+
|
|
5
|
+
import {view} from "../../../views/view.js"
|
|
6
|
+
import {Content} from "../../../views/types.js"
|
|
7
|
+
import {cssReset} from "../../../views/css-reset.js"
|
|
8
|
+
|
|
9
|
+
export function makeAsciiAnim(hz: number, frames: string[]): () => Content {
|
|
10
|
+
return () => AsciiAnim({hz, frames})
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export const AsciiAnim = view(use => ({hz, frames}: {
|
|
14
|
+
hz: number,
|
|
15
|
+
frames: string[],
|
|
16
|
+
}) => {
|
|
17
|
+
|
|
18
|
+
use.name("loading")
|
|
19
|
+
use.styles(cssReset, style)
|
|
20
|
+
const frame = use.signal(0)
|
|
21
|
+
|
|
22
|
+
use.mount(() => repeat(async() => {
|
|
23
|
+
await nap(1000 / hz)
|
|
24
|
+
const next = frame() + 1
|
|
25
|
+
frame(next >= frames.length ? 0 : next)
|
|
26
|
+
}))
|
|
27
|
+
|
|
28
|
+
return frames.at(frame())
|
|
29
|
+
})
|
|
30
|
+
|
|
31
|
+
const style = css`
|
|
32
|
+
:host {
|
|
33
|
+
font-family: monospace;
|
|
34
|
+
white-space: pre;
|
|
35
|
+
user-select: none;
|
|
36
|
+
}
|
|
37
|
+
`
|
|
38
|
+
|
|
@@ -1,17 +1,10 @@
|
|
|
1
1
|
|
|
2
2
|
import {css, html} from "lit"
|
|
3
|
-
import {view} from "
|
|
4
|
-
import {cssReset} from "
|
|
5
|
-
|
|
6
|
-
const style = css`
|
|
7
|
-
:host {
|
|
8
|
-
font-family: monospace;
|
|
9
|
-
color: red;
|
|
10
|
-
}
|
|
11
|
-
`
|
|
3
|
+
import {view} from "../../../views/view.js"
|
|
4
|
+
import {cssReset} from "../../../views/css-reset.js"
|
|
12
5
|
|
|
13
6
|
export const ErrorDisplay = view(use => (error: any) => {
|
|
14
|
-
use.name("
|
|
7
|
+
use.name("error")
|
|
15
8
|
use.styles(cssReset, style)
|
|
16
9
|
|
|
17
10
|
if (typeof error === "string")
|
|
@@ -24,3 +17,10 @@ export const ErrorDisplay = view(use => (error: any) => {
|
|
|
24
17
|
return `error`
|
|
25
18
|
})
|
|
26
19
|
|
|
20
|
+
const style = css`
|
|
21
|
+
:host {
|
|
22
|
+
font-family: monospace;
|
|
23
|
+
color: red;
|
|
24
|
+
}
|
|
25
|
+
`
|
|
26
|
+
|
package/s/features/op/op.ts
CHANGED
|
@@ -1,26 +1,14 @@
|
|
|
1
1
|
|
|
2
2
|
import {pub} from "@e280/stz"
|
|
3
|
-
import {signal} from "@e280/strata/signals"
|
|
3
|
+
import {Signal, signal} from "@e280/strata/signals"
|
|
4
4
|
|
|
5
|
-
import {
|
|
5
|
+
import {podium} from "./podium.js"
|
|
6
6
|
import {Pod, PodSelect} from "./types.js"
|
|
7
7
|
|
|
8
8
|
export class Op<V> {
|
|
9
|
-
static loading() {
|
|
10
|
-
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
static ready<V>(value: V) {
|
|
14
|
-
const op = new this<V>()
|
|
15
|
-
op.signal(["ready", value])
|
|
16
|
-
return op
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
static error(error: any) {
|
|
20
|
-
const op = new this()
|
|
21
|
-
op.signal(["error", error])
|
|
22
|
-
return op
|
|
23
|
-
}
|
|
9
|
+
static loading<V>() { return new this<V>() }
|
|
10
|
+
static ready<V>(value: V) { return new this<V>(["ready", value]) }
|
|
11
|
+
static error<V>(error: any) { return new this<V>(["error", error]) }
|
|
24
12
|
|
|
25
13
|
static promise<V>(promise: Promise<V>) {
|
|
26
14
|
const op = new this<V>()
|
|
@@ -32,10 +20,20 @@ export class Op<V> {
|
|
|
32
20
|
return this.promise(fn())
|
|
33
21
|
}
|
|
34
22
|
|
|
35
|
-
|
|
23
|
+
static all<V>(...ops: Op<V>[]) {
|
|
24
|
+
const pods = ops.map(op => op.pod)
|
|
25
|
+
const pod = podium.all(...pods)
|
|
26
|
+
return new this(pod)
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
readonly signal: Signal<Pod<V>>
|
|
36
30
|
#resolve = pub<[V]>()
|
|
37
31
|
#reject = pub<[any]>()
|
|
38
32
|
|
|
33
|
+
constructor(pod: Pod<V> = ["loading"]) {
|
|
34
|
+
this.signal = signal<Pod<V>>(pod)
|
|
35
|
+
}
|
|
36
|
+
|
|
39
37
|
get wait() {
|
|
40
38
|
return new Promise((resolve, reject) => {
|
|
41
39
|
this.#resolve.next().then(resolve)
|
|
@@ -77,12 +75,32 @@ export class Op<V> {
|
|
|
77
75
|
return this.signal()
|
|
78
76
|
}
|
|
79
77
|
|
|
78
|
+
set pod(p: Pod<V>) {
|
|
79
|
+
this.signal(p)
|
|
80
|
+
}
|
|
81
|
+
|
|
80
82
|
get status() {
|
|
81
83
|
return this.signal()[0]
|
|
82
84
|
}
|
|
83
85
|
|
|
84
86
|
get value() {
|
|
85
|
-
return
|
|
87
|
+
return podium.value(this.signal())
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
get error() {
|
|
91
|
+
return podium.error(this.signal())
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
get isLoading() {
|
|
95
|
+
return this.status === "loading"
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
get isReady() {
|
|
99
|
+
return this.status === "ready"
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
get isError() {
|
|
103
|
+
return this.status === "error"
|
|
86
104
|
}
|
|
87
105
|
|
|
88
106
|
require() {
|
|
@@ -92,7 +110,11 @@ export class Op<V> {
|
|
|
92
110
|
}
|
|
93
111
|
|
|
94
112
|
select<R>(select: PodSelect<V, R>) {
|
|
95
|
-
return
|
|
113
|
+
return podium.select(this.signal(), select)
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
morph<V2>(fn: (value: V) => V2) {
|
|
117
|
+
return new Op(podium.morph(this.pod, fn))
|
|
96
118
|
}
|
|
97
119
|
}
|
|
98
120
|
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
|
|
2
|
+
import {Pod, PodSelect} from "./types.js"
|
|
3
|
+
|
|
4
|
+
export const podium = {
|
|
5
|
+
status: (p: Pod<any>) => p[0],
|
|
6
|
+
|
|
7
|
+
value: <V>(p: Pod<V>) => {
|
|
8
|
+
return p[0] === "ready"
|
|
9
|
+
? p[1]
|
|
10
|
+
: undefined
|
|
11
|
+
},
|
|
12
|
+
|
|
13
|
+
error: <V>(p: Pod<V>) => {
|
|
14
|
+
return p[0] === "error"
|
|
15
|
+
? p[1]
|
|
16
|
+
: undefined
|
|
17
|
+
},
|
|
18
|
+
|
|
19
|
+
select: <V, R>(p: Pod<V>, select: PodSelect<V, R>) => {
|
|
20
|
+
switch (p[0]) {
|
|
21
|
+
case "loading": return select.loading()
|
|
22
|
+
case "error": return select.error(p[1])
|
|
23
|
+
case "ready": return select.ready(p[1])
|
|
24
|
+
default: throw new Error("unknown op status")
|
|
25
|
+
}
|
|
26
|
+
},
|
|
27
|
+
|
|
28
|
+
morph: <A, B>(p: Pod<A>, fn: (a: A) => B): Pod<B> => {
|
|
29
|
+
return podium.select<A, Pod<B>>(p, {
|
|
30
|
+
loading: () => ["loading"],
|
|
31
|
+
error: error => ["error", error],
|
|
32
|
+
ready: a => ["ready", fn(a)],
|
|
33
|
+
})
|
|
34
|
+
},
|
|
35
|
+
|
|
36
|
+
all: <V>(...ps: Pod<V>[]): Pod<V[]> => {
|
|
37
|
+
const values: V[] = []
|
|
38
|
+
const errors: any[] = []
|
|
39
|
+
let loading = 0
|
|
40
|
+
|
|
41
|
+
for (const p of ps) {
|
|
42
|
+
switch (p[0]) {
|
|
43
|
+
case "loading":
|
|
44
|
+
loading++
|
|
45
|
+
break
|
|
46
|
+
|
|
47
|
+
case "ready":
|
|
48
|
+
values.push(p[1])
|
|
49
|
+
break
|
|
50
|
+
|
|
51
|
+
case "error":
|
|
52
|
+
errors.push(p[1])
|
|
53
|
+
break
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
if (errors.length > 0)
|
|
58
|
+
return ["error", errors]
|
|
59
|
+
|
|
60
|
+
else if (loading === 0)
|
|
61
|
+
return ["ready", values]
|
|
62
|
+
|
|
63
|
+
else
|
|
64
|
+
return ["loading"]
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
|
|
@@ -4,11 +4,18 @@ import {CSSResultGroup, TemplateResult} from "lit"
|
|
|
4
4
|
|
|
5
5
|
import {Use} from "./use.js"
|
|
6
6
|
|
|
7
|
-
export type Content = TemplateResult | DirectiveResult | HTMLElement | string | null | undefined | void
|
|
7
|
+
export type Content = TemplateResult | DirectiveResult | HTMLElement | string | null | undefined | void | Content[]
|
|
8
8
|
export type AttrValue = string | boolean | number | undefined | null | void
|
|
9
9
|
|
|
10
10
|
export type ViewFn<Props extends any[]> = (use: Use) => (...props: Props) => Content
|
|
11
|
-
export type
|
|
11
|
+
export type BasicView<Props extends any[]> = (...props: Props) => DirectiveResult<any>
|
|
12
|
+
export type View<Props extends any[]> = BasicView<Props> & {
|
|
13
|
+
props: View<Props>
|
|
14
|
+
with: (w: Partial<ViewWith>) => View<Props>
|
|
15
|
+
children: (...children: Content[]) => View<Props>
|
|
16
|
+
attrs: (attrs: Record<string, AttrValue>) => View<Props>
|
|
17
|
+
attr: (name: string, value: AttrValue) => View<Props>
|
|
18
|
+
}
|
|
12
19
|
|
|
13
20
|
export type ViewSettings = ShadowRootInit & {
|
|
14
21
|
tag?: string
|
package/s/features/views/use.ts
CHANGED
|
@@ -37,6 +37,7 @@ export class Use {
|
|
|
37
37
|
constructor(
|
|
38
38
|
public element: HTMLElement,
|
|
39
39
|
public shadow: ShadowRoot,
|
|
40
|
+
public render: () => void,
|
|
40
41
|
) {}
|
|
41
42
|
|
|
42
43
|
get renderCount() {
|
|
@@ -47,29 +48,39 @@ export class Use {
|
|
|
47
48
|
return this.#rendered.promise
|
|
48
49
|
}
|
|
49
50
|
|
|
50
|
-
|
|
51
|
-
|
|
51
|
+
name(name: string) {
|
|
52
|
+
this.once(() => this.element.setAttribute("view", name))
|
|
52
53
|
}
|
|
53
54
|
|
|
54
55
|
styles(...styles: CSSResultGroup[]) {
|
|
55
56
|
this.once(() => applyStyles(this.shadow, styles))
|
|
56
57
|
}
|
|
57
58
|
|
|
58
|
-
|
|
59
|
-
this.
|
|
59
|
+
once<V>(fn: () => V) {
|
|
60
|
+
return this.#values.guarantee(this.#position++, fn) as V
|
|
60
61
|
}
|
|
61
62
|
|
|
62
|
-
|
|
63
|
-
return this.once(() =>
|
|
63
|
+
mount(fn: () => () => void) {
|
|
64
|
+
return this.once(() => this.#mounts.mount(fn))
|
|
64
65
|
}
|
|
65
66
|
|
|
66
|
-
|
|
67
|
-
|
|
67
|
+
life<V>(fn: () => [result: V, dispose: () => void]) {
|
|
68
|
+
let r: V | undefined
|
|
69
|
+
this.mount(() => {
|
|
70
|
+
const [result, dispose] = fn()
|
|
71
|
+
r = result
|
|
72
|
+
return dispose
|
|
73
|
+
})
|
|
74
|
+
return r as V
|
|
68
75
|
}
|
|
69
76
|
|
|
70
77
|
op = {
|
|
71
|
-
promise: <V>(p: Promise<V>) => this.once(() => Op.promise(p)),
|
|
72
78
|
fn: <V>(f: () => Promise<V>) => this.once(() => Op.fn(f)),
|
|
79
|
+
promise: <V>(p: Promise<V>) => this.once(() => Op.promise(p)),
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
signal<V>(value: V) {
|
|
83
|
+
return this.once(() => signal<V>(value))
|
|
73
84
|
}
|
|
74
85
|
}
|
|
75
86
|
|
package/s/features/views/view.ts
CHANGED
|
@@ -9,7 +9,7 @@ import {register} from "../dom/register.js"
|
|
|
9
9
|
import {applyAttrs} from "./utils/apply-attrs.js"
|
|
10
10
|
import {applyStyles} from "./utils/apply-styles.js"
|
|
11
11
|
import {Use, _wrap, _disconnect, _reconnect} from "./use.js"
|
|
12
|
-
import {AttrValue, Content, ViewFn, ViewSettings, ViewWith} from "./types.js"
|
|
12
|
+
import {AttrValue, Content, View, ViewFn, ViewSettings, ViewWith} from "./types.js"
|
|
13
13
|
|
|
14
14
|
export const view = setupView({mode: "open"})
|
|
15
15
|
export class SlyView extends HTMLElement {}
|
|
@@ -20,7 +20,7 @@ function setupView(settings: ViewSettings) {
|
|
|
20
20
|
class ViewDirective extends AsyncDirective {
|
|
21
21
|
#element = document.createElement(settings.tag ?? "sly-view")
|
|
22
22
|
#shadow = this.#element.attachShadow(settings)
|
|
23
|
-
#use = new Use(this.#element, this.#shadow)
|
|
23
|
+
#use = new Use(this.#element, this.#shadow, () => this.#render())
|
|
24
24
|
#fn = (() => {
|
|
25
25
|
const fn2 = fn(this.#use)
|
|
26
26
|
this.#element.setAttribute("view", settings.name ?? "")
|
|
@@ -29,9 +29,13 @@ function setupView(settings: ViewSettings) {
|
|
|
29
29
|
})()
|
|
30
30
|
|
|
31
31
|
#tracking = new MapG<any, () => void>
|
|
32
|
+
#params!: {with: ViewWith, props: Props}
|
|
32
33
|
|
|
33
|
-
#render
|
|
34
|
+
#render() {
|
|
35
|
+
if (!this.#params) return
|
|
34
36
|
if (!this.isConnected) return
|
|
37
|
+
const {with: w, props} = this.#params
|
|
38
|
+
|
|
35
39
|
this.#use[_wrap](() => {
|
|
36
40
|
// apply html attributes
|
|
37
41
|
applyAttrs(this.#element, w.attrs)
|
|
@@ -46,16 +50,19 @@ function setupView(settings: ViewSettings) {
|
|
|
46
50
|
for (const item of seen)
|
|
47
51
|
this.#tracking.guarantee(
|
|
48
52
|
item,
|
|
49
|
-
() => tracker.changed(item, async() => this.#
|
|
53
|
+
() => tracker.changed(item, async() => this.#renderDebounced()),
|
|
50
54
|
)
|
|
51
55
|
|
|
52
56
|
// inject content into light dom
|
|
53
57
|
render(w.children, this.#element)
|
|
54
58
|
})
|
|
55
|
-
}
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
#renderDebounced = debounce(0, () => this.#render())
|
|
56
62
|
|
|
57
63
|
render(w: ViewWith, props: Props) {
|
|
58
|
-
this.#
|
|
64
|
+
this.#params = {with: w, props}
|
|
65
|
+
this.#render()
|
|
59
66
|
return this.#element
|
|
60
67
|
}
|
|
61
68
|
|
|
@@ -71,12 +78,12 @@ function setupView(settings: ViewSettings) {
|
|
|
71
78
|
}
|
|
72
79
|
}
|
|
73
80
|
|
|
74
|
-
function setupDirective(w: ViewWith) {
|
|
81
|
+
function setupDirective(w: ViewWith): View<Props> {
|
|
75
82
|
const r = directive(ViewDirective)
|
|
76
83
|
const rend = (...props: Props): DirectiveResult<any> => r(w, props)
|
|
77
84
|
rend.props = rend
|
|
78
85
|
rend.with = (w2: Partial<ViewWith>) => setupDirective({...w, ...w2})
|
|
79
|
-
rend.children = (children: Content) => setupDirective({...w, children})
|
|
86
|
+
rend.children = (...children: Content[]) => setupDirective({...w, children})
|
|
80
87
|
rend.attrs = (attrs: Record<string, AttrValue>) => setupDirective({...w, attrs})
|
|
81
88
|
rend.attr = (name: string, value: AttrValue) => setupDirective({
|
|
82
89
|
...w,
|
package/s/index.html.ts
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
import {ssg, html} from "@e280/scute"
|
|
3
3
|
|
|
4
4
|
const title = "sly"
|
|
5
|
-
const description = "shadow views
|
|
5
|
+
const description = "mischievous shadow views"
|
|
6
6
|
const domain = "sly.e280.org"
|
|
7
7
|
const favicon = "/assets/favicon.png"
|
|
8
8
|
|
|
@@ -26,10 +26,10 @@ export default ssg.page(import.meta.url, async orb => ({
|
|
|
26
26
|
|
|
27
27
|
body: html`
|
|
28
28
|
<img class=icon alt="" src="/assets/favicon.png"/>
|
|
29
|
-
<h1>sly</h1>
|
|
29
|
+
<h1>sly testing page</h1>
|
|
30
|
+
<p><a href="https://github.com/e280/sly">github.com/e280/sly</a></p>
|
|
30
31
|
<p class=lil>v${orb.packageVersion()}</p>
|
|
31
32
|
<div class=demo></div>
|
|
32
|
-
<p><a href="https://github.com/e280/sly">github.com/e280/sly</a></p>
|
|
33
33
|
`,
|
|
34
34
|
}))
|
|
35
35
|
|
package/s/index.ts
CHANGED
|
@@ -4,11 +4,12 @@ export * from "./features/dom/dollar.js"
|
|
|
4
4
|
export * from "./features/dom/register.js"
|
|
5
5
|
export * from "./features/dom/types.js"
|
|
6
6
|
|
|
7
|
-
export * from "./features/
|
|
8
|
-
export * from "./features/
|
|
7
|
+
export * from "./features/op/loaders/make-loader.js"
|
|
8
|
+
export * from "./features/op/loaders/parts/ascii-anim.js"
|
|
9
|
+
export * from "./features/op/loaders/parts/error-display.js"
|
|
9
10
|
|
|
10
11
|
export * from "./features/op/op.js"
|
|
11
|
-
export * from "./features/op/
|
|
12
|
+
export * from "./features/op/podium.js"
|
|
12
13
|
export * from "./features/op/types.js"
|
|
13
14
|
|
|
14
15
|
export * from "./features/views/css-reset.js"
|