tinybase 6.2.0-beta.3 → 6.2.0

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.
Files changed (76) hide show
  1. package/@types/common/index.d.ts +295 -0
  2. package/@types/common/with-schemas/index.d.ts +375 -0
  3. package/@types/mergeable-store/index.d.ts +5 -34
  4. package/@types/mergeable-store/with-schemas/index.d.ts +5 -34
  5. package/@types/omni/with-schemas/index.d.ts +3 -3
  6. package/common/index.js +62 -3
  7. package/common/with-schemas/index.js +62 -3
  8. package/index.js +133 -86
  9. package/mergeable-store/index.js +102 -94
  10. package/mergeable-store/with-schemas/index.js +102 -94
  11. package/min/common/index.js +1 -1
  12. package/min/common/index.js.gz +0 -0
  13. package/min/common/with-schemas/index.js +1 -1
  14. package/min/common/with-schemas/index.js.gz +0 -0
  15. package/min/index.js +1 -1
  16. package/min/index.js.gz +0 -0
  17. package/min/mergeable-store/index.js +1 -1
  18. package/min/mergeable-store/index.js.gz +0 -0
  19. package/min/mergeable-store/with-schemas/index.js +1 -1
  20. package/min/mergeable-store/with-schemas/index.js.gz +0 -0
  21. package/min/omni/index.js +1 -1
  22. package/min/omni/index.js.gz +0 -0
  23. package/min/omni/with-schemas/index.js +1 -1
  24. package/min/omni/with-schemas/index.js.gz +0 -0
  25. package/min/persisters/index.js +1 -1
  26. package/min/persisters/index.js.gz +0 -0
  27. package/min/persisters/persister-pglite/index.js +1 -1
  28. package/min/persisters/persister-pglite/index.js.gz +0 -0
  29. package/min/persisters/persister-pglite/with-schemas/index.js +1 -1
  30. package/min/persisters/persister-pglite/with-schemas/index.js.gz +0 -0
  31. package/min/persisters/persister-postgres/index.js +1 -1
  32. package/min/persisters/persister-postgres/index.js.gz +0 -0
  33. package/min/persisters/persister-postgres/with-schemas/index.js +1 -1
  34. package/min/persisters/persister-postgres/with-schemas/index.js.gz +0 -0
  35. package/min/persisters/with-schemas/index.js +1 -1
  36. package/min/persisters/with-schemas/index.js.gz +0 -0
  37. package/min/store/index.js +1 -1
  38. package/min/store/index.js.gz +0 -0
  39. package/min/store/with-schemas/index.js +1 -1
  40. package/min/store/with-schemas/index.js.gz +0 -0
  41. package/min/ui-react-inspector/index.js +1 -1
  42. package/min/ui-react-inspector/index.js.gz +0 -0
  43. package/min/ui-react-inspector/with-schemas/index.js +1 -1
  44. package/min/ui-react-inspector/with-schemas/index.js.gz +0 -0
  45. package/min/with-schemas/index.js +1 -1
  46. package/min/with-schemas/index.js.gz +0 -0
  47. package/omni/index.js +148 -101
  48. package/omni/with-schemas/index.js +148 -101
  49. package/package.json +3 -3
  50. package/persisters/index.js +9 -9
  51. package/persisters/persister-durable-object-storage/index.js +12 -12
  52. package/persisters/persister-durable-object-storage/with-schemas/index.js +12 -12
  53. package/persisters/persister-pglite/index.js +11 -11
  54. package/persisters/persister-pglite/with-schemas/index.js +11 -11
  55. package/persisters/persister-postgres/index.js +11 -11
  56. package/persisters/persister-postgres/with-schemas/index.js +11 -11
  57. package/persisters/with-schemas/index.js +9 -9
  58. package/readme.md +2 -2
  59. package/releases.md +9 -10
  60. package/store/index.js +4 -4
  61. package/store/with-schemas/index.js +4 -4
  62. package/synchronizers/index.js +7 -7
  63. package/synchronizers/synchronizer-broadcast-channel/index.js +7 -7
  64. package/synchronizers/synchronizer-broadcast-channel/with-schemas/index.js +7 -7
  65. package/synchronizers/synchronizer-local/index.js +7 -7
  66. package/synchronizers/synchronizer-local/with-schemas/index.js +7 -7
  67. package/synchronizers/synchronizer-ws-client/index.js +7 -7
  68. package/synchronizers/synchronizer-ws-client/with-schemas/index.js +7 -7
  69. package/synchronizers/synchronizer-ws-server/index.js +7 -7
  70. package/synchronizers/synchronizer-ws-server/with-schemas/index.js +7 -7
  71. package/synchronizers/synchronizer-ws-server-durable-object/index.js +7 -7
  72. package/synchronizers/synchronizer-ws-server-durable-object/with-schemas/index.js +7 -7
  73. package/synchronizers/with-schemas/index.js +7 -7
  74. package/ui-react-inspector/index.js +1 -1
  75. package/ui-react-inspector/with-schemas/index.js +1 -1
  76. package/with-schemas/index.js +133 -86
@@ -53,17 +53,6 @@ const collClear = (coll) => coll.clear();
53
53
  const collForEach = (coll, cb) => coll?.forEach(cb);
54
54
  const collDel = (coll, keyOrValue) => coll?.delete(keyOrValue);
55
55
 
56
- const textEncoder = /* @__PURE__ */ new GLOBAL.TextEncoder();
57
- const getHash = (value) => {
58
- let hash = 2166136261;
59
- arrayForEach(textEncoder.encode(value), (char) => {
60
- hash ^= char;
61
- hash +=
62
- (hash << 1) + (hash << 4) + (hash << 7) + (hash << 8) + (hash << 24);
63
- });
64
- return hash >>> 0;
65
- };
66
-
67
56
  const object = Object;
68
57
  const getPrototypeOf = (obj) => object.getPrototypeOf(obj);
69
58
  const objEntries = object.entries;
@@ -102,6 +91,17 @@ const jsonStringWithUndefined = (obj) =>
102
91
  const jsonParseWithUndefined = (str) =>
103
92
  jsonParse(str, (_key, value) => (value === UNDEFINED ? void 0 : value));
104
93
 
94
+ const textEncoder = /* @__PURE__ */ new GLOBAL.TextEncoder();
95
+ const getHash = (string) => {
96
+ let hash = 2166136261;
97
+ arrayForEach(textEncoder.encode(string), (char) => {
98
+ hash ^= char;
99
+ hash +=
100
+ (hash << 1) + (hash << 4) + (hash << 7) + (hash << 8) + (hash << 24);
101
+ });
102
+ return hash >>> 0;
103
+ };
104
+
105
105
  const mapNew = (entries) => new Map(entries);
106
106
  const mapGet = (map, key) => map?.get(key);
107
107
  const mapForEach = (map, cb) =>
@@ -53,17 +53,6 @@ const collClear = (coll) => coll.clear();
53
53
  const collForEach = (coll, cb) => coll?.forEach(cb);
54
54
  const collDel = (coll, keyOrValue) => coll?.delete(keyOrValue);
55
55
 
56
- const textEncoder = /* @__PURE__ */ new GLOBAL.TextEncoder();
57
- const getHash = (value) => {
58
- let hash = 2166136261;
59
- arrayForEach(textEncoder.encode(value), (char) => {
60
- hash ^= char;
61
- hash +=
62
- (hash << 1) + (hash << 4) + (hash << 7) + (hash << 8) + (hash << 24);
63
- });
64
- return hash >>> 0;
65
- };
66
-
67
56
  const object = Object;
68
57
  const getPrototypeOf = (obj) => object.getPrototypeOf(obj);
69
58
  const objEntries = object.entries;
@@ -102,6 +91,17 @@ const jsonStringWithUndefined = (obj) =>
102
91
  const jsonParseWithUndefined = (str) =>
103
92
  jsonParse(str, (_key, value) => (value === UNDEFINED ? void 0 : value));
104
93
 
94
+ const textEncoder = /* @__PURE__ */ new GLOBAL.TextEncoder();
95
+ const getHash = (string) => {
96
+ let hash = 2166136261;
97
+ arrayForEach(textEncoder.encode(string), (char) => {
98
+ hash ^= char;
99
+ hash +=
100
+ (hash << 1) + (hash << 4) + (hash << 7) + (hash << 8) + (hash << 24);
101
+ });
102
+ return hash >>> 0;
103
+ };
104
+
105
105
  const mapNew = (entries) => new Map(entries);
106
106
  const mapGet = (map, key) => map?.get(key);
107
107
  const mapForEach = (map, cb) =>
@@ -52,17 +52,6 @@ const collClear = (coll) => coll.clear();
52
52
  const collForEach = (coll, cb) => coll?.forEach(cb);
53
53
  const collDel = (coll, keyOrValue) => coll?.delete(keyOrValue);
54
54
 
55
- const textEncoder = /* @__PURE__ */ new GLOBAL.TextEncoder();
56
- const getHash = (value) => {
57
- let hash = 2166136261;
58
- arrayForEach(textEncoder.encode(value), (char) => {
59
- hash ^= char;
60
- hash +=
61
- (hash << 1) + (hash << 4) + (hash << 7) + (hash << 8) + (hash << 24);
62
- });
63
- return hash >>> 0;
64
- };
65
-
66
55
  const object = Object;
67
56
  const getPrototypeOf = (obj) => object.getPrototypeOf(obj);
68
57
  const objEntries = object.entries;
@@ -101,6 +90,17 @@ const jsonStringWithUndefined = (obj) =>
101
90
  const jsonParseWithUndefined = (str) =>
102
91
  jsonParse(str, (_key, value) => (value === UNDEFINED ? void 0 : value));
103
92
 
93
+ const textEncoder = /* @__PURE__ */ new GLOBAL.TextEncoder();
94
+ const getHash = (string) => {
95
+ let hash = 2166136261;
96
+ arrayForEach(textEncoder.encode(string), (char) => {
97
+ hash ^= char;
98
+ hash +=
99
+ (hash << 1) + (hash << 4) + (hash << 7) + (hash << 8) + (hash << 24);
100
+ });
101
+ return hash >>> 0;
102
+ };
103
+
104
104
  const mapNew = (entries) => new Map(entries);
105
105
  const mapGet = (map, key) => map?.get(key);
106
106
  const mapForEach = (map, cb) =>
@@ -52,17 +52,6 @@ const collClear = (coll) => coll.clear();
52
52
  const collForEach = (coll, cb) => coll?.forEach(cb);
53
53
  const collDel = (coll, keyOrValue) => coll?.delete(keyOrValue);
54
54
 
55
- const textEncoder = /* @__PURE__ */ new GLOBAL.TextEncoder();
56
- const getHash = (value) => {
57
- let hash = 2166136261;
58
- arrayForEach(textEncoder.encode(value), (char) => {
59
- hash ^= char;
60
- hash +=
61
- (hash << 1) + (hash << 4) + (hash << 7) + (hash << 8) + (hash << 24);
62
- });
63
- return hash >>> 0;
64
- };
65
-
66
55
  const object = Object;
67
56
  const getPrototypeOf = (obj) => object.getPrototypeOf(obj);
68
57
  const objEntries = object.entries;
@@ -101,6 +90,17 @@ const jsonStringWithUndefined = (obj) =>
101
90
  const jsonParseWithUndefined = (str) =>
102
91
  jsonParse(str, (_key, value) => (value === UNDEFINED ? void 0 : value));
103
92
 
93
+ const textEncoder = /* @__PURE__ */ new GLOBAL.TextEncoder();
94
+ const getHash = (string) => {
95
+ let hash = 2166136261;
96
+ arrayForEach(textEncoder.encode(string), (char) => {
97
+ hash ^= char;
98
+ hash +=
99
+ (hash << 1) + (hash << 4) + (hash << 7) + (hash << 8) + (hash << 24);
100
+ });
101
+ return hash >>> 0;
102
+ };
103
+
104
104
  const mapNew = (entries) => new Map(entries);
105
105
  const mapGet = (map, key) => map?.get(key);
106
106
  const mapForEach = (map, cb) =>
@@ -468,10 +468,17 @@ const createCustomPersister = (
468
468
  return objFreeze(persister);
469
469
  };
470
470
 
471
+ const jsonString = JSON.stringify;
472
+ const jsonParse = JSON.parse;
473
+ const jsonStringWithUndefined = (obj) =>
474
+ jsonString(obj, (_key, value) => (value === void 0 ? UNDEFINED : value));
475
+ const jsonParseWithUndefined = (str) =>
476
+ jsonParse(str, (_key, value) => (value === UNDEFINED ? void 0 : value));
477
+
471
478
  const textEncoder = /* @__PURE__ */ new GLOBAL.TextEncoder();
472
- const getHash = (value) => {
479
+ const getHash = (string) => {
473
480
  let hash = 2166136261;
474
- arrayForEach(textEncoder.encode(value), (char) => {
481
+ arrayForEach(textEncoder.encode(string), (char) => {
475
482
  hash ^= char;
476
483
  hash +=
477
484
  (hash << 1) + (hash << 4) + (hash << 7) + (hash << 8) + (hash << 24);
@@ -479,13 +486,6 @@ const getHash = (value) => {
479
486
  return hash >>> 0;
480
487
  };
481
488
 
482
- const jsonString = JSON.stringify;
483
- const jsonParse = JSON.parse;
484
- const jsonStringWithUndefined = (obj) =>
485
- jsonString(obj, (_key, value) => (value === void 0 ? UNDEFINED : value));
486
- const jsonParseWithUndefined = (str) =>
487
- jsonParse(str, (_key, value) => (value === UNDEFINED ? void 0 : value));
488
-
489
489
  const SINGLE_ROW_ID = '_';
490
490
  const DEFAULT_ROW_ID_COLUMN_NAME = '_id';
491
491
  const SELECT = 'SELECT';
package/readme.md CHANGED
@@ -1,4 +1,4 @@
1
- <link rel="preload" as="image" href="https://beta.tinybase.org/react.svg?asImg"><link rel="preload" as="image" href="https://beta.tinybase.org/indexeddb.svg?asImg"><link rel="preload" as="image" href="https://beta.tinybase.org/cloudflare.svg?asImg"><link rel="preload" as="image" href="https://beta.tinybase.org/postgresql.svg?asImg"><link rel="preload" as="image" href="https://beta.tinybase.org/pglite.svg?asImg"><link rel="preload" as="image" href="https://beta.tinybase.org/sqlite.svg?asImg"><link rel="preload" as="image" href="https://beta.tinybase.org/bun.svg?asImg"><link rel="preload" as="image" href="https://beta.tinybase.org/expo.svg?asImg"><link rel="preload" as="image" href="https://beta.tinybase.org/electric.svg?asImg"><link rel="preload" as="image" href="https://beta.tinybase.org/turso.svg?asImg"><link rel="preload" as="image" href="https://beta.tinybase.org/powersync.svg?asImg"><link rel="preload" as="image" href="https://beta.tinybase.org/partykit.svg?asImg"><link rel="preload" as="image" href="https://beta.tinybase.org/yjs.svg?asImg"><link rel="preload" as="image" href="https://beta.tinybase.org/crsqlite.png"><link rel="preload" as="image" href="https://beta.tinybase.org/automerge.svg?asImg"><link rel="preload" as="image" href="https://img.shields.io/github/stars/tinyplex/tinybase?style=for-the-badge&amp;logo=GitHub&amp;logoColor=%23fff&amp;label=GitHub&amp;labelColor=%23d81b60&amp;color=%23333"><link rel="preload" as="image" href="https://img.shields.io/badge/Bluesky-Follow-blue?style=for-the-badge&amp;logo=bluesky&amp;logoColor=%23fff&amp;color=%23333&amp;labelColor=%230285FF"><link rel="preload" as="image" href="https://img.shields.io/badge/%2F%20Twitter-Follow-blue?style=for-the-badge&amp;logo=x&amp;logoColor=%23fff&amp;color=%23333&amp;labelColor=%23000"><link rel="preload" as="image" href="https://img.shields.io/discord/1027918215323590676?style=for-the-badge&amp;logo=discord&amp;logoColor=%23fff&amp;label=Discord&amp;labelColor=%233131e8&amp;color=%23333"><link rel="preload" as="image" href="https://img.shields.io/github/discussions/tinyplex/tinybase?style=for-the-badge&amp;logo=GitHub&amp;logoColor=%23fff&amp;label=Ideas&amp;labelColor=%23d81b60&amp;color=%23333"><link rel="preload" as="image" href="https://img.shields.io/github/issues/tinyplex/tinybase?style=for-the-badge&amp;logo=GitHub&amp;logoColor=%23fff&amp;label=Issues&amp;labelColor=%23d81b60&amp;color=%23333"><link rel="preload" as="image" href="https://img.shields.io/badge/Tests-100%25-green?style=for-the-badge&amp;logo=jest&amp;logoColor=%23fff&amp;color=%23333&amp;labelColor=%2387c305"><link rel="preload" as="image" href="https://img.shields.io/npm/v/tinybase?style=for-the-badge&amp;logo=npm&amp;logoColor=%23fff&amp;labelColor=%23bd0005&amp;color=%23333"><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://github.com/cpojer.png?size=48"><link rel="preload" as="image" href="https://github.com/expo.png?size=48"><link rel="preload" as="image" href="https://github.com/beekeeb.png?size=48"><link rel="preload" as="image" href="https://github.com/cancelself.png?size=48"><link rel="preload" as="image" href="https://github.com/WonderPanda.png?size=48"><link rel="preload" as="image" href="https://github.com/arpitBhalla.png?size=48"><link rel="preload" as="image" href="https://github.com/behrends.png?size=48"><link rel="preload" as="image" href="https://github.com/betomoedano.png?size=48"><link rel="preload" as="image" href="https://github.com/brentvatne.png?size=48"><link rel="preload" as="image" href="https://github.com/byCedric.png?size=48"><link rel="preload" as="image" href="https://github.com/circadian-risk.png?size=48"><link rel="preload" as="image" href="https://github.com/cubecull.png?size=48"><link rel="preload" as="image" href="https://github.com/erwinkn.png?size=48"><link rel="preload" as="image" href="https://github.com/ezra-en.png?size=48"><link rel="preload" as="image" href="https://github.com/feychenie.png?size=48"><link rel="preload" as="image" href="https://github.com/flaming-codes.png?size=48"><link rel="preload" as="image" href="https://github.com/fostertheweb.png?size=48"><link rel="preload" as="image" href="https://github.com/Giulio987.png?size=48"><link rel="preload" as="image" href="https://github.com/hi-ogawa.png?size=48"><link rel="preload" as="image" href="https://github.com/itsdevcoffee.png?size=48"><link rel="preload" as="image" href="https://github.com/jbolda.png?size=48"><link rel="preload" as="image" href="https://github.com/Kayoo-asso.png?size=48"><link rel="preload" as="image" href="https://github.com/kotofurumiya.png?size=48"><link rel="preload" as="image" href="https://github.com/Kudo.png?size=48"><link rel="preload" as="image" href="https://github.com/learn-anything.png?size=48"><link rel="preload" as="image" href="https://github.com/lluc.png?size=48"><link rel="preload" as="image" href="https://github.com/marksteve.png?size=48"><link rel="preload" as="image" href="https://github.com/miking-the-viking.png?size=48"><link rel="preload" as="image" href="https://github.com/mjamesderocher.png?size=48"><link rel="preload" as="image" href="https://github.com/mouktardev.png?size=48"><link rel="preload" as="image" href="https://github.com/nickmessing.png?size=48"><link rel="preload" as="image" href="https://github.com/nikitavoloboev.png?size=48"><link rel="preload" as="image" href="https://github.com/nkzw-tech.png?size=48"><link rel="preload" as="image" href="https://github.com/palerdot.png?size=48"><link rel="preload" as="image" href="https://github.com/PorcoRosso85.png?size=48"><link rel="preload" as="image" href="https://github.com/primodiumxyz.png?size=48"><link rel="preload" as="image" href="https://github.com/shaneosullivan.png?size=48"><link rel="preload" as="image" href="https://github.com/sudo-self.png?size=48"><link rel="preload" as="image" href="https://github.com/SuperSonicHub1.png?size=48"><link rel="preload" as="image" href="https://github.com/threepointone.png?size=48"><link rel="preload" as="image" href="https://github.com/uptonking.png?size=48"><link rel="preload" as="image" href="https://github.com/ViktorZhurbin.png?size=48"><link rel="preload" as="image" href="https://github.com/wilkerlucio.png?size=48"><link rel="preload" as="image" href="https://tinybase.org/favicon.svg?asImg"><link rel="preload" as="image" href="https://tinywidgets.org/favicon.svg?asImg"><link rel="preload" as="image" href="https://tinytick.org/favicon.svg?asImg"><link rel="preload" as="image" href="https://beta.tinybase.org/youtube.webp"><section id="hero"><h2 id="a-reactive-data-store-sync-engine">A <em>reactive</em> data store &amp; <span><em>sync</em> engine</span></h2></section><p><a href="https://beta.tinybase.org/guides/releases/#v6-2"><em>NEW!</em> v6.2 release</a></p><p><span id="one-with">&quot;The One With HLCs and <code>omni</code>!&quot;</span></p><p><a class="start" href="https://beta.tinybase.org/guides/the-basics/getting-started/">Get started</a></p><p><a href="https://beta.tinybase.org/demos/">Try the demos</a></p><p><a href="https://beta.tinybase.org/api/store/interfaces/store/store/">Read the docs</a></p><hr><section><h2 id="it-s-reactive">It&#x27;s <em>Reactive</em></h2><p>TinyBase lets you <a href="#register-granular-listeners">listen to changes</a> made to any part of your data. This means your app will be fast, since you only spend rendering cycles on things that change. The optional <a href="#call-hooks-to-bind-to-data">bindings to React</a> and <a href="#pre-built-reactive-components">pre-built components</a> let you easily build fully reactive UIs on top of TinyBase. You even get a built-in <a href="#set-checkpoints-for-an-undo-stack">undo stack</a>, and <a href="#an-inspector-for-your-data">developer tools</a>!</p></section><section><h2 id="it-s-database-like">It&#x27;s <em>Database-Like</em></h2><p>Consumer app? Enterprise app? Or even a game? Model <a href="#start-with-a-simple-key-value-store">key-value data</a> and <a href="#level-up-to-use-tabular-data">tabular data</a> with optional typed <a href="#apply-schemas-to-tables-values">schematization</a>, whatever its data structures. There are built-in <a href="#create-indexes-for-fast-lookups">indexing</a>, <a href="#define-metrics-and-aggregations">metric aggregation</a>, and tabular <a href="#model-table-relationships">relationships</a> APIs - and a powerful <a href="#build-complex-queries-with-tinyql">query engine</a> to select, join, filter, and group data (reactively!) without SQL.</p></section><section><h2 id="it-synchronizes">It <em>Synchronizes</em></h2><p>TinyBase has <a href="#synchronize-between-devices">native CRDT</a> support, meaning that you can deterministically <a href="https://beta.tinybase.org/guides/synchronization/">synchronize</a> and merge data across multiple sources, clients, and servers. And although TinyBase is an in-memory data store, you can easily <a href="#persist-to-storage-databases-more">persist</a> your data to file, <a href="https://beta.tinybase.org/api/persister-browser">browser storage</a>, <a href="https://beta.tinybase.org/api/persister-indexed-db">IndexedDB</a>, <a href="https://beta.tinybase.org/guides/persistence/database-persistence/">SQLite or PostgreSQL databases</a>, and <a href="https://beta.tinybase.org/guides/persistence/third-party-crdt-persistence/">more</a>.</p></section><section><h2 id="it-s-built-for-a-local-first-world">It&#x27;s Built For A <em>Local-First</em> World</h2><p>TinyBase works anywhere that JavaScript does, but it&#x27;s especially great for local-first apps: where data is stored locally on the user&#x27;s device and that can be run offline. It&#x27;s tiny by name, tiny by nature: just <a href="#did-we-say-tiny">5.4kB - 11.6kB</a> and with no dependencies - yet <a href="#well-tested-and-documented">100% tested</a>, <a href="https://beta.tinybase.org/guides/the-basics/getting-started/">fully documented</a>, and of course, <a href="https://github.com/tinyplex/tinybase">open source</a>!</p></section><hr><section id="friends"><h2 id="tinybase-works-great-on-its-own-but-also-plays-well-with-friends">TinyBase works great on its own, but also plays well with friends.</h2><div><a href="https://beta.tinybase.org/guides/building-uis/getting-started-with-ui-react"><img src="https://beta.tinybase.org/react.svg?asImg" width="48"> React</a></div><div><a href="https://beta.tinybase.org/api/persister-indexed-db/functions/creation/createindexeddbpersister"><img src="https://beta.tinybase.org/indexeddb.svg?asImg" width="48"> IndexedDB</a></div><div><a href="https://beta.tinybase.org/guides/integrations/cloudflare-durable-objects"><img src="https://beta.tinybase.org/cloudflare.svg?asImg" width="48"> Cloudflare</a></div><div><a href="https://beta.tinybase.org/guides/schemas-and-persistence/database-persistence"><img src="https://beta.tinybase.org/postgresql.svg?asImg" width="48"> PostgreSQL</a></div><div><a href="https://beta.tinybase.org/guides/schemas-and-persistence/database-persistence"><img src="https://beta.tinybase.org/pglite.svg?asImg" width="48"> PGlite</a></div><div><a href="https://beta.tinybase.org/guides/schemas-and-persistence/database-persistence"><img src="https://beta.tinybase.org/sqlite.svg?asImg" width="48"> SQLite</a></div><div><a href="https://beta.tinybase.org/guides/schemas-and-persistence/database-persistence"><img src="https://beta.tinybase.org/bun.svg?asImg" width="48"> Bun SQLite</a></div><div><a href="https://beta.tinybase.org/guides/schemas-and-persistence/database-persistence"><img src="https://beta.tinybase.org/expo.svg?asImg" width="48"> Expo SQLite</a></div><div><a href="https://beta.tinybase.org/guides/schemas-and-persistence/database-persistence"><img src="https://beta.tinybase.org/electric.svg?asImg" width="48"> ElectricSQL</a></div><div><a href="https://beta.tinybase.org/guides/schemas-and-persistence/database-persistence"><img src="https://beta.tinybase.org/turso.svg?asImg" width="48"> Turso</a></div><div><a href="https://beta.tinybase.org/guides/schemas-and-persistence/database-persistence"><img src="https://beta.tinybase.org/powersync.svg?asImg" width="48"> PowerSync</a></div><div><a href="https://beta.tinybase.org/api/persister-partykit-client"><img src="https://beta.tinybase.org/partykit.svg?asImg" width="48"> PartyKit</a></div><div><a href="https://beta.tinybase.org/api/persister-yjs/functions/creation/createyjspersister"><img src="https://beta.tinybase.org/yjs.svg?asImg" width="48"> YJS</a></div><div><a href="https://beta.tinybase.org/api/persister-cr-sqlite-wasm"><img src="https://beta.tinybase.org/crsqlite.png" width="48"> CR-SQLite</a></div><div><a href="https://beta.tinybase.org/api/persister-automerge"><img src="https://beta.tinybase.org/automerge.svg?asImg" width="48"> Automerge</a></div><p>(Baffled by all these logos? Check out our <a href="https://beta.tinybase.org/guides/the-basics/architectural-options">architectural options</a> guide to make sense of it all!)</p></section><hr><section id="follow"><a href="https://github.com/tinyplex/tinybase" target="_blank"><img src="https://img.shields.io/github/stars/tinyplex/tinybase?style=for-the-badge&amp;logo=GitHub&amp;logoColor=%23fff&amp;label=GitHub&amp;labelColor=%23d81b60&amp;color=%23333"> </a><a href="https://bsky.app/profile/tinybase.bsky.social"><img src="https://img.shields.io/badge/Bluesky-Follow-blue?style=for-the-badge&amp;logo=bluesky&amp;logoColor=%23fff&amp;color=%23333&amp;labelColor=%230285FF"> </a><a href="https://x.com/tinybasejs" target="_blank"><img src="https://img.shields.io/badge/%2F%20Twitter-Follow-blue?style=for-the-badge&amp;logo=x&amp;logoColor=%23fff&amp;color=%23333&amp;labelColor=%23000"> </a><a href="https://discord.com/invite/mGz3mevwP8" target="_blank"><img src="https://img.shields.io/discord/1027918215323590676?style=for-the-badge&amp;logo=discord&amp;logoColor=%23fff&amp;label=Discord&amp;labelColor=%233131e8&amp;color=%23333"></a><br><a href="https://github.com/tinyplex/tinybase/discussions" target="_blank"><img src="https://img.shields.io/github/discussions/tinyplex/tinybase?style=for-the-badge&amp;logo=GitHub&amp;logoColor=%23fff&amp;label=Ideas&amp;labelColor=%23d81b60&amp;color=%23333"> </a><a href="https://github.com/tinyplex/tinybase/issues" target="_blank"><img src="https://img.shields.io/github/issues/tinyplex/tinybase?style=for-the-badge&amp;logo=GitHub&amp;logoColor=%23fff&amp;label=Issues&amp;labelColor=%23d81b60&amp;color=%23333"> </a><a href="#well-tested-and-documented"><img src="https://img.shields.io/badge/Tests-100%25-green?style=for-the-badge&amp;logo=jest&amp;logoColor=%23fff&amp;color=%23333&amp;labelColor=%2387c305"> </a><a href="https://www.npmjs.com/package/tinybase/v/6.2.0-beta.2" target="_blank"><img src="https://img.shields.io/npm/v/tinybase?style=for-the-badge&amp;logo=npm&amp;logoColor=%23fff&amp;labelColor=%23bd0005&amp;color=%23333"></a></section><hr><section><h2 id="start-with-a-simple-key-value-store">Start with a simple key-value store.</h2><p>Creating a <a href="https://beta.tinybase.org/api/store/interfaces/store/store/"><code>Store</code></a> requires just a simple call to the <a href="https://beta.tinybase.org/api/store/functions/creation/createstore/"><code>createStore</code></a> function. Once you have one, you can easily set <a href="https://beta.tinybase.org/api/store/type-aliases/store/values/"><code>Values</code></a> in it by unique <a href="https://beta.tinybase.org/api/common/type-aliases/identity/id/"><code>Id</code></a>. And of course you can easily get them back out again.</p><p>Read more about using keyed value data in <a href="https://beta.tinybase.org/guides/the-basics/">The Basics</a> guide.</p></section>
1
+ <link rel="preload" as="image" href="https://beta.tinybase.org/react.svg?asImg"><link rel="preload" as="image" href="https://beta.tinybase.org/indexeddb.svg?asImg"><link rel="preload" as="image" href="https://beta.tinybase.org/cloudflare.svg?asImg"><link rel="preload" as="image" href="https://beta.tinybase.org/postgresql.svg?asImg"><link rel="preload" as="image" href="https://beta.tinybase.org/pglite.svg?asImg"><link rel="preload" as="image" href="https://beta.tinybase.org/sqlite.svg?asImg"><link rel="preload" as="image" href="https://beta.tinybase.org/bun.svg?asImg"><link rel="preload" as="image" href="https://beta.tinybase.org/expo.svg?asImg"><link rel="preload" as="image" href="https://beta.tinybase.org/electric.svg?asImg"><link rel="preload" as="image" href="https://beta.tinybase.org/turso.svg?asImg"><link rel="preload" as="image" href="https://beta.tinybase.org/powersync.svg?asImg"><link rel="preload" as="image" href="https://beta.tinybase.org/partykit.svg?asImg"><link rel="preload" as="image" href="https://beta.tinybase.org/yjs.svg?asImg"><link rel="preload" as="image" href="https://beta.tinybase.org/crsqlite.png"><link rel="preload" as="image" href="https://beta.tinybase.org/automerge.svg?asImg"><link rel="preload" as="image" href="https://img.shields.io/github/stars/tinyplex/tinybase?style=for-the-badge&amp;logo=GitHub&amp;logoColor=%23fff&amp;label=GitHub&amp;labelColor=%23d81b60&amp;color=%23333"><link rel="preload" as="image" href="https://img.shields.io/badge/Bluesky-Follow-blue?style=for-the-badge&amp;logo=bluesky&amp;logoColor=%23fff&amp;color=%23333&amp;labelColor=%230285FF"><link rel="preload" as="image" href="https://img.shields.io/badge/%2F%20Twitter-Follow-blue?style=for-the-badge&amp;logo=x&amp;logoColor=%23fff&amp;color=%23333&amp;labelColor=%23000"><link rel="preload" as="image" href="https://img.shields.io/discord/1027918215323590676?style=for-the-badge&amp;logo=discord&amp;logoColor=%23fff&amp;label=Discord&amp;labelColor=%233131e8&amp;color=%23333"><link rel="preload" as="image" href="https://img.shields.io/github/discussions/tinyplex/tinybase?style=for-the-badge&amp;logo=GitHub&amp;logoColor=%23fff&amp;label=Ideas&amp;labelColor=%23d81b60&amp;color=%23333"><link rel="preload" as="image" href="https://img.shields.io/github/issues/tinyplex/tinybase?style=for-the-badge&amp;logo=GitHub&amp;logoColor=%23fff&amp;label=Issues&amp;labelColor=%23d81b60&amp;color=%23333"><link rel="preload" as="image" href="https://img.shields.io/badge/Tests-100%25-green?style=for-the-badge&amp;logo=jest&amp;logoColor=%23fff&amp;color=%23333&amp;labelColor=%2387c305"><link rel="preload" as="image" href="https://img.shields.io/npm/v/tinybase?style=for-the-badge&amp;logo=npm&amp;logoColor=%23fff&amp;labelColor=%23bd0005&amp;color=%23333"><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://github.com/cpojer.png?size=48"><link rel="preload" as="image" href="https://github.com/expo.png?size=48"><link rel="preload" as="image" href="https://github.com/beekeeb.png?size=48"><link rel="preload" as="image" href="https://github.com/cancelself.png?size=48"><link rel="preload" as="image" href="https://github.com/WonderPanda.png?size=48"><link rel="preload" as="image" href="https://github.com/arpitBhalla.png?size=48"><link rel="preload" as="image" href="https://github.com/behrends.png?size=48"><link rel="preload" as="image" href="https://github.com/betomoedano.png?size=48"><link rel="preload" as="image" href="https://github.com/brentvatne.png?size=48"><link rel="preload" as="image" href="https://github.com/byCedric.png?size=48"><link rel="preload" as="image" href="https://github.com/circadian-risk.png?size=48"><link rel="preload" as="image" href="https://github.com/cubecull.png?size=48"><link rel="preload" as="image" href="https://github.com/erwinkn.png?size=48"><link rel="preload" as="image" href="https://github.com/ezra-en.png?size=48"><link rel="preload" as="image" href="https://github.com/feychenie.png?size=48"><link rel="preload" as="image" href="https://github.com/flaming-codes.png?size=48"><link rel="preload" as="image" href="https://github.com/fostertheweb.png?size=48"><link rel="preload" as="image" href="https://github.com/Giulio987.png?size=48"><link rel="preload" as="image" href="https://github.com/hi-ogawa.png?size=48"><link rel="preload" as="image" href="https://github.com/itsdevcoffee.png?size=48"><link rel="preload" as="image" href="https://github.com/jbolda.png?size=48"><link rel="preload" as="image" href="https://github.com/Kayoo-asso.png?size=48"><link rel="preload" as="image" href="https://github.com/kotofurumiya.png?size=48"><link rel="preload" as="image" href="https://github.com/Kudo.png?size=48"><link rel="preload" as="image" href="https://github.com/learn-anything.png?size=48"><link rel="preload" as="image" href="https://github.com/lluc.png?size=48"><link rel="preload" as="image" href="https://github.com/marksteve.png?size=48"><link rel="preload" as="image" href="https://github.com/miking-the-viking.png?size=48"><link rel="preload" as="image" href="https://github.com/mjamesderocher.png?size=48"><link rel="preload" as="image" href="https://github.com/mouktardev.png?size=48"><link rel="preload" as="image" href="https://github.com/nickmessing.png?size=48"><link rel="preload" as="image" href="https://github.com/nikitavoloboev.png?size=48"><link rel="preload" as="image" href="https://github.com/nkzw-tech.png?size=48"><link rel="preload" as="image" href="https://github.com/palerdot.png?size=48"><link rel="preload" as="image" href="https://github.com/PorcoRosso85.png?size=48"><link rel="preload" as="image" href="https://github.com/primodiumxyz.png?size=48"><link rel="preload" as="image" href="https://github.com/shaneosullivan.png?size=48"><link rel="preload" as="image" href="https://github.com/sudo-self.png?size=48"><link rel="preload" as="image" href="https://github.com/SuperSonicHub1.png?size=48"><link rel="preload" as="image" href="https://github.com/threepointone.png?size=48"><link rel="preload" as="image" href="https://github.com/uptonking.png?size=48"><link rel="preload" as="image" href="https://github.com/ViktorZhurbin.png?size=48"><link rel="preload" as="image" href="https://github.com/wilkerlucio.png?size=48"><link rel="preload" as="image" href="https://tinybase.org/favicon.svg?asImg"><link rel="preload" as="image" href="https://tinywidgets.org/favicon.svg?asImg"><link rel="preload" as="image" href="https://tinytick.org/favicon.svg?asImg"><link rel="preload" as="image" href="https://beta.tinybase.org/youtube.webp"><section id="hero"><h2 id="a-reactive-data-store-sync-engine">A <em>reactive</em> data store &amp; <span><em>sync</em> engine</span></h2></section><p><a href="https://beta.tinybase.org/guides/releases/#v6-2"><em>NEW!</em> v6.2 release</a></p><p><span id="one-with">&quot;The One With HLCs and <code>omni</code>!&quot;</span></p><p><a class="start" href="https://beta.tinybase.org/guides/the-basics/getting-started/">Get started</a></p><p><a href="https://beta.tinybase.org/demos/">Try the demos</a></p><p><a href="https://beta.tinybase.org/api/store/interfaces/store/store/">Read the docs</a></p><hr><section><h2 id="it-s-reactive">It&#x27;s <em>Reactive</em></h2><p>TinyBase lets you <a href="#register-granular-listeners">listen to changes</a> made to any part of your data. This means your app will be fast, since you only spend rendering cycles on things that change. The optional <a href="#call-hooks-to-bind-to-data">bindings to React</a> and <a href="#pre-built-reactive-components">pre-built components</a> let you easily build fully reactive UIs on top of TinyBase. You even get a built-in <a href="#set-checkpoints-for-an-undo-stack">undo stack</a>, and <a href="#an-inspector-for-your-data">developer tools</a>!</p></section><section><h2 id="it-s-database-like">It&#x27;s <em>Database-Like</em></h2><p>Consumer app? Enterprise app? Or even a game? Model <a href="#start-with-a-simple-key-value-store">key-value data</a> and <a href="#level-up-to-use-tabular-data">tabular data</a> with optional typed <a href="#apply-schemas-to-tables-values">schematization</a>, whatever its data structures. There are built-in <a href="#create-indexes-for-fast-lookups">indexing</a>, <a href="#define-metrics-and-aggregations">metric aggregation</a>, and tabular <a href="#model-table-relationships">relationships</a> APIs - and a powerful <a href="#build-complex-queries-with-tinyql">query engine</a> to select, join, filter, and group data (reactively!) without SQL.</p></section><section><h2 id="it-synchronizes">It <em>Synchronizes</em></h2><p>TinyBase has <a href="#synchronize-between-devices">native CRDT</a> support, meaning that you can deterministically <a href="https://beta.tinybase.org/guides/synchronization/">synchronize</a> and merge data across multiple sources, clients, and servers. And although TinyBase is an in-memory data store, you can easily <a href="#persist-to-storage-databases-more">persist</a> your data to file, <a href="https://beta.tinybase.org/api/persister-browser">browser storage</a>, <a href="https://beta.tinybase.org/api/persister-indexed-db">IndexedDB</a>, <a href="https://beta.tinybase.org/guides/persistence/database-persistence/">SQLite or PostgreSQL databases</a>, and <a href="https://beta.tinybase.org/guides/persistence/third-party-crdt-persistence/">more</a>.</p></section><section><h2 id="it-s-built-for-a-local-first-world">It&#x27;s Built For A <em>Local-First</em> World</h2><p>TinyBase works anywhere that JavaScript does, but it&#x27;s especially great for local-first apps: where data is stored locally on the user&#x27;s device and that can be run offline. It&#x27;s tiny by name, tiny by nature: just <a href="#did-we-say-tiny">5.4kB - 11.8kB</a> and with no dependencies - yet <a href="#well-tested-and-documented">100% tested</a>, <a href="https://beta.tinybase.org/guides/the-basics/getting-started/">fully documented</a>, and of course, <a href="https://github.com/tinyplex/tinybase">open source</a>!</p></section><hr><section id="friends"><h2 id="tinybase-works-great-on-its-own-but-also-plays-well-with-friends">TinyBase works great on its own, but also plays well with friends.</h2><div><a href="https://beta.tinybase.org/guides/building-uis/getting-started-with-ui-react"><img src="https://beta.tinybase.org/react.svg?asImg" width="48"> React</a></div><div><a href="https://beta.tinybase.org/api/persister-indexed-db/functions/creation/createindexeddbpersister"><img src="https://beta.tinybase.org/indexeddb.svg?asImg" width="48"> IndexedDB</a></div><div><a href="https://beta.tinybase.org/guides/integrations/cloudflare-durable-objects"><img src="https://beta.tinybase.org/cloudflare.svg?asImg" width="48"> Cloudflare</a></div><div><a href="https://beta.tinybase.org/guides/schemas-and-persistence/database-persistence"><img src="https://beta.tinybase.org/postgresql.svg?asImg" width="48"> PostgreSQL</a></div><div><a href="https://beta.tinybase.org/guides/schemas-and-persistence/database-persistence"><img src="https://beta.tinybase.org/pglite.svg?asImg" width="48"> PGlite</a></div><div><a href="https://beta.tinybase.org/guides/schemas-and-persistence/database-persistence"><img src="https://beta.tinybase.org/sqlite.svg?asImg" width="48"> SQLite</a></div><div><a href="https://beta.tinybase.org/guides/schemas-and-persistence/database-persistence"><img src="https://beta.tinybase.org/bun.svg?asImg" width="48"> Bun SQLite</a></div><div><a href="https://beta.tinybase.org/guides/schemas-and-persistence/database-persistence"><img src="https://beta.tinybase.org/expo.svg?asImg" width="48"> Expo SQLite</a></div><div><a href="https://beta.tinybase.org/guides/schemas-and-persistence/database-persistence"><img src="https://beta.tinybase.org/electric.svg?asImg" width="48"> ElectricSQL</a></div><div><a href="https://beta.tinybase.org/guides/schemas-and-persistence/database-persistence"><img src="https://beta.tinybase.org/turso.svg?asImg" width="48"> Turso</a></div><div><a href="https://beta.tinybase.org/guides/schemas-and-persistence/database-persistence"><img src="https://beta.tinybase.org/powersync.svg?asImg" width="48"> PowerSync</a></div><div><a href="https://beta.tinybase.org/api/persister-partykit-client"><img src="https://beta.tinybase.org/partykit.svg?asImg" width="48"> PartyKit</a></div><div><a href="https://beta.tinybase.org/api/persister-yjs/functions/creation/createyjspersister"><img src="https://beta.tinybase.org/yjs.svg?asImg" width="48"> YJS</a></div><div><a href="https://beta.tinybase.org/api/persister-cr-sqlite-wasm"><img src="https://beta.tinybase.org/crsqlite.png" width="48"> CR-SQLite</a></div><div><a href="https://beta.tinybase.org/api/persister-automerge"><img src="https://beta.tinybase.org/automerge.svg?asImg" width="48"> Automerge</a></div><p>(Baffled by all these logos? Check out our <a href="https://beta.tinybase.org/guides/the-basics/architectural-options">architectural options</a> guide to make sense of it all!)</p></section><hr><section id="follow"><a href="https://github.com/tinyplex/tinybase" target="_blank"><img src="https://img.shields.io/github/stars/tinyplex/tinybase?style=for-the-badge&amp;logo=GitHub&amp;logoColor=%23fff&amp;label=GitHub&amp;labelColor=%23d81b60&amp;color=%23333"> </a><a href="https://bsky.app/profile/tinybase.bsky.social"><img src="https://img.shields.io/badge/Bluesky-Follow-blue?style=for-the-badge&amp;logo=bluesky&amp;logoColor=%23fff&amp;color=%23333&amp;labelColor=%230285FF"> </a><a href="https://x.com/tinybasejs" target="_blank"><img src="https://img.shields.io/badge/%2F%20Twitter-Follow-blue?style=for-the-badge&amp;logo=x&amp;logoColor=%23fff&amp;color=%23333&amp;labelColor=%23000"> </a><a href="https://discord.com/invite/mGz3mevwP8" target="_blank"><img src="https://img.shields.io/discord/1027918215323590676?style=for-the-badge&amp;logo=discord&amp;logoColor=%23fff&amp;label=Discord&amp;labelColor=%233131e8&amp;color=%23333"></a><br><a href="https://github.com/tinyplex/tinybase/discussions" target="_blank"><img src="https://img.shields.io/github/discussions/tinyplex/tinybase?style=for-the-badge&amp;logo=GitHub&amp;logoColor=%23fff&amp;label=Ideas&amp;labelColor=%23d81b60&amp;color=%23333"> </a><a href="https://github.com/tinyplex/tinybase/issues" target="_blank"><img src="https://img.shields.io/github/issues/tinyplex/tinybase?style=for-the-badge&amp;logo=GitHub&amp;logoColor=%23fff&amp;label=Issues&amp;labelColor=%23d81b60&amp;color=%23333"> </a><a href="#well-tested-and-documented"><img src="https://img.shields.io/badge/Tests-100%25-green?style=for-the-badge&amp;logo=jest&amp;logoColor=%23fff&amp;color=%23333&amp;labelColor=%2387c305"> </a><a href="https://www.npmjs.com/package/tinybase/v/6.2.0-beta.4" target="_blank"><img src="https://img.shields.io/npm/v/tinybase?style=for-the-badge&amp;logo=npm&amp;logoColor=%23fff&amp;labelColor=%23bd0005&amp;color=%23333"></a></section><hr><section><h2 id="start-with-a-simple-key-value-store">Start with a simple key-value store.</h2><p>Creating a <a href="https://beta.tinybase.org/api/store/interfaces/store/store/"><code>Store</code></a> requires just a simple call to the <a href="https://beta.tinybase.org/api/store/functions/creation/createstore/"><code>createStore</code></a> function. Once you have one, you can easily set <a href="https://beta.tinybase.org/api/store/type-aliases/store/values/"><code>Values</code></a> in it by unique <a href="https://beta.tinybase.org/api/common/type-aliases/identity/id/"><code>Id</code></a>. And of course you can easily get them back out again.</p><p>Read more about using keyed value data in <a href="https://beta.tinybase.org/guides/the-basics/">The Basics</a> guide.</p></section>
2
2
 
3
3
  ```js
4
4
  import {createStore} from 'tinybase';
@@ -275,4 +275,4 @@ console.log(store.getCell('pets', 'felix', 'sold'));
275
275
  // -> false
276
276
  ```
277
277
 
278
- <section><h2 id="did-we-say-tiny">Did we say tiny?</h2><p>If you use the basic <a href="https://beta.tinybase.org/api/store/"><code>store</code></a> module alone, you&#x27;ll only add a gzipped <em>5.4kB</em> to your app. Incrementally add the other modules as you need more functionality, or get it all for <em>11.6kB</em>.</p><p>The optional <a href="https://beta.tinybase.org/api/ui-react/"><code>ui-react</code></a> module is just <em>5.2kB</em>, the ui-react-dom components are another <em>2.6kB</em>, and everything is super fast. Life is easy when you have zero dependencies!</p><p>Read more about how TinyBase is structured and packaged in the <a href="https://beta.tinybase.org/guides/how-tinybase-is-built/architecture/">Architecture</a> guide.</p></section><div class="table"><table class="fixed"><tbody><tr><th> </th><th>Minified .js.gz</th><th>Source .js</th></tr><tr><th class="right"><a href="https://beta.tinybase.org/api/store/">tinybase/store</a> (minimal)</th><td>5.4kB</td><td>53.6kB</td></tr><tr><th class="right">tinybase (complete)</th><td>11.6kB</td><td>121.2kB</td></tr><tr><th class="right"><a href="https://beta.tinybase.org/api/ui-react/">ui-react</a></th><td>5.2kB</td><td>55.6kB</td></tr><tr><th class="right"><a href="https://beta.tinybase.org/api/ui-react-dom/">ui-react-dom</a></th><td>2.6kB</td><td>21.1kB</td></tr></tbody></table></div><section><h2 id="well-tested-and-documented">Well tested and documented.</h2><p>TinyBase has <em>100.0%</em> test coverage, including the code throughout the documentation - even on this page! The guides, demos, and API examples are designed to make it as easy as possible for you to get your TinyBase-powered app up and running.</p><p>Read more about how TinyBase is tested in the Unit <a href="https://beta.tinybase.org/guides/how-tinybase-is-built/testing/">Testing</a> guide.</p></section><div class="table"><table class="fixed"><tbody><tr><th width="30%"> </th><th>Total</th><th>Tested</th><th>Coverage</th></tr><tr><th class="right">Lines</th><td>2,312</td><td>2,312</td><td>100.0%</td></tr><tr><th class="right">Statements</th><td>2,501</td><td>2,501</td><td>100.0%</td></tr><tr><th class="right">Functions</th><td>1,000</td><td>1,000</td><td>100.0%</td></tr><tr><th class="right">Branches</th><td>878</td><td>878</td><td>100.0%</td></tr><tr><th class="right">Tests</th><td colspan="3">7,084</td></tr><tr><th class="right">Assertions</th><td colspan="3">32,850</td></tr></tbody></table></div><hr><section id="sponsors"><h2 id="proud-to-be-sponsored-by">Proud to be sponsored by:</h2><a href="https://github.com/cpojer" target="_blank"><img src="https://github.com/cpojer.png?size=48" title="cpojer" width="48" height="48"></a><a href="https://github.com/expo" target="_blank"><img src="https://github.com/expo.png?size=48" title="expo" width="48" height="48"></a><a href="https://github.com/beekeeb" target="_blank"><img src="https://github.com/beekeeb.png?size=48" title="beekeeb" width="48" height="48"></a><a href="https://github.com/cancelself" target="_blank"><img src="https://github.com/cancelself.png?size=48" title="cancelself" width="48" height="48"></a><a href="https://github.com/WonderPanda" target="_blank"><img src="https://github.com/WonderPanda.png?size=48" title="WonderPanda" width="48" height="48"></a><a href="https://github.com/arpitBhalla" target="_blank"><img src="https://github.com/arpitBhalla.png?size=48" title="arpitBhalla" width="48" height="48"></a></section><section id="users"><h2 id="excited-to-be-used-by">Excited to be used by:</h2><a href="https://github.com/behrends" target="_blank"><img src="https://github.com/behrends.png?size=48" title="behrends" width="48" height="48"></a><a href="https://github.com/betomoedano" target="_blank"><img src="https://github.com/betomoedano.png?size=48" title="betomoedano" width="48" height="48"></a><a href="https://github.com/brentvatne" target="_blank"><img src="https://github.com/brentvatne.png?size=48" title="brentvatne" width="48" height="48"></a><a href="https://github.com/byCedric" target="_blank"><img src="https://github.com/byCedric.png?size=48" title="byCedric" width="48" height="48"></a><a href="https://github.com/circadian-risk" target="_blank"><img src="https://github.com/circadian-risk.png?size=48" title="circadian-risk" width="48" height="48"></a><a href="https://github.com/cpojer" target="_blank"><img src="https://github.com/cpojer.png?size=48" title="cpojer" width="48" height="48"></a><a href="https://github.com/cubecull" target="_blank"><img src="https://github.com/cubecull.png?size=48" title="cubecull" width="48" height="48"></a><a href="https://github.com/erwinkn" target="_blank"><img src="https://github.com/erwinkn.png?size=48" title="erwinkn" width="48" height="48"></a><a href="https://github.com/expo" target="_blank"><img src="https://github.com/expo.png?size=48" title="expo" width="48" height="48"></a><a href="https://github.com/ezra-en" target="_blank"><img src="https://github.com/ezra-en.png?size=48" title="ezra-en" width="48" height="48"></a><a href="https://github.com/feychenie" target="_blank"><img src="https://github.com/feychenie.png?size=48" title="feychenie" width="48" height="48"></a><a href="https://github.com/flaming-codes" target="_blank"><img src="https://github.com/flaming-codes.png?size=48" title="flaming-codes" width="48" height="48"></a><a href="https://github.com/fostertheweb" target="_blank"><img src="https://github.com/fostertheweb.png?size=48" title="fostertheweb" width="48" height="48"></a><a href="https://github.com/Giulio987" target="_blank"><img src="https://github.com/Giulio987.png?size=48" title="Giulio987" width="48" height="48"></a><a href="https://github.com/hi-ogawa" target="_blank"><img src="https://github.com/hi-ogawa.png?size=48" title="hi-ogawa" width="48" height="48"></a><a href="https://github.com/itsdevcoffee" target="_blank"><img src="https://github.com/itsdevcoffee.png?size=48" title="itsdevcoffee" width="48" height="48"></a><a href="https://github.com/jbolda" target="_blank"><img src="https://github.com/jbolda.png?size=48" title="jbolda" width="48" height="48"></a><a href="https://github.com/Kayoo-asso" target="_blank"><img src="https://github.com/Kayoo-asso.png?size=48" title="Kayoo-asso" width="48" height="48"></a><a href="https://github.com/kotofurumiya" target="_blank"><img src="https://github.com/kotofurumiya.png?size=48" title="kotofurumiya" width="48" height="48"></a><a href="https://github.com/Kudo" target="_blank"><img src="https://github.com/Kudo.png?size=48" title="Kudo" width="48" height="48"></a><a href="https://github.com/learn-anything" target="_blank"><img src="https://github.com/learn-anything.png?size=48" title="learn-anything" width="48" height="48"></a><a href="https://github.com/lluc" target="_blank"><img src="https://github.com/lluc.png?size=48" title="lluc" width="48" height="48"></a><a href="https://github.com/marksteve" target="_blank"><img src="https://github.com/marksteve.png?size=48" title="marksteve" width="48" height="48"></a><a href="https://github.com/miking-the-viking" target="_blank"><img src="https://github.com/miking-the-viking.png?size=48" title="miking-the-viking" width="48" height="48"></a><a href="https://github.com/mjamesderocher" target="_blank"><img src="https://github.com/mjamesderocher.png?size=48" title="mjamesderocher" width="48" height="48"></a><a href="https://github.com/mouktardev" target="_blank"><img src="https://github.com/mouktardev.png?size=48" title="mouktardev" width="48" height="48"></a><a href="https://github.com/nickmessing" target="_blank"><img src="https://github.com/nickmessing.png?size=48" title="nickmessing" width="48" height="48"></a><a href="https://github.com/nikitavoloboev" target="_blank"><img src="https://github.com/nikitavoloboev.png?size=48" title="nikitavoloboev" width="48" height="48"></a><a href="https://github.com/nkzw-tech" target="_blank"><img src="https://github.com/nkzw-tech.png?size=48" title="nkzw-tech" width="48" height="48"></a><a href="https://github.com/palerdot" target="_blank"><img src="https://github.com/palerdot.png?size=48" title="palerdot" width="48" height="48"></a><a href="https://github.com/PorcoRosso85" target="_blank"><img src="https://github.com/PorcoRosso85.png?size=48" title="PorcoRosso85" width="48" height="48"></a><a href="https://github.com/primodiumxyz" target="_blank"><img src="https://github.com/primodiumxyz.png?size=48" title="primodiumxyz" width="48" height="48"></a><a href="https://github.com/shaneosullivan" target="_blank"><img src="https://github.com/shaneosullivan.png?size=48" title="shaneosullivan" width="48" height="48"></a><a href="https://github.com/sudo-self" target="_blank"><img src="https://github.com/sudo-self.png?size=48" title="sudo-self" width="48" height="48"></a><a href="https://github.com/SuperSonicHub1" target="_blank"><img src="https://github.com/SuperSonicHub1.png?size=48" title="SuperSonicHub1" width="48" height="48"></a><a href="https://github.com/threepointone" target="_blank"><img src="https://github.com/threepointone.png?size=48" title="threepointone" width="48" height="48"></a><a href="https://github.com/uptonking" target="_blank"><img src="https://github.com/uptonking.png?size=48" title="uptonking" width="48" height="48"></a><a href="https://github.com/ViktorZhurbin" target="_blank"><img src="https://github.com/ViktorZhurbin.png?size=48" title="ViktorZhurbin" width="48" height="48"></a><a href="https://github.com/wilkerlucio" target="_blank"><img src="https://github.com/wilkerlucio.png?size=48" title="wilkerlucio" width="48" height="48"></a><a href="https://github.com/WonderPanda" target="_blank"><img src="https://github.com/WonderPanda.png?size=48" title="WonderPanda" width="48" height="48"></a></section><hr><p><a class="start" href="https://beta.tinybase.org/guides/the-basics/getting-started/">Get started</a></p><p><a href="https://beta.tinybase.org/demos/">Try the demos</a></p><p><a href="https://beta.tinybase.org/api/store/interfaces/store/store/">Read the docs</a></p><hr><section id="family"><h2 id="meet-the-family">Meet the family</h2><p>TinyBase is part of a group of small libraries designed to help make rich client and local-first apps easier to build. Check out the others!</p><p><img src="https://tinybase.org/favicon.svg?asImg" width="48"><br><b>TinyBase</b><br>A reactive data store and sync engine.</p><p><a href="https://tinywidgets.org" target="_blank"><img src="https://tinywidgets.org/favicon.svg?asImg" width="48"><br><b>TinyWidgets</b></a><br>A collection of tiny, reusable, UI components.</p><p><a href="https://tinytick.org" target="_blank"><img src="https://tinytick.org/favicon.svg?asImg" width="48"><br><b>TinyTick</b></a><br>A tiny but very useful task orchestrator.</p></section><hr><section id="about"><h2 id="about">About</h2><p>Modern apps deserve better. Why trade reactive user experiences to be able to use relational data? Or sacrifice features for bundle size? And why does the cloud do all the work <a href="https://localfirstweb.dev/" target="_blank">anyway</a>?</p><p>Building TinyBase was originally an interesting exercise for <a rel="me" href="https://tripleodeon.com">me</a> in API design, minification, and documentation. But now it has taken on a life of its own, and has grown beyond my wildest expectations.</p><p>It could not have been built without these great <a href="https://beta.tinybase.org/guides/how-tinybase-is-built/credits/#giants">projects</a> and <a href="https://beta.tinybase.org/guides/how-tinybase-is-built/credits/#and-friends">friends</a>, and I hope you enjoy using it as much as I do building it!</p></section><section id="story"><h2 id="the-story">The story</h2><a href="https://youtu.be/hXL7OkW-Prk?t=1232" target="_blank"><img src="https://beta.tinybase.org/youtube.webp"></a></section>
278
+ <section><h2 id="did-we-say-tiny">Did we say tiny?</h2><p>If you use the basic <a href="https://beta.tinybase.org/api/store/"><code>store</code></a> module alone, you&#x27;ll only add a gzipped <em>5.4kB</em> to your app. Incrementally add the other modules as you need more functionality, or get it all for <em>11.8kB</em>.</p><p>The optional <a href="https://beta.tinybase.org/api/ui-react/"><code>ui-react</code></a> module is just <em>5.2kB</em>, the ui-react-dom components are another <em>2.6kB</em>, and everything is super fast. Life is easy when you have zero dependencies!</p><p>Read more about how TinyBase is structured and packaged in the <a href="https://beta.tinybase.org/guides/how-tinybase-is-built/architecture/">Architecture</a> guide.</p></section><div class="table"><table class="fixed"><tbody><tr><th> </th><th>Minified .js.gz</th><th>Source .js</th></tr><tr><th class="right"><a href="https://beta.tinybase.org/api/store/">tinybase/store</a> (minimal)</th><td>5.4kB</td><td>53.6kB</td></tr><tr><th class="right">tinybase (complete)</th><td>11.8kB</td><td>122.5kB</td></tr><tr><th class="right"><a href="https://beta.tinybase.org/api/ui-react/">ui-react</a></th><td>5.2kB</td><td>55.6kB</td></tr><tr><th class="right"><a href="https://beta.tinybase.org/api/ui-react-dom/">ui-react-dom</a></th><td>2.6kB</td><td>21.1kB</td></tr></tbody></table></div><section><h2 id="well-tested-and-documented">Well tested and documented.</h2><p>TinyBase has <em>100.0%</em> test coverage, including the code throughout the documentation - even on this page! The guides, demos, and API examples are designed to make it as easy as possible for you to get your TinyBase-powered app up and running.</p><p>Read more about how TinyBase is tested in the Unit <a href="https://beta.tinybase.org/guides/how-tinybase-is-built/testing/">Testing</a> guide.</p></section><div class="table"><table class="fixed"><tbody><tr><th width="30%"> </th><th>Total</th><th>Tested</th><th>Coverage</th></tr><tr><th class="right">Lines</th><td>2,328</td><td>2,328</td><td>100.0%</td></tr><tr><th class="right">Statements</th><td>2,517</td><td>2,517</td><td>100.0%</td></tr><tr><th class="right">Functions</th><td>1,006</td><td>1,006</td><td>100.0%</td></tr><tr><th class="right">Branches</th><td>878</td><td>878</td><td>100.0%</td></tr><tr><th class="right">Tests</th><td colspan="3">7,099</td></tr><tr><th class="right">Assertions</th><td colspan="3">32,899</td></tr></tbody></table></div><hr><section id="sponsors"><h2 id="proud-to-be-sponsored-by">Proud to be sponsored by:</h2><a href="https://github.com/cpojer" target="_blank"><img src="https://github.com/cpojer.png?size=48" title="cpojer" width="48" height="48"></a><a href="https://github.com/expo" target="_blank"><img src="https://github.com/expo.png?size=48" title="expo" width="48" height="48"></a><a href="https://github.com/beekeeb" target="_blank"><img src="https://github.com/beekeeb.png?size=48" title="beekeeb" width="48" height="48"></a><a href="https://github.com/cancelself" target="_blank"><img src="https://github.com/cancelself.png?size=48" title="cancelself" width="48" height="48"></a><a href="https://github.com/WonderPanda" target="_blank"><img src="https://github.com/WonderPanda.png?size=48" title="WonderPanda" width="48" height="48"></a><a href="https://github.com/arpitBhalla" target="_blank"><img src="https://github.com/arpitBhalla.png?size=48" title="arpitBhalla" width="48" height="48"></a></section><section id="users"><h2 id="excited-to-be-used-by">Excited to be used by:</h2><a href="https://github.com/behrends" target="_blank"><img src="https://github.com/behrends.png?size=48" title="behrends" width="48" height="48"></a><a href="https://github.com/betomoedano" target="_blank"><img src="https://github.com/betomoedano.png?size=48" title="betomoedano" width="48" height="48"></a><a href="https://github.com/brentvatne" target="_blank"><img src="https://github.com/brentvatne.png?size=48" title="brentvatne" width="48" height="48"></a><a href="https://github.com/byCedric" target="_blank"><img src="https://github.com/byCedric.png?size=48" title="byCedric" width="48" height="48"></a><a href="https://github.com/circadian-risk" target="_blank"><img src="https://github.com/circadian-risk.png?size=48" title="circadian-risk" width="48" height="48"></a><a href="https://github.com/cpojer" target="_blank"><img src="https://github.com/cpojer.png?size=48" title="cpojer" width="48" height="48"></a><a href="https://github.com/cubecull" target="_blank"><img src="https://github.com/cubecull.png?size=48" title="cubecull" width="48" height="48"></a><a href="https://github.com/erwinkn" target="_blank"><img src="https://github.com/erwinkn.png?size=48" title="erwinkn" width="48" height="48"></a><a href="https://github.com/expo" target="_blank"><img src="https://github.com/expo.png?size=48" title="expo" width="48" height="48"></a><a href="https://github.com/ezra-en" target="_blank"><img src="https://github.com/ezra-en.png?size=48" title="ezra-en" width="48" height="48"></a><a href="https://github.com/feychenie" target="_blank"><img src="https://github.com/feychenie.png?size=48" title="feychenie" width="48" height="48"></a><a href="https://github.com/flaming-codes" target="_blank"><img src="https://github.com/flaming-codes.png?size=48" title="flaming-codes" width="48" height="48"></a><a href="https://github.com/fostertheweb" target="_blank"><img src="https://github.com/fostertheweb.png?size=48" title="fostertheweb" width="48" height="48"></a><a href="https://github.com/Giulio987" target="_blank"><img src="https://github.com/Giulio987.png?size=48" title="Giulio987" width="48" height="48"></a><a href="https://github.com/hi-ogawa" target="_blank"><img src="https://github.com/hi-ogawa.png?size=48" title="hi-ogawa" width="48" height="48"></a><a href="https://github.com/itsdevcoffee" target="_blank"><img src="https://github.com/itsdevcoffee.png?size=48" title="itsdevcoffee" width="48" height="48"></a><a href="https://github.com/jbolda" target="_blank"><img src="https://github.com/jbolda.png?size=48" title="jbolda" width="48" height="48"></a><a href="https://github.com/Kayoo-asso" target="_blank"><img src="https://github.com/Kayoo-asso.png?size=48" title="Kayoo-asso" width="48" height="48"></a><a href="https://github.com/kotofurumiya" target="_blank"><img src="https://github.com/kotofurumiya.png?size=48" title="kotofurumiya" width="48" height="48"></a><a href="https://github.com/Kudo" target="_blank"><img src="https://github.com/Kudo.png?size=48" title="Kudo" width="48" height="48"></a><a href="https://github.com/learn-anything" target="_blank"><img src="https://github.com/learn-anything.png?size=48" title="learn-anything" width="48" height="48"></a><a href="https://github.com/lluc" target="_blank"><img src="https://github.com/lluc.png?size=48" title="lluc" width="48" height="48"></a><a href="https://github.com/marksteve" target="_blank"><img src="https://github.com/marksteve.png?size=48" title="marksteve" width="48" height="48"></a><a href="https://github.com/miking-the-viking" target="_blank"><img src="https://github.com/miking-the-viking.png?size=48" title="miking-the-viking" width="48" height="48"></a><a href="https://github.com/mjamesderocher" target="_blank"><img src="https://github.com/mjamesderocher.png?size=48" title="mjamesderocher" width="48" height="48"></a><a href="https://github.com/mouktardev" target="_blank"><img src="https://github.com/mouktardev.png?size=48" title="mouktardev" width="48" height="48"></a><a href="https://github.com/nickmessing" target="_blank"><img src="https://github.com/nickmessing.png?size=48" title="nickmessing" width="48" height="48"></a><a href="https://github.com/nikitavoloboev" target="_blank"><img src="https://github.com/nikitavoloboev.png?size=48" title="nikitavoloboev" width="48" height="48"></a><a href="https://github.com/nkzw-tech" target="_blank"><img src="https://github.com/nkzw-tech.png?size=48" title="nkzw-tech" width="48" height="48"></a><a href="https://github.com/palerdot" target="_blank"><img src="https://github.com/palerdot.png?size=48" title="palerdot" width="48" height="48"></a><a href="https://github.com/PorcoRosso85" target="_blank"><img src="https://github.com/PorcoRosso85.png?size=48" title="PorcoRosso85" width="48" height="48"></a><a href="https://github.com/primodiumxyz" target="_blank"><img src="https://github.com/primodiumxyz.png?size=48" title="primodiumxyz" width="48" height="48"></a><a href="https://github.com/shaneosullivan" target="_blank"><img src="https://github.com/shaneosullivan.png?size=48" title="shaneosullivan" width="48" height="48"></a><a href="https://github.com/sudo-self" target="_blank"><img src="https://github.com/sudo-self.png?size=48" title="sudo-self" width="48" height="48"></a><a href="https://github.com/SuperSonicHub1" target="_blank"><img src="https://github.com/SuperSonicHub1.png?size=48" title="SuperSonicHub1" width="48" height="48"></a><a href="https://github.com/threepointone" target="_blank"><img src="https://github.com/threepointone.png?size=48" title="threepointone" width="48" height="48"></a><a href="https://github.com/uptonking" target="_blank"><img src="https://github.com/uptonking.png?size=48" title="uptonking" width="48" height="48"></a><a href="https://github.com/ViktorZhurbin" target="_blank"><img src="https://github.com/ViktorZhurbin.png?size=48" title="ViktorZhurbin" width="48" height="48"></a><a href="https://github.com/wilkerlucio" target="_blank"><img src="https://github.com/wilkerlucio.png?size=48" title="wilkerlucio" width="48" height="48"></a><a href="https://github.com/WonderPanda" target="_blank"><img src="https://github.com/WonderPanda.png?size=48" title="WonderPanda" width="48" height="48"></a></section><hr><p><a class="start" href="https://beta.tinybase.org/guides/the-basics/getting-started/">Get started</a></p><p><a href="https://beta.tinybase.org/demos/">Try the demos</a></p><p><a href="https://beta.tinybase.org/api/store/interfaces/store/store/">Read the docs</a></p><hr><section id="family"><h2 id="meet-the-family">Meet the family</h2><p>TinyBase is part of a group of small libraries designed to help make rich client and local-first apps easier to build. Check out the others!</p><p><img src="https://tinybase.org/favicon.svg?asImg" width="48"><br><b>TinyBase</b><br>A reactive data store and sync engine.</p><p><a href="https://tinywidgets.org" target="_blank"><img src="https://tinywidgets.org/favicon.svg?asImg" width="48"><br><b>TinyWidgets</b></a><br>A collection of tiny, reusable, UI components.</p><p><a href="https://tinytick.org" target="_blank"><img src="https://tinytick.org/favicon.svg?asImg" width="48"><br><b>TinyTick</b></a><br>A tiny but very useful task orchestrator.</p></section><hr><section id="about"><h2 id="about">About</h2><p>Modern apps deserve better. Why trade reactive user experiences to be able to use relational data? Or sacrifice features for bundle size? And why does the cloud do all the work <a href="https://localfirstweb.dev/" target="_blank">anyway</a>?</p><p>Building TinyBase was originally an interesting exercise for <a rel="me" href="https://tripleodeon.com">me</a> in API design, minification, and documentation. But now it has taken on a life of its own, and has grown beyond my wildest expectations.</p><p>It could not have been built without these great <a href="https://beta.tinybase.org/guides/how-tinybase-is-built/credits/#giants">projects</a> and <a href="https://beta.tinybase.org/guides/how-tinybase-is-built/credits/#and-friends">friends</a>, and I hope you enjoy using it as much as I do building it!</p></section><section id="story"><h2 id="the-story">The story</h2><a href="https://youtu.be/hXL7OkW-Prk?t=1232" target="_blank"><img src="https://beta.tinybase.org/youtube.webp"></a></section>
package/releases.md CHANGED
@@ -1,18 +1,17 @@
1
- <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="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="hlc-functions">HLC functions</h2><p>The <a href="https://beta.tinybase.org/api/common/"><code>common</code></a> module (and hence tinybase module) now export the getHlcFunction function. This returns set of seven functions that can be used to create and manipulate HLC (Hybrid Logical Clock) timestamps.</p>
1
+ <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="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>
2
2
 
3
- ```js
4
- import {getHlcFunctions} from 'tinybase';
5
- console.warn({getHlcFunctions});
6
- //const [getNextHlc, seenHlc, encodeHlc] = getHlcFunctions();
3
+ ```js yolo
4
+ import {createStore, createSqliteBunPersister} from 'tinybase/omni';
7
5
  ```
8
6
 
9
- <p>If needed, you can use these in your own systems to ensure the timestamps are compatible with the ones generated in TinyBase <a href="https://beta.tinybase.org/api/mergeable-store/interfaces/mergeable/mergeablestore/"><code>MergeableStore</code></a> objects.</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>
7
+ <p>However, it should go without saying that you should only use the <code>omni</code> module if you have a good tree-shaking bundler that can remove all the persisters, synchronizers, and so on, that you do <em>not</em> use.</p><h2 id="with-schema-exports">with-schema exports</h2><p>This release changes the <code>package.json</code> exports slightly so that imports of both <code>/with-schema</code> and non-schema&#x27;d versions of the modules resolve to the same JavaScript file. This reduces bundle size for apps that use both schema and non-schema imports.</p><h2 id="hlc-hash-functions">HLC &amp; hash functions</h2><p>The <a href="https://beta.tinybase.org/api/common/"><code>common</code></a> module (and hence tinybase module) now export the <a href="https://beta.tinybase.org/api/common/functions/stamps/gethlcfunctions/"><code>getHlcFunctions</code></a> function. This returns set of seven functions that can be used to create and manipulate HLC (Hybrid Logical Clock) timestamps.</p>
10
8
 
11
- ```js yolo
12
- import {createStore, createSqliteBunPersister} from 'tinybase/omni';
9
+ ```js
10
+ import {getHlcFunctions} from 'tinybase';
11
+ const [getNextHlc, seenHlc, encodeHlc] = getHlcFunctions();
13
12
  ```
14
13
 
15
- <p>However, it should go without saying that you should only use the <code>omni</code> module if you have a good tree-shaking bundler that can remove all the persisters, synchronizers, and so on, that you do <em>not</em> use.</p><h2 id="with-schema-exports">with-schema exports</h2><p>This release changes the <code>package.json</code> exports slightly so that imports of both <code>/with-schema</code> and non-schema&#x27;d versions of the modules resolve to the same JavaScript file. This reduces bundle size for apps that use both schema and non-schema imports.</p><h2 id="moving-the-getnow-type">Moving the <a href="https://beta.tinybase.org/api/common/type-aliases/stamps/getnow/"><code>GetNow</code></a> type</h2><p>The rarely-used <a href="https://beta.tinybase.org/api/common/type-aliases/stamps/getnow/"><code>GetNow</code></a> type has been moved from the <a href="https://beta.tinybase.org/api/mergeable-store/"><code>mergeable-store</code></a> module into the <a href="https://beta.tinybase.org/api/common/"><code>common</code></a> module.</p><h1 id="v6-1">v6.1</h1><h2 id="in-summary">In Summary</h2><ul><li><a href="#bun-sqlite">A new Persister for Bun</a>&#x27;s embedded SQLite database.</li><li><a href="#subset-persistence">Subset persistence</a> to load subsets of tables into a <a href="https://beta.tinybase.org/api/store/interfaces/store/store/"><code>Store</code></a>.</li><li><a href="#destructured-object-arguments-for-sorted-row-ids">Destructured object arguments</a> 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/id/"><code>Id</code></a> methods and hooks.</li><li><a href="#new-startautopersisting-method">A new startAutoPersisting method</a>.</li></ul><p>And more!</p><h2 id="bun-sqlite">Bun SQLite</h2><p>This release includes a new <a href="https://beta.tinybase.org/api/persisters/interfaces/persister/persister/"><code>Persister</code></a> for the <a href="https://bun.sh/docs/api/sqlite">embedded SQLite database</a> available in the Bun runtime.</p><p>You use it by passing a reference to a Bun Database object into the <a href="https://beta.tinybase.org/api/persister-sqlite-bun/functions/creation/createsqlitebunpersister/"><code>createSqliteBunPersister</code></a> function:</p>
14
+ <p>There are also several functions to help hash tabular and key-value data in a way that is compatible with the internal <a href="https://beta.tinybase.org/api/mergeable-store/interfaces/mergeable/mergeablestore/"><code>MergeableStore</code></a> implementation. These include the <a href="https://beta.tinybase.org/api/common/functions/hash/gethash/"><code>getHash</code></a> function and the <a href="https://beta.tinybase.org/api/common/functions/hash/getcellhash/"><code>getCellHash</code></a> function, for example.</p><p>These are for pretty advanced use-cases! But you can use these in your own systems to ensure the timestamps and hashes are compatible with the ones generated in TinyBase <a href="https://beta.tinybase.org/api/mergeable-store/interfaces/mergeable/mergeablestore/"><code>MergeableStore</code></a> objects.</p><h2 id="moved-types">Moved types</h2><p>The rarely-used <a href="https://beta.tinybase.org/api/common/type-aliases/stamps/getnow/"><code>GetNow</code></a> and <a href="https://beta.tinybase.org/api/common/type-aliases/stamps/hash/"><code>Hash</code></a> types have been moved from the <a href="https://beta.tinybase.org/api/mergeable-store/"><code>mergeable-store</code></a> module into the <a href="https://beta.tinybase.org/api/common/"><code>common</code></a> module.</p><h1 id="v6-1">v6.1</h1><h2 id="in-summary">In Summary</h2><ul><li><a href="#bun-sqlite">A new Persister for Bun</a>&#x27;s embedded SQLite database.</li><li><a href="#subset-persistence">Subset persistence</a> to load subsets of tables into a <a href="https://beta.tinybase.org/api/store/interfaces/store/store/"><code>Store</code></a>.</li><li><a href="#destructured-object-arguments-for-sorted-row-ids">Destructured object arguments</a> 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/id/"><code>Id</code></a> methods and hooks.</li><li><a href="#new-startautopersisting-method">A new startAutoPersisting method</a>.</li></ul><p>And more!</p><h2 id="bun-sqlite">Bun SQLite</h2><p>This release includes a new <a href="https://beta.tinybase.org/api/persisters/interfaces/persister/persister/"><code>Persister</code></a> for the <a href="https://bun.sh/docs/api/sqlite">embedded SQLite database</a> available in the Bun runtime.</p><p>You use it by passing a reference to a Bun Database object into the <a href="https://beta.tinybase.org/api/persister-sqlite-bun/functions/creation/createsqlitebunpersister/"><code>createSqliteBunPersister</code></a> function:</p>
16
15
 
17
16
  ```js bun
18
17
  import {Database} from 'bun:sqlite';
@@ -601,4 +600,4 @@ store.finishTransaction();
601
600
  // -> 'Fido changed'
602
601
  ```
603
602
 
604
- <p>In addition, see the <a href="https://beta.tinybase.org/api/store/interfaces/store/store/methods/listener/addwillfinishtransactionlistener/"><code>addWillFinishTransactionListener</code></a> method and the <a href="https://beta.tinybase.org/api/store/interfaces/store/store/methods/listener/adddidfinishtransactionlistener/"><code>addDidFinishTransactionListener</code></a> method for details around listening to transactions completing.</p><p>Together, this release allows stores to couple their transaction life-cycles together, which we need for the query engine.</p><p>Note: this API was updated to be more comprehensive in v4.0.</p><hr><h1 id="v1-2">v1.2</h1><p>This adds a way to revert transactions if they have not met certain conditions.</p><p>When using the <a href="https://beta.tinybase.org/api/store/interfaces/store/store/methods/transaction/transaction/"><code>transaction</code></a> method, you can provide an optional <code>doRollback</code> callback which should return true if you want to revert the whole transaction at its conclusion.</p><p>The callback is provided with two objects, <code>changedCells</code> and <code>invalidCells</code>, which list all the net changes and invalid attempts at changes that were made during the transaction. You will most likely use the contents of those objects to decide whether the transaction should be rolled back.</p><p>Note: this API was updated to be more comprehensive in v4.0.</p><hr><h1 id="v1-1">v1.1</h1><p>This release allows you to listen to invalid data being added to a <a href="https://beta.tinybase.org/api/store/interfaces/store/store/"><code>Store</code></a>, allowing you to gracefully handle errors, rather than them failing silently.</p><p>There is a new listener type <a href="https://beta.tinybase.org/api/store/type-aliases/listener/invalidcelllistener/"><code>InvalidCellListener</code></a> and a <a href="https://beta.tinybase.org/api/store/interfaces/store/store/methods/listener/addinvalidcelllistener/"><code>addInvalidCellListener</code></a> method in the <a href="https://beta.tinybase.org/api/store/interfaces/store/store/"><code>Store</code></a> interface.</p><p>These allow you to keep track of failed attempts to update the <a href="https://beta.tinybase.org/api/store/interfaces/store/store/"><code>Store</code></a> with invalid <a href="https://beta.tinybase.org/api/store/type-aliases/store/cell/"><code>Cell</code></a> data. These listeners can also be mutators, allowing you to address any failed writes programmatically.</p><p>For more information, please see the <a href="https://beta.tinybase.org/api/store/interfaces/store/store/methods/listener/addinvalidcelllistener/"><code>addInvalidCellListener</code></a> method documentation. In particular, this explains how this listener behaves for a <a href="https://beta.tinybase.org/api/store/interfaces/store/store/"><code>Store</code></a> with a <a href="https://beta.tinybase.org/api/store/type-aliases/schema/tablesschema/"><code>TablesSchema</code></a>.</p>
603
+ <p>In addition, see the <a href="https://beta.tinybase.org/api/store/interfaces/store/store/methods/listener/addwillfinishtransactionlistener/"><code>addWillFinishTransactionListener</code></a> method and the <a href="https://beta.tinybase.org/api/store/interfaces/store/store/methods/listener/adddidfinishtransactionlistener/"><code>addDidFinishTransactionListener</code></a> method for details around listening to transactions completing.</p><p>Together, this release allows stores to couple their transaction life-cycles together, which we need for the query engine.</p><p>Note: this API was updated to be more comprehensive in v4.0.</p><hr><h1 id="v1-2">v1.2</h1><p>This adds a way to revert transactions if they have not met certain conditions.</p><p>When using the <a href="https://beta.tinybase.org/api/store/interfaces/store/store/methods/transaction/transaction/"><code>transaction</code></a> method, you can provide an optional <code>doRollback</code> callback which should return true if you want to revert the whole transaction at its conclusion.</p><p>The callback is provided with two objects, <code>changedCells</code> and <code>invalidCells</code>, which list all the net changes and invalid attempts at changes that were made during the transaction. You will most likely use the contents of those objects to decide whether the transaction should be rolled back.</p><p>Note: this API was updated to be more comprehensive in v4.0.</p><hr><h1 id="v1-1">v1.1</h1><p>This release allows you to listen to invalid data being added to a <a href="https://beta.tinybase.org/api/store/interfaces/store/store/"><code>Store</code></a>, allowing you to gracefully handle errors, rather than them failing silently.</p><p>There is a new listener type <a href="https://beta.tinybase.org/api/store/type-aliases/listener/invalidcelllistener/"><code>InvalidCellListener</code></a> and a <a href="https://beta.tinybase.org/api/store/interfaces/store/store/methods/listener/addinvalidcelllistener/"><code>addInvalidCellListener</code></a> method in the <a href="https://beta.tinybase.org/api/store/interfaces/store/store/"><code>Store</code></a> interface.</p><p>These allow you to keep track of failed attempts to update the <a href="https://beta.tinybase.org/api/store/interfaces/store/store/"><code>Store</code></a> with invalid <a href="https://beta.tinybase.org/api/store/type-aliases/store/cell/"><code>Cell</code></a> data. These listeners can also be mutators, allowing you to address any failed writes programmatically.</p><p>For more information, please see the <a href="https://beta.tinybase.org/api/store/interfaces/store/store/methods/listener/addinvalidcelllistener/"><code>addInvalidCellListener</code></a> method documentation. In particular, this explains how this listener behaves for a <a href="https://beta.tinybase.org/api/store/interfaces/store/store/"><code>Store</code></a> with a <a href="https://beta.tinybase.org/api/store/type-aliases/schema/tablesschema/"><code>TablesSchema</code></a>.</p>
package/store/index.js CHANGED
@@ -84,8 +84,8 @@ const collDel = (coll, keyOrValue) => coll?.delete(keyOrValue);
84
84
 
85
85
  const object = Object;
86
86
  const getPrototypeOf = (obj) => object.getPrototypeOf(obj);
87
- const objEntries = object.entries;
88
87
  const objFrozen = object.isFrozen;
88
+ const objEntries = object.entries;
89
89
  const isObject = (obj) =>
90
90
  !isUndefined(obj) &&
91
91
  ifNotUndefined(
@@ -208,9 +208,6 @@ const visitTree = (node, path, ensureLeaf, pruneLeaf, p = 0) =>
208
208
  },
209
209
  );
210
210
 
211
- const defaultSorter = (sortKey1, sortKey2) =>
212
- (sortKey1 ?? 0) < (sortKey2 ?? 0) ? -1 : 1;
213
-
214
211
  const jsonString = JSON.stringify;
215
212
  const jsonParse = JSON.parse;
216
213
  const jsonStringWithMap = (obj) =>
@@ -218,6 +215,9 @@ const jsonStringWithMap = (obj) =>
218
215
  isInstanceOf(value, Map) ? object.fromEntries([...value]) : value,
219
216
  );
220
217
 
218
+ const defaultSorter = (sortKey1, sortKey2) =>
219
+ (sortKey1 ?? 0) < (sortKey2 ?? 0) ? -1 : 1;
220
+
221
221
  const INTEGER = /^\d+$/;
222
222
  const getPoolFunctions = () => {
223
223
  const pool = [];
@@ -84,8 +84,8 @@ const collDel = (coll, keyOrValue) => coll?.delete(keyOrValue);
84
84
 
85
85
  const object = Object;
86
86
  const getPrototypeOf = (obj) => object.getPrototypeOf(obj);
87
- const objEntries = object.entries;
88
87
  const objFrozen = object.isFrozen;
88
+ const objEntries = object.entries;
89
89
  const isObject = (obj) =>
90
90
  !isUndefined(obj) &&
91
91
  ifNotUndefined(
@@ -208,9 +208,6 @@ const visitTree = (node, path, ensureLeaf, pruneLeaf, p = 0) =>
208
208
  },
209
209
  );
210
210
 
211
- const defaultSorter = (sortKey1, sortKey2) =>
212
- (sortKey1 ?? 0) < (sortKey2 ?? 0) ? -1 : 1;
213
-
214
211
  const jsonString = JSON.stringify;
215
212
  const jsonParse = JSON.parse;
216
213
  const jsonStringWithMap = (obj) =>
@@ -218,6 +215,9 @@ const jsonStringWithMap = (obj) =>
218
215
  isInstanceOf(value, Map) ? object.fromEntries([...value]) : value,
219
216
  );
220
217
 
218
+ const defaultSorter = (sortKey1, sortKey2) =>
219
+ (sortKey1 ?? 0) < (sortKey2 ?? 0) ? -1 : 1;
220
+
221
221
  const INTEGER = /^\d+$/;
222
222
  const getPoolFunctions = () => {
223
223
  const pool = [];
@@ -121,11 +121,11 @@ const getUniqueId = (length = 16) =>
121
121
  '',
122
122
  );
123
123
 
124
- const stampNew = (value, time) => (time ? [value, time] : [value]);
125
- const getLatestTime = (time1, time2) =>
124
+ const stampNew = (value, hlc) => (hlc ? [value, hlc] : [value]);
125
+ const getLatestHlc = (hlc1, hlc2) =>
126
126
  /* istanbul ignore next */
127
- ((time1 ?? '') > (time2 ?? '') ? time1 : time2) ?? '';
128
- const stampNewObj = (time = EMPTY_STRING) => stampNew(objNew(), time);
127
+ ((hlc1 ?? '') > (hlc2 ?? '') ? hlc1 : hlc2) ?? '';
128
+ const stampNewObj = (hlc = EMPTY_STRING) => stampNew(objNew(), hlc);
129
129
 
130
130
  const INTEGER = /^\d+$/;
131
131
  const getPoolFunctions = () => {
@@ -521,11 +521,11 @@ const createCustomSynchronizer = (
521
521
  ([cell2, cellTime2], cellId) =>
522
522
  (rowStamp[0][cellId] = stampNew(cell2, cellTime2)),
523
523
  );
524
- rowStamp[1] = getLatestTime(rowStamp[1], rowTime2);
524
+ rowStamp[1] = getLatestHlc(rowStamp[1], rowTime2);
525
525
  });
526
- tableStamp[1] = getLatestTime(tableStamp[1], tableTime2);
526
+ tableStamp[1] = getLatestHlc(tableStamp[1], tableTime2);
527
527
  });
528
- tablesStamp[1] = getLatestTime(tablesStamp[1], tablesTime2);
528
+ tablesStamp[1] = getLatestHlc(tablesStamp[1], tablesTime2);
529
529
  };
530
530
  const getChangesFromOtherStore = (
531
531
  otherClientId = null,
@@ -121,11 +121,11 @@ const getUniqueId = (length = 16) =>
121
121
  '',
122
122
  );
123
123
 
124
- const stampNew = (value, time) => (time ? [value, time] : [value]);
125
- const getLatestTime = (time1, time2) =>
124
+ const stampNew = (value, hlc) => (hlc ? [value, hlc] : [value]);
125
+ const getLatestHlc = (hlc1, hlc2) =>
126
126
  /* istanbul ignore next */
127
- ((time1 ?? '') > (time2 ?? '') ? time1 : time2) ?? '';
128
- const stampNewObj = (time = EMPTY_STRING) => stampNew(objNew(), time);
127
+ ((hlc1 ?? '') > (hlc2 ?? '') ? hlc1 : hlc2) ?? '';
128
+ const stampNewObj = (hlc = EMPTY_STRING) => stampNew(objNew(), hlc);
129
129
 
130
130
  const INTEGER = /^\d+$/;
131
131
  const getPoolFunctions = () => {
@@ -511,11 +511,11 @@ const createCustomSynchronizer = (
511
511
  ([cell2, cellTime2], cellId) =>
512
512
  (rowStamp[0][cellId] = stampNew(cell2, cellTime2)),
513
513
  );
514
- rowStamp[1] = getLatestTime(rowStamp[1], rowTime2);
514
+ rowStamp[1] = getLatestHlc(rowStamp[1], rowTime2);
515
515
  });
516
- tableStamp[1] = getLatestTime(tableStamp[1], tableTime2);
516
+ tableStamp[1] = getLatestHlc(tableStamp[1], tableTime2);
517
517
  });
518
- tablesStamp[1] = getLatestTime(tablesStamp[1], tablesTime2);
518
+ tablesStamp[1] = getLatestHlc(tablesStamp[1], tablesTime2);
519
519
  };
520
520
  const getChangesFromOtherStore = (
521
521
  otherClientId = null,