tinybase 7.1.0-beta.3 → 7.1.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 (281) hide show
  1. package/@types/schematizers/schematizer-arktype/index.d.ts +114 -0
  2. package/@types/schematizers/schematizer-arktype/with-schemas/index.d.ts +8 -0
  3. package/@types/schematizers/schematizer-effect/index.d.ts +118 -0
  4. package/@types/schematizers/schematizer-effect/with-schemas/index.d.ts +8 -0
  5. package/@types/schematizers/schematizer-yup/index.d.ts +112 -0
  6. package/@types/schematizers/schematizer-yup/with-schemas/index.d.ts +7 -0
  7. package/checkpoints/index.js +2 -2
  8. package/checkpoints/with-schemas/index.js +2 -2
  9. package/index.js +6 -4
  10. package/indexes/index.js +2 -2
  11. package/indexes/with-schemas/index.js +2 -2
  12. package/mergeable-store/index.js +2 -2
  13. package/mergeable-store/with-schemas/index.js +2 -2
  14. package/metrics/index.js +6 -4
  15. package/metrics/with-schemas/index.js +6 -4
  16. package/min/checkpoints/index.js +1 -1
  17. package/min/checkpoints/index.js.gz +0 -0
  18. package/min/checkpoints/with-schemas/index.js +1 -1
  19. package/min/checkpoints/with-schemas/index.js.gz +0 -0
  20. package/min/index.js +1 -1
  21. package/min/index.js.gz +0 -0
  22. package/min/indexes/index.js +1 -1
  23. package/min/indexes/index.js.gz +0 -0
  24. package/min/indexes/with-schemas/index.js +1 -1
  25. package/min/indexes/with-schemas/index.js.gz +0 -0
  26. package/min/mergeable-store/index.js +1 -1
  27. package/min/mergeable-store/index.js.gz +0 -0
  28. package/min/mergeable-store/with-schemas/index.js +1 -1
  29. package/min/mergeable-store/with-schemas/index.js.gz +0 -0
  30. package/min/metrics/index.js +1 -1
  31. package/min/metrics/index.js.gz +0 -0
  32. package/min/metrics/with-schemas/index.js +1 -1
  33. package/min/metrics/with-schemas/index.js.gz +0 -0
  34. package/min/omni/index.js +1 -1
  35. package/min/omni/index.js.gz +0 -0
  36. package/min/omni/with-schemas/index.js +1 -1
  37. package/min/omni/with-schemas/index.js.gz +0 -0
  38. package/min/persisters/index.js +1 -1
  39. package/min/persisters/index.js.gz +0 -0
  40. package/min/persisters/persister-automerge/index.js +1 -1
  41. package/min/persisters/persister-automerge/index.js.gz +0 -0
  42. package/min/persisters/persister-automerge/with-schemas/index.js +1 -1
  43. package/min/persisters/persister-automerge/with-schemas/index.js.gz +0 -0
  44. package/min/persisters/persister-browser/index.js +1 -1
  45. package/min/persisters/persister-browser/index.js.gz +0 -0
  46. package/min/persisters/persister-browser/with-schemas/index.js +1 -1
  47. package/min/persisters/persister-browser/with-schemas/index.js.gz +0 -0
  48. package/min/persisters/persister-cr-sqlite-wasm/index.js +1 -1
  49. package/min/persisters/persister-cr-sqlite-wasm/index.js.gz +0 -0
  50. package/min/persisters/persister-cr-sqlite-wasm/with-schemas/index.js +1 -1
  51. package/min/persisters/persister-cr-sqlite-wasm/with-schemas/index.js.gz +0 -0
  52. package/min/persisters/persister-durable-object-sql-storage/index.js +1 -1
  53. package/min/persisters/persister-durable-object-sql-storage/index.js.gz +0 -0
  54. package/min/persisters/persister-durable-object-sql-storage/with-schemas/index.js +1 -1
  55. package/min/persisters/persister-durable-object-sql-storage/with-schemas/index.js.gz +0 -0
  56. package/min/persisters/persister-durable-object-storage/index.js +1 -1
  57. package/min/persisters/persister-durable-object-storage/index.js.gz +0 -0
  58. package/min/persisters/persister-durable-object-storage/with-schemas/index.js +1 -1
  59. package/min/persisters/persister-durable-object-storage/with-schemas/index.js.gz +0 -0
  60. package/min/persisters/persister-electric-sql/index.js +1 -1
  61. package/min/persisters/persister-electric-sql/index.js.gz +0 -0
  62. package/min/persisters/persister-electric-sql/with-schemas/index.js +1 -1
  63. package/min/persisters/persister-electric-sql/with-schemas/index.js.gz +0 -0
  64. package/min/persisters/persister-expo-sqlite/index.js +1 -1
  65. package/min/persisters/persister-expo-sqlite/index.js.gz +0 -0
  66. package/min/persisters/persister-expo-sqlite/with-schemas/index.js +1 -1
  67. package/min/persisters/persister-expo-sqlite/with-schemas/index.js.gz +0 -0
  68. package/min/persisters/persister-file/index.js +1 -1
  69. package/min/persisters/persister-file/index.js.gz +0 -0
  70. package/min/persisters/persister-file/with-schemas/index.js +1 -1
  71. package/min/persisters/persister-file/with-schemas/index.js.gz +0 -0
  72. package/min/persisters/persister-indexed-db/index.js +1 -1
  73. package/min/persisters/persister-indexed-db/index.js.gz +0 -0
  74. package/min/persisters/persister-indexed-db/with-schemas/index.js +1 -1
  75. package/min/persisters/persister-indexed-db/with-schemas/index.js.gz +0 -0
  76. package/min/persisters/persister-libsql/index.js +1 -1
  77. package/min/persisters/persister-libsql/index.js.gz +0 -0
  78. package/min/persisters/persister-libsql/with-schemas/index.js +1 -1
  79. package/min/persisters/persister-libsql/with-schemas/index.js.gz +0 -0
  80. package/min/persisters/persister-partykit-client/index.js +1 -1
  81. package/min/persisters/persister-partykit-client/index.js.gz +0 -0
  82. package/min/persisters/persister-partykit-client/with-schemas/index.js +1 -1
  83. package/min/persisters/persister-partykit-client/with-schemas/index.js.gz +0 -0
  84. package/min/persisters/persister-pglite/index.js +1 -1
  85. package/min/persisters/persister-pglite/index.js.gz +0 -0
  86. package/min/persisters/persister-pglite/with-schemas/index.js +1 -1
  87. package/min/persisters/persister-pglite/with-schemas/index.js.gz +0 -0
  88. package/min/persisters/persister-postgres/index.js +1 -1
  89. package/min/persisters/persister-postgres/index.js.gz +0 -0
  90. package/min/persisters/persister-postgres/with-schemas/index.js +1 -1
  91. package/min/persisters/persister-postgres/with-schemas/index.js.gz +0 -0
  92. package/min/persisters/persister-powersync/index.js +1 -1
  93. package/min/persisters/persister-powersync/index.js.gz +0 -0
  94. package/min/persisters/persister-powersync/with-schemas/index.js +1 -1
  95. package/min/persisters/persister-powersync/with-schemas/index.js.gz +0 -0
  96. package/min/persisters/persister-react-native-mmkv/index.js +1 -1
  97. package/min/persisters/persister-react-native-mmkv/index.js.gz +0 -0
  98. package/min/persisters/persister-react-native-mmkv/with-schemas/index.js +1 -1
  99. package/min/persisters/persister-react-native-mmkv/with-schemas/index.js.gz +0 -0
  100. package/min/persisters/persister-react-native-sqlite/index.js +1 -1
  101. package/min/persisters/persister-react-native-sqlite/index.js.gz +0 -0
  102. package/min/persisters/persister-react-native-sqlite/with-schemas/index.js +1 -1
  103. package/min/persisters/persister-react-native-sqlite/with-schemas/index.js.gz +0 -0
  104. package/min/persisters/persister-remote/index.js +1 -1
  105. package/min/persisters/persister-remote/index.js.gz +0 -0
  106. package/min/persisters/persister-remote/with-schemas/index.js +1 -1
  107. package/min/persisters/persister-remote/with-schemas/index.js.gz +0 -0
  108. package/min/persisters/persister-sqlite-bun/index.js +1 -1
  109. package/min/persisters/persister-sqlite-bun/index.js.gz +0 -0
  110. package/min/persisters/persister-sqlite-bun/with-schemas/index.js +1 -1
  111. package/min/persisters/persister-sqlite-bun/with-schemas/index.js.gz +0 -0
  112. package/min/persisters/persister-sqlite-wasm/index.js +1 -1
  113. package/min/persisters/persister-sqlite-wasm/index.js.gz +0 -0
  114. package/min/persisters/persister-sqlite-wasm/with-schemas/index.js +1 -1
  115. package/min/persisters/persister-sqlite-wasm/with-schemas/index.js.gz +0 -0
  116. package/min/persisters/persister-sqlite3/index.js +1 -1
  117. package/min/persisters/persister-sqlite3/index.js.gz +0 -0
  118. package/min/persisters/persister-sqlite3/with-schemas/index.js +1 -1
  119. package/min/persisters/persister-sqlite3/with-schemas/index.js.gz +0 -0
  120. package/min/persisters/persister-yjs/index.js +1 -1
  121. package/min/persisters/persister-yjs/index.js.gz +0 -0
  122. package/min/persisters/persister-yjs/with-schemas/index.js +1 -1
  123. package/min/persisters/persister-yjs/with-schemas/index.js.gz +0 -0
  124. package/min/persisters/with-schemas/index.js +1 -1
  125. package/min/persisters/with-schemas/index.js.gz +0 -0
  126. package/min/queries/index.js +1 -1
  127. package/min/queries/index.js.gz +0 -0
  128. package/min/queries/with-schemas/index.js +1 -1
  129. package/min/queries/with-schemas/index.js.gz +0 -0
  130. package/min/relationships/index.js +1 -1
  131. package/min/relationships/index.js.gz +0 -0
  132. package/min/relationships/with-schemas/index.js +1 -1
  133. package/min/relationships/with-schemas/index.js.gz +0 -0
  134. package/min/schematizers/schematizer-arktype/index.js +1 -0
  135. package/min/schematizers/schematizer-arktype/index.js.gz +0 -0
  136. package/min/schematizers/schematizer-arktype/with-schemas/index.js +1 -0
  137. package/min/schematizers/schematizer-arktype/with-schemas/index.js.gz +0 -0
  138. package/min/schematizers/schematizer-effect/index.js +1 -0
  139. package/min/schematizers/schematizer-effect/index.js.gz +0 -0
  140. package/min/schematizers/schematizer-effect/with-schemas/index.js +1 -0
  141. package/min/schematizers/schematizer-effect/with-schemas/index.js.gz +0 -0
  142. package/min/schematizers/schematizer-typebox/index.js +1 -1
  143. package/min/schematizers/schematizer-typebox/index.js.gz +0 -0
  144. package/min/schematizers/schematizer-typebox/with-schemas/index.js +1 -1
  145. package/min/schematizers/schematizer-typebox/with-schemas/index.js.gz +0 -0
  146. package/min/schematizers/schematizer-valibot/index.js +1 -1
  147. package/min/schematizers/schematizer-valibot/index.js.gz +0 -0
  148. package/min/schematizers/schematizer-valibot/with-schemas/index.js +1 -1
  149. package/min/schematizers/schematizer-valibot/with-schemas/index.js.gz +0 -0
  150. package/min/schematizers/schematizer-yup/index.js +1 -0
  151. package/min/schematizers/schematizer-yup/index.js.gz +0 -0
  152. package/min/schematizers/schematizer-yup/with-schemas/index.js +1 -0
  153. package/min/schematizers/schematizer-yup/with-schemas/index.js.gz +0 -0
  154. package/min/store/index.js +1 -1
  155. package/min/store/index.js.gz +0 -0
  156. package/min/store/with-schemas/index.js +1 -1
  157. package/min/store/with-schemas/index.js.gz +0 -0
  158. package/min/synchronizers/index.js +1 -1
  159. package/min/synchronizers/index.js.gz +0 -0
  160. package/min/synchronizers/synchronizer-broadcast-channel/index.js +1 -1
  161. package/min/synchronizers/synchronizer-broadcast-channel/index.js.gz +0 -0
  162. package/min/synchronizers/synchronizer-broadcast-channel/with-schemas/index.js +1 -1
  163. package/min/synchronizers/synchronizer-broadcast-channel/with-schemas/index.js.gz +0 -0
  164. package/min/synchronizers/synchronizer-local/index.js +1 -1
  165. package/min/synchronizers/synchronizer-local/index.js.gz +0 -0
  166. package/min/synchronizers/synchronizer-local/with-schemas/index.js +1 -1
  167. package/min/synchronizers/synchronizer-local/with-schemas/index.js.gz +0 -0
  168. package/min/synchronizers/synchronizer-ws-client/index.js +1 -1
  169. package/min/synchronizers/synchronizer-ws-client/index.js.gz +0 -0
  170. package/min/synchronizers/synchronizer-ws-client/with-schemas/index.js +1 -1
  171. package/min/synchronizers/synchronizer-ws-client/with-schemas/index.js.gz +0 -0
  172. package/min/synchronizers/synchronizer-ws-server/index.js +1 -1
  173. package/min/synchronizers/synchronizer-ws-server/index.js.gz +0 -0
  174. package/min/synchronizers/synchronizer-ws-server/with-schemas/index.js +1 -1
  175. package/min/synchronizers/synchronizer-ws-server/with-schemas/index.js.gz +0 -0
  176. package/min/synchronizers/synchronizer-ws-server-durable-object/index.js +1 -1
  177. package/min/synchronizers/synchronizer-ws-server-durable-object/index.js.gz +0 -0
  178. package/min/synchronizers/synchronizer-ws-server-durable-object/with-schemas/index.js +1 -1
  179. package/min/synchronizers/synchronizer-ws-server-durable-object/with-schemas/index.js.gz +0 -0
  180. package/min/synchronizers/synchronizer-ws-server-simple/index.js +1 -1
  181. package/min/synchronizers/synchronizer-ws-server-simple/index.js.gz +0 -0
  182. package/min/synchronizers/synchronizer-ws-server-simple/with-schemas/index.js +1 -1
  183. package/min/synchronizers/synchronizer-ws-server-simple/with-schemas/index.js.gz +0 -0
  184. package/min/synchronizers/with-schemas/index.js +1 -1
  185. package/min/synchronizers/with-schemas/index.js.gz +0 -0
  186. package/min/ui-react-dom/index.js +1 -1
  187. package/min/ui-react-dom/index.js.gz +0 -0
  188. package/min/ui-react-dom/with-schemas/index.js +1 -1
  189. package/min/ui-react-dom/with-schemas/index.js.gz +0 -0
  190. package/min/ui-react-inspector/index.js +1 -1
  191. package/min/ui-react-inspector/index.js.gz +0 -0
  192. package/min/ui-react-inspector/with-schemas/index.js +1 -1
  193. package/min/ui-react-inspector/with-schemas/index.js.gz +0 -0
  194. package/min/with-schemas/index.js +1 -1
  195. package/min/with-schemas/index.js.gz +0 -0
  196. package/omni/index.js +19 -16
  197. package/omni/with-schemas/index.js +19 -16
  198. package/package.json +118 -2
  199. package/persisters/index.js +6 -4
  200. package/persisters/persister-automerge/index.js +2 -2
  201. package/persisters/persister-automerge/with-schemas/index.js +2 -2
  202. package/persisters/persister-browser/index.js +3 -3
  203. package/persisters/persister-browser/with-schemas/index.js +3 -3
  204. package/persisters/persister-cr-sqlite-wasm/index.js +6 -4
  205. package/persisters/persister-cr-sqlite-wasm/with-schemas/index.js +6 -4
  206. package/persisters/persister-durable-object-sql-storage/index.js +6 -4
  207. package/persisters/persister-durable-object-sql-storage/with-schemas/index.js +6 -4
  208. package/persisters/persister-durable-object-storage/index.js +3 -3
  209. package/persisters/persister-durable-object-storage/with-schemas/index.js +3 -3
  210. package/persisters/persister-electric-sql/index.js +6 -4
  211. package/persisters/persister-electric-sql/with-schemas/index.js +6 -4
  212. package/persisters/persister-expo-sqlite/index.js +6 -4
  213. package/persisters/persister-expo-sqlite/with-schemas/index.js +6 -4
  214. package/persisters/persister-file/index.js +3 -3
  215. package/persisters/persister-file/with-schemas/index.js +3 -3
  216. package/persisters/persister-indexed-db/index.js +2 -2
  217. package/persisters/persister-indexed-db/with-schemas/index.js +2 -2
  218. package/persisters/persister-libsql/index.js +6 -4
  219. package/persisters/persister-libsql/with-schemas/index.js +6 -4
  220. package/persisters/persister-partykit-client/index.js +2 -2
  221. package/persisters/persister-partykit-client/with-schemas/index.js +2 -2
  222. package/persisters/persister-pglite/index.js +3 -3
  223. package/persisters/persister-pglite/with-schemas/index.js +3 -3
  224. package/persisters/persister-postgres/index.js +3 -3
  225. package/persisters/persister-postgres/with-schemas/index.js +3 -3
  226. package/persisters/persister-powersync/index.js +6 -4
  227. package/persisters/persister-powersync/with-schemas/index.js +6 -4
  228. package/persisters/persister-react-native-mmkv/index.js +4 -4
  229. package/persisters/persister-react-native-mmkv/with-schemas/index.js +4 -4
  230. package/persisters/persister-react-native-sqlite/index.js +6 -4
  231. package/persisters/persister-react-native-sqlite/with-schemas/index.js +6 -4
  232. package/persisters/persister-remote/index.js +2 -2
  233. package/persisters/persister-remote/with-schemas/index.js +2 -2
  234. package/persisters/persister-sqlite-bun/index.js +6 -4
  235. package/persisters/persister-sqlite-bun/with-schemas/index.js +6 -4
  236. package/persisters/persister-sqlite-wasm/index.js +6 -4
  237. package/persisters/persister-sqlite-wasm/with-schemas/index.js +6 -4
  238. package/persisters/persister-sqlite3/index.js +6 -4
  239. package/persisters/persister-sqlite3/with-schemas/index.js +6 -4
  240. package/persisters/persister-yjs/index.js +2 -2
  241. package/persisters/persister-yjs/with-schemas/index.js +2 -2
  242. package/persisters/with-schemas/index.js +6 -4
  243. package/queries/index.js +1 -1
  244. package/queries/with-schemas/index.js +1 -1
  245. package/readme.md +3 -3
  246. package/relationships/index.js +2 -2
  247. package/relationships/with-schemas/index.js +2 -2
  248. package/releases.md +1 -1
  249. package/schematizers/schematizer-arktype/index.js +163 -0
  250. package/schematizers/schematizer-arktype/with-schemas/index.js +163 -0
  251. package/schematizers/schematizer-effect/index.js +137 -0
  252. package/schematizers/schematizer-effect/with-schemas/index.js +137 -0
  253. package/schematizers/schematizer-typebox/index.js +3 -2
  254. package/schematizers/schematizer-typebox/with-schemas/index.js +3 -2
  255. package/schematizers/schematizer-valibot/index.js +4 -4
  256. package/schematizers/schematizer-valibot/with-schemas/index.js +4 -4
  257. package/schematizers/schematizer-yup/index.js +100 -0
  258. package/schematizers/schematizer-yup/with-schemas/index.js +100 -0
  259. package/schematizers/schematizer-zod/index.js +2 -2
  260. package/schematizers/schematizer-zod/with-schemas/index.js +2 -2
  261. package/store/index.js +2 -2
  262. package/store/with-schemas/index.js +2 -2
  263. package/synchronizers/index.js +2 -2
  264. package/synchronizers/synchronizer-broadcast-channel/index.js +2 -2
  265. package/synchronizers/synchronizer-broadcast-channel/with-schemas/index.js +2 -2
  266. package/synchronizers/synchronizer-local/index.js +2 -2
  267. package/synchronizers/synchronizer-local/with-schemas/index.js +2 -2
  268. package/synchronizers/synchronizer-ws-client/index.js +3 -3
  269. package/synchronizers/synchronizer-ws-client/with-schemas/index.js +3 -3
  270. package/synchronizers/synchronizer-ws-server/index.js +3 -3
  271. package/synchronizers/synchronizer-ws-server/with-schemas/index.js +3 -3
  272. package/synchronizers/synchronizer-ws-server-durable-object/index.js +3 -3
  273. package/synchronizers/synchronizer-ws-server-durable-object/with-schemas/index.js +3 -3
  274. package/synchronizers/synchronizer-ws-server-simple/index.js +1 -1
  275. package/synchronizers/synchronizer-ws-server-simple/with-schemas/index.js +1 -1
  276. package/synchronizers/with-schemas/index.js +2 -2
  277. package/ui-react-dom/index.js +11 -8
  278. package/ui-react-dom/with-schemas/index.js +11 -8
  279. package/ui-react-inspector/index.js +14 -11
  280. package/ui-react-inspector/with-schemas/index.js +14 -11
  281. package/with-schemas/index.js +6 -4
@@ -22,6 +22,8 @@ const stopInterval = clearInterval;
22
22
  const isNullish = (thing) => thing == null;
23
23
  const isUndefined = (thing) => thing === void 0;
24
24
  const isNull = (thing) => thing === null;
25
+ const isTrue = (thing) => thing === true;
26
+ const isFalse = (thing) => thing === false;
25
27
  const ifNotNullish = getIfNotFunction(isNullish);
26
28
  const ifNotUndefined = getIfNotFunction(isUndefined);
27
29
  const isString = (thing) => getTypeOf(thing) == STRING;
@@ -141,7 +143,7 @@ const mapForEach = (map, cb) =>
141
143
  const mapMap = (coll, cb) =>
142
144
  arrayMap([...(coll?.entries() ?? [])], ([key, value]) => cb(value, key));
143
145
  const mapSet = (map, key, value) =>
144
- value === void 0 ? (collDel(map, key), map) : map?.set(key, value);
146
+ isUndefined(value) ? (collDel(map, key), map) : map?.set(key, value);
145
147
  const mapEnsure = (map, key, getDefaultValue, hadExistingValue) => {
146
148
  if (!collHas(map, key)) {
147
149
  mapSet(map, key, getDefaultValue());
@@ -301,7 +303,7 @@ const getConfigStructures = (configOrStoreTableName) => {
301
303
  const jsonString = JSON.stringify;
302
304
  const jsonParse = JSON.parse;
303
305
  const jsonStringWithUndefined = (obj) =>
304
- jsonString(obj, (_key, value) => (value === void 0 ? UNDEFINED : value));
306
+ jsonString(obj, (_key, value) => (isUndefined(value) ? UNDEFINED : value));
305
307
  const jsonParseWithUndefined = (str) =>
306
308
  jsonParse(str, (_key, value) => (value === UNDEFINED ? void 0 : value));
307
309
 
@@ -324,7 +326,7 @@ const getWildcardedLeaves = (deepIdSet, path = [EMPTY_STRING]) => {
324
326
  const deep = (node, p) =>
325
327
  p == size(path)
326
328
  ? arrayPush(leaves, node)
327
- : path[p] === null
329
+ : isNull(path[p])
328
330
  ? collForEach(node, (node2) => deep(node2, p + 1))
329
331
  : arrayForEach([path[p], null], (id) => deep(mapGet(node, id), p + 1));
330
332
  deep(deepIdSet, 0);
@@ -1172,7 +1174,7 @@ const createCustomSqlitePersister = (
1172
1174
  EMPTY_STRING,
1173
1175
  upsert,
1174
1176
  (cellOrValue) =>
1175
- cellOrValue === true ? 1 : cellOrValue === false ? 0 : cellOrValue,
1177
+ isTrue(cellOrValue) ? 1 : isFalse(cellOrValue) ? 0 : cellOrValue,
1176
1178
  void 0,
1177
1179
  );
1178
1180
  };
@@ -22,6 +22,8 @@ const stopInterval = clearInterval;
22
22
  const isNullish = (thing) => thing == null;
23
23
  const isUndefined = (thing) => thing === void 0;
24
24
  const isNull = (thing) => thing === null;
25
+ const isTrue = (thing) => thing === true;
26
+ const isFalse = (thing) => thing === false;
25
27
  const ifNotNullish = getIfNotFunction(isNullish);
26
28
  const ifNotUndefined = getIfNotFunction(isUndefined);
27
29
  const isString = (thing) => getTypeOf(thing) == STRING;
@@ -141,7 +143,7 @@ const mapForEach = (map, cb) =>
141
143
  const mapMap = (coll, cb) =>
142
144
  arrayMap([...(coll?.entries() ?? [])], ([key, value]) => cb(value, key));
143
145
  const mapSet = (map, key, value) =>
144
- value === void 0 ? (collDel(map, key), map) : map?.set(key, value);
146
+ isUndefined(value) ? (collDel(map, key), map) : map?.set(key, value);
145
147
  const mapEnsure = (map, key, getDefaultValue, hadExistingValue) => {
146
148
  if (!collHas(map, key)) {
147
149
  mapSet(map, key, getDefaultValue());
@@ -301,7 +303,7 @@ const getConfigStructures = (configOrStoreTableName) => {
301
303
  const jsonString = JSON.stringify;
302
304
  const jsonParse = JSON.parse;
303
305
  const jsonStringWithUndefined = (obj) =>
304
- jsonString(obj, (_key, value) => (value === void 0 ? UNDEFINED : value));
306
+ jsonString(obj, (_key, value) => (isUndefined(value) ? UNDEFINED : value));
305
307
  const jsonParseWithUndefined = (str) =>
306
308
  jsonParse(str, (_key, value) => (value === UNDEFINED ? void 0 : value));
307
309
 
@@ -324,7 +326,7 @@ const getWildcardedLeaves = (deepIdSet, path = [EMPTY_STRING]) => {
324
326
  const deep = (node, p) =>
325
327
  p == size(path)
326
328
  ? arrayPush(leaves, node)
327
- : path[p] === null
329
+ : isNull(path[p])
328
330
  ? collForEach(node, (node2) => deep(node2, p + 1))
329
331
  : arrayForEach([path[p], null], (id) => deep(mapGet(node, id), p + 1));
330
332
  deep(deepIdSet, 0);
@@ -1172,7 +1174,7 @@ const createCustomSqlitePersister = (
1172
1174
  EMPTY_STRING,
1173
1175
  upsert,
1174
1176
  (cellOrValue) =>
1175
- cellOrValue === true ? 1 : cellOrValue === false ? 0 : cellOrValue,
1177
+ isTrue(cellOrValue) ? 1 : isFalse(cellOrValue) ? 0 : cellOrValue,
1176
1178
  void 0,
1177
1179
  );
1178
1180
  };
@@ -76,7 +76,7 @@ const mapGet = (map, key) => map?.get(key);
76
76
  const mapForEach = (map, cb) =>
77
77
  collForEach(map, (value, key) => cb(key, value));
78
78
  const mapSet = (map, key, value) =>
79
- value === void 0 ? (collDel(map, key), map) : map?.set(key, value);
79
+ isUndefined(value) ? (collDel(map, key), map) : map?.set(key, value);
80
80
  const mapEnsure = (map, key, getDefaultValue, hadExistingValue) => {
81
81
  if (!collHas(map, key)) {
82
82
  mapSet(map, key, getDefaultValue());
@@ -134,7 +134,7 @@ const getWildcardedLeaves = (deepIdSet, path = [EMPTY_STRING]) => {
134
134
  const deep = (node, p) =>
135
135
  p == size(path)
136
136
  ? arrayPush(leaves, node)
137
- : path[p] === null
137
+ : isNull(path[p])
138
138
  ? collForEach(node, (node2) => deep(node2, p + 1))
139
139
  : arrayForEach([path[p], null], (id) => deep(mapGet(node, id), p + 1));
140
140
  deep(deepIdSet, 0);
@@ -76,7 +76,7 @@ const mapGet = (map, key) => map?.get(key);
76
76
  const mapForEach = (map, cb) =>
77
77
  collForEach(map, (value, key) => cb(key, value));
78
78
  const mapSet = (map, key, value) =>
79
- value === void 0 ? (collDel(map, key), map) : map?.set(key, value);
79
+ isUndefined(value) ? (collDel(map, key), map) : map?.set(key, value);
80
80
  const mapEnsure = (map, key, getDefaultValue, hadExistingValue) => {
81
81
  if (!collHas(map, key)) {
82
82
  mapSet(map, key, getDefaultValue());
@@ -134,7 +134,7 @@ const getWildcardedLeaves = (deepIdSet, path = [EMPTY_STRING]) => {
134
134
  const deep = (node, p) =>
135
135
  p == size(path)
136
136
  ? arrayPush(leaves, node)
137
- : path[p] === null
137
+ : isNull(path[p])
138
138
  ? collForEach(node, (node2) => deep(node2, p + 1))
139
139
  : arrayForEach([path[p], null], (id) => deep(mapGet(node, id), p + 1));
140
140
  deep(deepIdSet, 0);
@@ -24,6 +24,8 @@ const stopInterval = clearInterval;
24
24
  const isNullish = (thing) => thing == null;
25
25
  const isUndefined = (thing) => thing === void 0;
26
26
  const isNull = (thing) => thing === null;
27
+ const isTrue = (thing) => thing === true;
28
+ const isFalse = (thing) => thing === false;
27
29
  const ifNotNullish = getIfNotFunction(isNullish);
28
30
  const ifNotUndefined = getIfNotFunction(isUndefined);
29
31
  const isString = (thing) => getTypeOf(thing) == STRING;
@@ -99,7 +101,7 @@ const mapForEach = (map, cb) =>
99
101
  const mapMap = (coll, cb) =>
100
102
  arrayMap([...(coll?.entries() ?? [])], ([key, value]) => cb(value, key));
101
103
  const mapSet = (map, key, value) =>
102
- value === void 0 ? (collDel(map, key), map) : map?.set(key, value);
104
+ isUndefined(value) ? (collDel(map, key), map) : map?.set(key, value);
103
105
  const mapEnsure = (map, key, getDefaultValue, hadExistingValue) => {
104
106
  if (!collHas(map, key)) {
105
107
  mapSet(map, key, getDefaultValue());
@@ -157,7 +159,7 @@ const getWildcardedLeaves = (deepIdSet, path = [EMPTY_STRING]) => {
157
159
  const deep = (node, p) =>
158
160
  p == size(path)
159
161
  ? arrayPush(leaves, node)
160
- : path[p] === null
162
+ : isNull(path[p])
161
163
  ? collForEach(node, (node2) => deep(node2, p + 1))
162
164
  : arrayForEach([path[p], null], (id) => deep(mapGet(node, id), p + 1));
163
165
  deep(deepIdSet, 0);
@@ -475,7 +477,7 @@ const createCustomPersister = (
475
477
  const jsonString = JSON.stringify;
476
478
  const jsonParse = JSON.parse;
477
479
  const jsonStringWithUndefined = (obj) =>
478
- jsonString(obj, (_key, value) => (value === void 0 ? UNDEFINED : value));
480
+ jsonString(obj, (_key, value) => (isUndefined(value) ? UNDEFINED : value));
479
481
  const jsonParseWithUndefined = (str) =>
480
482
  jsonParse(str, (_key, value) => (value === UNDEFINED ? void 0 : value));
481
483
 
@@ -1360,7 +1362,7 @@ const createCustomSqlitePersister = (
1360
1362
  EMPTY_STRING,
1361
1363
  upsert,
1362
1364
  (cellOrValue) =>
1363
- cellOrValue === true ? 1 : cellOrValue === false ? 0 : cellOrValue,
1365
+ isTrue(cellOrValue) ? 1 : isFalse(cellOrValue) ? 0 : cellOrValue,
1364
1366
  void 0,
1365
1367
  );
1366
1368
  };
package/queries/index.js CHANGED
@@ -72,7 +72,7 @@ const mapGet = (map, key) => map?.get(key);
72
72
  const mapForEach = (map, cb) =>
73
73
  collForEach(map, (value, key) => cb(key, value));
74
74
  const mapSet = (map, key, value) =>
75
- value === void 0 ? (collDel(map, key), map) : map?.set(key, value);
75
+ isUndefined(value) ? (collDel(map, key), map) : map?.set(key, value);
76
76
  const mapEnsure = (map, key, getDefaultValue, hadExistingValue) => {
77
77
  if (!collHas(map, key)) {
78
78
  mapSet(map, key, getDefaultValue());
@@ -72,7 +72,7 @@ const mapGet = (map, key) => map?.get(key);
72
72
  const mapForEach = (map, cb) =>
73
73
  collForEach(map, (value, key) => cb(key, value));
74
74
  const mapSet = (map, key, value) =>
75
- value === void 0 ? (collDel(map, key), map) : map?.set(key, value);
75
+ isUndefined(value) ? (collDel(map, key), map) : map?.set(key, value);
76
76
  const mapEnsure = (map, key, getDefaultValue, hadExistingValue) => {
77
77
  if (!collHas(map, key)) {
78
78
  mapSet(map, key, getDefaultValue());
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/browser.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://beta.tinybase.org/typebox.svg?asImg"><link rel="preload" as="image" href="https://beta.tinybase.org/valibot.svg?asImg"><link rel="preload" as="image" href="https://beta.tinybase.org/zod.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=Vitest&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/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://synclets.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/#v7-1"><em>NEW!</em> v7.1 release</a></p><p><span id="one-with">&quot;The one with Schematizers!&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/the-essentials/creating-stores/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/api/persister-browser"><img src="https://beta.tinybase.org/browser.svg?asImg" width="48"> OPFS</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><div><a href="https://beta.tinybase.org/api/schematizer-typebox/functions/creation/createtypeboxschematizer"><img src="https://beta.tinybase.org/typebox.svg?asImg" width="48"> TypeBox</a></div><div><a href="https://beta.tinybase.org/api/schematizer-valibot/functions/creation/createvalibotschematizer"><img src="https://beta.tinybase.org/valibot.svg?asImg" width="48"> Valibot</a></div><div><a href="https://beta.tinybase.org/api/schematizer-zod/functions/creation/createzodschematizer"><img src="https://beta.tinybase.org/zod.svg?asImg" width="48"> Zod</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"><p><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></p><p><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></p><p><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></p><p><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></p><br><p><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></p><p><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></p><p><a href="#well-tested-and-documented"><img src="https://img.shields.io/badge/Tests-100%25-green?style=for-the-badge&amp;logo=Vitest&amp;logoColor=%23fff&amp;color=%23333&amp;labelColor=%2387c305"></a></p><p><a href="https://www.npmjs.com/package/tinybase/v/7.1.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></p></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/the-essentials/creating-stores/store/"><code>Store</code></a> requires just a simple call to the <a href="https://beta.tinybase.org/api/the-essentials/creating-stores/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/browser.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://beta.tinybase.org/typebox.svg?asImg"><link rel="preload" as="image" href="https://beta.tinybase.org/valibot.svg?asImg"><link rel="preload" as="image" href="https://beta.tinybase.org/zod.svg?asImg"><link rel="preload" as="image" href="https://beta.tinybase.org/arktype.svg?asImg"><link rel="preload" as="image" href="https://beta.tinybase.org/yup.svg?asImg"><link rel="preload" as="image" href="https://beta.tinybase.org/effect.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=Vitest&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/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://synclets.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/#v7-1"><em>NEW!</em> v7.1 release</a></p><p><span id="one-with">&quot;The one with Schematizers!&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/the-essentials/creating-stores/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/api/persister-browser"><img src="https://beta.tinybase.org/browser.svg?asImg" width="48"> OPFS</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><div><a href="https://beta.tinybase.org/api/schematizer-typebox/functions/creation/createtypeboxschematizer"><img src="https://beta.tinybase.org/typebox.svg?asImg" width="48"> TypeBox</a></div><div><a href="https://beta.tinybase.org/api/schematizer-valibot/functions/creation/createvalibotschematizer"><img src="https://beta.tinybase.org/valibot.svg?asImg" width="48"> Valibot</a></div><div><a href="https://beta.tinybase.org/api/schematizer-zod/functions/creation/createzodschematizer"><img src="https://beta.tinybase.org/zod.svg?asImg" width="48"> Zod</a></div><div><a href="https://beta.tinybase.org/api/schematizer-arktype/functions/creation/createarktypeschematizer"><img src="https://beta.tinybase.org/arktype.svg?asImg" width="48"> ArkType</a></div><div><a href="https://beta.tinybase.org/api/schematizer-yup/functions/creation/createyupschematizer"><img src="https://beta.tinybase.org/yup.svg?asImg" width="48"> Yup</a></div><div><a href="https://beta.tinybase.org/api/schematizer-effect/functions/creation/createeffectschematizer"><img src="https://beta.tinybase.org/effect.svg?asImg" width="48"> Effect</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"><p><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></p><p><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></p><p><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></p><p><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></p><br><p><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></p><p><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></p><p><a href="#well-tested-and-documented"><img src="https://img.shields.io/badge/Tests-100%25-green?style=for-the-badge&amp;logo=Vitest&amp;logoColor=%23fff&amp;color=%23333&amp;labelColor=%2387c305"></a></p><p><a href="https://www.npmjs.com/package/tinybase/v/7.1.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></p></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/the-essentials/creating-stores/store/"><code>Store</code></a> requires just a simple call to the <a href="https://beta.tinybase.org/api/the-essentials/creating-stores/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';
@@ -60,7 +60,7 @@ console.log(app.innerHTML);
60
60
  root.unmount();
61
61
  ```
62
62
 
63
- <section><h2 id="pre-built-reactive-components">Pre-built reactive components.</h2><p>The <a href="https://beta.tinybase.org/api/ui-react/"><code>ui-react</code></a> module provides bare React components that let you build up a fully reactive user interface based on a <a href="https://beta.tinybase.org/api/the-essentials/creating-stores/store/"><code>Store</code></a>.</p><p>For web applications in particular, the new <a href="https://beta.tinybase.org/api/ui-react-dom/"><code>ui-react-dom</code></a> module provides pre-built components for tabular display of your data, with lots of customization and interactivity options.</p><p>Try them out in the <a href="https://beta.tinybase.org/demos/ui-components/">UI Components</a> demos, and read more about the underlying <a href="https://beta.tinybase.org/api/ui-react/"><code>ui-react</code></a> module in the <a href="https://beta.tinybase.org/guides/building-uis/">Building UIs</a> guides.</p></section><img src="https://beta.tinybase.org/ui-react-dom.webp"><section><h2 id="an-inspector-for-your-data">An inspector for your data.</h2><p>If you are building a web application, the new <a href="https://beta.tinybase.org/api/the-essentials/using-react/inspector/"><code>Inspector</code></a> component lets you overlay a view of the data in your <a href="https://beta.tinybase.org/api/the-essentials/creating-stores/store/"><code>Store</code></a>, <a href="https://beta.tinybase.org/api/indexes/interfaces/indexes/indexes/"><code>Indexes</code></a>, <a href="https://beta.tinybase.org/api/relationships/interfaces/relationships/relationships/"><code>Relationships</code></a>, and so on. You can even edit the data in place and see it update in your app immediately.</p><p>Read more about this powerful new tool in the <a href="https://beta.tinybase.org/guides/inspecting-data/">Inspecting Data</a> guide.</p></section><img src="https://beta.tinybase.org/inspector.webp"><section><h2 id="apply-schemas-to-tables-values">Apply schemas to tables &amp; values.</h2><p>Want clean data? You can add a <a href="https://beta.tinybase.org/api/store/type-aliases/schema/valuesschema/"><code>ValuesSchema</code></a> or a <a href="https://beta.tinybase.org/api/store/type-aliases/schema/tablesschema/"><code>TablesSchema</code></a> to a <a href="https://beta.tinybase.org/api/the-essentials/creating-stores/store/"><code>Store</code></a> to ensure that they are always what you expect by constraining types, and providing defaults. There are even TypeScript definitions that infer API types from the data schemas you apply.</p><p>And our &#x27;schematizer&#x27; modules let you convert schemas from libraries like Zod, TypeBox, and Valibot into TinyBase at runtime.</p><p>Read more about schemas in the <a href="https://beta.tinybase.org/guides/schemas/">Schemas</a> guide.</p></section>
63
+ <section><h2 id="pre-built-reactive-components">Pre-built reactive components.</h2><p>The <a href="https://beta.tinybase.org/api/ui-react/"><code>ui-react</code></a> module provides bare React components that let you build up a fully reactive user interface based on a <a href="https://beta.tinybase.org/api/the-essentials/creating-stores/store/"><code>Store</code></a>.</p><p>For web applications in particular, the new <a href="https://beta.tinybase.org/api/ui-react-dom/"><code>ui-react-dom</code></a> module provides pre-built components for tabular display of your data, with lots of customization and interactivity options.</p><p>Try them out in the <a href="https://beta.tinybase.org/demos/ui-components/">UI Components</a> demos, and read more about the underlying <a href="https://beta.tinybase.org/api/ui-react/"><code>ui-react</code></a> module in the <a href="https://beta.tinybase.org/guides/building-uis/">Building UIs</a> guides.</p></section><img src="https://beta.tinybase.org/ui-react-dom.webp"><section><h2 id="an-inspector-for-your-data">An inspector for your data.</h2><p>If you are building a web application, the new <a href="https://beta.tinybase.org/api/the-essentials/using-react/inspector/"><code>Inspector</code></a> component lets you overlay a view of the data in your <a href="https://beta.tinybase.org/api/the-essentials/creating-stores/store/"><code>Store</code></a>, <a href="https://beta.tinybase.org/api/indexes/interfaces/indexes/indexes/"><code>Indexes</code></a>, <a href="https://beta.tinybase.org/api/relationships/interfaces/relationships/relationships/"><code>Relationships</code></a>, and so on. You can even edit the data in place and see it update in your app immediately.</p><p>Read more about this powerful new tool in the <a href="https://beta.tinybase.org/guides/inspecting-data/">Inspecting Data</a> guide.</p></section><img src="https://beta.tinybase.org/inspector.webp"><section><h2 id="apply-schemas-to-tables-values">Apply schemas to tables &amp; values.</h2><p>Want clean data? You can add a <a href="https://beta.tinybase.org/api/store/type-aliases/schema/valuesschema/"><code>ValuesSchema</code></a> or a <a href="https://beta.tinybase.org/api/store/type-aliases/schema/tablesschema/"><code>TablesSchema</code></a> to a <a href="https://beta.tinybase.org/api/the-essentials/creating-stores/store/"><code>Store</code></a> to ensure that they are always what you expect by constraining types, and providing defaults. There are even TypeScript definitions that infer API types from the data schemas you apply.</p><p>And our &#x27;schematizer&#x27; modules let you convert schemas from libraries like Zod, TypeBox, Valibot, ArkType, Yup, and Effect Schema into TinyBase at runtime.</p><p>Read more about schemas in the <a href="https://beta.tinybase.org/guides/schemas/">Schemas</a> guide.</p></section>
64
64
 
65
65
  ```js
66
66
  store.setTablesSchema({
@@ -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.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>3.7kB</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>54.6kB</td></tr><tr><th class="right">tinybase (complete)</th><td>11.8kB</td><td>123.4kB</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>3.7kB</td><td>32.8kB</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,341</td><td>2,341</td><td>100.0%</td></tr><tr><th class="right">Statements</th><td>2,534</td><td>2,534</td><td>100.0%</td></tr><tr><th class="right">Functions</th><td>1,010</td><td>1,010</td><td>100.0%</td></tr><tr><th class="right">Branches</th><td>892</td><td>892</td><td>100.0%</td></tr><tr><th class="right">Tests</th><td colspan="3">7,142</td></tr><tr><th class="right">Assertions</th><td colspan="3">32,013</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/the-essentials/creating-stores/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><a href="https://synclets.org" target="_blank"><img src="https://synclets.org/favicon.svg?asImg" width="48"><br><b>Synclets</b></a><br>An open, storage-agnostic, sync engine development kit.</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>3.7kB</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>54.6kB</td></tr><tr><th class="right">tinybase (complete)</th><td>11.8kB</td><td>123.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>3.7kB</td><td>32.9kB</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,343</td><td>2,343</td><td>100.0%</td></tr><tr><th class="right">Statements</th><td>2,538</td><td>2,538</td><td>100.0%</td></tr><tr><th class="right">Functions</th><td>1,012</td><td>1,012</td><td>100.0%</td></tr><tr><th class="right">Branches</th><td>892</td><td>892</td><td>100.0%</td></tr><tr><th class="right">Tests</th><td colspan="3">7,180</td></tr><tr><th class="right">Assertions</th><td colspan="3">32,053</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/the-essentials/creating-stores/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><a href="https://synclets.org" target="_blank"><img src="https://synclets.org/favicon.svg?asImg" width="48"><br><b>Synclets</b></a><br>An open, storage-agnostic, sync engine development kit.</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>
@@ -43,7 +43,7 @@ const mapGet = (map, key) => map?.get(key);
43
43
  const mapForEach = (map, cb) =>
44
44
  collForEach(map, (value, key) => cb(key, value));
45
45
  const mapSet = (map, key, value) =>
46
- value === void 0 ? (collDel(map, key), map) : map?.set(key, value);
46
+ isUndefined(value) ? (collDel(map, key), map) : map?.set(key, value);
47
47
  const mapEnsure = (map, key, getDefaultValue, hadExistingValue) => {
48
48
  if (!collHas(map, key)) {
49
49
  mapSet(map, key, getDefaultValue());
@@ -272,7 +272,7 @@ const getWildcardedLeaves = (deepIdSet, path = [EMPTY_STRING]) => {
272
272
  const deep = (node, p) =>
273
273
  p == size(path)
274
274
  ? arrayPush(leaves, node)
275
- : path[p] === null
275
+ : isNull(path[p])
276
276
  ? collForEach(node, (node2) => deep(node2, p + 1))
277
277
  : arrayForEach([path[p], null], (id) => deep(mapGet(node, id), p + 1));
278
278
  deep(deepIdSet, 0);
@@ -43,7 +43,7 @@ const mapGet = (map, key) => map?.get(key);
43
43
  const mapForEach = (map, cb) =>
44
44
  collForEach(map, (value, key) => cb(key, value));
45
45
  const mapSet = (map, key, value) =>
46
- value === void 0 ? (collDel(map, key), map) : map?.set(key, value);
46
+ isUndefined(value) ? (collDel(map, key), map) : map?.set(key, value);
47
47
  const mapEnsure = (map, key, getDefaultValue, hadExistingValue) => {
48
48
  if (!collHas(map, key)) {
49
49
  mapSet(map, key, getDefaultValue());
@@ -272,7 +272,7 @@ const getWildcardedLeaves = (deepIdSet, path = [EMPTY_STRING]) => {
272
272
  const deep = (node, p) =>
273
273
  p == size(path)
274
274
  ? arrayPush(leaves, node)
275
- : path[p] === null
275
+ : isNull(path[p])
276
276
  ? collForEach(node, (node2) => deep(node2, p + 1))
277
277
  : arrayForEach([path[p], null], (id) => deep(mapGet(node, id), p + 1));
278
278
  deep(deepIdSet, 0);
package/releases.md CHANGED
@@ -24,7 +24,7 @@ console.log(schematizedStore.getRow('pets', 'fido'));
24
24
  // -> {species: 'dog', age: 3, sold: false}
25
25
  ```
26
26
 
27
- <p>Schematizers perform best-effort conversions, extracting basic type information (string, number, boolean), defaults, and nullable settings from your schemas.</p><p>This release includes support for Zod via the <a href="https://beta.tinybase.org/api/schematizer-zod/functions/creation/createzodschematizer/"><code>createZodSchematizer</code></a> function, TypeBox via the <a href="https://beta.tinybase.org/api/schematizer-typebox/functions/creation/createtypeboxschematizer/"><code>createTypeBoxSchematizer</code></a> function, and Valibot via the <a href="https://beta.tinybase.org/api/schematizer-valibot/functions/creation/createvalibotschematizer/"><code>createValibotSchematizer</code></a> function, with support for additional libraries planned for future releases.</p><p>For more information, see the <a href="https://beta.tinybase.org/guides/schemas/using-schematizers/">Using Schematizers</a> guide.</p><hr><h1 id="v7-0">v7.0</h1><p>This important (and slightly breaking!) release adds support for <code>null</code> as a valid <a href="https://beta.tinybase.org/api/store/type-aliases/store/cell/"><code>Cell</code></a> and <a href="https://beta.tinybase.org/api/store/type-aliases/store/value/"><code>Value</code></a> type, alongside <code>string</code>, <code>number</code>, and <code>boolean</code>.</p><h2 id="null-type-support">Null Type Support</h2><p>You can now set Cells and <a href="https://beta.tinybase.org/api/store/type-aliases/store/values/"><code>Values</code></a> to <code>null</code>:</p>
27
+ <p>Schematizers perform best-effort conversions, extracting basic type information (string, number, boolean), defaults, and nullable settings from your schemas.</p><p>This release includes support for:</p><ul><li><strong>Zod</strong> via the <a href="https://beta.tinybase.org/api/schematizer-zod/functions/creation/createzodschematizer/"><code>createZodSchematizer</code></a> function</li><li><strong>TypeBox</strong> via the <a href="https://beta.tinybase.org/api/schematizer-typebox/functions/creation/createtypeboxschematizer/"><code>createTypeBoxSchematizer</code></a> function</li><li><strong>Valibot</strong> via the <a href="https://beta.tinybase.org/api/schematizer-valibot/functions/creation/createvalibotschematizer/"><code>createValibotSchematizer</code></a> function</li><li><strong>ArkType</strong> via the <a href="https://beta.tinybase.org/api/schematizer-arktype/functions/creation/createarktypeschematizer/"><code>createArkTypeSchematizer</code></a> function</li><li><strong>Yup</strong> via the <a href="https://beta.tinybase.org/api/schematizer-yup/functions/creation/createyupschematizer/"><code>createYupSchematizer</code></a> function</li><li><strong>Effect Schema</strong> via the <a href="https://beta.tinybase.org/api/schematizer-effect/functions/creation/createeffectschematizer/"><code>createEffectSchematizer</code></a> function</li></ul><p>For more information, see the <a href="https://beta.tinybase.org/guides/schemas/using-schematizers/">Using Schematizers</a> guide.</p><hr><h1 id="v7-0">v7.0</h1><p>This important (and slightly breaking!) release adds support for <code>null</code> as a valid <a href="https://beta.tinybase.org/api/store/type-aliases/store/cell/"><code>Cell</code></a> and <a href="https://beta.tinybase.org/api/store/type-aliases/store/value/"><code>Value</code></a> type, alongside <code>string</code>, <code>number</code>, and <code>boolean</code>.</p><h2 id="null-type-support">Null Type Support</h2><p>You can now set Cells and <a href="https://beta.tinybase.org/api/store/type-aliases/store/values/"><code>Values</code></a> to <code>null</code>:</p>
28
28
 
29
29
  ```js
30
30
  const store = createStore();