Readme

simple App component made with VanJS

This script is not for execution but for import for SSR + hydration.

See https://www.val.town/v/reosablo/sampleVanSSR

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
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
/// <reference lib="dom.iterable" />
/// <reference lib="dom.asynciterable" />
import type { VanObj } from "npm:mini-van-plate@0.5.6/shared";
const fromClient = typeof document !== "undefined";
/** root DOM id of App component for hydration */
const appId = "3753aa97-a7cf-41d0-bcf4-0ed59d25cd26";
export default function App(props: { van: VanObj }) {
const { van } = props;
const {
button,
div,
form,
input,
label,
li,
progress,
ul,
} = van.tags;
const errorMessage = van.state("");
const generating = van.state(false);
const requestedCount = van.state(1);
const generatedCount = van.state(0);
// disable the button if we're not in the browser
const disabled = van.derive(() => !fromClient || generating.val);
const uuidsDom = ul();
const handleSubmit = async (event: SubmitEvent) => {
event.preventDefault();
const formData = new FormData(event.target as HTMLFormElement);
errorMessage.val = "";
generating.val = true;
requestedCount.val = +formData.get("count");
generatedCount.val = 0;
uuidsDom.replaceChildren();
try {
const requestUrl = `https://reosablo-uuidGeneratorStream.web.val.run/?count=${requestedCount.val}`;
const [response, { TextLineStream }] = await Promise.all([
fetch(requestUrl),
import("https://deno.land/std@0.224.0/streams/text_line_stream.ts"),
]);
if (!response.ok || response.body === null) {
throw new Error(response.statusText);
}
const body = response.body
.pipeThrough(new TextDecoderStream())
.pipeThrough(new TextLineStream());
for await (const uuid of body) {
van.add(uuidsDom, li(uuid));
}
} catch (error) {
errorMessage.val = error.message;
} finally {
generating.val = false;
}
};
return div(
{ "data-app": appId },
form(
{ onsubmit: fromClient && handleSubmit },
label(
"number of UUIDs to generate",
input({
name: "count",
type: "number",
min: 1,
max: 100,
step: 1,
value: 10,
}),
),
button({ disabled }, "Generate"),
),
progress({
max: requestedCount,
value: generatedCount,
hidden: () => !generating.val,
}),
div({ style: "color: red" }, errorMessage),
uuidsDom,
);
}
// hydrate App component if we're in the browser
// usually, this is done in `client.ts` script
if (fromClient) {
const { default: van } = await import("https://esm.sh/v135/vanjs-core@1.5.0");
for (const appDom of document.querySelectorAll(`[data-app="${appId}"]`)) {
van.hydrate(appDom, () => App({ van }));
}
Val Town is a social website to write and deploy JavaScript.
Build APIs and schedule functions from your browser.
Comments
Nobody has commented on this val yet: be the first!
May 4, 2024