{"_id":"y-arkiv","_rev":"2-086c8d853438f0b1a6d5ad17a0c83b3c","name":"y-arkiv","dist-tags":{"latest":"0.1.0"},"versions":{"0.0.0-stage":{"name":"y-arkiv","version":"0.0.0-stage","_id":"y-arkiv@0.0.0-stage","stub":true,"maintainers":[{"name":"heykinnu","email":"dhirajkavuri@gmail.com"}],"dist":{"shasum":"8c7b8297b2223b94e0f1860b6fe60db8d0207b32","tarball":"https://registry.npmjs.org/y-arkiv/-/y-arkiv-0.0.0-stage.tgz","fileCount":2,"integrity":"sha512-bjLbUVXrrLJXL2EzIATp9mnJESMC8u1MUH2bb4Bk5vL9+gT9xmRksbisVrV0vTSSTiSaTjI5cmv8jZFFWAyRGA==","signatures":[{"sig":"MEUCIQDrLs/ONX+EI+ZJ0Ft1UoEI+Ab7ktCy5BHSilhDHAoUewIgKTB0WRiupAXK9QdFEYtmlJY4ZIbI3QDcJh0Js6+BfaM=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":329},"_npmUser":{"name":"heykinnu","email":"dhirajkavuri@gmail.com"},"description":"Temporary package placeholder for staged publishing","directories":{}},"0.1.0":{"_id":"y-arkiv@0.1.0","bin":{"quire":"dist/cli.js","y-arkiv":"dist/cli.js"},"bugs":{"url":"https://github.com/kinnuworks/quire/issues"},"dist":{"shasum":"9da4fbb7e4a1b756ec845c14ef1466e955fc41aa","tarball":"https://registry.npmjs.org/y-arkiv/-/y-arkiv-0.1.0.tgz","fileCount":51,"integrity":"sha512-FUIjGJxZShUDDyBE2PP3W82vDKvutNn+kM5DB0pcIFvUL7BTjFMlsr6MigQBVjybHgcV1kWE8NSZOvYsjFUzAA==","signatures":[{"sig":"MEUCIQCOLmd6j2c7uhvMw+c8wWTl6z/3u+p+na+ApswzcX9v5AIgFwQ8tPSUNde+4PadvzP3k2hMqZs5xihkANYwWZ68z8o=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"},{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEYCIQDdAUFNhAEDJH4dR+7p0iAuiEq0RGJD9gVlcdxy1tDrjQIhAJrtC3EpzzQQbkV26yhMVaeIjGc1ycgb3F6SCnHhHpsu"}],"unpackedSize":445257},"main":"./dist/index.js","name":"y-arkiv","type":"module","types":"./dist/index.d.ts","engines":{"node":">=20"},"exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js"}},"gitHead":"ff94e4a49bb78ad04799568672e854b0c4f881fd","license":"MIT","scripts":{"test":"vitest run","build":"tsc -p tsconfig.build.json","prepack":"rm -rf dist && tsc -p tsconfig.build.json","vectors":"tsx scripts/vectors.ts","test:live":"LIVE=1 vitest run test/live.test.ts","typecheck":"tsc --noEmit","edge-cases":"tsx scripts/edge-cases.ts","prepublishOnly":"vitest run","compare-readers":"tsx scripts/compare-readers.ts"},"version":"0.1.0","_npmUser":{"name":"heykinnu","email":"dhirajkavuri@gmail.com"},"homepage":"https://github.com/kinnuworks/quire#readme","keywords":["yjs","crdt","arkiv","collaboration","encryption","local-first","provider"],"repository":{"url":"git+https://github.com/kinnuworks/quire.git","type":"git","directory":"packages/y-arkiv"},"_npmVersion":"11.20.0","description":"Serverless real-time collaboration for Yjs, stored as encrypted Arkiv entities","directories":{},"maintainers":[{"name":"heykinnu","email":"dhirajkavuri@gmail.com"}],"_nodeVersion":"26.12.0","dependencies":{"yjs":"^13.6.33","lib0":"^0.2.119","viem":"^2.57.7","@noble/curves":"^2.4.0","@noble/hashes":"^2.4.0","arkiv-encryption":"0.1.0","@arkiv-network/sdk":"0.8.1"},"_hasShrinkwrap":false,"devDependencies":{"ajv":"^8.20.0","tsx":"^4.23.15","vitest":"^5.0.5","fast-check":"^4.10.2","typescript":"^7.0.2","@types/node":"^26.6.5"},"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/y-arkiv_0.1.0_1792330144142_0.10645104361395252"}}},"time":{"created":"2026-10-18T13:26:26.918Z","modified":"2026-10-18T13:29:04.380Z","0.0.0-stage":"2026-10-18T13:26:26.918Z","0.1.0":"2026-10-18T13:29:04.226Z"},"description":"Serverless real-time collaboration for Yjs, stored as encrypted Arkiv entities","maintainers":[{"name":"heykinnu","email":"dhirajkavuri@gmail.com"}],"readme":"# y-arkiv\n\nA Yjs provider whose only backend is [Arkiv](https://arkiv.network). Every edit is encrypted in the browser and stored as an Arkiv entity, and peers receive it over a WebSocket subscription. There is no sync server. The data format is specified in [PROTOCOL.md](https://github.com/kinnuworks/quire/blob/main/PROTOCOL.md).\n\nTestnet only (Arkiv Tiramisu). MIT.\n\n## Use it in place of y-websocket\n\n```ts\nimport * as Y from \"yjs\"\nimport { ArkivProvider, newDocLink, prepareDoc, SdkStore } from \"y-arkiv\"\nimport { generatePrivateKey, privateKeyToAccount } from \"viem/accounts\"\n\n// a key made for this document only; fund it with a little test GLM\nconst privateKey = generatePrivateKey()\nconst identity = { address: privateKeyToAccount(privateKey).address, privateKey, name: \"Asha\" }\nconst store = new SdkStore({ privateKey })\n\n// create a document: the member list and first snapshot land in one transaction\nconst link = newDocLink(identity.address)\nawait ArkivProvider.createDocument({ store, link, identity })\n\n// open it: before   new WebsocketProvider(url, room, ydoc)\n//          after    new ArkivProvider(ydoc, { store, link, identity, salt })\nconst ydoc = new Y.Doc()\nconst salt = prepareDoc(ydoc, identity.address) // call before an editor binds to ydoc\nconst provider = new ArkivProvider(ydoc, { store, link, identity, salt })\nawait provider.connect()\n\nydoc.getText(\"t\").insert(0, \"hello\") // goes out about one block later\n```\n\nBind any Yjs editor to `ydoc` as usual: Tiptap's `Collaboration` extension, BlockNote, `y-codemirror.next`, `y-prosemirror`. The provider syncs the document only, with no awareness (cursors, presence), and edits land in about three to seven seconds.\n\nShare `formatDocLink(link)` inside a URL fragment. Whoever opens it can read the document, and can ask to join:\n\n```ts\nconst reader = new ArkivProvider(new Y.Doc(), { store: new SdkStore(), link: parseDocLink(fragment)! })\nawait reader.connect() // three queries, then live over WebSocket\n```\n\n## What you get\n\n- End-to-end encryption (AES-256-GCM, payloads padded to six fixed sizes), with a fresh key per member per document.\n- Membership by `$creator`: edits from outside the member list are never applied. Each edit's Yjs client id derives from its creator's address with a salt the creator signs.\n- Join requests sealed to the owner, approval, and revocation that rotates the key and seals the roster.\n- Snapshots as a 30-day lease renewed by members, published readonly versions anyone can keep alive, `keepFor`, `deleteDocument` and `shredMine`.\n- Time travel with `loadAt(store, link, block)`, which uses `atBlock` reads.\n- `blame(doc, provider)`: every visible run of text with its author, proven by an update entity or claimed through a snapshot. Open with `fullHistory: true` to count every edit still on chain; the provider checks each author against the member list as it stood at that edit's block by default (`membershipAtBlock`).\n- `MemoryChain`, an in-memory Arkiv for tests: blocks, `$creator`, expiry, flags, atomic batches, and the RPC's request size limit.\n\n## CLI\n\n```bash\nnpx y-arkiv verify '<document link>'   # members, epoch, lease, ignored writes, query cost\nnpx y-arkiv read '<document link>'\nnpx y-arkiv blame '<document link>'    # who wrote each run of text, with the entity and block that prove it\nnpx y-arkiv timeline '<document link>' # every edit in order, with characters added and removed\nnpx y-arkiv watch '<document link>'\nQUIRE_KEY=0x… npx y-arkiv extend '<version link>'\nnpx y-arkiv check-signature <address> '<message>' <signature>   # a \"Prove this key is yours\" signature\n```\n\nAll of them take `--rpc <url> --ws <url>`, to read through your own node.\n","readmeFilename":"README.md","homepage":"https://github.com/kinnuworks/quire#readme","keywords":["yjs","crdt","arkiv","collaboration","encryption","local-first","provider"],"repository":{"url":"git+https://github.com/kinnuworks/quire.git","type":"git","directory":"packages/y-arkiv"},"bugs":{"url":"https://github.com/kinnuworks/quire/issues"},"license":"MIT"}