From a38a439bbaf03d6ca9c33f5a24b724dc40e5ad90 Mon Sep 17 00:00:00 2001 From: Florian <45694132+flo-bit@users.noreply.github.com> Date: Wed, 22 Apr 2026 11:49:40 +0200 Subject: [PATCH] add record to payload --- src/core/realtime/publishing-adapter.ts | 3 +++ src/core/realtime/types.ts | 17 +++++++++++++++-- tests/realtime-durable-object.test.ts | 10 +++++++++- tests/realtime-e2e.test.ts | 7 ++++++- tests/realtime-foundations.test.ts | 3 +++ 5 files changed, 36 insertions(+), 4 deletions(-) diff --git a/src/core/realtime/publishing-adapter.ts b/src/core/realtime/publishing-adapter.ts index edffe0a..24c6e06 100644 --- a/src/core/realtime/publishing-adapter.ts +++ b/src/core/realtime/publishing-adapter.ts @@ -115,6 +115,9 @@ export function wrapWithPublishing( collection: record.collection, authorDid: record.authorDid, rkey: record.rkey, + cid: record.cid, + record: record.record, + createdAt: record.createdAt, }, ts: now, })); diff --git a/src/core/realtime/types.ts b/src/core/realtime/types.ts index c4aaff1..4f72dfd 100644 --- a/src/core/realtime/types.ts +++ b/src/core/realtime/types.ts @@ -1,11 +1,24 @@ /** Realtime module — canonical types + interfaces. See docs/realtime.md. */ -/** Discriminated union of every event kind that flows through the PubSub. */ +/** Discriminated union of every event kind that flows through the PubSub. + * + * `record.created` carries the full record body so a subscriber can apply an + * insert or upsert without a follow-up `getRecord` call. `putRecord` over an + * existing `(authorDid, rkey)` publishes another `record.created` — treat it + * as upsert. */ export type RealtimeEvent = | { topic: string; kind: "record.created"; - payload: { spaceUri: string; collection: string; authorDid: string; rkey: string }; + payload: { + spaceUri: string; + collection: string; + authorDid: string; + rkey: string; + cid: string | null; + record: Record; + createdAt: number; + }; ts: number; } | { diff --git a/tests/realtime-durable-object.test.ts b/tests/realtime-durable-object.test.ts index 237d184..0c79e34 100644 --- a/tests/realtime-durable-object.test.ts +++ b/tests/realtime-durable-object.test.ts @@ -51,7 +51,15 @@ function mkEvent(overrides: Partial = {}): RealtimeEvent { return { topic: "space:at://x/y/z", kind: "record.created", - payload: { spaceUri: "at://x/y/z", collection: "c", authorDid: "did:plc:x", rkey: "r" }, + payload: { + spaceUri: "at://x/y/z", + collection: "c", + authorDid: "did:plc:x", + rkey: "r", + cid: null, + record: {}, + createdAt: 1, + }, ts: 1, ...(overrides as any), }; diff --git a/tests/realtime-e2e.test.ts b/tests/realtime-e2e.test.ts index 431e1fa..df11f61 100644 --- a/tests/realtime-e2e.test.ts +++ b/tests/realtime-e2e.test.ts @@ -186,7 +186,12 @@ describe("realtime e2e (in-memory pubsub, SSE transport)", () => { expect(put.status).toBe(200); const next = await events.next(); expect(next.done).toBe(false); - expect((next.value as RealtimeEvent).kind).toBe("record.created"); + const event = next.value as RealtimeEvent & { kind: "record.created" }; + expect(event.kind).toBe("record.created"); + // Fat payload: subscribers can render the new record without a follow-up fetch. + expect(event.payload.record).toEqual({ text: "hello" }); + expect(event.payload.collection).toBe("app.event.message"); + expect(event.payload.authorDid).toBe(ALICE); close(); }); diff --git a/tests/realtime-foundations.test.ts b/tests/realtime-foundations.test.ts index b7ca223..9d814d8 100644 --- a/tests/realtime-foundations.test.ts +++ b/tests/realtime-foundations.test.ts @@ -15,6 +15,9 @@ function mk(topic: string, n: number): RealtimeEvent { collection: "c", authorDid: "did:plc:x", rkey: String(n), + cid: null, + record: {}, + createdAt: n, }, ts: n, }; -- 2.51.2