CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/npm-dexie

A minimalistic wrapper for IndexedDB providing reactive queries, transactions, and schema management

Pending

Quality

Pending

Does it follow best practices?

Impact

Pending

No eval scenarios have been run

Overview
Eval results
Files

table-operations.mddocs/

Table Operations

CRUD operations, bulk operations, and query initiation for database tables.

Capabilities

Get Operation

Retrieves a single record by primary key.

/**
 * Retrieves a single record by primary key
 * @param key - Primary key value
 * @returns Promise resolving to the record or undefined if not found
 */
get(key: IndexableType): Promise<T | undefined>;

Usage Examples:

// Get by primary key
const friend = await db.friends.get(1);
if (friend) {
  console.log(`Found: ${friend.name}, age ${friend.age}`);
} else {
  console.log("Friend not found");
}

// Get with string key
const user = await db.users.get("alice@example.com");

// Get with compound key
const message = await db.messages.get([userId, timestamp]);

Add Operation

Inserts a new record into the table.

/**
 * Inserts a new record into the table
 * @param item - Object to insert
 * @param key - Optional explicit key (for non-auto-increment tables)
 * @returns Promise resolving to the primary key of the inserted record
 */
add(item: TInsertType, key?: TKey): Promise<TKey>;

Usage Examples:

// Add with auto-increment key
const friendId = await db.friends.add({
  name: "Alice",
  age: 25,
  email: "alice@example.com"
});
console.log("New friend ID:", friendId);

// Add with explicit key
await db.settings.add({ theme: "dark", notifications: true }, "user-preferences");

// Add with error handling
try {
  await db.friends.add({ name: "Bob", age: 30 });
} catch (error) {
  if (error.name === "ConstraintError") {
    console.error("Friend already exists");
  }
}

Put Operation

Inserts a new record or updates an existing one.

/**
 * Inserts a new record or updates an existing one
 * @param item - Object to insert or update
 * @param key - Optional explicit key
 * @returns Promise resolving to the primary key
 */
put(item: TInsertType, key?: TKey): Promise<TKey>;

Usage Examples:

// Put with auto-increment (insert or update)
const friendId = await db.friends.put({
  id: 1,
  name: "Alice Updated",
  age: 26,
  email: "alice.new@example.com"
});

// Put without ID (will insert new record)
const newId = await db.friends.put({
  name: "Charlie",
  age: 35,
  email: "charlie@example.com"
});

// Put with explicit key
await db.settings.put({ theme: "light", notifications: false }, "user-preferences");

Update Operation

Updates an existing record by primary key.

/**
 * Updates an existing record by primary key
 * @param key - Primary key of record to update
 * @param changes - Object containing changes to apply
 * @returns Promise resolving to 1 if updated, 0 if record not found
 */
update(key: IndexableType, changes: UpdateSpec<T>): Promise<number>;

type UpdateSpec<T> = Partial<T> | { [keyPath: string]: any | PropModification };

Usage Examples:

// Update specific fields
const updated = await db.friends.update(1, {
  age: 26,
  email: "alice.updated@example.com"
});
console.log(updated ? "Friend updated" : "Friend not found");

// Update with keypath notation
await db.friends.update(1, {
  "address.city": "New York",
  "preferences.theme": "dark"
});

// Update with PropModification
import { add, remove } from "dexie";
await db.friends.update(1, {
  age: add(1), // Increment age by 1
  tags: add(["new-tag"]), // Add to array
  points: remove(10) // Subtract 10 points
});

// Conditional update
const friend = await db.friends.get(1);
if (friend && friend.age < 30) {
  await db.friends.update(1, { category: "young-adult" });
}

Delete Operation

Deletes a record by primary key.

/**
 * Deletes a record by primary key
 * @param key - Primary key of record to delete
 * @returns Promise that resolves when deletion completes
 */
delete(key: IndexableType): Promise<void>;

Usage Examples:

// Delete by primary key
await db.friends.delete(1);

// Delete with confirmation
const friend = await db.friends.get(1);
if (friend) {
  await db.friends.delete(1);
  console.log(`Deleted friend: ${friend.name}`);
}

// Delete with error handling
try {
  await db.friends.delete(1);
} catch (error) {
  console.error("Failed to delete friend:", error);
}

Clear Operation

Deletes all records from the table.

/**
 * Deletes all records from the table
 * @returns Promise that resolves when all records are deleted
 */
clear(): Promise<void>;

Usage Examples:

// Clear entire table
await db.friends.clear();
console.log("All friends deleted");

// Clear with confirmation
const count = await db.friends.count();
if (count > 0) {
  const confirmed = confirm(`Delete all ${count} friends?`);
  if (confirmed) {
    await db.friends.clear();
  }
}

Count Operation

Counts all records in the table.

/**
 * Counts all records in the table
 * @returns Promise resolving to the number of records
 */
count(): Promise<number>;

Usage Examples:

// Count all records
const totalFriends = await db.friends.count();
console.log(`Total friends: ${totalFriends}`);

// Use count for pagination
const pageSize = 10;
const totalRecords = await db.friends.count();
const totalPages = Math.ceil(totalRecords / pageSize);

ToArray Operation

Retrieves all records as an array.

/**
 * Retrieves all records as an array
 * @returns Promise resolving to array of all records
 */
toArray(): Promise<T[]>;

Usage Examples:

// Get all records
const allFriends = await db.friends.toArray();
console.log("All friends:", allFriends);

// Use with array methods
const names = (await db.friends.toArray()).map(f => f.name);
console.log("Friend names:", names);

Each Operation

Iterates through all records with a callback.

/**
 * Iterates through all records with a callback
 * @param callback - Function called for each record
 * @returns Promise that resolves when iteration completes
 */
each(callback: (obj: T, cursor: { key: any; primaryKey: TKey }) => void): Promise<void>;

Usage Examples:

// Iterate through all records
await db.friends.each((friend, cursor) => {
  console.log(`Friend: ${friend.name}, Primary Key: ${cursor.primaryKey}`);
});

// Early termination
await db.friends.each((friend, cursor) => {
  console.log(friend.name);
  if (friend.name === "Alice") {
    return false; // Stop iteration
  }
});

Bulk Add Operation

Inserts multiple records in a single operation.

/**
 * Inserts multiple records in a single operation
 * @param items - Array of objects to insert
 * @param keys - Optional array of explicit keys
 * @param options - Bulk operation options
 * @returns Promise resolving to the last inserted key
 */
bulkAdd(
  items: readonly TInsertType[], 
  keys?: readonly TKey[], 
  options?: BulkOptions
): Promise<TKey>;

interface BulkOptions {
  /** Return all keys instead of just the last one */
  allKeys?: boolean;
  /** Ignore individual success callbacks */
  ignoreOnsuccess?: boolean;
}

Usage Examples:

// Bulk add with auto-increment keys
const friends = [
  { name: "Alice", age: 25 },
  { name: "Bob", age: 30 },
  { name: "Charlie", age: 35 }
];
const lastKey = await db.friends.bulkAdd(friends);
console.log("Last inserted key:", lastKey);

// Bulk add with explicit keys
const settings = [
  { theme: "dark", notifications: true },
  { theme: "light", notifications: false }
];
const keys = ["user1-prefs", "user2-prefs"];
await db.settings.bulkAdd(settings, keys);

// Bulk add with all keys returned
const allKeys = await db.friends.bulkAdd(friends, undefined, { allKeys: true });
console.log("All inserted keys:", allKeys);

// Error handling
try {
  await db.friends.bulkAdd(friends);
} catch (error) {
  if (error.name === "BulkError") {
    console.log("Some items failed:", error.failures);
    console.log("Successful items:", error.successful);
  }
}

Bulk Put Operation

Inserts or updates multiple records in a single operation.

/**
 * Inserts or updates multiple records in a single operation
 * @param items - Array of objects to insert or update
 * @param keys - Optional array of explicit keys
 * @param options - Bulk operation options
 * @returns Promise resolving to the last key
 */
bulkPut(
  items: readonly TInsertType[], 
  keys?: readonly TKey[], 
  options?: BulkOptions
): Promise<TKey>;

Usage Examples:

// Bulk put (insert or update)
const friends = [
  { id: 1, name: "Alice Updated", age: 26 },
  { name: "David", age: 40 }, // New record (no ID)
  { id: 3, name: "Charlie Updated", age: 36 }
];
await db.friends.bulkPut(friends);

// Bulk put with explicit keys
const data = [
  { value: "setting1", enabled: true },
  { value: "setting2", enabled: false }
];
await db.settings.bulkPut(data, ["config1", "config2"]);

Bulk Update Operation

Updates multiple records by their keys.

/**
 * Updates multiple records by their keys
 * @param changes - Array of key-changes pairs
 * @returns Promise resolving to number of updated records
 */
bulkUpdate(changes: readonly {
  key: IndexableType;
  changes: UpdateSpec<T>;
}[]): Promise<number>;

Usage Examples:

// Bulk update multiple records
const updates = [
  { key: 1, changes: { age: 26, status: "active" } },
  { key: 2, changes: { age: 31, status: "inactive" } },
  { key: 3, changes: { email: "charlie.new@example.com" } }
];
const updatedCount = await db.friends.bulkUpdate(updates);
console.log(`Updated ${updatedCount} friends`);

// Bulk update with PropModification
import { add } from "dexie";
const incrementAges = [
  { key: 1, changes: { age: add(1) } },
  { key: 2, changes: { age: add(1) } },
  { key: 3, changes: { age: add(1) } }
];
await db.friends.bulkUpdate(incrementAges);

Bulk Delete Operation

Deletes multiple records by their keys.

/**
 * Deletes multiple records by their keys
 * @param keys - Array of primary keys to delete
 * @returns Promise that resolves when deletion completes
 */
bulkDelete(keys: readonly IndexableType[]): Promise<void>;

Usage Examples:

// Bulk delete by keys
const keysToDelete = [1, 3, 5, 7];
await db.friends.bulkDelete(keysToDelete);

// Delete all inactive users
const inactiveKeys = await db.friends
  .where("status")
  .equals("inactive")
  .primaryKeys();
await db.friends.bulkDelete(inactiveKeys);

Bulk Get Operation

Retrieves multiple records by their keys.

/**
 * Retrieves multiple records by their keys
 * @param keys - Array of primary keys to retrieve
 * @returns Promise resolving to array of records (undefined for missing keys)
 */
bulkGet(keys: readonly IndexableType[]): Promise<(T | undefined)[]>;

Usage Examples:

// Bulk get by keys
const keys = [1, 2, 3, 99]; // 99 might not exist
const friends = await db.friends.bulkGet(keys);
console.log("Retrieved friends:", friends); // [friend1, friend2, friend3, undefined]

// Filter out undefined results
const existingFriends = friends.filter(f => f !== undefined);

// Bulk get with error handling
const safeKeys = [1, 2, 3];
const results = await db.friends.bulkGet(safeKeys);
results.forEach((friend, index) => {
  if (friend) {
    console.log(`Key ${safeKeys[index]}: ${friend.name}`);
  } else {
    console.log(`Key ${safeKeys[index]}: not found`);
  }
});

Query Initiation

Methods that start query chains.

/**
 * Creates a query on an indexed field
 * @param index - Name of the index to query
 * @returns WhereClause for building the query
 */
where(index: string): WhereClause<T, TKey, TInsertType>;

/**
 * Filters records using a predicate function
 * @param predicate - Function that returns true for records to include
 * @returns Collection of filtered records
 */
filter(predicate: (obj: T) => boolean): Collection<T, TKey, TInsertType>;

/**
 * Orders records by an indexed field
 * @param index - Name of the index to order by
 * @returns Collection ordered by the specified index
 */
orderBy(index: string): Collection<T, TKey, TInsertType>;

Usage Examples:

// Query by index
const adults = await db.friends.where("age").above(18).toArray();

// Filter with function
const activeUsers = await db.friends
  .filter(friend => friend.status === "active")
  .toArray();

// Order by index
const sortedFriends = await db.friends.orderBy("name").toArray();

// Chain operations
const youngActiveUsers = await db.friends
  .where("age")
  .below(30)
  .filter(friend => friend.status === "active")
  .limit(10)
  .toArray();

Table Schema Information

Access to table metadata and schema information.

interface Table<T, TKey, TInsertType> {
  /** Table name */
  readonly name: string;
  /** Table schema information */
  readonly schema: TableSchema;
  /** Database reference */
  readonly db: Dexie;
  /** Event hooks for CRUD operations */
  readonly hook: TableHooks<T, TKey, TInsertType>;
}

interface TableSchema {
  /** Table name */
  name: string;
  /** Primary key specification */
  primKey: IndexSpec;
  /** Array of index specifications */
  indexes: IndexSpec[];
  /** Mapped class constructor (if using mapToClass) */
  mappedClass?: Function;
}

interface IndexSpec {
  /** Index name */
  name: string;
  /** Key path (string or array for compound indexes) */
  keyPath: string | string[];
  /** Whether index enforces uniqueness */
  unique?: boolean;
  /** Whether index supports multi-entry (arrays) */
  multi?: boolean;
  /** Whether index is auto-incrementing */
  auto?: boolean;
  /** Whether index is compound */
  compound?: boolean;
  /** Original schema string */
  src: string;
}

Usage Examples:

// Access table metadata
console.log("Table name:", db.friends.name);
console.log("Primary key:", db.friends.schema.primKey);
console.log("Indexes:", db.friends.schema.indexes);

// Check if table has specific index
const hasAgeIndex = db.friends.schema.indexes.some(idx => idx.name === "age");
console.log("Has age index:", hasAgeIndex);

// Get all index names
const indexNames = db.friends.schema.indexes.map(idx => idx.name);
console.log("Available indexes:", indexNames);

Install with Tessl CLI

npx tessl i tessl/npm-dexie

docs

database-management.md

error-handling.md

events.md

index.md

live-queries.md

query-building.md

schema-management.md

table-operations.md

utility-functions.md

tile.json