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
/** @jsxImportSource https://esm.sh/react */
import React, { useState, useEffect } from "https://esm.sh/react";
import { createRoot } from "https://esm.sh/react-dom/client";
import { Tldraw } from "https://esm.sh/@tldraw/tldraw@2.3.0";
function App() {
const [savedDrawings, setSavedDrawings] = useState([]);
useEffect(() => {
fetchSavedDrawings();
}, []);
const fetchSavedDrawings = async () => {
const response = await fetch('/list-drawings');
const drawings = await response.json();
setSavedDrawings(drawings);
};
const handleSave = async () => {
const response = await fetch('/save-drawing', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ drawing: 'example_drawing_data' }),
});
if (response.ok) {
fetchSavedDrawings();
}
};
return (
<div>
<Tldraw />
<button onClick={handleSave}>Save Drawing</button>
<h2>Saved Drawings:</h2>
<ul>
{savedDrawings.map((drawing, index) => (
<li key={index}>{drawing}</li>
))}
</ul>
</div>
);
}
function client() {
createRoot(document.getElementById("root")).render(<App />);
}
if (typeof document !== "undefined") { client(); }
export const server = (req) =>
handleRequest(req);
async function handleRequest(req: Request): Promise<Response> {
const { blob } = await import("https://esm.town/v/std/blob");
const url = new URL(req.url);
if (url.pathname === '/save-drawing') {
if (req.method === 'POST') {
const { drawing } = await req.json();
const key = `drawing_${Date.now()}`;
await blob.set(key, drawing);
return new Response('Drawing saved successfully', { status: 200 });
}
} else if (url.pathname === '/list-drawings') {
const drawings = await blob.list('drawing_');
const drawingKeys = drawings.map(d => d.key);
return new Response(JSON.stringify(drawingKeys), {
headers: { 'Content-Type': 'application/json' }
});
}
return new Response(
`<html>
<head>
<title>TLDraw with Saving</title>
<meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover" />
<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Inter:wght@500;700&display=swap"/>
<link rel="stylesheet" href="https://esm.sh/@tldraw/tldraw@2.3.0/tldraw.css"/>
<style>
body { font-family: "Inter"; }
#root { height: 100vh; }
</style>
</head>
<body>
<div id="root"></div>
<script type="module" src="${import.meta.url}"></script>
</body>
</html>`,
{ headers: { "Content-Type": "text/html" } }
);
}