Skip to content

feat: force-save before Preview/Publish#945

Open
kptdobe wants to merge 3 commits into
mainfrom
flushsav
Open

feat: force-save before Preview/Publish#945
kptdobe wants to merge 3 commits into
mainfrom
flushsav

Conversation

@kptdobe
Copy link
Copy Markdown
Contributor

@kptdobe kptdobe commented May 19, 2026

Problem

When a user drags and drops an image in the DA editor, the upload is a two-step process:

  1. An FPO placeholder is inserted immediately into the collaborative document.
  2. A debounced PUT to da-admin fires ~2 seconds later to persist the change.

If the user clicks Preview or Publish before that debounced save completes, the Cloudflare Durable Object (DO) backing the collab session may have migrated to a different machine in the meantime. The result: the preview/publish pipeline reads the old version of the document from da-admin — without the newly dropped image.

Solution

Before triggering a Preview or Publish action, the client now sends a WebSocket flush request (MSG_FLUSH_REQUEST = 2) to da-collab, asking it to immediately flush any pending in-memory changes to da-admin. The client then:

  • Waits up to 8 seconds for the collab server to acknowledge with MSG_FLUSH_RESPONSE = 3.
  • If the WebSocket is not yet connected, waits for reconnection before sending the flush.
  • Retries up to 3 times on timeout (e.g. transient network blips).
  • On server-reported error or exhausted retries, surfaces a clear user-facing error message in the title bar and aborts the preview/publish — preventing a silent stale-content push.
  • On success, proceeds normally with the AEM preview/publish call.

Dependencies

These da-collab PRs must be merged first, otherwise the Preview/Publish action will stall waiting for a flush ack that the server does not understand.

Changes

  • blocks/edit/prose/forcesave.js (new) — force-save protocol: MSG_FLUSH_REQUEST/RESPONSE constants, decodeFlushAck, sendFlushRequest, waitForWsConnection, and the exported forceSave(provider) function.
  • blocks/edit/prose/index.js — imports forceSave from ./forcesave.js; attaches daContent.forceSave at the end of initProse.
  • blocks/edit/da-title/da-title.js — calls daContent.forceSave() in handleAction before saveToAem, only for the prose edit view.
  • test/unit/blocks/edit/prose/index.test.js — 4 forceSave unit tests; imports forceSave from ./forcesave.js.

Test plan

Test page: https://flushsav--da-live--adobe.aem.live/

  • All existing unit tests pass (npm test — 1355 passed, 0 failed)
  • npm run lint passes with no errors
  • Manual: drag-drop an image, immediately click Preview — verify the image appears in the preview
  • Manual: simulate a slow network; verify the UI shows the flush error message and does not open a stale preview

🤖 Generated with Claude Code

kptdobe and others added 2 commits May 19, 2026 08:23
…r DO migration

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Move MSG_FLUSH_REQUEST/RESPONSE constants, decodeFlushAck,
sendFlushRequest, waitForWsConnection, and forceSave out of
index.js into a dedicated forcesave.js module. index.js
re-exports nothing — it imports forceSave and attaches it
to daContent. Test file updated to import forceSave from
the new module path.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@aem-code-sync
Copy link
Copy Markdown

aem-code-sync Bot commented May 19, 2026

Hello, I'm the AEM Code Sync Bot and I will run some actions to deploy your branch.
In case there are problems, just click the checkbox below to rerun the respective action.

  • Re-sync branch
Commits

@kptdobe kptdobe requested review from auniverseaway and chrischrischris and removed request for chrischrischris May 19, 2026 06:47
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants