This repository was archived by the owner on Oct 22, 2025. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 44
Expand file tree
/
Copy pathactor-sqlite.ts
More file actions
87 lines (75 loc) · 1.79 KB
/
actor-sqlite.ts
File metadata and controls
87 lines (75 loc) · 1.79 KB
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
import { actor } from "@rivetkit/worker";
import { drizzle } from "@rivetkit/drizzle";
import { documents, cursors } from "./schema";
export type Cursor = { x: number, y: number, userId: string };
const document = actor({
sql: drizzle(),
actions: {
getText: async (c) => {
const doc = await c.db
.select()
.from(documents)
.get();
return doc?.text || "";
},
// Update the document (real use case has better conflict resolution)
setText: async (c, text: string) => {
// Save document state
await c.db
.insert(documents)
.values({
text
})
.onConflictDoUpdate({
target: documents.id,
set: {
text
}
});
// Broadcast update
c.broadcast("textUpdated", {
text,
userId: c.conn.id
});
},
getCursors: async (c) => {
const result = await c.db
.select()
.from(cursors);
// Convert array to record object keyed by userId
return result.reduce((acc, cursor) => {
acc[cursor.userId] = {
x: cursor.x,
y: cursor.y,
userId: cursor.userId
};
return acc;
}, {} as Record<string, Cursor>);
},
updateCursor: async (c, x: number, y: number) => {
// Update user location
const userId = c.conn.id;
await c.db
.insert(cursors)
.values({
userId,
x,
y
})
.onConflictDoUpdate({
target: cursors.userId,
set: {
x,
y
}
});
// Broadcast location
c.broadcast("cursorUpdated", {
userId,
x,
y
});
},
}
});
export default document;