UNPKG

tinybase

Version:

A reactive data store and sync engine.

186 lines (183 loc) 7.05 kB
/** * The persister-electric-sql module of the TinyBase project lets you save and * load Store data to and from a local ElectricSQL database (in an appropriate * environment). * @see Database Persistence guide * @packageDocumentation * @module persister-electric-sql * @since v4.6.0 */ import type {Store} from '../../store/index.d.cts'; import type {DatabasePersisterConfig, Persister} from '../index.d.cts'; import type {ElectricClient} from 'electric-sql/client/model'; /** * The ElectricSqlPersister interface represents a Persister that lets you save * and load Store data to and from a local ElectricSQL database. * * You should use the createElectricSqlPersister function to create an * ElectricSqlPersister object. * * It is a minor extension to the Persister interface and simply provides an * extra getElectricClient method for accessing a reference to the Electric * client the Store is being persisted to. * @category Persister * @since v4.6.0 */ export interface ElectricSqlPersister extends Persister { /** * The getElectricClient method returns a reference to the Electric client the * Store is being persisted to. * @returns A reference to the Electric client. * @example * This example creates a Persister object against a newly-created Store and * then gets the Electric client back out again. * * ```js yolo * import {schema} from './generated/client'; * import {ElectricDatabase, electrify} from 'electric-sql/wa-sqlite'; * import {createStore} from 'tinybase'; * import {createElectricSqlPersister} from 'tinybase/persisters/persister-electric-sql'; * * const electricClient = await electrify( * await ElectricDatabase.init('electric.db', ''), * schema, * {url: import.meta.env.ELECTRIC_SERVICE}, * ); * const store = createStore().setTables({pets: {fido: {species: 'dog'}}}); * const persister = createElectricSqlPersister( * store, * electricClient, * 'my_tinybase', * ); * * console.log(persister.getElectricClient() == electricClient); * // -> true * * persister.destroy(); * ``` * @category Getter * @since v4.6.0 */ getElectricClient(): ElectricClient<any>; } /** * The createElectricSqlPersister function creates an ElectricSqlPersister * object that can persist a Store to a local ElectricSQL database. * * An ElectricSqlPersister only supports regular Store objects, and cannot be * used to persist the metadata of a MergeableStore. * * As well as providing a reference to the Store to persist, you must provide a * `electricClient` parameter which identifies the Electric client. * * A database Persister uses one of two modes: either a JSON serialization of * the whole Store stored in a single row of a table (the default), or a tabular * mapping of Table Ids to database table names and vice-versa). * * The third argument is a DatabasePersisterConfig object that configures which * of those modes to use, and settings for each. If the third argument is simply * a string, it is used as the `storeTableName` property of the JSON * serialization. * * See the documentation for the DpcJson and DpcTabular types for more * information on how both of those modes can be configured. * @param store The Store to persist. * @param electricClient The Electric client that was returned from `await * electrify(...)`. * @param configOrStoreTableName A DatabasePersisterConfig to configure the * persistence mode (or a string to set the `storeTableName` property of the * JSON serialization). * @param onSqlCommand An optional handler called every time the Persister * executes a SQL command or query. This is suitable for logging persistence * behavior in a development environment. * @param onIgnoredError 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. * @returns A reference to the new ElectricSqlPersister object. * @example * This example creates a ElectricSqlPersister object and persists the Store to * a local ElectricSql database as a JSON serialization into the `my_tinybase` * table. It makes a change to the database directly and then reloads it back * into the Store. * * ```js yolo * import {schema} from './generated/client'; * import {ElectricDatabase, electrify} from 'electric-sql/wa-sqlite'; * import {createStore} from 'tinybase'; * import {createElectricSqlPersister} from 'tinybase/persisters/persister-electric-sql'; * * const electricClient = await electrify( * await ElectricDatabase.init('electric.db', ''), * schema, * {url: import.meta.env.ELECTRIC_SERVICE}, * ); * const store = createStore().setTables({pets: {fido: {species: 'dog'}}}); * const persister = createElectricSqlPersister( * store, * electricClient, * 'my_tinybase', * ); * * await persister.save(); * // Store will be saved to the database. * * console.log( * await electricClient.db.raw({sql: 'SELECT * FROM my_tinybase;'}), * ); * // -> [{_id: '_', store: '[{"pets":{"fido":{"species":"dog"}}},{}]'}] * * await electricClient.db.raw({ * sql: * 'UPDATE my_tinybase SET store = ' + * `'[{"pets":{"felix":{"species":"cat"}}},{}]' WHERE _id = '_';`, * }); * await persister.load(); * console.log(store.getTables()); * // -> {pets: {felix: {species: 'cat'}}} * * persister.destroy(); * ``` * @example * This example creates a ElectricSqlPersister object and persists the Store to * a local ElectricSql database with tabular mapping. * * ```js yolo * import {schema} from './generated/client'; * import {ElectricDatabase, electrify} from 'electric-sql/wa-sqlite'; * import {createStore} from 'tinybase'; * import {createElectricSqlPersister} from 'tinybase/persisters/persister-electric-sql'; * * const electricClient = await electrify( * await ElectricDatabase.init('electric.db', ''), * schema, * {url: import.meta.env.ELECTRIC_SERVICE}, * ); * const store = createStore().setTables({pets: {fido: {species: 'dog'}}}); * const persister = createElectricSqlPersister(store, electricClient, { * mode: 'tabular', * tables: {load: {pets: 'pets'}, save: {pets: 'pets'}}, * }); * * await persister.save(); * console.log(await electricClient.db.raw({sql: 'SELECT * FROM pets;'})); * // -> [{_id: 'fido', species: 'dog'}] * * await electricClient.db.raw({ * sql: `INSERT INTO pets (_id, species) VALUES ('felix', 'cat')`, * }); * await persister.load(); * console.log(store.getTables()); * // -> {pets: {fido: {species: 'dog'}, felix: {species: 'cat'}}} * * persister.destroy(); * ``` * @category Creation * @since v4.6.0 */ export function createElectricSqlPersister( store: Store, electricClient: ElectricClient<any>, configOrStoreTableName?: DatabasePersisterConfig | string, onSqlCommand?: (sql: string, params?: any[]) => void, onIgnoredError?: (error: any) => void, ): ElectricSqlPersister;