Redux Database

0.0.20 · active · verified Wed Apr 22

Redux Database is a JavaScript library providing an in-memory, reducer-based relational database for client-side state management. It allows developers to organize application state in a structured, relational manner, similar to an SQL database, complete with queries and joins. The library ships with strong TypeScript typings, ensuring type safety for schema definitions, queries, and data manipulation. It supports immutable documents and offers plugins for seamless integration with Redux stores or can be used standalone, notably having no direct dependencies itself. Currently at version 0.0.20, its release cadence appears to be incremental, focusing on feature development and refinement rather than rapid major version changes. A key differentiator is its focus on client-side data normalization, offering a chainable query syntax, embedded relations for joins, and transaction support to optimize state updates and prevent performance issues from excessive dispatches. It aims to simplify complex client-side data challenges by providing a structured, queryable layer over the Redux state.

Common errors

Warnings

Install

Imports

Quickstart

Demonstrates defining a database schema, initializing a Redux store with the database reducer, performing transactional writes, and executing chainable queries including embedded relations.

import { createStore, combineReducers } from 'redux';
import { DB, emptyTable, createDatabaseReducer } from 'redux-database';

interface Item { id: string; name: string; categoryId?: string; }
interface Category { id: string; name: string; }

interface AppState {
  settings: { enableFeatureX: boolean; };
  data: {
    items: DataTable<Item>;
    categories: DataTable<Category>;
  };
}

const initialState: AppState = {
  settings: {
    enableFeatureX: true
  },
  data: {
    items: emptyTable,
    categories: emptyTable
  }
};

// Create the database reducer
const databaseReducer = createDatabaseReducer(initialState);

// Combine with other Redux reducers if any
const rootReducer = combineReducers({
  db: databaseReducer
});

const store = createStore(rootReducer);

// Get a DB instance from the current state
let db = new DB(store.getState().db);

// Example: Writing data using a transaction
store.dispatch(
  db.transaction((dispatch) => {
    dispatch(db.table('categories').insert({ id: 'cat1', name: 'Electronics' }));
    dispatch(db.table('items').insert({ id: 'item1', name: 'Laptop', categoryId: 'cat1' }));
    dispatch(db.table('items').insert({ id: 'item2', name: 'Mouse', categoryId: 'cat1' }));
    dispatch(db.set('enableFeatureX', false));
  })
);

// Refresh DB instance after state update
db = new DB(store.getState().db);

// Example: Reading data
console.log('Feature X enabled:', db.get('enableFeatureX'));

const allItems = db.table('items').all;
console.log('All Items:', allItems);

const electronicsItems = db
  .query('items')
  .where({ categoryId: 'cat1' })
  .embed('category', 'categories', 'categoryId')
  .all;

console.log('Electronics Items with Category:', electronicsItems);

// Update an item
store.dispatch(db.table('items').update('item1', { name: 'Gaming Laptop' }));

db = new DB(store.getState().db);
console.log('Updated Laptop:', db.table('items').find('item1'));

view raw JSON →