Search
⌘K

DB Mock

Simple in memory sync db, for mock or playground only. Do not use in production.

Example Usage

import { createDbTable } from './db.mock.utils';

// inferred

const table = createDbTable([
  {
    id: 1,
    name: 'Luke'
  },
  {
    id: 2,
    name: 'Leia'
  }
]);

const items = table.getAll();
const item = table.getById(1);
const createdItem = table.create({name: 'Yoda'});
const updatedItem = table.update(1, {name: 'Obi-Wan'});
const deletedItem = table.delete(2);


// with explicit type

const table = createDbTable<{id: number, name: string}>([
  {
    id: 1,
    name: 'Luke'
  }
])

const items = table.getAll();
const item = table.getById(1);
const createdItem = table.create({name: 'Yoda'});
const updatedItem = table.update(1, {name: 'Obi-Wan'});
const deletedItem = table.delete(2);

Dependencies

No dependencies

Auto Install

npx shadcn@latest add https://shadcn-registry-ts.vercel.app/r/util-db-mock.json

Manual Install

db-mock.ts
/**
 * Source: http://localhost:3000
 */

// export const repeat = (times: number) => new Array(times).fill('');

type BaseDbRecord = {
  id: number;
};

export type DbRecord<Extended extends { [key: string]: unknown; }> = BaseDbRecord & Extended;

/**
 * DB Table creator, for a in memory DB.
 * NOTE: USE THIS ONLY FOR PLAYGROUND DB, NOT IN REAL APP
 */
export const createDbTable = <
  SelectItem extends BaseDbRecord,
  InsertItem = Omit<SelectItem, 'id'>,
  UpdateItem = Partial<Omit<SelectItem, 'id'>>
>(initialRecords: SelectItem[]) => {

  let items: SelectItem[] = [...initialRecords];

  const generateId = () => items.length + 1;

  return {
    getAll: () => items,
    getById: (id: number) => items.find(item => item.id === id) ?? null,
    create: (item: InsertItem) => {
      const id = generateId();
      // @ts-expect-error ts don't allow unknown properties
      const newItem: SelectItem = {
        id,
        ...item
      };

      const newItems = [...items, newItem];
      items = newItems;

      return newItem;
    },
    update: (id: number, item: UpdateItem) => {
      const index = items.findIndex(item => item.id === id);
      if (index === -1) {
        // 'Item not found'
        return null;
      }

      const newItems = [...items];
      newItems[index] = { ...newItems[index], ...item };
      items = newItems;

      return newItems[index];
    },
    delete: (id: number) => {
      const index = items.findIndex(item => item.id === id);
      if (index === -1) {
        // 'Item not found'
        return null;
      }

      const newItems = [...items];
      const deletedItems = newItems.splice(index, 1);
      items = newItems;

      return deletedItems[0];
    }
  };
};

Test

db-mock.test.ts
import { describe, it, expect } from 'vitest';

import { createDbTable } from './db-mock';

describe('db-mock', () => {

  it('do it', () => {

    const NON_EXISTING_ID = 999_999;

    const initialRecords = [
      { id: 1, name: 'Luke' },
      { id: 2, name: 'Leia' }
    ];

    const table = createDbTable(initialRecords);

    // getAll
    expect(table.getAll()).toMatchObject(initialRecords);

    // getById
    expect(table.getById(1)).toMatchObject(initialRecords[0]);
    expect(table.getById(NON_EXISTING_ID)).toBeNull();

    // create
    expect(table.create({ name: 'Yoda' })).toMatchObject({ id: 3, name: 'Yoda' });

    // update
    expect(table.update(1, { name: 'Obi-Wan' })).toMatchObject({ id: 1, name: 'Obi-Wan' });
    expect(table.update(NON_EXISTING_ID, { name: 'Obi-Wan' })).toBeNull();

    // delete
    expect(table.delete(2)).toMatchObject({ id: 2, name: 'Leia' });
    expect(table.delete(NON_EXISTING_ID)).toBeNull();

    // getAll
    expect(table.getAll()).toMatchObject([
      { id: 1, name: 'Obi-Wan' },
      { id: 3, name: 'Yoda' }
    ]);

  });


});

Command Palette

Search for a command to run...