TinyBase logoTinyBase

createCustomPersister

The createCustomPersister function creates a Persister object that you can configure to persist the Store in any way you wish.

createCustomPersister<ListenerHandle, Persist>(
  store: PersistedStore<Persist>,
  getPersisted: () => Promise<undefined | PersistedContent<Persist>>,
  setPersisted: (getContent: () => PersistedContent<Persist>, changes?: PersistedChanges<Persist, false>) => Promise<void>,
  addPersisterListener: (listener: PersisterListener<Persist>) => ListenerHandle | Promise<ListenerHandle>,
  delPersisterListener: (listenerHandle: ListenerHandle) => void,
  onIgnoredError?: (error: any) => void,
  persist?: Persist,
): Persister<Persist>
TypeDescription
storePersistedStore<Persist>

The Store to persist.

getPersisted() => Promise<undefined | PersistedContent<Persist>>

An asynchronous function which will fetch content from the persistence layer (or undefined if not present).

setPersisted(getContent: () => PersistedContent<Persist>, changes?: PersistedChanges<Persist, false>) => Promise<void>

An asynchronous function which will send content to the persistence layer. Since v4.0, it receives functions for getting the Store content and information about the changes made during a transaction. Since v5.0, the changes are received directly by reference, rather than an accessor.

addPersisterListener(listener: PersisterListener<Persist>) => ListenerHandle | Promise<ListenerHandle>

A function that will register a listener listener on underlying changes to the persistence layer. You can return a listening handle that will be provided again when delPersisterListener is called. This function can be asynchronous.

delPersisterListener(listenerHandle: ListenerHandle) => void

A function that will unregister the listener from the underlying changes to the persistence layer. It receives whatever was returned from your addPersisterListener implementation.

onIgnoredError?(error: any) => void

An optional handler for the errors that the Persister would otherwise ignore when trying to save or load data. This is suitable for debugging persistence issues in a development environment, since v4.0.4.

persist?Persist

Since v5.0, an optional integer from the Persists enum to indicate which types of Store are supported by this Persister: 1 indicates only a regular Store is supported, 2 indicates only a MergeableStore is supported, and 3 indicates that both Store and MergeableStore are supported.

returnsPersister<Persist>

A reference to the new Persister object.

This is only used when developing custom Persisters, and most TinyBase users will not need to be particularly aware of it.

As well as providing a reference to the Store to persist, you must provide functions that handle how to fetch, write, and listen to, the persistence layer.

The other creation functions (such as the createSessionPersister function and createFilePersister function, for example) all use this function under the covers. See those implementations for ideas on how to implement your own Persister types.

This API changed in v4.0. Any custom persisters created on previous versions should be upgraded. Most notably, the setPersisted function parameter is provided with a getContent function to get the content from the Store itself, rather than being passed pre-serialized JSON. It also receives information about the changes made during a transaction. The getPersisted function must return the content (or nothing) rather than JSON. startListeningToPersisted has been renamed addPersisterListener, and stopListeningToPersisted has been renamed delPersisterListener.

Examples

This example creates a custom Persister object and persists a Store to a local string called persistedJson and which would automatically load by polling for changes every second. It implicitly supports only a regular Store.

import {createCustomPersister} from 'tinybase/persisters';
import {createStore} from 'tinybase';

const store = createStore().setTables({pets: {fido: {species: 'dog'}}});
let persistedJson;

const persister = createCustomPersister(
  store,
  async () => {
    // getPersisted
    return JSON.parse(persistedJson);
  },
  async (getContent) => {
    // setPersisted
    persistedJson = JSON.stringify(getContent());
  },
  (listener) => setInterval(listener, 1000),
  (interval) => clearInterval(interval),
);

await persister.save();
console.log(persistedJson);
// -> '[{"pets":{"fido":{"species":"dog"}}},{}]'

persistedJson = '[{"pets":{"fido":{"species":"dog","color":"brown"}}},{}]';
await persister.load();

console.log(store.getTables());
// -> {pets: {fido: {species: 'dog', color: 'brown'}}}

persister.destroy();

This example demonstrates a Persister creation function which returns a Persister. This can persists a store to a local string called persistedJson and which would automatically load by polling for changes every second. It emits warnings to the console and explicitly supports either a Store or a MergeableStore.

import {Persists, createCustomPersister} from 'tinybase/persisters';
import {createMergeableStore, createStore} from 'tinybase';

let persistedJson;
const createJsonPersister = (storeOrMergeableStore) =>
  createCustomPersister(
    storeOrMergeableStore,
    async () => {
      // getPersisted
      return JSON.parse(persistedJson);
    },
    async (getContent) => {
      // setPersisted
      persistedJson = JSON.stringify(getContent());
    },
    (listener) => setInterval(listener, 1000),
    (interval) => clearInterval(interval),
    console.warn,
    Persists.StoreOrMergeableStore,
  );

const store = createStore();
store.setTables({pets: {fido: {species: 'dog'}}});
const storePersister = createJsonPersister(store);
await storePersister.save();
console.log(persistedJson);
// -> '[{"pets":{"fido":{"species":"dog"}}},{}]'
storePersister.destroy();

const mergeableStore = createMergeableStore('mergeableStore1');
mergeableStore.setTables({pets: {fido: {species: 'dog'}}});
const mergeableStorePersister = createJsonPersister(mergeableStore);
await mergeableStorePersister.save();
console.log(JSON.parse(persistedJson));
// ->
[
  [
    {
      pets: [
        {
          fido: [
            {species: ['dog', 'Nn1JUF-----Zjl0M', 4176151067]},
            '',
            2722999044,
          ],
        },
        '',
        3367164653,
      ],
    },
    '',
    30627183,
  ],
  [{}, '', 0],
];
mergeableStorePersister.destroy();

Since

v1.0.0