Skip to content
This repository has been archived by the owner on Jan 5, 2025. It is now read-only.

Commit

Permalink
do a release
Browse files Browse the repository at this point in the history
  • Loading branch information
threepointone committed Dec 14, 2024
1 parent 50e7e86 commit d606dc9
Show file tree
Hide file tree
Showing 7 changed files with 457 additions and 56 deletions.
5 changes: 5 additions & 0 deletions .changeset/angry-rivers-float.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"durable-scheduler": patch
---

do a release
167 changes: 119 additions & 48 deletions example/src/client/app.tsx
Original file line number Diff line number Diff line change
@@ -1,27 +1,72 @@
import type { CoreMessage } from "ai";
import cronstrue from "cronstrue";
import { usePartySocket } from "partysocket/react";
import { useEffect, useState } from "react";

import { type Task as ToDo } from "../../../src";

function fetchTodos(callback: (todos: ToDo[]) => void) {
return fetch("/parties/to-dos/username/api/get-todos")
.then((res) => res.json())
.then((todos) => {
console.log("todos", todos);
callback(todos as ToDo[]);
});
async function fetchTodos(callback: (todos: ToDo[], messages: TaskMessages[]) => void) {
const todosRes = await fetch("/parties/to-dos/username/api/get-todos");
const todos = await todosRes.json();
const messagesRes = await fetch("/parties/to-dos/username/api/get-messages");
const messages = await messagesRes.json();
console.log("todos", todos);
console.log("messages", messages);
callback(todos as ToDo[], messages as TaskMessages[]);
}

// const ROOM_ID = "username"; // TODO: this will read a username from auth later

type TaskMessages = {
id: string;
todo_id: string;
messages: CoreMessage[];
};

export default function App() {
const [todos, setTodos] = useState<ToDo[]>([]);
const [messages, setMessages] = useState<TaskMessages[]>([]);
const [expandedMessageId, setExpandedMessageId] = useState<string | null>(null);
const [inputText, setInputText] = useState("");

usePartySocket({
party: "to-dos",
room: "username",
onMessage: (e) => {
console.log("message", e.data);
if (e.data === "refresh") {
fetchTodos((todos, messages) => {
setTodos(todos);
setMessages(messages);
}).catch((error) => {
console.error("Failed to fetch todos:", error);
});
}
},
});

function addOrReplaceTodo(todo: ToDo) {
setTodos((prev) => [...prev.filter((t) => t.id !== todo.id), todo]);
}

const handleDoToDo = async (todoId: string) => {
const todo = todos.find((t) => t.id === todoId);
if (!todo) return;
const res = await fetch("/parties/to-dos/username/api/do-todo", {
method: "POST",
body: JSON.stringify({ id: todoId, messages: [] }),
});
const result = await res.json();
console.log("result", result);

fetchTodos((todos, messages) => {
setTodos(todos);
setMessages(messages);
}).catch((error) => {
console.error("Failed to fetch todos:", error);
});
};

const handleAddToDo = async (e: React.FormEvent) => {
e.preventDefault();
if (!inputText.trim()) return;
Expand All @@ -47,11 +92,12 @@ export default function App() {
console.log("newToDoResponse", newToDoResponse);
addOrReplaceTodo(newToDoResponse as ToDo);

fetchTodos((todos) => {
fetchTodos((todos, messages) => {
for (const todo of todos) {
console.log("todo", todo);
addOrReplaceTodo(todo);
}
setMessages(messages);
}).catch((error) => {
console.error("Failed to fetch todos:", error);
});
Expand Down Expand Up @@ -85,7 +131,10 @@ export default function App() {
};

useEffect(() => {
fetchTodos((todos) => setTodos(todos)).catch((error) => {
fetchTodos((todos, messages) => {
setTodos(todos);
setMessages(messages);
}).catch((error) => {
console.error("Failed to fetch todos:", error);
});
}, []);
Expand Down Expand Up @@ -114,50 +163,72 @@ export default function App() {
</form>

<div className="space-y-4">
{todos.map((todo) => (
<div key={todo.id} className="bg-white rounded-lg shadow p-4 flex items-center gap-4">
<input
type="checkbox"
// checked={todo.completed}
onChange={() => void handleToggleToDo(todo.id)}
className="h-5 w-5 rounded border-gray-300 text-blue-500 focus:ring-blue-500"
/>
<div className="flex-1">
<p className={`text-gray-800 ${"a" /* todo.completed ? "line-through" : ""} */}`}>
{todo.description}
</p>
{todo.type !== "no-schedule" && (
<p className="text-sm text-gray-500">
Due: {new Date(todo.time).toLocaleString()}
</p>
)}
{todo.type === "cron" && (
<p className="text-sm text-gray-500 italic">
(Repeats: {cronstrue.toString(todo.cron)})
{todos.map((todo) => {
const todoMessages = messages.filter((m) => m.todo_id === todo.id);
return (
<div
key={todo.id}
className="bg-white rounded-lg shadow p-4 flex items-center gap-4"
onClick={() => setExpandedMessageId(todo.id)}
>
<input
type="checkbox"
checked={todoMessages.length > 0}
onChange={() => void handleToggleToDo(todo.id)}
className="h-5 w-5 rounded border-gray-300 text-blue-500 focus:ring-blue-500"
/>
<div className="flex-1">
<p className={`text-gray-800 ${"a" /* todo.completed ? "line-through" : ""} */}`}>
{todo.description}
</p>
{todo.type !== "no-schedule" && (
<p className="text-sm text-gray-500">
Due: {new Date(todo.time).toLocaleString()}
</p>
)}
{todo.type === "cron" && (
<p className="text-sm text-gray-500 italic">
(Repeats: {cronstrue.toString(todo.cron)})
</p>
)}
</div>
<button
onClick={() => void handleDoToDo(todo.id)}
className="p-2 text-blue-500 hover:text-blue-600 focus:outline-none"
>
Do
</button>
<button
onClick={() => void handleDeleteToDo(todo.id)}
className="p-2 text-red-500 hover:text-red-600 focus:outline-none"
>
<svg
xmlns="http://www.w3.org/2000/svg"
className="h-5 w-5"
viewBox="0 0 20 20"
fill="currentColor"
>
<path
fillRule="evenodd"
d="M9 2a1 1 0 00-.894.553L7.382 4H4a1 1 0 000 2v10a2 2 0 002 2h8a2 2 0 002-2V6a1 1 0 100-2h-3.382l-.724-1.447A1 1 0 0011 2H9zM7 8a1 1 0 012 0v6a1 1 0 11-2 0V8zm5-1a1 1 0 00-1 1v6a1 1 0 102 0V8a1 1 0 00-1-1z"
clipRule="evenodd"
/>
</svg>
</button>
{expandedMessageId === todo.id && (
<div className="clear-both">
{todoMessages.map((m) => (
<pre key={m.id}>{JSON.stringify(m.messages.at(-1), null, 2)}</pre>
))}
</div>
)}
</div>
<button
onClick={() => void handleDeleteToDo(todo.id)}
className="p-2 text-red-500 hover:text-red-600 focus:outline-none"
>
<svg
xmlns="http://www.w3.org/2000/svg"
className="h-5 w-5"
viewBox="0 0 20 20"
fill="currentColor"
>
<path
fillRule="evenodd"
d="M9 2a1 1 0 00-.894.553L7.382 4H4a1 1 0 000 2v10a2 2 0 002 2h8a2 2 0 002-2V6a1 1 0 100-2h-3.382l-.724-1.447A1 1 0 0011 2H9zM7 8a1 1 0 012 0v6a1 1 0 11-2 0V8zm5-1a1 1 0 00-1 1v6a1 1 0 102 0V8a1 1 0 00-1-1z"
clipRule="evenodd"
/>
</svg>
</button>
</div>
))}
);
})}
</div>
</div>
</div>
);
}

// <p>{JSON.stringify(todoMessages.map((m) => m.messages))}</p>
Loading

0 comments on commit d606dc9

Please sign in to comment.