{"_id":"loro-protocol","_rev":"6-837f534382f2aefbe5cb05c34e6c0196","name":"loro-protocol","dist-tags":{"latest":"0.3.0"},"versions":{"0.1.0":{"name":"loro-protocol","version":"0.1.0","keywords":["loro","crdt","protocol","encoding","decoding","binary","websocket","fragmentation","e2ee","aes-gcm","webcrypto","yjs","awareness"],"author":{"name":"Loro Team"},"license":"MIT","_id":"loro-protocol@0.1.0","maintainers":[{"name":"rem2018","email":"remch183@outlook.com"}],"homepage":"https://github.com/loro-dev/protocol/tree/main/packages/loro-protocol","bugs":{"url":"https://github.com/loro-dev/protocol/issues"},"dist":{"shasum":"bb812e27508f73d05584a10bfc2b232313feabb0","tarball":"https://registry.npmjs.org/loro-protocol/-/loro-protocol-0.1.0.tgz","fileCount":10,"integrity":"sha512-cImsQOwKn4ax0ptsmnUfPKyct7AzOhB/NnXNu911fSLIm4n9T0a2pCf6AzriyxZwGqMx/uIZlYq5QNUKRKZaXw==","signatures":[{"sig":"MEUCIFeop6wwCzuhxgBUbb0SMB+6jmugSYNfSYjV2tMg6WaiAiEA14Rgpii+LzKDi1F0vWrxuJBtHjRywuoTR2HUDj7WIB0=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":142615},"main":"dist/index.cjs","type":"module","_from":"file:loro-protocol-0.1.0.tgz","types":"dist/index.d.ts","module":"dist/index.js","engines":{"node":">=18.0.0"},"exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js","require":"./dist/index.cjs"}},"private":false,"scripts":{"dev":"tsdown --watch","test":"vitest run","build":"tsdown","clean":"tsdown --clean","typecheck":"tsc -p tsconfig.json --noEmit"},"_npmUser":{"name":"rem2018","email":"remch183@outlook.com"},"_resolved":"/tmp/afb5d3c74e7f2ba65cb67423d3a679ba/loro-protocol-0.1.0.tgz","_integrity":"sha512-cImsQOwKn4ax0ptsmnUfPKyct7AzOhB/NnXNu911fSLIm4n9T0a2pCf6AzriyxZwGqMx/uIZlYq5QNUKRKZaXw==","repository":{"url":"git+https://github.com/loro-dev/protocol.git","type":"git","directory":"packages/loro-protocol"},"_npmVersion":"10.8.2","description":"Compact binary wire protocol for collaborative CRDTs (Loro/Yjs), with encoders/decoders and bytes utilities","directories":{},"sideEffects":false,"_nodeVersion":"20.19.5","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"tsdown":"^0.14.1","vitest":"^3.2.4","typescript":"^5.9.2"},"_npmOperationalInternal":{"tmp":"tmp/loro-protocol_0.1.0_1757656447999_0.02166839147233368","host":"s3://npm-registry-packages-npm-production"}},"0.1.1":{"name":"loro-protocol","version":"0.1.1","keywords":["loro","crdt","protocol","encoding","decoding","binary","websocket","fragmentation","e2ee","aes-gcm","webcrypto","yjs","awareness"],"author":{"name":"Loro Team"},"license":"MIT","_id":"loro-protocol@0.1.1","maintainers":[{"name":"rem2018","email":"remch183@outlook.com"}],"homepage":"https://github.com/loro-dev/protocol/tree/main/packages/loro-protocol","bugs":{"url":"https://github.com/loro-dev/protocol/issues"},"dist":{"shasum":"71f22e012cc586fe1a4a4eee1d2ae28fe181027c","tarball":"https://registry.npmjs.org/loro-protocol/-/loro-protocol-0.1.1.tgz","fileCount":10,"integrity":"sha512-y5f0SK6rbQkCgy17Er9q7IrBwQC1wDTDopyL26gT20YlLHcpY3ZxGCmPVv9OJxbWaNs9hZAFIeBHUZSnsxJT3g==","signatures":[{"sig":"MEQCIDLoqi6wgZktTVoXLyPY/AtvoIuWq+9amTJCPNv1jvs7AiBRzH9mkXRmqhuly7vYkArZwO8lHkkgtf5cVOFXO91qww==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":142615},"main":"dist/index.cjs","type":"module","_from":"file:loro-protocol-0.1.1.tgz","types":"dist/index.d.ts","module":"dist/index.js","engines":{"node":">=18.0.0"},"exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js","require":"./dist/index.cjs"}},"private":false,"scripts":{"dev":"tsdown --watch","test":"vitest run","build":"tsdown","clean":"tsdown --clean","typecheck":"tsc -p tsconfig.json --noEmit"},"_npmUser":{"name":"rem2018","email":"remch183@outlook.com"},"_resolved":"/tmp/f73619322a62e6613331103ca1c1b56f/loro-protocol-0.1.1.tgz","_integrity":"sha512-y5f0SK6rbQkCgy17Er9q7IrBwQC1wDTDopyL26gT20YlLHcpY3ZxGCmPVv9OJxbWaNs9hZAFIeBHUZSnsxJT3g==","repository":{"url":"git+https://github.com/loro-dev/protocol.git","type":"git","directory":"packages/loro-protocol"},"_npmVersion":"10.8.2","description":"Compact binary wire protocol for collaborative CRDTs (Loro/Yjs), with encoders/decoders and bytes utilities","directories":{},"sideEffects":false,"_nodeVersion":"20.19.5","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"tsdown":"^0.14.1","vitest":"^3.2.4","typescript":"^5.9.2"},"_npmOperationalInternal":{"tmp":"tmp/loro-protocol_0.1.1_1761211257283_0.09229889987767703","host":"s3://npm-registry-packages-npm-production"}},"0.1.2":{"name":"loro-protocol","version":"0.1.2","keywords":["loro","crdt","protocol","encoding","decoding","binary","websocket","fragmentation","e2ee","aes-gcm","webcrypto","yjs","awareness"],"author":{"name":"Loro Team"},"license":"MIT","_id":"loro-protocol@0.1.2","maintainers":[{"name":"rem2018","email":"remch183@outlook.com"}],"homepage":"https://github.com/loro-dev/protocol/tree/main/packages/loro-protocol","bugs":{"url":"https://github.com/loro-dev/protocol/issues"},"dist":{"shasum":"62e5d2d6a460e482b609eb9056440097160319d0","tarball":"https://registry.npmjs.org/loro-protocol/-/loro-protocol-0.1.2.tgz","fileCount":10,"integrity":"sha512-nWjt097/bXnQaOPr86LSOdO9Sh2BPs7UscRKHDiHBXgVfsMGUy9m+MmIj2cZ/UFo26DeF/qpIVyPlV4KnIFEvw==","signatures":[{"sig":"MEUCIEuYqN+gmZ0yI9kvMlnWcOP3GE0dfylm2E1a/6u1Cr1MAiEAvPbjzvcuu0XfR+Vz3I8equDu5NqEJlCl5VUfBj37fFg=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":142059},"main":"dist/index.cjs","type":"module","_from":"file:loro-protocol-0.1.2.tgz","types":"dist/index.d.ts","module":"dist/index.js","engines":{"node":">=18.0.0"},"exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js","require":"./dist/index.cjs"}},"private":false,"scripts":{"dev":"tsdown --watch","test":"vitest run","build":"tsdown","clean":"tsdown --clean","typecheck":"tsc -p tsconfig.json --noEmit"},"_npmUser":{"name":"rem2018","email":"remch183@outlook.com"},"_resolved":"/tmp/9652f33e33d9061b054c938972bb51ef/loro-protocol-0.1.2.tgz","_integrity":"sha512-nWjt097/bXnQaOPr86LSOdO9Sh2BPs7UscRKHDiHBXgVfsMGUy9m+MmIj2cZ/UFo26DeF/qpIVyPlV4KnIFEvw==","repository":{"url":"git+https://github.com/loro-dev/protocol.git","type":"git","directory":"packages/loro-protocol"},"_npmVersion":"10.8.2","description":"Compact binary wire protocol for collaborative CRDTs (Loro/Yjs), with encoders/decoders and bytes utilities","directories":{},"sideEffects":false,"_nodeVersion":"20.19.5","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"tsdown":"^0.14.1","vitest":"^3.2.4","typescript":"^5.9.2"},"_npmOperationalInternal":{"tmp":"tmp/loro-protocol_0.1.2_1761817653742_0.9260863611014427","host":"s3://npm-registry-packages-npm-production"}},"0.1.3":{"name":"loro-protocol","version":"0.1.3","keywords":["loro","crdt","protocol","encoding","decoding","binary","websocket","fragmentation","e2ee","aes-gcm","webcrypto","yjs","awareness"],"author":{"name":"Loro Team"},"license":"MIT","_id":"loro-protocol@0.1.3","maintainers":[{"name":"rem2018","email":"remch183@outlook.com"}],"homepage":"https://github.com/loro-dev/protocol/tree/main/packages/loro-protocol","bugs":{"url":"https://github.com/loro-dev/protocol/issues"},"dist":{"shasum":"894627fe249589c312bccb9675df8fd3991b1551","tarball":"https://registry.npmjs.org/loro-protocol/-/loro-protocol-0.1.3.tgz","fileCount":10,"integrity":"sha512-+9fI/0aqgJe4mc/Yb+PmpT53FSkOP+mEGZQXNMWxbFdvm7MSsf4FFOVMqekFn1D2g03ALOofDK7aIpNwkUVl9Q==","signatures":[{"sig":"MEYCIQDhC1KdCT9py3m8j0gzulaEhpZhupcY/SMnQujOHem7RQIhAOj1jQBzS9eCyVuPDXiDfOjyL1PmwPwlUIH+1JWMmS2O","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/loro-protocol@0.1.3","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":143401},"main":"dist/index.cjs","type":"module","_from":"file:loro-protocol-0.1.3.tgz","types":"dist/index.d.ts","module":"dist/index.js","engines":{"node":">=18.0.0"},"exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js","require":"./dist/index.cjs"}},"private":false,"scripts":{"dev":"tsdown --watch","test":"vitest run","build":"tsdown","clean":"tsdown --clean","typecheck":"tsc -p tsconfig.json --noEmit"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:8816f56f-500c-48b2-80fd-07c36dd53d80"}},"_resolved":"/tmp/2e9492ddfc7b7e5b190a711eced97bff/loro-protocol-0.1.3.tgz","_integrity":"sha512-+9fI/0aqgJe4mc/Yb+PmpT53FSkOP+mEGZQXNMWxbFdvm7MSsf4FFOVMqekFn1D2g03ALOofDK7aIpNwkUVl9Q==","repository":{"url":"git+https://github.com/loro-dev/protocol.git","type":"git","directory":"packages/loro-protocol"},"_npmVersion":"11.6.1","description":"Compact binary wire protocol for collaborative CRDTs (Loro/Yjs), with encoders/decoders and bytes utilities","directories":{},"sideEffects":false,"_nodeVersion":"24.11.0","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"tsdown":"^0.14.1","vitest":"^3.2.4","typescript":"^5.9.2"},"_npmOperationalInternal":{"tmp":"tmp/loro-protocol_0.1.3_1762352883275_0.5782306925798115","host":"s3://npm-registry-packages-npm-production"}},"0.2.0":{"name":"loro-protocol","version":"0.2.0","keywords":["loro","crdt","protocol","encoding","decoding","binary","websocket","fragmentation","e2ee","aes-gcm","webcrypto","yjs","awareness"],"author":{"name":"Loro Team"},"license":"MIT","_id":"loro-protocol@0.2.0","maintainers":[{"name":"rem2018","email":"remch183@outlook.com"}],"homepage":"https://github.com/loro-dev/protocol/tree/main/packages/loro-protocol","bugs":{"url":"https://github.com/loro-dev/protocol/issues"},"dist":{"shasum":"34123e29939bb6824aab2c924e8146b831eb57d5","tarball":"https://registry.npmjs.org/loro-protocol/-/loro-protocol-0.2.0.tgz","fileCount":10,"integrity":"sha512-16FCgPj8A1ZCK8T97O9NWpZHbwJmPbq0WNhE+Nh0IDPxKRNYOi6XbPVfEsnnoe7gZW7X4OEdWERXm1O0W3vhwQ==","signatures":[{"sig":"MEQCIF9zo0/fZzhGx2e16+mka2IGwmTVEfNNMwYr7rjc3aMeAiBIqz4hC0BYGupHvShjK7yBctFy3hFwefwyBueDJhq3AQ==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/loro-protocol@0.2.0","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":142075},"main":"dist/index.cjs","type":"module","_from":"file:loro-protocol-0.2.0.tgz","types":"dist/index.d.ts","module":"dist/index.js","engines":{"node":">=18.0.0"},"exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js","require":"./dist/index.cjs"}},"private":false,"scripts":{"dev":"tsdown --watch","test":"vitest run","build":"tsdown","clean":"tsdown --clean","typecheck":"tsc -p tsconfig.json --noEmit"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:8816f56f-500c-48b2-80fd-07c36dd53d80"}},"_resolved":"/tmp/03ad92726e25e8023641cde373a4a9e4/loro-protocol-0.2.0.tgz","_integrity":"sha512-16FCgPj8A1ZCK8T97O9NWpZHbwJmPbq0WNhE+Nh0IDPxKRNYOi6XbPVfEsnnoe7gZW7X4OEdWERXm1O0W3vhwQ==","repository":{"url":"git+https://github.com/loro-dev/protocol.git","type":"git","directory":"packages/loro-protocol"},"_npmVersion":"11.6.2","description":"Compact binary wire protocol for collaborative CRDTs (Loro/Yjs), with encoders/decoders and bytes utilities","directories":{},"sideEffects":false,"_nodeVersion":"24.11.1","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"tsdown":"^0.14.1","vitest":"^3.2.4","typescript":"^5.9.2"},"_npmOperationalInternal":{"tmp":"tmp/loro-protocol_0.2.0_1763623761686_0.3415072822626122","host":"s3://npm-registry-packages-npm-production"}},"0.3.0":{"name":"loro-protocol","version":"0.3.0","private":false,"description":"Compact binary wire protocol for collaborative CRDTs (Loro/Yjs), with encoders/decoders and bytes utilities","author":{"name":"Loro Team"},"license":"MIT","type":"module","main":"dist/index.cjs","module":"dist/index.js","types":"dist/index.d.ts","keywords":["loro","crdt","protocol","encoding","decoding","binary","websocket","fragmentation","e2ee","aes-gcm","webcrypto","yjs","awareness"],"repository":{"type":"git","url":"git+https://github.com/loro-dev/protocol.git","directory":"packages/loro-protocol"},"bugs":{"url":"https://github.com/loro-dev/protocol/issues"},"homepage":"https://github.com/loro-dev/protocol/tree/main/packages/loro-protocol","sideEffects":false,"publishConfig":{"access":"public"},"engines":{"node":">=18.0.0"},"exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js","require":"./dist/index.cjs"}},"devDependencies":{"tsdown":"^0.14.1","typescript":"^5.9.2","vitest":"^3.2.4"},"scripts":{"build":"tsdown","dev":"tsdown --watch","test":"vitest run","typecheck":"tsc -p tsconfig.json --noEmit","clean":"tsdown --clean"},"_id":"loro-protocol@0.3.0","_integrity":"sha512-j28FzDwOVHk95asjQEk8yse7hfYHnStdusYcQBphWRwzA8wzE5iMHQpnDyog1O6kmJQ6W/iC8yDisHpxH0wUAg==","_resolved":"/tmp/3d2ea78d346057d46462df7a935b01de/loro-protocol-0.3.0.tgz","_from":"file:loro-protocol-0.3.0.tgz","_nodeVersion":"24.11.1","_npmVersion":"11.6.2","dist":{"integrity":"sha512-j28FzDwOVHk95asjQEk8yse7hfYHnStdusYcQBphWRwzA8wzE5iMHQpnDyog1O6kmJQ6W/iC8yDisHpxH0wUAg==","shasum":"fdc48efcfa02c5eb7655fcffb53a4a943a95e629","tarball":"https://registry.npmjs.org/loro-protocol/-/loro-protocol-0.3.0.tgz","fileCount":10,"unpackedSize":148910,"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/loro-protocol@0.3.0","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEYCIQCooh/HHcg6sZYbxWmOEG/VVv5mNQACK/UaMDmP2ga1iAIhAP34ueoWITtwWjLQqQ1L1kSykygPW7X7GcBTaSPTXPjJ"}]},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:8816f56f-500c-48b2-80fd-07c36dd53d80"}},"directories":{},"maintainers":[{"name":"rem2018","email":"remch183@outlook.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/loro-protocol_0.3.0_1765175119435_0.06043499211962877"},"_hasShrinkwrap":false}},"time":{"created":"2025-09-12T05:54:07.890Z","modified":"2025-12-08T06:25:19.903Z","0.1.0":"2025-09-12T05:54:08.189Z","0.1.1":"2025-10-23T09:20:57.506Z","0.1.2":"2025-10-30T09:47:33.923Z","0.1.3":"2025-11-05T14:28:03.456Z","0.2.0":"2025-11-20T07:29:21.887Z","0.3.0":"2025-12-08T06:25:19.564Z"},"bugs":{"url":"https://github.com/loro-dev/protocol/issues"},"author":{"name":"Loro Team"},"license":"MIT","homepage":"https://github.com/loro-dev/protocol/tree/main/packages/loro-protocol","keywords":["loro","crdt","protocol","encoding","decoding","binary","websocket","fragmentation","e2ee","aes-gcm","webcrypto","yjs","awareness"],"repository":{"type":"git","url":"git+https://github.com/loro-dev/protocol.git","directory":"packages/loro-protocol"},"description":"Compact binary wire protocol for collaborative CRDTs (Loro/Yjs), with encoders/decoders and bytes utilities","maintainers":[{"name":"rem2018","email":"remch183@outlook.com"}],"readme":"# loro-protocol\n\nBinary wire protocol for Loro CRDTs (TypeScript). Provides compact encoders/decoders for all protocol messages, bytes utilities, and helpers for the %ELO end-to-end encrypted flow (AES‑GCM with 12‑byte IV and exact-header AAD).\n\n## Install\n\n```bash\npnpm add loro-protocol\n```\n\n## Features\n\n- Message encoding/decoding for Join/DocUpdate/Fragments/Errors/Leave\n- 256 KiB message size guard with fragmentation support at higher layers\n- Bytes helpers (`BytesWriter`, `BytesReader`) with varUint/varBytes/varString\n- %ELO helpers: container codec, record header parsing, AES‑GCM encrypt/decrypt\n\nSee `protocol.md` and `protocol-e2ee.md` at the repo root for the ground‑truth spec.\n\n## Usage\n\nEncode and decode messages:\n\n```ts\nimport { encode, decode, CrdtType, MessageType } from \"loro-protocol\";\n\nconst join = encode({\n  type: MessageType.JoinRequest,\n  crdt: CrdtType.Loro,\n  roomId: \"room-1\",\n  auth: new Uint8Array(), // join metadata (auth/session tokens, etc.)\n  version: new Uint8Array(),\n});\n\nconst msg = decode(join);\nconsole.log(msg.type); // 0x00 JoinRequest\n```\n\n%ELO encrypted records (AES‑GCM):\n\n```ts\nimport {\n  EloRecordKind,\n  encryptSnapshot,\n  encryptDeltaSpan,\n  decryptEloRecord,\n  encodeEloContainer,\n  decodeEloContainer,\n  parseEloRecordHeader,\n} from \"loro-protocol\";\n\n// Encrypt a snapshot\nconst key = crypto.getRandomValues(new Uint8Array(32));\nconst plaintext = new Uint8Array([1, 2, 3]);\nconst { record } = await encryptSnapshot(plaintext, { vv: [], keyId: \"k1\" }, key);\nconst container = encodeEloContainer([record]);\n\n// Later, parse and decrypt\nconst [rec] = decodeEloContainer(container);\nconst parsed = parseEloRecordHeader(rec);\nconst out = await decryptEloRecord(rec, async () => key);\nconsole.log(parsed.kind === EloRecordKind.Snapshot, out.plaintext);\n```\n\nNotes\n- The server can parse %ELO headers to index/backfill but never decrypts `ct`.\n- IV must be exactly 12 bytes and unique per key; AAD is the exact encoded header.\n\n## API Surface\n\n- Encoding/decoding: `encode(msg)`, `decode(buf)`, `tryDecode(buf)`\n- Bytes: `BytesWriter`, `BytesReader`\n- %ELO: `encodeEloContainer`, `decodeEloContainer`, `parseEloRecordHeader`, `encryptSnapshot`, `encryptDeltaSpan`, `decryptEloRecord`\n\n## Node/Web Compatibility\n\n%ELO crypto uses Web Crypto (`globalThis.crypto.subtle`). Node 18+ provides it via `globalThis.crypto`.\n\n## License\n\nMIT\n","readmeFilename":"README.md"}