{"_id":"@edgelite/edgelite","name":"@edgelite/edgelite","dist-tags":{"latest":"0.2.0"},"versions":{"0.2.0":{"name":"@edgelite/edgelite","version":"0.2.0","description":"edgedb meets sqlite","type":"module","publishConfig":{"access":"public"},"main":"./dist/index.js","types":"./dist/index.d.ts","exports":{".":{"import":"./dist/index.js","types":"./dist/index.d.ts"},"./codegen":{"import":"./dist/codegen/builders.js","types":"./dist/codegen/builders.d.ts"}},"bin":{"edgelite":"cli/index.ts"},"dependencies":{"@electric-sql/pglite":"^0.2.0","peggy":"^5.1.0"},"keywords":["edgedb","pglite","postgres","query-builder","schema","migrations","typescript"],"scripts":{"build":"tsc","dev":"tsx src/index.ts","test":"vitest","test:watch":"vitest --watch","test:coverage":"vitest --coverage","lint":"biome ci . && eslint . --max-warnings=0","lint:fix":"biome check --write . && eslint --fix .","format":"biome format --write .","typecheck":"tsc --noEmit","check":"pnpm typecheck && pnpm lint","depcheck":"depcheck --config=.depcheckrc.json","docs:start":"docusaurus start","docs:build":"docusaurus build","docs:serve":"docusaurus serve","docs:clear":"docusaurus clear","prepare":"husky","prepublishOnly":"pnpm build && pnpm typecheck"},"devDependencies":{"@biomejs/biome":"^1.9.4","@docusaurus/core":"^3.8.0","@docusaurus/preset-classic":"^3.8.0","@docusaurus/types":"^3.8.0","@types/node":"^22.0.0","@vitest/coverage-v8":"^3.0.0","depcheck":"^1.4.7","docusaurus-plugin-llms":"^0.4.0","docusaurus-plugin-typedoc":"^1.2.0","eslint":"^9.28.0","eslint-import-resolver-typescript":"^4.4.4","eslint-plugin-import-x":"^4.12.2","eslint-plugin-no-secrets":"^1.1.2","eslint-plugin-sonarjs":"^3.0.2","eslint-plugin-unicorn":"^56.0.1","husky":"^9.1.7","lint-staged":"^15.5.2","react":"^18.0.0","react-dom":"^18.0.0","tsx":"^4.19.2","typedoc":"^0.27.0","typescript":"^5.8.3","typescript-eslint":"^8.32.1","vitest":"^3.0.0"},"author":{"name":"Joe Black","email":"me@joeblack.nyc"},"license":"MIT","repository":{"type":"git","url":"git+https://github.com/joeblackwaslike/edgelite.git"},"engines":{"node":">=22"},"pnpm":{"onlyBuiltDependencies":["@biomejs/biome","core-js","esbuild","unrs-resolver"]},"packageManager":"pnpm@11.0.8","lint-staged":{"*.{ts,js,json,md}":["biome check --write --no-errors-on-unmatched --files-ignore-unknown=true"],"*.ts":["eslint --fix --max-warnings=0 --no-warn-ignored"]},"_id":"@edgelite/edgelite@0.2.0","gitHead":"f12e43f1c0d1ece30d574a263ee9380bb964b776","bugs":{"url":"https://github.com/joeblackwaslike/edgelite/issues"},"homepage":"https://github.com/joeblackwaslike/edgelite#readme","_nodeVersion":"22.22.3","_npmVersion":"10.9.8","dist":{"integrity":"sha512-Z0iLqiGOKMqJe5sXLu0p0IibVyPMPxyDGNDbsNXkxMJEmpVeu4m/hzE9K3zwpe/m5h5xe030/ejfe8h6TTTEAA==","shasum":"bfbbc997613fd23298cf849652402af11fe004e5","tarball":"https://registry.npmjs.org/@edgelite/edgelite/-/edgelite-0.2.0.tgz","fileCount":116,"unpackedSize":174570,"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@edgelite%2fedgelite@0.2.0","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEUCIQC3q8bcyMPylrr3/aQU47CMtrwEGa2FAZJBUoAYRdUGDQIgfRv8sqll607pT4fHrO4Z3wfkRSUObjWMtbiXxenXR88="}]},"_npmUser":{"name":"joeblackwaslike2","email":"joeblackwaslike@me.com"},"directories":{},"maintainers":[{"name":"joeblackwaslike2","email":"joeblackwaslike@me.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/edgelite_0.2.0_1781283742142_0.24455429626757752"},"_hasShrinkwrap":false}},"time":{"created":"2026-06-12T17:02:21.904Z","0.2.0":"2026-06-12T17:02:22.295Z","modified":"2026-06-12T17:02:22.866Z"},"maintainers":[{"name":"joeblackwaslike2","email":"joeblackwaslike@me.com"}],"description":"edgedb meets sqlite","homepage":"https://github.com/joeblackwaslike/edgelite#readme","keywords":["edgedb","pglite","postgres","query-builder","schema","migrations","typescript"],"repository":{"type":"git","url":"git+https://github.com/joeblackwaslike/edgelite.git"},"author":{"name":"Joe Black","email":"me@joeblack.nyc"},"bugs":{"url":"https://github.com/joeblackwaslike/edgelite/issues"},"license":"MIT","readme":"# EdgeLite\n\n[![npm](https://img.shields.io/npm/v/@edgelite/edgelite)](https://npmjs.com/package/@edgelite/edgelite)\n[![CI](https://github.com/joeblackwaslike/edgelite/actions/workflows/ci.yml/badge.svg)](https://github.com/joeblackwaslike/edgelite/actions/workflows/ci.yml)\n[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](LICENSE)\n\nEdgeDB-style developer experience on [PGlite](https://pglite.dev) — SDL schema, TypeScript query builder, migration CLI. No server, no concurrency, single data directory on disk.\n\n## Install\n\n```bash\nbun add @edgelite/edgelite\n```\n\n## 5-minute quickstart\n\n### 1. Write your schema — `dbschema/schema.esdl`\n\n```sdl\nscalar type NodeKind extending enum<note, file_chunk>;\nscalar type NodeStatus extending enum<pending, live, pruned>;\n\ntype Node {\n  required kind:       NodeKind;\n  required status:     NodeStatus { default := 'pending' };\n  required content:    str        { default := '' };\n  required created_at: int64;\n  required updated_at: int64;\n}\n```\n\n### 2. Generate the query builder\n\n```bash\nbunx edgelite codegen dbschema/schema.esdl\n# → generates dbschema/edgelite.ts\n```\n\n### 3. Create and apply the initial migration\n\n```bash\nbunx edgelite migration create   # generates dbschema/migrations/00001-*.sql\nbunx edgelite migration apply    # applies it to your local PGlite DB\n```\n\n### 4. Query\n\n```typescript\nimport { openDb } from '@edgelite/edgelite';\nimport e from './dbschema/edgelite.js';\n\nconst db = await openDb('./my-db', './dbschema/schema.esdl', { autoMigrate: true });\n\n// Insert\nconst node = await db.run(e.insert(e.Node, {\n  kind: 'note', content: 'hello world',\n  created_at: Date.now(), updated_at: Date.now(),\n}));\n\n// Select\nconst notes = await db.run(e.select(e.Node, n => ({\n  id: true, content: true, status: true,\n  filter: e.op(n.kind, '=', 'note'),\n})));\n\n// Update\nawait db.run(e.update(e.Node, n => ({\n  filter: e.op(n.id, '=', node.id),\n  set: { status: 'live', updated_at: Date.now() },\n})));\n\n// Count\nconst pending = await db.run(e.count(e.Node, n => ({\n  filter: e.op(n.status, '=', 'pending'),\n})));\n\nawait db.close();\n```\n\n## SDL Reference (v1)\n\n### Scalar types\n\n| SDL type | Postgres type |\n| --- | --- |\n| `str` | `TEXT` |\n| `int64` | `BIGINT` |\n| `bool` | `BOOLEAN` |\n| `json` | `JSONB` |\n| `vector(N)` | `vector(N)` (pgvector) |\n\n### Enums\n\n```sdl\nscalar type Status extending enum<pending, live, pruned>;\n```\n\nEnums are enforced at the TypeScript layer only (no DB `CHECK` constraint). Passing an invalid value to the generated query builder is a compile error.\n\n### Properties\n\n```sdl\ntype Node {\n  required content: str;              # NOT NULL\n  source_uri:       str;              # nullable\n  required mtime:   int64 { default := 0 };  # with default\n}\n```\n\n### Links (foreign keys)\n\n```sdl\ntype Node {\n  parent: Node;  # → parent_id TEXT REFERENCES nodes(id)\n}\n```\n\nOne level of link traversal is supported in `select`:\n\n```typescript\ndb.run(e.select(e.Node, n => ({\n  id: true, content: true,\n  parent: { id: true },  // joins nodes table once\n  filter: e.op(n.status, '=', 'live'),\n})));\n```\n\n### Indexes\n\n```sdl\nindex fts on (.content);              # full-text search via tsvector\nindex vec on (.embedding) using ivfflat;  # pgvector approximate NN\n```\n\n### Constraints\n\n```sdl\nconstraint exclusive on ((.src, .dst, .kind));  # → UNIQUE(src_id, dst_id, kind)\n```\n\n## Query Builder Cheatsheet\n\n```typescript\nimport e from './dbschema/edgelite.js';\n\n// SELECT\ne.select(e.Node, n => ({\n  id: true, content: true,\n  parent: { id: true },            // link traversal (one level)\n  filter: e.op(n.status, '=', 'live'),\n  order_by: { expr: n.created_at, dir: 'DESC' },\n  limit: 20,\n}))\n\n// INSERT\ne.insert(e.Node, { kind: 'note', content: 'hello', ... })\n\n// INSERT OR IGNORE (unique constraint)\ne.insert(e.Edge, { src: id1, dst: id2, kind: 'derived_from', ... }).unlessConflict()\n\n// UPDATE\ne.update(e.Node, n => ({\n  filter: e.op(n.id, '=', id),\n  set: { status: 'pruned', updated_at: Date.now() },\n}))\n\n// COUNT\ne.count(e.Node, n => ({ filter: e.op(n.status, '=', 'pending') }))\n\n// FILTER HELPERS\ne.all(e.op(n.status, '=', 'live'), e.op(n.kind, '=', 'note'))  // AND\ne.any(e.op(n.status, '=', 'stale'), e.op(n.status, '=', 'pruned'))  // OR\n\n// NEIGHBORS (bidirectional edge traversal)\ne.neighbors(nodeId, { edgeKinds: ['derived_from', 'references'] })\n\n// FULL-TEXT SEARCH\ne.fts(e.Node, 'search term')\n```\n\n## Migrations\n\n```bash\nedgelite migration create   # diff schema.esdl vs DB → writes dbschema/migrations/000N-*.sql\nedgelite migration apply    # apply pending non-destructive migrations\nedgelite migration apply --allow-destructive  # also apply DROP TABLE / DROP COLUMN\nedgelite migration status   # list applied vs pending (⚠ warns on DESTRUCTIVE)\n```\n\nMigrations are explicit, numbered `.sql` files committed to git. `migration create` never modifies your DB — it only writes a file.\n\n### autoMigrate\n\n```typescript\n// Applies committed pending migrations on open (skips DESTRUCTIVE ones)\nconst db = await openDb('./my-db', './schema.esdl', { autoMigrate: true });\n```\n\n`autoMigrate: true` is safe for plugins and local tools. It never generates migration files.\n\n### Destructive migrations\n\nMigrations that contain `DROP TABLE` or `DROP COLUMN` are marked with a `-- DESTRUCTIVE` header. They are skipped by `autoMigrate` and plain `migration apply`. Apply them explicitly after backing up your data directory:\n\n```bash\ncp -r ./my-db ./my-db-backup\nedgelite migration apply --allow-destructive\n```\n\n## License\n\n[MIT](LICENSE) © 2026 [Joe Black](https://github.com/joeblackwaslike)\n","readmeFilename":"README.md","_rev":"1-ae9d42089828b67a21e72e8865c3263b"}