TinyBase

Store

A Store is the main location for keeping structured state and tabular data.

Create a Store easily with the createStore function. From there, you can set and get data, add listeners for when the data changes, set a Schema, and so on.

A Store has a simple hierarchical structure:

  • The Store contains a number of Table objects.
  • Each Table contains a number of Row objects.
  • Each Row contains a number of Cell objects.

A Cell is a string, boolean, or number value.

The members of each level of this hierarchy are identified with a unique Id (which is a string). In other words you can naively think of a Store as a three-level-deep JavaScript object, keyed with strings:

{                     // Store
  "table1": {           // Table
    "row1": {             // Row
      "cell1": "one",       // Cell (string)
      "cell2": true,        // Cell (boolean)
      "cell3": 3,           // Cell (number)
      ...
    },
    ...
  },
  ...
}

In its default form, a Store has no sense of a structured schema, so, as long as they are unique within their own parent, the Id keys can each be any string you want. However, you can optionally specify a Schema for a Store, which then usefully constrains the Table and Cell Ids (and Cell values) you can use.

Setting and getting data

Every part of the Store can be accessed with getter methods. When you retrieve data from the Store, you are receiving a copy - rather than a reference - of it. This means that manipulating the data in the Store must be performed with the equivalent setter and deleter methods.

To benefit from the reactive behavior of the Store, you can also subscribe to changes on any part of it with 'listeners'. Registering a listener returns a listener Id (that you can use later to remove it with the delListener method), and it will then be called every time there is a change within the part of the hierarchy you're listening to.

This table shows the main ways you can set, get, and listen to, different types of data in a Store:

Additionally, there are two extra methods to manipulate Row objects. The addRow method is like the setRow method but automatically assigns it a new unique Id. And the setPartialRow method lets you update multiple Cell values in a Row without affecting the others.

You can listen to attempts to write invalid data to a Cell with the addInvalidCellListener method.

The transaction method is used to wrap multiple changes to the Store so that the relevant listeners only fire once.

The setJson method and the getJson method allow you to work with a JSON-encoded representation of the entire Store, which is useful for persisting it.

Finally, the callListener method provides a way for you to manually provoke a listener to be called, even if the underlying data hasn't changed. This is useful when you are using mutator listeners to guarantee that data conforms to programmatic conditions, and those conditions change such that you need to update the Store in bulk.

Read more about setting and changing data in The Basics guides, and about listeners in the Listening to Stores guide.

Creating a Schema

You can set a Schema on a Store when you create it with createStore function, or at a later stage with the setSchema method. A Schema constrains the Table Ids the Store can have, and the types of Cell data in each Table. Each Cell requires its type to be specified, and can also take a default value for when it's not specified.

You can also get a serialization of the Schema out of the Store with the getSchemaJson method, and remove the Schema altogether with the delSchema method.

Read more about schemas in the Using Schemas guide.

Convenience methods

There are a few additional helper methods to make it easier to work with a Store. There are methods for easily checking the existence of a Table, Row, or Cell, and iterators that let you act on the children of a common parent:

Finally, the getListenerStats method describes the current state of the Store's listeners for debugging purposes.

Example

This example shows a very simple lifecycle of a Store: from creation, to adding and getting some data, and then registering and removing a listener.

const store = createStore().setTables({pets: {fido: {species: 'dog'}}});
console.log(store.getRow('pets', 'fido'));
// -> {species: 'dog'}

store.setCell('pets', 'fido', 'color', 'brown');
console.log(store.getCell('pets', 'fido', 'color'));
// -> 'brown'

const listenerId = store.addTableListener('pets', () => {
  console.log('changed');
});

store.setCell('pets', 'fido', 'sold', false);
// -> 'changed'

store.delListener(listenerId);

See also

The Basics guides

Using Schemas guides

Hello World demos

Todo App demos

Getter methods

This is the collection of getter methods within the Store interface. There are 14 getter methods in total.

Setter methods

This is the collection of setter methods within the Store interface. There are 8 setter methods in total.

Listener methods

This is the collection of listener methods within the Store interface. There are 13 listener methods in total.

Iterator methods

This is the collection of iterator methods within the Store interface. There are only three iterator methods, forEachTable, forEachRow, and forEachCell.

Transaction methods

This is the collection of transaction methods within the Store interface. There are only three transaction methods, finishTransaction, startTransaction, and transaction.

Deleter methods

This is the collection of deleter methods within the Store interface. There are 5 deleter methods in total.

Development methods

This is the collection of development methods within the Store interface. There is only one method, getListenerStats.