Files
logseq/docs/adr/0004-sync-tx-entry-outliner-op.md
megayu 79c25837cb Migrate from yarn to pnpm (#12529)
* migrate yarn to pnpm

* chore: update pnpm version to 10.33.0 across all package.json files

* chore: update .npmrc and package.json for improved dependency management

* chore: unify Clojure, Node, and Java version in workflow files

* fix: enable shamefully-hoist for now and add electron, keytar to onlyBuiltDependencies

* feat: add cider/piggieback dependency and update nREPL middleware configuration to silence warnings

* ensure pnpm setup prior to node setup

* fix: update logseq/bb-tasks git SHA

* feat: add pnpm configuration for onlyBuiltDependencies in package.json

* feat: add onlyBuiltDependencies configuration for better-sqlite3 in pnpm settings

* chore: update pnpm lockfile

* fix: resolve merge conflicts

* fix: remove invisible characters from markdown headers

* fix: update .npmrc comments for clarity on lockfile usage

* Revert "feat: add cider/piggieback dependency and update nREPL middleware configuration to silence warnings"

This reverts commit 70a111936f.

* fix: remove invisible characters from various README files and add .editorconfig

* fix: clarify lockfile resolution process in SKILL.md

---------

Co-authored-by: Tienson Qin <tiensonqin@gmail.com>
2026-04-24 23:40:25 +08:00

2.7 KiB

ADR 0004: Sync batches are ordered tx entries with persisted :outliner-op

Date: 2026-03-16 Status: Accepted

Context

DB sync previously treated a client upload batch as one transit-encoded tx blob and the client pull path could flatten remote tx entries into one local apply. That made sync failures hard to debug because:

  • a failed sync apply did not clearly identify which tx entry failed
  • the server did not persist the original :outliner-op
  • the client carried cross-batch tempid repair logic to make split txs work

We want sync errors to point to one specific tx entry and one specific operation intent.

We also want the server and client to follow the same mental model:

  • a batch is an ordered list of tx entries
  • each tx entry is applied one by one
  • each tx entry may carry its own :outliner-op

Decision

  1. tx/batch now sends a list of tx entries instead of one encoded tx blob.
  2. Each tx entry contains:
    • :tx
    • optional :outliner-op
  3. The server applies tx entries one by one, in order.
  4. The server persists :outliner-op in tx_log and returns it in pull/ok.
  5. The client applies pulled tx entries one by one and includes the returned :outliner-op in tx-meta for remote apply.
  6. Cross-batch tempid reuse is unsupported by contract. A tempid must be fully resolved within a single tx entry.

Storage and Protocol Notes

  • The persisted sync tx log is the per-graph SQLite store initialized in logseq.db-sync.storage, not the Cloudflare D1 graph index schema.
  • Because of that, outliner_op is added via runtime SQLite schema setup for the per-graph store, not a D1 migration under worker/migrations/.
  • pull/ok entries now have shape:
    • {:t ... :tx ... :outliner-op ...}
  • tx/batch entries now have shape:
    • {:tx ... :outliner-op ...}

Consequences

  • Positive:
    • Sync failures can be traced to one tx entry and its :outliner-op.
    • Client and server now share the same ordered per-entry apply model.
    • The protocol is simpler than carrying cross-batch tempid repair logic.
  • Negative:
    • Older assumptions that tempids can be reused across tx entries are no longer valid.
    • The wire format changed for tx/batch and pull/ok.

Follow-up Constraints

  • New sync producers must keep each tx entry self-contained.
  • If a future feature needs cross-entry references again, it must be introduced explicitly as protocol behavior rather than repaired implicitly by the client.

Verification

  • Updated frontend worker db-sync tests.
  • Updated deps/db-sync storage, handler, and node-adapter tests.
  • Passed:
    • bb dev:test -v frontend.worker.db-sync-test
    • pnpm test in deps/db-sync
    • bb dev:lint-and-test