{"_id":"@blocksight/chat-state-convex","name":"@blocksight/chat-state-convex","dist-tags":{"latest":"0.1.0"},"versions":{"0.1.0":{"name":"@blocksight/chat-state-convex","version":"0.1.0","description":"Convex component backing the Vercel Chat SDK's StateAdapter — key-value entries, lists, locks, per-thread queues, and subscriptions in one isolated table.","license":"MIT","type":"module","sideEffects":false,"repository":{"type":"git","url":"git+https://github.com/blocknavi/blocksight-web.git","directory":"packages/chat-state-convex"},"homepage":"https://github.com/blocknavi/blocksight-web/tree/main/packages/chat-state-convex#readme","keywords":["convex","convex-component","chat","chat-sdk","state-adapter"],"publishConfig":{"access":"public"},"main":"./src/client/index.ts","module":"./src/client/index.ts","types":"./src/client/index.ts","exports":{"./package.json":"./package.json",".":"./src/client/index.ts","./convex.config":"./src/component/convex.config.ts","./convex.config.js":"./src/component/convex.config.ts","./_generated/component.js":"./src/component/_generated/component.ts"},"scripts":{"typecheck":"tsc --noEmit","test":"bun test"},"peerDependencies":{"chat":"^4.0.0","convex":"^1.24.8"},"devDependencies":{"chat":"^4.29.0","convex":"^1.37.0","typescript":"^5.9.3"},"_id":"@blocksight/chat-state-convex@0.1.0","bugs":{"url":"https://github.com/blocknavi/blocksight-web/issues"},"_nodeVersion":"24.5.0","_npmVersion":"11.5.1","dist":{"integrity":"sha512-o94CQIlzdAu2FftL+EeG2Yvmwtt+uA9eqFiLqbpji2pEnKicpELBJHgQtdeegYXcX81UFgW8TOCgmli2HMtBew==","shasum":"8cd89401d072da806b284382f67c600a9a9c9d03","tarball":"https://registry.npmjs.org/@blocksight/chat-state-convex/-/chat-state-convex-0.1.0.tgz","fileCount":12,"unpackedSize":35379,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEQCIA7k3Bl9lnttW7EDq3oescYeS+EkDLAqXohAFo4dEYzcAiAP+GTE7nVNutsr2+eFo+ePQ5Px4OzFVgT7mxGl2K6crA=="}]},"_npmUser":{"name":"ryanyue123","email":"yue.ryan123@gmail.com"},"directories":{},"maintainers":[{"name":"ryanyue123","email":"yue.ryan123@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/chat-state-convex_0.1.0_1779224335893_0.48373075623425055"},"_hasShrinkwrap":false}},"time":{"created":"2026-05-19T20:58:55.728Z","0.1.0":"2026-05-19T20:58:56.043Z","modified":"2026-05-19T20:58:56.221Z"},"maintainers":[{"name":"ryanyue123","email":"yue.ryan123@gmail.com"}],"description":"Convex component backing the Vercel Chat SDK's StateAdapter — key-value entries, lists, locks, per-thread queues, and subscriptions in one isolated table.","homepage":"https://github.com/blocknavi/blocksight-web/tree/main/packages/chat-state-convex#readme","keywords":["convex","convex-component","chat","chat-sdk","state-adapter"],"repository":{"type":"git","url":"git+https://github.com/blocknavi/blocksight-web.git","directory":"packages/chat-state-convex"},"bugs":{"url":"https://github.com/blocknavi/blocksight-web/issues"},"license":"MIT","readme":"# @blocksight/chat-state-convex\n\nA [Convex](https://convex.dev) component that backs the\n[Vercel Chat SDK](https://chat-sdk.dev)'s `StateAdapter` with a Convex table —\nkey-value entries, lists, distributed locks, per-thread queues, and\nsubscriptions, all in one isolated `chat_state` table.\n\n## Install\n\n```sh\nnpm install @blocksight/chat-state-convex\n```\n\n`convex` (`^1.24.8`) and `chat` (`^4.0.0`) are peer dependencies.\n\n## Setup\n\nRegister the component in `convex/convex.config.ts`:\n\n```ts\nimport chatStateConvex from \"@blocksight/chat-state-convex/convex.config.js\";\nimport { defineApp } from \"convex/server\";\n\nconst app = defineApp();\napp.use(chatStateConvex);\n\nexport default app;\n```\n\n## Usage\n\nConstruct `ConvexStateAdapter` inside a Convex action, passing the action\ncontext and the `components.chatStateConvex` handle:\n\n```ts\nimport { ConvexStateAdapter } from \"@blocksight/chat-state-convex\";\nimport { components } from \"./_generated/api\";\nimport { action } from \"./_generated/server\";\n\nexport const handleMessage = action({\n  handler: async (ctx) => {\n    const adapter = new ConvexStateAdapter(ctx, components.chatStateConvex);\n    // pass `adapter` to the Chat SDK\n  },\n});\n```\n\n## Expiry sweep\n\nConvex has no native TTL. Entries written with a `ttlMs` are filtered out on\nread, but expired rows must be deleted by a cron.\n\nFirst, add an internal mutation that delegates to the component's\n`sweepExpired`. In `convex/chatStateSweep.ts`:\n\n```ts\nimport { components } from \"./_generated/api\";\nimport { internalMutation } from \"./_generated/server\";\n\nexport const run = internalMutation({\n  args: {},\n  handler: async (ctx) => {\n    await ctx.runMutation(components.chatStateConvex.store.sweepExpired, {});\n  },\n});\n```\n\nThen schedule it in `convex/crons.ts`:\n\n```ts\nimport { cronJobs } from \"convex/server\";\nimport { internal } from \"./_generated/api\";\n\nconst crons = cronJobs();\ncrons.interval(\n  \"chat-state-sweep\",\n  { minutes: 15 },\n  internal.chatStateSweep.run\n);\n\nexport default crons;\n```\n\n## API\n\nAll functions live under `components.chatStateConvex.store`:\n\n| Function | Purpose |\n| --- | --- |\n| `getValue` / `setValue` / `deleteValue` | key-value entries |\n| `setValueIfAbsent` | conditional write |\n| `appendValue` / `listValue` | append-only lists |\n| `acquireLock` / `releaseLock` / `extendLock` / `forceReleaseLock` | per-thread distributed locks |\n| `enqueue` / `dequeue` / `queueDepth` | per-thread queues |\n| `subscribeThread` / `unsubscribeThread` / `threadSubscribed` | thread subscriptions |\n| `sweepExpired` | delete expired rows (cron target) |\n\n## License\n\nMIT\n","readmeFilename":"README.md","_rev":"1-8ceea2d57a906c21400346ae8b2f9475"}