Skip to content

feat: WebSocket flush protocol for force-save before Preview/Publish#152

Merged
kptdobe merged 1 commit into
mainfrom
feat/flush-protocol
May 19, 2026
Merged

feat: WebSocket flush protocol for force-save before Preview/Publish#152
kptdobe merged 1 commit into
mainfrom
feat/flush-protocol

Conversation

@kptdobe
Copy link
Copy Markdown
Contributor

@kptdobe kptdobe commented May 19, 2026

Summary

  • Adds messageFlushRequest (type 2) and messageFlushResponse (type 3) constants to the WebSocket protocol so the DA editor client can request an immediate force-save before Preview or Publish reads the document from da-admin.
  • Implements the flush case in messageListener: awaits doc.flushSave() then sends a binary ack with ok=1 on success or ok=0 plus an error string on failure.
  • Introduces a savingPromise variable alongside the existing saving flag so that flushSave can wait for any already-in-flight PUT to complete before resolving — this prevents the ack being sent before the save actually finishes.

Problem

When Preview or Publish is clicked, the client sends a flush request over the existing WebSocket connection. Without this server-side handler, the da-collab Durable Object has no way to know it should flush its debounced 2-second save early. The race is subtle: if a PUT is already in progress when flushSave is called, the previous code would immediately resolve, causing an ack before the in-flight save had finished.

Protocol

varuint meaning
2 messageFlushRequest (client → server)
3 messageFlushResponse (server → client): followed by ok (1=success, 0=failure) and, on failure, an error string

Test plan

  • messageFlushRequest sends flush response ack with ok=1 after flushSave — happy path
  • messageFlushRequest sends flush response with ok=0 when flushSave throws — error path encodes error message
  • messageFlushRequest works when doc has no flushSave (still sends ok ack) — graceful no-op
  • Flush waits for an in-flight save before resolving — savingPromise race-condition fix
  • All 117 existing tests continue to pass with 100% statement/function coverage

🤖 Generated with Claude Code

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@kptdobe kptdobe force-pushed the feat/flush-protocol branch from c835290 to 5a701b0 Compare May 19, 2026 06:52
@kptdobe
Copy link
Copy Markdown
Contributor Author

kptdobe commented May 19, 2026

Branch rebuilt and force-pushed to isolate changes.

This PR (feat/flush-protocol) now contains only the flush-protocol changes:

  • export const messageFlushRequest = 2 and export const messageFlushResponse = 3 constants
  • savingPromise tracking in bindState so in-flight saves can be awaited
  • ydoc.flushSave waits for any in-flight savingPromise before starting a new save
  • ydoc.cancelSave helper
  • messageListener made async
  • messageFlushRequest case in the switch: awaits flushSave, sends a messageFlushResponse ack with ok=1 or ok=0+error string

Removed from this PR: all lastsync CF storage marker changes (those belong to #153).

Tests: 115 passing, 100% coverage. Lint clean.

@kptdobe kptdobe merged commit 8bf0ff4 into main May 19, 2026
5 checks passed
@kptdobe kptdobe deleted the feat/flush-protocol branch May 19, 2026 12:06
adobe-bot pushed a commit that referenced this pull request May 19, 2026
# [1.5.0](v1.4.2...v1.5.0) (2026-05-19)

### Bug Fixes

* preserve pending Yjs changes across DO evictions via lastsync CF storage marker ([#153](#153)) ([defb16c](defb16c))

### Features

* adopt Cloudflare WebSocket Hibernation API ([#137](#137)) ([61e6000](61e6000))
* WebSocket flush protocol for force-save before Preview/Publish ([#152](#152)) ([8bf0ff4](8bf0ff4))
@adobe-bot
Copy link
Copy Markdown
Collaborator

🎉 This PR is included in version 1.5.0 🎉

The release is available on:

Your semantic-release bot 📦🚀

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants