Skip to content

Releases: tinyplex/tinybase

v5.0.3

08 Jul 05:31
Compare
Choose a tag to compare

This includes a final tiny breaking change for v5 (before the working week starts!)

In the WsServer API, the PathIdsListener and ClientIdsListener types are now given the changing path Id or client Id directly, rather than needing to call the clumsy getIdChanges callback.

v5.0.2

07 Jul 23:41
Compare
Choose a tag to compare

This release includes a few minor improvements to the ui-react module hooks, including:

  • ensuring the callbacks are stable references when GetId-typed functions are used
  • allowing the useDel* hooks to use GetId-typed functions in order to delete specific tables, rows, cells, or values based on the event parameter

Thanks to @cpojer for identifying these improvements.

v5.0.1

07 Jul 02:41
Compare
Choose a tag to compare

Fixes #151

v5.0.0

05 Jul 22:55
Compare
Choose a tag to compare

We're excited to announce this major release for TinyBase! It includes important data synchronization functionality and a range of other improvements.

In Summary

There are also some small breaking changes that may affect you (but which should easy to fix if they do).

Let's look at the major functionality in more detail!

The New MergeableStore Type

A key part of TinyBase v5.0 is the new mergeable-store module, which contains a subtype of Store - called MergeableStore - that can be merged with another with deterministic results. The implementation uses an encoded hybrid logical clock (HLC) to timestamp the changes made so that they can be cleanly merged.

The getMergeableContent method on a MergeableStore is used to get the state of a store that can be merged into another. The applyMergeableChanges method will let you apply that to (another) store. The merge method is a convenience function to bidirectionally merge two stores together:

import {createMergeableStore} from 'tinybase';

const localStore1 = createMergeableStore();
const localStore2 = createMergeableStore();

localStore1.setCell('pets', 'fido', 'species', 'dog');
localStore2.setCell('pets', 'felix', 'species', 'cat');

localStore1.merge(localStore2);

console.log(localStore1.getContent());
// -> [{pets: {felix: {species: 'cat'}, fido: {species: 'dog'}}}, {}]

console.log(localStore2.getContent());
// -> [{pets: {felix: {species: 'cat'}, fido: {species: 'dog'}}}, {}]

Please read the new Using A MergeableStore guide for more details of how to use this important new API.

A MergeableStore can be persisted locally, just like a regular Store into file, local and session storage, and simple SQLite environments such as Expo and SQLite3. These allow you to save the state of a MergeableStore locally before it has had the chance to be synchronized online, for example.

Which leads us onto the next important feature in v5.0, allowing you to synchronize stores between systems...

The New Synchronizer Framework

The v5.0 release also introduces the new concept of synchronization. Synchronizer objects implement a negotiation protocol that allows multiple MergeableStore objects to be merged together. This can be across a network, using WebSockets, for example:

import {WebSocketServer, WebSocket} from 'ws';
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: 8043}));

// On the first client machine:
const store1 = createMergeableStore();
const synchronizer1 = await createWsSynchronizer(
  store1,
  new WebSocket('ws://localhost:8043'),
);
await synchronizer1.startSync();
store1.setCell('pets', 'fido', 'legs', 4);

// On the second client machine:
const store2 = createMergeableStore();
const synchronizer2 = await createWsSynchronizer(
  store2,
  new WebSocket('ws://localhost:8043'),
);
await synchronizer2.startSync();
store2.setCell('pets', 'felix', 'price', 5);
// ...

console.log(store1.getTables());
// -> {pets: {felix: {price: 5}, fido: {legs: 4}}}
console.log(store2.getTables());
// -> {pets: {felix: {price: 5}, fido: {legs: 4}}}

synchronizer1.destroy();
synchronizer2.destroy();
server.destroy();

This release includes three types of Synchronizer:

  • The WsSynchronizer uses WebSockets to communicate between different systems as shown above.
  • The BroadcastChannelSynchronizer uses the browser's BroadcastChannel API to communicate between different tabs and workers.
  • The LocalSynchronizer demonstrates synchronization in memory on a single local system.

Notice that the WsSynchronizer assumes that there exists a server that can forward requests to other WsSynchronizer systems. This can be created using the createWsServer function that takes a WebSocketServer as also shown above.

Please read the new Using A Synchronizer guide for more details of how to synchronize your data.

Improved Module Folder Structure

We have previously found issues with legacy bundlers and other tools that didn't fully support the new exports field in the module's package.

To mitigate that, the TinyBase distribution now has a top-level folder structure that fully echoes the import paths, including signifiers for JavaScript versions, schema support, minification and so on.

Please read the comprehensive Importing TinyBase guide for more details of how to construct the correct import paths in v5.0.

Breaking Changes in v5.0

Module File Structure

If you previously had /lib/ in your import paths, you should remove it. You also do not have to explicitly specify whether you need the cjs version of TinyBase - if you are using a require rather than an import, you will get it automatically.

The non-minified version of the code is now default and you need to be explicit with you want minified code. Previously you would add /debug to the import path to get non-minified code, but now you add /min to the import path to get minified code.

Expo SQLite Persister

Previously the persister-expo-sqlite module supported expo-sqlite v13 and the persister-expo-sqlite-next module supported their modern 'next' package. In v5.0, the persister-expo-sqlite module only supports v14 and later, and the persister-expo-sqlite-next module has been removed.

The TinyBase Inspector

Previously, the React-based inspector (then known as StoreInspector) resided in the debug version of the ui-react-dom module. It now lives in its own ui-react-inspector module (so that it can be used against non-debug code) and has been renamed to Inspector.

Please update your imports and rename the component when used, accordingly. See the API documentation for details, or the demo, for example.

API Changes

The following changes have been made to the existing TinyBase API for consistency. These are less common parts of the API but should straightforward to correct if you are using them.

In the type definitions:

  • The GetTransactionChanges and GetTransactionLog types have been removed.
  • The TransactionChanges type has been renamed as the Changes type.
  • The Changes type now uses undefined instead of null to indicate a Cell or Value that has been deleted or ...
Read more

v4.8.17

03 Jul 05:12
Compare
Choose a tag to compare

Updates peer dependencies.

v4.8.15

23 Jun 00:14
Compare
Choose a tag to compare

Updates peer dependencies and fixes some documentation issues.

v4.8.14

16 Jun 13:05
Compare
Choose a tag to compare

This dials back the React version for peer dependencies so that TinyBase installs cleanly with the Expo create-expo-app tool.

v4.8.13

14 Jun 18:59
Compare
Choose a tag to compare

Updates peer dependencies.

v4.8.12

10 Jun 22:19
Compare
Choose a tag to compare

Updates peer dependencies.

v4.8.11

03 Jun 02:57
Compare
Choose a tag to compare

Updates peer dependencies.