Skip to content

Commit 98be292

Browse files
committed
refactor(core): replace sync event cast with Schema guard
Use Schema.is to narrow converted sync events instead of asserting the payload type manually. Move the Zod-to-Effect bridge into effect-zod so remaining Zod-backed sync payloads have one explicit interop helper.
1 parent 11ffed6 commit 98be292

3 files changed

Lines changed: 15 additions & 11 deletions

File tree

packages/opencode/src/server/projectors.ts

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,12 +5,14 @@ import { Session } from "@/session"
55
import { SessionTable } from "@/session/session.sql"
66
import { Database, eq } from "@/storage"
77

8+
const isSessionUpdated = Schema.is(Session.Event.Updated.schema)
9+
810
export function initProjectors() {
911
SyncEvent.init({
1012
projectors: sessionProjectors,
1113
convertEvent: (type, data) => {
12-
if (type === "session.updated") {
13-
const id = (data as Schema.Schema.Type<typeof Session.Event.Updated.schema>).sessionID
14+
if (type === Session.Event.Updated.type && isSessionUpdated(data)) {
15+
const id = data.sessionID
1416
const row = Database.use((db) => db.select().from(SessionTable).where(eq(SessionTable.id, id)).get())
1517

1618
if (!row) return data

packages/opencode/src/session/session.ts

Lines changed: 3 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ import type { Provider } from "@/provider"
2828
import { Permission } from "@/permission"
2929
import { Global } from "@/global"
3030
import { Effect, Layer, Option, Context, Schema } from "effect"
31-
import { ZodOverride } from "@/util/effect-zod"
31+
import { fromZod } from "@/util/effect-zod"
3232

3333
const log = Log.create({ service: "session" })
3434

@@ -201,14 +201,8 @@ export const SetRevertInput = z.object({
201201
})
202202
export const MessagesInput = z.object({ sessionID: SessionID.zod, limit: z.number().optional() })
203203

204-
function schemaFromZod<T extends z.ZodTypeAny>(value: T) {
205-
return Schema.declare((input): input is z.output<T> => value.safeParse(input).success).annotate({
206-
[ZodOverride]: value,
207-
})
208-
}
209-
210-
const SessionInfoSchema = schemaFromZod(Info)
211-
const SessionUpdateInfoSchema = schemaFromZod(
204+
const SessionInfoSchema = fromZod(Info)
205+
const SessionUpdateInfoSchema = fromZod(
212206
updateSchema(Info).extend({
213207
share: updateSchema(Info.shape.share.unwrap()).optional(),
214208
time: updateSchema(Info.shape.time).optional(),

packages/opencode/src/util/effect-zod.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,14 @@ export function zod<S extends Schema.Top>(schema: S): z.ZodType<Schema.Schema.Ty
2222
return walk(schema.ast) as z.ZodType<Schema.Schema.Type<S>>
2323
}
2424

25+
// Bridge a Zod-first schema into Effect Schema while preserving the original
26+
// Zod for downstream JSON Schema/OpenAPI generation.
27+
export function fromZod<T extends z.ZodTypeAny>(value: T) {
28+
return Schema.declare((input): input is z.output<T> => value.safeParse(input).success).annotate({
29+
[ZodOverride]: value,
30+
})
31+
}
32+
2533
function walk(ast: SchemaAST.AST): z.ZodTypeAny {
2634
const cached = walkCache.get(ast)
2735
if (cached) return cached

0 commit comments

Comments
 (0)