Val Town is a social website to write and deploy JavaScript.
Build APIs and schedule functions from your browser.
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 }));
}
May 4, 2024