{
5 | const body: Body = await context.request.json();
6 | sendMessage(body.username, body.body);
7 | return new Response(null);
8 | }
9 |
10 | interface Body {
11 | username: string;
12 | body: string;
13 | }
14 |
--------------------------------------------------------------------------------
/src/pages/api/messages.ts:
--------------------------------------------------------------------------------
1 | import { addMessageListener } from "../../lib/message";
2 | import { encodeBase64 } from "oslo/encoding";
3 |
4 | export async function GET() {
5 | const textEncoder = new TextEncoder();
6 | let unsubscribe: () => void;
7 | const stream = new ReadableStream({
8 | start(controller) {
9 | controller.enqueue(textEncoder.encode("\n"));
10 | unsubscribe = addMessageListener((message) => {
11 | let body = JSON.stringify({
12 | username: message.username,
13 | body: message.body,
14 | timestamp: Math.floor(message.date.getTime() / 1000),
15 | });
16 | body = encodeBase64(new TextEncoder().encode(body));
17 | controller.enqueue(textEncoder.encode("event: message\n"));
18 | controller.enqueue(textEncoder.encode("data: " + body + "\n\n"));
19 | });
20 | },
21 | cancel() {
22 | console.log("cancelled");
23 | unsubscribe();
24 | },
25 | });
26 | return new Response(stream, {
27 | headers: {
28 | "X-Content-Type-Options": "nosniff",
29 | "Content-Type": "text/event-stream; charset=utf-8",
30 | "Transfer-Encoding": "chunked",
31 | },
32 | });
33 | }
34 |
--------------------------------------------------------------------------------
/src/pages/index.astro:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | Realtime chat
8 |
9 |
10 | Realtime chat with Fetch API
11 |
12 |
23 |
24 |
25 |
26 |
27 |
28 |
121 |
--------------------------------------------------------------------------------
/tailwind.config.mjs:
--------------------------------------------------------------------------------
1 | /** @type {import('tailwindcss').Config} */
2 | export default {
3 | content: ['./src/**/*.{astro,html,js,jsx,md,mdx,svelte,ts,tsx,vue}'],
4 | theme: {
5 | extend: {},
6 | },
7 | plugins: [],
8 | }
9 |
--------------------------------------------------------------------------------
/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "astro/tsconfigs/strict"
3 | }
--------------------------------------------------------------------------------