{"_id":"@lushly-dev/local-db","_rev":"5-f73620e75a8fe7f4be348e04234e5f5b","name":"@lushly-dev/local-db","dist-tags":{"latest":"1.0.0"},"versions":{"0.1.0":{"name":"@lushly-dev/local-db","version":"0.1.0","keywords":["local-storage","lowdb","adapter","schema-migration","persistence"],"license":"MIT","_id":"@lushly-dev/local-db@0.1.0","maintainers":[{"name":"lushly-admin","email":"falkicon@gmail.com"}],"homepage":"https://github.com/lushly-dev/libraries#readme","bugs":{"url":"https://github.com/lushly-dev/libraries/issues"},"dist":{"shasum":"bca2919ff98d9c71d7ce6bc2827d3303a92d5c2e","tarball":"https://registry.npmjs.org/@lushly-dev/local-db/-/local-db-0.1.0.tgz","fileCount":5,"integrity":"sha512-iNc6gS/RVuHoBddRsKcAixT3PEj2ax15UEUtJN2dO9QdWQi29YN6/inK19nBuAk3aGmb2rE6ViqDjWAXp6s09w==","signatures":[{"sig":"MEUCIQCD1BgkzrZol5efc7msProOdPGz6W1Nrz1Nnq6R8egISgIgCMyw82a18wtFI3lexfO6JnXT0veep1ub9SBZYqmLKhs=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":14074},"main":"./dist/index.js","type":"module","_from":"file:lushly-dev-local-db-0.1.0.tgz","types":"./dist/index.d.ts","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js"}},"scripts":{"test":"vitest watch","build":"tsc --project tsconfig.build.json","test:run":"vitest run","typecheck":"tsc --noEmit"},"_npmUser":{"name":"lushly-admin","email":"falkicon@gmail.com"},"_resolved":"/tmp/f8eb9a72537625590532758186c30c45/lushly-dev-local-db-0.1.0.tgz","_integrity":"sha512-iNc6gS/RVuHoBddRsKcAixT3PEj2ax15UEUtJN2dO9QdWQi29YN6/inK19nBuAk3aGmb2rE6ViqDjWAXp6s09w==","repository":{"url":"git+https://github.com/lushly-dev/libraries.git","type":"git","directory":"ts/packages/local-db"},"_npmVersion":"10.9.4","description":"Schema-migrating local storage adapter with swappable backends (LocalStorage, in-memory) and per-namespace data isolation.","directories":{},"_nodeVersion":"22.22.0","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"lowdb":"^7.0.0","vitest":"^3.0.0","typescript":"^5.7.0"},"peerDependencies":{"lowdb":"^7.0.0"},"peerDependenciesMeta":{"lowdb":{"optional":true}},"_npmOperationalInternal":{"tmp":"tmp/local-db_0.1.0_1771410407769_0.5791365820248335","host":"s3://npm-registry-packages-npm-production"}},"0.4.0":{"name":"@lushly-dev/local-db","version":"0.4.0","keywords":["afd","agent-first","database","adapter","sqlite","local-storage","data-layer"],"author":{"name":"Falkicon"},"license":"MIT","_id":"@lushly-dev/local-db@0.4.0","maintainers":[{"name":"lushly-admin","email":"falkicon@gmail.com"}],"homepage":"https://github.com/lushly-dev/afd#readme","bugs":{"url":"https://github.com/lushly-dev/afd/issues"},"dist":{"shasum":"6793d29f25e5e0b028fab81ff51340fdd9c706f6","tarball":"https://registry.npmjs.org/@lushly-dev/local-db/-/local-db-0.4.0.tgz","fileCount":19,"integrity":"sha512-LXz2TpWZqqMNwdio3lk3wtBYgTsLXw2BFqsi8ds6u7FaT0EAalgzi1AEFasanDVwrzbo4bmMrecb/yDy8rjZyw==","signatures":[{"sig":"MEQCIBkeiFSsNcpJztdMMilaTZ7lsfBv32+/GX16dqH8Ge6MAiB7JP/evSvD55Tv0eiKtEAAlDKMCZitWpmoQHB5Ia9rZQ==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@lushly-dev%2flocal-db@0.4.0","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":36504},"main":"./dist/index.js","type":"module","_from":"file:lushly-dev-local-db-0.4.0.tgz","types":"./dist/index.d.ts","engines":{"node":">=20.0.0"},"exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js"}},"scripts":{"dev":"tsc --watch","test":"vitest run","build":"tsc","clean":"rimraf dist *.tsbuildinfo","typecheck":"tsc --noEmit","test:watch":"vitest"},"_npmUser":{"name":"lushly-admin","email":"falkicon@gmail.com"},"_resolved":"/tmp/25fa3c269e44cf4341b5fbad846f40f0/lushly-dev-local-db-0.4.0.tgz","_integrity":"sha512-LXz2TpWZqqMNwdio3lk3wtBYgTsLXw2BFqsi8ds6u7FaT0EAalgzi1AEFasanDVwrzbo4bmMrecb/yDy8rjZyw==","repository":{"url":"git+https://github.com/lushly-dev/afd.git","type":"git","directory":"packages/local-db"},"_npmVersion":"10.9.4","description":"Async data adapter with swappable backends (Memory, HTTP, Browser) for Agent-First Development","directories":{},"sideEffects":false,"_nodeVersion":"22.22.0","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"rimraf":"^6.0.1","vitest":"^4.0.18","typescript":"^5.7.2","@types/node":"^22.10.2","@vitest/coverage-v8":"^4.0.18"},"_npmOperationalInternal":{"tmp":"tmp/local-db_0.4.0_1772310058895_0.2380389235545155","host":"s3://npm-registry-packages-npm-production"}},"0.5.0":{"name":"@lushly-dev/local-db","version":"0.5.0","keywords":["afd","agent-first","database","adapter","sqlite","local-storage","data-layer"],"author":{"name":"Falkicon"},"license":"MIT","_id":"@lushly-dev/local-db@0.5.0","maintainers":[{"name":"lushly-admin","email":"falkicon@gmail.com"}],"homepage":"https://github.com/lushly-dev/afd#readme","bugs":{"url":"https://github.com/lushly-dev/afd/issues"},"dist":{"shasum":"3c5fd2f27246d4ccf0d867247cb42d78fa72c50d","tarball":"https://registry.npmjs.org/@lushly-dev/local-db/-/local-db-0.5.0.tgz","fileCount":19,"integrity":"sha512-B2D4cUABxHv5Cd4SPbquBtHShDY+pLViVEXSa2nXvXwGCoIOnP1q+4rC63f1XKJ8hb445t38W7WfJ022egy1bw==","signatures":[{"sig":"MEQCIHzd3OgZ+TfVKgdRhaTrLj8YtSq6iJSVeVwAFizb1sg2AiADq7wQ87IruonCcAPpN1T2zisF1GXK/JXlBKDVwqbh9g==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@lushly-dev%2flocal-db@0.5.0","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":36504},"main":"./dist/index.js","type":"module","_from":"file:lushly-dev-local-db-0.5.0.tgz","types":"./dist/index.d.ts","engines":{"node":">=20.0.0"},"exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js"}},"scripts":{"dev":"tsc --watch","test":"vitest run","build":"tsc","clean":"rimraf dist *.tsbuildinfo","typecheck":"tsc --noEmit","test:watch":"vitest"},"_npmUser":{"name":"lushly-admin","email":"falkicon@gmail.com"},"_resolved":"/tmp/b79af0867470935ec1127fed79ad9909/lushly-dev-local-db-0.5.0.tgz","_integrity":"sha512-B2D4cUABxHv5Cd4SPbquBtHShDY+pLViVEXSa2nXvXwGCoIOnP1q+4rC63f1XKJ8hb445t38W7WfJ022egy1bw==","repository":{"url":"git+https://github.com/lushly-dev/afd.git","type":"git","directory":"packages/local-db"},"_npmVersion":"10.9.4","description":"Async data adapter with swappable backends (Memory, HTTP, Browser) for Agent-First Development","directories":{},"sideEffects":false,"_nodeVersion":"22.22.0","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"rimraf":"^6.0.1","vitest":"^4.0.18","typescript":"^5.7.2","@types/node":"^22.10.2","@vitest/coverage-v8":"^4.0.18"},"_npmOperationalInternal":{"tmp":"tmp/local-db_0.5.0_1773188881919_0.07771750822103574","host":"s3://npm-registry-packages-npm-production"}},"0.6.0":{"name":"@lushly-dev/local-db","version":"0.6.0","keywords":["afd","agent-first","database","adapter","sqlite","local-storage","data-layer"],"author":{"name":"Falkicon"},"license":"MIT","_id":"@lushly-dev/local-db@0.6.0","maintainers":[{"name":"lushly-admin","email":"falkicon@gmail.com"}],"homepage":"https://github.com/lushly-dev/afd#readme","bugs":{"url":"https://github.com/lushly-dev/afd/issues"},"dist":{"shasum":"8205dd0c2d627ce28c7fd4ebd662eb19bcd26977","tarball":"https://registry.npmjs.org/@lushly-dev/local-db/-/local-db-0.6.0.tgz","fileCount":19,"integrity":"sha512-gzB0AjGvMk1cliueQgBkf0W5Du228Y3yEQlOC6lIzQFPTYPFRUr+SDiUY7mvh4Vwm4oQy9x5SvjXhpx1lN7wMA==","signatures":[{"sig":"MEUCIHeSVSdruX5+JqS9hp4g5buzC0svVeeJKM3SCHXK0VOlAiEAyLO6SkrnLedG6kYB6HVQxc3CVWUutOIzF3w2uH8nNpg=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@lushly-dev%2flocal-db@0.6.0","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":36501},"main":"./dist/index.js","type":"module","_from":"file:lushly-dev-local-db-0.6.0.tgz","types":"./dist/index.d.ts","engines":{"node":">=22.0.0"},"exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js"}},"scripts":{"dev":"tsc --watch","test":"vitest run","build":"tsc","clean":"rimraf dist *.tsbuildinfo","typecheck":"tsc --noEmit","test:watch":"vitest"},"_npmUser":{"name":"lushly-admin","email":"falkicon@gmail.com"},"_resolved":"/tmp/5250a064ce792c7a1cf78ff8003056aa/lushly-dev-local-db-0.6.0.tgz","_integrity":"sha512-gzB0AjGvMk1cliueQgBkf0W5Du228Y3yEQlOC6lIzQFPTYPFRUr+SDiUY7mvh4Vwm4oQy9x5SvjXhpx1lN7wMA==","repository":{"url":"git+https://github.com/lushly-dev/afd.git","type":"git","directory":"packages/local-db"},"_npmVersion":"11.9.0","description":"Async data adapter with swappable backends (Memory, HTTP, Browser) for Agent-First Development","directories":{},"sideEffects":false,"_nodeVersion":"24.14.0","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"rimraf":"^6.1.3","vitest":"^4.1.0","typescript":"^5.9.3","@types/node":"^25.5.0","@vitest/coverage-v8":"^4.1.0"},"_npmOperationalInternal":{"tmp":"tmp/local-db_0.6.0_1773466658891_0.5820196028488538","host":"s3://npm-registry-packages-npm-production"}},"1.0.0":{"name":"@lushly-dev/local-db","version":"1.0.0","description":"Async data adapter with swappable backends (Memory, HTTP, Browser) for Agent-First Development","type":"module","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js"}},"main":"./dist/index.js","types":"./dist/index.d.ts","keywords":["afd","agent-first","database","adapter","sqlite","local-storage","data-layer"],"author":{"name":"Falkicon"},"license":"MIT","homepage":"https://github.com/lushly-dev/afd#readme","bugs":{"url":"https://github.com/lushly-dev/afd/issues"},"repository":{"type":"git","url":"git+https://github.com/lushly-dev/afd.git","directory":"packages/local-db"},"engines":{"node":">=22.0.0"},"sideEffects":false,"devDependencies":{"@types/node":"^25.5.0","@vitest/coverage-v8":"^4.1.0","rimraf":"^6.1.3","typescript":"^5.9.3","vitest":"^4.1.0"},"publishConfig":{"access":"public"},"scripts":{"build":"tsc","clean":"rimraf dist *.tsbuildinfo","dev":"tsc --watch","typecheck":"tsc --noEmit","test":"vitest run","test:watch":"vitest"},"_id":"@lushly-dev/local-db@1.0.0","_integrity":"sha512-XswFxeNyFu9DwVfdNGINquTHBA9fTMsQaJtZht6gddJalHHK+GqXeKkn8Nhg1Ur2xjqB59H/NUIZCDsX4rXlKw==","_resolved":"/tmp/db442e8f852755e3a42f7b20ffc5d787/lushly-dev-local-db-1.0.0.tgz","_from":"file:lushly-dev-local-db-1.0.0.tgz","_nodeVersion":"24.14.0","_npmVersion":"11.9.0","dist":{"integrity":"sha512-XswFxeNyFu9DwVfdNGINquTHBA9fTMsQaJtZht6gddJalHHK+GqXeKkn8Nhg1Ur2xjqB59H/NUIZCDsX4rXlKw==","shasum":"cbfa484fe65db0dfa5bdf835ff74d04966958883","tarball":"https://registry.npmjs.org/@lushly-dev/local-db/-/local-db-1.0.0.tgz","fileCount":19,"unpackedSize":36501,"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@lushly-dev%2flocal-db@1.0.0","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEQCICueEZBvCoHd4nKTKhthUBQVyLyu+0HObGgbVyePWlocAiAqTxNecWY4ArLsI3p40XPO57kShWl3WC57vEHPx2EMOA=="}]},"_npmUser":{"name":"lushly-admin","email":"falkicon@gmail.com"},"directories":{},"maintainers":[{"name":"lushly-admin","email":"falkicon@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/local-db_1.0.0_1773633892302_0.10056882035108083"},"_hasShrinkwrap":false}},"time":{"created":"2026-02-18T10:26:47.649Z","modified":"2026-03-16T04:04:52.799Z","0.1.0":"2026-02-18T10:26:47.925Z","0.4.0":"2026-02-28T20:20:59.026Z","0.5.0":"2026-03-11T00:28:02.109Z","0.6.0":"2026-03-14T05:37:39.060Z","1.0.0":"2026-03-16T04:04:52.452Z"},"bugs":{"url":"https://github.com/lushly-dev/afd/issues"},"author":{"name":"Falkicon"},"license":"MIT","homepage":"https://github.com/lushly-dev/afd#readme","keywords":["afd","agent-first","database","adapter","sqlite","local-storage","data-layer"],"repository":{"type":"git","url":"git+https://github.com/lushly-dev/afd.git","directory":"packages/local-db"},"description":"Async data adapter with swappable backends (Memory, HTTP, Browser) for Agent-First Development","maintainers":[{"name":"lushly-admin","email":"falkicon@gmail.com"}],"readme":"# @lushly-dev/local-db\n\nAsync data adapter with swappable backends for [Agent-First Development](https://github.com/lushly-dev/afd).\n\n## Why\n\nAFD commands need persistent storage, but the backend varies:\n- **Unit tests** need fast, in-memory storage with no setup\n- **Local dev** needs a REST API backed by SQLite or similar\n- **Production** needs a cloud database (Azure SQL, Cosmos DB, Postgres)\n\n`@lushly-dev/local-db` provides a single `DataAdapter` interface that all backends implement. Your commands write to the interface once — swap the backend by changing one line.\n\n## Installation\n\n```bash\nnpm install @lushly-dev/local-db\n# or\npnpm add @lushly-dev/local-db\n```\n\n## Quick start\n\n```ts\nimport { createMemoryAdapter, createHttpAdapter } from '@lushly-dev/local-db';\n\n// Tests — no server needed\nconst db = createMemoryAdapter({\n  users: [{ id: 'u1', name: 'Alice' }],\n});\n\n// Production — talks to your REST API\nconst db = createHttpAdapter('https://api.example.com/v1');\n\n// Same API either way\nconst user = await db.get('users', 'u1');\nconst all = await db.list('users', { limit: 10 });\nawait db.create('users', { name: 'Bob' });\nawait db.update('users', 'u1', { name: 'Updated' });\nawait db.remove('users', 'u1');\n```\n\n## API\n\n### `DataAdapter` interface\n\n| Method | Signature | Description |\n|--------|-----------|-------------|\n| `get` | `get<T>(table, id): Promise<T \\| null>` | Get record by ID |\n| `list` | `list<T>(table, params?): Promise<ListResult<T>>` | List with filter/sort/paginate |\n| `create` | `create<T>(table, data): Promise<T>` | Create a record |\n| `update` | `update<T>(table, id, patch): Promise<T>` | Update (merge patch) |\n| `remove` | `remove(table, id): Promise<void>` | Delete a record |\n| `batch` | `batch(ops): Promise<BatchResult>` | Atomic multi-operation |\n| `health` | `health(): Promise<HealthStatus>` | Backend health check |\n\n### `QueryParams`\n\n```ts\ninterface QueryParams {\n  limit?: number;\n  offset?: number;\n  sort?: string;\n  order?: 'asc' | 'desc';\n  [key: string]: string | number | boolean | undefined; // filters\n}\n```\n\n### Adapters\n\n#### `MemoryAdapter`\n\nIn-memory storage backed by `Map`. Supports filtering, sorting, pagination, batch.\n\n```ts\nconst db = createMemoryAdapter(initialData?);\ndb.clear();        // reset all data\ndb.count('table'); // row count\n```\n\n#### `HttpAdapter`\n\nREST client via `fetch()`. Maps table names to URL paths.\n\n```ts\nconst db = createHttpAdapter(baseUrl, {\n  pathMap: { my_table: '/custom-endpoint' },\n  fetch: customFetchFn, // for Node or testing\n});\n```\n\nDefault path mapping: `accounts` → `/accounts`, `flags` → `/flags`, `settings` → `/settings`, etc.\n\nUses PUT for upsert-style tables (settings, flags), PATCH for entity tables (accounts, annotations).\n\n## With AFD commands\n\n```ts\nimport { defineCommand, success } from '@lushly-dev/afd-server';\nimport type { DataAdapter } from '@lushly-dev/local-db';\nimport { z } from 'zod/v3';\n\n// Inject adapter — no storage coupling in command logic\nexport function createUserCommands(db: DataAdapter) {\n  return defineCommand({\n    name: 'user-list',\n    input: z.object({ limit: z.number().optional() }),\n    async handler(input) {\n      const result = await db.list('users', { limit: input.limit });\n      return success(result);\n    },\n  });\n}\n```\n\n## License\n\nMIT\n","readmeFilename":"README.md"}