tinybase
Version:
A reactive data store and sync engine.
1,536 lines (1,488 loc) • 318 kB
TypeScript
/**
* The store module is the core of the TinyBase project and contains the types,
* interfaces, and functions to work with Store objects.
*
* The main entry point to this module is the createStore function, which
* returns a new Store. From there, you can set and get data, register
* listeners, and use other modules to build an entire app around the state and
* tabular data within.
* @packageDocumentation
* @module store
* @since v1.0.0
*/
import type {
AllCellIdFromSchema,
CellIdFromSchema,
DefaultCellIdFromSchema,
DefaultValueIdFromSchema,
DefaultedCellFromSchema,
DefaultedValueFromSchema,
StoreAlias,
TableIdFromSchema,
Truncate,
ValueIdFromSchema,
} from '../../_internal/store/with-schemas/index.d.ts';
import type {
Id,
IdOrNull,
Ids,
Json,
} from '../../common/with-schemas/index.d.ts';
/**
* The TablesSchema type describes the tabular structure of a Store in terms of
* valid Table Ids and the types of Cell that can exist within them.
*
* A TablesSchema comprises a JavaScript object describing each Table, in turn a
* nested JavaScript object containing information about each Cell and its
* CellSchema. It is provided to the setTablesSchema method.
* @example
* When applied to a Store, this TablesSchema only allows one Table called
* `pets`, in which each Row may contain a string `species` Cell, and is
* guaranteed to contain a boolean `sold` Cell that defaults to `false`.
*
* ```js
* import type {TablesSchema} from 'tinybase';
*
* export const tableSchema: TablesSchema = {
* pets: {
* species: {type: 'string'},
* sold: {type: 'boolean', default: false},
* },
* };
* ```
* @category Schema
* @since v1.0.0
*/
export type TablesSchema = {[tableId: Id]: {[cellId: Id]: CellSchema}};
/**
* The CellSchema type describes what values are allowed for each Cell in a
* Table.
*
* A CellSchema specifies the type of the Cell (`string`, `boolean`, or
* `number`), and what the default value can be when an explicit value is not
* specified.
*
* If a default value is provided (and its type is correct), you can be certain
* that that Cell will always be present in a Row.
*
* If the default value is _not_ provided (or its type is incorrect), the Cell
* may be missing from the Row, but when present you can be guaranteed it is of
* the correct type.
* @example
* When applied to a Store, this CellSchema ensures a boolean Cell is always
* present, and defaults it to `false`.
*
* ```js
* import type {CellSchema} from 'tinybase';
*
* export const requiredBoolean: CellSchema = {
* type: 'boolean',
* default: false,
* };
* ```
* @category Schema
* @since v1.0.0
*/
export type CellSchema =
| {type: 'string'; default?: string}
| {type: 'number'; default?: number}
| {type: 'boolean'; default?: boolean};
/**
* The ValuesSchema type describes the keyed Values that can be set in a Store
* and their types.
*
* A ValuesSchema comprises a JavaScript object describing each Value and its
* ValueSchema. It is provided to the setValuesSchema method.
* @example
* When applied to a Store, this ValuesSchema only allows one boolean Value
* called `open`, that defaults to `false`.
*
* ```js
* import type {ValuesSchema} from 'tinybase';
*
* export const valuesSchema: ValuesSchema = {
* open: {type: 'boolean', default: false},
* };
* ```
* @category Schema
* @since v3.0.0
*/
export type ValuesSchema = {[valueId: Id]: ValueSchema};
/**
* The ValueSchema type describes what values are allowed for keyed Values in a
* Store.
*
* A ValueSchema specifies the type of the Value (`string`, `boolean`, or
* `number`), and what the default value can be when an explicit value is not
* specified.
*
* If a default value is provided (and its type is correct), you can be certain
* that the Value will always be present in a Store.
*
* If the default value is _not_ provided (or its type is incorrect), the Value
* may not be present in the Store, but when present you can be guaranteed it is
* of the correct type.
* @example
* When applied to a Store, this ValueSchema ensures a boolean Value is always
* present, and defaults it to `false`.
*
* ```js
* import type {ValueSchema} from 'tinybase';
*
* export const requiredBoolean: ValueSchema = {
* type: 'boolean',
* default: false,
* };
* ```
* @category Schema
* @since v3.0.0
*/
export type ValueSchema =
| {type: 'string'; default?: string}
| {type: 'number'; default?: number}
| {type: 'boolean'; default?: boolean};
/**
* The NoTablesSchema type is a TablesSchema-like type for when one has not been
* provided.
* @category Schema
* @since v1.0.0
*/
export type NoTablesSchema = {[tableId: Id]: {[cellId: Id]: {type: 'any'}}};
/**
* The NoValuesSchema type is a ValuesSchema-like type for when one has not been
* provided.
* @category Schema
* @since v1.0.0
*/
export type NoValuesSchema = {[valueId: Id]: {type: 'any'}};
/**
* The OptionalTablesSchema type is used by generic types that can optionally
* take a TablesSchema.
* @category Schema
* @since v1.0.0
*/
export type OptionalTablesSchema = TablesSchema | NoTablesSchema;
/**
* The OptionalValuesSchema type is used by generic types that can optionally
* take a ValuesSchema.
* @category Schema
* @since v1.0.0
*/
export type OptionalValuesSchema = ValuesSchema | NoValuesSchema;
/**
* The OptionalSchemas type is used by generic types that can optionally take
* either or both of a TablesSchema and ValuesSchema.
* @category Schema
* @since v1.0.0
*/
export type OptionalSchemas = [OptionalTablesSchema, OptionalValuesSchema];
/**
* The NoSchemas type is used as a default by generic types that can optionally
* take either or both of a TablesSchema and ValuesSchema.
* @category Schema
* @since v1.0.0
*/
export type NoSchemas = [NoTablesSchema, NoValuesSchema];
/**
* The Content type describes both the Tables and Values in a Store.
*
* This has schema-based typing. The following is a simplified representation:
*
* ```ts override
* [Tables, Values];
* ```
*
* It is an array of two objects, representing tabular and keyed value content.
* @example
* The following is a valid Content array:
* ```json
* [
* {
* "pets": {
* "fido": {
* "sold": false,
* "price": 4,
* },
* "felix": {
* "sold": true,
* "price": 5,
* },
* },
* },
* {
* open: true,
* employees: 3,
* },
* ]
* ```
* @category Store
* @since v5.0.0
*/
export type Content<
Schemas extends OptionalSchemas,
WhenSet extends boolean = false,
> = [Tables<Schemas[0], WhenSet>, Values<Schemas[1], WhenSet>];
/**
* The Tables type is the data structure representing all of the data in a
* Store.
*
* This has schema-based typing. The following is a simplified representation:
*
* ```ts override
* {[tableId: Id]: Table};
* ```
*
* A Tables object is used when setting all of the tables together with the
* setTables method, and when getting them back out again with the getTables
* method. A Tables object is a regular JavaScript object containing individual
* Table objects, keyed by their Id.
* @example
* ```js
* import type {Tables} from 'tinybase';
*
* export const tables: Tables = {
* pets: {
* fido: {species: 'dog', color: 'brown'},
* felix: {species: 'cat'},
* },
* species: {
* dog: {price: 5},
* cat: {price: 4},
* },
* };
* ```
* @category Store
* @since v1.0.0
*/
export type Tables<
Schema extends OptionalTablesSchema,
WhenSet extends boolean = false,
> = {
-readonly [TableId in TableIdFromSchema<Schema>]?: Table<
Schema,
TableId,
WhenSet
>;
};
/**
* The Table type is the data structure representing the data in a single table.
*
* This has schema-based typing. The following is a simplified representation:
*
* ```ts override
* {[rowId: Id]: Row};
* ```
*
* A Table is used when setting a table with the setTable method, and when
* getting it back out again with the getTable method. A Table object is a
* regular JavaScript object containing individual Row objects, keyed by their
* Id.
* @example
* ```js
* import type {Table} from 'tinybase';
*
* export const table: Table = {
* fido: {species: 'dog', color: 'brown'},
* felix: {species: 'cat'},
* };
* ```
* @category Store
* @since v1.0.0
*/
export type Table<
Schema extends OptionalTablesSchema,
TableId extends TableIdFromSchema<Schema>,
WhenSet extends boolean = false,
> = {[rowId: Id]: Row<Schema, TableId, WhenSet>};
/**
* The Row type is the data structure representing the data in a single row.
*
* This has schema-based typing. The following is a simplified representation:
*
* ```ts override
* {[cellId: Id]: Cell};
* ```
*
* A Row is used when setting a row with the setRow method, and when getting it
* back out again with the getRow method. A Row object is a regular JavaScript
* object containing individual Cell objects, keyed by their Id.
* @example
* ```js
* import type {Row} from 'tinybase';
*
* export const row: Row = {species: 'dog', color: 'brown'};
* ```
* @category Store
* @since v1.0.0
*/
export type Row<
Schema extends OptionalTablesSchema,
TableId extends TableIdFromSchema<Schema>,
WhenSet extends boolean = false,
> = (WhenSet extends true
? {
-readonly [CellId in DefaultCellIdFromSchema<Schema, TableId>]?: Cell<
Schema,
TableId,
CellId
>;
}
: {
-readonly [CellId in DefaultCellIdFromSchema<Schema, TableId>]: Cell<
Schema,
TableId,
CellId
>;
}) & {
-readonly [CellId in DefaultCellIdFromSchema<Schema, TableId, false>]?: Cell<
Schema,
TableId,
CellId
>;
};
/**
* The Cell type is the data structure representing the data in a single cell.
*
* This has schema-based typing. The following is a simplified representation:
*
* ```ts override
* string | number | boolean;
* ```
*
* A Cell is used when setting a cell with the setCell method, and when getting
* it back out again with the getCell method. A Cell is a JavaScript string,
* number, or boolean.
* @example
* ```js
* import type {Cell} from 'tinybase';
*
* export const cell: Cell = 'dog';
* ```
* @category Store
* @since v1.0.0
*/
export type Cell<
Schema extends OptionalTablesSchema,
TableId extends TableIdFromSchema<Schema>,
CellId extends CellIdFromSchema<Schema, TableId>,
CellType = Schema[TableId][CellId]['type'],
> = CellType extends 'string'
? string
: CellType extends 'number'
? number
: CellType extends 'boolean'
? boolean
: string | number | boolean;
/**
* The CellOrUndefined type is a data structure representing the data in a
* single cell, or the value `undefined`.
*
* This has schema-based typing. The following is a simplified representation:
*
* ```ts override
* Cell | undefined;
* ```
*
* This is used when describing a Cell that is present _or_ that is not present,
* such as when it has been deleted, or when describing a previous state where
* the Cell value has since been added.
* @category Store
* @since v1.0.0
*/
export type CellOrUndefined<
Schema extends OptionalTablesSchema,
TableId extends TableIdFromSchema<Schema>,
CellId extends CellIdFromSchema<Schema, TableId>,
> = Cell<Schema, TableId, CellId> | undefined;
/**
* The Values type is the data structure representing all the keyed values in a
* Store.
*
* This has schema-based typing. The following is a simplified representation:
*
* ```ts override
* {[valueId: Id]: Value};
* ```
*
* A Values object is used when setting values with the setValues method, and
* when getting them back out again with the getValues method. A Values object
* is a regular JavaScript object containing individual Value objects, keyed by
* their Id.
* @example
* ```js
* import type {Values} from 'tinybase';
*
* export const values: Values = {open: true, employees: 4};
* ```
* @category Store
* @since v3.0.0
*/
export type Values<
Schema extends OptionalValuesSchema,
WhenSet extends boolean = false,
> = (WhenSet extends true
? {
-readonly [ValueId in DefaultValueIdFromSchema<Schema>]?: Value<
Schema,
ValueId
>;
}
: {
-readonly [ValueId in DefaultValueIdFromSchema<Schema>]: Value<
Schema,
ValueId
>;
}) & {
-readonly [ValueId in DefaultValueIdFromSchema<Schema, false>]?: Value<
Schema,
ValueId
>;
};
/**
* The Value type is the data structure representing the data in a single keyed
* value.
*
* This has schema-based typing. The following is a simplified representation:
*
* ```ts override
* string | number | boolean;
* ```
*
* A Value is used when setting a value with the setValue method, and when
* getting it back out again with the getValue method. A Value is a JavaScript
* string, number, or boolean.
* @example
* ```js
* import type {Value} from 'tinybase';
*
* export const value: Value = 'dog';
* ```
* @category Store
* @since v3.0.0
*/
export type Value<
Schema extends OptionalValuesSchema,
ValueId extends ValueIdFromSchema<Schema>,
ValueType = Schema[ValueId]['type'],
> = ValueType extends 'string'
? string
: ValueType extends 'number'
? number
: ValueType extends 'boolean'
? boolean
: string | number | boolean;
/**
* The ValueOrUndefined type is a data structure representing the data in a
* single value, or the value `undefined`.
*
* This has schema-based typing. The following is a simplified representation:
*
* ```ts override
* Value | undefined;
* ```
*
* This is used when describing a Value that is present _or_ that is not
* present, such as when it has been deleted, or when describing a previous
* state where the Value has since been added.
* @category Store
* @since v3.0.0
*/
export type ValueOrUndefined<
Schema extends OptionalValuesSchema,
ValueId extends ValueIdFromSchema<Schema>,
> = Value<Schema, ValueId> | undefined;
/**
* The TableCallback type describes a function that takes a Table's Id and a
* callback to loop over each Row within it.
*
* This has schema-based typing. The following is a simplified representation:
*
* ```ts override
* (
* tableId: Id,
* forEachRow: (rowCallback: RowCallback) => void,
* ) => void;
* ```
*
* A TableCallback is provided when using the forEachTable method, so that you
* can do something based on every Table in the Store. See that method for
* specific examples.
* @param tableId The Id of the Table that the callback can operate on.
* @param forEachRow A function that will let you iterate over the Row objects
* in this Table.
* @category Callback
* @since v1.0.0
*/
export type TableCallback<
Schema extends OptionalTablesSchema,
Params extends any[] = TableIdFromSchema<Schema> extends infer TableId
? TableId extends TableIdFromSchema<Schema>
? [
tableId: TableId,
forEachRow: (rowCallback: RowCallback<Schema, TableId>) => void,
]
: never
: never,
Params2 extends any[] = Params | [tableId: never, forEachRow: never],
Params1 extends any[] = Truncate<Params2>,
> = ((...params: Params2) => void) | ((...params: Params1) => void);
/**
* The TableCellCallback type describes a function that takes a Cell's Id and
* the count of times it appears across a whole Table.
*
* This has schema-based typing. The following is a simplified representation:
*
* ```ts override
* (cellId: Id, count: number) => void;
* ```
*
* A TableCellCallback is provided when using the forEachTableCell method, so
* that you can do something based on every Cell used across a Table. See that
* method for specific examples.
* @param cellId The Id of the Cell that the callback can operate on.
* @param count The number of times this Cell is used across a whole Table.
* @category Callback
* @since v1.0.0
*/
export type TableCellCallback<
Schema extends OptionalTablesSchema,
TableId extends TableIdFromSchema<Schema>,
> = (cellId: CellIdFromSchema<Schema, TableId>, count: number) => void;
/**
* The RowCallback type describes a function that takes a Row's Id and a
* callback to loop over each Cell within it.
*
* This has schema-based typing. The following is a simplified representation:
*
* ```ts override
* (
* rowId: Id,
* forEachCell: (cellCallback: CellCallback) => void,
* ) => void;
* ```
*
* A RowCallback is provided when using the forEachRow method, so that you can
* do something based on every Row in a Table. See that method for specific
* examples.
* @param rowId The Id of the Row that the callback can operate on.
* @param forEachCell A function that will let you iterate over the Cell values
* in this Row.
* @category Callback
* @since v1.0.0
*/
export type RowCallback<
Schema extends OptionalTablesSchema,
TableIdOrNull extends TableIdFromSchema<Schema> | null = null,
Params extends any[] = [
rowId: Id,
forEachCell: (cellCallback: CellCallback<Schema, TableIdOrNull>) => void,
],
Params2 extends any[] = Params | [rowId: never, forEachCell: never],
// Params1 extends any[] = Truncate<Params2>,
> = Params extends any[] ? (...params: Params2) => void : never;
// | ((...params: Params1) => void)
/**
* The CellCallback type describes a function that takes a Cell's Id and its
* value.
*
* This has schema-based typing. The following is a simplified representation:
*
* ```ts override
* (cellId: Id, cell: Cell) => void;
* ```
*
* A CellCallback is provided when using the forEachCell method, so that you can
* do something based on every Cell in a Row. See that method for specific
* examples.
* @param cellId The Id of the Cell that the callback can operate on.
* @param cell The value of the Cell.
* @category Callback
* @since v1.0.0
*/
export type CellCallback<
Schema extends OptionalTablesSchema,
TableIdOrNull extends TableIdFromSchema<Schema> | null = null,
Params extends any[] = (
TableIdOrNull extends null ? TableIdFromSchema<Schema> : TableIdOrNull
) extends infer TableId
? TableId extends TableIdFromSchema<Schema>
? CellIdFromSchema<Schema, TableId> extends infer CellId
? CellId extends CellIdFromSchema<Schema, TableId>
? [cellId: CellId, cell: Cell<Schema, TableId, CellId>]
: never
: never
: never
: never,
Params2 extends any[] = Params | [cellId: never, cell: never],
Params1 extends any[] = Truncate<Params2>,
> = Params extends any[]
? ((...params: Params2) => void) | ((...params: Params1) => void)
: never;
/**
* The ValueCallback type describes a function that takes a Value's Id and its
* actual value.
*
* This has schema-based typing. The following is a simplified representation:
*
* ```ts override
* (valueId: Id, value: Value) => void;
* ```
*
* A ValueCallback is provided when using the forEachValue method, so that you
* can do something based on every Value in a Store. See that method for
* specific examples.
* @param valueId The Id of the Value that the callback can operate on.
* @param value The Value itself.
* @category Callback
* @since v3.0.0
*/
export type ValueCallback<
Schema extends OptionalValuesSchema,
Params extends any[] = ValueIdFromSchema<Schema> extends infer ValueId
? ValueId extends ValueIdFromSchema<Schema>
?
| [valueId: ValueId, value: Value<Schema, ValueId>]
| [valueId: never, value: never]
: never
: never,
Params2 extends any[] = Params | [valueId: never, value: never],
Params1 extends any[] = Truncate<Params2>,
> = Params extends any[]
? ((...params: Params2) => void) | ((...params: Params1) => void)
: never;
/**
* The MapCell type describes a function that takes an existing Cell value and
* returns another.
*
* This has schema-based typing. The following is a simplified representation:
*
* ```ts override
* (cell: CellOrUndefined) => Cell;
* ```
*
* A MapCell can be provided in the setCell method to map an existing value to a
* new one, such as when incrementing a number. See that method for specific
* examples.
* @param cell The current value of the Cell to map to a new value.
* @category Callback
* @since v1.0.0
*/
export type MapCell<
Schema extends OptionalTablesSchema,
TableId extends TableIdFromSchema<Schema>,
CellId extends CellIdFromSchema<Schema, TableId>,
> = (
cell: CellOrUndefined<Schema, TableId, CellId>,
) => Cell<Schema, TableId, CellId>;
/**
* The MapValue type describes a function that takes an existing Value and
* returns another.
*
* This has schema-based typing. The following is a simplified representation:
*
* ```ts override
* (value: ValueOrUndefined) => Value;
* ```
*
* A MapValue can be provided in the setValue method to map an existing Value to
* a new one, such as when incrementing a number. See that method for specific
* examples.
* @param value The current Value to map to a new Value.
* @category Callback
* @since v3.0.0
*/
export type MapValue<
Schema extends OptionalValuesSchema,
ValueId extends ValueIdFromSchema<Schema> = ValueIdFromSchema<Schema>,
> = (value: ValueOrUndefined<Schema, ValueId>) => Value<Schema, ValueId>;
/**
* The GetCell type describes a function that takes a Id and returns the Cell
* value for a particular Row.
*
* This has schema-based typing. The following is a simplified representation:
*
* ```ts override
* (cellId: Id) => CellOrUndefined;
* ```
*
* A GetCell can be provided when setting definitions, as in the
* setMetricDefinition method of a Metrics object, or the setIndexDefinition
* method of an Indexes object. See those methods for specific examples.
* @param cellId The Id of the Cell to fetch the value for.
* @category Callback
* @since v1.0.0
*/
export type GetCell<
Schema extends OptionalTablesSchema,
TableId extends TableIdFromSchema<Schema>,
> = <CellId extends CellIdFromSchema<Schema, TableId>>(
cellId: CellId,
) => DefaultedCellFromSchema<Schema, TableId, CellId>;
/**
* The IdAddedOrRemoved type describes a change made to an Id in either the
* tabular or keyed-value part of the Store (or in other TinyBase modules).
*
* This type is used in other types like ChangedTableIds, ChangedRowIds,
* ChangedCellIds, and ChangedValueIds, as well as in other events or listeners
* where a list of Ids has changed.
*
* It is a simple number: a 1 indicates that a given Id was added to a list of
* Ids, and a -1 indicates that it was removed.
* @category Transaction
* @since v4.0.0
*/
export type IdAddedOrRemoved = 1 | -1;
/**
* The ChangedTableIds type describes the Table Ids that were added or removed
* during a transaction.
*
* This has schema-based typing. The following is a simplified representation:
*
* ```ts override
* {[tableId: Id]: IdAddedOrRemoved};
* ```
*
* It is available to the DoRollback function and to a TransactionListener
* function via the TransactionLog object.
*
* It is a simple object that has Table Id as key, and an IdAddedOrRemoved
* number indicating whether the Table Id was added (1) or removed (-1).
*
* Note that there will be no entry if the content of the Table itself changed.
* For that you should consult the ChangedRowIds, ChangedCellIds, or
* ChangedCells types.
* @category Transaction
* @since v4.0.0
*/
export type ChangedTableIds<Schema extends OptionalTablesSchema> = {
[TableId in TableIdFromSchema<Schema>]: IdAddedOrRemoved;
};
/**
* The ChangedRowIds type describes the Row Ids that were added or removed
* during a transaction.
*
* This has schema-based typing. The following is a simplified representation:
*
* ```ts override
* {[tableId: Id]: {[rowId: Id]: IdAddedOrRemoved}};
* ```
*
* It is available to the DoRollback function and to a TransactionListener
* function via the TransactionLog object.
*
* It is a nested object that has Table Id as a top-level key, and then Row Id
* as an inner key. The values of the inner objects are IdAddedOrRemoved numbers
* indicating whether the Row Id was added (1) or removed (-1) to the given
* Table.
*
* Note that there will be no entry if the content of the Row itself changed.
* For that you should consult the ChangedCellIds or ChangedCells types.
* @category Transaction
* @since v4.0.0
*/
export type ChangedRowIds<Schema extends OptionalTablesSchema> = {
[TableId in TableIdFromSchema<Schema>]: {[rowId: Id]: IdAddedOrRemoved};
};
/**
* The ChangedCellIds type describes the Cell Ids that were added or removed
* during a transaction.
*
* This has schema-based typing. The following is a simplified representation:
*
* ```ts override
* {
* [tableId: Id]: {[rowId: Id]: {[cellId: Id]: IdAddedOrRemoved}};
* };
* ```
*
* It is available to the DoRollback function and to a TransactionListener
* function via the TransactionLog object.
*
* It is a nested object that has Table Id as a top-level key, and Row Id, and
* then CellId as inner keys. The values of the inner objects are
* IdAddedOrRemoved numbers indicating whether the Cell Id was added (1) or
* removed (-1) to the given Row.
*
* Note that there will be no entry if the content of the Cell itself changed.
* For that you should consult the ChangedCells type.
* @category Transaction
* @since v4.0.0
*/
export type ChangedCellIds<Schema extends OptionalTablesSchema> = {
[TableId in TableIdFromSchema<Schema>]: {
[rowId: Id]: {
[CellId in CellIdFromSchema<Schema, TableId>]: IdAddedOrRemoved;
};
};
};
/**
* The ChangedValueIds type describes the Value Ids that were added or removed
* during a transaction.
*
* This has schema-based typing. The following is a simplified representation:
*
* ```ts override
* {[valueId: Id]: IdAddedOrRemoved};
* ```
*
* It is available to the DoRollback function and to a TransactionListener
* function via the TransactionLog object.
*
* It is a simple object that has Value Id as key, and an IdAddedOrRemoved
* number indicating whether the Value Id was added (1) or removed (-1).
*
* Note that there will be no entry if the content of the Value itself changed.
* For that you should consult the ChangedValues type.
* @category Transaction
* @since v4.0.0
*/
export type ChangedValueIds<Schema extends OptionalValuesSchema> = {
[ValueId in ValueIdFromSchema<Schema>]: IdAddedOrRemoved;
};
/**
* The DoRollback type describes a function that you can use to rollback the
* transaction if it did not complete to your satisfaction.
*
* This has schema-based typing. The following is a simplified representation:
*
* ```ts override
* (store: Store) => boolean;
* ```
*
* A DoRollback can be provided when calling the transaction method or the
* finishTransaction method. See those methods for specific examples.
*
* Since v5.0, this function is called with the Store as a single argument. You
* can use the getTransactionChanges method and getTransactionLog method of the
* Store directly to decide whether to do the rollback.
* @param store A reference to the Store that is completing a transaction.
* @category Callback
* @since v1.0.0
*/
export type DoRollback<Schemas extends OptionalSchemas> = (
store: Store<Schemas>,
) => boolean;
/**
* The TransactionListener type describes a function that is used to listen to
* the completion of a transaction for the Store.
*
* This has schema-based typing. The following is a simplified representation:
*
* ```ts override
* export type TransactionListener<Store extends StoreAlias = StoreAlias> = (
* store: Store,
* ) => void;
* ```
*
* A TransactionListener is provided when using the
* addWillFinishTransactionListener and addDidFinishTransactionListener methods.
* See those methods for specific examples.
*
* Since v5.0, this listener is called with no arguments other than the Store.
* You can use the getTransactionChanges method and getTransactionLog method of
* the Store directly to get information about the changes made within the
* transaction.
* @param store A reference to the Store that is completing a transaction.
* @category Listener
* @since v1.0.0
*/
export type TransactionListener<
Schemas extends OptionalSchemas,
Store extends StoreAlias<Schemas> = StoreAlias<Schemas>,
> = (store: Store) => void;
/**
* The HasTablesListener type describes a function that is used to listen to
* Tables as a whole being added to or removed from the Store.
*
* This has schema-based typing. The following is a simplified representation:
*
* ```ts override
* export type HasTablesListener<Store extends StoreAlias = StoreAlias> = (
* store: Store,
* hasTables: boolean,
* ) => void;
* ```
*
* A HasTablesListener is provided when using the addHasTablesListener method.
* See that method for specific examples.
*
* When called, a HasTablesListener is given a reference to the Store. It is
* also given a flag to indicate whether Tables now exist (having not done
* previously), or do not (having done so previously).
* @param store A reference to the Store that changed.
* @param hasTables Whether Tables now exist or not.
* @category Listener
* @since v4.4.0
*/
export type HasTablesListener<
Schemas extends OptionalSchemas,
Store extends StoreAlias<Schemas> = StoreAlias<Schemas>,
> = (store: Store, hasTables: boolean) => void;
/**
* The TablesListener type describes a function that is used to listen to
* changes to the tabular part of the Store.
*
* This has schema-based typing. The following is a simplified representation:
*
* ```ts override
* export type TablesListener<Store extends StoreAlias = StoreAlias> = (
* store: Store,
* getCellChange: GetCellChange | undefined,
* ) => void;
* ```
*
* A TablesListener is provided when using the addTablesListener method. See
* that method for specific examples.
*
* When called, a TablesListener is given a reference to the Store and a
* GetCellChange function that can be used to query Cell values before and after
* the current transaction.
*
* Note that if the listener was manually forced to be called (with the
* callListener method rather than due to a real change in the Store), the
* GetCellChange function will not be present.
* @param store A reference to the Store that changed.
* @param getCellChange A function that returns information about any Cell's
* changes.
* @category Listener
* @since v1.0.0
*/
export type TablesListener<
Schemas extends OptionalSchemas,
Store extends StoreAlias<Schemas> = StoreAlias<Schemas>,
> = (
store: Store,
getCellChange: GetCellChange<Schemas[0]> | undefined,
) => void;
/**
* The TableIdsListener type describes a function that is used to listen to
* changes to the Table Ids in the Store.
*
* This has schema-based typing. The following is a simplified representation:
*
* ```ts override
* export type TableIdsListener<Store extends StoreAlias = StoreAlias> = (
* store: Store,
* getIdChanges: GetIdChanges | undefined,
* ) => void;
* ```
*
* A TableIdsListener is provided when using the addTableIdsListener method. See
* that method for specific examples.
*
* When called, a TableIdsListener is given a reference to the Store.
*
* Since v3.3, the listener is also passed a GetIdChanges function that can be
* used to query which Ids changed during the transaction.
* @param store A reference to the Store that changed.
* @param getIdChanges A function that returns information about the Id changes,
* since v3.3.
* @category Listener
* @since v1.0.0
*/
export type TableIdsListener<
Schemas extends OptionalSchemas,
Store extends StoreAlias<Schemas> = StoreAlias<Schemas>,
> = (
store: Store,
getIdChanges: GetIdChanges<TableIdFromSchema<Schemas[0]>> | undefined,
) => void;
/**
* The HasTableListener type describes a function that is used to listen to a
* Table being added to or removed from the Store.
*
* This has schema-based typing. The following is a simplified representation:
*
* ```ts override
* export type HasTableListener<Store extends StoreAlias = StoreAlias> = (
* store: Store,
* tableId: Id,
* hasTable: boolean,
* ) => void;
* ```
*
* A HasTableListener is provided when using the addHasTableListener method. See
* that method for specific examples.
*
* When called, a HasTableListener is given a reference to the Store, and the Id
* of the Table that changed. It is also given a flag to indicate whether the
* Table now exists (having not done previously), or does not (having done so
* previously).
* @param store A reference to the Store that changed.
* @param tableId The Id of the Table that changed.
* @param hasTable Whether the Table now exists or not.
* @category Listener
* @since v4.4.0
*/
export type HasTableListener<
Schemas extends OptionalSchemas,
TableIdOrNull extends TableIdFromSchema<Schemas[0]> | null,
Store extends StoreAlias<Schemas> = StoreAlias<Schemas>,
> = (
store: Store,
tableId: TableIdOrNull extends null
? TableIdFromSchema<Schemas[0]>
: TableIdOrNull,
hasTable: boolean,
) => void;
/**
* The TableListener type describes a function that is used to listen to changes
* to a Table.
*
* This has schema-based typing. The following is a simplified representation:
*
* ```ts override
* export type TableListener<Store extends StoreAlias = StoreAlias> = (
* store: Store,
* tableId: Id,
* getCellChange: GetCellChange | undefined,
* ) => void;
* ```
*
* A TableListener is provided when using the addTableListener method. See that
* method for specific examples.
*
* When called, a TableListener is given a reference to the Store, the Id of the
* Table that changed, and a GetCellChange function that can be used to query
* Cell values before and after the current transaction.
*
* Note that if the listener was manually forced to be called (with the
* callListener method rather than due to a real change in the Store), the
* GetCellChange function will not be present.
* @param store A reference to the Store that changed.
* @param tableId The Id of the Table that changed.
* @param getCellChange A function that returns information about any Cell's
* changes.
* @category Listener
* @since v1.0.0
*/
export type TableListener<
Schemas extends OptionalSchemas,
TableIdOrNull extends TableIdFromSchema<Schemas[0]> | null,
Store extends StoreAlias<Schemas> = StoreAlias<Schemas>,
> = (
store: Store,
tableId: TableIdOrNull extends null
? TableIdFromSchema<Schemas[0]>
: TableIdOrNull,
getCellChange: GetCellChange<Schemas[0]> | undefined,
) => void;
/**
* The TableCellIdsListener type describes a function that is used to listen to
* changes to the Cell Ids that appear anywhere in a Table.
*
* This has schema-based typing. The following is a simplified representation:
*
* ```ts override
* export type TableCellIdsListener<Store extends StoreAlias = StoreAlias> = (
* store: Store,
* tableId: Id,
* getIdChanges: GetIdChanges | undefined,
* ) => void;
* ```
*
* A TableCellIdsListener is provided when using the addTableCellIdsListener
* method. See that method for specific examples.
*
* When called, a TableCellIdsListener is given a reference to the Store, the Id
* of the Table whose Cell Ids changed, and a GetIdChanges function that can be
* used to query which Ids changed during the transaction.
* @param store A reference to the Store that changed.
* @param tableId The Id of the Table that changed.
* @param getIdChanges A function that returns information about the Id changes.
* @category Listener
* @since v3.3.0
*/
export type TableCellIdsListener<
Schemas extends OptionalSchemas,
TableIdOrNull extends TableIdFromSchema<Schemas[0]> | null,
Store extends StoreAlias<Schemas> = StoreAlias<Schemas>,
Params extends any[] = (
TableIdOrNull extends null ? TableIdFromSchema<Schemas[0]> : TableIdOrNull
) extends infer TableId
? TableId extends TableIdFromSchema<Schemas[0]>
? [
store: Store,
tableId: TableId,
getIdChanges: GetIdChanges<CellIdFromSchema<Schemas[0], TableId>>,
]
: never
: never,
Params3 extends any[] =
| Params
| [store: never, tableId: never, getIdChanges: never],
Params2 extends any[] = Truncate<Params3>,
// Params1 extends any[] = Truncate<Params2>,
> = Params extends any
? ((...params: Params3) => void) | ((...params: Params2) => void)
: // | ((...params: Params1) => void)
never;
/**
* The HasTableCellListener type describes a function that is used to listen to
* a Cell being added to or removed from a Table as a whole.
*
* This has schema-based typing. The following is a simplified representation:
*
* ```ts override
* export type HasTableCellListener<Store extends StoreAlias = StoreAlias> = (
* store: Store,
* tableId: Id,
* cellId: Id,
* hasTableCell: boolean,
* ) => void;
* ```
*
* A HasTableCellListener is provided when using the addHasTableCellListener
* method. See that method for specific examples.
*
* When called, a HasTableCellListener is given a reference to the Store, the Id
* of the Table that changed, and the Id of the Cell that changed. It is also
* given a flag to indicate whether the Cell now exists anywhere in the Table
* (having not done previously), or does not (having done so previously).
* @param store A reference to the Store that changed.
* @param tableId The Id of the Table that changed.
* @param cellId The Id of the Table Cell that changed.
* @param hasTableCell Whether the Cell now exists anywhere in the Table or not.
* @category Listener
* @since v4.4.0
*/
export type HasTableCellListener<
Schemas extends OptionalSchemas,
TableIdOrNull extends TableIdFromSchema<Schemas[0]> | null,
CellIdOrNull extends
| (TableIdOrNull extends TableIdFromSchema<Schemas[0]>
? CellIdFromSchema<Schemas[0], TableIdOrNull>
: AllCellIdFromSchema<Schemas[0]>)
| null,
Store extends StoreAlias<Schemas> = StoreAlias<Schemas>,
Params extends any[] = (
TableIdOrNull extends null ? TableIdFromSchema<Schemas[0]> : TableIdOrNull
) extends infer TableId
? TableId extends TableIdFromSchema<Schemas[0]>
? (
CellIdOrNull extends null
? CellIdFromSchema<Schemas[0], TableId>
: CellIdOrNull
) extends infer CellId
? CellId extends CellIdFromSchema<Schemas[0], TableId>
? [
store: Store,
tableId: TableId,
cellId: CellId,
hasTableCell: boolean,
]
: never
: never
: never
: never,
Params4 extends any[] =
| Params
| [store: never, tableId: never, cellId: never, hasTableCell: never],
Params3 extends any[] = Truncate<Params4>,
// Params2 extends any[] = Truncate<Params3>,
// Params1 extends any[] = Truncate<Params2>,
> = Params extends any
? ((...params: Params4) => void) | ((...params: Params3) => void)
: // | ((...params: Params2) => void)
// | ((...params: Params1) => void)
never;
/**
* The RowCountListener type describes a function that is used to listen to
* changes to the number of Row objects in a Table.
*
* This has schema-based typing. The following is a simplified representation:
*
* ```ts override
* export type RowCountListener<Store extends StoreAlias = StoreAlias> = (
* store: Store,
* tableId: Id,
* count: number,
* ) => void;
* ```
*
* A RowCountListener is provided when using the addRowCountListener method. See
* that method for specific examples.
*
* When called, a RowCountListener is given a reference to the Store, the Id of
* the Table whose Row Ids changed, and the number of Row objects in the Table.
* @param store A reference to the Store that changed.
* @param tableId The Id of the Table that changed.
* @param count The number of Row objects in the Table.
* @category Listener
* @since v4.1.0
*/
export type RowCountListener<
Schemas extends OptionalSchemas,
TableIdOrNull extends TableIdFromSchema<Schemas[0]> | null,
Store extends StoreAlias<Schemas> = StoreAlias<Schemas>,
> = (
store: Store,
tableId: TableIdOrNull extends null
? TableIdFromSchema<Schemas[0]>
: TableIdOrNull,
count: number,
) => void;
/**
* The RowIdsListener type describes a function that is used to listen to
* changes to the Row Ids in a Table.
*
* This has schema-based typing. The following is a simplified representation:
*
* ```ts override
* export type RowIdsListener<Store extends StoreAlias = StoreAlias> = (
* store: Store,
* tableId: Id,
* getIdChanges: GetIdChanges | undefined,
* ) => void;
* ```
*
* A RowIdsListener is provided when using the addRowIdsListener method. See
* that method for specific examples.
*
* When called, a RowIdsListener is given a reference to the Store, and the Id
* of the Table whose Row Ids changed.
*
* Since v3.3, the listener is also passed a GetIdChanges function that can be
* used to query which Ids changed during the transaction.
* @param store A reference to the Store that changed.
* @param tableId The Id of the Table that changed.
* @param getIdChanges A function that returns information about the Id changes,
* since v3.3.
* @category Listener
* @since v1.0.0
*/
export type RowIdsListener<
Schemas extends OptionalSchemas,
TableIdOrNull extends TableIdFromSchema<Schemas[0]> | null,
Store extends StoreAlias<Schemas> = StoreAlias<Schemas>,
> = (
store: Store,
tableId: TableIdOrNull extends null
? TableIdFromSchema<Schemas[0]>
: TableIdOrNull,
getIdChanges: GetIdChanges<Id> | undefined,
) => void;
/**
* The SortedRowIdsListener type describes a function that is used to listen to
* changes to sorted Row Ids in a Table.
*
* This has schema-based typing. The following is a simplified representation:
*
* ```ts override
* export type SortedRowIdsListener<Store extends StoreAlias = StoreAlias> = (
* store: Store,
* tableId: Id,
* cellId: Id | undefined,
* descending: boolean,
* offset: number,
* limit: number | undefined,
* sortedRowIds: Ids,
* ) => void;
* ```
*
* A SortedRowIdsListener is provided when using the addSortedRowIdsListener
* method. See that method for specific examples.
*
* When called, a SortedRowIdsListener is given a reference to the Store, the Id
* of the Table whose Row Ids sorting changed, the Cell Id being used to sort
* them, whether descending or not, and the offset and limit of the number of
* Ids returned, for pagination purposes. It also receives the sorted array of
* Ids itself, so that you can use them in the listener without the additional
* cost of an explicit call to getSortedRowIds.
* @param store A reference to the Store that changed.
* @param tableId The Id of the Table whose sorted Row Ids changed.
* @param cellId The Id of the Cell whose values were used for the sorting.
* @param descending Whether the sorting was in descending order.
* @param offset The number of Row Ids skipped.
* @param limit The maximum number of Row Ids returned.
* @param sortedRowIds The sorted Row Ids themselves.
* @category Listener
* @since v2.0.0
*/
export type SortedRowIdsListener<
Schemas extends OptionalSchemas,
TableId extends TableIdFromSchema<Schemas[0]>,
CellId extends CellIdFromSchema<Schemas[0], TableId> | undefined,
Descending extends boolean,
Offset extends number,
Limit extends number | undefined,
Store extends StoreAlias<Schemas> = StoreAlias<Schemas>,
> = (
store: Store,
tableId: TableId,
cellId: CellId,
descending: Descending,
offset: Offset,
limit: Limit,
sortedRowIds: Ids,
) => void;
/**
* The HasRowListener type describes a function that is used to listen to a Row
* being added to or removed from the Store.
*
* This has schema-based typing. The following is a simplified representation:
*
* ```ts override
* export type HasRowListener<Store extends StoreAlias = StoreAlias> = (
* store: Store,
* tableId: Id,
* rowId: Id,
* hasRow: boolean,
* ) => void;
* ```
*
* A HasRowListener is provided when using the addHasRowListener method. See
* that method for specific examples.
*
* When called, a HasRowListener is given a reference to the Store, the Id of
* the Table that changed, and the Id of the Row that changed. It is also given
* a flag to indicate whether the Row now exists (having not done previously),
* or does not (having done so previously).
* @param store A reference to the Store that changed.
* @param tableId The Id of the Table that changed.
* @param rowId The Id of the Row that changed.
* @param hasRow Whether the Row now exists or not.
* @category Listener
* @since v4.4.0
*/
export type HasRowListener<
Schemas extends OptionalSchemas,
TableIdOrNull extends TableIdFromSchema<Schemas[0]> | null,
RowIdOrNull extends IdOrNull,
Store extends StoreAlias<Schemas> = StoreAlias<Schemas>,
> = (
store: Store,
tableId: TableIdOrNull extends null
? TableIdFromSchema<Schemas[0]>
: TableIdOrNull,
rowId: RowIdOrNull extends null ? Id : RowIdOrNull,
hasRow: boolean,
) => void;
/**
* The RowListener type describes a function that is used to listen to changes
* to a Row.
*
* This has schema-based typing. The following is a simplified representation:
*
* ```ts override
* export type RowListener<Store extends StoreAlias = StoreAlias> = (
* store: Store,
* tableId: Id,
* rowId: Id,
* getCellChange: GetCellChange | undefined,
* ) => void;
* ```
*
* A RowListener is provided when using the addRowListener method. See that
* method for specific examples.
*
* When called, a RowListener is given a reference to the Store, the Id of the
* Table that changed, the Id of the Row that changed, and a GetCellChange
* function that can be used to query Cell values before and after the current
* transaction.
*
* Note that if the listener was manually forced to be called (with the
* callListener method rather than due to a real change in the Store), the
* GetCellChange function will not be present.
* @param store A reference to the Store that changed.
* @param tableId The Id of the Table that changed.
* @param rowId The Id of the Row that changed.
* @param getCellChange A function that returns information about any Cell's
* changes.
* @category Listener
* @since v1.0.0
*/
export type RowListener<
Schemas extends OptionalSchemas,
TableIdOrNull extends TableIdFromSchema<Schemas[0]> | null,
RowIdOrNull extends IdOrNull,
Store extends StoreAlias<Schemas> = StoreAlias<Schemas>,
> = (
store: Store,
tableId: TableIdOrNull extends null
? TableIdFromSchema<Schemas[0]>
: TableIdOrNull,
rowId: RowIdOrNull extends null ? Id : RowIdOrNull,
getCellChange: GetCellChange<Schemas[0]> | undefined,
) => void;
/**
* The CellIdsListener type describes a function that is used to listen to
* changes to the Cell Ids in a Row.
*
* This has schema-based typing. The following is a simplified representation:
*
* ```ts override
* export type CellIdsListener<Store extends StoreAlias = StoreAlias> = (
* store: Store,
* tableId: Id,
* rowId: Id,
* getIdChanges: GetIdChanges | undefined,
* ) => void;
* ```
*
* A CellIdsListener is provided when using the addCellIdsListener method. See
* that method for specific examples.
*
* When called, a CellIdsListener is given a reference to the Store, the Id of
* the Table that changed, and the Id of the Row whose Cell Ids changed.
*
* Since v3.3, the listener is also passed a GetIdChanges function that can be
* used to query which Ids changed during the transaction.
* @param store A reference to the Store that changed.
* @param tableId The Id of the Table that changed.
* @param rowId The Id of the Row that changed.
* @param getIdChanges A function that returns information about the Id changes,
* since v3.3.
* @category Listener
* @since v1.0.0
*/
export type CellIdsListener<
Schemas extends OptionalSchemas,
TableIdOrNull extends TableIdFromSchema<Schemas[0]> | null,
RowIdOrNull extends IdOrNull,
Store extends StoreAlias<Schemas> = StoreAlias<Schemas>,
Params extends any[] = (
TableIdOrNull extends null ? TableIdFromSchema<Schemas[0]> : TableIdOrNull
) extends infer TableId
? TableId extends TableIdFromSchema<Schemas[0]>
? [
store: Store,
tableId: TableId,
rowId: RowIdOrNull extends null ? Id : RowIdOrNull,
getIdChanges: GetIdChanges<CellIdFromSchema<Schemas[0], TableId>>,
]
: never
: never,
Params4 extends any[] =
| Params
| [store: never, tableId: never, rowId: never, getIdChanges: never],
Params3 extends any[] = Truncate<Params4>,
// Params2 extends any[] = Truncate<Params3>,
// Params1 extends any[] = Truncate<Params2>,
> = Params extends any
? ((...params: Params4) => void) | ((...params: Params3) => void)
: // | ((...params: Params2) => void)
// | ((...params: Params1) => void)
never;
/**
* The HasCellListener type describes a function that is used to listen to a
* Cell being added to or removed from the Store.
*
* This has schema-based typing. The following is a simplified representation:
*
* ```ts override
* export type HasCellListener<Store extends StoreAlias = StoreAlias> = (
* store: Store,
* tableId: Id,
* rowId: Id,
* cellId: Id,
* hasCell: boolean,
* ) => void;
* ```
*
* A HasCellListener is provided when using the addHasCellListener method. See
* that method for specific examples.
*
* When called, a HasCellListener is given a reference to the Store, the Id of
* the Table that changed, the Id of the Row that changed, and the Id of Cell
* that changed. It is also given a flag to indicate whether