Files
zopu-code/packages/backend/convex/daemonRuntime.ts

108 lines
2.6 KiB
TypeScript

import { v } from "convex/values";
import { mutation, query } from "./_generated/server";
export const connect = mutation({
args: {
daemonId: v.string(),
sessionId: v.string(),
hostname: v.string(),
platform: v.string(),
architecture: v.string(),
version: v.string(),
},
handler: async (ctx, args) => {
const existing = await ctx.db
.query("daemonPresence")
.withIndex("by_sessionId", (q) => q.eq("sessionId", args.sessionId))
.unique();
const timestamp = Date.now();
if (existing) {
await ctx.db.patch("daemonPresence", existing._id, {
status: "online",
lastHeartbeatAt: timestamp,
});
return existing._id;
}
return await ctx.db.insert("daemonPresence", {
...args,
status: "online",
startedAt: timestamp,
lastHeartbeatAt: timestamp,
});
},
});
export const heartbeat = mutation({
args: {
daemonId: v.string(),
sessionId: v.string(),
},
handler: async (ctx, args) => {
const presence = await ctx.db
.query("daemonPresence")
.withIndex("by_sessionId", (q) => q.eq("sessionId", args.sessionId))
.unique();
if (!presence || presence.daemonId !== args.daemonId) {
return false;
}
await ctx.db.patch("daemonPresence", presence._id, {
status: "online",
lastHeartbeatAt: Date.now(),
});
return true;
},
});
export const disconnect = mutation({
args: {
daemonId: v.string(),
sessionId: v.string(),
},
handler: async (ctx, args) => {
const presence = await ctx.db
.query("daemonPresence")
.withIndex("by_sessionId", (q) => q.eq("sessionId", args.sessionId))
.unique();
if (!presence || presence.daemonId !== args.daemonId) {
return false;
}
await ctx.db.patch("daemonPresence", presence._id, {
status: "offline",
lastHeartbeatAt: Date.now(),
});
return true;
},
});
export const recordEvent = mutation({
args: {
daemonId: v.string(),
commandId: v.optional(v.id("daemonCommands")),
kind: v.string(),
data: v.any(),
},
handler: async (ctx, args) => {
return await ctx.db.insert("daemonCommandEvents", {
...args,
createdAt: Date.now(),
});
},
});
export const listEvents = query({
args: {
daemonId: v.string(),
limit: v.optional(v.number()),
},
handler: async (ctx, args) => {
return await ctx.db
.query("daemonCommandEvents")
.withIndex("by_daemonId_and_createdAt", (q) =>
q.eq("daemonId", args.daemonId)
)
.order("desc")
.take(Math.min(args.limit ?? 100, 500));
},
});