1import { Match as M, Schema as S } from "effect";
2import type { Runtime, Update } from "foldkit";
3import type { Document, HtmlBuilder } from "foldkit/html";
4import { defineMessageUnion } from "foldkit/message";
5
6// Proves the module served/bundled is this source (the dev server serves it
7// verbatim; the built bundle inlines it).
8export const marker = "FOLDKIT_AWS_MODULE_MARKER";
9
10// MODEL
11
12export const Model = S.Struct({ count: S.Number });
13export type Model = typeof Model.Type;
14
15// MESSAGE
16
17export const Message = defineMessageUnion({
18 ClickedIncrement: {},
19});
20export const { ClickedIncrement } = Message;
21export type Message = typeof Message.Type;
22
23// UPDATE
24
25export const update = (
26 model: Model,
27 message: Message,
28): Update.Return<Model, Message> =>
29 M.value(message).pipe(
30 M.withReturnType<Update.Return<Model, Message>>(),
31 M.tagsExhaustive({
32 ClickedIncrement: () => ({ model: { count: model.count + 1 } }),
33 }),
34 );
35
36// INIT
37
38export const init: Runtime.ApplicationInit<Model, Message> = () => ({
39 model: { count: 0 },
40});
41
42// VIEW
43
44export const view = (model: Model, h: HtmlBuilder<Message>): Document => ({
45 title: `Counter: ${model.count}`,
46 body: h.div(
47 [h.Id("app")],
48 [
49 h.p([h.Id("count")], [model.count.toString()]),
50 h.button([h.Id("increment"), h.OnClick(ClickedIncrement())], ["+"]),
51 ],
52 ),
53});