import type { Doc } from '@automerge/automerge' import type { DocumentId } from '../document-id.js' /** * A `Source` is a place changes flow to and from — the local store, the atproto * PDS, or (later) a libp2p peer link. It exposes exactly one operation per * direction and **hides all transport internally**: no libp2p / network / atproto * concept ever appears on this interface. The sync {@link Engine} coordinates a * set of Sources; it never learns how any of them moves bytes. */ export interface Source { /** Stable identifier, used for merge provenance and policy lookup. */ readonly id: string /** Engine → Source: send our canonical doc state out (persist / publish / gossip). */ push(documentId: DocumentId, doc: Doc): Promise /** * Engine ← Source (engine-initiated): fetch this source's current view of the * doc, or `null` if it has none. Used for initial load, catch-up, and * request/response sources (e.g. the PDS) that cannot push to us. */ pull(documentId: DocumentId): Promise | null> /** * Source → Engine (source-initiated delivery): when the source receives changes * from its transport (a peer message, a cross-tab edit) it applies them * internally and hands the Engine the updated doc — which merges immediately, * with no pull round-trip. Returns an unsubscribe function. */ subscribe(onInbound: (documentId: DocumentId, doc: Doc) => void): () => void }