tinybase 4.0.0-beta.1 → 4.0.0-beta.3
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.
- package/bin/cli.js +1 -1
- package/lib/checkpoints.js +1 -1
- package/lib/checkpoints.js.gz +0 -0
- package/lib/cjs/checkpoints.cjs +1 -1
- package/lib/cjs/checkpoints.cjs.gz +0 -0
- package/lib/cjs/indexes.cjs +1 -1
- package/lib/cjs/indexes.cjs.gz +0 -0
- package/lib/cjs/metrics.cjs +1 -1
- package/lib/cjs/metrics.cjs.gz +0 -0
- package/lib/cjs/persister-automerge.cjs +1 -0
- package/lib/cjs/persister-automerge.cjs.gz +0 -0
- package/lib/cjs/persister-browser.cjs +1 -1
- package/lib/cjs/persister-browser.cjs.gz +0 -0
- package/lib/cjs/persister-file.cjs +1 -1
- package/lib/cjs/persister-file.cjs.gz +0 -0
- package/lib/cjs/persister-remote.cjs +1 -1
- package/lib/cjs/persister-remote.cjs.gz +0 -0
- package/lib/cjs/persister-yjs.cjs +1 -1
- package/lib/cjs/persister-yjs.cjs.gz +0 -0
- package/lib/cjs/persisters.cjs +1 -1
- package/lib/cjs/persisters.cjs.gz +0 -0
- package/lib/cjs/queries.cjs +1 -1
- package/lib/cjs/queries.cjs.gz +0 -0
- package/lib/cjs/relationships.cjs +1 -1
- package/lib/cjs/relationships.cjs.gz +0 -0
- package/lib/cjs/store.cjs +1 -1
- package/lib/cjs/store.cjs.gz +0 -0
- package/lib/cjs/tinybase.cjs +1 -1
- package/lib/cjs/tinybase.cjs.gz +0 -0
- package/lib/cjs/tools.cjs +1 -1
- package/lib/cjs/tools.cjs.gz +0 -0
- package/lib/cjs/ui-react.cjs +1 -1
- package/lib/cjs/ui-react.cjs.gz +0 -0
- package/lib/cjs-es6/checkpoints.cjs +1 -1
- package/lib/cjs-es6/checkpoints.cjs.gz +0 -0
- package/lib/cjs-es6/indexes.cjs +1 -1
- package/lib/cjs-es6/indexes.cjs.gz +0 -0
- package/lib/cjs-es6/metrics.cjs +1 -1
- package/lib/cjs-es6/metrics.cjs.gz +0 -0
- package/lib/cjs-es6/persister-automerge.cjs +1 -0
- package/lib/cjs-es6/persister-automerge.cjs.gz +0 -0
- package/lib/cjs-es6/persister-browser.cjs +1 -1
- package/lib/cjs-es6/persister-browser.cjs.gz +0 -0
- package/lib/cjs-es6/persister-file.cjs +1 -1
- package/lib/cjs-es6/persister-file.cjs.gz +0 -0
- package/lib/cjs-es6/persister-remote.cjs +1 -1
- package/lib/cjs-es6/persister-remote.cjs.gz +0 -0
- package/lib/cjs-es6/persister-yjs.cjs +1 -1
- package/lib/cjs-es6/persister-yjs.cjs.gz +0 -0
- package/lib/cjs-es6/persisters.cjs +1 -1
- package/lib/cjs-es6/persisters.cjs.gz +0 -0
- package/lib/cjs-es6/queries.cjs +1 -1
- package/lib/cjs-es6/queries.cjs.gz +0 -0
- package/lib/cjs-es6/relationships.cjs +1 -1
- package/lib/cjs-es6/relationships.cjs.gz +0 -0
- package/lib/cjs-es6/store.cjs +1 -1
- package/lib/cjs-es6/store.cjs.gz +0 -0
- package/lib/cjs-es6/tinybase.cjs +1 -1
- package/lib/cjs-es6/tinybase.cjs.gz +0 -0
- package/lib/cjs-es6/tools.cjs +1 -1
- package/lib/cjs-es6/tools.cjs.gz +0 -0
- package/lib/cjs-es6/ui-react.cjs +1 -1
- package/lib/cjs-es6/ui-react.cjs.gz +0 -0
- package/lib/debug/checkpoints.js +3 -3
- package/lib/debug/indexes.js +3 -3
- package/lib/debug/metrics.js +3 -3
- package/lib/debug/persister-automerge.js +257 -0
- package/lib/debug/persister-browser.js +40 -41
- package/lib/debug/persister-file.js +39 -39
- package/lib/debug/persister-remote.js +39 -36
- package/lib/debug/persister-yjs.js +227 -42
- package/lib/debug/persisters.js +38 -35
- package/lib/debug/queries.js +5 -5
- package/lib/debug/relationships.js +3 -3
- package/lib/debug/store.js +129 -94
- package/lib/debug/tinybase.js +167 -127
- package/lib/debug/tools.js +51 -11
- package/lib/es6/checkpoints.js +1 -1
- package/lib/es6/checkpoints.js.gz +0 -0
- package/lib/es6/indexes.js +1 -1
- package/lib/es6/indexes.js.gz +0 -0
- package/lib/es6/metrics.js +1 -1
- package/lib/es6/metrics.js.gz +0 -0
- package/lib/es6/persister-automerge.js +1 -0
- package/lib/es6/persister-automerge.js.gz +0 -0
- package/lib/es6/persister-browser.js +1 -1
- package/lib/es6/persister-browser.js.gz +0 -0
- package/lib/es6/persister-file.js +1 -1
- package/lib/es6/persister-file.js.gz +0 -0
- package/lib/es6/persister-remote.js +1 -1
- package/lib/es6/persister-remote.js.gz +0 -0
- package/lib/es6/persister-yjs.js +1 -1
- package/lib/es6/persister-yjs.js.gz +0 -0
- package/lib/es6/persisters.js +1 -1
- package/lib/es6/persisters.js.gz +0 -0
- package/lib/es6/queries.js +1 -1
- package/lib/es6/queries.js.gz +0 -0
- package/lib/es6/relationships.js +1 -1
- package/lib/es6/relationships.js.gz +0 -0
- package/lib/es6/store.js +1 -1
- package/lib/es6/store.js.gz +0 -0
- package/lib/es6/tinybase.js +1 -1
- package/lib/es6/tinybase.js.gz +0 -0
- package/lib/es6/tools.js +1 -1
- package/lib/es6/tools.js.gz +0 -0
- package/lib/es6/ui-react.js +1 -1
- package/lib/es6/ui-react.js.gz +0 -0
- package/lib/indexes.js +1 -1
- package/lib/indexes.js.gz +0 -0
- package/lib/metrics.js +1 -1
- package/lib/metrics.js.gz +0 -0
- package/lib/persister-automerge.js +1 -0
- package/lib/persister-automerge.js.gz +0 -0
- package/lib/persister-browser.js +1 -1
- package/lib/persister-browser.js.gz +0 -0
- package/lib/persister-file.js +1 -1
- package/lib/persister-file.js.gz +0 -0
- package/lib/persister-remote.js +1 -1
- package/lib/persister-remote.js.gz +0 -0
- package/lib/persister-yjs.js +1 -1
- package/lib/persister-yjs.js.gz +0 -0
- package/lib/persisters.js +1 -1
- package/lib/persisters.js.gz +0 -0
- package/lib/queries.js +1 -1
- package/lib/queries.js.gz +0 -0
- package/lib/relationships.js +1 -1
- package/lib/relationships.js.gz +0 -0
- package/lib/store.js +1 -1
- package/lib/store.js.gz +0 -0
- package/lib/tinybase.js +1 -1
- package/lib/tinybase.js.gz +0 -0
- package/lib/tools.js +1 -1
- package/lib/tools.js.gz +0 -0
- package/lib/types/persister-automerge.d.ts +110 -0
- package/lib/types/persister-yjs.d.ts +71 -8
- package/lib/types/persisters.d.ts +45 -20
- package/lib/types/queries.d.ts +52 -52
- package/lib/types/store.d.ts +399 -145
- package/lib/types/tools.d.ts +20 -20
- package/lib/types/ui-react.d.ts +56 -47
- package/lib/types/with-schemas/internal/ui-react.d.ts +2 -2
- package/lib/types/with-schemas/persister-automerge.d.ts +120 -0
- package/lib/types/with-schemas/persister-yjs.d.ts +73 -9
- package/lib/types/with-schemas/persisters.d.ts +62 -21
- package/lib/types/with-schemas/queries.d.ts +52 -52
- package/lib/types/with-schemas/store.d.ts +480 -163
- package/lib/types/with-schemas/tools.d.ts +20 -20
- package/lib/types/with-schemas/ui-react.d.ts +54 -45
- package/lib/ui-react.js +1 -1
- package/lib/ui-react.js.gz +0 -0
- package/lib/umd/checkpoints.js +1 -1
- package/lib/umd/checkpoints.js.gz +0 -0
- package/lib/umd/indexes.js +1 -1
- package/lib/umd/indexes.js.gz +0 -0
- package/lib/umd/metrics.js +1 -1
- package/lib/umd/metrics.js.gz +0 -0
- package/lib/umd/persister-automerge.js +1 -0
- package/lib/umd/persister-automerge.js.gz +0 -0
- package/lib/umd/persister-browser.js +1 -1
- package/lib/umd/persister-browser.js.gz +0 -0
- package/lib/umd/persister-file.js +1 -1
- package/lib/umd/persister-file.js.gz +0 -0
- package/lib/umd/persister-remote.js +1 -1
- package/lib/umd/persister-remote.js.gz +0 -0
- package/lib/umd/persister-yjs.js +1 -1
- package/lib/umd/persister-yjs.js.gz +0 -0
- package/lib/umd/persisters.js +1 -1
- package/lib/umd/persisters.js.gz +0 -0
- package/lib/umd/queries.js +1 -1
- package/lib/umd/queries.js.gz +0 -0
- package/lib/umd/relationships.js +1 -1
- package/lib/umd/relationships.js.gz +0 -0
- package/lib/umd/store.js +1 -1
- package/lib/umd/store.js.gz +0 -0
- package/lib/umd/tinybase.js +1 -1
- package/lib/umd/tinybase.js.gz +0 -0
- package/lib/umd/tools.js +1 -1
- package/lib/umd/tools.js.gz +0 -0
- package/lib/umd/ui-react.js +1 -1
- package/lib/umd/ui-react.js.gz +0 -0
- package/lib/umd-es6/checkpoints.js +1 -1
- package/lib/umd-es6/checkpoints.js.gz +0 -0
- package/lib/umd-es6/indexes.js +1 -1
- package/lib/umd-es6/indexes.js.gz +0 -0
- package/lib/umd-es6/metrics.js +1 -1
- package/lib/umd-es6/metrics.js.gz +0 -0
- package/lib/umd-es6/persister-automerge.js +1 -0
- package/lib/umd-es6/persister-automerge.js.gz +0 -0
- package/lib/umd-es6/persister-browser.js +1 -1
- package/lib/umd-es6/persister-browser.js.gz +0 -0
- package/lib/umd-es6/persister-file.js +1 -1
- package/lib/umd-es6/persister-file.js.gz +0 -0
- package/lib/umd-es6/persister-remote.js +1 -1
- package/lib/umd-es6/persister-remote.js.gz +0 -0
- package/lib/umd-es6/persister-yjs.js +1 -1
- package/lib/umd-es6/persister-yjs.js.gz +0 -0
- package/lib/umd-es6/persisters.js +1 -1
- package/lib/umd-es6/persisters.js.gz +0 -0
- package/lib/umd-es6/queries.js +1 -1
- package/lib/umd-es6/queries.js.gz +0 -0
- package/lib/umd-es6/relationships.js +1 -1
- package/lib/umd-es6/relationships.js.gz +0 -0
- package/lib/umd-es6/store.js +1 -1
- package/lib/umd-es6/store.js.gz +0 -0
- package/lib/umd-es6/tinybase.js +1 -1
- package/lib/umd-es6/tinybase.js.gz +0 -0
- package/lib/umd-es6/tools.js +1 -1
- package/lib/umd-es6/tools.js.gz +0 -0
- package/lib/umd-es6/ui-react.js +1 -1
- package/lib/umd-es6/ui-react.js.gz +0 -0
- package/package.json +59 -29
- package/readme.md +3 -3
|
@@ -1,4 +1,10 @@
|
|
|
1
|
-
|
|
1
|
+
import {Map} from 'yjs';
|
|
2
|
+
|
|
3
|
+
const arrayForEach = (array, cb) => array.forEach(cb);
|
|
4
|
+
const arrayMap = (array, cb) => array.map(cb);
|
|
5
|
+
const arrayLength = (array) => array.length;
|
|
6
|
+
const arrayIsEmpty = (array) => arrayLength(array) == 0;
|
|
7
|
+
const arrayShift = (array) => array.shift();
|
|
2
8
|
|
|
3
9
|
const isUndefined = (thing) => thing == void 0;
|
|
4
10
|
const ifNotUndefined = (value, then, otherwise) =>
|
|
@@ -6,6 +12,17 @@ const ifNotUndefined = (value, then, otherwise) =>
|
|
|
6
12
|
|
|
7
13
|
const object = Object;
|
|
8
14
|
const objFreeze = object.freeze;
|
|
15
|
+
const objNew = () => ({});
|
|
16
|
+
const objGet = (obj, id) => ifNotUndefined(obj, (obj2) => obj2[id]);
|
|
17
|
+
const objHas = (obj, id) => !isUndefined(objGet(obj, id));
|
|
18
|
+
const objMap = (obj, cb) =>
|
|
19
|
+
arrayMap(object.entries(obj), ([id, value]) => cb(value, id));
|
|
20
|
+
const objEnsure = (obj, id, getDefaultValue) => {
|
|
21
|
+
if (!objHas(obj, id)) {
|
|
22
|
+
obj[id] = getDefaultValue();
|
|
23
|
+
}
|
|
24
|
+
return obj[id];
|
|
25
|
+
};
|
|
9
26
|
|
|
10
27
|
const createCustomPersister = (
|
|
11
28
|
store,
|
|
@@ -20,43 +37,45 @@ const createCustomPersister = (
|
|
|
20
37
|
let saves = 0;
|
|
21
38
|
let listening = false;
|
|
22
39
|
let listeningHandle;
|
|
23
|
-
const
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
loads++;
|
|
30
|
-
}
|
|
31
|
-
const body = await getPersisted();
|
|
32
|
-
if (!isUndefined(body) && body != EMPTY_STRING) {
|
|
33
|
-
store.setJson(body);
|
|
34
|
-
} else {
|
|
35
|
-
store.setContent([initialTables, initialValues]);
|
|
36
|
-
}
|
|
37
|
-
loadSave = 0;
|
|
40
|
+
const loadLock = async (actions) => {
|
|
41
|
+
/* istanbul ignore else */
|
|
42
|
+
if (loadSave != 2) {
|
|
43
|
+
loadSave = 1;
|
|
44
|
+
{
|
|
45
|
+
loads++;
|
|
38
46
|
}
|
|
47
|
+
await actions();
|
|
48
|
+
loadSave = 0;
|
|
49
|
+
}
|
|
50
|
+
};
|
|
51
|
+
const persister = {
|
|
52
|
+
load: async (initialTables = {}, initialValues = {}) => {
|
|
53
|
+
await loadLock(async () => {
|
|
54
|
+
let content;
|
|
55
|
+
try {
|
|
56
|
+
content = await getPersisted();
|
|
57
|
+
} catch {}
|
|
58
|
+
store.setContent(content ?? [initialTables, initialValues]);
|
|
59
|
+
});
|
|
39
60
|
return persister;
|
|
40
61
|
},
|
|
41
|
-
startAutoLoad: async (initialTables, initialValues) => {
|
|
62
|
+
startAutoLoad: async (initialTables = {}, initialValues = {}) => {
|
|
42
63
|
persister.stopAutoLoad();
|
|
43
64
|
await persister.load(initialTables, initialValues);
|
|
44
65
|
listening = true;
|
|
45
|
-
listeningHandle = addPersisterListener(
|
|
46
|
-
|
|
47
|
-
await
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
66
|
+
listeningHandle = addPersisterListener(
|
|
67
|
+
async (getContent, getTransactionChanges) => {
|
|
68
|
+
await loadLock(async () => {
|
|
69
|
+
if (getTransactionChanges) {
|
|
70
|
+
store.setTransactionChanges(getTransactionChanges());
|
|
71
|
+
} else {
|
|
72
|
+
try {
|
|
73
|
+
store.setContent(getContent?.() ?? (await getPersisted()));
|
|
74
|
+
} catch {}
|
|
54
75
|
}
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
}
|
|
59
|
-
});
|
|
76
|
+
});
|
|
77
|
+
},
|
|
78
|
+
);
|
|
60
79
|
return persister;
|
|
61
80
|
},
|
|
62
81
|
stopAutoLoad: () => {
|
|
@@ -67,21 +86,24 @@ const createCustomPersister = (
|
|
|
67
86
|
}
|
|
68
87
|
return persister;
|
|
69
88
|
},
|
|
70
|
-
save: async () => {
|
|
89
|
+
save: async (getTransactionChanges) => {
|
|
71
90
|
/* istanbul ignore else */
|
|
72
91
|
if (loadSave != 1) {
|
|
73
92
|
loadSave = 2;
|
|
74
93
|
{
|
|
75
94
|
saves++;
|
|
76
95
|
}
|
|
77
|
-
await setPersisted(store.getContent);
|
|
96
|
+
await setPersisted(store.getContent, getTransactionChanges);
|
|
78
97
|
loadSave = 0;
|
|
79
98
|
}
|
|
80
99
|
return persister;
|
|
81
100
|
},
|
|
82
101
|
startAutoSave: async () => {
|
|
83
102
|
await persister.stopAutoSave().save();
|
|
84
|
-
listenerId = store.addDidFinishTransactionListener(
|
|
103
|
+
listenerId = store.addDidFinishTransactionListener(
|
|
104
|
+
(_store, getTransactionChanges) =>
|
|
105
|
+
persister.save(getTransactionChanges),
|
|
106
|
+
);
|
|
85
107
|
return persister;
|
|
86
108
|
},
|
|
87
109
|
stopAutoSave: () => {
|
|
@@ -95,18 +117,181 @@ const createCustomPersister = (
|
|
|
95
117
|
return objFreeze(persister);
|
|
96
118
|
};
|
|
97
119
|
|
|
98
|
-
const
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
120
|
+
const collForEach = (coll, cb) => coll?.forEach(cb);
|
|
121
|
+
|
|
122
|
+
const mapForEach = (map, cb) =>
|
|
123
|
+
collForEach(map, (value, key) => cb(key, value));
|
|
124
|
+
|
|
125
|
+
const tablesKey = 't';
|
|
126
|
+
const valuesKey = 'v';
|
|
127
|
+
const DELETE = 'delete';
|
|
128
|
+
const ensureYContent = (yContent) => {
|
|
129
|
+
if (!yContent.size) {
|
|
130
|
+
yContent.set(tablesKey, new Map());
|
|
131
|
+
yContent.set(valuesKey, new Map());
|
|
132
|
+
}
|
|
133
|
+
};
|
|
134
|
+
const getYContent = (yContent) => [
|
|
135
|
+
yContent.get(tablesKey),
|
|
136
|
+
yContent.get(valuesKey),
|
|
137
|
+
];
|
|
138
|
+
const getTransactionChangesFromYDoc = (yContent, events) => {
|
|
139
|
+
if (arrayLength(events) == 1 && arrayIsEmpty(events[0].path)) {
|
|
140
|
+
return [yContent.get('t').toJSON(), yContent.get('v').toJSON()];
|
|
141
|
+
}
|
|
142
|
+
const [yTables, yValues] = getYContent(yContent);
|
|
143
|
+
const tables = {};
|
|
144
|
+
const values = {};
|
|
145
|
+
arrayForEach(events, ({path, changes: {keys}}) =>
|
|
146
|
+
arrayShift(path) == tablesKey
|
|
147
|
+
? ifNotUndefined(
|
|
148
|
+
arrayShift(path),
|
|
149
|
+
(yTableId) => {
|
|
150
|
+
const table = objEnsure(tables, yTableId, objNew);
|
|
151
|
+
const yTable = yTables.get(yTableId);
|
|
152
|
+
ifNotUndefined(
|
|
153
|
+
arrayShift(path),
|
|
154
|
+
(yRowId) => {
|
|
155
|
+
const row = objEnsure(table, yRowId, objNew);
|
|
156
|
+
const yRow = yTable.get(yRowId);
|
|
157
|
+
mapForEach(
|
|
158
|
+
keys,
|
|
159
|
+
(cellId, {action}) =>
|
|
160
|
+
(row[cellId] = action == DELETE ? null : yRow.get(cellId)),
|
|
161
|
+
);
|
|
162
|
+
},
|
|
163
|
+
() =>
|
|
164
|
+
mapForEach(
|
|
165
|
+
keys,
|
|
166
|
+
(rowId, {action}) =>
|
|
167
|
+
(table[rowId] =
|
|
168
|
+
action == DELETE ? null : yTable.get(rowId)?.toJSON()),
|
|
169
|
+
),
|
|
170
|
+
);
|
|
171
|
+
},
|
|
172
|
+
() =>
|
|
173
|
+
mapForEach(
|
|
174
|
+
keys,
|
|
175
|
+
(tableId, {action}) =>
|
|
176
|
+
(tables[tableId] =
|
|
177
|
+
action == DELETE ? null : yTables.get(tableId)?.toJSON()),
|
|
178
|
+
),
|
|
179
|
+
)
|
|
180
|
+
: mapForEach(
|
|
181
|
+
keys,
|
|
182
|
+
(valueId, {action}) =>
|
|
183
|
+
(values[valueId] = action == DELETE ? null : yValues.get(valueId)),
|
|
184
|
+
),
|
|
185
|
+
);
|
|
186
|
+
return [tables, values];
|
|
187
|
+
};
|
|
188
|
+
const setTransactionChangesToYDoc = (
|
|
189
|
+
yContent,
|
|
190
|
+
getContent,
|
|
191
|
+
getTransactionChanges,
|
|
192
|
+
) => {
|
|
193
|
+
ensureYContent(yContent);
|
|
194
|
+
const [yTables, yValues] = getYContent(yContent);
|
|
195
|
+
const transactionChangesDidFail = () => {
|
|
196
|
+
transactionChangesFailed = 1;
|
|
103
197
|
};
|
|
198
|
+
let transactionChangesFailed = 1;
|
|
199
|
+
ifNotUndefined(getTransactionChanges?.(), ([cellChanges, valueChanges]) => {
|
|
200
|
+
transactionChangesFailed = 0;
|
|
201
|
+
objMap(cellChanges, (table, tableId) =>
|
|
202
|
+
transactionChangesFailed
|
|
203
|
+
? 0
|
|
204
|
+
: isUndefined(table)
|
|
205
|
+
? yTables.delete(tableId)
|
|
206
|
+
: ifNotUndefined(
|
|
207
|
+
yTables.get(tableId),
|
|
208
|
+
(yTable) =>
|
|
209
|
+
objMap(table, (row, rowId) =>
|
|
210
|
+
transactionChangesFailed
|
|
211
|
+
? 0
|
|
212
|
+
: isUndefined(row)
|
|
213
|
+
? yTable.delete(rowId)
|
|
214
|
+
: ifNotUndefined(
|
|
215
|
+
yTable.get(rowId),
|
|
216
|
+
(yRow) =>
|
|
217
|
+
objMap(row, (cell, cellId) =>
|
|
218
|
+
isUndefined(cell)
|
|
219
|
+
? yRow.delete(cellId)
|
|
220
|
+
: yRow.set(cellId, cell),
|
|
221
|
+
),
|
|
222
|
+
transactionChangesDidFail,
|
|
223
|
+
),
|
|
224
|
+
),
|
|
225
|
+
transactionChangesDidFail,
|
|
226
|
+
),
|
|
227
|
+
);
|
|
228
|
+
objMap(valueChanges, (value, valueId) =>
|
|
229
|
+
transactionChangesFailed
|
|
230
|
+
? 0
|
|
231
|
+
: isUndefined(value)
|
|
232
|
+
? yValues.delete(valueId)
|
|
233
|
+
: yValues.set(valueId, value),
|
|
234
|
+
);
|
|
235
|
+
});
|
|
236
|
+
if (transactionChangesFailed) {
|
|
237
|
+
const [tables, values] = getContent();
|
|
238
|
+
yMapMatch(yTables, void 0, tables, (_, tableId, table) =>
|
|
239
|
+
yMapMatch(yTables, tableId, table, (yTable, rowId, row) =>
|
|
240
|
+
yMapMatch(yTable, rowId, row, (yRow, cellId, cell) => {
|
|
241
|
+
if (yRow.get(cellId) !== cell) {
|
|
242
|
+
yRow.set(cellId, cell);
|
|
243
|
+
return 1;
|
|
244
|
+
}
|
|
245
|
+
}),
|
|
246
|
+
),
|
|
247
|
+
);
|
|
248
|
+
yMapMatch(yValues, void 0, values, (_, valueId, value) => {
|
|
249
|
+
if (yValues.get(valueId) !== value) {
|
|
250
|
+
yValues.set(valueId, value);
|
|
251
|
+
}
|
|
252
|
+
});
|
|
253
|
+
}
|
|
254
|
+
};
|
|
255
|
+
const yMapMatch = (yMapOrParent, idInParent, obj, set) => {
|
|
256
|
+
const yMap = isUndefined(idInParent)
|
|
257
|
+
? yMapOrParent
|
|
258
|
+
: yMapOrParent.get(idInParent) ?? yMapOrParent.set(idInParent, new Map());
|
|
259
|
+
let changed;
|
|
260
|
+
objMap(obj, (value, id) => {
|
|
261
|
+
if (set(yMap, id, value)) {
|
|
262
|
+
changed = 1;
|
|
263
|
+
}
|
|
264
|
+
});
|
|
265
|
+
yMap.forEach((_, id) => {
|
|
266
|
+
if (!objHas(obj, id)) {
|
|
267
|
+
yMap.delete(id);
|
|
268
|
+
changed = 1;
|
|
269
|
+
}
|
|
270
|
+
});
|
|
271
|
+
if (!isUndefined(idInParent) && !yMap.size) {
|
|
272
|
+
yMapOrParent.delete(idInParent);
|
|
273
|
+
}
|
|
274
|
+
return changed;
|
|
275
|
+
};
|
|
276
|
+
const createYjsPersister = (store, yDoc, yMapName = 'tinybase') => {
|
|
277
|
+
const yContent = yDoc.getMap(yMapName);
|
|
278
|
+
const getPersisted = async () =>
|
|
279
|
+
yContent.size
|
|
280
|
+
? [yContent.get(tablesKey).toJSON(), yContent.get(valuesKey).toJSON()]
|
|
281
|
+
: void 0;
|
|
282
|
+
const setPersisted = async (getContent, getTransactionChanges) =>
|
|
283
|
+
yDoc.transact(() =>
|
|
284
|
+
setTransactionChangesToYDoc(yContent, getContent, getTransactionChanges),
|
|
285
|
+
);
|
|
104
286
|
const addPersisterListener = (listener) => {
|
|
105
|
-
const observer = () =>
|
|
106
|
-
|
|
287
|
+
const observer = (events) =>
|
|
288
|
+
listener(void 0, () => getTransactionChangesFromYDoc(yContent, events));
|
|
289
|
+
yContent.observeDeep(observer);
|
|
107
290
|
return observer;
|
|
108
291
|
};
|
|
109
|
-
const delPersisterListener = (observer) =>
|
|
292
|
+
const delPersisterListener = (observer) => {
|
|
293
|
+
yContent.unobserveDeep(observer);
|
|
294
|
+
};
|
|
110
295
|
return createCustomPersister(
|
|
111
296
|
store,
|
|
112
297
|
getPersisted,
|
package/lib/debug/persisters.js
CHANGED
|
@@ -1,5 +1,3 @@
|
|
|
1
|
-
const EMPTY_STRING = '';
|
|
2
|
-
|
|
3
1
|
const isUndefined = (thing) => thing == void 0;
|
|
4
2
|
const ifNotUndefined = (value, then, otherwise) =>
|
|
5
3
|
isUndefined(value) ? otherwise?.() : then(value);
|
|
@@ -20,43 +18,45 @@ const createCustomPersister = (
|
|
|
20
18
|
let saves = 0;
|
|
21
19
|
let listening = false;
|
|
22
20
|
let listeningHandle;
|
|
23
|
-
const
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
loads++;
|
|
30
|
-
}
|
|
31
|
-
const body = await getPersisted();
|
|
32
|
-
if (!isUndefined(body) && body != EMPTY_STRING) {
|
|
33
|
-
store.setJson(body);
|
|
34
|
-
} else {
|
|
35
|
-
store.setContent([initialTables, initialValues]);
|
|
36
|
-
}
|
|
37
|
-
loadSave = 0;
|
|
21
|
+
const loadLock = async (actions) => {
|
|
22
|
+
/* istanbul ignore else */
|
|
23
|
+
if (loadSave != 2) {
|
|
24
|
+
loadSave = 1;
|
|
25
|
+
{
|
|
26
|
+
loads++;
|
|
38
27
|
}
|
|
28
|
+
await actions();
|
|
29
|
+
loadSave = 0;
|
|
30
|
+
}
|
|
31
|
+
};
|
|
32
|
+
const persister = {
|
|
33
|
+
load: async (initialTables = {}, initialValues = {}) => {
|
|
34
|
+
await loadLock(async () => {
|
|
35
|
+
let content;
|
|
36
|
+
try {
|
|
37
|
+
content = await getPersisted();
|
|
38
|
+
} catch {}
|
|
39
|
+
store.setContent(content ?? [initialTables, initialValues]);
|
|
40
|
+
});
|
|
39
41
|
return persister;
|
|
40
42
|
},
|
|
41
|
-
startAutoLoad: async (initialTables, initialValues) => {
|
|
43
|
+
startAutoLoad: async (initialTables = {}, initialValues = {}) => {
|
|
42
44
|
persister.stopAutoLoad();
|
|
43
45
|
await persister.load(initialTables, initialValues);
|
|
44
46
|
listening = true;
|
|
45
|
-
listeningHandle = addPersisterListener(
|
|
46
|
-
|
|
47
|
-
await
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
47
|
+
listeningHandle = addPersisterListener(
|
|
48
|
+
async (getContent, getTransactionChanges) => {
|
|
49
|
+
await loadLock(async () => {
|
|
50
|
+
if (getTransactionChanges) {
|
|
51
|
+
store.setTransactionChanges(getTransactionChanges());
|
|
52
|
+
} else {
|
|
53
|
+
try {
|
|
54
|
+
store.setContent(getContent?.() ?? (await getPersisted()));
|
|
55
|
+
} catch {}
|
|
54
56
|
}
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
}
|
|
59
|
-
});
|
|
57
|
+
});
|
|
58
|
+
},
|
|
59
|
+
);
|
|
60
60
|
return persister;
|
|
61
61
|
},
|
|
62
62
|
stopAutoLoad: () => {
|
|
@@ -67,21 +67,24 @@ const createCustomPersister = (
|
|
|
67
67
|
}
|
|
68
68
|
return persister;
|
|
69
69
|
},
|
|
70
|
-
save: async () => {
|
|
70
|
+
save: async (getTransactionChanges) => {
|
|
71
71
|
/* istanbul ignore else */
|
|
72
72
|
if (loadSave != 1) {
|
|
73
73
|
loadSave = 2;
|
|
74
74
|
{
|
|
75
75
|
saves++;
|
|
76
76
|
}
|
|
77
|
-
await setPersisted(store.getContent);
|
|
77
|
+
await setPersisted(store.getContent, getTransactionChanges);
|
|
78
78
|
loadSave = 0;
|
|
79
79
|
}
|
|
80
80
|
return persister;
|
|
81
81
|
},
|
|
82
82
|
startAutoSave: async () => {
|
|
83
83
|
await persister.stopAutoSave().save();
|
|
84
|
-
listenerId = store.addDidFinishTransactionListener(
|
|
84
|
+
listenerId = store.addDidFinishTransactionListener(
|
|
85
|
+
(_store, getTransactionChanges) =>
|
|
86
|
+
persister.save(getTransactionChanges),
|
|
87
|
+
);
|
|
85
88
|
return persister;
|
|
86
89
|
},
|
|
87
90
|
stopAutoSave: () => {
|
package/lib/debug/queries.js
CHANGED
|
@@ -44,6 +44,11 @@ const isFunction = (thing) => getTypeOf(thing) == FUNCTION;
|
|
|
44
44
|
const isArray = (thing) => Array.isArray(thing);
|
|
45
45
|
const getUndefined = () => void 0;
|
|
46
46
|
|
|
47
|
+
const object = Object;
|
|
48
|
+
const objFreeze = object.freeze;
|
|
49
|
+
const objMap = (obj, cb) =>
|
|
50
|
+
arrayMap(object.entries(obj), ([id, value]) => cb(value, id));
|
|
51
|
+
|
|
47
52
|
const collSize = (coll) => coll.size;
|
|
48
53
|
const collHas = (coll, keyOrValue) => coll?.has(keyOrValue) ?? false;
|
|
49
54
|
const collIsEmpty = (coll) => isUndefined(coll) || collSize(coll) == 0;
|
|
@@ -329,11 +334,6 @@ const getCreateFunction = (getFunction) => {
|
|
|
329
334
|
};
|
|
330
335
|
};
|
|
331
336
|
|
|
332
|
-
const object = Object;
|
|
333
|
-
const objFreeze = object.freeze;
|
|
334
|
-
const objMap = (obj, cb) =>
|
|
335
|
-
arrayMap(object.entries(obj), ([id, value]) => cb(value, id));
|
|
336
|
-
|
|
337
337
|
const createQueries = getCreateFunction((store) => {
|
|
338
338
|
const createStore = store.createStore;
|
|
339
339
|
const [
|
|
@@ -20,6 +20,9 @@ const isString = (thing) => getTypeOf(thing) == STRING;
|
|
|
20
20
|
const isArray = (thing) => Array.isArray(thing);
|
|
21
21
|
const test = (regex, subject) => regex.test(subject);
|
|
22
22
|
|
|
23
|
+
const object = Object;
|
|
24
|
+
const objFreeze = object.freeze;
|
|
25
|
+
|
|
23
26
|
const collSizeN = (collSizer) => (coll) =>
|
|
24
27
|
arrayReduce(collValues(coll), (total, coll2) => total + collSizer(coll2), 0);
|
|
25
28
|
const collSize = (coll) => coll.size;
|
|
@@ -317,9 +320,6 @@ const getListenerFunctions = (getThing) => {
|
|
|
317
320
|
return [addListener, callListeners, delListener, callListener];
|
|
318
321
|
};
|
|
319
322
|
|
|
320
|
-
const object = Object;
|
|
321
|
-
const objFreeze = object.freeze;
|
|
322
|
-
|
|
323
323
|
const createRelationships = getCreateFunction((store) => {
|
|
324
324
|
const remoteTableIds = mapNew();
|
|
325
325
|
const remoteRowIdListeners = mapNew();
|