UNPKG

ethercalc

Version:

Multi-User Spreadsheet Server — TypeScript rewrite (Cloudflare fullstack)

83 lines (61 loc) 2.78 kB
# @ethercalc/migrate Phase 11b migrator — streams a legacy EtherCalc Redis out of a live RESP server and seeds each room into the new Cloudflare stack via the worker's `PUT /_migrate/seed/:room` endpoint. See `AGENTS.md` §12 for the full design. ## Exporting the legacy data Load the legacy `dump.rdb` into a RESP-speaking server on the migration host. Any of these works — the migrator only talks RESP: ```bash # Option A — real redis-server redis-server --dir /path/to/dump/ --dbfilename dump.rdb --port 6379 # Option B — Zedis or any other RESP-compatible RDB loader. ``` The server owns the RDB decode; the migrator owns shape-shifting into Worker PUTs. Total memory in the migrator stays O(1-per-room) regardless of dump size — rooms are streamed via `SCAN` and pipelined `GET`/`LRANGE`/`HGETALL`. ## Running the migration Start the new worker in one terminal (Miniflare or `wrangler dev`): ```bash echo 'ETHERCALC_MIGRATE_TOKEN="local-only"' > packages/worker/.dev.vars ./bin/ethercalc ``` Then run the migrator in another: ```bash ./bin/ethercalc migrate \ --source redis://127.0.0.1:6379 \ --target http://127.0.0.1:8000 \ --token local-only ``` `--token` must match `env.ETHERCALC_MIGRATE_TOKEN` on the worker. In production, set it with `wrangler secret put ETHERCALC_MIGRATE_TOKEN` before running with `--target https://ethercalc.workers.dev`. ## Dry-run preview ```bash ./bin/ethercalc migrate \ --source redis://127.0.0.1:6379 \ --dry-run ``` Enumerates every room via RESP and prints the intended writes to stdout without contacting any worker. Useful for sanity-checking the dump before a real seed. ## What goes where | Legacy Redis key | New location | | --------------------------- | --------------------------------------------------- | | `snapshot-<room>` | DO storage `snapshot` (+ `meta:updated_at`) | | `log-<room>[i]` | DO storage `log:<padSeq(i+1)>` | | `audit-<room>[i]` | DO storage `audit:<padSeq(i+1)>` | | `chat-<room>[i]` | DO storage `chat:<padSeq(i+1)>` | | `ecell-<room>` hash field | DO storage `ecell:<user>` | | `timestamps` hash | D1 `rooms(room, updated_at)` | | (new) existence flag | KV `rooms:exists:<room>``"1"` | Room names preserve the exact bytes they had in Redis (including URL encoding applied by the legacy `encodeURI` call). ## Testing ```bash bun run --cwd packages/migrate test bun run --cwd packages/migrate test:coverage # 100% gate ``` All tests run in pure Node — no Redis, no wrangler, no Cloudflare credentials required.