1.0.1-alpha.4 • Published 1 year ago

@tabular-state/store v1.0.1-alpha.4

Weekly downloads
-
License
MIT
Repository
github
Last release
1 year ago

@tabular-state/store

Tabular-State is a simple and reactive state mangement solution based on tables, rows and cells. Under the hood it uses observables from @legendapp/state which is a super fast and powerful state manager for JavaScript apps.

Tabular-State brings also the possibility to query and persist state.

Warning Tabular-State is in early stage and not yet ready for production

Install

npm install @tabular-state/store
pnpm install @tabular-state/store
yarn add @tabular-state/store

Basic Usage

import { createStore } from '@tabular-state/store';

type Tables = {
  users: {
    idField: number; // could be string or number
    item: {
      id: string;
      name: string;
      age: number;
    };
  };
  posts: {
    idField: string;
    item: {
      id: string;
      title: string;
      content: string;
      authorId: string;
      createdAt: string;
    };
  };
};

const store = createStore<Tables>();

Set and Get Tables

import { ObservableObject } from '@legendapp/state';

// write
store.setTable('users');

// read
/**
 * @returns {ObservableObject<Tables['users']>}
 */
const users = store.getTable('users');
console.log(users.peek());
console.log(users.get());

Set and Get Rows

Note Rows are managed by the store and are not directly accessible. You can only get a row by its id.

For reactivity have a look into Legend-State Docs.

import { ObservableObject } from '@legendapp/state';

// write
setRow('users', 1, {
  id: 1,
  name: 'John Doe',
  age: 42,
});

// read
/**
 * @returns {ObservableObject<Tables['users']['item']>}
 */
const user = store.getRow('users', 1);
console.log(user.peek());
console.log(user.get());

Set and Get Cells

Note Cells are managed by the store and are not directly accessible. You can only get a cell by its key.

For reactivity have a look into Legend-State Docs.

import { ObservableObject } from '@legendapp/state';

// read
/**
 * @returns {ObservableObject<Tables['users']['item']['age']>}
 */
const userAge = store.getCell('users', 1, 'age');
console.log(userAge.peek()); // 42
console.log(userAge.get()); // 42

// write
setCell('users', 1, 'age', 43);
console.log(userAge.peek()); // 43

Querying

Querying is based on sift which is a mongo-query like implementation for JavaScript.

const [results, queryFn, queryMeta] = store.queryRows('posts', {
  query: { authorId: user.peek().id },
  limit: 5,
  skip: 0,
  sort: { createdAt: 1 }, // 1 = asc, -1 = desc
  select: ['id', 'title', 'createdAt'],
  style: 'paginated', // paginated | infinite
});

// read
console.log(results.peek()); // [{ id: '1', title: 'Hello World', createdAt: '2021-01-01' }]
console.log(results.get());

Query Pagination

Property style defines in which form the pagination works.

/**
 * paginated: The query will return the items from the current
 * infinite: The query will get bigger on every page change.
 * @default infinite
 */
type PaginationStyle = 'paginated' | 'infinite';

type QueryFn = {
  // if possible will open/load next page
  next(): void;
  // if possible will open previous page or unload items from the current page
  prev(): void;
};

queryFn.next();
queryFn.prev();

Query Meta

type QueryMeta = {
  // current page
  page: Observable<number>;
  // number of items per page
  pageSize: ObservableComputed<number>;
  // total number of items
  total: Observable<number>;
  // if there is a next page
  canShowMore: ObservableComputed<boolean>;
};

// read
console.log(queryMeta.page.peek());
console.log(queryMeta.page.get());

console.log(queryMeta.pageSize.peek());
console.log(queryMeta.pageSize.get());

console.log(queryMeta.total.peek());
console.log(queryMeta.total.get());

console.log(queryMeta.canShowMore.peek());
console.log(queryMeta.canShowMore.get());

Mount hooks to listen to reads

You can listen to all reads by using hooks (before, after, error) on the methods getTable, getRow, getCell, setRow, setCell, delRow, delCell and queryRows.

const store = createStore();

const dispose = store.hook('before', 'getRow', (ctx) => {
  // ctx.method = 'getRow'
  // ctx.params.table = the table on which the method was called
  // ctx.params.rowId = the id of the row
});

dispose(); // remove hook

store.hook('before', 'getTable', (ctx) => {
  // ctx.method = 'getRow'
  // ctx.params.table = the table on which the method was called
});

store.hook('before', 'getCell', (ctx) => {
  // ctx.method = 'getRow'
  // ctx.params.table = the table on which the method was called
  // ctx.params.rowId = the id of the row
  // ctx.params.cellKey = the key of the cell
});

store.hook('before', 'queryRows', (ctx) => {
  // ctx.method = 'queryRows'
  // ctx.params.table = the table on which the method was called
  // ctx.params.query = the query object
});
1.0.1-alpha.4

1 year ago

1.0.1-alpha.3

1 year ago

1.0.1-alpha.1

1 year ago

1.0.1-alpha.0

1 year ago

1.0.0-alpha.0

1 year ago

0.7.2-alpha.0

1 year ago

0.7.1-alpha.0

1 year ago

0.7.0-alpha.0

1 year ago

0.5.0-alpha.0

1 year ago

0.4.0-alpha.0

1 year ago

0.3.1-alpha.0

1 year ago

0.3.0-alpha.0

1 year ago

0.2.0-alpha.0

1 year ago

0.1.0-alpha.0

1 year ago