You are browsing as a guest. Sign up (or log in) to start making projects!

Open comments for this post

55m 56s logged

the sync backend exists now

so the TODO said “Cloud sync” and I was like “how hard can it be”

it was not hard actually. which is suspicious. but it works.

new directory: Backend/sync-worker/. it’s a Cloudflare Worker backed by R2 for storage. the whole sync API is three JS files and a wrangler config.


the API

  • POST /sync/push - batch upload notes, embeddings, and positions
  • POST /sync/pull - batch download everything (or since a snapshot)
  • GET /sync/status - storage stats (note count, bytes used, 512MB limit)
  • POST /sync/clear - nuke everything
  • plus individual CRUD routes for single notes, embeddings, and positions

notes are JSON. embeddings are raw f32 bytes (384 * 4 = 1,536 bytes per note). positions are JSON. everything lives in R2 under a clean key scheme: notes/{id}.json, embeddings/{id}.bin, positions/{id}.json.


the storage layer

storage.js is the R2 abstraction. getJson, putJson, getBinary, putBinary, del, listKeys. plus a manifest system that tracks note count, last modified time, and the current snapshot ID. snapshots are versioned so the client can eventually do “pull only what changed since X” (right now it just dumps everything, but the plumbing is there).


push and pull

push accepts a JSON body with notes, embeddings, and positions objects. writes them all to R2, updates the manifest, creates a snapshot record, returns the snapshot ID.

pull lists all note keys, fetches each note plus its embedding and position, and returns the whole bundle. embeddings get round-tripped through Float32Array so the binary format is preserved correctly.

CORS is wide open (*) because this is a personal sync worker, not a public API. the client will be the Penumbra app running in the browser or on desktop.
I’ll probably change this tho


the generated types file

wrangler generated a 14,000-line TypeScript declaration file for the Cloudflare runtime. I committed it because it’s how wrangler works and I don’t want to fight it. it defines the R2Bucket binding and every other Workers API type. it’s big. it’s fine.


this is the first non-Rust code in the repo. feels weird. but the sync layer is inherently a server-side thing and Cloudflare Workers with R2 is genuinely the simplest way to get object storage with an HTTP API. no server to manage, no database to provision, just a bucket and some routing.


Also, had to kick out usearch since it wasn’t WASM compatible now everything but Candle is WASM compatible!

0
1

Comments 0

No comments yet. Be the first!