@genie-design/tinybase
v5.1.6
Published
The reactive data store for local-first apps.
Downloads
4
Maintainers
Readme
import {createStore} from 'tinybase';
const store = createStore()
.setValues({employees: 3})
.setValue('open', true);
console.log(store.getValues());
// -> {employees: 3, open: true}
store
.setTable('pets', {fido: {species: 'dog'}})
.setCell('pets', 'fido', 'color', 'brown');
console.log(store.getRow('pets', 'fido'));
// -> {species: 'dog', color: 'brown'}
const listenerId = store.addTableListener('pets', () =>
console.log('changed'),
);
store.setCell('pets', 'fido', 'sold', false);
// -> 'changed'
store.delListener(listenerId);
import React from 'react';
import {createRoot} from 'react-dom/client';
import {useCell} from 'tinybase/ui-react';
const App1 = () => {
const color = useCell('pets', 'fido', 'color', store);
return <>Color: {color}</>;
};
const app = document.createElement('div');
const root = createRoot(app);
root.render(<App1 />);
console.log(app.innerHTML);
// -> 'Color: brown'
store.setCell('pets', 'fido', 'color', 'walnut');
console.log(app.innerHTML);
// -> 'Color: walnut'
store.setTablesSchema({
pets: {
species: {type: 'string'},
color: {type: 'string'},
sold: {type: 'boolean', default: false},
},
});
store.setRow('pets', 'polly', {species: 'parrot'});
console.log(store.getRow('pets', 'polly'));
// -> {species: 'parrot', sold: false}
store.delTablesSchema();
import {WebSocketServer, WebSocket} from 'ws';
import {createMergeableStore} from 'tinybase';
import {createWsServer} from 'tinybase/synchronizers/synchronizer-ws-server';
import {createWsSynchronizer} from 'tinybase/synchronizers/synchronizer-ws-client';
// On a server machine:
const server = createWsServer(
new WebSocketServer({port: 8040}),
);
// On a client machine:
const store1 = createMergeableStore();
const synchronizer1 = await createWsSynchronizer(
store1,
new WebSocket('ws://localhost:8040'),
);
await synchronizer1.startSync();
// ...
synchronizer1.destroy();
server.destroy();
import {createSessionPersister} from 'tinybase/persisters/persister-browser';
const persister = createSessionPersister(store, 'demo');
await persister.save();
console.log(sessionStorage.getItem('demo'));
// ->
`
[
{
"pets":{
"fido":{"species":"dog","color":"walnut","sold":false},
"polly":{"species":"parrot","sold":false}
}
},
{"employees":3,"open":true}
]
`;
persister.destroy();
sessionStorage.clear();
import {createQueries} from 'tinybase';
store
.setTable('pets', {
fido: {species: 'dog', ownerId: '1', price: 5},
rex: {species: 'dog', ownerId: '2', price: 4},
felix: {species: 'cat', ownerId: '2', price: 3},
cujo: {species: 'dog', ownerId: '3', price: 4},
})
.setTable('owners', {
1: {name: 'Alice', state: 'CA'},
2: {name: 'Bob', state: 'CA'},
3: {name: 'Carol', state: 'WA'},
});
const queries = createQueries(store);
queries.setQueryDefinition(
'prices',
'pets',
({select, join, group}) => {
select('species');
select('owners', 'state');
select('price');
join('owners', 'ownerId');
group('price', 'avg').as('avgPrice');
},
);
queries
.getResultSortedRowIds('prices', 'avgPrice', true)
.forEach((rowId) => {
console.log(queries.getResultRow('prices', rowId));
});
// -> {species: 'dog', state: 'CA', avgPrice: 4.5}
// -> {species: 'dog', state: 'WA', avgPrice: 4}
// -> {species: 'cat', state: 'CA', avgPrice: 3}
queries.destroy();
import {createMetrics} from 'tinybase';
store.setTable('species', {
dog: {price: 5},
cat: {price: 4},
worm: {price: 1},
});
const metrics = createMetrics(store);
metrics.setMetricDefinition(
'highestPrice', // metricId
'species', // tableId to aggregate
'max', // aggregation
'price', // cellId to aggregate
);
console.log(metrics.getMetric('highestPrice'));
// -> 5
metrics.addMetricListener('highestPrice', () =>
console.log(metrics.getMetric('highestPrice')),
);
store.setCell('species', 'horse', 'price', 20);
// -> 20
metrics.destroy();
import {createIndexes} from 'tinybase';
const indexes = createIndexes(store);
indexes.setIndexDefinition(
'bySpecies', // indexId
'pets', // tableId to index
'species', // cellId to index
);
console.log(indexes.getSliceIds('bySpecies'));
// -> ['dog', 'cat']
console.log(indexes.getSliceRowIds('bySpecies', 'dog'));
// -> ['fido', 'rex', 'cujo']
indexes.addSliceIdsListener('bySpecies', () =>
console.log(indexes.getSliceIds('bySpecies')),
);
store.setRow('pets', 'lowly', {species: 'worm'});
// -> ['dog', 'cat', 'worm']
indexes.destroy();
import {createRelationships} from 'tinybase';
const relationships = createRelationships(store);
relationships.setRelationshipDefinition(
'petSpecies', // relationshipId
'pets', // local tableId to link from
'species', // remote tableId to link to
'species', // cellId containing remote key
);
console.log(
store.getCell(
relationships.getRemoteTableId('petSpecies'),
relationships.getRemoteRowId('petSpecies', 'fido'),
'price',
),
);
// -> 5
relationships.destroy();
import {createCheckpoints} from 'tinybase';
const checkpoints = createCheckpoints(store);
store.setCell('pets', 'felix', 'sold', false);
checkpoints.addCheckpoint('pre-sale');
store.setCell('pets', 'felix', 'sold', true);
console.log(store.getCell('pets', 'felix', 'sold'));
// -> true
checkpoints.goBackward();
console.log(store.getCell('pets', 'felix', 'sold'));
// -> false
const tools = createTools(store);
const [dTs, ts] = tools.getStoreApi('shop');
// -- shop.d.ts --
/* Represents the 'pets' Table. */
export type PetsTable = {[rowId: Id]: PetsRow};
/* Represents a Row when getting the content of the 'pets' Table. */
export type PetsRow = {species: string /* ... */};
//...
// -- shop.ts --
export const createShop: typeof createShopDecl = () => {
//...
};