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// MODEL
7
8export const Model = S.Struct({ count: S.Number });
9export type Model = typeof Model.Type;
10
11// MESSAGE
12
13export const Message = defineMessageUnion({
14 ClickedIncrement: {},
15});
16export const { ClickedIncrement } = Message;
17export type Message = typeof Message.Type;
18
19// UPDATE
20
21export const update = (
22 model: Model,
23 message: Message,
24): Update.Return<Model, Message> =>
25 M.value(message).pipe(
26 M.withReturnType<Update.Return<Model, Message>>(),
27 M.tagsExhaustive({
28 ClickedIncrement: () => ({ model: { count: model.count + 1 } }),
29 }),
30 );
31
32// INIT
33
34export const init: Runtime.ApplicationInit<Model, Message> = () => ({
35 model: { count: 0 },
36});
37
38// VIEW
39
40export const view = (model: Model, h: HtmlBuilder<Message>): Document => ({
41 title: `Counter: ${model.count}`,
42 body: h.div(
43 [h.Id("app")],
44 [
45 h.p([h.Id("count")], [model.count.toString()]),
46 h.button([h.Id("increment"), h.OnClick(ClickedIncrement())], ["+"]),
47 ],
48 ),
49});