npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@azarov-serge/indexed-db-client

v1.0.2

Published

A simple IndexedDB client for working with IndexedDB. Designed as ORM.

Downloads

37

Readme

IndexedDbClient

A simple and powerful IndexedDB client for working with IndexedDB in the browser. Designed as an ORM-like interface that makes IndexedDB operations intuitive and type-safe.

🇷🇺 Читать на русском языке

Features

  • 🚀 Simple API - Intuitive ORM-like interface
  • 🔒 Type Safety - Full TypeScript support with generics
  • 📊 Indexed Queries - Support for custom indexes and range queries
  • 🔄 Promise-based - All operations return promises
  • 🎯 Flexible Configuration - Multiple ways to configure the client
  • 🛡️ Error Handling - Comprehensive error handling and validation

Installation

npm install @azarov-serge/indexed-db-client

Quick Start

import { IndexedDbClient } from '@azarov-serge/indexed-db-client';

// Define your types
type Task = {
  id: number;
  name: string;
  isDone: boolean;
  createdAt: Date;
};

// Configure the client
const config = {
  dbName: 'myApp',
  dbVersion: 1,
  storageNames: ['tasks'] as const,
  storeNameToIndexes: {
    tasks: [
      { index: 'tasksName', key: 'name' },
      { index: 'tasksCreatedAt', key: 'createdAt' }
    ]
  }
};

// Create and initialize
const client = new IndexedDbClient(config);
await client.init();

// Use the client
const taskId = await client.from('tasks').insert({
  name: 'Learn IndexedDB',
  isDone: false,
  createdAt: new Date()
});

Table of Contents

Configuration

1. Define Types

First, define your storage names and data types:

// types.ts
export type StorageName = 'tasks' | 'categories';

export type Task = {
  id: number;
  name: string;
  isDone: boolean;
  createdAt: Date;
  categoryId?: number;
};

export type Category = {
  id: number;
  name: string;
  color: string;
};

// Define index names for type safety
export type TaskIndexName = 'tasksName' | 'tasksCreatedAt' | 'tasksCategoryId';
export type CategoryIndexName = 'categoriesName';

2. Create Configuration

// config.ts
import { IDBConfig } from '@azarov-serge/indexed-db-client';
import { StorageName, TaskIndexName, CategoryIndexName } from './types';

export const indexedDbConfig: IDBConfig<StorageName, TaskIndexName | CategoryIndexName> = {
  dbName: 'myApp',
  dbVersion: 1,
  storageNames: ['tasks', 'categories'],
  storeNameToIndexes: {
    tasks: [
      { index: 'tasksName', key: 'name' },
      { index: 'tasksCreatedAt', key: 'createdAt' },
      { index: 'tasksCategoryId', key: 'categoryId' }
    ],
    categories: [
      { index: 'categoriesName', key: 'name', unique: true }
    ]
  }
};

3. Initialize Client

You have two ways to configure the client:

Method 1: Constructor Configuration

const client = new IndexedDbClient(indexedDbConfig);
await client.init();

Method 2: Separate Configuration

const client = new IndexedDbClient();
await client.configure(indexedDbConfig).init();

API Reference

Constructor

new IndexedDbClient<StorageName, IndexName>(config?)
  • config (optional): Initial configuration object

Methods

configure(config)

Configure the client after instantiation.

client.configure(config).init();

init()

Initialize the database connection.

await client.init();

from(storageName)

Select a storage to work with. Returns the client for chaining.

client.from('tasks')

insert<T>(data)

Insert a new record. Returns the generated ID.

const id = await client.from('tasks').insert<Task>({
  name: 'New Task',
  isDone: false,
  createdAt: new Date()
});

select<T>(params?)

Select records from storage.

// Select all records
const allTasks = await client.from('tasks').select<Task>();

// Select with parameters
const tasks = await client.from('tasks').select<Task>({
  key: 'tasksName',
  value: 'Task Name',
  count: 10,
  orderBy: 'desc'
});

Select Parameters:

  • key: Index name or 'id' for primary key
  • value: Value to search for or IDBKeyRange
  • count: Limit number of results
  • orderBy: 'asc' (default) or 'desc'

update<T>(data)

Update an existing record.

await client.from('tasks').update<Task>({
  id: 1,
  name: 'Updated Task',
  isDone: true,
  createdAt: new Date()
});

delete(params)

Delete records by ID or index.

// Delete by ID
await client.from('tasks').delete({ key: 'id', value: 1 });

// Delete by index
await client.from('tasks').delete({ 
  key: 'tasksName', 
  value: 'Task Name' 
});

createStorage(storageName)

Create a new storage (object store).

await client.createStorage('newStorage');

deleteStorage(storageName)

Delete a storage.

await client.deleteStorage('tasks');

deleteDb()

Delete the entire database.

await client.deleteDb();

Properties

isInited

Check if the client is initialized.

if (client.isInited) {
  // Client is ready to use
}

Examples

Basic CRUD Operations

import { IndexedDbClient } from '@azarov-serge/indexed-db-client';

// Setup
const client = new IndexedDbClient(config);
await client.init();

// Create
const taskId = await client.from('tasks').insert({
  name: 'Learn TypeScript',
  isDone: false,
  createdAt: new Date()
});

// Read
const task = await client.from('tasks').select<Task>({ 
  key: 'id', 
  value: taskId 
});

// Update
await client.from('tasks').update({
  id: taskId,
  name: 'Learn TypeScript (Updated)',
  isDone: true,
  createdAt: new Date()
});

// Delete
await client.from('tasks').delete({ key: 'id', value: taskId });

Advanced Queries

// Select all tasks ordered by creation date (newest first)
const recentTasks = await client
  .from('tasks')
  .select<Task>({ orderBy: 'desc' });

// Select first 5 tasks
const firstFive = await client
  .from('tasks')
  .select<Task>({ count: 5 });

// Select tasks by name
const tasksByName = await client
  .from('tasks')
  .select<Task>({ 
    key: 'tasksName', 
    value: 'Learn TypeScript' 
  });

// Select tasks created after a specific date
const recentTasks = await client
  .from('tasks')
  .select<Task>({
    key: 'tasksCreatedAt',
    value: IDBKeyRange.lowerBound(new Date('2024-01-01'))
  });

// Select tasks in a date range
const tasksInRange = await client
  .from('tasks')
  .select<Task>({
    key: 'tasksCreatedAt',
    value: IDBKeyRange.bound(
      new Date('2024-01-01'),
      new Date('2024-12-31')
    )
  });

// Select tasks by category
const tasksByCategory = await client
  .from('tasks')
  .select<Task>({
    key: 'tasksCategoryId',
    value: 1
  });

Working with Multiple Storages

// Insert category
const categoryId = await client.from('categories').insert({
  name: 'Work',
  color: '#ff0000'
});

// Insert task with category
const taskId = await client.from('tasks').insert({
  name: 'Complete project',
  isDone: false,
  createdAt: new Date(),
  categoryId: categoryId
});

// Get all categories
const categories = await client.from('categories').select<Category>();

// Get tasks by category
const workTasks = await client
  .from('tasks')
  .select<Task>({
    key: 'tasksCategoryId',
    value: categoryId
  });

Error Handling

try {
  await client.init();
  
  const taskId = await client.from('tasks').insert({
    name: 'Task',
    isDone: false,
    createdAt: new Date()
  });
  
  console.log('Task created with ID:', taskId);
} catch (error) {
  console.error('Error:', error);
  
  if (error instanceof Error) {
    switch (error.message) {
      case 'Config is not exist':
        console.error('Client not configured');
        break;
      case 'DB is not init':
        console.error('Database not initialized');
        break;
      case 'No storage selected':
        console.error('No storage selected');
        break;
      default:
        console.error('Unknown error:', error.message);
    }
  }
}

Advanced Usage

Custom Indexes

// Create unique index
const config = {
  // ... other config
  storeNameToIndexes: {
    users: [
      { index: 'usersEmail', key: 'email', unique: true },
      { index: 'usersUsername', key: 'username', unique: true }
    ]
  }
};

// Use unique index
const user = await client
  .from('users')
  .select<User>({ 
    key: 'usersEmail', 
    value: '[email protected]' 
  });

Database Versioning

// Increment version to trigger schema updates
const config = {
  dbName: 'myApp',
  dbVersion: 2, // Increased from 1
  // ... rest of config
};

// The client will automatically handle schema migrations
await client.init();

Bulk Operations

// Insert multiple records
const tasks = [
  { name: 'Task 1', isDone: false, createdAt: new Date() },
  { name: 'Task 2', isDone: false, createdAt: new Date() },
  { name: 'Task 3', isDone: false, createdAt: new Date() }
];

const ids = await Promise.all(
  tasks.map(task => client.from('tasks').insert(task))
);

// Delete multiple records
await Promise.all(
  ids.map(id => client.from('tasks').delete({ key: 'id', value: id }))
);

Browser Support

This library works in all modern browsers that support IndexedDB:

  • Chrome 23+
  • Firefox 16+
  • Safari 10+
  • Edge 12+
  • Internet Explorer 10+

License

MIT

Contributing

Contributions are welcome! Please feel free to submit a Pull Request.


🇷🇺 Читать на русском языке