Skip to content

Commit 53e1d7b

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 25c30e0 commit 53e1d7b

3 files changed

Lines changed: 14 additions & 10 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: 2 additions & 8 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, Types } from "effect"
31-
import { ZodOverride, zod, zodObject } from "@/util/effect-zod"
31+
import { fromZod, zod, zodObject } from "@/util/effect-zod"
3232
import { withStatics } from "@/util/schema"
3333

3434
const log = Log.create({ service: "session" })
@@ -215,13 +215,7 @@ export const MessagesInput = Schema.Struct({
215215
limit: Schema.optional(Schema.Number),
216216
}).pipe(withStatics((s) => ({ zod: zod(s) })))
217217

218-
function schemaFromZod<T extends z.ZodTypeAny>(value: T) {
219-
return Schema.declare((input): input is z.output<T> => value.safeParse(input).success).annotate({
220-
[ZodOverride]: value,
221-
})
222-
}
223-
224-
const SessionUpdateInfoSchema = schemaFromZod(
218+
const SessionUpdateInfoSchema = fromZod(
225219
updateSchema(zodObject(Info)).extend({
226220
share: updateSchema(zodObject(Share)).optional(),
227221
time: updateSchema(zodObject(Time)).optional(),

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

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,14 @@ function isZodType(value: unknown): value is z.ZodTypeAny {
4949
return typeof value === "object" && value !== null && "_zod" in value
5050
}
5151

52+
// Bridge a Zod-first schema into Effect Schema while preserving the original
53+
// Zod for downstream JSON Schema/OpenAPI generation.
54+
export function fromZod<T extends z.ZodTypeAny>(value: T) {
55+
return Schema.declare((input): input is z.output<T> => value.safeParse(input).success).annotate({
56+
[ZodOverride]: value,
57+
})
58+
}
59+
5260
function walk(ast: SchemaAST.AST): z.ZodTypeAny {
5361
const cached = walkCache.get(ast)
5462
if (cached) return cached

0 commit comments

Comments
 (0)