{"_id":"@backloghq/opslog","_rev":"16-e61855768a5a30abcf0e981caab4b48f","name":"@backloghq/opslog","dist-tags":{"latest":"0.8.1"},"versions":{"0.1.0":{"name":"@backloghq/opslog","version":"0.1.0","keywords":["event-sourcing","append-only","wal","document-store","embedded","jsonl","snapshots"],"author":{"name":"mbocevski"},"license":"MIT","_id":"@backloghq/opslog@0.1.0","maintainers":[{"name":"fenrirbaest","email":"marko.bocevski@gmail.com"}],"dist":{"shasum":"569b47391fa3ca98dea6bbf81eae3bea1c759d1c","tarball":"https://registry.npmjs.org/@backloghq/opslog/-/opslog-0.1.0.tgz","fileCount":17,"integrity":"sha512-1uFsGusGJU0V0ZDAn/i5oc0+ks6njoJxZQ1lvmNt6M+VP4yLVWRDq5mtaV7pUVSd0XfS8zsa9gkzjnt9tQMaDQ==","signatures":[{"sig":"MEUCIQC6HnlVHiRiJOWyQEMNd18rYgqQpmv6xDaV4++uozrT2AIgA8IAPOHt3ImEE0phdyK5GiZGesb+RX7PRAJgXN3F/4o=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":24891},"main":"dist/index.js","type":"module","types":"dist/index.d.ts","engines":{"node":">=20"},"gitHead":"fbbbbc8784b45cbec2067081f30d161349ee9e02","scripts":{"dev":"tsc --watch","lint":"eslint src/ tests/","test":"vitest run","build":"tsc","test:watch":"vitest","test:coverage":"vitest run --coverage"},"_npmUser":{"name":"fenrirbaest","email":"marko.bocevski@gmail.com"},"_npmVersion":"11.12.1","description":"Embedded event-sourced document store. Append-only operation log with immutable snapshots, zero native dependencies.","directories":{},"_nodeVersion":"25.9.0","_hasShrinkwrap":false,"devDependencies":{"eslint":"*","vitest":"*","@eslint/js":"*","typescript":"*","@types/node":"*","typescript-eslint":"*","@vitest/coverage-v8":"^4.1.2"},"_npmOperationalInternal":{"tmp":"tmp/opslog_0.1.0_1775506892389_0.7600556802978289","host":"s3://npm-registry-packages-npm-production"}},"0.1.1":{"name":"@backloghq/opslog","version":"0.1.1","keywords":["event-sourcing","append-only","wal","document-store","embedded","jsonl","snapshots"],"author":{"name":"mbocevski"},"license":"MIT","_id":"@backloghq/opslog@0.1.1","maintainers":[{"name":"fenrirbaest","email":"marko.bocevski@gmail.com"}],"dist":{"shasum":"306a8b85831b6822f29a74c5fdadb29fcc02fb6e","tarball":"https://registry.npmjs.org/@backloghq/opslog/-/opslog-0.1.1.tgz","fileCount":19,"integrity":"sha512-0Kvuq7KqdNO52lf2yudMwksgnpLbLsUpbHGYBKYtIi3zmUXqWd4j3X+RxGgiBhavSiovSdisFTBIynDK8sbprg==","signatures":[{"sig":"MEQCIAr7riqtMTnkSA6xAXly/gCvsj1JnTfILIxW2hVztMWJAiAwd84/FacOPrOOoY6pOR63xe1yMay1H09/VFBJCXJE8A==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":28642},"main":"dist/index.js","type":"module","types":"dist/index.d.ts","engines":{"node":">=20"},"gitHead":"0259d2df1183870d2cc87dc5c460293ac28e202b","scripts":{"dev":"tsc --watch","lint":"eslint src/ tests/","test":"vitest run","build":"tsc","test:watch":"vitest","test:coverage":"vitest run --coverage"},"_npmUser":{"name":"fenrirbaest","email":"marko.bocevski@gmail.com"},"_npmVersion":"11.12.1","description":"Embedded event-sourced document store. Append-only operation log with immutable snapshots, zero native dependencies.","directories":{},"_nodeVersion":"25.9.0","_hasShrinkwrap":false,"devDependencies":{"eslint":"^10.0.0","vitest":"^4.1.2","@eslint/js":"^10.0.0","typescript":"~6.0.2","@types/node":"^25.0.0","typescript-eslint":"^8.58.0","@vitest/coverage-v8":"^4.1.2"},"_npmOperationalInternal":{"tmp":"tmp/opslog_0.1.1_1775517616490_0.9153780085574246","host":"s3://npm-registry-packages-npm-production"}},"0.1.2":{"name":"@backloghq/opslog","version":"0.1.2","keywords":["event-sourcing","append-only","wal","document-store","embedded","jsonl","snapshots"],"author":{"name":"mbocevski"},"license":"MIT","_id":"@backloghq/opslog@0.1.2","maintainers":[{"name":"fenrirbaest","email":"marko.bocevski@gmail.com"}],"dist":{"shasum":"9f06562c5686b2bbb635f8367631c004ce835997","tarball":"https://registry.npmjs.org/@backloghq/opslog/-/opslog-0.1.2.tgz","fileCount":19,"integrity":"sha512-8fpeUQzBtJkKpxqxJTkSJ7AUwZNFDi5IzLp/5pb9r03hcJS597crb+42ckbXbW/h/1yxDoLZKUQRCNS+9vywKg==","signatures":[{"sig":"MEYCIQCsnVjMLBt3EOeHkqXrn6RFHpQtRDUrd+Ac0xDbgHZ2GgIhAJ96hucKbWOH0SG6q+EVsKhWhZJWG12Rq/VaSQTr89vg","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":29852},"main":"dist/index.js","type":"module","types":"dist/index.d.ts","engines":{"node":">=20"},"gitHead":"9ed0b0d301c467aea39f5c135795f47b792e68da","scripts":{"dev":"tsc --watch","lint":"eslint src/ tests/","test":"vitest run","build":"tsc","test:watch":"vitest","test:coverage":"vitest run --coverage"},"_npmUser":{"name":"fenrirbaest","email":"marko.bocevski@gmail.com"},"_npmVersion":"11.12.1","description":"Embedded event-sourced document store. Append-only operation log with immutable snapshots, zero native dependencies.","directories":{},"_nodeVersion":"25.9.0","_hasShrinkwrap":false,"devDependencies":{"eslint":"^10.0.0","vitest":"^4.1.2","@eslint/js":"^10.0.0","typescript":"~6.0.2","@types/node":"^25.0.0","typescript-eslint":"^8.58.0","@vitest/coverage-v8":"^4.1.2"},"_npmOperationalInternal":{"tmp":"tmp/opslog_0.1.2_1775519053102_0.10983896001825855","host":"s3://npm-registry-packages-npm-production"}},"0.1.3":{"name":"@backloghq/opslog","version":"0.1.3","keywords":["event-sourcing","append-only","wal","document-store","embedded","jsonl","snapshots"],"author":{"name":"mbocevski"},"license":"MIT","_id":"@backloghq/opslog@0.1.3","maintainers":[{"name":"fenrirbaest","email":"marko.bocevski@gmail.com"}],"dist":{"shasum":"967d271277e97734c773ebbc1877c95d8463b430","tarball":"https://registry.npmjs.org/@backloghq/opslog/-/opslog-0.1.3.tgz","fileCount":19,"integrity":"sha512-XtUDeDi1/zNtj62ylcJIj9IJbbR4zGBIhQNgY28/K2ergrwDpKA0GB/PjF0iqnaC7/OPosxwpGkfDLSAwHLELg==","signatures":[{"sig":"MEUCIA25so7hdTV4ob6WEWeMAxiQ+2VlT8NBozoewO4mh0b7AiEAyFJkC2/jYrFduO1bykWlxZ6YLSqveJiEMoTTbrR28xA=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":30830},"main":"dist/index.js","type":"module","types":"dist/index.d.ts","engines":{"node":">=20"},"gitHead":"6a5418e6fb7a14c2a673e7fc3f96dad98199e76d","scripts":{"dev":"tsc --watch","lint":"eslint src/ tests/","test":"vitest run","build":"tsc","test:watch":"vitest","test:coverage":"vitest run --coverage"},"_npmUser":{"name":"fenrirbaest","email":"marko.bocevski@gmail.com"},"_npmVersion":"11.12.1","description":"Embedded event-sourced document store. Append-only operation log with immutable snapshots, zero native dependencies.","directories":{},"_nodeVersion":"25.9.0","_hasShrinkwrap":false,"devDependencies":{"eslint":"^10.0.0","vitest":"^4.1.2","@eslint/js":"^10.0.0","typescript":"~6.0.2","@types/node":"^25.0.0","typescript-eslint":"^8.58.0","@vitest/coverage-v8":"^4.1.2"},"_npmOperationalInternal":{"tmp":"tmp/opslog_0.1.3_1775550798091_0.8017039006012476","host":"s3://npm-registry-packages-npm-production"}},"0.1.4":{"name":"@backloghq/opslog","version":"0.1.4","keywords":["event-sourcing","append-only","wal","document-store","embedded","jsonl","snapshots"],"author":{"name":"mbocevski"},"license":"MIT","_id":"@backloghq/opslog@0.1.4","maintainers":[{"name":"fenrirbaest","email":"marko.bocevski@gmail.com"}],"dist":{"shasum":"7546ac71058584f6c26e0375b747b015dfbdb3fa","tarball":"https://registry.npmjs.org/@backloghq/opslog/-/opslog-0.1.4.tgz","fileCount":19,"integrity":"sha512-zkPpPFplNChSyH/e0e4NbbwPQiJfIcClohCarTypewzh9NpNPKW6eGHwQUGikJGhqZ2of9vtEJkuzDjj78qwhQ==","signatures":[{"sig":"MEYCIQDo3AE6pMwA/RwyLby8DymhaxPXtCnyJxHsEtZxb2qE+QIhAN2ZNpdd7OdmupfhsowYh+/Ia9ftzbeAQZCp6+mUlWtA","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":32700},"main":"dist/index.js","type":"module","types":"dist/index.d.ts","engines":{"node":">=20"},"gitHead":"5366625762a3673c744dc47aea9896f41122589f","scripts":{"dev":"tsc --watch","lint":"eslint src/ tests/","test":"vitest run","build":"tsc","test:watch":"vitest","test:coverage":"vitest run --coverage"},"_npmUser":{"name":"fenrirbaest","email":"marko.bocevski@gmail.com"},"_npmVersion":"11.12.1","description":"Embedded event-sourced document store. Append-only operation log with immutable snapshots, zero native dependencies.","directories":{},"_nodeVersion":"25.9.0","_hasShrinkwrap":false,"devDependencies":{"eslint":"^10.0.0","vitest":"^4.1.2","@eslint/js":"^10.0.0","typescript":"~6.0.2","@types/node":"^25.0.0","typescript-eslint":"^8.58.0","@vitest/coverage-v8":"^4.1.2"},"_npmOperationalInternal":{"tmp":"tmp/opslog_0.1.4_1775553988977_0.3454220804034327","host":"s3://npm-registry-packages-npm-production"}},"0.2.0":{"name":"@backloghq/opslog","version":"0.2.0","keywords":["event-sourcing","append-only","wal","document-store","embedded","jsonl","snapshots"],"author":{"name":"mbocevski"},"license":"MIT","_id":"@backloghq/opslog@0.2.0","maintainers":[{"name":"fenrirbaest","email":"marko.bocevski@gmail.com"}],"dist":{"shasum":"b1c78c394e20039452a2e18e199d1898c908c4ec","tarball":"https://registry.npmjs.org/@backloghq/opslog/-/opslog-0.2.0.tgz","fileCount":21,"integrity":"sha512-CYEazqIpwY4RT3zaHckJ0HD9wGHOnf+Z8qkijQzRplf1LR4vUBRsvhli7FAjpqNusxbEQO+pVXyhdB4jtqqlpA==","signatures":[{"sig":"MEMCIBrgEuCXGRrvBo1PrWbjYDnEVk2YNDW1ibJhKdfyCVotAh923Ws2xL3Oy5Cc9wUfxwNzc2+0bWuqIKWg5sLbjBHa","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":41094},"main":"dist/index.js","type":"module","types":"dist/index.d.ts","engines":{"node":">=20"},"gitHead":"a7366140d0d5b909f61f4123a1056d7f42ba5f16","scripts":{"dev":"tsc --watch","lint":"eslint src/ tests/","test":"vitest run","build":"tsc","test:watch":"vitest","test:coverage":"vitest run --coverage"},"_npmUser":{"name":"fenrirbaest","email":"marko.bocevski@gmail.com"},"_npmVersion":"11.12.1","description":"Embedded event-sourced document store. Append-only operation log with immutable snapshots, zero native dependencies.","directories":{},"_nodeVersion":"25.9.0","_hasShrinkwrap":false,"devDependencies":{"eslint":"^10.0.0","vitest":"^4.1.2","@eslint/js":"^10.0.0","typescript":"~6.0.2","@types/node":"^25.0.0","typescript-eslint":"^8.58.0","@vitest/coverage-v8":"^4.1.2"},"_npmOperationalInternal":{"tmp":"tmp/opslog_0.2.0_1775751885790_0.06491037877838668","host":"s3://npm-registry-packages-npm-production"}},"0.3.0":{"name":"@backloghq/opslog","version":"0.3.0","keywords":["event-sourcing","append-only","wal","document-store","embedded","jsonl","snapshots"],"author":{"name":"mbocevski"},"license":"MIT","_id":"@backloghq/opslog@0.3.0","maintainers":[{"name":"fenrirbaest","email":"marko.bocevski@gmail.com"}],"dist":{"shasum":"2c0c075474acc207a1adc1a3740e052e485bc18e","tarball":"https://registry.npmjs.org/@backloghq/opslog/-/opslog-0.3.0.tgz","fileCount":25,"integrity":"sha512-QkEl+Kv+oeSspOhlvaXXW6d5tV1jCzpdPEfwKsC08rTzXIYN8qUHvUnPZIdOcnviBROnKEk3Y4yvqQFuN8Godw==","signatures":[{"sig":"MEUCIA7dSG0RKf2wfOMIhZ8iNrT2H91q1diJk+C4MCl0IX4SAiEA23F5JUK1kmbOW9cy85UZzo0Ha/PHqNgNFiqm9x+Jjzc=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":62102},"main":"dist/index.js","type":"module","types":"dist/index.d.ts","engines":{"node":">=20"},"gitHead":"f4cf05b93e8cc5469736b9acebf2b27cb446355e","scripts":{"dev":"tsc --watch","lint":"eslint src/ tests/","test":"vitest run","build":"tsc","test:watch":"vitest","test:coverage":"vitest run --coverage"},"_npmUser":{"name":"fenrirbaest","email":"marko.bocevski@gmail.com"},"_npmVersion":"11.12.1","description":"Embedded event-sourced document store. Append-only operation log with immutable snapshots, zero native dependencies.","directories":{},"_nodeVersion":"25.9.0","_hasShrinkwrap":false,"devDependencies":{"eslint":"^10.0.0","vitest":"^4.1.2","@eslint/js":"^10.0.0","typescript":"~6.0.2","@types/node":"^25.0.0","typescript-eslint":"^8.58.0","@vitest/coverage-v8":"^4.1.2"},"_npmOperationalInternal":{"tmp":"tmp/opslog_0.3.0_1775757145467_0.3961416128443478","host":"s3://npm-registry-packages-npm-production"}},"0.4.0":{"name":"@backloghq/opslog","version":"0.4.0","keywords":["event-sourcing","append-only","wal","document-store","embedded","jsonl","snapshots"],"author":{"name":"mbocevski"},"license":"MIT","_id":"@backloghq/opslog@0.4.0","maintainers":[{"name":"fenrirbaest","email":"marko.bocevski@gmail.com"}],"dist":{"shasum":"83c77624bc0b9a3961b12bc9966b677527188a71","tarball":"https://registry.npmjs.org/@backloghq/opslog/-/opslog-0.4.0.tgz","fileCount":27,"integrity":"sha512-mpmCP4JAwEvf1drspUnRmwk0VjaNStGtn6MzzyXg+6oIFrHZfqmb7DE4kvLV5HG2UgdyXiOEWWm6/3i9tbOcUg==","signatures":[{"sig":"MEYCIQD29PZBTsQHC5aWpQdS1jYx3EiepG77JJcVI1PF7jN9iQIhAJFRb4HH0FovzNJDG8tPQcsB7ttvZ5XZ/fCNaFVoLjcc","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":69707},"main":"dist/index.js","type":"module","types":"dist/index.d.ts","engines":{"node":">=20"},"gitHead":"f3282bb26c25830de5209d6f80587fc1407f11ab","scripts":{"dev":"tsc --watch","lint":"eslint src/ tests/","test":"vitest run","build":"tsc","test:watch":"vitest","test:coverage":"vitest run --coverage"},"_npmUser":{"name":"fenrirbaest","email":"marko.bocevski@gmail.com"},"_npmVersion":"11.12.1","description":"Embedded event-sourced document store. Append-only operation log with immutable snapshots, zero native dependencies.","directories":{},"_nodeVersion":"25.9.0","_hasShrinkwrap":false,"devDependencies":{"eslint":"^10.0.0","vitest":"^4.1.2","@eslint/js":"^10.0.0","typescript":"~6.0.2","@types/node":"^25.0.0","typescript-eslint":"^8.58.0","@vitest/coverage-v8":"^4.1.2"},"_npmOperationalInternal":{"tmp":"tmp/opslog_0.4.0_1775759027673_0.5541256210322796","host":"s3://npm-registry-packages-npm-production"}},"0.4.1":{"name":"@backloghq/opslog","version":"0.4.1","keywords":["event-sourcing","append-only","wal","document-store","embedded","jsonl","snapshots"],"author":{"name":"mbocevski"},"license":"MIT","_id":"@backloghq/opslog@0.4.1","maintainers":[{"name":"fenrirbaest","email":"marko.bocevski@gmail.com"}],"dist":{"shasum":"0ba9cf07013892a2d6d52b52a05daf822e10f7c5","tarball":"https://registry.npmjs.org/@backloghq/opslog/-/opslog-0.4.1.tgz","fileCount":27,"integrity":"sha512-suj8BJBqLXhqozDTTTq+O7Pmue2UUUh3xWNfVG29pQ3eyNgz+AjlRDUmvbKjqwfKXAaCQY94N/vFf0qDlBpHCw==","signatures":[{"sig":"MEYCIQDDct6rwCbNQtDY2AdOTxmqw0UK5ZWPu1hEWW3k9mMM+AIhALD7/DJk6izFb6ukeVc0WkhODNd7TJI59pOFbHaOMqIw","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":70250},"main":"dist/index.js","type":"module","types":"dist/index.d.ts","engines":{"node":">=20"},"gitHead":"0ecd3eb5d9664a95c945b9661b1cdcd55d34ade6","scripts":{"dev":"tsc --watch","lint":"eslint src/ tests/","test":"vitest run","build":"tsc","test:watch":"vitest","test:coverage":"vitest run --coverage"},"_npmUser":{"name":"fenrirbaest","email":"marko.bocevski@gmail.com"},"_npmVersion":"11.12.1","description":"Embedded event-sourced document store. Append-only operation log with immutable snapshots, zero native dependencies.","directories":{},"_nodeVersion":"25.9.0","_hasShrinkwrap":false,"devDependencies":{"eslint":"^10.0.0","vitest":"^4.1.2","@eslint/js":"^10.0.0","typescript":"~6.0.2","@types/node":"^25.0.0","typescript-eslint":"^8.58.0","@vitest/coverage-v8":"^4.1.2"},"_npmOperationalInternal":{"tmp":"tmp/opslog_0.4.1_1775761841161_0.13418955025915658","host":"s3://npm-registry-packages-npm-production"}},"0.5.0":{"name":"@backloghq/opslog","version":"0.5.0","keywords":["event-sourcing","append-only","wal","document-store","embedded","jsonl","snapshots"],"author":{"name":"mbocevski"},"license":"MIT","_id":"@backloghq/opslog@0.5.0","maintainers":[{"name":"fenrirbaest","email":"marko.bocevski@gmail.com"}],"dist":{"shasum":"b97b210ee1214bdc4d6fd64ed346c4789f470842","tarball":"https://registry.npmjs.org/@backloghq/opslog/-/opslog-0.5.0.tgz","fileCount":27,"integrity":"sha512-nt7KFMwr3HUJnIOOIt0meGq+xh2VkBALNlVIHUL77UGAujOEFhOBVKFcLQCim157/3XVReWQeW3H9W6G4cjXug==","signatures":[{"sig":"MEUCIQC5yEkwyBwbBBfllWQgRvsIpg2OBiVZKum+clT0GJCsPAIgWnc3S+XbxRlWyVd2vAFnpnvnwSn8hlm+ul0YKWiOTEs=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":74426},"main":"dist/index.js","type":"module","types":"dist/index.d.ts","engines":{"node":">=20"},"gitHead":"410c59305244600e907b6cd0431049dcdfdcbc0d","scripts":{"dev":"tsc --watch","lint":"eslint src/ tests/","test":"vitest run","build":"tsc","test:watch":"vitest","test:coverage":"vitest run --coverage"},"_npmUser":{"name":"fenrirbaest","email":"marko.bocevski@gmail.com"},"_npmVersion":"11.12.1","description":"Embedded event-sourced document store. Append-only operation log with immutable snapshots, zero native dependencies.","directories":{},"_nodeVersion":"25.9.0","_hasShrinkwrap":false,"devDependencies":{"eslint":"^10.0.0","vitest":"^4.1.2","@eslint/js":"^10.0.0","typescript":"~6.0.2","@types/node":"^25.0.0","typescript-eslint":"^8.58.0","@vitest/coverage-v8":"^4.1.2"},"_npmOperationalInternal":{"tmp":"tmp/opslog_0.5.0_1775767292277_0.649638434545952","host":"s3://npm-registry-packages-npm-production"}},"0.5.1":{"name":"@backloghq/opslog","version":"0.5.1","keywords":["event-sourcing","append-only","wal","document-store","embedded","jsonl","snapshots"],"author":{"name":"mbocevski"},"license":"MIT","_id":"@backloghq/opslog@0.5.1","maintainers":[{"name":"fenrirbaest","email":"marko.bocevski@gmail.com"}],"dist":{"shasum":"84496401df4ab1f5413b5607d7c11fd53f6b93b6","tarball":"https://registry.npmjs.org/@backloghq/opslog/-/opslog-0.5.1.tgz","fileCount":27,"integrity":"sha512-liY296vHQiVR0xYdV7MAXIwIRpQzp/+rbHH9EZ85pRhFFpbd1ixIphxpvRoAoYFcFEwTFZIlDEE9bKTFVhpi6g==","signatures":[{"sig":"MEYCIQCz978MD6ti9kyjUPHrzaWm5LCqkXbShECBAot9SOsSkgIhAOn02O5eGxsD2+fP71QpQWSZV96XSE0PFcMuYcOQt5BQ","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":76760},"main":"dist/index.js","type":"module","types":"dist/index.d.ts","engines":{"node":">=20"},"gitHead":"97653ffc02a1df82583d9f6579251f6b0baecd8e","scripts":{"dev":"tsc --watch","lint":"eslint src/ tests/","test":"vitest run","build":"tsc","test:watch":"vitest","test:coverage":"vitest run --coverage"},"_npmUser":{"name":"fenrirbaest","email":"marko.bocevski@gmail.com"},"_npmVersion":"11.12.1","description":"Embedded event-sourced document store. Append-only operation log with immutable snapshots, zero native dependencies.","directories":{},"_nodeVersion":"25.9.0","_hasShrinkwrap":false,"devDependencies":{"eslint":"^10.0.0","vitest":"^4.1.2","@eslint/js":"^10.0.0","typescript":"~6.0.2","@types/node":"^25.0.0","typescript-eslint":"^8.58.0","@vitest/coverage-v8":"^4.1.2"},"_npmOperationalInternal":{"tmp":"tmp/opslog_0.5.1_1775771957610_0.9148596090781764","host":"s3://npm-registry-packages-npm-production"}},"0.6.0":{"name":"@backloghq/opslog","version":"0.6.0","keywords":["event-sourcing","append-only","wal","document-store","embedded","jsonl","snapshots"],"author":{"name":"mbocevski"},"license":"MIT","_id":"@backloghq/opslog@0.6.0","maintainers":[{"name":"fenrirbaest","email":"marko.bocevski@gmail.com"}],"dist":{"shasum":"56e71bfb1a99506382c983819b5bbace3be29988","tarball":"https://registry.npmjs.org/@backloghq/opslog/-/opslog-0.6.0.tgz","fileCount":27,"integrity":"sha512-ldG5tCt3cAdWH7XhbeucQPw6gQcXhMkW1j26xQDqTD1U9hFmPPOcEs5Z5fSB8Y2ujV75fds+TDrYWXiOqdIrcQ==","signatures":[{"sig":"MEQCIEYtxYsbdtmZsHCJ/YCKK6CwQ+Xq23EnWjCj9QXan8V6AiBVdViI5W9lrda9kampSrc5WpbpGKOwowwCMclF7NnsvQ==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":78376},"main":"dist/index.js","type":"module","types":"dist/index.d.ts","engines":{"node":">=22"},"gitHead":"fc4b726f6a7057f0e8d0395fb20601270b57d1e3","scripts":{"dev":"tsc --watch","lint":"eslint src/ tests/","test":"vitest run","build":"tsc","test:watch":"vitest","test:coverage":"vitest run --coverage"},"_npmUser":{"name":"fenrirbaest","email":"marko.bocevski@gmail.com"},"_npmVersion":"11.12.1","description":"Embedded event-sourced document store. Append-only operation log with immutable snapshots, zero native dependencies.","directories":{},"_nodeVersion":"25.9.0","_hasShrinkwrap":false,"devDependencies":{"eslint":"^10.0.0","vitest":"^4.1.2","@eslint/js":"^10.0.0","typescript":"~6.0.2","@types/node":"^25.0.0","typescript-eslint":"^8.58.0","@vitest/coverage-v8":"^4.1.2"},"_npmOperationalInternal":{"tmp":"tmp/opslog_0.6.0_1775835932409_0.3794790991560153","host":"s3://npm-registry-packages-npm-production"}},"0.7.0":{"name":"@backloghq/opslog","version":"0.7.0","keywords":["event-sourcing","append-only","wal","document-store","embedded","jsonl","snapshots"],"author":{"name":"mbocevski"},"license":"MIT","_id":"@backloghq/opslog@0.7.0","maintainers":[{"name":"fenrirbaest","email":"marko.bocevski@gmail.com"}],"dist":{"shasum":"6c1fb7fdf4a44e65c701f764708c55d04ab757bd","tarball":"https://registry.npmjs.org/@backloghq/opslog/-/opslog-0.7.0.tgz","fileCount":27,"integrity":"sha512-P7o9vwGWXGZJmQE6t7fMqFX2d3NQzksDHzDEPDLgdlP2aa4GkSP1uP+P9aAPhTXmOU6GXieJKlx0vTbX9fS0DQ==","signatures":[{"sig":"MEUCIBaPhKH2TYZwrn/zBXnbDAxSyEurQsz0zmDfxoiVHrCVAiEAlAvbP/9v32IlIAPFF4JGoIeAorNc3qdUh1lO3DRjvY0=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":87091},"main":"dist/index.js","type":"module","types":"dist/index.d.ts","engines":{"node":">=22"},"gitHead":"a7f0cd6f09bcee52c10b2c4dfd67bbd7f50ce375","scripts":{"dev":"tsc --watch","lint":"eslint src/ tests/","test":"vitest run","build":"tsc","test:watch":"vitest","test:coverage":"vitest run --coverage"},"_npmUser":{"name":"fenrirbaest","email":"marko.bocevski@gmail.com"},"_npmVersion":"11.12.1","description":"Embedded event-sourced document store. Append-only operation log with immutable snapshots, zero native dependencies.","directories":{},"_nodeVersion":"25.9.0","_hasShrinkwrap":false,"devDependencies":{"eslint":"^10.0.0","vitest":"^4.1.2","@eslint/js":"^10.0.0","typescript":"~6.0.2","@types/node":"^25.0.0","typescript-eslint":"^8.58.0","@vitest/coverage-v8":"^4.1.2"},"_npmOperationalInternal":{"tmp":"tmp/opslog_0.7.0_1775907922713_0.35078795936625906","host":"s3://npm-registry-packages-npm-production"}},"0.7.1":{"name":"@backloghq/opslog","version":"0.7.1","keywords":["event-sourcing","append-only","wal","document-store","embedded","jsonl","snapshots"],"author":{"name":"mbocevski"},"license":"MIT","_id":"@backloghq/opslog@0.7.1","maintainers":[{"name":"fenrirbaest","email":"marko.bocevski@gmail.com"}],"dist":{"shasum":"db036fcc896b42d6b2b0119d5573303156992b83","tarball":"https://registry.npmjs.org/@backloghq/opslog/-/opslog-0.7.1.tgz","fileCount":27,"integrity":"sha512-wFJxJ5wARrTpN63Ox3P9Yu72Vmab9x7vl739SrJg+GolniaQ3nUMnZSPZijymqT7bXXbIMlGljBQ/TB+4p1d2g==","signatures":[{"sig":"MEQCIENhi8xbYB7fGI/9+CPkMs5nRre7+mmek9ktqoTyXte/AiBIr/TwSleNMLrdEebLd9cmqdLDXFiQq3ABYpTZsXH+VQ==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":87288},"main":"dist/index.js","type":"module","types":"dist/index.d.ts","engines":{"node":">=22"},"gitHead":"869125d35dfbc4c99b6ab20498bd502dd1bd1ad2","scripts":{"dev":"tsc --watch","lint":"eslint src/ tests/","test":"vitest run","build":"tsc","test:watch":"vitest","test:coverage":"vitest run --coverage"},"_npmUser":{"name":"fenrirbaest","email":"marko.bocevski@gmail.com"},"_npmVersion":"11.12.1","description":"Embedded event-sourced document store. Append-only operation log with immutable snapshots, zero native dependencies.","directories":{},"_nodeVersion":"25.9.0","_hasShrinkwrap":false,"devDependencies":{"eslint":"^10.0.0","vitest":"^4.1.2","@eslint/js":"^10.0.0","typescript":"~6.0.2","@types/node":"^25.0.0","typescript-eslint":"^8.58.0","@vitest/coverage-v8":"^4.1.2"},"_npmOperationalInternal":{"tmp":"tmp/opslog_0.7.1_1775919437325_0.35709048580551617","host":"s3://npm-registry-packages-npm-production"}},"0.8.0":{"name":"@backloghq/opslog","version":"0.8.0","keywords":["event-sourcing","append-only","wal","document-store","embedded","jsonl","snapshots"],"author":{"name":"mbocevski"},"license":"MIT","_id":"@backloghq/opslog@0.8.0","maintainers":[{"name":"fenrirbaest","email":"marko.bocevski@gmail.com"}],"dist":{"shasum":"3a189fcf3edd0bb10e8e07c9f6bd22badf8f06da","tarball":"https://registry.npmjs.org/@backloghq/opslog/-/opslog-0.8.0.tgz","fileCount":27,"integrity":"sha512-m34H/cA6v1oU8XFmuCB4D8YHZtLPO2PgTCEDtmQD3SZJC2BFWWHSo06AbJ694ExMSVD4/svpwNNLc44V5iT17Q==","signatures":[{"sig":"MEUCIC1R5xJBt6P2njYE+fpCNbAWLMlhMtdSSepRfKUGKPIPAiEA4BO59znwukkgKHhUjZjbQN7eFhjmDBEl+P6jaW7LvzI=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":88783},"main":"dist/index.js","type":"module","types":"dist/index.d.ts","engines":{"node":">=22"},"gitHead":"8eeaf7a9073f60000ec64571f56311464e959162","scripts":{"dev":"tsc --watch","lint":"eslint src/ tests/","test":"vitest run","build":"tsc","test:watch":"vitest","test:coverage":"vitest run --coverage"},"_npmUser":{"name":"fenrirbaest","email":"marko.bocevski@gmail.com"},"_npmVersion":"11.12.1","description":"Embedded event-sourced document store. Append-only operation log with immutable snapshots, zero native dependencies.","directories":{},"_nodeVersion":"25.9.0","_hasShrinkwrap":false,"devDependencies":{"eslint":"^10.0.0","vitest":"^4.1.2","@eslint/js":"^10.0.0","typescript":"~6.0.2","@types/node":"^25.0.0","typescript-eslint":"^8.58.0","@vitest/coverage-v8":"^4.1.2"},"_npmOperationalInternal":{"tmp":"tmp/opslog_0.8.0_1775921408435_0.1983152844669651","host":"s3://npm-registry-packages-npm-production"}},"0.8.1":{"name":"@backloghq/opslog","version":"0.8.1","description":"Embedded event-sourced document store. Append-only operation log with immutable snapshots, zero native dependencies.","main":"dist/index.js","types":"dist/index.d.ts","scripts":{"build":"tsc","dev":"tsc --watch","lint":"eslint src/ tests/","test":"vitest run","test:watch":"vitest","test:coverage":"vitest run --coverage"},"keywords":["event-sourcing","append-only","wal","document-store","embedded","jsonl","snapshots"],"author":{"name":"mbocevski"},"license":"MIT","type":"module","engines":{"node":">=22"},"devDependencies":{"@eslint/js":"^10.0.0","@types/node":"^25.0.0","@vitest/coverage-v8":"^4.1.2","eslint":"^10.0.0","typescript":"~6.0.2","typescript-eslint":"^8.58.0","vitest":"^4.1.2"},"gitHead":"f7190cf329ab893abe3b79191e2a6d17e5716fdf","_id":"@backloghq/opslog@0.8.1","_nodeVersion":"25.9.0","_npmVersion":"11.12.1","dist":{"integrity":"sha512-Y+hZRaL4M7DnRA1wmMEcOJ0j5fVwJHjw5qm5zvYsMYpXORwdXOwAR5DyU41bm+RqSqsuT5E4jtYEk14GOHzP3Q==","shasum":"2e45f2d363403a1e6c8a38d3eca1f234f391b97a","tarball":"https://registry.npmjs.org/@backloghq/opslog/-/opslog-0.8.1.tgz","fileCount":27,"unpackedSize":89341,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEQCIHXY9LZcMui0j40olt6vLaIeTL71AiviEO+DkmC0iZMKAiB32UT6+6uCH1DJyjfOwOphownlykqnm4lqlTfXiOjqsQ=="}]},"_npmUser":{"name":"fenrirbaest","email":"marko.bocevski@gmail.com"},"directories":{},"maintainers":[{"name":"fenrirbaest","email":"marko.bocevski@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/opslog_0.8.1_1775930077621_0.988001899574219"},"_hasShrinkwrap":false}},"time":{"created":"2026-04-06T20:21:32.299Z","modified":"2026-04-11T17:54:37.905Z","0.1.0":"2026-04-06T20:21:32.563Z","0.1.1":"2026-04-06T23:20:16.689Z","0.1.2":"2026-04-06T23:44:13.271Z","0.1.3":"2026-04-07T08:33:18.227Z","0.1.4":"2026-04-07T09:26:29.137Z","0.2.0":"2026-04-09T16:24:45.918Z","0.3.0":"2026-04-09T17:52:25.614Z","0.4.0":"2026-04-09T18:23:47.811Z","0.4.1":"2026-04-09T19:10:41.303Z","0.5.0":"2026-04-09T20:41:32.439Z","0.5.1":"2026-04-09T21:59:17.773Z","0.6.0":"2026-04-10T15:45:32.566Z","0.7.0":"2026-04-11T11:45:22.862Z","0.7.1":"2026-04-11T14:57:17.578Z","0.8.0":"2026-04-11T15:30:08.582Z","0.8.1":"2026-04-11T17:54:37.765Z"},"author":{"name":"mbocevski"},"license":"MIT","keywords":["event-sourcing","append-only","wal","document-store","embedded","jsonl","snapshots"],"description":"Embedded event-sourced document store. Append-only operation log with immutable snapshots, zero native dependencies.","maintainers":[{"name":"fenrirbaest","email":"marko.bocevski@gmail.com"}],"readme":"# opslog\n\nEmbedded event-sourced document store for Node.js. Zero native dependencies.\n\nEvery mutation is recorded as an operation in an append-only log. Current state is derived by replaying operations from the latest snapshot. You get crash safety, undo, audit trails, and sync-readiness without a database server.\n\n## Install\n\n```bash\nnpm install @backloghq/opslog\n```\n\n## Usage\n\n```typescript\nimport { Store } from \"@backloghq/opslog\";\n\nconst store = new Store<{ name: string; status: string }>();\nawait store.open(\"./data\");\n\n// Create\nawait store.set(\"task-1\", { name: \"Build API\", status: \"active\" });\n\n// Read\nconst task = store.get(\"task-1\");\n\n// Update\nawait store.set(\"task-1\", { ...task, status: \"done\" });\n\n// Delete\nawait store.delete(\"task-1\");\n\n// Undo the delete\nawait store.undo();\n\n// Query\nconst active = store.filter((r) => r.status === \"active\");\nconst count = store.count((r) => r.status === \"done\");\n\n// Batch (single disk write for multiple operations)\nawait store.batch(() => {\n  store.set(\"a\", { name: \"A\", status: \"active\" });\n  store.set(\"b\", { name: \"B\", status: \"active\" });\n  store.set(\"c\", { name: \"C\", status: \"active\" });\n});\n\n// Close (checkpoints automatically)\nawait store.close();\n```\n\nState survives restarts — reopen the same directory and everything is there.\n\n## How It Works\n\n```\ndata/\n  manifest.json                    # Points to current snapshot + ops file(s)\n  snapshots/\n    snap-<timestamp>.jsonl          # Immutable full-state capture (JSONL: header + one line per record)\n  ops/\n    ops-<timestamp>.jsonl          # Append-only operation log (single-writer)\n    agent-<id>-<timestamp>.jsonl   # Per-agent operation log (multi-writer)\n  archive/\n    archive-<period>.json          # Old records, lazy-loaded\n```\n\n**Writes** append an operation (one JSON line) to the ops file. **Reads** come from an in-memory map built from the latest snapshot + ops replay. **Checkpoints** materialize current state as a new immutable snapshot.\n\nEvery operation records the previous value, so **undo** pops the last operation and restores the old state. The operations log doubles as an **audit trail** and a natural unit for **sync** between nodes.\n\n## API\n\n### Lifecycle\n\n```typescript\nawait store.open(dir, options?)   // Load state from directory\nawait store.close()               // Checkpoint and close\n```\n\n### CRUD\n\n```typescript\nstore.get(id)                     // Get record by ID\nawait store.set(id, value)        // Create or update\nawait store.delete(id)            // Remove (throws if not found)\nstore.has(id)                     // Check existence\n```\n\n### Query\n\n```typescript\nstore.all()                       // All records\nstore.entries()                   // All [id, record] pairs\nstore.filter(predicate)           // Records matching predicate\nstore.count(predicate?)           // Count (all or matching)\nstore.getManifest()               // Read-only ManifestInfo (snapshot/WAL paths, stats)\n```\n\n### Streaming (for external consumers)\n\n```typescript\n// Stream snapshot records without loading all into memory\nfor await (const [id, record] of store.streamSnapshot()) {\n  process(id, record);\n}\n\n// Read WAL operations (optionally since a timestamp)\nfor await (const op of store.getWalOps(sinceTimestamp?)) {\n  // op: { ts, op: \"set\"|\"delete\", id, data?, prev }\n}\n```\n\n### Batch\n\n```typescript\nawait store.batch(() => {         // Multiple ops, single disk write\n  store.set(\"a\", valueA);        // Rolls back all on error\n  store.set(\"b\", valueB);\n});\n```\n\nEmpty batches (no `set`/`delete` calls) are no-ops — no I/O is performed.\n\n### History\n\n```typescript\nawait store.undo()                // Undo last operation\nstore.getHistory(id)              // All operations for a record\nstore.getOps(since?)              // Operations since timestamp\n```\n\n### Maintenance\n\n```typescript\nawait store.compact()             // Create new snapshot, clear ops\nawait store.archive(predicate)    // Move matching records to archive\nawait store.loadArchive(segment)  // Lazy-load archived records\nstore.listArchiveSegments()       // List available archive files\nstore.stats()                     // { activeRecords, opsCount, archiveSegments }\nawait store.refresh()             // Reload from all agent WALs (multi-writer only)\n```\n\n### Blob Storage (via StorageBackend)\n\n```typescript\nawait backend.writeBlob(\"data/file.jsonl\", buffer);  // Write at relative path\nconst buf = await backend.readBlob(\"data/file.jsonl\"); // Read full file\nconst range = await backend.readBlobRange(\"data/file.jsonl\", 1024, 256); // Byte-range read\nconst names = await backend.listBlobs(\"data\");         // List files under prefix\nawait backend.deleteBlob(\"data/file.jsonl\");            // Delete file\n```\n\n`readBlobRange` enables O(1) point lookups in JSONL record stores — seek to byte offset, read exact length. FsBackend uses `fs.read` with file offset. S3Backend uses HTTP Range header.\n\n## Options\n\n```typescript\nawait store.open(dir, {\n  checkpointThreshold: 100,       // Auto-checkpoint after N ops (default: 100)\n  checkpointOnClose: true,        // Checkpoint when close() is called (default: true)\n  version: 1,                     // Schema version\n  migrate: (record, fromVersion) => record, // Migration function\n  readOnly: false,                // Open in read-only mode (default: false)\n  skipLoad: false,                // Skip loading snapshot/WAL into memory (default: false)\n  writeMode: \"immediate\",         // \"immediate\" (default), \"group\" (~12x faster), or \"async\" (~50x faster, lossy on crash)\n  groupCommitSize: 50,            // Group: flush after N ops (default: 50)\n  groupCommitMs: 100,             // Group: flush after N ms (default: 100)\n  agentId: \"agent-A\",             // Enable multi-writer mode (optional)\n  backend: new FsBackend(),       // Custom storage backend (optional, default: FsBackend)\n});\n```\n\n## Group Commit\n\nBuffer writes in memory and flush as a single disk write. ~12x faster for sustained writes.\n\n```typescript\nconst store = new Store();\nawait store.open(\"./data\", {\n  writeMode: \"group\",     // Buffer ops, flush periodically\n  groupCommitSize: 50,    // Flush when buffer has 50 ops\n  groupCommitMs: 100,     // Or after 100ms idle\n});\n\n// Writes are buffered — no fsync per op\nawait store.set(\"a\", valueA);\nawait store.set(\"b\", valueB);  // Both flushed together\n\n// Explicit flush if needed\nawait store.flush();\n\n// close() always flushes before shutting down\nawait store.close();\n```\n\n### Async Mode\n\nFor maximum write throughput, use `writeMode: \"async\"`. Writes resolve immediately after buffering in memory — no disk I/O on the hot path. ~50x faster than immediate mode.\n\n```typescript\nconst store = new Store();\nawait store.open(\"./data\", {\n  writeMode: \"async\",\n  groupCommitSize: 50,\n  groupCommitMs: 100,\n});\n\nawait store.set(\"a\", valueA);  // Returns instantly — buffered in memory\nawait store.set(\"b\", valueB);  // Same\n\n// Ensure durability before exit\nawait store.sync();\nawait store.close();\n```\n\n**Crash semantics:** Data buffered since the last flush is **lost** on unclean shutdown. Call `sync()` before process exit for durability. `close()` always flushes.\n\n**Safety:** Forced to `\"immediate\"` when `agentId` is set (multi-writer mode). Other agents can't see buffered ops, so group/async commit is single-writer only.\n\n**When to use which mode:**\n- `\"immediate\"` (default) — every write is durable. Use when data loss is unacceptable.\n- `\"group\"` — writes are batched but caller still waits for flush. ~12x faster. Crash loses up to `groupCommitMs` ms of data.\n- `\"async\"` — writes return instantly. ~50x faster. Crash loses all unflushed data. Best for high-throughput, latency-sensitive, crash-tolerant workloads.\n\n## Multi-Writer Mode\n\nMultiple agents can write to the same store concurrently. Each agent gets its own WAL file — no write contention.\n\n```typescript\n// Agent A (process 1 / machine 1)\nconst storeA = new Store<Task>();\nawait storeA.open(\"./data\", { agentId: \"agent-A\" });\nawait storeA.set(\"task-1\", { title: \"Build API\", status: \"active\" });\nawait storeA.close();\n\n// Agent B (process 2 / machine 2)\nconst storeB = new Store<Task>();\nawait storeB.open(\"./data\", { agentId: \"agent-B\" });\n// B sees A's writes on open\nstoreB.get(\"task-1\"); // { title: \"Build API\", status: \"active\" }\nawait storeB.set(\"task-2\", { title: \"Write tests\", status: \"active\" });\nawait storeB.close();\n```\n\n### How it works\n\n- Each agent writes to `ops/agent-{id}-{timestamp}.jsonl` — separate files, no locking needed for writes\n- Operations carry a [Lamport clock](https://en.wikipedia.org/wiki/Lamport_timestamp) for ordering\n- On `open()`, all agent WAL files are merge-sorted by `(clock, agentId)` for a deterministic total order\n- Conflicts (two agents write the same key) are resolved with **last-writer-wins** by clock value\n- `undo()` only undoes the calling agent's last operation\n- `compact()` acquires a compaction lock, snapshots the merged state, and resets all WAL files\n- `refresh()` re-reads all agent WALs to pick up other agents' writes\n\n### Conflict resolution\n\nWhen two agents modify the same key, the operation with the higher Lamport clock wins. If clocks are equal, the lexicographically higher agent ID wins. This is deterministic — all agents arrive at the same state regardless of replay order.\n\n```typescript\n// Agent A sets \"shared\" (clock=1)\nawait storeA.set(\"shared\", { value: \"from-A\" });\n\n// Agent B opens (sees clock=1), sets \"shared\" (clock=2)\nawait storeB.set(\"shared\", { value: \"from-B\" });\n\n// B wins — higher clock\nstore.get(\"shared\"); // { value: \"from-B\" }\n```\n\n## Custom Storage Backend\n\nopslog uses a pluggable `StorageBackend` interface for all I/O. The default is `FsBackend` (local filesystem). You can implement your own backend for S3, databases, or other storage systems.\n\n```typescript\nimport { Store, FsBackend } from \"@backloghq/opslog\";\nimport type { StorageBackend } from \"@backloghq/opslog\";\n\n// Use the default filesystem backend (implicit)\nconst store = new Store();\nawait store.open(\"./data\");\n\n// Or pass a custom backend explicitly\nconst store = new Store();\nawait store.open(\"./data\", { backend: new FsBackend() });\n\n// Or implement your own\nclass S3Backend implements StorageBackend {\n  // ... implement all methods\n}\nconst store = new Store();\nawait store.open(\"s3://bucket/prefix\", { backend: new S3Backend() });\n```\n\n## Read-Only Mode\n\nOpen a store for reading without acquiring the write lock. Useful for dashboards, backup processes, or multiple readers alongside a single writer.\n\n```typescript\nconst reader = new Store();\nawait reader.open(\"./data\", { readOnly: true });\n\n// All reads work\nconst tasks = reader.all();\nconst active = reader.filter((t) => t.status === \"active\");\n\n// All mutations throw\nawait reader.set(\"x\", value); // Error: Store is read-only\n```\n\nRead-only stores load the latest snapshot and replay ops on open. They do not checkpoint on close. Multiple read-only stores can open the same directory concurrently alongside one writer.\n\n## Concurrency\n\nAll state-mutating operations (`set`, `delete`, `batch`, `undo`, `compact`, `archive`) are serialized through an internal async mutex. This prevents interleaving of concurrent mutations — e.g., `compact()` swapping the ops file while `set()` is appending, or `undo()` truncating while `set()` is writing.\n\nRead operations (`get`, `all`, `filter`, `count`, `has`, `entries`) are synchronous and lock-free.\n\nAn advisory directory write lock (`.lock` file with PID) prevents two processes from opening the same store. Stale locks from crashed processes are automatically recovered.\n\n## Crash Safety\n\n- **Ops file**: append-only writes. A crash mid-append loses at most the last operation. Malformed lines are skipped on recovery.\n- **Snapshots**: immutable. Written to a temp file, then atomically renamed.\n- **Manifest**: atomically replaced via temp-file-rename. Always points to a valid snapshot.\n- **Undo**: uses `ftruncate()` — a single atomic POSIX syscall. O(1) regardless of file size.\n\nNo data corruption on crash. At most one in-flight operation is lost.\n\n## Schema Migration\n\n```typescript\nconst store = new Store();\nawait store.open(dir, {\n  version: 2,\n  migrate: (record, fromVersion) => {\n    if (fromVersion < 2) return { ...record, newField: \"default\" };\n    return record;\n  },\n});\n```\n\nRecords are migrated in memory on open. Next checkpoint persists the migrated state.\n\n## Development\n\n```bash\nnpm run build          # Compile TypeScript\nnpm run lint           # ESLint\nnpm test               # Run tests\nnpm run test:coverage  # Tests with coverage\n```\n\n## License\n\nMIT\n","readmeFilename":"README.md"}