tinybase 9.4.0-beta.1 → 9.4.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.
Files changed (225) hide show
  1. package/@types/persisters/index.d.ts +4 -0
  2. package/@types/persisters/persister-durable-object-sql-storage/index.d.ts +9 -2
  3. package/@types/persisters/persister-durable-object-sql-storage/with-schemas/index.d.ts +9 -2
  4. package/@types/persisters/with-schemas/index.d.ts +4 -0
  5. package/@types/queries/index.d.ts +4 -0
  6. package/@types/queries/with-schemas/index.d.ts +4 -0
  7. package/@types/synchronizers/synchronizer-ws-client/index.d.ts +7 -3
  8. package/@types/synchronizers/synchronizer-ws-client/with-schemas/index.d.ts +7 -3
  9. package/@types/synchronizers/synchronizer-ws-server/index.d.ts +9 -3
  10. package/@types/synchronizers/synchronizer-ws-server/with-schemas/index.d.ts +9 -3
  11. package/@types/synchronizers/synchronizer-ws-server-simple/index.d.ts +6 -3
  12. package/@types/synchronizers/synchronizer-ws-server-simple/with-schemas/index.d.ts +6 -3
  13. package/index.js +191 -74
  14. package/min/index.js +1 -1
  15. package/min/index.js.gz +0 -0
  16. package/min/omni/index.js +1 -1
  17. package/min/omni/index.js.gz +0 -0
  18. package/min/omni/with-schemas/index.js +1 -1
  19. package/min/omni/with-schemas/index.js.gz +0 -0
  20. package/min/persisters/index.js +1 -1
  21. package/min/persisters/index.js.gz +0 -0
  22. package/min/persisters/persister-automerge/index.js +1 -1
  23. package/min/persisters/persister-automerge/index.js.gz +0 -0
  24. package/min/persisters/persister-automerge/with-schemas/index.js +1 -1
  25. package/min/persisters/persister-automerge/with-schemas/index.js.gz +0 -0
  26. package/min/persisters/persister-browser/index.js +1 -1
  27. package/min/persisters/persister-browser/index.js.gz +0 -0
  28. package/min/persisters/persister-browser/with-schemas/index.js +1 -1
  29. package/min/persisters/persister-browser/with-schemas/index.js.gz +0 -0
  30. package/min/persisters/persister-cr-sqlite-wasm/index.js +1 -1
  31. package/min/persisters/persister-cr-sqlite-wasm/index.js.gz +0 -0
  32. package/min/persisters/persister-cr-sqlite-wasm/with-schemas/index.js +1 -1
  33. package/min/persisters/persister-cr-sqlite-wasm/with-schemas/index.js.gz +0 -0
  34. package/min/persisters/persister-durable-object-sql-storage/index.js +1 -1
  35. package/min/persisters/persister-durable-object-sql-storage/index.js.gz +0 -0
  36. package/min/persisters/persister-durable-object-sql-storage/with-schemas/index.js +1 -1
  37. package/min/persisters/persister-durable-object-sql-storage/with-schemas/index.js.gz +0 -0
  38. package/min/persisters/persister-durable-object-storage/index.js +1 -1
  39. package/min/persisters/persister-durable-object-storage/index.js.gz +0 -0
  40. package/min/persisters/persister-durable-object-storage/with-schemas/index.js +1 -1
  41. package/min/persisters/persister-durable-object-storage/with-schemas/index.js.gz +0 -0
  42. package/min/persisters/persister-electric-sql/index.js +1 -1
  43. package/min/persisters/persister-electric-sql/index.js.gz +0 -0
  44. package/min/persisters/persister-electric-sql/with-schemas/index.js +1 -1
  45. package/min/persisters/persister-electric-sql/with-schemas/index.js.gz +0 -0
  46. package/min/persisters/persister-expo-sqlite/index.js +1 -1
  47. package/min/persisters/persister-expo-sqlite/index.js.gz +0 -0
  48. package/min/persisters/persister-expo-sqlite/with-schemas/index.js +1 -1
  49. package/min/persisters/persister-expo-sqlite/with-schemas/index.js.gz +0 -0
  50. package/min/persisters/persister-file/index.js +1 -1
  51. package/min/persisters/persister-file/index.js.gz +0 -0
  52. package/min/persisters/persister-file/with-schemas/index.js +1 -1
  53. package/min/persisters/persister-file/with-schemas/index.js.gz +0 -0
  54. package/min/persisters/persister-indexed-db/index.js +1 -1
  55. package/min/persisters/persister-indexed-db/index.js.gz +0 -0
  56. package/min/persisters/persister-indexed-db/with-schemas/index.js +1 -1
  57. package/min/persisters/persister-indexed-db/with-schemas/index.js.gz +0 -0
  58. package/min/persisters/persister-libsql/index.js +1 -1
  59. package/min/persisters/persister-libsql/index.js.gz +0 -0
  60. package/min/persisters/persister-libsql/with-schemas/index.js +1 -1
  61. package/min/persisters/persister-libsql/with-schemas/index.js.gz +0 -0
  62. package/min/persisters/persister-partykit-client/index.js +1 -1
  63. package/min/persisters/persister-partykit-client/index.js.gz +0 -0
  64. package/min/persisters/persister-partykit-client/with-schemas/index.js +1 -1
  65. package/min/persisters/persister-partykit-client/with-schemas/index.js.gz +0 -0
  66. package/min/persisters/persister-pglite/index.js +1 -1
  67. package/min/persisters/persister-pglite/index.js.gz +0 -0
  68. package/min/persisters/persister-pglite/with-schemas/index.js +1 -1
  69. package/min/persisters/persister-pglite/with-schemas/index.js.gz +0 -0
  70. package/min/persisters/persister-postgres/index.js +1 -1
  71. package/min/persisters/persister-postgres/index.js.gz +0 -0
  72. package/min/persisters/persister-postgres/with-schemas/index.js +1 -1
  73. package/min/persisters/persister-postgres/with-schemas/index.js.gz +0 -0
  74. package/min/persisters/persister-powersync/index.js +1 -1
  75. package/min/persisters/persister-powersync/index.js.gz +0 -0
  76. package/min/persisters/persister-powersync/with-schemas/index.js +1 -1
  77. package/min/persisters/persister-powersync/with-schemas/index.js.gz +0 -0
  78. package/min/persisters/persister-react-native-mmkv/index.js +1 -1
  79. package/min/persisters/persister-react-native-mmkv/index.js.gz +0 -0
  80. package/min/persisters/persister-react-native-mmkv/with-schemas/index.js +1 -1
  81. package/min/persisters/persister-react-native-mmkv/with-schemas/index.js.gz +0 -0
  82. package/min/persisters/persister-react-native-sqlite/index.js +1 -1
  83. package/min/persisters/persister-react-native-sqlite/index.js.gz +0 -0
  84. package/min/persisters/persister-react-native-sqlite/with-schemas/index.js +1 -1
  85. package/min/persisters/persister-react-native-sqlite/with-schemas/index.js.gz +0 -0
  86. package/min/persisters/persister-remote/index.js +1 -1
  87. package/min/persisters/persister-remote/index.js.gz +0 -0
  88. package/min/persisters/persister-remote/with-schemas/index.js +1 -1
  89. package/min/persisters/persister-remote/with-schemas/index.js.gz +0 -0
  90. package/min/persisters/persister-sqlite-bun/index.js +1 -1
  91. package/min/persisters/persister-sqlite-bun/index.js.gz +0 -0
  92. package/min/persisters/persister-sqlite-bun/with-schemas/index.js +1 -1
  93. package/min/persisters/persister-sqlite-bun/with-schemas/index.js.gz +0 -0
  94. package/min/persisters/persister-sqlite-wasm/index.js +1 -1
  95. package/min/persisters/persister-sqlite-wasm/index.js.gz +0 -0
  96. package/min/persisters/persister-sqlite-wasm/with-schemas/index.js +1 -1
  97. package/min/persisters/persister-sqlite-wasm/with-schemas/index.js.gz +0 -0
  98. package/min/persisters/persister-sqlite3/index.js +1 -1
  99. package/min/persisters/persister-sqlite3/index.js.gz +0 -0
  100. package/min/persisters/persister-sqlite3/with-schemas/index.js +1 -1
  101. package/min/persisters/persister-sqlite3/with-schemas/index.js.gz +0 -0
  102. package/min/persisters/persister-yjs/index.js +1 -1
  103. package/min/persisters/persister-yjs/index.js.gz +0 -0
  104. package/min/persisters/persister-yjs/with-schemas/index.js +1 -1
  105. package/min/persisters/persister-yjs/with-schemas/index.js.gz +0 -0
  106. package/min/persisters/with-schemas/index.js +1 -1
  107. package/min/persisters/with-schemas/index.js.gz +0 -0
  108. package/min/queries/index.js +1 -1
  109. package/min/queries/index.js.gz +0 -0
  110. package/min/queries/with-schemas/index.js +1 -1
  111. package/min/queries/with-schemas/index.js.gz +0 -0
  112. package/min/synchronizers/index.js +1 -1
  113. package/min/synchronizers/index.js.gz +0 -0
  114. package/min/synchronizers/synchronizer-broadcast-channel/index.js +1 -1
  115. package/min/synchronizers/synchronizer-broadcast-channel/index.js.gz +0 -0
  116. package/min/synchronizers/synchronizer-broadcast-channel/with-schemas/index.js +1 -1
  117. package/min/synchronizers/synchronizer-broadcast-channel/with-schemas/index.js.gz +0 -0
  118. package/min/synchronizers/synchronizer-local/index.js +1 -1
  119. package/min/synchronizers/synchronizer-local/index.js.gz +0 -0
  120. package/min/synchronizers/synchronizer-local/with-schemas/index.js +1 -1
  121. package/min/synchronizers/synchronizer-local/with-schemas/index.js.gz +0 -0
  122. package/min/synchronizers/synchronizer-ws-client/index.js +1 -1
  123. package/min/synchronizers/synchronizer-ws-client/index.js.gz +0 -0
  124. package/min/synchronizers/synchronizer-ws-client/with-schemas/index.js +1 -1
  125. package/min/synchronizers/synchronizer-ws-client/with-schemas/index.js.gz +0 -0
  126. package/min/synchronizers/synchronizer-ws-server/index.js +1 -1
  127. package/min/synchronizers/synchronizer-ws-server/index.js.gz +0 -0
  128. package/min/synchronizers/synchronizer-ws-server/with-schemas/index.js +1 -1
  129. package/min/synchronizers/synchronizer-ws-server/with-schemas/index.js.gz +0 -0
  130. package/min/synchronizers/synchronizer-ws-server-durable-object/index.js +1 -1
  131. package/min/synchronizers/synchronizer-ws-server-durable-object/index.js.gz +0 -0
  132. package/min/synchronizers/synchronizer-ws-server-durable-object/with-schemas/index.js +1 -1
  133. package/min/synchronizers/synchronizer-ws-server-durable-object/with-schemas/index.js.gz +0 -0
  134. package/min/synchronizers/synchronizer-ws-server-simple/index.js +1 -1
  135. package/min/synchronizers/synchronizer-ws-server-simple/index.js.gz +0 -0
  136. package/min/synchronizers/synchronizer-ws-server-simple/with-schemas/index.js +1 -1
  137. package/min/synchronizers/synchronizer-ws-server-simple/with-schemas/index.js.gz +0 -0
  138. package/min/synchronizers/with-schemas/index.js +1 -1
  139. package/min/synchronizers/with-schemas/index.js.gz +0 -0
  140. package/min/ui-react-inspector/index.js +1 -1
  141. package/min/ui-react-inspector/index.js.gz +0 -0
  142. package/min/ui-react-inspector/with-schemas/index.js +1 -1
  143. package/min/ui-react-inspector/with-schemas/index.js.gz +0 -0
  144. package/min/ui-solid-inspector/index.js +1 -1
  145. package/min/ui-solid-inspector/index.js.gz +0 -0
  146. package/min/ui-solid-inspector/with-schemas/index.js +1 -1
  147. package/min/ui-solid-inspector/with-schemas/index.js.gz +0 -0
  148. package/min/ui-svelte-inspector/index.js +1 -1
  149. package/min/ui-svelte-inspector/index.js.gz +0 -0
  150. package/min/ui-svelte-inspector/with-schemas/index.js +1 -1
  151. package/min/ui-svelte-inspector/with-schemas/index.js.gz +0 -0
  152. package/min/with-schemas/index.js +1 -1
  153. package/min/with-schemas/index.js.gz +0 -0
  154. package/omni/index.js +606 -179
  155. package/omni/with-schemas/index.js +606 -179
  156. package/package.json +8 -4
  157. package/persisters/index.js +49 -10
  158. package/persisters/persister-automerge/index.js +29 -5
  159. package/persisters/persister-automerge/with-schemas/index.js +29 -5
  160. package/persisters/persister-browser/index.js +29 -5
  161. package/persisters/persister-browser/with-schemas/index.js +29 -5
  162. package/persisters/persister-cr-sqlite-wasm/index.js +29 -5
  163. package/persisters/persister-cr-sqlite-wasm/with-schemas/index.js +29 -5
  164. package/persisters/persister-durable-object-sql-storage/index.js +44 -8
  165. package/persisters/persister-durable-object-sql-storage/with-schemas/index.js +44 -8
  166. package/persisters/persister-durable-object-storage/index.js +31 -5
  167. package/persisters/persister-durable-object-storage/with-schemas/index.js +31 -5
  168. package/persisters/persister-electric-sql/index.js +29 -5
  169. package/persisters/persister-electric-sql/with-schemas/index.js +29 -5
  170. package/persisters/persister-expo-sqlite/index.js +29 -5
  171. package/persisters/persister-expo-sqlite/with-schemas/index.js +29 -5
  172. package/persisters/persister-file/index.js +31 -5
  173. package/persisters/persister-file/with-schemas/index.js +31 -5
  174. package/persisters/persister-indexed-db/index.js +29 -5
  175. package/persisters/persister-indexed-db/with-schemas/index.js +29 -5
  176. package/persisters/persister-libsql/index.js +29 -5
  177. package/persisters/persister-libsql/with-schemas/index.js +29 -5
  178. package/persisters/persister-partykit-client/index.js +31 -5
  179. package/persisters/persister-partykit-client/with-schemas/index.js +31 -5
  180. package/persisters/persister-pglite/index.js +49 -10
  181. package/persisters/persister-pglite/with-schemas/index.js +49 -10
  182. package/persisters/persister-postgres/index.js +49 -10
  183. package/persisters/persister-postgres/with-schemas/index.js +49 -10
  184. package/persisters/persister-powersync/index.js +29 -5
  185. package/persisters/persister-powersync/with-schemas/index.js +29 -5
  186. package/persisters/persister-react-native-mmkv/index.js +31 -5
  187. package/persisters/persister-react-native-mmkv/with-schemas/index.js +31 -5
  188. package/persisters/persister-react-native-sqlite/index.js +29 -5
  189. package/persisters/persister-react-native-sqlite/with-schemas/index.js +29 -5
  190. package/persisters/persister-remote/index.js +31 -5
  191. package/persisters/persister-remote/with-schemas/index.js +31 -5
  192. package/persisters/persister-sqlite-bun/index.js +29 -5
  193. package/persisters/persister-sqlite-bun/with-schemas/index.js +29 -5
  194. package/persisters/persister-sqlite-wasm/index.js +29 -5
  195. package/persisters/persister-sqlite-wasm/with-schemas/index.js +29 -5
  196. package/persisters/persister-sqlite3/index.js +29 -5
  197. package/persisters/persister-sqlite3/with-schemas/index.js +29 -5
  198. package/persisters/persister-yjs/index.js +29 -5
  199. package/persisters/persister-yjs/with-schemas/index.js +29 -5
  200. package/persisters/with-schemas/index.js +49 -10
  201. package/queries/index.js +205 -74
  202. package/queries/with-schemas/index.js +205 -74
  203. package/readme.md +3 -3
  204. package/releases.md +22 -5
  205. package/synchronizers/index.js +31 -5
  206. package/synchronizers/synchronizer-broadcast-channel/index.js +39 -13
  207. package/synchronizers/synchronizer-broadcast-channel/with-schemas/index.js +39 -13
  208. package/synchronizers/synchronizer-local/index.js +31 -5
  209. package/synchronizers/synchronizer-local/with-schemas/index.js +31 -5
  210. package/synchronizers/synchronizer-ws-client/index.js +220 -61
  211. package/synchronizers/synchronizer-ws-client/with-schemas/index.js +220 -61
  212. package/synchronizers/synchronizer-ws-server/index.js +253 -73
  213. package/synchronizers/synchronizer-ws-server/with-schemas/index.js +253 -73
  214. package/synchronizers/synchronizer-ws-server-durable-object/index.js +88 -40
  215. package/synchronizers/synchronizer-ws-server-durable-object/with-schemas/index.js +88 -40
  216. package/synchronizers/synchronizer-ws-server-simple/index.js +184 -60
  217. package/synchronizers/synchronizer-ws-server-simple/with-schemas/index.js +184 -60
  218. package/synchronizers/with-schemas/index.js +31 -5
  219. package/ui-react-inspector/index.js +29 -5
  220. package/ui-react-inspector/with-schemas/index.js +29 -5
  221. package/ui-solid-inspector/index.js +29 -5
  222. package/ui-solid-inspector/with-schemas/index.js +29 -5
  223. package/ui-svelte-inspector/index.js +29 -5
  224. package/ui-svelte-inspector/with-schemas/index.js +29 -5
  225. package/with-schemas/index.js +191 -74
package/releases.md CHANGED
@@ -1,4 +1,25 @@
1
- <link rel="preload" as="image" href="https://beta.tinybase.org/shots/styled-chart-react-demo.png"><link rel="preload" as="image" href="https://beta.tinybase.org/shots/axis-overrides-react-demo.png"><link rel="preload" as="image" href="https://beta.tinybase.org/shots/sortedtableinhtmltable-solid-demo.png"><link rel="preload" as="image" href="https://beta.tinybase.org/shots/inspector-solid-demo.png"><link rel="preload" as="image" href="https://beta.tinybase.org/shots/editablevalueview-solid-demo.png"><link rel="preload" as="image" href="https://beta.tinybase.org/shots/sortedtableinhtmltable-svelte-demo.png"><link rel="preload" as="image" href="https://beta.tinybase.org/shots/inspector-svelte-demo.png"><link rel="preload" as="image" href="https://beta.tinybase.org/shots/editablevalueview-svelte-full-demo.png"><link rel="preload" as="image" href="https://beta.tinybase.org/shots/inspector-react-demo.png"><link rel="preload" as="image" href="https://beta.tinybase.org/partykit.gif"><link rel="preload" as="image" href="https://beta.tinybase.org/shots/sortedtableinhtmltable-react-demo.png"><link rel="preload" as="image" href="https://beta.tinybase.org/shots/car-analysis-demo.png"><link rel="preload" as="image" href="https://beta.tinybase.org/shots/movie-database-demo.png"><p>This is a reverse chronological list of the major TinyBase releases, with highlighted features.</p><hr><h1 id="v9-3">v9.3</h1><p>TinyBase v9.3 lets multiple independently synchronized MergeableStores share one WebSocket connection. It also includes broad reliability and hardening work across core data, synchronization, persistence, UI integrations, packaging, and performance.</p><h2 id="multiple-stores-over-one-websocket">Multiple Stores Over One WebSocket</h2><p>Multiple WebSocket Synchronizers can now share a single physical WebSocket connection (<a href="https://github.com/tinyplex/tinybase/issues/177">#177</a>). This is useful when an application has several independently synchronized <a href="https://beta.tinybase.org/api/mergeable-store/interfaces/mergeable/mergeablestore/"><code>MergeableStore</code></a> instances but needs to limit its connection count.</p><p>Create the WebSocket with the <code>tinybase</code> subprotocol and provide a channel <a href="https://beta.tinybase.org/api/common/type-aliases/identity/id/"><code>Id</code></a> as the third argument to each createWsSynchronizer call:</p>
1
+ <link rel="preload" as="image" href="https://beta.tinybase.org/shots/styled-chart-react-demo.png"><link rel="preload" as="image" href="https://beta.tinybase.org/shots/axis-overrides-react-demo.png"><link rel="preload" as="image" href="https://beta.tinybase.org/shots/sortedtableinhtmltable-solid-demo.png"><link rel="preload" as="image" href="https://beta.tinybase.org/shots/inspector-solid-demo.png"><link rel="preload" as="image" href="https://beta.tinybase.org/shots/editablevalueview-solid-demo.png"><link rel="preload" as="image" href="https://beta.tinybase.org/shots/sortedtableinhtmltable-svelte-demo.png"><link rel="preload" as="image" href="https://beta.tinybase.org/shots/inspector-svelte-demo.png"><link rel="preload" as="image" href="https://beta.tinybase.org/shots/editablevalueview-svelte-full-demo.png"><link rel="preload" as="image" href="https://beta.tinybase.org/shots/inspector-react-demo.png"><link rel="preload" as="image" href="https://beta.tinybase.org/partykit.gif"><link rel="preload" as="image" href="https://beta.tinybase.org/shots/sortedtableinhtmltable-react-demo.png"><link rel="preload" as="image" href="https://beta.tinybase.org/shots/car-analysis-demo.png"><link rel="preload" as="image" href="https://beta.tinybase.org/shots/movie-database-demo.png"><p>This is a reverse chronological list of the major TinyBase releases, with highlighted features.</p><hr><h1 id="v9-4">v9.4</h1><h2 id="selectall"><code>selectAll</code></h2><p><a href="https://beta.tinybase.org/api/queries/interfaces/queries/queries/"><code>Queries</code></a> can now select every <a href="https://beta.tinybase.org/api/store/type-aliases/store/cell/"><code>Cell</code></a> present in a root or joined <a href="https://beta.tinybase.org/api/store/type-aliases/store/row/"><code>Row</code></a> with the <code>selectAll</code> keyword (as requested in issue <a href="https://github.com/tinyplex/tinybase/issues/40">#40</a>). Heterogeneous Rows are supported directly: each result <a href="https://beta.tinybase.org/api/store/type-aliases/store/row/"><code>Row</code></a> contains only its source <a href="https://beta.tinybase.org/api/store/type-aliases/store/row/"><code>Row</code></a>&#x27;s Cells, while the result <a href="https://beta.tinybase.org/api/store/type-aliases/store/table/"><code>Table</code></a>&#x27;s <a href="https://beta.tinybase.org/api/store/type-aliases/store/cell/"><code>Cell</code></a> <a href="https://beta.tinybase.org/api/common/type-aliases/identity/ids/"><code>Ids</code></a> are their reactive union.</p><p>Joined selections retain their <a href="https://beta.tinybase.org/api/store/type-aliases/store/cell/"><code>Cell</code></a> <a href="https://beta.tinybase.org/api/common/type-aliases/identity/ids/"><code>Ids</code></a> by default, or can take a <a href="https://beta.tinybase.org/api/store/type-aliases/store/cell/"><code>Cell</code></a> <a href="https://beta.tinybase.org/api/common/type-aliases/identity/id/"><code>Id</code></a> prefix or mapping callback. Selection clauses are applied in declaration order, and source <a href="https://beta.tinybase.org/api/store/type-aliases/store/cell/"><code>Cell</code></a> <a href="https://beta.tinybase.org/api/common/type-aliases/identity/ids/"><code>Ids</code></a> within a <code>selectAll</code> function call are processed lexically, so collision behavior is deterministic.</p>
2
+
3
+ ```js
4
+ import {createQueries, createStore} from 'tinybase';
5
+
6
+ const selectAllStore = createStore().setTable('pets', {
7
+ fido: {species: 'dog', color: 'brown'},
8
+ felix: {species: 'cat', indoor: true},
9
+ });
10
+ const selectAllQueries = createQueries(selectAllStore);
11
+
12
+ selectAllQueries.setQueryDefinition('allPets', 'pets', ({selectAll}) =>
13
+ selectAll(),
14
+ );
15
+
16
+ console.log(selectAllQueries.getResultRow('allPets', 'fido'));
17
+ // -> {color: 'brown', species: 'dog'}
18
+ console.log(selectAllQueries.getResultRow('allPets', 'felix'));
19
+ // -> {indoor: true, species: 'cat'}
20
+ ```
21
+
22
+ <p>Ungrouped queries iterate only the Cells present in each matched <a href="https://beta.tinybase.org/api/store/type-aliases/store/row/"><code>Row</code></a>. Grouped queries use the table-wide <a href="https://beta.tinybase.org/api/store/type-aliases/store/cell/"><code>Cell</code></a> <a href="https://beta.tinybase.org/api/common/type-aliases/identity/id/"><code>Id</code></a> union and rebuild when that union changes; selected Cells that are not aggregated remain grouping dimensions.</p><hr><h1 id="v9-3">v9.3</h1><p>TinyBase v9.3 lets multiple independently synchronized MergeableStores share one WebSocket connection. It also includes broad reliability and hardening work across core data, synchronization, persistence, UI integrations, packaging, and performance.</p><h2 id="multiple-stores-over-one-websocket">Multiple Stores Over One WebSocket</h2><p>Multiple WebSocket Synchronizers can now share a single physical WebSocket connection (<a href="https://github.com/tinyplex/tinybase/issues/177">#177</a>). This is useful when an application has several independently synchronized <a href="https://beta.tinybase.org/api/mergeable-store/interfaces/mergeable/mergeablestore/"><code>MergeableStore</code></a> instances but needs to limit its connection count.</p><p>Create the WebSocket with the <code>tinybase</code> subprotocol and provide a channel <a href="https://beta.tinybase.org/api/common/type-aliases/identity/id/"><code>Id</code></a> as the third argument to each createWsSynchronizer call:</p>
2
23
 
3
24
  ```js
4
25
  import {createMergeableStore} from 'tinybase';
@@ -44,8 +65,6 @@ npm create tinybase@latest -- --list-options
44
65
  <p>The generated guidance records the chosen language, UI framework, persistence, synchronization, and schema options, identifies the important files, and states the verification expected for that architecture.</p><p>If you&#x27;re a human, you shouldn&#x27;t notice or mind these changes. If you&#x27;re an agent, we hope this makes it easier to find and use TinyBase correctly. Either way, let us know how it goes!</p><hr><h1 id="v9-1">v9.1</h1><h2 id="required-schema-fields">Required Schema Fields</h2><p><a href="https://beta.tinybase.org/guides/schemas/">Schemas</a> can now mark 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> as required without providing a default value (<a href="https://github.com/tinyplex/tinybase/issues/173">#173</a>). Full writes now reject Rows or <a href="https://beta.tinybase.org/api/store/type-aliases/store/values/"><code>Values</code></a> that omit a required non-default field, while preserving the existing rule that a <code>default</code> also implies &#x27;requiredness&#x27; (and will be filled automatically if omitted).</p>
45
66
 
46
67
  ```js
47
- import {createStore} from 'tinybase';
48
-
49
68
  const requiredSchemaStore = createStore().setTablesSchema({
50
69
  pets: {
51
70
  species: {type: 'string', required: true},
@@ -243,8 +262,6 @@ disposeSolid();
243
262
  <p>Read more in the <a href="https://beta.tinybase.org/guides/building-uis-with-solid/">Building UIs With Solid</a> guides and the <a href="https://beta.tinybase.org/api/ui-solid/"><code>ui-solid</code></a> module documentation.</p><p>A huge thanks to <a href="https://github.com/djgrant">Daniel Grant</a> for designing and implementing this new Solid support! Please let us know how it works for you and if you have any feedback or suggestions.</p><h2 id="queries-from-queries"><a href="https://beta.tinybase.org/api/queries/interfaces/queries/queries/"><code>Queries</code></a> From <a href="https://beta.tinybase.org/api/queries/interfaces/queries/queries/"><code>Queries</code></a></h2><p>Also in this release, <a href="https://beta.tinybase.org/guides/using-queries/tinyql/">TinyQL</a> queries can now use the result of another query as their source. This lets you build complex results in small, readable steps - for example, first finding all dogs, and then querying that result to find just the brown ones:</p>
244
263
 
245
264
  ```js
246
- import {createQueries} from 'tinybase';
247
-
248
265
  const queryStore = createStore().setTable('pets', {
249
266
  fido: {species: 'dog', color: 'brown'},
250
267
  felix: {species: 'cat', color: 'black'},
@@ -188,6 +188,8 @@ const tryCatch = async (action, onError) => {
188
188
  onError?.(error);
189
189
  }
190
190
  };
191
+ const tryCatchIgnore = (action, onIgnoredError) =>
192
+ tryCatch(action, (error) => void tryCatch(() => onIgnoredError?.(error)));
191
193
  const tryCatchSync = (action, onError) => {
192
194
  try {
193
195
  return action();
@@ -665,11 +667,35 @@ const createCustomPersister = (
665
667
  initialContent,
666
668
  startSaveFirst = false,
667
669
  ) => {
668
- const [call1, call2] = startSaveFirst
669
- ? [startAutoSave, startAutoLoad]
670
- : [startAutoLoad, startAutoSave];
671
- await call1(initialContent);
672
- await call2(initialContent);
670
+ const [call1, call2, stop1, stop2] = startSaveFirst
671
+ ? [startAutoSave, startAutoLoad, stopAutoSave, stopAutoLoad]
672
+ : [startAutoLoad, startAutoSave, stopAutoLoad, stopAutoSave];
673
+ const start1 = call1(initialContent);
674
+ const generation1 = startSaveFirst
675
+ ? autoSaveGeneration
676
+ : autoLoadGeneration;
677
+ await start1;
678
+ const start2 = call2(initialContent);
679
+ const generation2 = startSaveFirst
680
+ ? autoLoadGeneration
681
+ : autoSaveGeneration;
682
+ try {
683
+ await start2;
684
+ } catch (error) {
685
+ if (
686
+ generation2 ==
687
+ (startSaveFirst ? autoLoadGeneration : autoSaveGeneration)
688
+ ) {
689
+ await tryCatchIgnore(stop2);
690
+ }
691
+ if (
692
+ generation1 ==
693
+ (startSaveFirst ? autoSaveGeneration : autoLoadGeneration)
694
+ ) {
695
+ await tryCatchIgnore(stop1);
696
+ }
697
+ throw error;
698
+ }
673
699
  return persister;
674
700
  };
675
701
  const stopAutoPersisting = async (stopSaveFirst = false) => {
@@ -188,6 +188,8 @@ const tryCatch = async (action, onError) => {
188
188
  onError?.(error);
189
189
  }
190
190
  };
191
+ const tryCatchIgnore = (action, onIgnoredError) =>
192
+ tryCatch(action, (error) => void tryCatch(() => onIgnoredError?.(error)));
191
193
  const tryCatchSync = (action, onError) => {
192
194
  try {
193
195
  return action();
@@ -250,6 +252,14 @@ const isHlc = (hlc, maxLogicalTime) =>
250
252
  hlc == EMPTY_STRING ||
251
253
  (isString(hlc) && test(HLC, hlc) && decodeHlcTime(hlc) <= maxLogicalTime);
252
254
 
255
+ const setNew = (entryOrEntries) =>
256
+ new Set(
257
+ isArray(entryOrEntries) || isUndefined(entryOrEntries)
258
+ ? entryOrEntries
259
+ : [entryOrEntries],
260
+ );
261
+ const setAdd = (set, value) => set?.add(value);
262
+
253
263
  const MAX_PENDING_REQUESTS = 100;
254
264
  const isHash = (hash) =>
255
265
  isNumber(hash) &&
@@ -331,14 +341,6 @@ const getPoolFunctions = () => {
331
341
  ];
332
342
  };
333
343
 
334
- const setNew = (entryOrEntries) =>
335
- new Set(
336
- isArray(entryOrEntries) || isUndefined(entryOrEntries)
337
- ? entryOrEntries
338
- : [entryOrEntries],
339
- );
340
- const setAdd = (set, value) => set?.add(value);
341
-
342
344
  const getWildcardedLeaves = (deepIdSet, path = [EMPTY_STRING]) => {
343
345
  const leaves = [];
344
346
  const deep = (node, p) =>
@@ -763,11 +765,35 @@ const createCustomPersister = (
763
765
  initialContent,
764
766
  startSaveFirst = false,
765
767
  ) => {
766
- const [call1, call2] = startSaveFirst
767
- ? [startAutoSave, startAutoLoad]
768
- : [startAutoLoad, startAutoSave];
769
- await call1(initialContent);
770
- await call2(initialContent);
768
+ const [call1, call2, stop1, stop2] = startSaveFirst
769
+ ? [startAutoSave, startAutoLoad, stopAutoSave, stopAutoLoad]
770
+ : [startAutoLoad, startAutoSave, stopAutoLoad, stopAutoSave];
771
+ const start1 = call1(initialContent);
772
+ const generation1 = startSaveFirst
773
+ ? autoSaveGeneration
774
+ : autoLoadGeneration;
775
+ await start1;
776
+ const start2 = call2(initialContent);
777
+ const generation2 = startSaveFirst
778
+ ? autoLoadGeneration
779
+ : autoSaveGeneration;
780
+ try {
781
+ await start2;
782
+ } catch (error) {
783
+ if (
784
+ generation2 ==
785
+ (startSaveFirst ? autoLoadGeneration : autoSaveGeneration)
786
+ ) {
787
+ await tryCatchIgnore(stop2);
788
+ }
789
+ if (
790
+ generation1 ==
791
+ (startSaveFirst ? autoSaveGeneration : autoLoadGeneration)
792
+ ) {
793
+ await tryCatchIgnore(stop1);
794
+ }
795
+ throw error;
796
+ }
771
797
  return persister;
772
798
  };
773
799
  const stopAutoPersisting = async (stopSaveFirst = false) => {
@@ -188,6 +188,8 @@ const tryCatch = async (action, onError) => {
188
188
  onError?.(error);
189
189
  }
190
190
  };
191
+ const tryCatchIgnore = (action, onIgnoredError) =>
192
+ tryCatch(action, (error) => void tryCatch(() => onIgnoredError?.(error)));
191
193
  const tryCatchSync = (action, onError) => {
192
194
  try {
193
195
  return action();
@@ -250,6 +252,14 @@ const isHlc = (hlc, maxLogicalTime) =>
250
252
  hlc == EMPTY_STRING ||
251
253
  (isString(hlc) && test(HLC, hlc) && decodeHlcTime(hlc) <= maxLogicalTime);
252
254
 
255
+ const setNew = (entryOrEntries) =>
256
+ new Set(
257
+ isArray(entryOrEntries) || isUndefined(entryOrEntries)
258
+ ? entryOrEntries
259
+ : [entryOrEntries],
260
+ );
261
+ const setAdd = (set, value) => set?.add(value);
262
+
253
263
  const MAX_PENDING_REQUESTS = 100;
254
264
  const isHash = (hash) =>
255
265
  isNumber(hash) &&
@@ -331,14 +341,6 @@ const getPoolFunctions = () => {
331
341
  ];
332
342
  };
333
343
 
334
- const setNew = (entryOrEntries) =>
335
- new Set(
336
- isArray(entryOrEntries) || isUndefined(entryOrEntries)
337
- ? entryOrEntries
338
- : [entryOrEntries],
339
- );
340
- const setAdd = (set, value) => set?.add(value);
341
-
342
344
  const getWildcardedLeaves = (deepIdSet, path = [EMPTY_STRING]) => {
343
345
  const leaves = [];
344
346
  const deep = (node, p) =>
@@ -763,11 +765,35 @@ const createCustomPersister = (
763
765
  initialContent,
764
766
  startSaveFirst = false,
765
767
  ) => {
766
- const [call1, call2] = startSaveFirst
767
- ? [startAutoSave, startAutoLoad]
768
- : [startAutoLoad, startAutoSave];
769
- await call1(initialContent);
770
- await call2(initialContent);
768
+ const [call1, call2, stop1, stop2] = startSaveFirst
769
+ ? [startAutoSave, startAutoLoad, stopAutoSave, stopAutoLoad]
770
+ : [startAutoLoad, startAutoSave, stopAutoLoad, stopAutoSave];
771
+ const start1 = call1(initialContent);
772
+ const generation1 = startSaveFirst
773
+ ? autoSaveGeneration
774
+ : autoLoadGeneration;
775
+ await start1;
776
+ const start2 = call2(initialContent);
777
+ const generation2 = startSaveFirst
778
+ ? autoLoadGeneration
779
+ : autoSaveGeneration;
780
+ try {
781
+ await start2;
782
+ } catch (error) {
783
+ if (
784
+ generation2 ==
785
+ (startSaveFirst ? autoLoadGeneration : autoSaveGeneration)
786
+ ) {
787
+ await tryCatchIgnore(stop2);
788
+ }
789
+ if (
790
+ generation1 ==
791
+ (startSaveFirst ? autoSaveGeneration : autoLoadGeneration)
792
+ ) {
793
+ await tryCatchIgnore(stop1);
794
+ }
795
+ throw error;
796
+ }
771
797
  return persister;
772
798
  };
773
799
  const stopAutoPersisting = async (stopSaveFirst = false) => {
@@ -197,6 +197,8 @@ const tryCatch = async (action, onError) => {
197
197
  onError?.(error);
198
198
  }
199
199
  };
200
+ const tryCatchIgnore = (action, onIgnoredError) =>
201
+ tryCatch(action, (error) => void tryCatch(() => onIgnoredError?.(error)));
200
202
  const tryCatchSync = (action, onError) => {
201
203
  try {
202
204
  return action();
@@ -666,11 +668,35 @@ const createCustomPersister = (
666
668
  initialContent,
667
669
  startSaveFirst = false,
668
670
  ) => {
669
- const [call1, call2] = startSaveFirst
670
- ? [startAutoSave, startAutoLoad]
671
- : [startAutoLoad, startAutoSave];
672
- await call1(initialContent);
673
- await call2(initialContent);
671
+ const [call1, call2, stop1, stop2] = startSaveFirst
672
+ ? [startAutoSave, startAutoLoad, stopAutoSave, stopAutoLoad]
673
+ : [startAutoLoad, startAutoSave, stopAutoLoad, stopAutoSave];
674
+ const start1 = call1(initialContent);
675
+ const generation1 = startSaveFirst
676
+ ? autoSaveGeneration
677
+ : autoLoadGeneration;
678
+ await start1;
679
+ const start2 = call2(initialContent);
680
+ const generation2 = startSaveFirst
681
+ ? autoLoadGeneration
682
+ : autoSaveGeneration;
683
+ try {
684
+ await start2;
685
+ } catch (error) {
686
+ if (
687
+ generation2 ==
688
+ (startSaveFirst ? autoLoadGeneration : autoSaveGeneration)
689
+ ) {
690
+ await tryCatchIgnore(stop2);
691
+ }
692
+ if (
693
+ generation1 ==
694
+ (startSaveFirst ? autoSaveGeneration : autoLoadGeneration)
695
+ ) {
696
+ await tryCatchIgnore(stop1);
697
+ }
698
+ throw error;
699
+ }
674
700
  return persister;
675
701
  };
676
702
  const stopAutoPersisting = async (stopSaveFirst = false) => {
@@ -197,6 +197,8 @@ const tryCatch = async (action, onError) => {
197
197
  onError?.(error);
198
198
  }
199
199
  };
200
+ const tryCatchIgnore = (action, onIgnoredError) =>
201
+ tryCatch(action, (error) => void tryCatch(() => onIgnoredError?.(error)));
200
202
  const tryCatchSync = (action, onError) => {
201
203
  try {
202
204
  return action();
@@ -666,11 +668,35 @@ const createCustomPersister = (
666
668
  initialContent,
667
669
  startSaveFirst = false,
668
670
  ) => {
669
- const [call1, call2] = startSaveFirst
670
- ? [startAutoSave, startAutoLoad]
671
- : [startAutoLoad, startAutoSave];
672
- await call1(initialContent);
673
- await call2(initialContent);
671
+ const [call1, call2, stop1, stop2] = startSaveFirst
672
+ ? [startAutoSave, startAutoLoad, stopAutoSave, stopAutoLoad]
673
+ : [startAutoLoad, startAutoSave, stopAutoLoad, stopAutoSave];
674
+ const start1 = call1(initialContent);
675
+ const generation1 = startSaveFirst
676
+ ? autoSaveGeneration
677
+ : autoLoadGeneration;
678
+ await start1;
679
+ const start2 = call2(initialContent);
680
+ const generation2 = startSaveFirst
681
+ ? autoLoadGeneration
682
+ : autoSaveGeneration;
683
+ try {
684
+ await start2;
685
+ } catch (error) {
686
+ if (
687
+ generation2 ==
688
+ (startSaveFirst ? autoLoadGeneration : autoSaveGeneration)
689
+ ) {
690
+ await tryCatchIgnore(stop2);
691
+ }
692
+ if (
693
+ generation1 ==
694
+ (startSaveFirst ? autoSaveGeneration : autoLoadGeneration)
695
+ ) {
696
+ await tryCatchIgnore(stop1);
697
+ }
698
+ throw error;
699
+ }
674
700
  return persister;
675
701
  };
676
702
  const stopAutoPersisting = async (stopSaveFirst = false) => {