refactor(todo): effectify session todo (#20595)
parent
f549fde874
commit
5e1b513527
|
|
@ -1,6 +1,8 @@
|
||||||
import { BusEvent } from "@/bus/bus-event"
|
import { BusEvent } from "@/bus/bus-event"
|
||||||
import { Bus } from "@/bus"
|
import { Bus } from "@/bus"
|
||||||
|
import { makeRuntime } from "@/effect/run-service"
|
||||||
import { SessionID } from "./schema"
|
import { SessionID } from "./schema"
|
||||||
|
import { Effect, Layer, ServiceMap } from "effect"
|
||||||
import z from "zod"
|
import z from "zod"
|
||||||
import { Database, eq, asc } from "../storage/db"
|
import { Database, eq, asc } from "../storage/db"
|
||||||
import { TodoTable } from "./session.sql"
|
import { TodoTable } from "./session.sql"
|
||||||
|
|
@ -25,7 +27,20 @@ export namespace Todo {
|
||||||
),
|
),
|
||||||
}
|
}
|
||||||
|
|
||||||
export function update(input: { sessionID: SessionID; todos: Info[] }) {
|
export interface Interface {
|
||||||
|
readonly update: (input: { sessionID: SessionID; todos: Info[] }) => Effect.Effect<void>
|
||||||
|
readonly get: (sessionID: SessionID) => Effect.Effect<Info[]>
|
||||||
|
}
|
||||||
|
|
||||||
|
export class Service extends ServiceMap.Service<Service, Interface>()("@opencode/SessionTodo") {}
|
||||||
|
|
||||||
|
export const layer = Layer.effect(
|
||||||
|
Service,
|
||||||
|
Effect.gen(function* () {
|
||||||
|
const bus = yield* Bus.Service
|
||||||
|
|
||||||
|
const update = Effect.fn("Todo.update")(function* (input: { sessionID: SessionID; todos: Info[] }) {
|
||||||
|
yield* Effect.sync(() =>
|
||||||
Database.transaction((db) => {
|
Database.transaction((db) => {
|
||||||
db.delete(TodoTable).where(eq(TodoTable.session_id, input.sessionID)).run()
|
db.delete(TodoTable).where(eq(TodoTable.session_id, input.sessionID)).run()
|
||||||
if (input.todos.length === 0) return
|
if (input.todos.length === 0) return
|
||||||
|
|
@ -40,18 +55,41 @@ export namespace Todo {
|
||||||
})),
|
})),
|
||||||
)
|
)
|
||||||
.run()
|
.run()
|
||||||
|
}),
|
||||||
|
)
|
||||||
|
yield* bus.publish(Event.Updated, input)
|
||||||
})
|
})
|
||||||
Bus.publish(Event.Updated, input)
|
|
||||||
}
|
|
||||||
|
|
||||||
export function get(sessionID: SessionID) {
|
const get = Effect.fn("Todo.get")(function* (sessionID: SessionID) {
|
||||||
const rows = Database.use((db) =>
|
const rows = yield* Effect.sync(() =>
|
||||||
db.select().from(TodoTable).where(eq(TodoTable.session_id, sessionID)).orderBy(asc(TodoTable.position)).all(),
|
Database.use((db) =>
|
||||||
|
db
|
||||||
|
.select()
|
||||||
|
.from(TodoTable)
|
||||||
|
.where(eq(TodoTable.session_id, sessionID))
|
||||||
|
.orderBy(asc(TodoTable.position))
|
||||||
|
.all(),
|
||||||
|
),
|
||||||
)
|
)
|
||||||
return rows.map((row) => ({
|
return rows.map((row) => ({
|
||||||
content: row.content,
|
content: row.content,
|
||||||
status: row.status,
|
status: row.status,
|
||||||
priority: row.priority,
|
priority: row.priority,
|
||||||
}))
|
}))
|
||||||
|
})
|
||||||
|
|
||||||
|
return Service.of({ update, get })
|
||||||
|
}),
|
||||||
|
)
|
||||||
|
|
||||||
|
const defaultLayer = layer.pipe(Layer.provide(Bus.layer))
|
||||||
|
const { runPromise } = makeRuntime(Service, defaultLayer)
|
||||||
|
|
||||||
|
export async function update(input: { sessionID: SessionID; todos: Info[] }) {
|
||||||
|
return runPromise((svc) => svc.update(input))
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function get(sessionID: SessionID) {
|
||||||
|
return runPromise((svc) => svc.get(sessionID))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -16,7 +16,7 @@ export const TodoWriteTool = Tool.define("todowrite", {
|
||||||
metadata: {},
|
metadata: {},
|
||||||
})
|
})
|
||||||
|
|
||||||
Todo.update({
|
await Todo.update({
|
||||||
sessionID: ctx.sessionID,
|
sessionID: ctx.sessionID,
|
||||||
todos: params.todos,
|
todos: params.todos,
|
||||||
})
|
})
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue