tinybase 4.0.0-beta.4 → 4.0.0-beta.5

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} +57 -30
  54. package/lib/debug/{persister-browser.js → persisters/persister-browser.js} +48 -19
  55. package/lib/debug/persisters/persister-cr-sqlite-wasm.js +665 -0
  56. package/lib/debug/{persister-file.js → persisters/persister-file.js} +50 -24
  57. package/lib/debug/{persister-remote.js → persisters/persister-remote.js} +47 -18
  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} +48 -19
  61. package/lib/debug/persisters.js +46 -17
  62. package/lib/debug/store.js +77 -27
  63. package/lib/debug/tinybase.js +120 -43
  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 +38 -21
  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
@@ -1,9 +1,12 @@
1
1
  import {Map} from 'yjs';
2
2
 
3
+ const TINYBASE = 'tinybase';
4
+
3
5
  const arrayForEach = (array, cb) => array.forEach(cb);
4
6
  const arrayMap = (array, cb) => array.map(cb);
5
7
  const arrayLength = (array) => array.length;
6
8
  const arrayIsEmpty = (array) => arrayLength(array) == 0;
9
+ const arrayPush = (array, ...values) => array.push(...values);
7
10
  const arrayShift = (array) => array.shift();
8
11
 
9
12
  const isUndefined = (thing) => thing == void 0;
@@ -12,7 +15,7 @@ const ifNotUndefined = (value, then, otherwise) =>
12
15
 
13
16
  const object = Object;
14
17
  const objFreeze = object.freeze;
15
- const objNew = () => ({});
18
+ const objNew = (entries = []) => object.fromEntries(entries);
16
19
  const objGet = (obj, id) => ifNotUndefined(obj, (obj2) => obj2[id]);
17
20
  const objHas = (obj, id) => !isUndefined(objGet(obj, id));
18
21
  const objMap = (obj, cb) =>
@@ -35,8 +38,23 @@ const createCustomPersister = (
35
38
  let loadSave = 0;
36
39
  let loads = 0;
37
40
  let saves = 0;
38
- let listening = false;
41
+ let running = 0;
42
+ let listening = 0;
43
+ let action;
39
44
  let listeningHandle;
45
+ const scheduledActions = [];
46
+ const run = async () => {
47
+ /* istanbul ignore else */
48
+ if (!running) {
49
+ running = 1;
50
+ while (!isUndefined((action = arrayShift(scheduledActions)))) {
51
+ try {
52
+ await action();
53
+ } catch {}
54
+ }
55
+ running = 0;
56
+ }
57
+ };
40
58
  const loadLock = async (actions) => {
41
59
  /* istanbul ignore else */
42
60
  if (loadSave != 2) {
@@ -51,18 +69,18 @@ const createCustomPersister = (
51
69
  const persister = {
52
70
  load: async (initialTables = {}, initialValues = {}) => {
53
71
  await loadLock(async () => {
54
- let content;
55
72
  try {
56
- content = await getPersisted();
57
- } catch {}
58
- store.setContent(content ?? [initialTables, initialValues]);
73
+ store.setContent(await getPersisted());
74
+ } catch {
75
+ store.setContent([initialTables, initialValues]);
76
+ }
59
77
  });
60
78
  return persister;
61
79
  },
62
80
  startAutoLoad: async (initialTables = {}, initialValues = {}) => {
63
81
  persister.stopAutoLoad();
64
82
  await persister.load(initialTables, initialValues);
65
- listening = true;
83
+ listening = 1;
66
84
  listeningHandle = addPersisterListener(
67
85
  async (getContent, getTransactionChanges) => {
68
86
  await loadLock(async () => {
@@ -82,27 +100,33 @@ const createCustomPersister = (
82
100
  if (listening) {
83
101
  delPersisterListener(listeningHandle);
84
102
  listeningHandle = void 0;
85
- listening = false;
103
+ listening = 0;
86
104
  }
87
105
  return persister;
88
106
  },
89
107
  save: async (getTransactionChanges) => {
90
- /* istanbul ignore else */
91
- if (loadSave != 1) {
92
- loadSave = 2;
93
- {
94
- saves++;
108
+ await persister.schedule(async () => {
109
+ /* istanbul ignore else */
110
+ if (loadSave != 1) {
111
+ loadSave = 2;
112
+ {
113
+ saves++;
114
+ }
115
+ try {
116
+ await setPersisted(store.getContent, getTransactionChanges);
117
+ } catch {}
118
+ loadSave = 0;
95
119
  }
96
- await setPersisted(store.getContent, getTransactionChanges);
97
- loadSave = 0;
98
- }
120
+ });
99
121
  return persister;
100
122
  },
101
123
  startAutoSave: async () => {
102
124
  await persister.stopAutoSave().save();
103
125
  listenerId = store.addDidFinishTransactionListener(
104
- (_store, getTransactionChanges) =>
105
- persister.save(getTransactionChanges),
126
+ (_store, getTransactionChanges) => {
127
+ const transactionChanges = getTransactionChanges();
128
+ persister.save(() => transactionChanges);
129
+ },
106
130
  );
107
131
  return persister;
108
132
  },
@@ -110,6 +134,11 @@ const createCustomPersister = (
110
134
  ifNotUndefined(listenerId, store.delListener);
111
135
  return persister;
112
136
  },
137
+ schedule: async (...actions) => {
138
+ arrayPush(scheduledActions, ...actions);
139
+ await run();
140
+ return persister;
141
+ },
113
142
  getStore: () => store,
114
143
  destroy: () => persister.stopAutoLoad().stopAutoSave(),
115
144
  getStats: () => ({loads, saves}),
@@ -273,7 +302,7 @@ const yMapMatch = (yMapOrParent, idInParent, obj, set) => {
273
302
  }
274
303
  return changed;
275
304
  };
276
- const createYjsPersister = (store, yDoc, yMapName = 'tinybase') => {
305
+ const createYjsPersister = (store, yDoc, yMapName = TINYBASE) => {
277
306
  const yContent = yDoc.getMap(yMapName);
278
307
  const getPersisted = async () =>
279
308
  yContent.size
@@ -1,3 +1,6 @@
1
+ const arrayPush = (array, ...values) => array.push(...values);
2
+ const arrayShift = (array) => array.shift();
3
+
1
4
  const isUndefined = (thing) => thing == void 0;
2
5
  const ifNotUndefined = (value, then, otherwise) =>
3
6
  isUndefined(value) ? otherwise?.() : then(value);
@@ -16,8 +19,23 @@ const createCustomPersister = (
16
19
  let loadSave = 0;
17
20
  let loads = 0;
18
21
  let saves = 0;
19
- let listening = false;
22
+ let running = 0;
23
+ let listening = 0;
24
+ let action;
20
25
  let listeningHandle;
26
+ const scheduledActions = [];
27
+ const run = async () => {
28
+ /* istanbul ignore else */
29
+ if (!running) {
30
+ running = 1;
31
+ while (!isUndefined((action = arrayShift(scheduledActions)))) {
32
+ try {
33
+ await action();
34
+ } catch {}
35
+ }
36
+ running = 0;
37
+ }
38
+ };
21
39
  const loadLock = async (actions) => {
22
40
  /* istanbul ignore else */
23
41
  if (loadSave != 2) {
@@ -32,18 +50,18 @@ const createCustomPersister = (
32
50
  const persister = {
33
51
  load: async (initialTables = {}, initialValues = {}) => {
34
52
  await loadLock(async () => {
35
- let content;
36
53
  try {
37
- content = await getPersisted();
38
- } catch {}
39
- store.setContent(content ?? [initialTables, initialValues]);
54
+ store.setContent(await getPersisted());
55
+ } catch {
56
+ store.setContent([initialTables, initialValues]);
57
+ }
40
58
  });
41
59
  return persister;
42
60
  },
43
61
  startAutoLoad: async (initialTables = {}, initialValues = {}) => {
44
62
  persister.stopAutoLoad();
45
63
  await persister.load(initialTables, initialValues);
46
- listening = true;
64
+ listening = 1;
47
65
  listeningHandle = addPersisterListener(
48
66
  async (getContent, getTransactionChanges) => {
49
67
  await loadLock(async () => {
@@ -63,27 +81,33 @@ const createCustomPersister = (
63
81
  if (listening) {
64
82
  delPersisterListener(listeningHandle);
65
83
  listeningHandle = void 0;
66
- listening = false;
84
+ listening = 0;
67
85
  }
68
86
  return persister;
69
87
  },
70
88
  save: async (getTransactionChanges) => {
71
- /* istanbul ignore else */
72
- if (loadSave != 1) {
73
- loadSave = 2;
74
- {
75
- saves++;
89
+ await persister.schedule(async () => {
90
+ /* istanbul ignore else */
91
+ if (loadSave != 1) {
92
+ loadSave = 2;
93
+ {
94
+ saves++;
95
+ }
96
+ try {
97
+ await setPersisted(store.getContent, getTransactionChanges);
98
+ } catch {}
99
+ loadSave = 0;
76
100
  }
77
- await setPersisted(store.getContent, getTransactionChanges);
78
- loadSave = 0;
79
- }
101
+ });
80
102
  return persister;
81
103
  },
82
104
  startAutoSave: async () => {
83
105
  await persister.stopAutoSave().save();
84
106
  listenerId = store.addDidFinishTransactionListener(
85
- (_store, getTransactionChanges) =>
86
- persister.save(getTransactionChanges),
107
+ (_store, getTransactionChanges) => {
108
+ const transactionChanges = getTransactionChanges();
109
+ persister.save(() => transactionChanges);
110
+ },
87
111
  );
88
112
  return persister;
89
113
  },
@@ -91,6 +115,11 @@ const createCustomPersister = (
91
115
  ifNotUndefined(listenerId, store.delListener);
92
116
  return persister;
93
117
  },
118
+ schedule: async (...actions) => {
119
+ arrayPush(scheduledActions, ...actions);
120
+ await run();
121
+ return persister;
122
+ },
94
123
  getStore: () => store,
95
124
  destroy: () => persister.stopAutoLoad().stopAutoSave(),
96
125
  getStats: () => ({loads, saves}),
@@ -30,7 +30,6 @@ const arraySort = (array, sorter) => array.sort(sorter);
30
30
  const arrayForEach = (array, cb) => array.forEach(cb);
31
31
  const arrayMap = (array, cb) => array.map(cb);
32
32
  const arrayLength = (array) => array.length;
33
- const arrayIsEmpty = (array) => arrayLength(array) == 0;
34
33
  const arrayReduce = (array, cb, initial) => array.reduce(cb, initial);
35
34
  const arraySlice = (array, start, end) => array.slice(start, end);
36
35
  const arrayPush = (array, ...values) => array.push(...values);
@@ -68,10 +67,14 @@ const isObject = (obj) =>
68
67
  isInstanceOf(obj, object) && obj.constructor == object;
69
68
  const objGet = (obj, id) => ifNotUndefined(obj, (obj2) => obj2[id]);
70
69
  const objHas = (obj, id) => !isUndefined(objGet(obj, id));
71
- const objDel = (obj, id) => delete obj[id];
70
+ const objDel = (obj, id) => {
71
+ delete obj[id];
72
+ return obj;
73
+ };
72
74
  const objMap = (obj, cb) =>
73
75
  arrayMap(object.entries(obj), ([id, value]) => cb(value, id));
74
- const objIsEmpty = (obj) => isObject(obj) && arrayIsEmpty(objIds(obj));
76
+ const objSize = (obj) => arrayLength(objIds(obj));
77
+ const objIsEmpty = (obj) => isObject(obj) && objSize(obj) == 0;
75
78
 
76
79
  const collSizeN = (collSizer) => (coll) =>
77
80
  arrayReduce(collValues(coll), (total, coll2) => total + collSizer(coll2), 0);
@@ -101,6 +104,11 @@ const mapEnsure = (map, key, getDefaultValue) => {
101
104
  }
102
105
  return mapGet(map, key);
103
106
  };
107
+ const mapMatch = (map, obj, set, del = mapSet) => {
108
+ objMap(obj, (value, id) => set(map, id, value));
109
+ mapForEach(map, (id) => (objHas(obj, id) ? 0 : del(map, id)));
110
+ return map;
111
+ };
104
112
  const mapToObj = (map, mapValue, excludeValue) => {
105
113
  const obj = {};
106
114
  collForEach(map, (value, id) => {
@@ -263,11 +271,6 @@ const setOrDelValue = (store, valueId, value) =>
263
271
 
264
272
  const defaultSorter = (sortKey1, sortKey2) => (sortKey1 < sortKey2 ? -1 : 1);
265
273
 
266
- const mapMatch = (map, obj, set, del = mapSet) => {
267
- objMap(obj, (value, id2) => set(map, id2, value));
268
- mapForEach(map, (id2) => (objHas(obj, id2) ? 0 : del(map, id2)));
269
- return map;
270
- };
271
274
  const validate = (obj, validateChild, onInvalidObj) => {
272
275
  if (isUndefined(obj) || !isObject(obj) || objIsEmpty(obj) || objFrozen(obj)) {
273
276
  onInvalidObj?.();
@@ -293,6 +296,7 @@ const createStore = () => {
293
296
  let valuesTouched = false;
294
297
  let transactions = 0;
295
298
  const changedTableIds = mapNew();
299
+ const changedTableCellIds = mapNew();
296
300
  const changedRowIds = mapNew();
297
301
  const changedCellIds = mapNew();
298
302
  const changedCells = mapNew();
@@ -306,11 +310,13 @@ const createStore = () => {
306
310
  const valuesDefaulted = mapNew();
307
311
  const valuesNonDefaulted = setNew();
308
312
  const tablePoolFunctions = mapNew();
313
+ const tableCellIds = mapNew();
309
314
  const tablesMap = mapNew();
310
315
  const valuesMap = mapNew();
311
316
  const tablesListeners = pairNewMap();
312
317
  const tableIdsListeners = pairNewMap();
313
318
  const tableListeners = pairNewMap();
319
+ const tableCellIdsListeners = pairNewMap();
314
320
  const rowIdsListeners = pairNewMap();
315
321
  const sortedRowIdsListeners = pairNewMap();
316
322
  const rowListeners = pairNewMap();
@@ -499,6 +505,8 @@ const createStore = () => {
499
505
  mapMatch(
500
506
  mapEnsure(tablesMap, tableId, () => {
501
507
  tableIdsChanged(tableId, 1);
508
+ mapSet(tablePoolFunctions, tableId, getPoolFunctions());
509
+ mapSet(tableCellIds, tableId, mapNew());
502
510
  return mapNew();
503
511
  }),
504
512
  table,
@@ -559,7 +567,7 @@ const createStore = () => {
559
567
  }
560
568
  };
561
569
  const getNewRowId = (tableId, reuse) => {
562
- const [getId] = mapEnsure(tablePoolFunctions, tableId, getPoolFunctions);
570
+ const [getId] = mapGet(tablePoolFunctions, tableId);
563
571
  const rowId = getId(reuse);
564
572
  if (!collHas(mapGet(tablesMap, tableId), rowId)) {
565
573
  return rowId;
@@ -570,11 +578,7 @@ const createStore = () => {
570
578
  mapGet(tablesMap, tableId) ?? setValidTable(tableId, {});
571
579
  const delValidTable = (tableId) => setValidTable(tableId, {});
572
580
  const delValidRow = (tableId, tableMap, rowId) => {
573
- const [, releaseId] = mapEnsure(
574
- tablePoolFunctions,
575
- tableId,
576
- getPoolFunctions,
577
- );
581
+ const [, releaseId] = mapGet(tablePoolFunctions, tableId);
578
582
  releaseId(rowId);
579
583
  setValidRow(tableId, tableMap, rowId, {}, true);
580
584
  };
@@ -598,6 +602,7 @@ const createStore = () => {
598
602
  tableIdsChanged(tableId, -1);
599
603
  mapSet(tablesMap, tableId);
600
604
  mapSet(tablePoolFunctions, tableId);
605
+ mapSet(tableCellIds, tableId);
601
606
  }
602
607
  }
603
608
  };
@@ -618,12 +623,30 @@ const createStore = () => {
618
623
  rowId,
619
624
  addedOrRemoved,
620
625
  );
621
- const cellIdsChanged = (tableId, rowId, cellId, addedOrRemoved) =>
626
+ const cellIdsChanged = (tableId, rowId, cellId, addedOrRemoved) => {
627
+ const cellIds = mapGet(tableCellIds, tableId);
628
+ const count = mapGet(cellIds, cellId) ?? 0;
629
+ if (
630
+ (count == 0 && addedOrRemoved == 1) ||
631
+ (count == 1 && addedOrRemoved == -1)
632
+ ) {
633
+ idsChanged(
634
+ mapEnsure(changedTableCellIds, tableId, mapNew),
635
+ cellId,
636
+ addedOrRemoved,
637
+ );
638
+ }
639
+ mapSet(
640
+ cellIds,
641
+ cellId,
642
+ count != -addedOrRemoved ? count + addedOrRemoved : null,
643
+ );
622
644
  idsChanged(
623
645
  mapEnsure(mapEnsure(changedCellIds, tableId, mapNew), rowId, mapNew),
624
646
  cellId,
625
647
  addedOrRemoved,
626
648
  );
649
+ };
627
650
  const cellChanged = (tableId, rowId, cellId, oldCell, newCell) =>
628
651
  (mapEnsure(
629
652
  mapEnsure(mapEnsure(changedCells, tableId, mapNew), rowId, mapNew),
@@ -694,7 +717,7 @@ const createStore = () => {
694
717
  : 0;
695
718
  const callIdsListenersIfChanged = (listeners, changedIds, ids) => {
696
719
  if (!collIsEmpty(changedIds)) {
697
- callListeners(listeners, ids);
720
+ callListeners(listeners, ids, () => mapToObj(changedIds));
698
721
  return 1;
699
722
  }
700
723
  };
@@ -704,6 +727,7 @@ const createStore = () => {
704
727
  );
705
728
  const emptyIdListeners =
706
729
  collIsEmpty(cellIdsListeners[mutator]) &&
730
+ collIsEmpty(tableCellIdsListeners[mutator]) &&
707
731
  collIsEmpty(rowIdsListeners[mutator]) &&
708
732
  emptySortedRowIdListeners &&
709
733
  collIsEmpty(tableIdsListeners[mutator]);
@@ -716,22 +740,29 @@ const createStore = () => {
716
740
  const changes = mutator
717
741
  ? [
718
742
  mapClone(changedTableIds),
743
+ mapClone2(changedTableCellIds),
719
744
  mapClone2(changedRowIds),
720
745
  mapClone3(changedCellIds),
721
746
  mapClone3(changedCells),
722
747
  ]
723
- : [changedTableIds, changedRowIds, changedCellIds, changedCells];
748
+ : [
749
+ changedTableIds,
750
+ changedTableCellIds,
751
+ changedRowIds,
752
+ changedCellIds,
753
+ changedCells,
754
+ ];
724
755
  if (!emptyIdListeners) {
725
- collForEach(changes[2], (rowCellIds, tableId) =>
726
- collForEach(rowCellIds, (changedIds, rowId) =>
727
- callIdsListenersIfChanged(cellIdsListeners[mutator], changedIds, [
728
- tableId,
729
- rowId,
730
- ]),
756
+ callIdsListenersIfChanged(tableIdsListeners[mutator], changes[0]);
757
+ collForEach(changes[1], (changedIds, tableId) =>
758
+ callIdsListenersIfChanged(
759
+ tableCellIdsListeners[mutator],
760
+ changedIds,
761
+ [tableId],
731
762
  ),
732
763
  );
733
764
  const calledSortableTableIds = setNew();
734
- collForEach(changes[1], (changedIds, tableId) => {
765
+ collForEach(changes[2], (changedIds, tableId) => {
735
766
  if (
736
767
  callIdsListenersIfChanged(rowIdsListeners[mutator], changedIds, [
737
768
  tableId,
@@ -743,7 +774,7 @@ const createStore = () => {
743
774
  }
744
775
  });
745
776
  if (!emptySortedRowIdListeners) {
746
- collForEach(changes[3], (rows, tableId) => {
777
+ collForEach(changes[4], (rows, tableId) => {
747
778
  if (!collHas(calledSortableTableIds, tableId)) {
748
779
  const sortableCellIds = setNew();
749
780
  collForEach(rows, (cells) =>
@@ -762,11 +793,18 @@ const createStore = () => {
762
793
  }
763
794
  });
764
795
  }
765
- callIdsListenersIfChanged(tableIdsListeners[mutator], changes[0]);
796
+ collForEach(changes[3], (rowCellIds, tableId) =>
797
+ collForEach(rowCellIds, (changedIds, rowId) =>
798
+ callIdsListenersIfChanged(cellIdsListeners[mutator], changedIds, [
799
+ tableId,
800
+ rowId,
801
+ ]),
802
+ ),
803
+ );
766
804
  }
767
805
  if (!emptyOtherListeners) {
768
806
  let tablesChanged;
769
- collForEach(changes[3], (rows, tableId) => {
807
+ collForEach(changes[4], (rows, tableId) => {
770
808
  let tableChanged;
771
809
  collForEach(rows, (cells, rowId) => {
772
810
  let rowChanged;
@@ -878,6 +916,8 @@ const createStore = () => {
878
916
  const getTables = () => mapToObj3(tablesMap);
879
917
  const getTableIds = () => mapKeys(tablesMap);
880
918
  const getTable = (tableId) => mapToObj2(mapGet(tablesMap, id(tableId)));
919
+ const getTableCellIds = (tableId) =>
920
+ mapKeys(mapGet(tableCellIds, id(tableId)));
881
921
  const getRowIds = (tableId) => mapKeys(mapGet(tablesMap, id(tableId)));
882
922
  const getSortedRowIds = (tableId, cellId, descending, offset = 0, limit) =>
883
923
  arrayMap(
@@ -906,6 +946,8 @@ const createStore = () => {
906
946
  const getValue = (valueId) => mapGet(valuesMap, id(valueId));
907
947
  const hasTables = () => !collIsEmpty(tablesMap);
908
948
  const hasTable = (tableId) => collHas(tablesMap, id(tableId));
949
+ const hasTableCell = (tableId, cellId) =>
950
+ collHas(mapGet(tableCellIds, id(tableId)), id(cellId));
909
951
  const hasRow = (tableId, rowId) =>
910
952
  collHas(mapGet(tablesMap, id(tableId)), id(rowId));
911
953
  const hasCell = (tableId, rowId, cellId) =>
@@ -1219,6 +1261,7 @@ const createStore = () => {
1219
1261
  arrayForEach(
1220
1262
  [
1221
1263
  changedTableIds,
1264
+ changedTableCellIds,
1222
1265
  changedRowIds,
1223
1266
  changedCellIds,
1224
1267
  changedCells,
@@ -1243,6 +1286,8 @@ const createStore = () => {
1243
1286
  ),
1244
1287
  ),
1245
1288
  );
1289
+ const forEachTableCell = (tableId, tableCellCallback) =>
1290
+ mapForEach(mapGet(tableCellIds, id(tableId)), tableCellCallback);
1246
1291
  const forEachRow = (tableId, rowCallback) =>
1247
1292
  collForEach(mapGet(tablesMap, id(tableId)), (rowMap, rowId) =>
1248
1293
  rowCallback(rowId, (cellCallback) => mapForEach(rowMap, cellCallback)),
@@ -1310,6 +1355,7 @@ const createStore = () => {
1310
1355
  const getListenerStats = () => ({
1311
1356
  tables: pairCollSize2(tablesListeners),
1312
1357
  tableIds: pairCollSize2(tableIdsListeners),
1358
+ tableCellIds: pairCollSize2(tableCellIdsListeners),
1313
1359
  table: pairCollSize2(tableListeners),
1314
1360
  rowIds: pairCollSize2(rowIdsListeners),
1315
1361
  sortedRowIds: pairCollSize2(sortedRowIdsListeners),
@@ -1330,6 +1376,7 @@ const createStore = () => {
1330
1376
  getTables,
1331
1377
  getTableIds,
1332
1378
  getTable,
1379
+ getTableCellIds,
1333
1380
  getRowIds,
1334
1381
  getSortedRowIds,
1335
1382
  getRow,
@@ -1340,6 +1387,7 @@ const createStore = () => {
1340
1387
  getValue,
1341
1388
  hasTables,
1342
1389
  hasTable,
1390
+ hasTableCell,
1343
1391
  hasRow,
1344
1392
  hasCell,
1345
1393
  hasValues,
@@ -1380,6 +1428,7 @@ const createStore = () => {
1380
1428
  startTransaction,
1381
1429
  finishTransaction,
1382
1430
  forEachTable,
1431
+ forEachTableCell,
1383
1432
  forEachRow,
1384
1433
  forEachCell,
1385
1434
  forEachValue,
@@ -1397,6 +1446,7 @@ const createStore = () => {
1397
1446
  [TABLES]: [0, tablesListeners],
1398
1447
  [TABLE_IDS]: [0, tableIdsListeners],
1399
1448
  [TABLE]: [1, tableListeners, [getTableIds]],
1449
+ [TABLE + CELL_IDS]: [1, tableCellIdsListeners, [getTableIds]],
1400
1450
  [ROW_IDS]: [1, rowIdsListeners, [getTableIds]],
1401
1451
  [ROW]: [2, rowListeners, [getTableIds, getRowIds]],
1402
1452
  [CELL_IDS]: [2, cellIdsListeners, [getTableIds, getRowIds]],