tinybase 4.0.0-beta.0 → 4.0.0-beta.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (203) hide show
  1. package/bin/cli.js +1 -1
  2. package/lib/checkpoints.js +1 -1
  3. package/lib/checkpoints.js.gz +0 -0
  4. package/lib/cjs/checkpoints.cjs +1 -1
  5. package/lib/cjs/checkpoints.cjs.gz +0 -0
  6. package/lib/cjs/indexes.cjs +1 -1
  7. package/lib/cjs/indexes.cjs.gz +0 -0
  8. package/lib/cjs/metrics.cjs +1 -1
  9. package/lib/cjs/metrics.cjs.gz +0 -0
  10. package/lib/cjs/persister-browser.cjs +1 -0
  11. package/lib/cjs/persister-browser.cjs.gz +0 -0
  12. package/lib/cjs/persister-file.cjs +1 -0
  13. package/lib/cjs/persister-file.cjs.gz +0 -0
  14. package/lib/cjs/persister-remote.cjs +1 -0
  15. package/lib/cjs/persister-remote.cjs.gz +0 -0
  16. package/lib/cjs/persister-yjs.cjs +1 -1
  17. package/lib/cjs/persister-yjs.cjs.gz +0 -0
  18. package/lib/cjs/persisters.cjs +1 -1
  19. package/lib/cjs/persisters.cjs.gz +0 -0
  20. package/lib/cjs/queries.cjs +1 -1
  21. package/lib/cjs/queries.cjs.gz +0 -0
  22. package/lib/cjs/relationships.cjs +1 -1
  23. package/lib/cjs/relationships.cjs.gz +0 -0
  24. package/lib/cjs/store.cjs +1 -1
  25. package/lib/cjs/store.cjs.gz +0 -0
  26. package/lib/cjs/tinybase.cjs +1 -1
  27. package/lib/cjs/tinybase.cjs.gz +0 -0
  28. package/lib/cjs/tools.cjs +1 -1
  29. package/lib/cjs/tools.cjs.gz +0 -0
  30. package/lib/cjs/ui-react.cjs +1 -1
  31. package/lib/cjs/ui-react.cjs.gz +0 -0
  32. package/lib/cjs-es6/checkpoints.cjs +1 -1
  33. package/lib/cjs-es6/checkpoints.cjs.gz +0 -0
  34. package/lib/cjs-es6/indexes.cjs +1 -1
  35. package/lib/cjs-es6/indexes.cjs.gz +0 -0
  36. package/lib/cjs-es6/metrics.cjs +1 -1
  37. package/lib/cjs-es6/metrics.cjs.gz +0 -0
  38. package/lib/cjs-es6/persister-browser.cjs +1 -0
  39. package/lib/cjs-es6/persister-browser.cjs.gz +0 -0
  40. package/lib/cjs-es6/persister-file.cjs +1 -0
  41. package/lib/cjs-es6/persister-file.cjs.gz +0 -0
  42. package/lib/cjs-es6/persister-remote.cjs +1 -0
  43. package/lib/cjs-es6/persister-remote.cjs.gz +0 -0
  44. package/lib/cjs-es6/persister-yjs.cjs +1 -1
  45. package/lib/cjs-es6/persister-yjs.cjs.gz +0 -0
  46. package/lib/cjs-es6/persisters.cjs +1 -1
  47. package/lib/cjs-es6/persisters.cjs.gz +0 -0
  48. package/lib/cjs-es6/queries.cjs +1 -1
  49. package/lib/cjs-es6/queries.cjs.gz +0 -0
  50. package/lib/cjs-es6/relationships.cjs +1 -1
  51. package/lib/cjs-es6/relationships.cjs.gz +0 -0
  52. package/lib/cjs-es6/store.cjs +1 -1
  53. package/lib/cjs-es6/store.cjs.gz +0 -0
  54. package/lib/cjs-es6/tinybase.cjs +1 -1
  55. package/lib/cjs-es6/tinybase.cjs.gz +0 -0
  56. package/lib/cjs-es6/tools.cjs +1 -1
  57. package/lib/cjs-es6/tools.cjs.gz +0 -0
  58. package/lib/cjs-es6/ui-react.cjs +1 -1
  59. package/lib/cjs-es6/ui-react.cjs.gz +0 -0
  60. package/lib/debug/checkpoints.js +3 -3
  61. package/lib/debug/indexes.js +3 -3
  62. package/lib/debug/metrics.js +3 -3
  63. package/lib/debug/persister-browser.js +147 -0
  64. package/lib/debug/persister-file.js +140 -0
  65. package/lib/debug/persister-remote.js +159 -0
  66. package/lib/debug/persister-yjs.js +234 -40
  67. package/lib/debug/persisters.js +43 -133
  68. package/lib/debug/queries.js +5 -5
  69. package/lib/debug/relationships.js +3 -3
  70. package/lib/debug/store.js +137 -87
  71. package/lib/debug/tinybase.js +179 -215
  72. package/lib/debug/tools.js +9 -9
  73. package/lib/es6/checkpoints.js +1 -1
  74. package/lib/es6/checkpoints.js.gz +0 -0
  75. package/lib/es6/indexes.js +1 -1
  76. package/lib/es6/indexes.js.gz +0 -0
  77. package/lib/es6/metrics.js +1 -1
  78. package/lib/es6/metrics.js.gz +0 -0
  79. package/lib/es6/persister-browser.js +1 -0
  80. package/lib/es6/persister-browser.js.gz +0 -0
  81. package/lib/es6/persister-file.js +1 -0
  82. package/lib/es6/persister-file.js.gz +0 -0
  83. package/lib/es6/persister-remote.js +1 -0
  84. package/lib/es6/persister-remote.js.gz +0 -0
  85. package/lib/es6/persister-yjs.js +1 -1
  86. package/lib/es6/persister-yjs.js.gz +0 -0
  87. package/lib/es6/persisters.js +1 -1
  88. package/lib/es6/persisters.js.gz +0 -0
  89. package/lib/es6/queries.js +1 -1
  90. package/lib/es6/queries.js.gz +0 -0
  91. package/lib/es6/relationships.js +1 -1
  92. package/lib/es6/relationships.js.gz +0 -0
  93. package/lib/es6/store.js +1 -1
  94. package/lib/es6/store.js.gz +0 -0
  95. package/lib/es6/tinybase.js +1 -1
  96. package/lib/es6/tinybase.js.gz +0 -0
  97. package/lib/es6/tools.js +1 -1
  98. package/lib/es6/tools.js.gz +0 -0
  99. package/lib/es6/ui-react.js +1 -1
  100. package/lib/es6/ui-react.js.gz +0 -0
  101. package/lib/indexes.js +1 -1
  102. package/lib/indexes.js.gz +0 -0
  103. package/lib/metrics.js +1 -1
  104. package/lib/metrics.js.gz +0 -0
  105. package/lib/persister-browser.js +1 -0
  106. package/lib/persister-browser.js.gz +0 -0
  107. package/lib/persister-file.js +1 -0
  108. package/lib/persister-file.js.gz +0 -0
  109. package/lib/persister-remote.js +1 -0
  110. package/lib/persister-remote.js.gz +0 -0
  111. package/lib/persister-yjs.js +1 -1
  112. package/lib/persister-yjs.js.gz +0 -0
  113. package/lib/persisters.js +1 -1
  114. package/lib/persisters.js.gz +0 -0
  115. package/lib/queries.js +1 -1
  116. package/lib/queries.js.gz +0 -0
  117. package/lib/relationships.js +1 -1
  118. package/lib/relationships.js.gz +0 -0
  119. package/lib/store.js +1 -1
  120. package/lib/store.js.gz +0 -0
  121. package/lib/tinybase.js +1 -1
  122. package/lib/tinybase.js.gz +0 -0
  123. package/lib/tools.js +1 -1
  124. package/lib/tools.js.gz +0 -0
  125. package/lib/types/persister-browser.d.ts +85 -0
  126. package/lib/types/persister-file.d.ts +41 -0
  127. package/lib/types/persister-remote.d.ts +60 -0
  128. package/lib/types/persister-yjs.d.ts +70 -8
  129. package/lib/types/persisters.d.ts +73 -181
  130. package/lib/types/queries.d.ts +52 -52
  131. package/lib/types/store.d.ts +499 -139
  132. package/lib/types/tools.d.ts +16 -16
  133. package/lib/types/ui-react.d.ts +56 -47
  134. package/lib/types/with-schemas/internal/ui-react.d.ts +2 -2
  135. package/lib/types/with-schemas/persister-browser.d.ts +103 -0
  136. package/lib/types/with-schemas/persister-file.d.ts +50 -0
  137. package/lib/types/with-schemas/persister-remote.d.ts +71 -0
  138. package/lib/types/with-schemas/persister-yjs.d.ts +72 -9
  139. package/lib/types/with-schemas/persisters.d.ts +99 -223
  140. package/lib/types/with-schemas/queries.d.ts +52 -52
  141. package/lib/types/with-schemas/store.d.ts +595 -153
  142. package/lib/types/with-schemas/tools.d.ts +16 -16
  143. package/lib/types/with-schemas/ui-react.d.ts +54 -45
  144. package/lib/ui-react.js +1 -1
  145. package/lib/ui-react.js.gz +0 -0
  146. package/lib/umd/checkpoints.js +1 -1
  147. package/lib/umd/checkpoints.js.gz +0 -0
  148. package/lib/umd/indexes.js +1 -1
  149. package/lib/umd/indexes.js.gz +0 -0
  150. package/lib/umd/metrics.js +1 -1
  151. package/lib/umd/metrics.js.gz +0 -0
  152. package/lib/umd/persister-browser.js +1 -0
  153. package/lib/umd/persister-browser.js.gz +0 -0
  154. package/lib/umd/persister-file.js +1 -0
  155. package/lib/umd/persister-file.js.gz +0 -0
  156. package/lib/umd/persister-remote.js +1 -0
  157. package/lib/umd/persister-remote.js.gz +0 -0
  158. package/lib/umd/persister-yjs.js +1 -1
  159. package/lib/umd/persister-yjs.js.gz +0 -0
  160. package/lib/umd/persisters.js +1 -1
  161. package/lib/umd/persisters.js.gz +0 -0
  162. package/lib/umd/queries.js +1 -1
  163. package/lib/umd/queries.js.gz +0 -0
  164. package/lib/umd/relationships.js +1 -1
  165. package/lib/umd/relationships.js.gz +0 -0
  166. package/lib/umd/store.js +1 -1
  167. package/lib/umd/store.js.gz +0 -0
  168. package/lib/umd/tinybase.js +1 -1
  169. package/lib/umd/tinybase.js.gz +0 -0
  170. package/lib/umd/tools.js +1 -1
  171. package/lib/umd/tools.js.gz +0 -0
  172. package/lib/umd/ui-react.js +1 -1
  173. package/lib/umd/ui-react.js.gz +0 -0
  174. package/lib/umd-es6/checkpoints.js +1 -1
  175. package/lib/umd-es6/checkpoints.js.gz +0 -0
  176. package/lib/umd-es6/indexes.js +1 -1
  177. package/lib/umd-es6/indexes.js.gz +0 -0
  178. package/lib/umd-es6/metrics.js +1 -1
  179. package/lib/umd-es6/metrics.js.gz +0 -0
  180. package/lib/umd-es6/persister-browser.js +1 -0
  181. package/lib/umd-es6/persister-browser.js.gz +0 -0
  182. package/lib/umd-es6/persister-file.js +1 -0
  183. package/lib/umd-es6/persister-file.js.gz +0 -0
  184. package/lib/umd-es6/persister-remote.js +1 -0
  185. package/lib/umd-es6/persister-remote.js.gz +0 -0
  186. package/lib/umd-es6/persister-yjs.js +1 -1
  187. package/lib/umd-es6/persister-yjs.js.gz +0 -0
  188. package/lib/umd-es6/persisters.js +1 -1
  189. package/lib/umd-es6/persisters.js.gz +0 -0
  190. package/lib/umd-es6/queries.js +1 -1
  191. package/lib/umd-es6/queries.js.gz +0 -0
  192. package/lib/umd-es6/relationships.js +1 -1
  193. package/lib/umd-es6/relationships.js.gz +0 -0
  194. package/lib/umd-es6/store.js +1 -1
  195. package/lib/umd-es6/store.js.gz +0 -0
  196. package/lib/umd-es6/tinybase.js +1 -1
  197. package/lib/umd-es6/tinybase.js.gz +0 -0
  198. package/lib/umd-es6/tools.js +1 -1
  199. package/lib/umd-es6/tools.js.gz +0 -0
  200. package/lib/umd-es6/ui-react.js +1 -1
  201. package/lib/umd-es6/ui-react.js.gz +0 -0
  202. package/package.json +15 -15
  203. package/readme.md +2 -2
@@ -1,5 +1,3 @@
1
- import {promises, watch} from 'fs';
2
-
3
1
  const getTypeOf = (thing) => typeof thing;
4
2
  const EMPTY_STRING = '';
5
3
  const STRING = getTypeOf(EMPTY_STRING);
@@ -8,7 +6,6 @@ const NUMBER = getTypeOf(0);
8
6
  const FUNCTION = getTypeOf(getTypeOf);
9
7
  const TYPE = 'type';
10
8
  const DEFAULT = 'default';
11
- const UTF8 = 'utf8';
12
9
  const SUM = 'sum';
13
10
  const AVG = 'avg';
14
11
  const MIN = 'min';
@@ -48,7 +45,6 @@ const arraySum = (array) => arrayReduce(array, (i, j) => i + j, 0);
48
45
  const arrayLength = (array) => array.length;
49
46
  const arrayIsEmpty = (array) => arrayLength(array) == 0;
50
47
  const arrayReduce = (array, cb, initial) => array.reduce(cb, initial);
51
- const arrayFilter = (array, cb) => array.filter(cb);
52
48
  const arraySlice = (array, start, end) => array.slice(start, end);
53
49
  const arrayClear = (array, to) => array.splice(0, to);
54
50
  const arrayPush = (array, ...values) => array.push(...values);
@@ -84,6 +80,19 @@ const isArray = (thing) => Array.isArray(thing);
84
80
  const test = (regex, subject) => regex.test(subject);
85
81
  const getUndefined = () => void 0;
86
82
 
83
+ const object = Object;
84
+ const objIds = object.keys;
85
+ const objFrozen = object.isFrozen;
86
+ const objFreeze = object.freeze;
87
+ const isObject = (obj) =>
88
+ isInstanceOf(obj, object) && obj.constructor == object;
89
+ const objGet = (obj, id) => ifNotUndefined(obj, (obj2) => obj2[id]);
90
+ const objHas = (obj, id) => !isUndefined(objGet(obj, id));
91
+ const objDel = (obj, id) => delete obj[id];
92
+ const objMap = (obj, cb) =>
93
+ arrayMap(object.entries(obj), ([id, value]) => cb(value, id));
94
+ const objIsEmpty = (obj) => isObject(obj) && arrayIsEmpty(objIds(obj));
95
+
87
96
  const collSizeN = (collSizer) => (coll) =>
88
97
  arrayReduce(collValues(coll), (total, coll2) => total + collSizer(coll2), 0);
89
98
  const collSize = (coll) => coll.size;
@@ -112,23 +121,33 @@ const mapEnsure = (map, key, getDefaultValue) => {
112
121
  }
113
122
  return mapGet(map, key);
114
123
  };
115
- const mapToObj = (map, childMapper, childExclude) => {
124
+ const mapToObj = (map, mapValue, excludeValue) => {
116
125
  const obj = {};
117
- const mapper = childMapper ?? ((mapValue) => mapValue);
118
- collForEach(map, (value, key) =>
119
- ifNotUndefined(mapper(value), (mappedValue) =>
120
- childExclude?.(mappedValue) ? 0 : (obj[key] = mappedValue),
121
- ),
122
- );
126
+ collForEach(map, (value, id) => {
127
+ const mappedValue = mapValue ? mapValue(value, id) : value;
128
+ excludeValue?.(mappedValue, value) ? 0 : (obj[id] = mappedValue);
129
+ });
123
130
  return obj;
124
131
  };
125
- const mapClone = (map, childMapper) => {
132
+ const mapToObj2 = (map, mapValue, excludeValue) =>
133
+ mapToObj(
134
+ map,
135
+ (childMap) => mapToObj(childMap, mapValue, excludeValue),
136
+ objIsEmpty,
137
+ );
138
+ const mapToObj3 = (map, mapValue, excludeValue) =>
139
+ mapToObj(
140
+ map,
141
+ (childMap) => mapToObj2(childMap, mapValue, excludeValue),
142
+ objIsEmpty,
143
+ );
144
+ const mapClone = (map, mapValue) => {
126
145
  const map2 = mapNew();
127
- const mapper = childMapper ?? ((mapValue) => mapValue);
128
- collForEach(map, (value, key) => map2.set(key, mapper(value)));
146
+ collForEach(map, (value, key) => map2.set(key, mapValue?.(value) ?? value));
129
147
  return map2;
130
148
  };
131
149
  const mapClone2 = (map) => mapClone(map, mapClone);
150
+ const mapClone3 = (map) => mapClone(map, mapClone2);
132
151
  const visitTree = (node, path, ensureLeaf, pruneLeaf, p = 0) =>
133
152
  ifNotUndefined(
134
153
  (ensureLeaf ? mapEnsure : mapGet)(
@@ -414,19 +433,6 @@ const getListenerFunctions = (getThing) => {
414
433
  return [addListener, callListeners, delListener, callListener];
415
434
  };
416
435
 
417
- const object = Object;
418
- const objIds = object.keys;
419
- const objFrozen = object.isFrozen;
420
- const objFreeze = object.freeze;
421
- const isObject = (obj) =>
422
- isInstanceOf(obj, object) && obj.constructor == object;
423
- const objGet = (obj, id) => ifNotUndefined(obj, (obj2) => obj2[id]);
424
- const objHas = (obj, id) => !isUndefined(objGet(obj, id));
425
- const objDel = (obj, id) => delete obj[id];
426
- const objMap = (obj, cb) =>
427
- arrayMap(object.entries(obj), ([id, value]) => cb(value, id));
428
- const objIsEmpty = (obj) => isObject(obj) && arrayIsEmpty(objIds(obj));
429
-
430
436
  const createCheckpoints = getCreateFunction((store) => {
431
437
  let backwardIdsSize = 100;
432
438
  let currentId;
@@ -1016,72 +1022,86 @@ const createCustomPersister = (
1016
1022
  store,
1017
1023
  getPersisted,
1018
1024
  setPersisted,
1019
- startListeningToPersisted,
1020
- stopListeningToPersisted,
1025
+ addPersisterListener,
1026
+ delPersisterListener,
1021
1027
  ) => {
1022
- let tablesListenerId;
1023
- let valuesListenerId;
1028
+ let listenerId;
1024
1029
  let loadSave = 0;
1025
1030
  let loads = 0;
1026
1031
  let saves = 0;
1027
1032
  let listening = false;
1028
1033
  let listeningHandle;
1034
+ const loadLock = async (actions) => {
1035
+ /* istanbul ignore else */
1036
+ if (loadSave != 2) {
1037
+ loadSave = 1;
1038
+ {
1039
+ loads++;
1040
+ }
1041
+ await actions();
1042
+ loadSave = 0;
1043
+ }
1044
+ };
1029
1045
  const persister = {
1030
1046
  load: async (initialTables, initialValues) => {
1031
- /* istanbul ignore else */
1032
- if (loadSave != 2) {
1033
- loadSave = 1;
1034
- {
1035
- loads++;
1036
- }
1037
- const body = await getPersisted();
1038
- if (!isUndefined(body) && body != EMPTY_STRING) {
1039
- store.setJson(body);
1040
- } else {
1041
- store.transaction(() =>
1042
- store.setTables(initialTables).setValues(initialValues),
1043
- );
1044
- }
1045
- loadSave = 0;
1046
- }
1047
+ await loadLock(async () => {
1048
+ let content;
1049
+ try {
1050
+ content = await getPersisted();
1051
+ } catch {}
1052
+ store.setContent(content ?? [initialTables, initialValues]);
1053
+ });
1047
1054
  return persister;
1048
1055
  },
1049
1056
  startAutoLoad: async (initialTables, initialValues) => {
1050
1057
  persister.stopAutoLoad();
1051
1058
  await persister.load(initialTables, initialValues);
1052
1059
  listening = true;
1053
- listeningHandle = startListeningToPersisted(persister.load);
1060
+ listeningHandle = addPersisterListener(
1061
+ async (getContent, getTransactionChanges) => {
1062
+ await loadLock(async () => {
1063
+ if (getTransactionChanges) {
1064
+ store.setTransactionChanges(getTransactionChanges());
1065
+ } else {
1066
+ try {
1067
+ store.setContent(getContent?.() ?? (await getPersisted()));
1068
+ } catch {}
1069
+ }
1070
+ });
1071
+ },
1072
+ );
1054
1073
  return persister;
1055
1074
  },
1056
1075
  stopAutoLoad: () => {
1057
1076
  if (listening) {
1058
- stopListeningToPersisted(listeningHandle);
1077
+ delPersisterListener(listeningHandle);
1059
1078
  listeningHandle = void 0;
1060
1079
  listening = false;
1061
1080
  }
1062
1081
  return persister;
1063
1082
  },
1064
- save: async () => {
1083
+ save: async (getTransactionChanges) => {
1065
1084
  /* istanbul ignore else */
1066
1085
  if (loadSave != 1) {
1067
1086
  loadSave = 2;
1068
1087
  {
1069
1088
  saves++;
1070
1089
  }
1071
- await setPersisted(store.getJson());
1090
+ await setPersisted(store.getContent, getTransactionChanges);
1072
1091
  loadSave = 0;
1073
1092
  }
1074
1093
  return persister;
1075
1094
  },
1076
1095
  startAutoSave: async () => {
1077
1096
  await persister.stopAutoSave().save();
1078
- tablesListenerId = store.addTablesListener(persister.save);
1079
- valuesListenerId = store.addValuesListener(persister.save);
1097
+ listenerId = store.addDidFinishTransactionListener(
1098
+ (_store, getTransactionChanges) =>
1099
+ persister.save(getTransactionChanges),
1100
+ );
1080
1101
  return persister;
1081
1102
  },
1082
1103
  stopAutoSave: () => {
1083
- ifNotUndefined(tablesListenerId, store.delListener);
1084
- ifNotUndefined(valuesListenerId, store.delListener);
1104
+ ifNotUndefined(listenerId, store.delListener);
1085
1105
  return persister;
1086
1106
  },
1087
1107
  getStore: () => store,
@@ -1091,99 +1111,6 @@ const createCustomPersister = (
1091
1111
  return objFreeze(persister);
1092
1112
  };
1093
1113
 
1094
- const STORAGE = 'storage';
1095
- const WINDOW = globalThis.window;
1096
- const getStoragePersister = (store, storageName, storage) => {
1097
- const getPersisted = async () => storage.getItem(storageName);
1098
- const setPersisted = async (json) => storage.setItem(storageName, json);
1099
- const startListeningToPersisted = (didChange) => {
1100
- const listener = (event) => {
1101
- if (event.storageArea === storage && event.key === storageName) {
1102
- didChange();
1103
- }
1104
- };
1105
- WINDOW.addEventListener(STORAGE, listener);
1106
- return listener;
1107
- };
1108
- const stopListeningToPersisted = (listener) =>
1109
- WINDOW.removeEventListener(STORAGE, listener);
1110
- return createCustomPersister(
1111
- store,
1112
- getPersisted,
1113
- setPersisted,
1114
- startListeningToPersisted,
1115
- stopListeningToPersisted,
1116
- );
1117
- };
1118
- const createLocalPersister = (store, storageName) =>
1119
- getStoragePersister(store, storageName, localStorage);
1120
- const createSessionPersister = (store, storageName) =>
1121
- getStoragePersister(store, storageName, sessionStorage);
1122
-
1123
- const createFilePersister = (store, filePath) => {
1124
- const getPersisted = async () => {
1125
- try {
1126
- return await promises.readFile(filePath, UTF8);
1127
- } catch {}
1128
- };
1129
- const setPersisted = async (json) => {
1130
- try {
1131
- await promises.writeFile(filePath, json, UTF8);
1132
- } catch {}
1133
- };
1134
- const startListeningToPersisted = (didChange) => watch(filePath, didChange);
1135
- const stopListeningToPersisted = (watcher) => watcher?.close();
1136
- return createCustomPersister(
1137
- store,
1138
- getPersisted,
1139
- setPersisted,
1140
- startListeningToPersisted,
1141
- stopListeningToPersisted,
1142
- );
1143
- };
1144
-
1145
- const getETag = (response) => response.headers.get('ETag');
1146
- const createRemotePersister = (
1147
- store,
1148
- loadUrl,
1149
- saveUrl,
1150
- autoLoadIntervalSeconds,
1151
- ) => {
1152
- let lastEtag;
1153
- const getPersisted = async () => {
1154
- const response = await fetch(loadUrl);
1155
- lastEtag = getETag(response);
1156
- return response.text();
1157
- };
1158
- const setPersisted = async (json) =>
1159
- await fetch(saveUrl, {
1160
- method: 'POST',
1161
- headers: {'Content-Type': 'application/json'},
1162
- body: json,
1163
- });
1164
- const startListeningToPersisted = (didChange) =>
1165
- setInterval(async () => {
1166
- const response = await fetch(loadUrl, {method: 'HEAD'});
1167
- const currentEtag = getETag(response);
1168
- if (
1169
- !isUndefined(lastEtag) &&
1170
- !isUndefined(currentEtag) &&
1171
- currentEtag != lastEtag
1172
- ) {
1173
- lastEtag = currentEtag;
1174
- didChange();
1175
- }
1176
- }, autoLoadIntervalSeconds * 1e3);
1177
- const stopListeningToPersisted = (interval) => clearInterval(interval);
1178
- return createCustomPersister(
1179
- store,
1180
- getPersisted,
1181
- setPersisted,
1182
- startListeningToPersisted,
1183
- stopListeningToPersisted,
1184
- );
1185
- };
1186
-
1187
1114
  const createQueries = getCreateFunction((store) => {
1188
1115
  const createStore = store.createStore;
1189
1116
  const [
@@ -1813,16 +1740,12 @@ const createRelationships = getCreateFunction((store) => {
1813
1740
  const pairNew = (value) => [value, value];
1814
1741
  const pairCollSize2 = (pair, func = collSize2) => func(pair[0]) + func(pair[1]);
1815
1742
  const pairNewMap = () => [mapNew(), mapNew()];
1743
+ const pairClone = (array) => [...array];
1744
+ const pairIsEqual = ([entry1, entry2]) => entry1 === entry2;
1816
1745
 
1817
- const transformMap = (map, toBeLikeObject, setId, delId = mapSet) => {
1818
- const idsToDelete = arrayFilter(
1819
- mapKeys(map),
1820
- (id2) => !objHas(toBeLikeObject, id2),
1821
- );
1822
- arrayForEach(objIds(toBeLikeObject), (id2) =>
1823
- setId(map, id2, toBeLikeObject[id2]),
1824
- );
1825
- arrayForEach(idsToDelete, (id2) => delId(map, id2));
1746
+ const mapMatch = (map, obj, set, del = mapSet) => {
1747
+ objMap(obj, (value, id2) => set(map, id2, value));
1748
+ mapForEach(map, (id2) => (objHas(obj, id2) ? 0 : del(map, id2)));
1826
1749
  return map;
1827
1750
  };
1828
1751
  const validate = (obj, validateChild, onInvalidObj) => {
@@ -1837,8 +1760,12 @@ const validate = (obj, validateChild, onInvalidObj) => {
1837
1760
  });
1838
1761
  return !objIsEmpty(obj);
1839
1762
  };
1840
- const idsChanged = (changedIds, id2, added) =>
1841
- mapSet(changedIds, id2, mapGet(changedIds, id2) == -added ? void 0 : added);
1763
+ const idsChanged = (changedIds, id2, addedOrRemoved) =>
1764
+ mapSet(
1765
+ changedIds,
1766
+ id2,
1767
+ mapGet(changedIds, id2) == -addedOrRemoved ? void 0 : addedOrRemoved,
1768
+ );
1842
1769
  const createStore = () => {
1843
1770
  let hasTablesSchema;
1844
1771
  let hasValuesSchema;
@@ -1995,13 +1922,13 @@ const createStore = () => {
1995
1922
  return values;
1996
1923
  };
1997
1924
  const setValidTablesSchema = (tablesSchema) =>
1998
- transformMap(
1925
+ mapMatch(
1999
1926
  tablesSchemaMap,
2000
1927
  tablesSchema,
2001
1928
  (_tablesSchema, tableId, tableSchema) => {
2002
1929
  const rowDefaulted = mapNew();
2003
1930
  const rowNonDefaulted = setNew();
2004
- transformMap(
1931
+ mapMatch(
2005
1932
  mapEnsure(tablesSchemaMap, tableId, mapNew),
2006
1933
  tableSchema,
2007
1934
  (tableSchemaMap, cellId, cellSchema) => {
@@ -2021,7 +1948,7 @@ const createStore = () => {
2021
1948
  },
2022
1949
  );
2023
1950
  const setValidValuesSchema = (valuesSchema) =>
2024
- transformMap(
1951
+ mapMatch(
2025
1952
  valuesSchemaMap,
2026
1953
  valuesSchema,
2027
1954
  (_valuesSchema, valueId, valueSchema) => {
@@ -2041,14 +1968,14 @@ const createStore = () => {
2041
1968
  const setOrDelTables = (tables) =>
2042
1969
  objIsEmpty(tables) ? delTables() : setTables(tables);
2043
1970
  const setValidTables = (tables) =>
2044
- transformMap(
1971
+ mapMatch(
2045
1972
  tablesMap,
2046
1973
  tables,
2047
1974
  (_tables, tableId, table) => setValidTable(tableId, table),
2048
1975
  (_tables, tableId) => delValidTable(tableId),
2049
1976
  );
2050
1977
  const setValidTable = (tableId, table) =>
2051
- transformMap(
1978
+ mapMatch(
2052
1979
  mapEnsure(tablesMap, tableId, () => {
2053
1980
  tableIdsChanged(tableId, 1);
2054
1981
  return mapNew();
@@ -2058,7 +1985,7 @@ const createStore = () => {
2058
1985
  (tableMap, rowId) => delValidRow(tableId, tableMap, rowId),
2059
1986
  );
2060
1987
  const setValidRow = (tableId, tableMap, rowId, row, forceDel) =>
2061
- transformMap(
1988
+ mapMatch(
2062
1989
  mapEnsure(tableMap, rowId, () => {
2063
1990
  rowIdsChanged(tableId, rowId, 1);
2064
1991
  return mapNew();
@@ -2094,7 +2021,7 @@ const createStore = () => {
2094
2021
  const setOrDelValues = (values) =>
2095
2022
  objIsEmpty(values) ? delValues() : setValues(values);
2096
2023
  const setValidValues = (values) =>
2097
- transformMap(
2024
+ mapMatch(
2098
2025
  valuesMap,
2099
2026
  values,
2100
2027
  (_valuesMap, valueId, value) => setValidValue(valueId, value),
@@ -2162,15 +2089,19 @@ const createStore = () => {
2162
2089
  valueIdsChanged(valueId, -1);
2163
2090
  mapSet(valuesMap, valueId);
2164
2091
  };
2165
- const tableIdsChanged = (tableId, added) =>
2166
- idsChanged(changedTableIds, tableId, added);
2167
- const rowIdsChanged = (tableId, rowId, added) =>
2168
- idsChanged(mapEnsure(changedRowIds, tableId, mapNew), rowId, added);
2169
- const cellIdsChanged = (tableId, rowId, cellId, added) =>
2092
+ const tableIdsChanged = (tableId, addedOrRemoved) =>
2093
+ idsChanged(changedTableIds, tableId, addedOrRemoved);
2094
+ const rowIdsChanged = (tableId, rowId, addedOrRemoved) =>
2095
+ idsChanged(
2096
+ mapEnsure(changedRowIds, tableId, mapNew),
2097
+ rowId,
2098
+ addedOrRemoved,
2099
+ );
2100
+ const cellIdsChanged = (tableId, rowId, cellId, addedOrRemoved) =>
2170
2101
  idsChanged(
2171
2102
  mapEnsure(mapEnsure(changedCellIds, tableId, mapNew), rowId, mapNew),
2172
2103
  cellId,
2173
- added,
2104
+ addedOrRemoved,
2174
2105
  );
2175
2106
  const cellChanged = (tableId, rowId, cellId, oldCell, newCell) =>
2176
2107
  (mapEnsure(
@@ -2178,8 +2109,8 @@ const createStore = () => {
2178
2109
  cellId,
2179
2110
  () => [oldCell, 0],
2180
2111
  )[1] = newCell);
2181
- const valueIdsChanged = (valueId, added) =>
2182
- idsChanged(changedValueIds, valueId, added);
2112
+ const valueIdsChanged = (valueId, addedOrRemoved) =>
2113
+ idsChanged(changedValueIds, valueId, addedOrRemoved);
2183
2114
  const valueChanged = (valueId, oldValue, newValue) =>
2184
2115
  (mapEnsure(changedValues, valueId, () => [oldValue, 0])[1] = newValue);
2185
2116
  const cellInvalid = (tableId, rowId, cellId, invalidCell, defaultedCell) => {
@@ -2215,7 +2146,7 @@ const createStore = () => {
2215
2146
  const callInvalidCellListeners = (mutator) =>
2216
2147
  !collIsEmpty(invalidCells) && !collIsEmpty(invalidCellListeners[mutator])
2217
2148
  ? collForEach(
2218
- mutator ? mapClone(invalidCells, mapClone2) : invalidCells,
2149
+ mutator ? mapClone3(invalidCells) : invalidCells,
2219
2150
  (rows, tableId) =>
2220
2151
  collForEach(rows, (cells, rowId) =>
2221
2152
  collForEach(cells, (invalidCell, cellId) =>
@@ -2265,8 +2196,8 @@ const createStore = () => {
2265
2196
  ? [
2266
2197
  mapClone(changedTableIds),
2267
2198
  mapClone2(changedRowIds),
2268
- mapClone(changedCellIds, mapClone2),
2269
- mapClone(changedCells, mapClone2),
2199
+ mapClone3(changedCellIds),
2200
+ mapClone3(changedCells),
2270
2201
  ]
2271
2202
  : [changedTableIds, changedRowIds, changedCellIds, changedCells];
2272
2203
  if (!emptyIdListeners) {
@@ -2384,11 +2315,48 @@ const createStore = () => {
2384
2315
  transaction(() => actions(...arrayMap(args, id)));
2385
2316
  return store;
2386
2317
  };
2387
- const getTables = () =>
2388
- mapToObj(tablesMap, (table) => mapToObj(table, mapToObj));
2318
+ const getTransactionChanges = () => [
2319
+ mapToObj(
2320
+ changedCells,
2321
+ (table, tableId) =>
2322
+ mapGet(changedTableIds, tableId) === -1
2323
+ ? null
2324
+ : mapToObj(
2325
+ table,
2326
+ (row, rowId) =>
2327
+ mapGet(mapGet(changedRowIds, tableId), rowId) === -1
2328
+ ? null
2329
+ : mapToObj(
2330
+ row,
2331
+ ([, newCell]) => newCell ?? null,
2332
+ (_, changedCell) => pairIsEqual(changedCell),
2333
+ ),
2334
+ objIsEmpty,
2335
+ ),
2336
+ objIsEmpty,
2337
+ ),
2338
+ mapToObj(
2339
+ changedValues,
2340
+ ([, newValue]) => newValue ?? null,
2341
+ (_, changedValue) => pairIsEqual(changedValue),
2342
+ ),
2343
+ ];
2344
+ const getTransactionLog = () => ({
2345
+ cellsTouched,
2346
+ valuesTouched,
2347
+ changedCells: mapToObj3(changedCells, pairClone, pairIsEqual),
2348
+ invalidCells: mapToObj3(invalidCells),
2349
+ changedValues: mapToObj(changedValues, pairClone, pairIsEqual),
2350
+ invalidValues: mapToObj(invalidValues),
2351
+ changedTableIds: mapToObj(changedTableIds),
2352
+ changedRowIds: mapToObj2(changedRowIds),
2353
+ changedCellIds: mapToObj3(changedCellIds),
2354
+ changedValueIds: mapToObj(changedValueIds),
2355
+ });
2356
+ const getContent = () => [getTables(), getValues()];
2357
+ const getTables = () => mapToObj3(tablesMap);
2389
2358
  const getTableIds = () => mapKeys(tablesMap);
2390
- const getTable = (tableId) =>
2391
- mapToObj(mapGet(tablesMap, id(tableId)), mapToObj);
2359
+ const getTable = (tableId) => mapToObj2(mapGet(tablesMap, id(tableId)));
2392
2360
  const getRowIds = (tableId) => mapKeys(mapGet(tablesMap, id(tableId)));
2393
2361
  const getSortedRowIds = (tableId, cellId, descending, offset = 0, limit) =>
2394
2362
  arrayMap(
@@ -2429,6 +2397,11 @@ const createStore = () => {
2429
2397
  const getTablesSchemaJson = () => jsonString(tablesSchemaMap);
2430
2398
  const getValuesSchemaJson = () => jsonString(valuesSchemaMap);
2431
2399
  const getSchemaJson = () => jsonString([tablesSchemaMap, valuesSchemaMap]);
2400
+ const setContent = ([tables, values]) =>
2401
+ fluentTransaction(() => {
2402
+ setTables(tables);
2403
+ setValues(values);
2404
+ });
2432
2405
  const setTables = (tables) =>
2433
2406
  fluentTransaction(() =>
2434
2407
  validateTables(tables) ? setValidTables(tables) : 0,
@@ -2522,6 +2495,23 @@ const createStore = () => {
2522
2495
  ),
2523
2496
  valueId,
2524
2497
  );
2498
+ const setTransactionChanges = (transactionChanges) =>
2499
+ fluentTransaction(() => {
2500
+ objMap(transactionChanges[0], (table, tableId) =>
2501
+ isUndefined(table)
2502
+ ? delTable(tableId)
2503
+ : objMap(table, (row, rowId) =>
2504
+ isUndefined(row)
2505
+ ? delRow(tableId, rowId)
2506
+ : objMap(row, (cell, cellId) =>
2507
+ setOrDelCell(store, tableId, rowId, cellId, cell),
2508
+ ),
2509
+ ),
2510
+ );
2511
+ objMap(transactionChanges[1], (value, valueId) =>
2512
+ setOrDelValue(store, valueId, value),
2513
+ );
2514
+ });
2525
2515
  const setTablesJson = (tablesJson) => {
2526
2516
  try {
2527
2517
  setOrDelTables(jsonParse(tablesJson));
@@ -2661,32 +2651,7 @@ const createStore = () => {
2661
2651
  callKeyedValuesListenersForChanges(1);
2662
2652
  }
2663
2653
  transactions = -1;
2664
- if (
2665
- doRollback?.(
2666
- mapToObj(
2667
- changedCells,
2668
- (table) =>
2669
- mapToObj(
2670
- table,
2671
- (row) =>
2672
- mapToObj(
2673
- row,
2674
- (cells) => [...cells],
2675
- ([oldCell, newCell]) => oldCell === newCell,
2676
- ),
2677
- objIsEmpty,
2678
- ),
2679
- objIsEmpty,
2680
- ),
2681
- mapToObj(invalidCells, (map) => mapToObj(map, mapToObj)),
2682
- mapToObj(
2683
- changedValues,
2684
- (values) => [...values],
2685
- ([oldValue, newValue]) => oldValue === newValue,
2686
- ),
2687
- mapToObj(invalidValues),
2688
- )
2689
- ) {
2654
+ if (doRollback?.(getTransactionChanges, getTransactionLog)) {
2690
2655
  transactions = 1;
2691
2656
  collForEach(changedCells, (table, tableId) =>
2692
2657
  collForEach(table, (row, rowId) =>
@@ -2704,8 +2669,8 @@ const createStore = () => {
2704
2669
  callListeners(
2705
2670
  finishTransactionListeners[0],
2706
2671
  void 0,
2707
- cellsTouched,
2708
- valuesTouched,
2672
+ getTransactionChanges,
2673
+ getTransactionLog,
2709
2674
  );
2710
2675
  callInvalidCellListeners(0);
2711
2676
  if (cellsTouched) {
@@ -2718,8 +2683,8 @@ const createStore = () => {
2718
2683
  callListeners(
2719
2684
  finishTransactionListeners[1],
2720
2685
  void 0,
2721
- cellsTouched,
2722
- valuesTouched,
2686
+ getTransactionChanges,
2687
+ getTransactionLog,
2723
2688
  );
2724
2689
  transactions = 0;
2725
2690
  arrayForEach(
@@ -2828,6 +2793,7 @@ const createStore = () => {
2828
2793
  transaction: pairCollSize2(finishTransactionListeners),
2829
2794
  });
2830
2795
  const store = {
2796
+ getContent,
2831
2797
  getTables,
2832
2798
  getTableIds,
2833
2799
  getTable,
@@ -2851,6 +2817,7 @@ const createStore = () => {
2851
2817
  getTablesSchemaJson,
2852
2818
  getValuesSchemaJson,
2853
2819
  getSchemaJson,
2820
+ setContent,
2854
2821
  setTables,
2855
2822
  setTable,
2856
2823
  setRow,
@@ -2860,6 +2827,7 @@ const createStore = () => {
2860
2827
  setValues,
2861
2828
  setPartialValues,
2862
2829
  setValue,
2830
+ setTransactionChanges,
2863
2831
  setTablesJson,
2864
2832
  setValuesJson,
2865
2833
  setJson,
@@ -2932,14 +2900,10 @@ const createStore = () => {
2932
2900
  export {
2933
2901
  createCheckpoints,
2934
2902
  createCustomPersister,
2935
- createFilePersister,
2936
2903
  createIndexes,
2937
- createLocalPersister,
2938
2904
  createMetrics,
2939
2905
  createQueries,
2940
2906
  createRelationships,
2941
- createRemotePersister,
2942
- createSessionPersister,
2943
2907
  createStore,
2944
2908
  defaultSorter,
2945
2909
  };
@@ -48,6 +48,15 @@ const getCellOrValueType = (cell) => {
48
48
  : void 0;
49
49
  };
50
50
 
51
+ const object = Object;
52
+ const objIds = object.keys;
53
+ const objFreeze = object.freeze;
54
+ const isObject = (obj) =>
55
+ isInstanceOf(obj, object) && obj.constructor == object;
56
+ const objMap = (obj, cb) =>
57
+ arrayMap(object.entries(obj), ([id, value]) => cb(value, id));
58
+ const objIsEmpty = (obj) => isObject(obj) && arrayIsEmpty(objIds(obj));
59
+
51
60
  const collHas = (coll, keyOrValue) => coll?.has(keyOrValue) ?? false;
52
61
  const collValues = (coll) => [...(coll?.values() ?? [])];
53
62
  const collForEach = (coll, cb) => coll?.forEach(cb);
@@ -349,15 +358,6 @@ const getCodeFunctions = () => {
349
358
  ];
350
359
  };
351
360
 
352
- const object = Object;
353
- const objIds = object.keys;
354
- const objFreeze = object.freeze;
355
- const isObject = (obj) =>
356
- isInstanceOf(obj, object) && obj.constructor == object;
357
- const objMap = (obj, cb) =>
358
- arrayMap(object.entries(obj), ([id, value]) => cb(value, id));
359
- const objIsEmpty = (obj) => isObject(obj) && arrayIsEmpty(objIds(obj));
360
-
361
361
  const getCreateFunction = (getFunction) => {
362
362
  const getFunctionsByStore = /* @__PURE__ */ new WeakMap();
363
363
  return (store) => {