|
1 | 1 | import { Identifier } from "@/id/id" |
| 2 | +import { Database } from "@/node" |
| 3 | +import type { SessionID } from "@/session/schema" |
| 4 | +import { SessionEntryTable } from "@/session/session.sql" |
2 | 5 | import { withStatics } from "@/util/schema" |
3 | | -import { DateTime, Effect, Schema } from "effect" |
| 6 | +import { Context, DateTime, Effect, Layer, Schema } from "effect" |
| 7 | +import { eq } from "../storage/db" |
4 | 8 |
|
5 | 9 | export namespace SessionEntry { |
6 | 10 | export const ID = Schema.String.pipe(Schema.brand("Session.Entry.ID")).pipe( |
@@ -181,6 +185,43 @@ export namespace SessionEntry { |
181 | 185 | overflow: Schema.Boolean.pipe(Schema.optional), |
182 | 186 | }) {} |
183 | 187 |
|
184 | | - export const Entry = Schema.Union([User, Synthetic, Request, Tool, Text, Reasoning, Complete, Retry, Compaction]) |
| 188 | + export const Entry = Schema.Union([User, Synthetic, Request, Tool, Text, Reasoning, Complete, Retry, Compaction], { |
| 189 | + mode: "oneOf", |
| 190 | + }) |
185 | 191 | export type Entry = Schema.Schema.Type<typeof Entry> |
| 192 | + |
| 193 | + export type Type = Entry["type"] |
| 194 | + |
| 195 | + export interface Interface { |
| 196 | + readonly decode: (row: typeof SessionEntryTable.$inferSelect) => Entry |
| 197 | + readonly fromSession: (sessionID: SessionID) => Effect.Effect<Entry[], never> |
| 198 | + } |
| 199 | + |
| 200 | + export class Service extends Context.Service<Service, Interface>()("@opencode/SessionEntry") {} |
| 201 | + |
| 202 | + export const layer: Layer.Layer<Service, never, never> = Layer.effect( |
| 203 | + Service, |
| 204 | + Effect.gen(function* () { |
| 205 | + const decodeEntry = Schema.decodeUnknownSync(Entry) |
| 206 | + |
| 207 | + const decode: (typeof Service.Service)["decode"] = (row) => decodeEntry({ ...row, id: row.id, type: row.type }) |
| 208 | + |
| 209 | + const fromSession = Effect.fn("SessionEntry.fromSession")(function* (sessionID: SessionID) { |
| 210 | + return Database.use((db) => |
| 211 | + db |
| 212 | + .select() |
| 213 | + .from(SessionEntryTable) |
| 214 | + .where(eq(SessionEntryTable.session_id, sessionID)) |
| 215 | + .orderBy(SessionEntryTable.id) |
| 216 | + .all() |
| 217 | + .map((row) => decode(row)), |
| 218 | + ) |
| 219 | + }) |
| 220 | + |
| 221 | + return Service.of({ |
| 222 | + decode, |
| 223 | + fromSession, |
| 224 | + }) |
| 225 | + }), |
| 226 | + ) |
186 | 227 | } |
0 commit comments