Blob flow
NodalMerge treats blobs as content-addressed payloads synchronized alongside, but separate from, node history. Node operations reference blob hashes. Blob bytes are transferred through dedicated blob messages or direct object-storage URLs when negotiated.Why blob flow is separate
Large binary payloads behave differently from CRDT node history:- Much larger payload sizes
- Different retry and lifecycle behavior
- Different storage backend needs
Core blob messages
Typical blob-related wire messages include:blob-upload(client uploads bytes over WebSocket)blob-request(client asks for specific blob hashes)blob-pack(server replies with requested blob bytes)blob-available(broadcast hint that blobs are now retrievable)
request-upload(ask server for upload URL)upload-granted/upload-deniedblob-uploaded(client confirms direct upload completion)blob-redirect(server returns direct download URLs)upload-rejected(verification failure on direct upload path)
Baseline flow (WebSocket bytes path)
Upload path
- Client sends
blob-uploadwith{ hash, data_b64 }entries - Server verifies content hash matches payload
- Server persists accepted blobs and stores them in room blob store
- Server broadcasts
blob-available
Download path
- Client sends
blob-requestfor hash list - Server looks up available blobs in room store
- Server replies with
blob-pack - Client resolves pending blob fetches from returned entries
Direct blob I/O flow (negotiated)
Direct blob I/O offloads payload transfer to backing object storage while keeping protocol control in NodalMerge.Direct upload
- Client sends
request-uploadwith target hash and size - Server may return presigned upload URL (
upload-granted) - Client uploads bytes directly to object storage
- Client sends
blob-uploaded - Server verifies upload (
verify_uploaded) and then broadcastsblob-available
Direct download
- Client sends
blob-request - Server resolves download URLs where available
- Server replies with
blob-redirectfor redirect-capable hashes - Remaining hashes fall through to
blob-packbytes-over-WebSocket
Integrity model
Blob integrity is content-hash based:- Upload acceptance requires hash match
- Direct-upload completion may require backend verification
- Blob references in room state are hash pointers, not mutable file handles
Availability signaling
blob-available is a lightweight signal to peers that data may now be retrievable.
It does not replace request/response fetch semantics. Peers still request missing blob payloads explicitly.
Storage coupling and lifecycle
Blob protocol behavior is tied to persistence backend capabilities:- In-memory or local file-backed stores can serve bytes directly
- Object-storage backends can expose direct URL flows
- GC/lifecycle rules remain backend-governed but must respect reachability semantics
Failure and fallback behavior
Blob flow is designed to fail safely:- Bad hash payloads are rejected
- Unsupported direct I/O capability falls back to WebSocket bytes path
- Verification failures produce explicit rejection semantics
- Missing blobs stay request-driven and retryable
Implementation guidance
- Always treat hash as source of truth for blob identity
- Use direct I/O for large payload optimization, not correctness
- Keep WebSocket path healthy as compatibility fallback
- Monitor upload verification and missing-blob retry patterns in production