mirror of
https://github.com/logseq/logseq.git
synced 2026-05-01 09:26:28 +00:00
4.1 KiB
4.1 KiB
DB-Sync Client-Server Protocol
Transport
- WebSocket
ws(s)to/sync/:graph-id. - Client builds URL from config and appends
?token=...when available. - Encoding: JSON objects;
txpayloads are Transit strings. - Note: keep this document in sync with the current implementation.
Client -> Server
{"type":"hello","client":"<repo-id>"}- Initial handshake from client.
{"type":"pull","since":<t>}- Request txs after
since(defaults to 0).
- Request txs after
{"type":"tx/batch","t_before":<t>,"txs":["<tx-transit>", ...]}- Upload a batch of txs based on
t_before(required).
- Upload a batch of txs based on
{"type":"ping"}- Optional keepalive; server replies
pong.
- Optional keepalive; server replies
Server -> Client
{"type":"hello","t":<t>}- Server hello with current t.
{"type":"pull/ok","t":<t>,"txs":[{"t":<t>,"tx":"<tx-transit>"}...]}- Pull response with txs.
{"type":"tx/batch/ok","t":<t>}- Batch accepted; server advanced to t.
{"type":"changed","t":<t>}- Broadcast that server state advanced; client should pull.
{"type":"tx/reject","reason":"stale","t":<t>}- Client tx is based on stale t.
{"type":"tx/reject","reason":"cycle","data":"<transit {:attr <kw> :server_values ...}>"}- Cycle detected with server values.
{"type":"tx/reject","reason":"empty tx data"|"invalid tx"|"invalid t_before"}- Invalid batch.
{"type":"pong"}- Keepalive response.
{"type":"error","message":"..."}- Invalid/unknown message. Current messages:
"unknown type","invalid request","server error","invalid since".
- Invalid/unknown message. Current messages:
HTTP API
- Auth: Bearer token via
Authorization: Bearer <token>or?token=.... - JSON body/response unless noted.
- Auth required for
/graphs,/sync/:graph-id/*, and/assets/*. Expect401(unauthorized) or403(forbidden) on access failure.
Worker Health
GET /health- Worker health check. Response:
{"ok":true}.
- Worker health check. Response:
Graphs (index DO)
GET /graphs- List graphs the user owns. Response:
{"graphs":[{graph_id, graph_name, schema_version?, created_at, updated_at}...]}.
- List graphs the user owns. Response:
POST /graphs- Create graph. Body:
{"graph_name":"...","schema_version":"<major>"}(schema_version optional). Response:{"graph_id":"..."}.
- Create graph. Body:
GET /graphs/:graph-id/access- Access check. Response:
{"ok":true},401(unauthorized),403(forbidden), or404(not found).
- Access check. Response:
DELETE /graphs/:graph-id- Delete graph and reset data. Response:
{"graph_id":"...","deleted":true}or400(missing graph id).
- Delete graph and reset data. Response:
Sync (per-graph DO, via /sync/:graph-id/...)
GET /sync/:graph-id/health- Health check. Response:
{"ok":true}.
- Health check. Response:
GET /sync/:graph-id/pull?since=<t>- Same as WS pull. Response:
{"type":"pull/ok","t":<t>,"txs":[{"t":<t>,"tx":"<tx-transit>"}...]}. - Error response (400):
{"error":"invalid since"}.
- Same as WS pull. Response:
POST /sync/:graph-id/tx/batch- Same as WS tx/batch. Body:
{"t_before":<t>,"txs":["<tx-transit>", ...]}. - Response:
{"type":"tx/batch/ok","t":<t>}or{"type":"tx/reject","reason":...}. - Error response (400):
{"error":"missing body"|"invalid tx"}.
- Same as WS tx/batch. Body:
GET /sync/:graph-id/snapshot/rows?after=<addr>&limit=<n>- Pull sqlite kvs rows. Response:
{"rows":[{"addr":<addr>,"content":"<transit>","addresses":<json|null>}...],"last_addr":<addr>,"done":true|false}.
- Pull sqlite kvs rows. Response:
POST /sync/:graph-id/snapshot/import- Import sqlite kvs rows. Body:
{"reset":true|false,"rows":[[addr,content,addresses]...]}. - Response:
{"ok":true,"count":<n>}. - Error response (400):
{"error":"missing body"|"invalid body"}.
- Import sqlite kvs rows. Body:
DELETE /sync/:graph-id/admin/reset- Drop/recreate per-graph tables. Response:
{"ok":true}.
- Drop/recreate per-graph tables. Response:
Assets
GET /assets/:graph-id/:asset-uuid.:ext- Download asset (binary response,
content-typeset,x-asset-typeheader included).
- Download asset (binary response,
PUT /assets/:graph-id/:asset-uuid.:ext- Upload asset (binary body). Size limit ~100MB. Response:
{"ok":true}.
- Upload asset (binary body). Size limit ~100MB. Response:
DELETE /assets/:graph-id/:asset-uuid.:ext- Delete asset. Response:
{"ok":true}.
- Delete asset. Response:
- Asset error responses:
{"error":"invalid asset path"}(400),{"error":"not found"}(404),{"error":"asset too large"}(413),{"error":"method not allowed"}(405),{"error":"missing assets bucket"}(500).