{"_id":"@aibind/service-worker","name":"@aibind/service-worker","dist-tags":{"latest":"0.4.0"},"versions":{"0.4.0":{"name":"@aibind/service-worker","version":"0.4.0","description":"Service Worker backend for @aibind — run AI streaming with zero server infrastructure using IndexedDB","license":"MIT","keywords":["service-worker","pwa","offline","indexeddb","aibind","ai","streaming"],"repository":{"type":"git","url":"git+https://github.com/puruvj/aibind.git"},"type":"module","main":"./dist/index.js","types":"./dist/index.d.ts","exports":{".":{"types":"./dist/index.d.ts","default":"./dist/index.js"}},"peerDependencies":{"@aibind/core":"*","ai":"*"},"devDependencies":{"ai":"^4.0.0","fake-indexeddb":"^6.0.0","tsup":"^8.5.1","typescript":"^5.7.0","vitest":"^3.0.0","@aibind/core":"0.4.0"},"scripts":{"test":"vitest run","test:watch":"vitest","package":"tsup"},"_id":"@aibind/service-worker@0.4.0","bugs":{"url":"https://github.com/puruvj/aibind/issues"},"homepage":"https://github.com/puruvj/aibind#readme","_integrity":"sha512-JtAOxaHySnopxBTMXInmLYYkdMUVm3EW4jAKtXQ6D4M+ON43m/lbtpOd3FyAHqMIk4xGVHtY1Z9fc0yqCVXRLQ==","_resolved":"/private/var/folders/g3/rxrpm2hd0j1cp1zw5sqckdyc0000gn/T/981b0d3fb32e2aeebf4574186ac2b187/aibind-service-worker-0.4.0.tgz","_from":"file:aibind-service-worker-0.4.0.tgz","_nodeVersion":"24.1.0","_npmVersion":"11.3.0","dist":{"integrity":"sha512-JtAOxaHySnopxBTMXInmLYYkdMUVm3EW4jAKtXQ6D4M+ON43m/lbtpOd3FyAHqMIk4xGVHtY1Z9fc0yqCVXRLQ==","shasum":"36603330eefa07aa8b2d63b26db609064642e3c0","tarball":"https://registry.npmjs.org/@aibind/service-worker/-/service-worker-0.4.0.tgz","fileCount":5,"unpackedSize":21381,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEYCIQCmSo0Vj5n2t2RvHHeufP92gr9fEHVGuWMEy37KiGahVgIhAMS5fXou2BPi1BqY50N86q/owTA3j4SAQMuYQs0JqYsM"}]},"_npmUser":{"name":"puruvj","email":"awesomepuruvj@gmail.com"},"directories":{},"maintainers":[{"name":"puruvj","email":"awesomepuruvj@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/service-worker_0.4.0_1772816837761_0.46747426055816343"},"_hasShrinkwrap":false}},"time":{"created":"2026-03-06T17:07:17.666Z","0.4.0":"2026-03-06T17:07:17.918Z","modified":"2026-03-06T17:07:18.088Z"},"maintainers":[{"name":"puruvj","email":"awesomepuruvj@gmail.com"}],"description":"Service Worker backend for @aibind — run AI streaming with zero server infrastructure using IndexedDB","homepage":"https://github.com/puruvj/aibind#readme","keywords":["service-worker","pwa","offline","indexeddb","aibind","ai","streaming"],"repository":{"type":"git","url":"git+https://github.com/puruvj/aibind.git"},"bugs":{"url":"https://github.com/puruvj/aibind/issues"},"license":"MIT","readme":"# @aibind/service-worker\n\nRun AI streaming with **zero server infrastructure** — the Service Worker is the backend.\n\n`@aibind/service-worker` installs a fetch handler in your SW that intercepts `@aibind` requests and handles them entirely in the browser. The LLM API is called directly from the SW; conversation history and durable stream chunks are stored in IndexedDB.\n\nThe client-side `Stream` class (from `@aibind/svelte`, `@aibind/react`, etc.) sees the same SSE protocol as a normal server-backed setup — no changes needed.\n\n## When to use this\n\n- Personal tools and internal apps where an embedded API key is acceptable\n- PWAs that need AI features without any backend\n- Demos and prototypes where zero infrastructure matters\n- Offline-capable apps (combined with caching strategies)\n\n> **Note:** The API key will be visible in your SW source code. Only use this when that trade-off is intentional.\n\n## Install\n\n```bash\nnpm install @aibind/service-worker ai @openrouter/ai-sdk-provider\n```\n\n## Usage\n\n### 1. Create your service worker\n\n```ts\n// sw.ts\nimport { createSWHandler, IDBStreamStore, IDBConversationStore } from \"@aibind/service-worker\";\nimport { createOpenRouter } from \"@openrouter/ai-sdk-provider\";\n\nconst openrouter = createOpenRouter({ apiKey: \"sk-...\" }); // user accepts key exposure\n\nconst handler = createSWHandler({\n  models: {\n    fast: openrouter(\"google/gemini-3.1-flash-lite-preview\"),\n    smart: openrouter(\"openai/gpt-5-mini\"),\n  },\n  resumable: true,\n  store: new IDBStreamStore(),\n  conversation: {\n    store: new IDBConversationStore(),\n  },\n});\n\nself.addEventListener(\"fetch\", handler);\n```\n\n### 2. Register the service worker in your app\n\n```ts\n// main.ts (or app entry point)\nif (\"serviceWorker\" in navigator) {\n  navigator.serviceWorker.register(\"/sw.js\");\n}\n```\n\n### 3. Use Stream as normal\n\n```svelte\n<script lang=\"ts\">\n  import { Stream } from \"@aibind/sveltekit\";\n  const stream = new Stream({ model: \"fast\" });\n</script>\n\n<button onclick={() => stream.send(\"Hello!\")}>Send</button>\n<p>{stream.text}</p>\n```\n\nNo changes to client code — the SW handles the request before it ever reaches the network.\n\n## IndexedDB stores\n\n### IDBStreamStore\n\nBacks durable/resumable streams. Chunks are written to IndexedDB as they arrive and can be replayed if the page reloads mid-stream.\n\n```ts\nconst store = new IDBStreamStore({\n  dbName: \"aibind_sw\",        // IndexedDB database name\n  pollIntervalMs: 50,          // how often readFrom() checks for new chunks\n  ttlMs: 300_000,              // TTL for completed streams before cleanup\n});\n```\n\n### IDBConversationStore\n\nPersists conversation history per session. Preserves branching structure (edits, regenerations).\n\n```ts\nconst store = new IDBConversationStore({\n  dbName: \"aibind_sw\",        // IndexedDB database name\n  ttlMs: 1_800_000,            // TTL for idle sessions (30 min default)\n});\n```\n\nBoth stores share the same IndexedDB database by default (`aibind_sw`). Tables are created automatically on first open — no schema setup required.\n\n### Cleanup\n\nCall `cleanup()` periodically to remove expired records:\n\n```ts\n// In your SW activate event\nself.addEventListener(\"activate\", (event) => {\n  event.waitUntil(\n    Promise.all([streamStore.cleanup(), conversationStore.cleanup()])\n  );\n});\n```\n\n## Options reference\n\n**`createSWHandler(config)`** — accepts the same `StreamHandlerConfig` as server-side `createStreamHandler`, plus all model, conversation, and resumable options.\n\n**`IDBStreamStore`**\n\n| Option | Type | Default | Description |\n|--------|------|---------|-------------|\n| `dbName` | `string` | `\"aibind_sw\"` | IndexedDB database name |\n| `pollIntervalMs` | `number` | `50` | Polling interval for readFrom() |\n| `ttlMs` | `number` | `300_000` | TTL for completed streams |\n\n**`IDBConversationStore`**\n\n| Option | Type | Default | Description |\n|--------|------|---------|-------------|\n| `dbName` | `string` | `\"aibind_sw\"` | IndexedDB database name |\n| `ttlMs` | `number` | `1_800_000` | TTL for idle sessions |\n\n## Documentation\n\n[Full docs →](https://aibind.dev/integrations/service-worker)\n","readmeFilename":"README.md","_rev":"1-9377b464877964299370f91ac46302bf"}