{"id":16691,"library":"tedb","title":"TeDB: TypeScript Embedded Database","description":"TeDB (TypeScript Embedded Database) is an embedded database designed specifically for TypeScript applications, supporting various environments like Node.js, Electron, and webkit. It's currently at version 0.5.1, with a development cadence that includes regular minor fixes and improvements. A key differentiator is its pluggable storage architecture, allowing developers to implement custom storage drivers for disk persistence, in-memory operations, or even browser-based solutions like IndexedDB. Unlike some other JavaScript embedded databases, TeDB leverages an AVL balanced binary tree to index only document `_id`s and specified indexed field values in memory, preventing potential out-of-memory issues with very large datasets, as the actual document data is managed by the storage driver. All operations are Promise-based, and the library is written entirely in TypeScript, providing strong type safety.","status":"active","version":"0.5.1","language":"javascript","source_language":"en","source_url":"https://github.com/tsturzl/teDB","tags":["javascript","typescript","embedded","database","db","electron"],"install":[{"cmd":"npm install tedb","lang":"bash","label":"npm"},{"cmd":"yarn add tedb","lang":"bash","label":"yarn"},{"cmd":"pnpm add tedb","lang":"bash","label":"pnpm"}],"dependencies":[{"reason":"Common utility methods moved to this package as of v0.5.0 for reusability across TeDB-related projects.","package":"tedb-utils","optional":false},{"reason":"Underlying AVL balanced binary tree implementation used for indexing documents.","package":"binary-type-tree","optional":false}],"imports":[{"note":"Primary class for interacting with the database. CommonJS `require` works but `import` is preferred for TypeScript projects.","wrong":"const Datastore = require('tedb').Datastore;","symbol":"Datastore","correct":"import { Datastore } from 'tedb';"},{"note":"Used for chaining queries and operations. Named import is standard.","wrong":"import * as tedb from 'tedb'; const cursor = new tedb.Cursor();","symbol":"Cursor","correct":"import { Cursor } from 'tedb';"},{"note":"A utility function moved into `tedb-utils` and re-exported. Many other utilities like `isEmpty`, `getDate` are also available as named imports.","symbol":"range","correct":"import { range } from 'tedb';"},{"note":"Useful for accessing all exported members when you prefer a namespace approach, rather than individual named imports. TeDB does not offer a default export.","wrong":"import tedb from 'tedb';","symbol":"* as tedb","correct":"import * as tedb from 'tedb';"}],"quickstart":{"code":"import { Datastore } from 'tedb';\n\n// A minimal in-memory storage driver example\nclass InMemoryStorageDriver {\n  private data: Map<string, any> = new Map();\n  constructor(private collectionName: string) {}\n  async read(key: string): Promise<any> { return this.data.get(key); }\n  async write(key: string, value: any): Promise<boolean> { this.data.set(key, value); return true; }\n  async remove(key: string): Promise<boolean> { return this.data.delete(key); }\n  async exists(key: string): Promise<boolean> { return this.data.has(key); }\n  async getAllKeys(): Promise<string[]> { return Array.from(this.data.keys()); }\n}\n\nasync function runDbExample() {\n  const storageDriver = new InMemoryStorageDriver('myCollection');\n  const db = new Datastore({ \n    storage: storageDriver, \n    collection: 'myCollection' \n  });\n\n  // Load any existing data (for persistent drivers)\n  await db.loadDatabase();\n\n  // Insert a document\n  const doc1 = await db.insert({ name: 'Alice', age: 30 });\n  console.log('Inserted doc1:', doc1);\n\n  // Find documents\n  const foundDocs = await db.find({ age: { $gt: 25 } }).exec();\n  console.log('Found docs (age > 25):', foundDocs);\n\n  // Update a document\n  const updatedCount = await db.update({ _id: doc1._id }, { $set: { age: 31 } });\n  console.log('Updated documents count:', updatedCount);\n\n  // Find the updated document\n  const updatedDoc = await db.findOne({ _id: doc1._id }).exec();\n  console.log('Updated doc1:', updatedDoc);\n\n  // Remove a document and sanitize indices\n  const removedCount = await db.remove({ _id: doc1._id });\n  console.log('Removed documents count:', removedCount);\n  await db.sanitize(); // Recommended after remove\n\n  const allDocs = await db.find({}).exec();\n  console.log('All remaining docs:', allDocs);\n}\n\nrunDbExample().catch(console.error);","lang":"typescript","description":"Demonstrates initializing a TeDB Datastore with a custom in-memory storage driver, inserting, finding, updating, and removing documents, and the recommended `sanitize` operation."},"warnings":[{"fix":"When storing dates, save them as `dateObject.getTime()`. When querying, convert comparison dates to timestamps using `new Date().getTime()`.","message":"When querying with date fields using comparison operators like `$gt`, `$gte`, `$lt`, or `$lte`, dates must be saved as numbers (e.g., using `Date.prototype.getTime()`) to ensure proper comparison within the index.","severity":"gotcha","affected_versions":">=0.5.1"},{"fix":"Upgrade TeDB to version 0.5.0 or newer to get the fix. Rebuilding indices might be necessary if data corruption occurred.","message":"Older versions (prior to 0.5.0) of TeDB had a major bug in the underlying `binary-type-tree` which could cause endless appending to non-unique indices, leading to stack overflows upon loading the index after sufficient data accumulation.","severity":"breaking","affected_versions":"<0.5.0"},{"fix":"Explicitly call `await datastore.sanitize()` after performing `remove` operations to ensure index integrity and prevent potential issues with querying or memory usage.","message":"After removing documents, indices might retain references to non-existent keys. It is recommended to call `datastore.sanitize()` to clean up these orphaned index entries.","severity":"gotcha","affected_versions":">=0.3.0"},{"fix":"Upgrade TeDB to version 0.2.16 or newer. If on an older version, avoid updating by matching on the same `_id` and ensure `sanitize()` is run regularly.","message":"In versions prior to 0.2.16, attempting to update a document by matching on its own `_id` could incorrectly cause the document to be removed from indices before the update was applied, leading to data inconsistencies.","severity":"gotcha","affected_versions":"<0.2.16"}],"env_vars":null,"last_verified":"2026-04-22T00:00:00.000Z","next_check":"2026-07-21T00:00:00.000Z","problems":[{"fix":"Upgrade TeDB to version 0.5.0 or higher. If the problem persists with existing data, you may need to manually inspect and potentially rebuild your database indices, or restore from a backup.","cause":"This error, especially on database load, indicates that the `binary-type-tree` index structure has become corrupted or excessively large due to a bug in older versions that caused endless appending to non-unique indices.","error":"RangeError: Maximum call stack size exceeded"},{"fix":"Ensure all date fields in your documents are stored as `number` (e.g., `new Date().getTime()`). When querying, convert your comparison dates to timestamps as well (e.g., `{ dateField: { $gt: new Date('2023-01-01').getTime() } }`).","cause":"Date objects are compared lexicographically or in unexpected ways if not stored as numerical timestamps, leading to inaccurate range queries.","error":"Query results are incorrect or missing when using $gt, $gte, $lt, $lte, $ne on date fields."},{"fix":"Always call `await datastore.sanitize()` after performing `remove` operations to ensure the indices are synchronized with the actual data in your storage driver.","cause":"After `remove` operations, the in-memory indices might still hold references to keys that no longer exist in the underlying storage if `sanitize()` is not called.","error":"Documents appear in query results after being removed, or index doesn't reflect actual data state."}],"ecosystem":"npm"}