Releases: tinyplex/tinybase
v8.2.0-beta.1
Svelte DOM Components And Inspector
This release completes TinyBase's Svelte support with two new additions: the ui-svelte-dom module and the ui-svelte-inspector module.
The ui-svelte-dom module provides browser-ready Svelte components for rendering and editing TinyBase data as HTML tables. They mirror the React DOM components, but use Svelte component composition and props throughout:
<script>
import {createStore} from 'tinybase';
import {TableInHtmlTable} from 'tinybase/ui-svelte-dom';
const store = createStore().setTable('pets', {
fido: {species: 'dog', color: 'brown'},
felix: {species: 'cat', color: 'black'},
});
</script>
<TableInHtmlTable tableId="pets" {store} editable />Alongside the table components, the new ui-svelte-inspector module brings the TinyBase development inspector to Svelte apps too, making it easy to inspect and edit Stores, Indexes, Relationships, and Queries during development:
<script>
import {createStore} from 'tinybase';
import {Provider} from 'tinybase/ui-svelte';
import {Inspector} from 'tinybase/ui-svelte-inspector';
const store = createStore().setTable('pets', {
fido: {species: 'dog'},
});
</script>
<Provider {store}>
<Inspector />
</Provider>Read more in the Using Svelte DOM Components guide and the Inspecting Data guide.
New Demos
This release also adds a complete set of Svelte UI component demos, plus an Inspector demo, so you can see the new modules working across Stores, Indexes, Relationships, Queries, and editable views.
These demos intentionally mirror the React set where possible, making it easier to compare implementation patterns across frameworks.
There are no intended breaking changes in this release. If you spot any issues with the new Svelte DOM components or the Svelte inspector, please let us know!
v8.1
Svelte Support
This highly-anticipated release introduces the new ui-svelte module, bringing native Svelte 5 runes-based reactive bindings to TinyBase. The module provides reactive functions and view components for building reactive UIs without any additional state management.
Reactive functions return a reactive object backed by Svelte's reactivity. Any component that reads current from it will automatically re-render when the underlying TinyBase data changes:
<script>
import {createStore} from 'tinybase';
import {getCell} from 'tinybase/ui-svelte';
const store = createStore().setCell('pets', 'fido', 'color', 'brown');
const color = getCell('pets', 'fido', 'color', store);
</script>
<p>Color: {color.current}</p>The getCell function and the getValue function provide a writable current property that pairs naturally with Svelte's bind: directive for two-way data binding:
<script>
import {getCell} from 'tinybase/ui-svelte';
const color = getCell('pets', 'fido', 'color', store);
</script>
<input bind:value={color.current} />All reactive functions accept reactive getter functions as parameters — the MaybeGetter type (T | (() => T)) — so passing () => rowId from a $state variable causes the function to reactively track which row it reads, without unmounting and remounting.
The module further includes a provider component and context helpers for sharing TinyBase objects across a component tree, and many built-in view components for assembling UIs directly from Store data.
Read more in the ui-svelte module documentation and the Building UIs With Svelte guide.
New Demos
To showcase the new Svelte support, we have created two new Svelte-specific demos: a Hello World (Svelte) demo and a Countries (Svelte) demo. Check them out to see the new module in action.
The create-tinybase CLI tool also now includes an option to create a Svelte demo project, so you can easily get started with Svelte and TinyBase in exactly the same way you can with React:
> npm create tinybase@latest
📦 Creating your project...Breaking Changes
If you tried the ui-svelte module in earlier beta releases, there are some intentional breaking changes made to ensure the API is more idiomatic for Svelte. What was useX is now a reactive getX or hasX function, so for example useCell has become the getCell function and useHasCell has become the hasCell function. Context lookups also use getX, as with the getMetrics function, but those return TinyBase objects directly from Provider context rather than reactive current-based wrappers. Listener functions now use onX; so for example useCellListener has become the onCell function. The old useBindableCell and useBindableValue beta names have also gone away because the getCell function and getValue function expose the writable scalar accessors directly.
This release also contains a minor breaking change since v8.0. The tinybase/omni module no longer includes the ui-react module, ui-react-dom module, or ui-react-inspector module. Since the ui-svelte module exports many of the same names, including both in a single flat namespace would cause silent name collisions.
If you were importing React UI helpers from tinybase/omni, update your imports:
// Before
import {createStore, useCell, Provider} from 'tinybase/omni';
// After
import {createStore} from 'tinybase/omni';
import {useCell, Provider} from 'tinybase/ui-react';(Sorry about that!)
We need your help
We hope you enjoy exploring this early new Svelte support. But we really need feedback on how it works and whether or not you find it easy and idiomatic to work with! Please let us know in the issues, discussions, or on social media. Thanks and good luck!
v8.0.2
v8.0.1
This release updates dependencies and restores 100% test coverage.
v8.0.0
Object And Array Types
This release extends the range of types that a Cell or Value can hold. Previously, TinyBase supported string, number, boolean, and (since v7.0) null. Now you can also store plain JavaScript objects and arrays directly in a Store.
import {createStore} from 'tinybase';
const store = createStore().setRow('pets', 'fido', {
species: 'dog',
traits: {friendly: true, energetic: true},
vaccinations: ['rabies', 'distemper', 'parvovirus'],
});
console.log(store.getCell('pets', 'fido', 'traits'));
// -> {friendly: true, energetic: true}
console.log(store.getCell('pets', 'fido', 'vaccinations'));
// -> ['rabies', 'distemper', 'parvovirus']Internally, objects and arrays are stored as JSON-encoded strings with a special prefix character, so they round-trip transparently through persistence layers. But in and out of your application code, the Store API always expects or returns them as native JavaScript values.
Schemas also gain object and array as valid types:
store.setTablesSchema({
pets: {
species: {type: 'string'},
traits: {type: 'object', default: {}},
vaccinations: {type: 'array', default: []},
},
});
store.setRow('pets', 'fido', {species: 'dog'});
console.log(store.getRow('pets', 'fido'));
// -> {species: 'dog', traits: {}, vaccinations: []}
store.delSchema();Note that TinyBase does not deeply validate the contents of objects or arrays when a schema is applied - it simply checks that the value is of the right top-level type. For deeper validation, consider combining with a Middleware callback. On which note...
Introducing Middleware
This release introduces a powerful new system for intercepting and transforming data as it flows into your TinyBase Store. Middleware callbacks can be registered to fire before data is written to the Store, allowing you to modify, validate, or even reject changes before they take effect.
import {createMiddleware, createStore} from 'tinybase';
const store = createStore();
const middleware = createMiddleware(store);
middleware.addWillSetCellCallback((tableId, rowId, cellId, cell) => {
if (tableId === 'pets' && cellId === 'age' && cell < 0) {
// Reject negative ages by returning undefined
return undefined;
}
// Otherwise, allow the change to proceed unmodified
return cell;
});Read more in our new comprehensive Using Middleware guide, which includes examples of using Middleware for data validation, transformation, and more.
Middleware complements listeners but is distinct in that it runs before changes are applied to the Store, whereas listeners run after. Middleware can modify the data that listeners see, and can prevent changes from being applied at all by returning undefined. In conjunction with schemas, Middleware provides a powerful way to enforce data integrity and implement complex data transformations - and it should work in synchronization environments too.
Many, many thanks to Brandon Mason for designing and implementing this concept.
Despite the major version number, we trust there are no breaking changes in this release. But please let us know if you find any!
v7.3.5
This release updates dependencies.
v7.3.4
v7.3.3
v7.3.2
v7.3.1
This release updates dependencies.