tinybase 4.0.0-beta.4 → 4.0.0-beta.5.1

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 (269) hide show
  1. package/lib/cjs/persisters/persister-automerge.cjs +1 -0
  2. package/lib/cjs/persisters/persister-automerge.cjs.gz +0 -0
  3. package/lib/cjs/persisters/persister-browser.cjs +1 -0
  4. package/lib/cjs/persisters/persister-browser.cjs.gz +0 -0
  5. package/lib/cjs/persisters/persister-cr-sqlite-wasm.cjs +1 -0
  6. package/lib/cjs/persisters/persister-cr-sqlite-wasm.cjs.gz +0 -0
  7. package/lib/cjs/persisters/persister-file.cjs +1 -0
  8. package/lib/cjs/persisters/persister-file.cjs.gz +0 -0
  9. package/lib/cjs/persisters/persister-remote.cjs +1 -0
  10. package/lib/cjs/persisters/persister-remote.cjs.gz +0 -0
  11. package/lib/cjs/persisters/persister-sqlite-wasm.cjs +1 -0
  12. package/lib/cjs/persisters/persister-sqlite-wasm.cjs.gz +0 -0
  13. package/lib/cjs/persisters/persister-sqlite3.cjs +1 -0
  14. package/lib/cjs/persisters/persister-sqlite3.cjs.gz +0 -0
  15. package/lib/cjs/persisters/persister-yjs.cjs +1 -0
  16. package/lib/cjs/persisters/persister-yjs.cjs.gz +0 -0
  17. package/lib/cjs/persisters.cjs +1 -1
  18. package/lib/cjs/persisters.cjs.gz +0 -0
  19. package/lib/cjs/store.cjs +1 -1
  20. package/lib/cjs/store.cjs.gz +0 -0
  21. package/lib/cjs/tinybase.cjs +1 -1
  22. package/lib/cjs/tinybase.cjs.gz +0 -0
  23. package/lib/cjs/tools.cjs +1 -1
  24. package/lib/cjs/tools.cjs.gz +0 -0
  25. package/lib/cjs/ui-react.cjs +1 -1
  26. package/lib/cjs/ui-react.cjs.gz +0 -0
  27. package/lib/cjs-es6/persisters/persister-automerge.cjs +1 -0
  28. package/lib/cjs-es6/persisters/persister-automerge.cjs.gz +0 -0
  29. package/lib/cjs-es6/persisters/persister-browser.cjs +1 -0
  30. package/lib/cjs-es6/persisters/persister-browser.cjs.gz +0 -0
  31. package/lib/cjs-es6/persisters/persister-cr-sqlite-wasm.cjs +1 -0
  32. package/lib/cjs-es6/persisters/persister-cr-sqlite-wasm.cjs.gz +0 -0
  33. package/lib/cjs-es6/persisters/persister-file.cjs +1 -0
  34. package/lib/cjs-es6/persisters/persister-file.cjs.gz +0 -0
  35. package/lib/cjs-es6/persisters/persister-remote.cjs +1 -0
  36. package/lib/cjs-es6/persisters/persister-remote.cjs.gz +0 -0
  37. package/lib/cjs-es6/persisters/persister-sqlite-wasm.cjs +1 -0
  38. package/lib/cjs-es6/persisters/persister-sqlite-wasm.cjs.gz +0 -0
  39. package/lib/cjs-es6/persisters/persister-sqlite3.cjs +1 -0
  40. package/lib/cjs-es6/persisters/persister-sqlite3.cjs.gz +0 -0
  41. package/lib/cjs-es6/persisters/persister-yjs.cjs +1 -0
  42. package/lib/cjs-es6/persisters/persister-yjs.cjs.gz +0 -0
  43. package/lib/cjs-es6/persisters.cjs +1 -1
  44. package/lib/cjs-es6/persisters.cjs.gz +0 -0
  45. package/lib/cjs-es6/store.cjs +1 -1
  46. package/lib/cjs-es6/store.cjs.gz +0 -0
  47. package/lib/cjs-es6/tinybase.cjs +1 -1
  48. package/lib/cjs-es6/tinybase.cjs.gz +0 -0
  49. package/lib/cjs-es6/tools.cjs +1 -1
  50. package/lib/cjs-es6/tools.cjs.gz +0 -0
  51. package/lib/cjs-es6/ui-react.cjs +1 -1
  52. package/lib/cjs-es6/ui-react.cjs.gz +0 -0
  53. package/lib/debug/{persister-automerge.js → persisters/persister-automerge.js} +58 -31
  54. package/lib/debug/{persister-browser.js → persisters/persister-browser.js} +49 -20
  55. package/lib/debug/persisters/persister-cr-sqlite-wasm.js +665 -0
  56. package/lib/debug/{persister-file.js → persisters/persister-file.js} +51 -25
  57. package/lib/debug/{persister-remote.js → persisters/persister-remote.js} +48 -19
  58. package/lib/debug/persisters/persister-sqlite-wasm.js +673 -0
  59. package/lib/debug/persisters/persister-sqlite3.js +676 -0
  60. package/lib/debug/{persister-yjs.js → persisters/persister-yjs.js} +49 -20
  61. package/lib/debug/persisters.js +47 -18
  62. package/lib/debug/store.js +79 -29
  63. package/lib/debug/tinybase.js +123 -46
  64. package/lib/debug/tools.js +121 -27
  65. package/lib/debug/ui-react.js +24 -0
  66. package/lib/es6/persisters/persister-automerge.js +1 -0
  67. package/lib/es6/persisters/persister-automerge.js.gz +0 -0
  68. package/lib/es6/persisters/persister-browser.js +1 -0
  69. package/lib/es6/persisters/persister-browser.js.gz +0 -0
  70. package/lib/es6/persisters/persister-cr-sqlite-wasm.js +1 -0
  71. package/lib/es6/persisters/persister-cr-sqlite-wasm.js.gz +0 -0
  72. package/lib/es6/persisters/persister-file.js +1 -0
  73. package/lib/es6/persisters/persister-file.js.gz +0 -0
  74. package/lib/es6/persisters/persister-remote.js +1 -0
  75. package/lib/es6/persisters/persister-remote.js.gz +0 -0
  76. package/lib/es6/persisters/persister-sqlite-wasm.js +1 -0
  77. package/lib/es6/persisters/persister-sqlite-wasm.js.gz +0 -0
  78. package/lib/es6/persisters/persister-sqlite3.js +1 -0
  79. package/lib/es6/persisters/persister-sqlite3.js.gz +0 -0
  80. package/lib/es6/persisters/persister-yjs.js +1 -0
  81. package/lib/es6/persisters/persister-yjs.js.gz +0 -0
  82. package/lib/es6/persisters.js +1 -1
  83. package/lib/es6/persisters.js.gz +0 -0
  84. package/lib/es6/store.js +1 -1
  85. package/lib/es6/store.js.gz +0 -0
  86. package/lib/es6/tinybase.js +1 -1
  87. package/lib/es6/tinybase.js.gz +0 -0
  88. package/lib/es6/tools.js +1 -1
  89. package/lib/es6/tools.js.gz +0 -0
  90. package/lib/es6/ui-react.js +1 -1
  91. package/lib/es6/ui-react.js.gz +0 -0
  92. package/lib/persisters/persister-automerge.js +1 -0
  93. package/lib/persisters/persister-automerge.js.gz +0 -0
  94. package/lib/persisters/persister-browser.js +1 -0
  95. package/lib/persisters/persister-browser.js.gz +0 -0
  96. package/lib/persisters/persister-cr-sqlite-wasm.js +1 -0
  97. package/lib/persisters/persister-cr-sqlite-wasm.js.gz +0 -0
  98. package/lib/persisters/persister-file.js +1 -0
  99. package/lib/persisters/persister-file.js.gz +0 -0
  100. package/lib/persisters/persister-remote.js +1 -0
  101. package/lib/persisters/persister-remote.js.gz +0 -0
  102. package/lib/persisters/persister-sqlite-wasm.js +1 -0
  103. package/lib/persisters/persister-sqlite-wasm.js.gz +0 -0
  104. package/lib/persisters/persister-sqlite3.js +1 -0
  105. package/lib/persisters/persister-sqlite3.js.gz +0 -0
  106. package/lib/persisters/persister-yjs.js +1 -0
  107. package/lib/persisters/persister-yjs.js.gz +0 -0
  108. package/lib/persisters.js +1 -1
  109. package/lib/persisters.js.gz +0 -0
  110. package/lib/store.js +1 -1
  111. package/lib/store.js.gz +0 -0
  112. package/lib/tinybase.js +1 -1
  113. package/lib/tinybase.js.gz +0 -0
  114. package/lib/tools.js +1 -1
  115. package/lib/tools.js.gz +0 -0
  116. package/lib/types/checkpoints.d.ts +0 -27
  117. package/lib/types/common.d.ts +0 -9
  118. package/lib/types/indexes.d.ts +0 -26
  119. package/lib/types/metrics.d.ts +0 -23
  120. package/lib/types/{persister-automerge.d.ts → persisters/persister-automerge.d.ts} +4 -6
  121. package/lib/types/{persister-browser.d.ts → persisters/persister-browser.d.ts} +2 -5
  122. package/lib/types/persisters/persister-cr-sqlite-wasm.d.ts +95 -0
  123. package/lib/types/{persister-file.d.ts → persisters/persister-file.d.ts} +3 -5
  124. package/lib/types/{persister-remote.d.ts → persisters/persister-remote.d.ts} +2 -4
  125. package/lib/types/persisters/persister-sqlite-wasm.d.ts +102 -0
  126. package/lib/types/persisters/persister-sqlite3.d.ts +109 -0
  127. package/lib/types/{persister-yjs.d.ts → persisters/persister-yjs.d.ts} +4 -6
  128. package/lib/types/persisters.d.ts +517 -27
  129. package/lib/types/queries.d.ts +52 -127
  130. package/lib/types/relationships.d.ts +0 -26
  131. package/lib/types/store.d.ts +347 -196
  132. package/lib/types/tinybase.d.ts +0 -1
  133. package/lib/types/tools.d.ts +15 -28
  134. package/lib/types/ui-react.d.ts +196 -181
  135. package/lib/types/with-schemas/checkpoints.d.ts +5 -32
  136. package/lib/types/with-schemas/common.d.ts +0 -9
  137. package/lib/types/with-schemas/indexes.d.ts +9 -35
  138. package/lib/types/with-schemas/metrics.d.ts +9 -32
  139. package/lib/types/with-schemas/{persister-automerge.d.ts → persisters/persister-automerge.d.ts} +4 -6
  140. package/lib/types/with-schemas/{persister-browser.d.ts → persisters/persister-browser.d.ts} +2 -5
  141. package/lib/types/with-schemas/persisters/persister-cr-sqlite-wasm.d.ts +105 -0
  142. package/lib/types/with-schemas/{persister-file.d.ts → persisters/persister-file.d.ts} +3 -5
  143. package/lib/types/with-schemas/{persister-remote.d.ts → persisters/persister-remote.d.ts} +2 -4
  144. package/lib/types/with-schemas/persisters/persister-sqlite-wasm.d.ts +113 -0
  145. package/lib/types/with-schemas/persisters/persister-sqlite3.d.ts +119 -0
  146. package/lib/types/with-schemas/{persister-yjs.d.ts → persisters/persister-yjs.d.ts} +4 -6
  147. package/lib/types/with-schemas/persisters.d.ts +534 -29
  148. package/lib/types/with-schemas/queries.d.ts +61 -224
  149. package/lib/types/with-schemas/relationships.d.ts +9 -35
  150. package/lib/types/with-schemas/store.d.ts +488 -239
  151. package/lib/types/with-schemas/tinybase.d.ts +0 -1
  152. package/lib/types/with-schemas/tools.d.ts +19 -32
  153. package/lib/types/with-schemas/ui-react.d.ts +221 -186
  154. package/lib/ui-react.js +1 -1
  155. package/lib/ui-react.js.gz +0 -0
  156. package/lib/umd/persisters/persister-automerge.js +1 -0
  157. package/lib/umd/persisters/persister-automerge.js.gz +0 -0
  158. package/lib/umd/persisters/persister-browser.js +1 -0
  159. package/lib/umd/persisters/persister-browser.js.gz +0 -0
  160. package/lib/umd/persisters/persister-cr-sqlite-wasm.js +1 -0
  161. package/lib/umd/persisters/persister-cr-sqlite-wasm.js.gz +0 -0
  162. package/lib/umd/persisters/persister-file.js +1 -0
  163. package/lib/umd/persisters/persister-file.js.gz +0 -0
  164. package/lib/umd/persisters/persister-remote.js +1 -0
  165. package/lib/umd/persisters/persister-remote.js.gz +0 -0
  166. package/lib/umd/persisters/persister-sqlite-wasm.js +1 -0
  167. package/lib/umd/persisters/persister-sqlite-wasm.js.gz +0 -0
  168. package/lib/umd/persisters/persister-sqlite3.js +1 -0
  169. package/lib/umd/persisters/persister-sqlite3.js.gz +0 -0
  170. package/lib/umd/persisters/persister-yjs.js +1 -0
  171. package/lib/umd/persisters/persister-yjs.js.gz +0 -0
  172. package/lib/umd/persisters.js +1 -1
  173. package/lib/umd/persisters.js.gz +0 -0
  174. package/lib/umd/store.js +1 -1
  175. package/lib/umd/store.js.gz +0 -0
  176. package/lib/umd/tinybase.js +1 -1
  177. package/lib/umd/tinybase.js.gz +0 -0
  178. package/lib/umd/tools.js +1 -1
  179. package/lib/umd/tools.js.gz +0 -0
  180. package/lib/umd/ui-react.js +1 -1
  181. package/lib/umd/ui-react.js.gz +0 -0
  182. package/lib/umd-es6/persisters/persister-automerge.js +1 -0
  183. package/lib/umd-es6/persisters/persister-automerge.js.gz +0 -0
  184. package/lib/umd-es6/persisters/persister-browser.js +1 -0
  185. package/lib/umd-es6/persisters/persister-browser.js.gz +0 -0
  186. package/lib/umd-es6/persisters/persister-cr-sqlite-wasm.js +1 -0
  187. package/lib/umd-es6/persisters/persister-cr-sqlite-wasm.js.gz +0 -0
  188. package/lib/umd-es6/persisters/persister-file.js +1 -0
  189. package/lib/umd-es6/persisters/persister-file.js.gz +0 -0
  190. package/lib/umd-es6/persisters/persister-remote.js +1 -0
  191. package/lib/umd-es6/persisters/persister-remote.js.gz +0 -0
  192. package/lib/umd-es6/persisters/persister-sqlite-wasm.js +1 -0
  193. package/lib/umd-es6/persisters/persister-sqlite-wasm.js.gz +0 -0
  194. package/lib/umd-es6/persisters/persister-sqlite3.js +1 -0
  195. package/lib/umd-es6/persisters/persister-sqlite3.js.gz +0 -0
  196. package/lib/umd-es6/persisters/persister-yjs.js +1 -0
  197. package/lib/umd-es6/persisters/persister-yjs.js.gz +0 -0
  198. package/lib/umd-es6/persisters.js +1 -1
  199. package/lib/umd-es6/persisters.js.gz +0 -0
  200. package/lib/umd-es6/store.js +1 -1
  201. package/lib/umd-es6/store.js.gz +0 -0
  202. package/lib/umd-es6/tinybase.js +1 -1
  203. package/lib/umd-es6/tinybase.js.gz +0 -0
  204. package/lib/umd-es6/tools.js +1 -1
  205. package/lib/umd-es6/tools.js.gz +0 -0
  206. package/lib/umd-es6/ui-react.js +1 -1
  207. package/lib/umd-es6/ui-react.js.gz +0 -0
  208. package/package.json +39 -22
  209. package/readme.md +3 -3
  210. package/lib/cjs/persister-automerge.cjs +0 -1
  211. package/lib/cjs/persister-automerge.cjs.gz +0 -0
  212. package/lib/cjs/persister-browser.cjs +0 -1
  213. package/lib/cjs/persister-browser.cjs.gz +0 -0
  214. package/lib/cjs/persister-file.cjs +0 -1
  215. package/lib/cjs/persister-file.cjs.gz +0 -0
  216. package/lib/cjs/persister-remote.cjs +0 -1
  217. package/lib/cjs/persister-remote.cjs.gz +0 -0
  218. package/lib/cjs/persister-yjs.cjs +0 -1
  219. package/lib/cjs/persister-yjs.cjs.gz +0 -0
  220. package/lib/cjs-es6/persister-automerge.cjs +0 -1
  221. package/lib/cjs-es6/persister-automerge.cjs.gz +0 -0
  222. package/lib/cjs-es6/persister-browser.cjs +0 -1
  223. package/lib/cjs-es6/persister-browser.cjs.gz +0 -0
  224. package/lib/cjs-es6/persister-file.cjs +0 -1
  225. package/lib/cjs-es6/persister-file.cjs.gz +0 -0
  226. package/lib/cjs-es6/persister-remote.cjs +0 -1
  227. package/lib/cjs-es6/persister-remote.cjs.gz +0 -0
  228. package/lib/cjs-es6/persister-yjs.cjs +0 -1
  229. package/lib/cjs-es6/persister-yjs.cjs.gz +0 -0
  230. package/lib/es6/persister-automerge.js +0 -1
  231. package/lib/es6/persister-automerge.js.gz +0 -0
  232. package/lib/es6/persister-browser.js +0 -1
  233. package/lib/es6/persister-browser.js.gz +0 -0
  234. package/lib/es6/persister-file.js +0 -1
  235. package/lib/es6/persister-file.js.gz +0 -0
  236. package/lib/es6/persister-remote.js +0 -1
  237. package/lib/es6/persister-remote.js.gz +0 -0
  238. package/lib/es6/persister-yjs.js +0 -1
  239. package/lib/es6/persister-yjs.js.gz +0 -0
  240. package/lib/persister-automerge.js +0 -1
  241. package/lib/persister-automerge.js.gz +0 -0
  242. package/lib/persister-browser.js +0 -1
  243. package/lib/persister-browser.js.gz +0 -0
  244. package/lib/persister-file.js +0 -1
  245. package/lib/persister-file.js.gz +0 -0
  246. package/lib/persister-remote.js +0 -1
  247. package/lib/persister-remote.js.gz +0 -0
  248. package/lib/persister-yjs.js +0 -1
  249. package/lib/persister-yjs.js.gz +0 -0
  250. package/lib/umd/persister-automerge.js +0 -1
  251. package/lib/umd/persister-automerge.js.gz +0 -0
  252. package/lib/umd/persister-browser.js +0 -1
  253. package/lib/umd/persister-browser.js.gz +0 -0
  254. package/lib/umd/persister-file.js +0 -1
  255. package/lib/umd/persister-file.js.gz +0 -0
  256. package/lib/umd/persister-remote.js +0 -1
  257. package/lib/umd/persister-remote.js.gz +0 -0
  258. package/lib/umd/persister-yjs.js +0 -1
  259. package/lib/umd/persister-yjs.js.gz +0 -0
  260. package/lib/umd-es6/persister-automerge.js +0 -1
  261. package/lib/umd-es6/persister-automerge.js.gz +0 -0
  262. package/lib/umd-es6/persister-browser.js +0 -1
  263. package/lib/umd-es6/persister-browser.js.gz +0 -0
  264. package/lib/umd-es6/persister-file.js +0 -1
  265. package/lib/umd-es6/persister-file.js.gz +0 -0
  266. package/lib/umd-es6/persister-remote.js +0 -1
  267. package/lib/umd-es6/persister-remote.js.gz +0 -0
  268. package/lib/umd-es6/persister-yjs.js +0 -1
  269. package/lib/umd-es6/persister-yjs.js.gz +0 -0
@@ -4,22 +4,28 @@
4
4
  * underlying storage types.
5
5
  *
6
6
  * Several entry points are provided (in separately installed modules), each of
7
- * which returns a new Persister object that can load and save a Store:
7
+ * which returns a new Persister object that can load and save a Store. Between
8
+ * them, these allow you to store your TinyBase data locally, remotely, to
9
+ * SQLite databases, and across synchronization boundaries with CRDT frameworks.
8
10
  *
9
- * - The createSessionPersister function (in the persister-browser module)
10
- * returns a Persister that uses the browser's session storage.
11
- * - The createLocalPersister function (in the persister-browser module) returns
12
- * a Persister that uses the browser's local storage.
13
- * - The createRemotePersister function (in the persister-remote module) returns
14
- * a Persister that uses a remote server.
15
- * - The createFilePersister function (in the persister-file module) returns a
16
- * Persister that uses a local file (in an appropriate environment).
11
+ * |Module|Function|Storage|
12
+ * |-|-|-|
13
+ * |persister-browser|createSessionPersister|Browser session storage|
14
+ * |persister-browser|createLocalPersister|Browser local storage|
15
+ * |persister-remote|createRemotePersister|Remote server|
16
+ * |persister-file|createFilePersister|Local file (where possible)|
17
+ * |persister-sqlite3|createSqlite3Persister|SQLite in Node, via [sqlite3](https://github.com/TryGhost/node-sqlite3)|
18
+ * |persister-sqlite-wasm|createSqliteWasmPersister|SQLite in a browser, via [sqlite-wasm](https://github.com/tomayac/sqlite-wasm)|
19
+ * |persister-cr-sqlite-wasm|createCrSqliteWasmPersister|SQLite CRDTs, via [cr-sqlite-wasm](https://github.com/vlcn-io/cr-sqlite)|
20
+ * |persister-yjs|createYjsPersister|Yjs CRDTs, via [yjs](https://github.com/yjs/yjs)|
21
+ * |persister-automerge|createSqliteWasmPersister|Automerge CRDTs, via [automerge-repo](https://github.com/automerge/automerge-repo)|
17
22
  *
18
23
  * Since persistence requirements can be different for every app, the
19
24
  * createCustomPersister function in this module can also be used to easily
20
25
  * create a fully customized way to save and load Store data.
21
- *
22
26
  * @see Persisting Data guide
27
+ * @see Database Persistence guide
28
+ * @see Synchronizing Data guide
23
29
  * @see Countries demo
24
30
  * @see Todo App demos
25
31
  * @see Drawing demo
@@ -28,6 +34,7 @@
28
34
  */
29
35
 
30
36
  import {GetTransactionChanges, Store, Tables, Values} from './store.d';
37
+ import {Id} from './common.d';
31
38
 
32
39
  /**
33
40
  * The PersisterStats type describes the number of times a Persister object has
@@ -35,7 +42,6 @@ import {GetTransactionChanges, Store, Tables, Values} from './store.d';
35
42
  *
36
43
  * A PersisterStats object is returned from the getStats method, and is only
37
44
  * populated in a debug build.
38
- *
39
45
  * @category Development
40
46
  */
41
47
  export type PersisterStats = {
@@ -58,18 +64,468 @@ export type PersisterStats = {
58
64
  * function _is_ available, that will be used to make a wholesale change to the
59
65
  * Store. If neither are present, the content will be loaded from the
60
66
  * Persister's load method.
61
- *
62
67
  * @param getContent An optional function that, if provided, returns an array of
63
68
  * Store content and can be used to immediately wholesale update the Store.
64
69
  * @param getTransactionChanges An optional function that, if provided, returns
65
70
  * a TransactionChanges object and can be used to immediately incrementally
66
71
  * update the Store.
72
+ * @category Creation
73
+ * @since v4.0.0
67
74
  */
68
75
  export type PersisterListener = (
69
76
  getContent?: () => [Tables, Values],
70
77
  getTransactionChanges?: GetTransactionChanges,
71
78
  ) => void;
72
79
 
80
+ /**
81
+ * The DatabasePersisterConfig type describes the configuration of a
82
+ * database-oriented Persister, such as those for SQLite.
83
+ *
84
+ * There are two modes for persisting a Store with a database:
85
+ *
86
+ * - A JSON serialization of the whole Store, which is stored in a single row of
87
+ * a table (normally called `tinybase`) within the database. This is
88
+ * configured by providing a DpcJson object.
89
+ * - A tabular mapping of Table Ids to database table names (and vice-versa).
90
+ * Values are stored in a separate special table (normally called
91
+ * `tinybase_values`). This is configured by providing a DpcTabular object.
92
+ *
93
+ * Please see the DpcJson and DpcTabular type documentation for more detail on
94
+ * each. If not specified otherwise, JSON serialization will be used for
95
+ * persistence.
96
+ *
97
+ * Changes made to the database (outside of this Persister) are picked up
98
+ * immediately if they are made via the same connection or library that it is
99
+ * using. If the database is being changed by another client, the Persister
100
+ * needs to poll for changes. Hence both configuration types also contain an
101
+ * `autoLoadIntervalSeconds` property which indicates how often it should do
102
+ * that. This defaults to 1 second.
103
+ *
104
+ * Note that all the nested types within this type have a 'Dpc' prefix, short
105
+ * for 'DatabasePersisterConfig'.
106
+ * @example
107
+ * When applied to a database Persister, this DatabasePersisterConfig will load
108
+ * and save a JSON serialization from and to a table called `my_tinybase`,
109
+ * polling the database every 2 seconds. See DpcJson for more details on these
110
+ * settings.
111
+ *
112
+ * ```js
113
+ * const databasePersisterConfig: DatabasePersisterConfig = {
114
+ * mode: 'json',
115
+ * storeTableName: 'my_tinybase',
116
+ * autoLoadIntervalSeconds: 2,
117
+ * };
118
+ * ```
119
+ * @example
120
+ * When applied to a database Persister, this DatabasePersisterConfig will load
121
+ * and save tabular data from and to tables specified in the `load` and `save`
122
+ * mappings. See DpcTabular for more details on these settings.
123
+ *
124
+ * ```js
125
+ * const databasePersisterConfig: DatabasePersisterConfig = {
126
+ * mode: 'tabular',
127
+ * tables: {
128
+ * load: {petsInDb: 'pets', speciesInDb: 'species'},
129
+ * save: {pets: 'petsInDb', species: 'speciesInDb'},
130
+ * },
131
+ * };
132
+ * ```
133
+ * @category Configuration
134
+ * @since v4.0.0
135
+ */
136
+ export type DatabasePersisterConfig = DpcJson | DpcTabular;
137
+
138
+ /**
139
+ * The DpcJson type describes the configuration of a database-oriented Persister
140
+ * operating in serialized JSON mode.
141
+ *
142
+ * The only setting is the `storeTableName` property, which indicates the name
143
+ * of a table in the database which will be used to serialize the Store content
144
+ * into. It defaults to `tinybase`.
145
+ *
146
+ * That table in the database will be given two columns: a primary key column
147
+ * called `_id`, and one called `store`. The Persister will place a single row
148
+ * in this table with `_` in the `_id` column, and the JSON serialization in the
149
+ * `store` column, something like:
150
+ *
151
+ * ```
152
+ * > SELECT * FROM tinybase;
153
+ * +-----+-----------------------------------------------------+
154
+ * | _id | store |
155
+ * +-----+-----------------------------------------------------+
156
+ * | _ | [{"pets":{"fido":{"species":"dog"}}},{"open":true}] |
157
+ * +-----+-----------------------------------------------------+
158
+ * ```
159
+ *
160
+ * The 'Dpc' prefix indicates that this type is used within the
161
+ * DatabasePersisterConfig type.
162
+ * @example
163
+ * When applied to a database Persister, this DatabasePersisterConfig will load
164
+ * and save a JSON serialization from and to a table called `tinybase_json`.
165
+ *
166
+ * ```js
167
+ * const databasePersisterConfig: DatabasePersisterConfig = {
168
+ * mode: 'json',
169
+ * storeTableName: 'tinybase_json',
170
+ * };
171
+ * ```
172
+ * @category Configuration
173
+ * @since v4.0.0
174
+ */
175
+ export type DpcJson = {
176
+ /**
177
+ * The mode to be used for persisting the Store to the database, in this case
178
+ * JSON serialization. See the DpcTabular type for the alternative tabular
179
+ * mapping mode.
180
+ */
181
+ mode: 'json';
182
+ /**
183
+ * An optional string which indicates the name of a table in the database
184
+ * which will be used to serialize the Store content into. It defaults to
185
+ * `tinybase`.
186
+ */
187
+ storeTableName?: string;
188
+ /**
189
+ * How often the Persister should poll the database for any changes made to it
190
+ * by other clients, defaulting to 1 second.
191
+ */
192
+ autoLoadIntervalSeconds?: number;
193
+ };
194
+
195
+ /**
196
+ * The DpcTabular type describes the configuration of a database-oriented
197
+ * Persister that is operating in tabular mapping mode.
198
+ *
199
+ * It is important to note that both the tabular mapping in ('save') and out
200
+ * ('load') of an underlying database are disabled by default. This is to ensure
201
+ * that if you pass in an existing populated database you don't run the
202
+ * immediate risk of corrupting or losing all your data.
203
+ *
204
+ * This configuration therefore takes a `tables` property object (with child
205
+ * `load` and `save` property objects) and a `values` property object. These
206
+ * indicate how you want to load and save Tables and Values respectively. At
207
+ * least one of these two properties are required for the Persister to do
208
+ * anything!
209
+ *
210
+ * Note that if you are planning to both load from and save to a database, it is
211
+ * important to make sure that the load and save table mappings are symmetrical.
212
+ * For example:
213
+ *
214
+ * ```js
215
+ * const databasePersisterConfig: DatabasePersisterConfig = {
216
+ * mode: 'tabular',
217
+ * tables: {
218
+ * load: {petsInDb: 'pets', speciesInDb: 'species'},
219
+ * save: {pets: 'petsInDb', species: 'speciesInDb'},
220
+ * },
221
+ * };
222
+ * ```
223
+ *
224
+ * See the documentation for the DpcTabularLoad, DpcTabularSave, and
225
+ * DpcTabularValues types for more details on how to configure the tabular
226
+ * mapping mode.
227
+ *
228
+ * The 'Dpc' prefix indicates that this type is used within the
229
+ * DatabasePersisterConfig type.
230
+ * @example
231
+ * When applied to a database Persister, this DatabasePersisterConfig will load
232
+ * and save Tables data from and to tables specified in the `load` and `save`
233
+ * mappings, and Values data from and to a table called `my_tinybase_values`.
234
+ *
235
+ * ```js
236
+ * const databasePersisterConfig: DatabasePersisterConfig = {
237
+ * mode: 'tabular',
238
+ * tables: {
239
+ * load: {petsInDb: 'pets', speciesInDb: 'species'},
240
+ * save: {pets: 'petsInDb', species: 'speciesInDb'},
241
+ * },
242
+ * values: {
243
+ * load: true,
244
+ * save: true,
245
+ * tableName: 'my_tinybase_values',
246
+ * },
247
+ * };
248
+ * ```
249
+ * @category Configuration
250
+ * @since v4.0.0
251
+ */
252
+ export type DpcTabular = {
253
+ /**
254
+ * The mode to be used for persisting the Store to the database, in this case
255
+ * tabular mapping. See the DpcJson type for the alternative JSON
256
+ * serialization mode.
257
+ */
258
+ mode: 'tabular';
259
+ /**
260
+ * The settings for how the Store Tables are mapped to and from the database.
261
+ */
262
+ tables?: {
263
+ /**
264
+ * The settings for how the database tables are mapped into the Store Tables
265
+ * when loading.
266
+ */
267
+ load?: DpcTabularLoad;
268
+ /**
269
+ * The settings for how the Store Tables are mapped out to the database
270
+ * tables when saving.
271
+ */
272
+ save?: DpcTabularSave;
273
+ };
274
+ /**
275
+ * The settings for how the Store Values are mapped to and from the database.
276
+ */
277
+ values?: DpcTabularValues;
278
+ /**
279
+ * How often the Persister should poll the database for any changes made to it
280
+ * by other clients, defaulting to 1 second.
281
+ */
282
+ autoLoadIntervalSeconds?: number;
283
+ };
284
+
285
+ /**
286
+ * The DpcTabularLoad type describes the configuration for loading Tables in a
287
+ * database-oriented Persister that is operating in tabular mode.
288
+ *
289
+ * It is an object where each key is a name of a database table, and the value
290
+ * is a child configuration object for how that table should be loaded into the
291
+ * Store. The properties of the child configuration object are:
292
+ *
293
+ * ||Type|Description|
294
+ * |-|-|-|
295
+ * |`tableId`|Id|The Id of the Store Table into which data from this database table should be loaded.|
296
+ * |`rowIdColumnName?`|string|The optional name of the column in the database table that will be used as the Row Ids in the Store Table, defaulting to '_id'.|
297
+ *
298
+ * As a shortcut, if you do not need to specify a custom `rowIdColumnName`, you
299
+ * can simply provide the Id of the Store Table instead of the whole object.
300
+ *
301
+ * The 'Dpc' prefix indicates that this type is used within the
302
+ * DatabasePersisterConfig type.
303
+ * @example
304
+ * When applied to a database Persister, this DatabasePersisterConfig will load
305
+ * the data of two database tables (called 'petsInDb' and 'speciesInDb') into
306
+ * two Store Tables (called 'pets' and 'species'). One has a column for the Row
307
+ * Id called 'id' and the other defaults it to '_id'.
308
+ *
309
+ * ```js
310
+ * const databasePersisterConfig: DatabasePersisterConfig = {
311
+ * mode: 'tabular',
312
+ * tables: {
313
+ * load: {
314
+ * petsInDb: {tableId: 'pets', rowIdColumnName: 'id'},
315
+ * speciesInDb: 'species',
316
+ * },
317
+ * },
318
+ * };
319
+ * ```
320
+ *
321
+ * Imagine database tables that look like this:
322
+ *
323
+ * ```
324
+ * > SELECT * FROM petsInDb;
325
+ * +-------+---------+-------+
326
+ * | id | species | color |
327
+ * +-------+---------+-------+
328
+ * | fido | dog | brown |
329
+ * | felix | cat | black |
330
+ * +-------+---------+-------+
331
+ *
332
+ * > SELECT * FROM speciesInDb;
333
+ * +------+-------+
334
+ * | _id | price |
335
+ * +------+-------+
336
+ * | dog | 5 |
337
+ * | cat | 4 |
338
+ * +------+-------+
339
+ * ```
340
+ *
341
+ * With the configuration above, this will load into a Store with Tables that
342
+ * look like this:
343
+ *
344
+ * ```json
345
+ * {
346
+ * "pets": {
347
+ * "fido": {"species": "dog", "color": "brown"},
348
+ * "felix": {"species": "cat", "color": "black"},
349
+ * },
350
+ * "species": {
351
+ * "dog": {"price": 5},
352
+ * "cat": {"price": 4},
353
+ * },
354
+ * }
355
+ * ```
356
+ * @category Configuration
357
+ * @since v4.0.0
358
+ */
359
+ export type DpcTabularLoad = {
360
+ [tableName: string]:
361
+ | {
362
+ /**
363
+ * The Id of the Store Table into which data from this database table
364
+ * should be loaded.
365
+ */
366
+ tableId: Id;
367
+ /**
368
+ * The optional name of the column in the database table that will be
369
+ * used as the Row Ids in the Store Table, defaulting to '_id'.
370
+ */
371
+ rowIdColumnName?: string;
372
+ }
373
+ | Id;
374
+ };
375
+
376
+ /**
377
+ * The DpcTabularSave type describes the configuration for saving Tables in a
378
+ * database-oriented Persister that is operating in tabular mode.
379
+ *
380
+ * It is an object where each key is an Id of a Store Table, and the value is a
381
+ * child configuration object for how that Table should be saved out to the
382
+ * database. The properties of the child configuration object are:
383
+ *
384
+ * ||Type|Description|
385
+ * |-|-|-|
386
+ * |`tableName`|string|The name of the database table out to which the Store Table should be saved.|
387
+ * |`rowIdColumnName?`|string|The optional name of the column in the database table that will be used to save the Row Ids from the Store Table, defaulting to '_id'.|
388
+ * |`deleteEmptyColumns?`|boolean|Whether columns in the database table will be removed if they are empty in the Store Table, defaulting to false.|
389
+ * |`deleteEmptyTable?`|boolean|Whether tables in the database will be removed if the Store Table is empty, defaulting to false.|
390
+ *
391
+ * As a shortcut, if you do not need to specify a custom `rowIdColumnName`, or
392
+ * enable the `deleteEmptyColumns` or `deleteEmptyTable` settings, you can
393
+ * simply provide the name of the database table instead of the whole object.
394
+ *
395
+ * The 'Dpc' prefix indicates that this type is used within the
396
+ * DatabasePersisterConfig type.
397
+ * @example
398
+ * When applied to a database Persister, this DatabasePersisterConfig will save
399
+ * the data of two Store Tables (called 'pets' and 'species') into two database
400
+ * tables (called 'petsInDb' and 'speciesInDb'). One has a column for the Row
401
+ * Id called 'id' and will delete columns and the whole table if empty, the
402
+ * other defaults to '_id' and will not delete columns or the whole table if
403
+ * empty.
404
+ *
405
+ * ```js
406
+ * const databasePersisterConfig: DatabasePersisterConfig = {
407
+ * mode: 'tabular',
408
+ * tables: {
409
+ * save: {
410
+ * pets: {
411
+ * tableName: 'petsInDb',
412
+ * deleteEmptyColumns: true,
413
+ * deleteEmptyTable: true,
414
+ * },
415
+ * species: 'speciesInDb',
416
+ * },
417
+ * },
418
+ * };
419
+ * ```
420
+ *
421
+ * Imagine a Store with Tables that look like this:
422
+ *
423
+ * ```json
424
+ * {
425
+ * "pets": {
426
+ * "fido": {"species": "dog", "color": "brown"},
427
+ * "felix": {"species": "cat", "color": "black"},
428
+ * },
429
+ * "species": {
430
+ * "dog": {"price": 5},
431
+ * "cat": {"price": 4},
432
+ * },
433
+ * }
434
+ * ```
435
+ *
436
+ * With the configuration above, this will save out to a database with tables
437
+ * that look like this:
438
+ *
439
+ * ```
440
+ * > SELECT * FROM petsInDb;
441
+ * +-------+---------+-------+
442
+ * | id | species | color |
443
+ * +-------+---------+-------+
444
+ * | fido | dog | brown |
445
+ * | felix | cat | black |
446
+ * +-------+---------+-------+
447
+ *
448
+ * > SELECT * FROM speciesInDb;
449
+ * +------+-------+
450
+ * | _id | price |
451
+ * +------+-------+
452
+ * | dog | 5 |
453
+ * | cat | 4 |
454
+ * +------+-------+
455
+ * ```
456
+ * @category Configuration
457
+ * @since v4.0.0
458
+ */
459
+ export type DpcTabularSave = {
460
+ [tableId: Id]:
461
+ | {
462
+ /**
463
+ * The name of the database table out to which the Store Table should be
464
+ * saved.
465
+ */
466
+ tableName: string;
467
+ /**
468
+ * The optional name of the column in the database table that will be
469
+ * used to save the Row Ids from the Store Table, defaulting to '_id'.
470
+ */
471
+ rowIdColumnName?: string;
472
+ /**
473
+ * Whether columns in the database table will be removed if they are
474
+ * empty in the Store Table, defaulting to false.
475
+ */
476
+ deleteEmptyColumns?: boolean;
477
+ /**
478
+ * Whether tables in the database will be removed if the Store Table
479
+ * is empty, defaulting to false.
480
+ */
481
+ deleteEmptyTable?: boolean;
482
+ }
483
+ | string;
484
+ };
485
+
486
+ /**
487
+ * The DpcTabularValues type describes the configuration for handling Values in
488
+ * a database-oriented Persister that is operating in tabular mode.
489
+ *
490
+ * Note that both loading and saving of Values from and to the database are
491
+ * disabled by default.
492
+ *
493
+ * The 'Dpc' prefix indicates that this type is used within the
494
+ * DatabasePersisterConfig type.
495
+ * @example
496
+ * When applied to a database Persister, this DatabasePersisterConfig will load
497
+ * and save the data of a Store's Values into a database
498
+ * table called 'my_tinybase_values'.
499
+ *
500
+ * ```js
501
+ * const databasePersisterConfig: DatabasePersisterConfig = {
502
+ * mode: 'tabular',
503
+ * values: {
504
+ * load: true,
505
+ * save: true,
506
+ * tableName: 'my_tinybase_values',
507
+ * },
508
+ * };
509
+ * ```
510
+ * @category Configuration
511
+ * @since v4.0.0
512
+ */
513
+ export type DpcTabularValues = {
514
+ /**
515
+ * Whether Store Values will be loaded from a database table.
516
+ */
517
+ load?: boolean;
518
+ /**
519
+ * Whether Store Values will be saved to a database table.
520
+ */
521
+ save?: boolean;
522
+ /**
523
+ * The optional name of the database table from and to which the Store Table
524
+ * should be loaded or saved, defaulting to `tinybase_values`.
525
+ */
526
+ tableName?: string;
527
+ };
528
+
73
529
  /**
74
530
  * A Persister object lets you save and load Store data to and from different
75
531
  * locations, or underlying storage types.
@@ -113,7 +569,6 @@ export type PersisterListener = (
113
569
  * persistence strategy to understand the opportunity for data loss (in the case
114
570
  * of trying to save data to a server under poor network conditions, for
115
571
  * example).
116
- *
117
572
  * @example
118
573
  * This example creates a Store, persists it to the browser's session storage as
119
574
  * a JSON string, changes the persisted data, updates the Store from it, and
@@ -181,7 +636,6 @@ export interface Persister {
181
636
  * machine or a filesystem. Even for those storage types that are synchronous
182
637
  * (like browser storage) it is still recommended that you `await` calls to
183
638
  * this method or handle the return type natively as a Promise.
184
- *
185
639
  * @param initialTables An optional Tables object used when the underlying
186
640
  * storage has not previously been populated.
187
641
  * @param initialValues An optional Values object used when the underlying
@@ -249,7 +703,6 @@ export interface Persister {
249
703
  * the asynchronous load method. Even for those storage types that are
250
704
  * synchronous (like browser storage) it is still recommended that you `await`
251
705
  * calls to this method or handle the return type natively as a Promise.
252
- *
253
706
  * @param initialTables An optional Tables object used when the underlying
254
707
  * storage has not previously been populated.
255
708
  * @param initialValues An optional Values object used when the underlying
@@ -294,7 +747,6 @@ export interface Persister {
294
747
  *
295
748
  * If the Persister is not currently set to automatically load, this method
296
749
  * has no effect.
297
- *
298
750
  * @returns A reference to the Persister object.
299
751
  * @example
300
752
  * This example creates an empty Store, and starts automatically loading data
@@ -341,7 +793,6 @@ export interface Persister {
341
793
  * machine or a filesystem. Even for those storage types that are synchronous
342
794
  * (like browser storage) it is still recommended that you `await` calls to
343
795
  * this method or handle the return type natively as a Promise.
344
- *
345
796
  * @returns A Promise containing a reference to the Persister object.
346
797
  * @example
347
798
  * This example creates a Store with some data, and saves into the browser's
@@ -374,7 +825,6 @@ export interface Persister {
374
825
  * the asynchronous save method. Even for those storage types that are
375
826
  * synchronous (like browser storage) it is still recommended that you `await`
376
827
  * calls to this method or handle the return type natively as a Promise.
377
- *
378
828
  * @returns A Promise containing a reference to the Persister object.
379
829
  * @example
380
830
  * This example creates a Store with some data, and saves into the browser's
@@ -406,7 +856,6 @@ export interface Persister {
406
856
  *
407
857
  * If the Persister is not currently set to automatically save, this method
408
858
  * has no effect.
409
- *
410
859
  * @returns A reference to the Persister object.
411
860
  * @example
412
861
  * This example creates a Store with some data, and saves into the browser's
@@ -438,10 +887,52 @@ export interface Persister {
438
887
  */
439
888
  stopAutoSave(): Persister;
440
889
 
890
+ /**
891
+ * The schedule method allows you to queue up a series of asynchronous actions
892
+ * that must run in sequence during persistence.
893
+ *
894
+ * For example, a database Persister may need to ensure that multiple
895
+ * asynchronous tasks to check and update the database schema are completed
896
+ * before data is written to it. Therefore it's most likely you will be using
897
+ * this method inside your `setPersisted` implementation.
898
+ *
899
+ * Call this method to add a single asynchronous action, or a sequence of them
900
+ * in one call. This will also start to run the first task in the queue (which
901
+ * once complete will then run the next, and so on), and so this method itself
902
+ * is also asynchronous and returns a promise of the Persister.
903
+ * @returns A reference to the Persister object.
904
+ * @example
905
+ * This example creates a custom Persister object against a newly-created
906
+ * Store and then sequences two tasks in order to update its data on a
907
+ * hypothetical remote system.
908
+ *
909
+ * ```js yolo
910
+ * const store = createStore();
911
+ * const persister = createCustomPersister(
912
+ * store,
913
+ * async () => {
914
+ * // getPersisted
915
+ * return await getDataFromRemoteSystem();
916
+ * },
917
+ * async (getContent) => {
918
+ * // setPersisted
919
+ * await persister.schedule(
920
+ * async () => await checkRemoteSystemIsReady(),
921
+ * async () => await sendDataToRemoteSystem(getContent()),
922
+ * );
923
+ * },
924
+ * (listener) => setInterval(listener, 1000),
925
+ * (interval) => clearInterval(interval),
926
+ * );
927
+ * ```
928
+ * @category Lifecycle
929
+ * @since v4.0.0
930
+ */
931
+ schedule(...actions: Promise<any>[]): Promise<Persister>;
932
+
441
933
  /**
442
934
  * The getStore method returns a reference to the underlying Store that is
443
935
  * backing this Persister object.
444
- *
445
936
  * @returns A reference to the Store.
446
937
  * @example
447
938
  * This example creates a Persister object against a newly-created Store and
@@ -470,7 +961,6 @@ export interface Persister {
470
961
  * the underlying Store and storage are removed and it can be correctly
471
962
  * garbage collected. It is equivalent to running the stopAutoLoad method and
472
963
  * the stopAutoSave method in succession.
473
- *
474
964
  * @example
475
965
  * This example creates a Store, associates a Persister object with it (that
476
966
  * registers a TablesListener with the underlying Store), and then destroys it
@@ -504,7 +994,6 @@ export interface Persister {
504
994
  * return an empty object. The method is intended to be used during
505
995
  * development to ensure your persistence layer is acting as expected, for
506
996
  * example.
507
- *
508
997
  * @returns A PersisterStats object containing Persister load and save
509
998
  * statistics.
510
999
  * @example
@@ -561,7 +1050,6 @@ export interface Persister {
561
1050
  * function must return the content (or nothing) rather than JSON.
562
1051
  * `startListeningToPersisted` has been renamed `addPersisterListener`, and
563
1052
  * `stopListeningToPersisted` has been renamed `delPersisterListener`.
564
- *
565
1053
  * @param store The Store to persist.
566
1054
  * @param getPersisted An asynchronous function which will fetch content from
567
1055
  * the persistence layer (or `undefined` if not present).
@@ -588,11 +1076,13 @@ export interface Persister {
588
1076
  * const persister = createCustomPersister(
589
1077
  * store,
590
1078
  * async () => {
591
- * try {
592
- * return JSON.parse(storeJson);
593
- * } catch {}
1079
+ * // getPersisted
1080
+ * return JSON.parse(storeJson);
1081
+ * },
1082
+ * async (getContent) => {
1083
+ * // setPersisted
1084
+ * storeJson = JSON.stringify(getContent());
594
1085
  * },
595
- * async (getContent) => (storeJson = JSON.stringify(getContent())),
596
1086
  * (listener) => setInterval(listener, 1000),
597
1087
  * (interval) => clearInterval(interval),
598
1088
  * );