{"_id":"@agile-nuxt/edge-db","_rev":"2-2ede257bc9385d956a5cb72c001a2738","name":"@agile-nuxt/edge-db","dist-tags":{"latest":"0.2.0"},"versions":{"0.1.0":{"name":"@agile-nuxt/edge-db","version":"0.1.0","keywords":["nuxt","nitro","database","embedded-database","typescript","backend","crud","cpanel","edge-db"],"author":{"name":"Agile Nuxt contributors"},"license":"MIT","_id":"@agile-nuxt/edge-db@0.1.0","maintainers":[{"name":"tfive","email":"Pooyan.tfive@ymail.com"}],"homepage":"https://github.com/agile-nuxt/agile-nuxt-edge-backend#readme","bugs":{"url":"https://github.com/agile-nuxt/agile-nuxt-edge-backend/issues"},"bin":{"edge-db":"dist/cli/cli.mjs"},"dist":{"shasum":"e8f1bbb35efb618a2e8949965067b8e064955e0a","tarball":"https://registry.npmjs.org/@agile-nuxt/edge-db/-/edge-db-0.1.0.tgz","fileCount":12,"integrity":"sha512-I28mUJuY7iWG2T3N5N1HFQrbAM/jls2EAFG1mpiMgIYkyXgmuDM3J6zo+NhJNh7Xm46niBaicIi8hXv5+lmJIQ==","signatures":[{"sig":"MEQCIBKcAm8YgnOzglLtAGo9tuVSZNd3ijAS6O25K16IfbLDAiAG9rWGnogr8NalRSCx3xXhTvlJZfXT49nygpH8ggxDFQ==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":747891},"main":"./dist/index.cjs","type":"module","types":"./dist/index.d.ts","module":"./dist/index.mjs","engines":{"node":">=20.0.0"},"exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.mjs","require":"./dist/index.cjs"}},"gitHead":"26a2e60f16c1fabb850e6a611d15c5febbf95849","scripts":{"lint":"eslint src tests tsup.config.ts","test":"vitest run","build":"tsup","clean":"rm -rf dist coverage","typecheck":"tsc --noEmit","pack:check":"tsx ../../scripts/check-package.ts --package edge-db --pack"},"_npmUser":{"name":"tfive","email":"Pooyan.tfive@ymail.com"},"repository":{"url":"git+https://github.com/agile-nuxt/agile-nuxt-edge-backend.git","type":"git","directory":"packages/edge-db"},"_npmVersion":"10.9.3","description":"A zero-setup pure TypeScript embedded database for Nuxt and Nitro apps, optimized for fast indexed CRUD.","directories":{},"sideEffects":false,"_nodeVersion":"22.20.0","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"tsup":"^8.4.0","vitest":"^3.1.2","typescript":"^5.8.3","@types/node":"^22.15.3"},"_npmOperationalInternal":{"tmp":"tmp/edge-db_0.1.0_1782305097868_0.10783980428624229","host":"s3://npm-registry-packages-npm-production"}},"0.2.0":{"name":"@agile-nuxt/edge-db","version":"0.2.0","description":"A zero-setup pure TypeScript embedded database for Nuxt and Nitro apps, optimized for fast indexed CRUD.","type":"module","license":"MIT","author":{"name":"Agile Nuxt contributors"},"homepage":"https://github.com/agile-nuxt/agile-nuxt-edge-backend#readme","repository":{"type":"git","url":"git+https://github.com/agile-nuxt/agile-nuxt-edge-backend.git","directory":"packages/edge-db"},"bugs":{"url":"https://github.com/agile-nuxt/agile-nuxt-edge-backend/issues"},"keywords":["nuxt","nitro","database","embedded-database","typescript","backend","crud","cpanel","edge-db"],"engines":{"node":">=20.0.0"},"main":"./dist/index.cjs","module":"./dist/index.mjs","types":"./dist/index.d.ts","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.mjs","require":"./dist/index.cjs"}},"bin":{"edge-db":"dist/cli/cli.mjs"},"scripts":{"build":"tsup","test":"vitest run","typecheck":"tsc --noEmit","lint":"eslint src tests tsup.config.ts","pack:check":"tsx ../../scripts/check-package.ts --package edge-db --pack","clean":"rm -rf dist coverage"},"publishConfig":{"access":"public"},"sideEffects":false,"devDependencies":{"@types/node":"^22.15.3","tsup":"^8.4.0","typescript":"^5.8.3","vitest":"^3.1.2"},"_id":"@agile-nuxt/edge-db@0.2.0","gitHead":"a3be71c3a5572114021602e7ba9be8e95ac1ef58","_nodeVersion":"22.1.0","_npmVersion":"10.7.0","dist":{"integrity":"sha512-QCZtFMIpyW6nglDNXKT0ml1awWLFqhwElz+nSbwPA28xeAqPymn9vZMpOfISL2xw9nF8BrrpeiTqkWI/fzPAXw==","shasum":"d46f823564f4a43d7ac937c094a0bbd038432665","tarball":"https://registry.npmjs.org/@agile-nuxt/edge-db/-/edge-db-0.2.0.tgz","fileCount":12,"unpackedSize":989187,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEUCIQD/JvncwYXAO+GSwUWay5iH6PbHUX8F3vyBwp7/yC6udgIgRkCeZho3V14o4XPbI6Yb98fboZh7mJ9DRNldb0PyTN0="}]},"_npmUser":{"name":"tfive","email":"Pooyan.tfive@ymail.com"},"directories":{},"maintainers":[{"name":"tfive","email":"Pooyan.tfive@ymail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/edge-db_0.2.0_1782393816875_0.6715438775905833"},"_hasShrinkwrap":false}},"time":{"created":"2026-06-24T12:44:57.705Z","modified":"2026-06-25T13:23:37.275Z","0.1.0":"2026-06-24T12:44:58.042Z","0.2.0":"2026-06-25T13:23:37.111Z"},"bugs":{"url":"https://github.com/agile-nuxt/agile-nuxt-edge-backend/issues"},"author":{"name":"Agile Nuxt contributors"},"license":"MIT","homepage":"https://github.com/agile-nuxt/agile-nuxt-edge-backend#readme","keywords":["nuxt","nitro","database","embedded-database","typescript","backend","crud","cpanel","edge-db"],"repository":{"type":"git","url":"git+https://github.com/agile-nuxt/agile-nuxt-edge-backend.git","directory":"packages/edge-db"},"description":"A zero-setup pure TypeScript embedded database for Nuxt and Nitro apps, optimized for fast indexed CRUD.","maintainers":[{"name":"tfive","email":"Pooyan.tfive@ymail.com"}],"readme":"# `@agile-nuxt/edge-db`\n\nA zero-setup, pure TypeScript embedded database for schema-driven Node, Nuxt,\nand Nitro applications.\n\nCurrent release: `0.2.0`.\n\n## Installation\n\n```bash\npnpm add @agile-nuxt/edge-db\n```\n\nRequires Node.js 20 or newer and a writable persistent filesystem.\n\n## What It Is\n\n- Append-only, checksum-validated collection logs.\n- Cross-collection transaction journal and single-writer queue.\n- Primary, secondary, unique, and compound indexes.\n- Snapshots, compaction, recovery, diagnostics, backup, restore, and CLI.\n- Type inference from `defineSchema`.\n- Pure TypeScript with no native database dependency.\n\n## What It Is Not\n\nVersion 0.2 is not SQL, PostgreSQL, a multi-active-writer database, an analytical\nengine, or an ephemeral serverless database. It does not implement arbitrary joins.\n\n## Schema Example\n\n```ts\nimport {\n  createDatabase,\n  defineSchema,\n  type InferCreate,\n  type InferPublicCollection,\n  type InferSchema,\n  type InferUpdate\n} from '@agile-nuxt/edge-db'\n\nconst schema = defineSchema({\n  users: {\n    fields: {\n      id: 'id',\n      name: 'text',\n      email: 'text.unique',\n      passwordHash: 'text.private',\n      role: 'text.default:user',\n      createdAt: 'datetime',\n      updatedAt: 'datetime'\n    },\n    indexes: ['email', 'role', 'createdAt'],\n    unique: ['email'],\n    timestamps: true\n  }\n})\n\ntype AppData = InferSchema<typeof schema>\ntype NewUser = InferCreate<(typeof schema)['users']>\ntype UserPatch = InferUpdate<(typeof schema)['users']>\ntype PublicUser = InferPublicCollection<(typeof schema)['users']>\n\nconst db = createDatabase({\n  path: './storage/edge-db',\n  schema\n})\n\nawait db.boot()\n```\n\nSupported field types are `id`, `text`, `integer`, `real`, `boolean`, `json`,\nand `datetime`, with nullable, unique, private, default, and reference metadata.\n\n## Storage Model\n\n```text\nedge-db/\n  manifest.json\n  journal.ndjson\n  lock\n  archive/\n  collections/\n    users/\n      schema.json\n      snapshot-000123.json\n      log-000002.ndjson\n      archive/\n```\n\nManifests, schemas, snapshots, and log records carry format versions. Writes are\nappend-only and fsynced. Manifests and snapshots use temp files plus atomic rename.\n\n## CRUD\n\n```ts\nconst users = db.collection('users')\n\nconst user = await users.create({\n  name: 'Admin',\n  email: 'admin@example.com',\n  passwordHash: 'server-created-hash'\n})\n\nawait users.update(user.id, { role: 'admin' })\nawait users.findById(user.id)\nawait users.delete(user.id)\n```\n\nCollections also support `createMany`, `findFirst`, `findMany`, `count`, `exists`,\n`updateMany`, `deleteMany`, `softDelete`, `restore`, and `upsert`.\n\nPrivate fields are removed from normal query output. Trusted server-only code can\nuse the explicitly named internal read helpers when private data is required.\n\n## Declared Relation Includes\n\n```ts\nconst posts = await db.collection('posts').findMany({\n  include: {\n    author: { select: ['id', 'name'] }\n  }\n})\n```\n\nIncludes are limited to one level of declared `belongsTo` or `hasMany` metadata\nand bounded by `query.maxIncludeRecords`. They are not arbitrary or recursive joins.\n\n## Filters and Pagination\n\n```ts\nconst page = await users.findMany({\n  where: {\n    role: 'admin',\n    createdAt: { gte: '2026-01-01T00:00:00.000Z' }\n  },\n  orderBy: { createdAt: 'desc' },\n  limit: 20,\n  cursor: undefined,\n  select: ['id', 'name', 'email', 'role'],\n  debug: true\n})\n```\n\nOperators: `eq`, `ne`, `gt`, `gte`, `lt`, `lte`, `in`, `notIn`, `contains`,\n`startsWith`, `endsWith`, and `isNull`.\n\nLimits are enforced for result size and `in`/`notIn` items. Cursor pagination is\nused instead of offset pagination.\n\n## Indexes and Query Planner\n\nThe deterministic planner prefers:\n\n1. Primary ID index.\n2. Unique index.\n3. Compound index.\n4. Secondary index with the smallest candidate set.\n5. Scan fallback, when allowed.\n\nDevelopment logs warnings for scans and unindexed sorting. Production rejects\nexpensive unindexed queries by default unless `allowUnindexedQueries` is enabled.\n\n## Transactions\n\n```ts\nawait db.transaction(async (tx) => {\n  const user = await tx.collection('users').create({ /* ... */ })\n  await tx.collection('auditLogs').create({\n    userId: user.id,\n    action: 'created'\n  })\n})\n```\n\nRecovery applies only globally committed transactions. Failed transactions are\nrolled back in memory and ignored on replay.\n\n## Snapshots and Compaction\n\nSnapshots limit boot replay. Compaction pauses writes, writes and reload-verifies\nnew snapshots, atomically activates the manifest, then archives old logs.\n\n```ts\nawait db.compact()\n```\n\n## Backup and Restore\n\n```ts\nawait db.backup('/srv/backups/app-2026-06-24')\nawait db.restore('/srv/backups/app-2026-06-24')\n```\n\nDo not copy the live database folder while writes are active. Backup format 2\nstores and verifies a SHA-256 inventory of every file before restore activation.\nFormat 1 backups remain readable with a reduced-verification warning.\n\n## Schema Planning and Migrations\n\n```ts\nconst plan = await db.planSchemaChanges()\n\nconst migrated = createDatabase({\n  path: './storage/edge-db',\n  schema: nextSchema,\n  schemaSync: {\n    migrations: {\n      users: (record) => ({\n        ...record,\n        slug: String(record.email).toLocaleLowerCase()\n      })\n    }\n  }\n})\n```\n\nRequired fields, type changes, removed fields, and new unique constraints require\nexplicit handlers. Verified migration snapshots use a recovery marker so an\ninterruption can complete or roll back safely.\n\n## Diagnostics\n\n```ts\nconst diagnostics = await db.diagnostics()\n```\n\nDiagnostics include boot duration, recovery counts, lock state, permission checks,\nrecord/index counts, log and snapshot files, storage size, memory estimates, and\noptional query statistics.\n\nBoot also tests read, write, rename, delete, and exclusive-lock permissions.\nWritable recovery quarantines and truncates invalid tail bytes before accepting\nnew writes. Read-only mode reports damaged tails without modifying storage.\n\n## CLI\n\n```bash\nedge-db doctor --path ./storage/edge-db\nedge-db doctor --repair --path ./storage/edge-db\nedge-db schema diff --schema ./schema.json --path ./storage/edge-db\nedge-db inspect --path ./storage/edge-db\nedge-db backup ./backup --path ./storage/edge-db\nedge-db restore ./backup --path ./storage/edge-db\nedge-db compact --path ./storage/edge-db\nedge-db export ./data.json --path ./storage/edge-db\nedge-db import ./data.json --path ./storage/edge-db\nedge-db benchmark\n```\n\nThe backup command acquires the writer lock and refuses to copy an active database\nowned by another process.\n\n## Multi-Server Adaptability\n\nThe default `FileCoordinator` enforces one writable process. Multi-server\ndeployments can supply a `DatabaseCoordinator` backed by a strong lease service:\n\n```ts\nconst db = createDatabase({\n  path: '/shared/persistent/edge-db',\n  schema,\n  coordination: {\n    adapter: redisLeaseCoordinator,\n    ownerId: process.env.INSTANCE_ID,\n    autoRefreshReadOnly: true\n  }\n})\n```\n\nAll instances must share the same durable filesystem. The adapter must maintain\none renewable writer lease and report lease loss through `assertOwned()`. Change\nevents can refresh read-only replicas. This is one active writer across servers,\nnot simultaneous multi-writer file appends.\n\n## cPanel Notes\n\n- Use Nitro's `node-server` preset.\n- Store data outside `.output` and release directories.\n- Ensure the Node user can read, write, rename, delete, and lock the path.\n- Run one active writer. Multiple servers require shared durable storage and a\n  tested external writer-lease coordinator.\n- Use the backup API or CLI, not raw live-folder copies.\n\n## API Reference\n\nPublic exports include:\n\n- `createDatabase`\n- `defineSchema`\n- `Database`\n- `Collection`\n- `EdgeDbError`\n- `diagnoseStorage`\n- `restoreBackup`\n- `verifyBackup`\n- `InferCollection`\n- `InferCreate`\n- `InferUpdate`\n- `InferPublicCollection`\n- `InferSchema`\n- `DatabaseCoordinator`\n- schema planning and migration types\n- query, schema, diagnostics, relation, and logger types\n\n## Limitations\n\nNot for simultaneous multi-writer operation, uncoordinated network filesystems,\nanalytical workloads, arbitrary SQL, PostgreSQL-style joins, ephemeral filesystems,\nor datasets that cannot fit records and configured indexes in one Node process.\n\nSee the [root documentation](../../README.md) for disaster recovery, deployment,\npublishing, and the GitHub-only quickstart template.\n","readmeFilename":"README.md"}