Skip to content

refactor(sync): make session events schema-first - #24019

Merged
kitlangton merged 2 commits into
devfrom
sync-event-schema-session
Apr 23, 2026
Merged

refactor(sync): make session events schema-first#24019
kitlangton merged 2 commits into
devfrom
sync-event-schema-session

Conversation

@kitlangton

@kitlangton kitlangton commented Apr 23, 2026

Copy link
Copy Markdown
Contributor

Summary

  • teach SyncEvent.define(...) to work from native Effect Schema payloads and derive zod internally for runtime/bus compatibility
  • migrate Session.Event.Created, Updated, and Deleted to Schema payloads
  • migrate MessageV2.Event.Updated, Removed, PartUpdated, and PartRemoved to Schema payloads too

What this finishes

This PR completes the sync-event side of the session/message Effect Schema migration:

  • SyncEvent is now Schema-only at the definition layer
  • the old mixed z.ZodObject | Effect Schema path is gone
  • the temporary phantom _data / _propertiesData fields are gone
  • bus payload typing now derives from the stored effectProperties schema directly

Follow-on cleanup included

  • remove the last updateSchema(zodObject(...)) interop from session.ts
  • reuse def.properties on the bus publish path
  • reuse isRecord(...) for sync conversion object checks
  • remove an extra session.get(...) read in share-next
  • export and reuse Session.Patch in the session projector
  • update sync tests to define events with Schema.Struct(...), matching production

Behavior change

This changes the generated SDK type for session.updated patches:

  • before: fields in data.info were required and nullable
  • after: fields in data.info are optional and nullable

Example:

  • before: title: string | null
  • after: title?: string | null

This matches the actual patch semantics more closely:

  • missing key = unchanged
  • key: null = cleared
  • key: value = updated

Verification

  • bun typecheck
  • ./packages/sdk/js/script/build.ts
  • push hook also ran repo typecheck successfully

Teach SyncEvent definitions to accept Effect Schema payloads, migrate
Session.Event.Created/Updated/Deleted off zod wrappers, and thread the
bus-facing payload type through sync definitions.

This removes the last zodObject/updateSchema interop from session.ts and
lets session.updated emit a true patch shape, which changes the generated
SDK type from required-nullable fields to optional-nullable fields.
Migrate message-v2 sync event payloads to Effect Schema and remove the
mixed zod/Schema path from SyncEvent definitions.

- SyncEvent.define now accepts Effect Schema only and stores the original
  effect schema alongside derived zod objects for runtime/bus use.
- Bus payload typing derives from effectProperties directly; the old
  phantom _data/_propertiesData fields are gone.
- sync tests now define events with Schema.Struct, matching production.

This completes the sync-event side of the session/message schema
migration and removes the last reason for SyncEvent to accept zod.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment