tinybase 8.2.0-beta.1 → 8.2.0-beta.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/@types/ui-react-dom/index.d.ts +44 -10
- package/@types/ui-react-dom/with-schemas/index.d.ts +44 -10
- package/@types/ui-react-inspector/index.d.ts +4 -1
- package/@types/ui-react-inspector/with-schemas/index.d.ts +4 -1
- package/@types/ui-svelte-dom/index.d.ts +44 -10
- package/@types/ui-svelte-dom/with-schemas/index.d.ts +44 -10
- package/@types/ui-svelte-inspector/index.d.ts +4 -1
- package/@types/ui-svelte-inspector/with-schemas/index.d.ts +4 -1
- package/agents.md +7 -3
- package/min/ui-svelte-dom/index.js +1 -1
- package/min/ui-svelte-dom/index.js.gz +0 -0
- package/min/ui-svelte-dom/with-schemas/index.js +1 -1
- package/min/ui-svelte-dom/with-schemas/index.js.gz +0 -0
- package/min/ui-svelte-inspector/index.js +1 -1
- package/min/ui-svelte-inspector/index.js.gz +0 -0
- package/min/ui-svelte-inspector/with-schemas/index.js +1 -1
- package/min/ui-svelte-inspector/with-schemas/index.js.gz +0 -0
- package/package.json +11 -11
- package/readme.md +5 -5
- package/releases.md +55 -21
- package/ui-svelte/index.js +1 -1
- package/ui-svelte/with-schemas/index.js +1 -1
- package/ui-svelte-dom/index.js +22 -24
- package/ui-svelte-dom/with-schemas/index.js +22 -24
- package/ui-svelte-inspector/index.js +22 -24
- package/ui-svelte-inspector/with-schemas/index.js +22 -24
package/releases.md
CHANGED
|
@@ -1,4 +1,38 @@
|
|
|
1
|
-
<link rel="preload" as="image" href="https://beta.tinybase.org/inspector.webp"><link rel="preload" as="image" href="https://beta.tinybase.org/partykit.gif"><link rel="preload" as="image" href="https://beta.tinybase.org/ui-react-dom.webp"><link rel="preload" as="image" href="https://beta.tinybase.org/store-inspector.webp"><link rel="preload" as="image" href="https://beta.tinybase.org/car-analysis.webp"><link rel="preload" as="image" href="https://beta.tinybase.org/movie-database.webp"><p>This is a reverse chronological list of the major TinyBase releases, with highlighted features.</p><hr><h1 id="v8-
|
|
1
|
+
<link rel="preload" as="image" href="https://beta.tinybase.org/inspector.webp"><link rel="preload" as="image" href="https://beta.tinybase.org/partykit.gif"><link rel="preload" as="image" href="https://beta.tinybase.org/ui-react-dom.webp"><link rel="preload" as="image" href="https://beta.tinybase.org/store-inspector.webp"><link rel="preload" as="image" href="https://beta.tinybase.org/car-analysis.webp"><link rel="preload" as="image" href="https://beta.tinybase.org/movie-database.webp"><p>This is a reverse chronological list of the major TinyBase releases, with highlighted features.</p><hr><h1 id="v8-2">v8.2</h1><h2 id="svelte-dom-components-and-inspector">Svelte DOM Components And Inspector</h2><p>This release completes TinyBase's Svelte support with two new additions: the <a href="https://beta.tinybase.org/api/ui-svelte-dom/"><code>ui-svelte-dom</code></a> module and the <a href="https://beta.tinybase.org/api/ui-svelte-inspector/"><code>ui-svelte-inspector</code></a> module.</p><p>The <a href="https://beta.tinybase.org/api/ui-svelte-dom/"><code>ui-svelte-dom</code></a> 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:</p>
|
|
2
|
+
|
|
3
|
+
```svelte
|
|
4
|
+
<script>
|
|
5
|
+
import {createStore} from 'tinybase';
|
|
6
|
+
import {TableInHtmlTable} from 'tinybase/ui-svelte-dom';
|
|
7
|
+
|
|
8
|
+
const store = createStore().setTable('pets', {
|
|
9
|
+
fido: {species: 'dog', color: 'brown'},
|
|
10
|
+
felix: {species: 'cat', color: 'black'},
|
|
11
|
+
});
|
|
12
|
+
</script>
|
|
13
|
+
|
|
14
|
+
<TableInHtmlTable tableId="pets" {store} editable />
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
<p>Alongside the table components, the new <a href="https://beta.tinybase.org/api/ui-svelte-inspector/"><code>ui-svelte-inspector</code></a> module brings the TinyBase development inspector to Svelte apps too, making it easy to inspect and edit Stores, <a href="https://beta.tinybase.org/api/indexes/interfaces/indexes/indexes/"><code>Indexes</code></a>, <a href="https://beta.tinybase.org/api/relationships/interfaces/relationships/relationships/"><code>Relationships</code></a>, and <a href="https://beta.tinybase.org/api/queries/interfaces/queries/queries/"><code>Queries</code></a> during development:</p>
|
|
18
|
+
|
|
19
|
+
```svelte
|
|
20
|
+
<script>
|
|
21
|
+
import {createStore} from 'tinybase';
|
|
22
|
+
import {Provider} from 'tinybase/ui-svelte';
|
|
23
|
+
import {Inspector} from 'tinybase/ui-svelte-inspector';
|
|
24
|
+
|
|
25
|
+
const store = createStore().setTable('pets', {
|
|
26
|
+
fido: {species: 'dog'},
|
|
27
|
+
});
|
|
28
|
+
</script>
|
|
29
|
+
|
|
30
|
+
<Provider {store}>
|
|
31
|
+
<Inspector />
|
|
32
|
+
</Provider>
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
<p>Read more in the <a href="https://beta.tinybase.org/guides/building-uis-with-svelte/using-svelte-dom-components/">Using Svelte DOM Components</a> guide and the <a href="https://beta.tinybase.org/guides/inspecting-data/">Inspecting Data</a> guide.</p><h2 id="new-demos">New <a href="https://beta.tinybase.org/demos/">Demos</a></h2><p>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, <a href="https://beta.tinybase.org/api/indexes/interfaces/indexes/indexes/"><code>Indexes</code></a>, <a href="https://beta.tinybase.org/api/relationships/interfaces/relationships/relationships/"><code>Relationships</code></a>, <a href="https://beta.tinybase.org/api/queries/interfaces/queries/queries/"><code>Queries</code></a>, and editable views.</p><p>These demos intentionally mirror the React set where possible, making it easier to compare implementation patterns across frameworks.</p><p>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!</p><hr><h1 id="v8-1">v8.1</h1><h2 id="svelte-support">Svelte Support</h2><p>This highly-anticipated release introduces the new <a href="https://beta.tinybase.org/api/ui-svelte/"><code>ui-svelte</code></a> 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.</p><p>Reactive functions return a reactive object backed by Svelte's reactivity. Any component that reads <code>current</code> from it will automatically re-render when the underlying TinyBase data changes:</p>
|
|
2
36
|
|
|
3
37
|
```svelte
|
|
4
38
|
<script>
|
|
@@ -24,7 +58,7 @@
|
|
|
24
58
|
<input bind:value={color.current} />
|
|
25
59
|
```
|
|
26
60
|
|
|
27
|
-
<p>All reactive functions accept reactive getter functions as parameters — the <a href="https://beta.tinybase.org/api/ui-svelte/type-aliases/identity/maybegetter/"><code>MaybeGetter</code></a> type (<code>T | (() => T)</code>) — so passing <code>() => rowId</code> from a <code>$state</code> variable causes the function to reactively track which row it reads, without unmounting and remounting.</p><p>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 <a href="https://beta.tinybase.org/api/the-essentials/creating-stores/store/"><code>Store</code></a> data.</p><p>Read more in the <a href="https://beta.tinybase.org/api/ui-svelte/"><code>ui-svelte</code></a> module documentation and the <a href="https://beta.tinybase.org/guides/building-uis
|
|
61
|
+
<p>All reactive functions accept reactive getter functions as parameters — the <a href="https://beta.tinybase.org/api/ui-svelte/type-aliases/identity/maybegetter/"><code>MaybeGetter</code></a> type (<code>T | (() => T)</code>) — so passing <code>() => rowId</code> from a <code>$state</code> variable causes the function to reactively track which row it reads, without unmounting and remounting.</p><p>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 <a href="https://beta.tinybase.org/api/the-essentials/creating-stores/store/"><code>Store</code></a> data.</p><p>Read more in the <a href="https://beta.tinybase.org/api/ui-svelte/"><code>ui-svelte</code></a> module documentation and the <a href="https://beta.tinybase.org/guides/building-uis-with-svelte/">Building UIs With Svelte</a> guide.</p><h2 id="new-demos">New <a href="https://beta.tinybase.org/demos/">Demos</a></h2><p>To showcase the new Svelte support, we have created two new Svelte-specific demos: a <a href="https://beta.tinybase.org/demos/hello-world/hello-world-svelte/">Hello World (Svelte)</a> demo and a <a href="https://beta.tinybase.org/demos/countries/countries-svelte/">Countries (Svelte)</a> demo. Check them out to see the new module in action.</p><p>The <code>create-tinybase</code> 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:</p>
|
|
28
62
|
|
|
29
63
|
```bash
|
|
30
64
|
> npm create tinybase@latest
|
|
@@ -34,7 +68,7 @@
|
|
|
34
68
|
|
|
35
69
|
<h2 id="breaking-changes">Breaking <a href="https://beta.tinybase.org/api/store/type-aliases/transaction/changes/"><code>Changes</code></a></h2><p>If you tried the <a href="https://beta.tinybase.org/api/ui-svelte/"><code>ui-svelte</code></a> module in earlier beta releases, there are some intentional breaking changes made to ensure the API is more idiomatic for Svelte. What was <code>useX</code> is now a reactive <code>getX</code> or <code>hasX</code> function, so for example <code>useCell</code> has become the <a href="https://beta.tinybase.org/api/ui-svelte/functions/getter/getcell/"><code>getCell</code></a> function and <code>useHasCell</code> has become the <a href="https://beta.tinybase.org/api/ui-svelte/functions/getter/hascell/"><code>hasCell</code></a> function. Context lookups also use <code>getX</code>, as with the <a href="https://beta.tinybase.org/api/ui-svelte/functions/getter/getmetrics/"><code>getMetrics</code></a> function, but those return TinyBase objects directly from Provider context rather than reactive <code>current</code>-based wrappers. Listener functions now use <code>onX</code>; so for example <code>useCellListener</code> has become the <a href="https://beta.tinybase.org/api/ui-svelte/functions/listener/oncell/"><code>onCell</code></a> function. The old <code>useBindableCell</code> and <code>useBindableValue</code> beta names have also gone away because the <a href="https://beta.tinybase.org/api/ui-svelte/functions/getter/getcell/"><code>getCell</code></a> function and <a href="https://beta.tinybase.org/api/ui-svelte/functions/getter/getvalue/"><code>getValue</code></a> function expose the writable scalar accessors directly.</p><p>This release also contains a minor breaking change since v8.0. The <code>tinybase/omni</code> module no longer includes the <a href="https://beta.tinybase.org/api/ui-react/"><code>ui-react</code></a> module, <a href="https://beta.tinybase.org/api/ui-react-dom/"><code>ui-react-dom</code></a> module, or <a href="https://beta.tinybase.org/api/ui-react-inspector/"><code>ui-react-inspector</code></a> module. Since the <a href="https://beta.tinybase.org/api/ui-svelte/"><code>ui-svelte</code></a> module exports many of the same names, including both in a single flat namespace would cause silent name collisions.</p><p>If you were importing React UI helpers from <code>tinybase/omni</code>, update your imports:</p>
|
|
36
70
|
|
|
37
|
-
```js
|
|
71
|
+
```js ignore
|
|
38
72
|
// Before
|
|
39
73
|
import {createStore, useCell, Provider} from 'tinybase/omni';
|
|
40
74
|
|
|
@@ -251,7 +285,7 @@ console.log(store.getRow('pets', 'fido'));
|
|
|
251
285
|
|
|
252
286
|
<p>This is the correct semantic mapping since SQL databases have fixed schemas where every row must account for every column. See the <a href="https://beta.tinybase.org/guides/persistence/database-persistence/">Database Persistence</a> guide for more details.</p><h2 id="migration-guide">Migration Guide</h2><p>If you are using database persisters, you should:</p><ol><li><p><strong>Review your data access patterns</strong>: If you were checking <code>hasCell(...) === false</code> to detect missing data, you now need to check <code>getCell(...) === null</code> for null values.</p></li><li><p><strong>Update your schemas</strong>: Add <code>allowNull: true</code> to <a href="https://beta.tinybase.org/api/store/type-aliases/store/cell/"><code>Cell</code></a> definitions that should permit null values:</p></li></ol>
|
|
253
287
|
|
|
254
|
-
```js
|
|
288
|
+
```js ignore
|
|
255
289
|
store.setTablesSchema({
|
|
256
290
|
pets: {
|
|
257
291
|
species: {type: 'string'},
|
|
@@ -283,7 +317,7 @@ await opfsPersister.destroy();
|
|
|
283
317
|
|
|
284
318
|
<p>That's it! If you've used other TinyBase persisters, this API should be easy and familiar to use.</p><p>One caveat: observability in OPFS is not yet standardized in browsers. This means that the auto-load functionality of the persister may not work as expected, although a best effort is made using the experimental FileSystemObserverAPI, so please let us know how that works!</p><hr><h1 id="v6-6">v6.6</h1><p>This release improves the Inspector tool, making it easier to debug, inspect, and mutate your TinyBase stores.</p><p><img src="https://beta.tinybase.org/inspector.webp" alt="Inspector" title="Inspector"></p><p>As well as a modernized UI, new in this release is the ability to create, duplicate, or delete tables, rows, values and cells directly within the Inspector. Press the 'pencil' icon to start editing items, and then hover over the new icons to see how to manipulate the data.</p><p>See the <a href="https://beta.tinybase.org/guides/inspecting-data/">Inspecting Data</a> guide for more information about how to use the Inspector in your application during development.</p><h1 id="v6-5">v6.5</h1><p>This release includes the new <a href="https://beta.tinybase.org/api/persister-react-native-mmkv/"><code>persister-react-native-mmkv</code></a> module, which allows you to persist data in a React Native MMKV store via the <a href="https://github.com/mrousavy/react-native-mmkv">react-native-mmkv</a> library.</p><p>Usage should be as simple as this:</p>
|
|
285
319
|
|
|
286
|
-
```js
|
|
320
|
+
```js ignore
|
|
287
321
|
import {createMMKV} from 'react-native-mmkv';
|
|
288
322
|
import {createReactNativeMmkvPersister} from 'tinybase/persisters/persister-react-native-mmkv';
|
|
289
323
|
|
|
@@ -297,7 +331,7 @@ await persister.save();
|
|
|
297
331
|
|
|
298
332
|
<p>A huge shout out to <a href="https://github.com/JeremyBarbet">Jérémy Barbet</a> for this new persister!</p><hr><h1 id="v6-4">v6.4</h1><p>This release includes the new <a href="https://beta.tinybase.org/api/persister-react-native-sqlite/"><code>persister-react-native-sqlite</code></a> module, which allows you to persist data in a React Native SQLite database via the <a href="https://github.com/andpor/react-native-sqlite-storage">react-native-sqlite-storage</a> library.</p><p>Usage should be as simple as this:</p>
|
|
299
333
|
|
|
300
|
-
```js
|
|
334
|
+
```js ignore
|
|
301
335
|
import {enablePromise, openDatabase} from 'react-native-sqlite-storage';
|
|
302
336
|
import {createStore} from 'tinybase';
|
|
303
337
|
import {createReactNativeSqlitePersister} from 'tinybase/persisters/persister-react-native-sqlite';
|
|
@@ -313,7 +347,7 @@ await persister.save();
|
|
|
313
347
|
|
|
314
348
|
<p>Please let us know how you get on with this new <a href="https://beta.tinybase.org/api/the-essentials/persisting-stores/persister/"><code>Persister</code></a>, and if you have any feedback or suggestions.</p><hr><h1 id="v6-3">v6.3</h1><p>This release includes the new <a href="https://beta.tinybase.org/api/persister-durable-object-sql-storage/"><code>persister-durable-object-sql-storage</code></a> module, which allows you to persist data in a Cloudflare Durable Object's SQLite-based storage in conjunction with websocket-based synchronization (using the <a href="https://beta.tinybase.org/api/the-essentials/synchronizing-stores/wsserverdurableobject/"><code>WsServerDurableObject</code></a> class).</p><p>Huge thanks to <a href="https://github.com/acoreyj">Corey Jepperson</a> for implementing the entirety of this functionality!</p>
|
|
315
349
|
|
|
316
|
-
```js
|
|
350
|
+
```js ignore
|
|
317
351
|
import {createMergeableStore} from 'tinybase';
|
|
318
352
|
import {createDurableObjectSqlStoragePersister} from 'tinybase/persisters/persister-durable-object-sql-storage';
|
|
319
353
|
import {WsServerDurableObject} from 'tinybase/synchronizers/synchronizer-ws-server-durable-object';
|
|
@@ -338,7 +372,7 @@ export class MyDurableObject extends WsServerDurableObject {
|
|
|
338
372
|
|
|
339
373
|
<p>Prior to this release, the only way to persist data in a Durable Object was to use the <a href="https://beta.tinybase.org/api/persister-durable-object-storage/"><code>persister-durable-object-storage</code></a> module, which uses CloudFlare's key-value storage backend behind the scenes.</p><p>However, Cloudflare's SQLite storage backend for Durable Objects offers significantly better pricing compared to the key-value storage backend. The SQLite storage backend is Cloudflare's recommended storage option for new Durable Object namespaces.</p><p>Note that, before using this persister, you must configure your Durable Object class to use SQLite storage by adding a migration to your <code>wrangler.toml</code> or <code>wrangler.json</code> configuration file. Use <code>new_sqlite_classes</code> in your migration configuration to enable SQLite storage for your Durable Object class. See the module documentation for more information.</p><p>This release also addresses a local-storage persistence issue, #<a href="https://github.com/tinyplex/tinybase/issues/257">257</a>.</p><hr><h1 id="v6-2">v6.2</h1><p>This release contains various packaging improvements and exposes some internal HLC functions that are useful for people building their own persisters or synchronizers.</p><h2 id="new-omni-module">New <code>omni</code> module</h2><p>There is a new <code>omni</code> module that is an explicit superset of everything in the TinyBase ecosystem. It exports the features and functionality of every <code>tinybase/*</code> module, including every persister, every synchronizer, and every UI component. This is useful for applications that want to use multiple facets of the overall TinyBase ecosystem and also benefit from the fact they share a lot of code internally.</p>
|
|
340
374
|
|
|
341
|
-
```js
|
|
375
|
+
```js ignore
|
|
342
376
|
import {createStore, createSqliteBunPersister} from 'tinybase/omni';
|
|
343
377
|
```
|
|
344
378
|
|
|
@@ -379,7 +413,7 @@ await persister.destroy();
|
|
|
379
413
|
|
|
380
414
|
<p>There's more information the documentation for the new <a href="https://beta.tinybase.org/api/persister-sqlite-bun/"><code>persister-sqlite-bun</code></a> module.</p><h2 id="subset-persistence">Subset persistence</h2><p>Persisters that load and save data to an underlying database can now be configured to only load a <em>subset</em> of the rows in a table into a <a href="https://beta.tinybase.org/api/the-essentials/creating-stores/store/"><code>Store</code></a>.</p><p>This is useful for reducing the amount of data that is loaded into memory, or for working with a subset of data that is relevant to the current user, for example.</p><p>Do this by specifying a <code>condition</code> in the <a href="https://beta.tinybase.org/api/the-essentials/persisting-stores/persister/"><code>Persister</code></a> configuration. This is a single string argument which is used as a SQL <code>WHERE</code> clause when reading and observing data in the table.</p><p>For example, the following code will only load rows from the <code>pets</code> database table where the <code>sold</code> column is set to <code>0</code>:</p>
|
|
381
415
|
|
|
382
|
-
```js
|
|
416
|
+
```js ignore
|
|
383
417
|
const subsetPersister = createSqliteWasmPersister(store, sqlite3, db, {
|
|
384
418
|
mode: 'tabular',
|
|
385
419
|
tables: {
|
|
@@ -391,19 +425,19 @@ const subsetPersister = createSqliteWasmPersister(store, sqlite3, db, {
|
|
|
391
425
|
|
|
392
426
|
<p>See the '<a href="https://beta.tinybase.org/guides/persistence/database-persistence/#loading-subsets-of-database-tables">Loading subsets of database tables</a>' section of the <a href="https://beta.tinybase.org/guides/persistence/database-persistence/">Database Persistence</a> guide for more details. And a huge thank you to Jakub Riedl (<a href="https://github.com/jakubriedl">@jakubriedl</a>) for landing this functionality!</p><h2 id="destructured-object-arguments-for-sorted-row-ids">Destructured object arguments for sorted <a href="https://beta.tinybase.org/api/store/type-aliases/store/row/"><code>Row</code></a> <a href="https://beta.tinybase.org/api/common/type-aliases/identity/ids/"><code>Ids</code></a></h2><p>The <a href="https://beta.tinybase.org/api/store/interfaces/store/store/methods/getter/getsortedrowids/"><code>getSortedRowIds</code></a> method on the <a href="https://beta.tinybase.org/api/the-essentials/creating-stores/store/"><code>Store</code></a> interface has a number of optional parameters and it can be tiresome to fill in the defaults if you only want to change the last one, for example. So this release introduces an override such that you can pass an object with the parameters as properties.</p><p>So instead of:</p>
|
|
393
427
|
|
|
394
|
-
```js
|
|
428
|
+
```js ignore
|
|
395
429
|
store.getSortedRowIds('pets', undefined, undefined, undefined, 10);
|
|
396
430
|
```
|
|
397
431
|
|
|
398
432
|
<p>You can now do:</p>
|
|
399
433
|
|
|
400
|
-
```js
|
|
434
|
+
```js ignore
|
|
401
435
|
store.getSortedRowIds({tableId: 'pets', limit: 10});
|
|
402
436
|
```
|
|
403
437
|
|
|
404
438
|
<p>This pattern is also made available to the <a href="https://beta.tinybase.org/api/store/interfaces/store/store/methods/listener/addsortedrowidslistener/"><code>addSortedRowIdsListener</code></a> method, the <a href="https://beta.tinybase.org/api/ui-react/functions/store-hooks/usesortedrowids/"><code>useSortedRowIds</code></a> hook, and the <a href="https://beta.tinybase.org/api/ui-react/functions/store-hooks/usesortedrowidslistener/"><code>useSortedRowIdsListener</code></a> hook.</p><h2 id="new-startautopersisting-method">New <a href="https://beta.tinybase.org/api/persisters/interfaces/persister/persister/methods/lifecycle/startautopersisting/"><code>startAutoPersisting</code></a> method</h2><p>The new <a href="https://beta.tinybase.org/api/persisters/interfaces/persister/persister/methods/lifecycle/startautopersisting/"><code>startAutoPersisting</code></a> method and <a href="https://beta.tinybase.org/api/persisters/interfaces/persister/persister/methods/lifecycle/stopautopersisting/"><code>stopAutoPersisting</code></a> method on the <a href="https://beta.tinybase.org/api/the-essentials/persisting-stores/persister/"><code>Persister</code></a> interface act as convenience methods for starting (and stopping) both the automatic loading and saving of data.</p><h2 id="new-createmergeablestore-getnow-parameter">New createMergeableStore getNow parameter</h2><p>The <a href="https://beta.tinybase.org/api/the-essentials/creating-stores/createmergeablestore/"><code>createMergeableStore</code></a> function now takes an optional <code>getNow</code> argument that lets you override the clock used to generate HLC timestamps.</p><h2 id="asynchronous-persister-synchronizer-methods">Asynchronous <a href="https://beta.tinybase.org/api/the-essentials/persisting-stores/persister/"><code>Persister</code></a> & <a href="https://beta.tinybase.org/api/the-essentials/synchronizing-stores/synchronizer/"><code>Synchronizer</code></a> methods</h2><p>Please note that some methods in the <a href="https://beta.tinybase.org/api/the-essentials/persisting-stores/persister/"><code>Persister</code></a> and <a href="https://beta.tinybase.org/api/the-essentials/synchronizing-stores/synchronizer/"><code>Synchronizer</code></a> APIs are now asynchronous. Although most implementations of these methods are synchronous, some (particularly for Postgres-based databases) are no longer so and you are recommended to await them all.</p><p>The <a href="https://beta.tinybase.org/api/persisters/interfaces/persister/persister/methods/load/stopautoload/"><code>stopAutoLoad</code></a> method, the <a href="https://beta.tinybase.org/api/persisters/interfaces/persister/persister/methods/save/stopautosave/"><code>stopAutoSave</code></a> method, and the <a href="https://beta.tinybase.org/api/metrics/interfaces/metrics/metrics/methods/lifecycle/destroy/"><code>destroy</code></a> method in the base <a href="https://beta.tinybase.org/api/the-essentials/persisting-stores/persister/"><code>Persister</code></a> interface have been marked asynchronous and return Promises. The <a href="https://beta.tinybase.org/api/synchronizers/interfaces/synchronizer/synchronizer/methods/synchronization/stopsync/"><code>stopSync</code></a> method in the <a href="https://beta.tinybase.org/api/the-essentials/synchronizing-stores/synchronizer/"><code>Synchronizer</code></a> interface and the <a href="https://beta.tinybase.org/api/metrics/interfaces/metrics/metrics/methods/lifecycle/destroy/"><code>destroy</code></a> method in the <a href="https://beta.tinybase.org/api/the-essentials/synchronizing-stores/synchronizer/"><code>Synchronizer</code></a> server interfaces should also be considered asynchronous.</p><hr><h1 id="v6-0">v6.0</h1><p>This major release is about updating dependencies and infrastructure rather than adding new features.</p><p>The most notable changes for users are:</p><ul><li>The package distribution only includes modern ESM packages (both minified and non-minified).</li><li>React 19 is now compatible as an optional peer dependency.</li><li>The tools module and TinyBase CLI have been removed.</li></ul><p>If you have been using CJS or UMD packages, you will need to update your bundling strategy for TinyBase (in the same way that you will have had to have done for React 19, for example) but this change should be compatible with most packaging tools. If you had been using the library directly a browser, you should consider the <a href="https://esm.sh/">esm.sh</a> CDN, as we have for our demos.</p><p>As a result of these changes, there have been some additional knock-on effects to the project and developer infrastructure as a whole. For example:</p><ul><li>The test suite has been updated to use <code>react-testing-library</code> instead of <code>react-test-renderer</code>.</li><li>The React <code>jsx-runtime</code> is used for JSX transformations.</li><li><a href="https://beta.tinybase.org/demos/">Demos</a> (and CodePen examples) have been updated to use an <code>importmap</code> mapping the modules to the <a href="https://esm.sh/">esm.sh</a> CDN.</li><li>ESLint has finally been upgraded to v9.</li></ul><p>Note that TinyBase v6.0 adds no new functionality, so you can afford to stay on v5.4.x for a while if these changes are somehow incompatible for you. However, all future functionality changes and bug fixes <em>will</em> take effect as v6.x releases (and probably won't be back-ported to v5.4.x), so you should endeavor to upgrade as soon as you can.</p><p>Please let us know how these changes find you, and please file an issue on GitHub if you need help adapting to any of them.</p><hr><h1 id="v5-4">v5.4</h1><h2 id="durable-objects-synchronization">Durable Objects synchronization</h2><p>This release contains a new WebSocket synchronization server that runs on Cloudflare as a Durable Object.</p><p><embed src="https://beta.tinybase.org/durable.svg" title="Durable Objects"></p><p>It's in the new <a href="https://beta.tinybase.org/api/synchronizer-ws-server-durable-object/"><code>synchronizer-ws-server-durable-object</code></a> module, and you use it by extending the <a href="https://beta.tinybase.org/api/the-essentials/synchronizing-stores/wsserverdurableobject/"><code>WsServerDurableObject</code></a> class. Use the <a href="https://beta.tinybase.org/api/synchronizer-ws-server-durable-object/functions/creation/getwsserverdurableobjectfetch/"><code>getWsServerDurableObjectFetch</code></a> function for conveniently binding your Cloudflare Worker to your Durable Object:</p>
|
|
405
439
|
|
|
406
|
-
```js
|
|
440
|
+
```js ignore
|
|
407
441
|
import {
|
|
408
442
|
WsServerDurableObject,
|
|
409
443
|
getWsServerDurableObjectFetch,
|
|
@@ -424,7 +458,7 @@ class_name = "MyDurableObject"
|
|
|
424
458
|
|
|
425
459
|
<p>With this you can now easily connect and synchronize clients that are using the <a href="https://beta.tinybase.org/api/synchronizer-ws-client/interfaces/synchronizer/wssynchronizer/"><code>WsSynchronizer</code></a> synchronizer.</p><h2 id="durable-objects-persistence">Durable Objects <a href="https://beta.tinybase.org/guides/persistence/">Persistence</a></h2><p>But wait! There's more. Durable Objects also provide a storage mechanism, and sometimes you want TinyBase data to also be stored on the server (in case all the current clients disconnect and a new one joins, for example). So this release of TinyBase also includes a dedicated persister, the <a href="https://beta.tinybase.org/api/persister-durable-object-storage/interfaces/persister/durableobjectstoragepersister/"><code>DurableObjectStoragePersister</code></a>, that also synchronizes the data to the Durable Object storage layer.</p><p>You create it with the <a href="https://beta.tinybase.org/api/persister-durable-object-storage/functions/creation/createdurableobjectstoragepersister/"><code>createDurableObjectStoragePersister</code></a> function, and hook it into the Durable Object by returning it from the <a href="https://beta.tinybase.org/api/synchronizer-ws-server-durable-object/classes/creation/wsserverdurableobject/methods/creation/createpersister/"><code>createPersister</code></a> method of your <a href="https://beta.tinybase.org/api/the-essentials/synchronizing-stores/wsserverdurableobject/"><code>WsServerDurableObject</code></a>:</p>
|
|
426
460
|
|
|
427
|
-
```js
|
|
461
|
+
```js ignore
|
|
428
462
|
export class MyDurableObject extends WsServerDurableObject {
|
|
429
463
|
createPersister() {
|
|
430
464
|
return createDurableObjectStoragePersister(
|
|
@@ -550,7 +584,7 @@ await server.destroy();
|
|
|
550
584
|
|
|
551
585
|
<p>This release includes three types of <a href="https://beta.tinybase.org/api/the-essentials/synchronizing-stores/synchronizer/"><code>Synchronizer</code></a>:</p><ul><li>The <a href="https://beta.tinybase.org/api/synchronizer-ws-client/interfaces/synchronizer/wssynchronizer/"><code>WsSynchronizer</code></a> uses WebSockets to communicate between different systems as shown above.</li><li>The <a href="https://beta.tinybase.org/api/synchronizer-broadcast-channel/interfaces/synchronizer/broadcastchannelsynchronizer/"><code>BroadcastChannelSynchronizer</code></a> uses the browser's BroadcastChannel API to communicate between different tabs and workers.</li><li>The <a href="https://beta.tinybase.org/api/synchronizer-local/interfaces/synchronizer/localsynchronizer/"><code>LocalSynchronizer</code></a> demonstrates synchronization in memory on a single local system.</li></ul><p>Notice that the <a href="https://beta.tinybase.org/api/synchronizer-ws-client/interfaces/synchronizer/wssynchronizer/"><code>WsSynchronizer</code></a> assumes that there exists a server that can forward requests to other <a href="https://beta.tinybase.org/api/synchronizer-ws-client/interfaces/synchronizer/wssynchronizer/"><code>WsSynchronizer</code></a> systems. This can be created using the <a href="https://beta.tinybase.org/api/synchronizer-ws-server/functions/creation/createwsserver/"><code>createWsServer</code></a> function that takes a WebSocketServer as also shown above.</p><p>Please read the new <a href="https://beta.tinybase.org/guides/synchronization/using-a-synchronizer/">Using A Synchronizer</a> guide for more details of how to synchronize your data.</p><h2 id="improved-module-folder-structure">Improved Module Folder Structure</h2><p>We have previously found issues with legacy bundlers and other tools that didn't fully support the new <code>exports</code> field in the module's package.</p><p>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.</p><p>Please read the comprehensive <a href="https://beta.tinybase.org/guides/the-basics/importing-tinybase/">Importing TinyBase</a> guide for more details of how to construct the correct import paths in v5.0.</p><h2 id="breaking-changes-in-v5-0">Breaking <a href="https://beta.tinybase.org/api/store/type-aliases/transaction/changes/"><code>Changes</code></a> in v5.0</h2><h3 id="module-file-structure">Module File Structure</h3><p>If you previously had <code>/lib/</code> in your import paths, you should remove it. You also do not have to explicitly specify whether you need the <code>cjs</code> version of TinyBase - if you are using a <code>require</code> rather than an <code>import</code>, you will get it automatically.</p><p>The non-minified version of the code is now default and you need to be explicit when you <em>want</em> minified code. Previously you would add <code>/debug</code> to the import path to get non-minified code, but now you add <code>/min</code> to the import path to get <em>minified</em> code.</p><h3 id="expo-sqlite-persister">Expo SQLite <a href="https://beta.tinybase.org/api/the-essentials/persisting-stores/persister/"><code>Persister</code></a></h3><p>Previously the <a href="https://beta.tinybase.org/api/persister-expo-sqlite/"><code>persister-expo-sqlite</code></a> module supported expo-sqlite v13 and the persister-expo-sqlite-next module supported their modern 'next' package. In v5.0, the <a href="https://beta.tinybase.org/api/persister-expo-sqlite/"><code>persister-expo-sqlite</code></a> module only supports v14 and later, and the persister-expo-sqlite-next module has been removed.</p><h3 id="the-tinybase-inspector">The TinyBase Inspector</h3><p>Previously, the React-based inspector (then known as <code>StoreInspector</code>) resided in the debug version of the <a href="https://beta.tinybase.org/api/ui-react-dom/"><code>ui-react-dom</code></a> module. It now lives in its own <a href="https://beta.tinybase.org/api/ui-react-inspector/"><code>ui-react-inspector</code></a> module (so that it can be used against non-debug code) and has been renamed to Inspector.</p><p>Please update your imports and rename the component when used, accordingly. See the API documentation for details, or the <a href="https://beta.tinybase.org/demos/ui-components-react/inspector-react/"><inspector>(React)</inspector></a>demo, for example.</p><h3 id="api-changes">API <a href="https://beta.tinybase.org/api/store/type-aliases/transaction/changes/"><code>Changes</code></a></h3><p>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.</p><p>In the type definitions:</p><ul><li>The GetTransactionChanges and GetTransactionLog types have been removed.</li><li>The TransactionChanges type has been renamed as the <a href="https://beta.tinybase.org/api/store/type-aliases/transaction/changes/"><code>Changes</code></a> type.</li><li>The <a href="https://beta.tinybase.org/api/store/type-aliases/transaction/changes/"><code>Changes</code></a> type now uses <code>undefined</code> instead of <code>null</code> to indicate a <a href="https://beta.tinybase.org/api/store/type-aliases/store/cell/"><code>Cell</code></a> or <a href="https://beta.tinybase.org/api/store/type-aliases/store/value/"><code>Value</code></a> that has been deleted or that was not present.</li><li>The <a href="https://beta.tinybase.org/api/store/type-aliases/transaction/transactionlog/"><code>TransactionLog</code></a> type is now an array instead of a JavaScript object.</li></ul><p>In the <a href="https://beta.tinybase.org/api/the-essentials/creating-stores/store/"><code>Store</code></a> interface:</p><ul><li>There is a new <a href="https://beta.tinybase.org/api/store/interfaces/store/store/methods/transaction/gettransactionchanges/"><code>getTransactionChanges</code></a> method and a new getTransactionLog method.</li><li>The setTransactionChanges method is renamed as the <a href="https://beta.tinybase.org/api/store/interfaces/store/store/methods/setter/applychanges/"><code>applyChanges</code></a> method.</li><li>A <a href="https://beta.tinybase.org/api/store/type-aliases/callback/dorollback/"><code>DoRollback</code></a> function no longer gets passed arguments. You can use the <a href="https://beta.tinybase.org/api/store/interfaces/store/store/methods/transaction/gettransactionchanges/"><code>getTransactionChanges</code></a> method and <a href="https://beta.tinybase.org/api/store/interfaces/store/store/methods/transaction/gettransactionlog/"><code>getTransactionLog</code></a> method directly instead.</li><li>Similarly, a <a href="https://beta.tinybase.org/api/store/type-aliases/listener/transactionlistener/"><code>TransactionListener</code></a> function no longer gets passed arguments.</li></ul><p>In the <a href="https://beta.tinybase.org/api/persisters/"><code>persisters</code></a> module:</p><ul><li>The <a href="https://beta.tinybase.org/api/persisters/functions/creation/createcustompersister/"><code>createCustomPersister</code></a> function now takes a final optional boolean (<code>supportsMergeableStore</code>) to indicate that the <a href="https://beta.tinybase.org/api/the-essentials/persisting-stores/persister/"><code>Persister</code></a> can support <a href="https://beta.tinybase.org/api/mergeable-store/interfaces/mergeable/mergeablestore/"><code>MergeableStore</code></a> as well as <a href="https://beta.tinybase.org/api/the-essentials/creating-stores/store/"><code>Store</code></a> objects.</li><li>A <a href="https://beta.tinybase.org/api/the-essentials/persisting-stores/persister/"><code>Persister</code></a>'s <a href="https://beta.tinybase.org/api/persisters/interfaces/persister/persister/methods/load/load/"><code>load</code></a> method and <a href="https://beta.tinybase.org/api/persisters/interfaces/persister/persister/methods/load/startautoload/"><code>startAutoLoad</code></a> method now take a <a href="https://beta.tinybase.org/api/store/type-aliases/store/content/"><code>Content</code></a> object as one parameter, rather than <a href="https://beta.tinybase.org/api/store/type-aliases/store/tables/"><code>Tables</code></a> and <a href="https://beta.tinybase.org/api/store/type-aliases/store/values/"><code>Values</code></a> as two.</li><li>If you create a custom <a href="https://beta.tinybase.org/api/the-essentials/persisting-stores/persister/"><code>Persister</code></a>, the setPersisted method now receives changes made to a <a href="https://beta.tinybase.org/api/the-essentials/creating-stores/store/"><code>Store</code></a> directly by reference, rather than via a callback. Similarly, the <a href="https://beta.tinybase.org/api/persisters/type-aliases/creation/persisterlistener/"><code>PersisterListener</code></a> you register in your addPersisterListener implementation now takes <a href="https://beta.tinybase.org/api/store/type-aliases/store/content/"><code>Content</code></a> and <a href="https://beta.tinybase.org/api/store/type-aliases/transaction/changes/"><code>Changes</code></a> objects directly rather than via a callback.</li><li>The broadcastTransactionChanges method in the <a href="https://beta.tinybase.org/api/persister-partykit-server/"><code>persister-partykit-server</code></a> module has been renamed to the broadcastChanges method.</li></ul><hr><h1 id="v4-8">v4.8</h1><p>This release includes the new <a href="https://beta.tinybase.org/api/persister-powersync/"><code>persister-powersync</code></a> module, which provides a <a href="https://beta.tinybase.org/api/the-essentials/persisting-stores/persister/"><code>Persister</code></a> for <a href="https://www.powersync.com/">PowerSync's SQLite</a> database.</p><p>Much like the other SQLite persisters, use it by passing in a PowerSync instance to the <a href="https://beta.tinybase.org/api/persister-powersync/functions/creation/createpowersyncpersister/"><code>createPowerSyncPersister</code></a> function; something like:</p>
|
|
552
586
|
|
|
553
|
-
```js
|
|
587
|
+
```js ignore
|
|
554
588
|
const powerSync = usePowerSync();
|
|
555
589
|
|
|
556
590
|
const persister = createPowerSyncPersister(store, powerSync, {
|
|
@@ -564,7 +598,7 @@ const persister = createPowerSyncPersister(store, powerSync, {
|
|
|
564
598
|
|
|
565
599
|
<p>A huge thank you to <a href="https://bndkt.com/">Benedikt Mueller</a> (<a href="https://github.com/bndkt">@bndkt</a>) for building out this functionality! And please provide feedback on how this new <a href="https://beta.tinybase.org/api/the-essentials/persisting-stores/persister/"><code>Persister</code></a> works for you.</p><hr><h1 id="v4-7">v4.7</h1><p>This release includes the new <a href="https://beta.tinybase.org/api/persister-libsql/"><code>persister-libsql</code></a> module, which provides a <a href="https://beta.tinybase.org/api/the-essentials/persisting-stores/persister/"><code>Persister</code></a> for <a href="https://turso.tech/libsql">Turso's LibSQL</a> database.</p><p>Use the <a href="https://beta.tinybase.org/api/the-essentials/persisting-stores/persister/"><code>Persister</code></a> by passing in a reference to the LibSQL client to the createLibSQLPersister function; something like:</p>
|
|
566
600
|
|
|
567
|
-
```js
|
|
601
|
+
```js ignore
|
|
568
602
|
const client = createClient({url: 'file:my.db'});
|
|
569
603
|
|
|
570
604
|
const persister = createLibSqlPersister(store, client, {
|
|
@@ -578,7 +612,7 @@ const persister = createLibSqlPersister(store, client, {
|
|
|
578
612
|
|
|
579
613
|
<p>This is the first version of this functionality, so please provide feedback on how it works for you!</p><hr><h1 id="v4-6">v4.6</h1><p>This release includes the new <a href="https://beta.tinybase.org/api/persister-electric-sql/"><code>persister-electric-sql</code></a> module, which provides a <a href="https://beta.tinybase.org/api/the-essentials/persisting-stores/persister/"><code>Persister</code></a> for <a href="https://electric-sql.com/">ElectricSQL</a> client databases.</p><p>Use the <a href="https://beta.tinybase.org/api/the-essentials/persisting-stores/persister/"><code>Persister</code></a> by passing in a reference to the Electric client to the <a href="https://beta.tinybase.org/api/persister-electric-sql/functions/creation/createelectricsqlpersister/"><code>createElectricSqlPersister</code></a> function; something like:</p>
|
|
580
614
|
|
|
581
|
-
```js
|
|
615
|
+
```js ignore
|
|
582
616
|
const electric = await electrify(connection, schema, config);
|
|
583
617
|
|
|
584
618
|
const persister = createElectricSqlPersister(store, electric, {
|
|
@@ -592,7 +626,7 @@ const persister = createElectricSqlPersister(store, electric, {
|
|
|
592
626
|
|
|
593
627
|
<p>This release is accompanied by a <a href="https://github.com/tinyplex/tinybase-ts-react-electricsql">template project</a> to get started quickly with this integration. Enjoy!</p><hr><h1 id="v4-5">v4.5</h1><p>This release includes the new persister-expo-sqlite-next module, which provides a <a href="https://beta.tinybase.org/api/the-essentials/persisting-stores/persister/"><code>Persister</code></a> for the modern version of Expo's <a href="https://docs.expo.dev/versions/latest/sdk/sqlite">SQLite</a> library, designated 'next' as of November 2023. This API should be used if you are installing the <code>expo-sqlite/next</code> module.</p><p>Note that TinyBase support for the legacy version of Expo-SQLite (<code>expo-sqlite</code>) is still available in the <a href="https://beta.tinybase.org/api/persister-expo-sqlite/"><code>persister-expo-sqlite</code></a> module.</p><p>NB as of TinyBase v5.0, this is now the default and legacy support has been removed.</p><p>Thank you to Expo for providing this functionality!</p><hr><h1 id="v4-4">v4.4</h1><p>This relatively straightforward release adds a selection of new listeners to the <a href="https://beta.tinybase.org/api/the-essentials/creating-stores/store/"><code>Store</code></a> object, and their respective hooks. These are for listening to changes in the 'existence' of entities rather than to their value. For example, the <a href="https://beta.tinybase.org/api/store/interfaces/store/store/methods/listener/addhastablelistener/"><code>addHasTableListener</code></a> method will let you listen for the presence (or not) of a specific table.</p><p>The full set of new existence-listening methods and hooks to work with this is as follows:</p><div class="table"><table><thead><tr><th>Existence of:</th><th>Add Listener</th><th>Hook</th><th>Add Listener Hook</th></tr></thead><tbody><tr><td><a href="https://beta.tinybase.org/api/store/type-aliases/store/tables/"><code>Tables</code></a></td><td><a href="https://beta.tinybase.org/api/store/interfaces/store/store/methods/listener/addhastableslistener/"><code>addHasTablesListener</code></a></td><td><a href="https://beta.tinybase.org/api/ui-react/functions/store-hooks/usehastables/"><code>useHasTables</code></a></td><td><a href="https://beta.tinybase.org/api/ui-react/functions/store-hooks/usehastableslistener/"><code>useHasTablesListener</code></a></td></tr><tr><td>A <a href="https://beta.tinybase.org/api/store/type-aliases/store/table/"><code>Table</code></a></td><td><a href="https://beta.tinybase.org/api/store/interfaces/store/store/methods/listener/addhastablelistener/"><code>addHasTableListener</code></a></td><td><a href="https://beta.tinybase.org/api/ui-react/functions/store-hooks/usehastable/"><code>useHasTable</code></a></td><td><a href="https://beta.tinybase.org/api/ui-react/functions/store-hooks/usehastablelistener/"><code>useHasTableListener</code></a></td></tr><tr><td>A <a href="https://beta.tinybase.org/api/store/type-aliases/store/table/"><code>Table</code></a> <a href="https://beta.tinybase.org/api/store/type-aliases/store/cell/"><code>Cell</code></a></td><td><a href="https://beta.tinybase.org/api/store/interfaces/store/store/methods/listener/addhastablecelllistener/"><code>addHasTableCellListener</code></a></td><td><a href="https://beta.tinybase.org/api/ui-react/functions/store-hooks/usehastablecell/"><code>useHasTableCell</code></a></td><td><a href="https://beta.tinybase.org/api/ui-react/functions/store-hooks/usehastablecelllistener/"><code>useHasTableCellListener</code></a></td></tr><tr><td>A <a href="https://beta.tinybase.org/api/store/type-aliases/store/row/"><code>Row</code></a></td><td><a href="https://beta.tinybase.org/api/store/interfaces/store/store/methods/listener/addhasrowlistener/"><code>addHasRowListener</code></a></td><td><a href="https://beta.tinybase.org/api/ui-react/functions/store-hooks/usehasrow/"><code>useHasRow</code></a></td><td><a href="https://beta.tinybase.org/api/ui-react/functions/store-hooks/usehasrowlistener/"><code>useHasRowListener</code></a></td></tr><tr><td>A <a href="https://beta.tinybase.org/api/store/type-aliases/store/cell/"><code>Cell</code></a></td><td><a href="https://beta.tinybase.org/api/store/interfaces/store/store/methods/listener/addhascelllistener/"><code>addHasCellListener</code></a></td><td><a href="https://beta.tinybase.org/api/ui-react/functions/store-hooks/usehascell/"><code>useHasCell</code></a></td><td><a href="https://beta.tinybase.org/api/ui-react/functions/store-hooks/usehascelllistener/"><code>useHasCellListener</code></a></td></tr><tr><td><a href="https://beta.tinybase.org/api/store/type-aliases/store/values/"><code>Values</code></a></td><td><a href="https://beta.tinybase.org/api/store/interfaces/store/store/methods/listener/addhasvalueslistener/"><code>addHasValuesListener</code></a></td><td><a href="https://beta.tinybase.org/api/ui-react/functions/store-hooks/usehasvalues/"><code>useHasValues</code></a></td><td><a href="https://beta.tinybase.org/api/ui-react/functions/store-hooks/usehasvalueslistener/"><code>useHasValuesListener</code></a></td></tr><tr><td>A <a href="https://beta.tinybase.org/api/store/type-aliases/store/value/"><code>Value</code></a></td><td><a href="https://beta.tinybase.org/api/store/interfaces/store/store/methods/listener/addhasvaluelistener/"><code>addHasValueListener</code></a></td><td><a href="https://beta.tinybase.org/api/ui-react/functions/store-hooks/usehasvalue/"><code>useHasValue</code></a></td><td><a href="https://beta.tinybase.org/api/ui-react/functions/store-hooks/usehasvaluelistener/"><code>useHasValueListener</code></a></td></tr></tbody></table></div><p>These methods may become particularly important in future versions of TinyBase that support <code>null</code> as valid Cells and <a href="https://beta.tinybase.org/api/store/type-aliases/store/values/"><code>Values</code></a>.</p><hr><h1 id="v4-3">v4.3</h1><p>We're excited to announce TinyBase 4.3, which provides an integration with <a href="https://www.partykit.io/">PartyKit</a>, a cloud-based collaboration provider.</p><p>This allows you to enjoy the benefits of both a "local-first" architecture and a "sharing-first" platform. You can have structured data on the client with fast, reactive user experiences, but also benefit from cloud-based persistence and room-based collaboration.</p><p><img src="https://beta.tinybase.org/partykit.gif" alt="PartyKit" title="PartyKit"></p><p>This release includes two new modules:</p><ul><li>The <a href="https://beta.tinybase.org/api/persister-partykit-server/"><code>persister-partykit-server</code></a> module provides a server class for coordinating clients and persisting <a href="https://beta.tinybase.org/api/the-essentials/creating-stores/store/"><code>Store</code></a> data to the PartyKit cloud.</li><li>The <a href="https://beta.tinybase.org/api/persister-partykit-client/"><code>persister-partykit-client</code></a> module provides the API to create connections to the server and a binding to your <a href="https://beta.tinybase.org/api/the-essentials/creating-stores/store/"><code>Store</code></a>.</li></ul><p>A TinyBase server implementation on PartyKit can be as simple as this:</p>
|
|
594
628
|
|
|
595
|
-
```js
|
|
629
|
+
```js ignore
|
|
596
630
|
import {TinyBasePartyKitServer} from 'tinybase/persisters/persister-partykit-server';
|
|
597
631
|
|
|
598
632
|
export default class extends TinyBasePartyKitServer {}
|
|
@@ -600,7 +634,7 @@ export default class extends TinyBasePartyKitServer {}
|
|
|
600
634
|
|
|
601
635
|
<p>On the client, use the familiar <a href="https://beta.tinybase.org/api/the-essentials/persisting-stores/persister/"><code>Persister</code></a> API, passing in a reference to a PartyKit socket object that's been configured to connect to your server deployment and named room:</p>
|
|
602
636
|
|
|
603
|
-
```js
|
|
637
|
+
```js ignore
|
|
604
638
|
import {createPartyKitPersister} from 'tinybase/persisters/persister-partykit-client';
|
|
605
639
|
|
|
606
640
|
const persister = createPartyKitPersister(
|
|
@@ -821,7 +855,7 @@ store.delTables();
|
|
|
821
855
|
|
|
822
856
|
<p>This release also fixes a bug where using the explicit <a href="https://beta.tinybase.org/api/store/interfaces/store/store/methods/transaction/starttransaction/"><code>startTransaction</code></a> method <em>inside</em> another listener could create infinite recursion.</p><hr><h1 id="v3-1">v3.1</h1><p>This new release adds a powerful schema-based type system to TinyBase.</p><p>If you define the shape and structure of your data with a <a href="https://beta.tinybase.org/api/store/type-aliases/schema/tablesschema/"><code>TablesSchema</code></a> or <a href="https://beta.tinybase.org/api/store/type-aliases/schema/valuesschema/"><code>ValuesSchema</code></a>, you can benefit from an enhanced developer experience when operating on it. For example:</p>
|
|
823
857
|
|
|
824
|
-
```ts
|
|
858
|
+
```ts ignore
|
|
825
859
|
// Import the 'with-schemas' definition:
|
|
826
860
|
import {createStore} from 'tinybase/with-schemas';
|
|
827
861
|
|
|
@@ -859,7 +893,7 @@ store.delListener(listenerId).delValues();
|
|
|
859
893
|
|
|
860
894
|
<p><a href="https://beta.tinybase.org/guides/">Guides</a> and documentation have been fully updated, and certain demos - such as the <a href="https://beta.tinybase.org/demos/todo-app/todo-app-v2-indexes/">Todo App v2 (indexes)</a> demo, and the <a href="https://beta.tinybase.org/demos/countries/">Countries</a> demo - have been updated to use this new functionality.</p><p>If you use the optional <a href="https://beta.tinybase.org/api/ui-react/"><code>ui-react</code></a> module with TinyBase, v3.0 now uses and expects React v18.</p><p>In terms of core API changes in v3.0, there are some minor breaking changes (see below), but the majority of the alterations are additions.</p><p>The <a href="https://beta.tinybase.org/api/the-essentials/creating-stores/store/"><code>Store</code></a> object gains the following:</p><ul><li>The <a href="https://beta.tinybase.org/api/store/interfaces/store/store/methods/setter/setvalues/"><code>setValues</code></a> method, <a href="https://beta.tinybase.org/api/store/interfaces/store/store/methods/setter/setpartialvalues/"><code>setPartialValues</code></a> method, and <a href="https://beta.tinybase.org/api/the-essentials/setting-data/setvalue/"><code>setValue</code></a> method, to set keyed value data into the <a href="https://beta.tinybase.org/api/the-essentials/creating-stores/store/"><code>Store</code></a>.</li><li>The <a href="https://beta.tinybase.org/api/store/interfaces/store/store/methods/getter/getvalues/"><code>getValues</code></a> method, <a href="https://beta.tinybase.org/api/store/interfaces/store/store/methods/getter/getvalueids/"><code>getValueIds</code></a> method, and <a href="https://beta.tinybase.org/api/the-essentials/getting-data/getvalue/"><code>getValue</code></a> method, to get keyed value data out of the <a href="https://beta.tinybase.org/api/the-essentials/creating-stores/store/"><code>Store</code></a>.</li><li>The <a href="https://beta.tinybase.org/api/store/interfaces/store/store/methods/deleter/delvalues/"><code>delValues</code></a> method and <a href="https://beta.tinybase.org/api/store/interfaces/store/store/methods/deleter/delvalue/"><code>delValue</code></a> method for removing keyed value data.</li><li>The <a href="https://beta.tinybase.org/api/store/interfaces/store/store/methods/listener/addvalueslistener/"><code>addValuesListener</code></a> method, <a href="https://beta.tinybase.org/api/store/interfaces/store/store/methods/listener/addvalueidslistener/"><code>addValueIdsListener</code></a> method, addValueListener method, and <a href="https://beta.tinybase.org/api/store/interfaces/store/store/methods/listener/addinvalidvaluelistener/"><code>addInvalidValueListener</code></a> method, for listening to changes to keyed value data.</li><li>The <a href="https://beta.tinybase.org/api/store/interfaces/store/store/methods/getter/hasvalues/"><code>hasValues</code></a> method, <a href="https://beta.tinybase.org/api/store/interfaces/store/store/methods/getter/hasvalue/"><code>hasValue</code></a> method, and <a href="https://beta.tinybase.org/api/store/interfaces/store/store/methods/iterator/foreachvalue/"><code>forEachValue</code></a> method, for existence and enumeration purposes.</li><li>The <a href="https://beta.tinybase.org/api/store/interfaces/store/store/methods/getter/gettablesjson/"><code>getTablesJson</code></a> method, <a href="https://beta.tinybase.org/api/store/interfaces/store/store/methods/getter/getvaluesjson/"><code>getValuesJson</code></a> method, <a href="https://beta.tinybase.org/api/store/interfaces/store/store/methods/setter/settablesjson/"><code>setTablesJson</code></a> method, and <a href="https://beta.tinybase.org/api/store/interfaces/store/store/methods/setter/setvaluesjson/"><code>setValuesJson</code></a> method, for reading and writing tabular and keyed value data to and from a JSON string. Also see below.</li><li>The <a href="https://beta.tinybase.org/api/store/interfaces/store/store/methods/getter/gettablesschemajson/"><code>getTablesSchemaJson</code></a> method, <a href="https://beta.tinybase.org/api/store/interfaces/store/store/methods/getter/getvaluesschemajson/"><code>getValuesSchemaJson</code></a> method, setTablesSchema method, <a href="https://beta.tinybase.org/api/store/interfaces/store/store/methods/setter/setvaluesschema/"><code>setValuesSchema</code></a> method, <a href="https://beta.tinybase.org/api/store/interfaces/store/store/methods/deleter/deltablesschema/"><code>delTablesSchema</code></a> method, and delValuesSchema method, for reading and writing tabular and keyed value schemas for the <a href="https://beta.tinybase.org/api/the-essentials/creating-stores/store/"><code>Store</code></a>. Also see below.</li></ul><p>The following types have been added to the <a href="https://beta.tinybase.org/api/store/"><code>store</code></a> module:</p><ul><li><a href="https://beta.tinybase.org/api/store/type-aliases/store/values/"><code>Values</code></a>, <a href="https://beta.tinybase.org/api/store/type-aliases/store/value/"><code>Value</code></a>, and <a href="https://beta.tinybase.org/api/store/type-aliases/store/valueorundefined/"><code>ValueOrUndefined</code></a>, representing keyed value data in a <a href="https://beta.tinybase.org/api/the-essentials/creating-stores/store/"><code>Store</code></a>.</li><li><a href="https://beta.tinybase.org/api/store/type-aliases/listener/valuelistener/"><code>ValueListener</code></a> and <a href="https://beta.tinybase.org/api/store/type-aliases/listener/invalidvaluelistener/"><code>InvalidValueListener</code></a>, to describe functions used to listen to (valid or invalid) changes to a <a href="https://beta.tinybase.org/api/store/type-aliases/store/value/"><code>Value</code></a>.</li><li><a href="https://beta.tinybase.org/api/store/type-aliases/schema/valuesschema/"><code>ValuesSchema</code></a> and <a href="https://beta.tinybase.org/api/store/type-aliases/schema/valueschema/"><code>ValueSchema</code></a>, to describe the keyed <a href="https://beta.tinybase.org/api/store/type-aliases/store/values/"><code>Values</code></a> that can be set in a <a href="https://beta.tinybase.org/api/the-essentials/creating-stores/store/"><code>Store</code></a> and their types.</li><li><a href="https://beta.tinybase.org/api/store/type-aliases/callback/valuecallback/"><code>ValueCallback</code></a>, <a href="https://beta.tinybase.org/api/store/type-aliases/callback/mapvalue/"><code>MapValue</code></a>, <a href="https://beta.tinybase.org/api/store/type-aliases/transaction/changedvalues/"><code>ChangedValues</code></a>, and <a href="https://beta.tinybase.org/api/store/type-aliases/transaction/invalidvalues/"><code>InvalidValues</code></a>, which also correspond to their '<a href="https://beta.tinybase.org/api/store/type-aliases/store/cell/"><code>Cell</code></a>' equivalents.</li></ul><p>Additionally:</p><ul><li>The persisters' <a href="https://beta.tinybase.org/api/persisters/interfaces/persister/persister/methods/load/load/"><code>load</code></a> method and <a href="https://beta.tinybase.org/api/persisters/interfaces/persister/persister/methods/load/startautoload/"><code>startAutoLoad</code></a> method take an optional <code>initialValues</code> parameter for setting <a href="https://beta.tinybase.org/api/store/type-aliases/store/values/"><code>Values</code></a> when a persisted <a href="https://beta.tinybase.org/api/the-essentials/creating-stores/store/"><code>Store</code></a> is bootstrapped.</li><li>The <a href="https://beta.tinybase.org/api/checkpoints/interfaces/checkpoints/checkpoints/"><code>Checkpoints</code></a> module will undo and redo changes to keyed values in the same way they do for tabular data.</li><li>The tools module provides a getStoreValuesSchema method for inferring value-based schemas. The getStoreApi method and getPrettyStoreApi method now also provides an ORM-like code-generated API for schematized key values.</li></ul><p>All attempts have been made to provide backwards compatibility and/or easy upgrade paths.</p><p>In previous versions, <a href="https://beta.tinybase.org/api/store/interfaces/store/store/methods/getter/getjson/"><code>getJson</code></a> method would get a JSON serialization of the <a href="https://beta.tinybase.org/api/the-essentials/creating-stores/store/"><code>Store</code></a>'s tabular data. That functionality is now provided by the <a href="https://beta.tinybase.org/api/store/interfaces/store/store/methods/getter/gettablesjson/"><code>getTablesJson</code></a> method, and the <a href="https://beta.tinybase.org/api/store/interfaces/store/store/methods/getter/getjson/"><code>getJson</code></a> method instead now returns a two-part array containing the tabular data and the keyed value data.</p><p>Similarly, the <a href="https://beta.tinybase.org/api/store/interfaces/store/store/methods/getter/getschemajson/"><code>getSchemaJson</code></a> method used to return the tabular schema, now provided by the <a href="https://beta.tinybase.org/api/store/interfaces/store/store/methods/getter/gettablesschemajson/"><code>getTablesSchemaJson</code></a> method. The <a href="https://beta.tinybase.org/api/store/interfaces/store/store/methods/getter/getschemajson/"><code>getSchemaJson</code></a> method instead now returns a two-part array of tabular schema and the keyed value schema.</p><p>The <a href="https://beta.tinybase.org/api/store/interfaces/store/store/methods/setter/setjson/"><code>setJson</code></a> method used to take a serialization of just the tabular data object. That's now provided by the <a href="https://beta.tinybase.org/api/store/interfaces/store/store/methods/setter/settablesjson/"><code>setTablesJson</code></a> method, and the <a href="https://beta.tinybase.org/api/store/interfaces/store/store/methods/setter/setjson/"><code>setJson</code></a> method instead expects a two-part array containing the tabular data and the keyed value data (as emitted by the <a href="https://beta.tinybase.org/api/store/interfaces/store/store/methods/getter/getjson/"><code>getJson</code></a> method). However, for backwards compatibility, if the <a href="https://beta.tinybase.org/api/store/interfaces/store/store/methods/setter/setjson/"><code>setJson</code></a> method is passed an object, it <em>will</em> set the tabular data, as it did prior to v3.0.</p><p>Along similar lines, the <a href="https://beta.tinybase.org/api/store/interfaces/store/store/methods/setter/setschema/"><code>setSchema</code></a> method's previous behavior is now provided by the <a href="https://beta.tinybase.org/api/store/interfaces/store/store/methods/setter/settablesschema/"><code>setTablesSchema</code></a> method. The <a href="https://beta.tinybase.org/api/store/interfaces/store/store/methods/setter/setschema/"><code>setSchema</code></a> method now takes two arguments, the second of which is optional, also aiding backward compatibility. The <a href="https://beta.tinybase.org/api/store/interfaces/store/store/methods/deleter/delschema/"><code>delSchema</code></a> method removes both types of schema.</p><hr><h1 id="v2-2">v2.2</h1><p>Note: The tools module has been removed in TinyBase v6.0.</p><p>This release includes a new tools module. These tools are not intended for production use, but are instead to be used as part of your engineering workflow to perform tasks like generating APIs from schemas, or schemas from data. For example:</p>
|
|
861
895
|
|
|
862
|
-
```js
|
|
896
|
+
```js ignore
|
|
863
897
|
import {createTools} from 'tinybase/tools';
|
|
864
898
|
|
|
865
899
|
store.setTable('pets', {
|
|
@@ -874,7 +908,7 @@ const [dTs, ts] = tools.getStoreApi('shop');
|
|
|
874
908
|
|
|
875
909
|
<p>This will generate two files:</p>
|
|
876
910
|
|
|
877
|
-
```js
|
|
911
|
+
```js ignore
|
|
878
912
|
// -- shop.d.ts --
|
|
879
913
|
/* Represents the 'pets' Table. */
|
|
880
914
|
export type PetsTable = {[rowId: Id]: PetsRow};
|
package/ui-svelte/index.js
CHANGED
|
@@ -59,7 +59,7 @@ const objGet = (obj, id) => ifNotUndefined(obj, (obj2) => obj2[id]);
|
|
|
59
59
|
|
|
60
60
|
const TINYBASE_CONTEXT_KEY = TINYBASE + '_uisc';
|
|
61
61
|
|
|
62
|
-
/* functions.svelte.ts generated by Svelte v5.55.
|
|
62
|
+
/* functions.svelte.ts generated by Svelte v5.55.4 */
|
|
63
63
|
|
|
64
64
|
class ReactiveHandle {
|
|
65
65
|
#get;
|
|
@@ -59,7 +59,7 @@ const objGet = (obj, id) => ifNotUndefined(obj, (obj2) => obj2[id]);
|
|
|
59
59
|
|
|
60
60
|
const TINYBASE_CONTEXT_KEY = TINYBASE + '_uisc';
|
|
61
61
|
|
|
62
|
-
/* functions.svelte.ts generated by Svelte v5.55.
|
|
62
|
+
/* functions.svelte.ts generated by Svelte v5.55.4 */
|
|
63
63
|
|
|
64
64
|
class ReactiveHandle {
|
|
65
65
|
#get;
|
package/ui-svelte-dom/index.js
CHANGED
|
@@ -88,7 +88,7 @@ const objMap = (obj, cb) =>
|
|
|
88
88
|
|
|
89
89
|
const TINYBASE_CONTEXT_KEY = TINYBASE + '_uisc';
|
|
90
90
|
|
|
91
|
-
/* functions.svelte.ts generated by Svelte v5.55.
|
|
91
|
+
/* functions.svelte.ts generated by Svelte v5.55.4 */
|
|
92
92
|
|
|
93
93
|
class ReactiveHandle {
|
|
94
94
|
#get;
|
|
@@ -443,7 +443,7 @@ var root_3$3 = $.from_html(`<input type="number"/>`);
|
|
|
443
443
|
var root_4$4 = $.from_html(`<input type="checkbox"/>`);
|
|
444
444
|
var root_5$3 = $.from_html(`<input/>`);
|
|
445
445
|
var root_6$2 = $.from_html(`<input/>`);
|
|
446
|
-
var root$5 = $.from_html(`<div
|
|
446
|
+
var root$5 = $.from_html(`<div><!><!></div>`);
|
|
447
447
|
|
|
448
448
|
function EditableThing($$anchor, $$props) {
|
|
449
449
|
$.push($$props, true);
|
|
@@ -562,7 +562,7 @@ function EditableThing($$anchor, $$props) {
|
|
|
562
562
|
});
|
|
563
563
|
}
|
|
564
564
|
|
|
565
|
-
var node_1 = $.sibling(node
|
|
565
|
+
var node_1 = $.sibling(node);
|
|
566
566
|
|
|
567
567
|
{
|
|
568
568
|
var consequent_1 = ($$anchor) => {
|
|
@@ -1621,7 +1621,7 @@ function HtmlTable($$anchor, $$props) {
|
|
|
1621
1621
|
$.delegate(['click']);
|
|
1622
1622
|
|
|
1623
1623
|
var root_1$1 = $.from_html(
|
|
1624
|
-
`<button class="previous"></button
|
|
1624
|
+
`<button class="previous"></button><button class="next"></button> `,
|
|
1625
1625
|
1,
|
|
1626
1626
|
);
|
|
1627
1627
|
var root$1 = $.from_html(`<!> `, 1);
|
|
@@ -1639,6 +1639,14 @@ function SortedTablePaginator($$anchor, $$props) {
|
|
|
1639
1639
|
const limit = $.derived(() => $$props.limit ?? $$props.total);
|
|
1640
1640
|
const singular = $.derived(() => $$props.singular ?? 'row');
|
|
1641
1641
|
const plural = $.derived(() => $$props.plural ?? $.get(singular) + 's');
|
|
1642
|
+
const rangeLabel = $.derived(
|
|
1643
|
+
() =>
|
|
1644
|
+
`${$.get(offset) + 1} to ${mathMin($$props.total, $.get(offset) + $.get(limit))} of `,
|
|
1645
|
+
);
|
|
1646
|
+
const totalLabel = $.derived(
|
|
1647
|
+
() =>
|
|
1648
|
+
`${$$props.total} ${$$props.total != 1 ? $.get(plural) : $.get(singular)}`,
|
|
1649
|
+
);
|
|
1642
1650
|
|
|
1643
1651
|
$.user_effect(() => {
|
|
1644
1652
|
if (($$props.offset ?? 0) > $$props.total || ($$props.offset ?? 0) < 0) {
|
|
@@ -1656,20 +1664,17 @@ function SortedTablePaginator($$anchor, $$props) {
|
|
|
1656
1664
|
|
|
1657
1665
|
button.textContent = '←';
|
|
1658
1666
|
|
|
1659
|
-
var button_1 = $.sibling(button
|
|
1667
|
+
var button_1 = $.sibling(button);
|
|
1660
1668
|
|
|
1661
1669
|
button_1.textContent = '→';
|
|
1662
1670
|
|
|
1663
|
-
var text = $.sibling(button_1);
|
|
1671
|
+
var text = $.sibling(button_1, 1, true);
|
|
1664
1672
|
|
|
1665
|
-
$.template_effect(
|
|
1666
|
-
(
|
|
1667
|
-
|
|
1668
|
-
|
|
1669
|
-
|
|
1670
|
-
},
|
|
1671
|
-
[() => mathMin($$props.total, $.get(offset) + $.get(limit))],
|
|
1672
|
-
);
|
|
1673
|
+
$.template_effect(() => {
|
|
1674
|
+
button.disabled = $.get(offset) == 0;
|
|
1675
|
+
button_1.disabled = $.get(offset) + $.get(limit) >= $$props.total;
|
|
1676
|
+
$.set_text(text, $.get(rangeLabel));
|
|
1677
|
+
});
|
|
1673
1678
|
|
|
1674
1679
|
$.delegated('click', button, () =>
|
|
1675
1680
|
$$props.onChange($.get(offset) - $.get(limit)),
|
|
@@ -1685,23 +1690,16 @@ function SortedTablePaginator($$anchor, $$props) {
|
|
|
1685
1690
|
});
|
|
1686
1691
|
}
|
|
1687
1692
|
|
|
1688
|
-
var text_1 = $.sibling(node);
|
|
1689
|
-
|
|
1690
|
-
$.template_effect(() =>
|
|
1691
|
-
$.set_text(
|
|
1692
|
-
text_1,
|
|
1693
|
-
` ${$$props.total ?? ''}
|
|
1694
|
-
${($$props.total != 1 ? $.get(plural) : $.get(singular)) ?? ''}`,
|
|
1695
|
-
),
|
|
1696
|
-
);
|
|
1693
|
+
var text_1 = $.sibling(node, 1, true);
|
|
1697
1694
|
|
|
1695
|
+
$.template_effect(() => $.set_text(text_1, $.get(totalLabel)));
|
|
1698
1696
|
$.append($$anchor, fragment);
|
|
1699
1697
|
$.pop();
|
|
1700
1698
|
}
|
|
1701
1699
|
|
|
1702
1700
|
$.delegate(['click']);
|
|
1703
1701
|
|
|
1704
|
-
/* sortingAndPagination.svelte.ts generated by Svelte v5.55.
|
|
1702
|
+
/* sortingAndPagination.svelte.ts generated by Svelte v5.55.4 */
|
|
1705
1703
|
|
|
1706
1704
|
const createSortingAndPagination = (
|
|
1707
1705
|
getCellId,
|
|
@@ -88,7 +88,7 @@ const objMap = (obj, cb) =>
|
|
|
88
88
|
|
|
89
89
|
const TINYBASE_CONTEXT_KEY = TINYBASE + '_uisc';
|
|
90
90
|
|
|
91
|
-
/* functions.svelte.ts generated by Svelte v5.55.
|
|
91
|
+
/* functions.svelte.ts generated by Svelte v5.55.4 */
|
|
92
92
|
|
|
93
93
|
class ReactiveHandle {
|
|
94
94
|
#get;
|
|
@@ -443,7 +443,7 @@ var root_3$3 = $.from_html(`<input type="number"/>`);
|
|
|
443
443
|
var root_4$4 = $.from_html(`<input type="checkbox"/>`);
|
|
444
444
|
var root_5$3 = $.from_html(`<input/>`);
|
|
445
445
|
var root_6$2 = $.from_html(`<input/>`);
|
|
446
|
-
var root$5 = $.from_html(`<div
|
|
446
|
+
var root$5 = $.from_html(`<div><!><!></div>`);
|
|
447
447
|
|
|
448
448
|
function EditableThing($$anchor, $$props) {
|
|
449
449
|
$.push($$props, true);
|
|
@@ -562,7 +562,7 @@ function EditableThing($$anchor, $$props) {
|
|
|
562
562
|
});
|
|
563
563
|
}
|
|
564
564
|
|
|
565
|
-
var node_1 = $.sibling(node
|
|
565
|
+
var node_1 = $.sibling(node);
|
|
566
566
|
|
|
567
567
|
{
|
|
568
568
|
var consequent_1 = ($$anchor) => {
|
|
@@ -1621,7 +1621,7 @@ function HtmlTable($$anchor, $$props) {
|
|
|
1621
1621
|
$.delegate(['click']);
|
|
1622
1622
|
|
|
1623
1623
|
var root_1$1 = $.from_html(
|
|
1624
|
-
`<button class="previous"></button
|
|
1624
|
+
`<button class="previous"></button><button class="next"></button> `,
|
|
1625
1625
|
1,
|
|
1626
1626
|
);
|
|
1627
1627
|
var root$1 = $.from_html(`<!> `, 1);
|
|
@@ -1639,6 +1639,14 @@ function SortedTablePaginator($$anchor, $$props) {
|
|
|
1639
1639
|
const limit = $.derived(() => $$props.limit ?? $$props.total);
|
|
1640
1640
|
const singular = $.derived(() => $$props.singular ?? 'row');
|
|
1641
1641
|
const plural = $.derived(() => $$props.plural ?? $.get(singular) + 's');
|
|
1642
|
+
const rangeLabel = $.derived(
|
|
1643
|
+
() =>
|
|
1644
|
+
`${$.get(offset) + 1} to ${mathMin($$props.total, $.get(offset) + $.get(limit))} of `,
|
|
1645
|
+
);
|
|
1646
|
+
const totalLabel = $.derived(
|
|
1647
|
+
() =>
|
|
1648
|
+
`${$$props.total} ${$$props.total != 1 ? $.get(plural) : $.get(singular)}`,
|
|
1649
|
+
);
|
|
1642
1650
|
|
|
1643
1651
|
$.user_effect(() => {
|
|
1644
1652
|
if (($$props.offset ?? 0) > $$props.total || ($$props.offset ?? 0) < 0) {
|
|
@@ -1656,20 +1664,17 @@ function SortedTablePaginator($$anchor, $$props) {
|
|
|
1656
1664
|
|
|
1657
1665
|
button.textContent = '←';
|
|
1658
1666
|
|
|
1659
|
-
var button_1 = $.sibling(button
|
|
1667
|
+
var button_1 = $.sibling(button);
|
|
1660
1668
|
|
|
1661
1669
|
button_1.textContent = '→';
|
|
1662
1670
|
|
|
1663
|
-
var text = $.sibling(button_1);
|
|
1671
|
+
var text = $.sibling(button_1, 1, true);
|
|
1664
1672
|
|
|
1665
|
-
$.template_effect(
|
|
1666
|
-
(
|
|
1667
|
-
|
|
1668
|
-
|
|
1669
|
-
|
|
1670
|
-
},
|
|
1671
|
-
[() => mathMin($$props.total, $.get(offset) + $.get(limit))],
|
|
1672
|
-
);
|
|
1673
|
+
$.template_effect(() => {
|
|
1674
|
+
button.disabled = $.get(offset) == 0;
|
|
1675
|
+
button_1.disabled = $.get(offset) + $.get(limit) >= $$props.total;
|
|
1676
|
+
$.set_text(text, $.get(rangeLabel));
|
|
1677
|
+
});
|
|
1673
1678
|
|
|
1674
1679
|
$.delegated('click', button, () =>
|
|
1675
1680
|
$$props.onChange($.get(offset) - $.get(limit)),
|
|
@@ -1685,23 +1690,16 @@ function SortedTablePaginator($$anchor, $$props) {
|
|
|
1685
1690
|
});
|
|
1686
1691
|
}
|
|
1687
1692
|
|
|
1688
|
-
var text_1 = $.sibling(node);
|
|
1689
|
-
|
|
1690
|
-
$.template_effect(() =>
|
|
1691
|
-
$.set_text(
|
|
1692
|
-
text_1,
|
|
1693
|
-
` ${$$props.total ?? ''}
|
|
1694
|
-
${($$props.total != 1 ? $.get(plural) : $.get(singular)) ?? ''}`,
|
|
1695
|
-
),
|
|
1696
|
-
);
|
|
1693
|
+
var text_1 = $.sibling(node, 1, true);
|
|
1697
1694
|
|
|
1695
|
+
$.template_effect(() => $.set_text(text_1, $.get(totalLabel)));
|
|
1698
1696
|
$.append($$anchor, fragment);
|
|
1699
1697
|
$.pop();
|
|
1700
1698
|
}
|
|
1701
1699
|
|
|
1702
1700
|
$.delegate(['click']);
|
|
1703
1701
|
|
|
1704
|
-
/* sortingAndPagination.svelte.ts generated by Svelte v5.55.
|
|
1702
|
+
/* sortingAndPagination.svelte.ts generated by Svelte v5.55.4 */
|
|
1705
1703
|
|
|
1706
1704
|
const createSortingAndPagination = (
|
|
1707
1705
|
getCellId,
|