tinybase 4.0.0-beta.5.2 → 4.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/cjs/persisters/persister-automerge.cjs +1 -1
- package/lib/cjs/persisters/persister-automerge.cjs.gz +0 -0
- package/lib/cjs/persisters/persister-browser.cjs +1 -1
- package/lib/cjs/persisters/persister-browser.cjs.gz +0 -0
- package/lib/cjs/persisters/persister-cr-sqlite-wasm.cjs +1 -1
- package/lib/cjs/persisters/persister-cr-sqlite-wasm.cjs.gz +0 -0
- package/lib/cjs/persisters/persister-file.cjs +1 -1
- package/lib/cjs/persisters/persister-file.cjs.gz +0 -0
- package/lib/cjs/persisters/persister-remote.cjs +1 -1
- package/lib/cjs/persisters/persister-remote.cjs.gz +0 -0
- package/lib/cjs/persisters/persister-sqlite-wasm.cjs +1 -1
- package/lib/cjs/persisters/persister-sqlite-wasm.cjs.gz +0 -0
- package/lib/cjs/persisters/persister-sqlite3.cjs +1 -1
- package/lib/cjs/persisters/persister-sqlite3.cjs.gz +0 -0
- package/lib/cjs/persisters/persister-yjs.cjs +1 -1
- package/lib/cjs/persisters/persister-yjs.cjs.gz +0 -0
- package/lib/cjs/persisters.cjs +1 -1
- package/lib/cjs/persisters.cjs.gz +0 -0
- package/lib/cjs/tinybase.cjs +1 -1
- package/lib/cjs/tinybase.cjs.gz +0 -0
- package/lib/cjs-es6/persisters/persister-automerge.cjs +1 -1
- package/lib/cjs-es6/persisters/persister-automerge.cjs.gz +0 -0
- package/lib/cjs-es6/persisters/persister-browser.cjs +1 -1
- package/lib/cjs-es6/persisters/persister-browser.cjs.gz +0 -0
- package/lib/cjs-es6/persisters/persister-cr-sqlite-wasm.cjs +1 -1
- package/lib/cjs-es6/persisters/persister-cr-sqlite-wasm.cjs.gz +0 -0
- package/lib/cjs-es6/persisters/persister-file.cjs +1 -1
- package/lib/cjs-es6/persisters/persister-file.cjs.gz +0 -0
- package/lib/cjs-es6/persisters/persister-remote.cjs +1 -1
- package/lib/cjs-es6/persisters/persister-remote.cjs.gz +0 -0
- package/lib/cjs-es6/persisters/persister-sqlite-wasm.cjs +1 -1
- package/lib/cjs-es6/persisters/persister-sqlite-wasm.cjs.gz +0 -0
- package/lib/cjs-es6/persisters/persister-sqlite3.cjs +1 -1
- package/lib/cjs-es6/persisters/persister-sqlite3.cjs.gz +0 -0
- package/lib/cjs-es6/persisters/persister-yjs.cjs +1 -1
- package/lib/cjs-es6/persisters/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/tinybase.cjs +1 -1
- package/lib/cjs-es6/tinybase.cjs.gz +0 -0
- package/lib/debug/persisters/persister-automerge.js +22 -20
- package/lib/debug/persisters/persister-browser.js +28 -20
- package/lib/debug/persisters/persister-cr-sqlite-wasm.js +199 -150
- package/lib/debug/persisters/persister-file.js +28 -20
- package/lib/debug/persisters/persister-remote.js +28 -20
- package/lib/debug/persisters/persister-sqlite-wasm.js +204 -150
- package/lib/debug/persisters/persister-sqlite3.js +199 -150
- package/lib/debug/persisters/persister-yjs.js +28 -20
- package/lib/debug/persisters.js +29 -20
- package/lib/debug/tinybase.js +22 -20
- package/lib/es6/persisters/persister-automerge.js +1 -1
- package/lib/es6/persisters/persister-automerge.js.gz +0 -0
- package/lib/es6/persisters/persister-browser.js +1 -1
- package/lib/es6/persisters/persister-browser.js.gz +0 -0
- package/lib/es6/persisters/persister-cr-sqlite-wasm.js +1 -1
- package/lib/es6/persisters/persister-cr-sqlite-wasm.js.gz +0 -0
- package/lib/es6/persisters/persister-file.js +1 -1
- package/lib/es6/persisters/persister-file.js.gz +0 -0
- package/lib/es6/persisters/persister-remote.js +1 -1
- package/lib/es6/persisters/persister-remote.js.gz +0 -0
- package/lib/es6/persisters/persister-sqlite-wasm.js +1 -1
- package/lib/es6/persisters/persister-sqlite-wasm.js.gz +0 -0
- package/lib/es6/persisters/persister-sqlite3.js +1 -1
- package/lib/es6/persisters/persister-sqlite3.js.gz +0 -0
- package/lib/es6/persisters/persister-yjs.js +1 -1
- package/lib/es6/persisters/persister-yjs.js.gz +0 -0
- package/lib/es6/persisters.js +1 -1
- package/lib/es6/persisters.js.gz +0 -0
- package/lib/es6/tinybase.js +1 -1
- package/lib/es6/tinybase.js.gz +0 -0
- package/lib/persisters/persister-automerge.js +1 -1
- package/lib/persisters/persister-automerge.js.gz +0 -0
- package/lib/persisters/persister-browser.js +1 -1
- package/lib/persisters/persister-browser.js.gz +0 -0
- package/lib/persisters/persister-cr-sqlite-wasm.js +1 -1
- package/lib/persisters/persister-cr-sqlite-wasm.js.gz +0 -0
- package/lib/persisters/persister-file.js +1 -1
- package/lib/persisters/persister-file.js.gz +0 -0
- package/lib/persisters/persister-remote.js +1 -1
- package/lib/persisters/persister-remote.js.gz +0 -0
- package/lib/persisters/persister-sqlite-wasm.js +1 -1
- package/lib/persisters/persister-sqlite-wasm.js.gz +0 -0
- package/lib/persisters/persister-sqlite3.js +1 -1
- package/lib/persisters/persister-sqlite3.js.gz +0 -0
- package/lib/persisters/persister-yjs.js +1 -1
- package/lib/persisters/persister-yjs.js.gz +0 -0
- package/lib/persisters.js +1 -1
- package/lib/persisters.js.gz +0 -0
- package/lib/tinybase.js +1 -1
- package/lib/tinybase.js.gz +0 -0
- package/lib/types/persisters/persister-cr-sqlite-wasm.d.ts +2 -0
- package/lib/types/persisters/persister-sqlite-wasm.d.ts +2 -0
- package/lib/types/persisters/persister-sqlite3.d.ts +2 -0
- package/lib/types/with-schemas/persisters/persister-cr-sqlite-wasm.d.ts +2 -0
- package/lib/types/with-schemas/persisters/persister-sqlite-wasm.d.ts +2 -0
- package/lib/types/with-schemas/persisters/persister-sqlite3.d.ts +2 -0
- package/lib/umd/persisters/persister-automerge.js +1 -1
- package/lib/umd/persisters/persister-automerge.js.gz +0 -0
- package/lib/umd/persisters/persister-browser.js +1 -1
- package/lib/umd/persisters/persister-browser.js.gz +0 -0
- package/lib/umd/persisters/persister-cr-sqlite-wasm.js +1 -1
- package/lib/umd/persisters/persister-cr-sqlite-wasm.js.gz +0 -0
- package/lib/umd/persisters/persister-file.js +1 -1
- package/lib/umd/persisters/persister-file.js.gz +0 -0
- package/lib/umd/persisters/persister-remote.js +1 -1
- package/lib/umd/persisters/persister-remote.js.gz +0 -0
- package/lib/umd/persisters/persister-sqlite-wasm.js +1 -1
- package/lib/umd/persisters/persister-sqlite-wasm.js.gz +0 -0
- package/lib/umd/persisters/persister-sqlite3.js +1 -1
- package/lib/umd/persisters/persister-sqlite3.js.gz +0 -0
- package/lib/umd/persisters/persister-yjs.js +1 -1
- package/lib/umd/persisters/persister-yjs.js.gz +0 -0
- package/lib/umd/persisters.js +1 -1
- package/lib/umd/persisters.js.gz +0 -0
- package/lib/umd/tinybase.js +1 -1
- package/lib/umd/tinybase.js.gz +0 -0
- package/lib/umd-es6/persisters/persister-automerge.js +1 -1
- package/lib/umd-es6/persisters/persister-automerge.js.gz +0 -0
- package/lib/umd-es6/persisters/persister-browser.js +1 -1
- package/lib/umd-es6/persisters/persister-browser.js.gz +0 -0
- package/lib/umd-es6/persisters/persister-cr-sqlite-wasm.js +1 -1
- package/lib/umd-es6/persisters/persister-cr-sqlite-wasm.js.gz +0 -0
- package/lib/umd-es6/persisters/persister-file.js +1 -1
- package/lib/umd-es6/persisters/persister-file.js.gz +0 -0
- package/lib/umd-es6/persisters/persister-remote.js +1 -1
- package/lib/umd-es6/persisters/persister-remote.js.gz +0 -0
- package/lib/umd-es6/persisters/persister-sqlite-wasm.js +1 -1
- package/lib/umd-es6/persisters/persister-sqlite-wasm.js.gz +0 -0
- package/lib/umd-es6/persisters/persister-sqlite3.js +1 -1
- package/lib/umd-es6/persisters/persister-sqlite3.js.gz +0 -0
- package/lib/umd-es6/persisters/persister-yjs.js +1 -1
- package/lib/umd-es6/persisters/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/tinybase.js +1 -1
- package/lib/umd-es6/tinybase.js.gz +0 -0
- package/package.json +16 -16
- package/readme.md +14 -14
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
const arrayLength = (array) => array.length;
|
|
1
2
|
const arrayReduce = (array, cb, initial) => array.reduce(cb, initial);
|
|
2
3
|
const arrayPush = (array, ...values) => array.push(...values);
|
|
3
4
|
const arrayShift = (array) => array.shift();
|
|
@@ -22,7 +23,12 @@ const ifNotUndefined = (value, then, otherwise) =>
|
|
|
22
23
|
isUndefined(value) ? otherwise?.() : then(value);
|
|
23
24
|
|
|
24
25
|
const object = Object;
|
|
26
|
+
const objIds = object.keys;
|
|
25
27
|
const objFreeze = object.freeze;
|
|
28
|
+
const isObject = (obj) =>
|
|
29
|
+
isInstanceOf(obj, object) && obj.constructor == object;
|
|
30
|
+
const objSize = (obj) => arrayLength(objIds(obj));
|
|
31
|
+
const objIsEmpty = (obj) => isObject(obj) && objSize(obj) == 0;
|
|
26
32
|
|
|
27
33
|
const createCustomPersister = (
|
|
28
34
|
store,
|
|
@@ -59,27 +65,28 @@ const createCustomPersister = (
|
|
|
59
65
|
{
|
|
60
66
|
loads++;
|
|
61
67
|
}
|
|
62
|
-
await
|
|
63
|
-
|
|
68
|
+
await persister.schedule(async () => {
|
|
69
|
+
await actions();
|
|
70
|
+
loadSave = 0;
|
|
71
|
+
});
|
|
64
72
|
}
|
|
73
|
+
return persister;
|
|
65
74
|
};
|
|
66
75
|
const persister = {
|
|
67
|
-
load: async (initialTables, initialValues) =>
|
|
76
|
+
load: async (initialTables, initialValues) =>
|
|
68
77
|
await loadLock(async () => {
|
|
69
78
|
try {
|
|
70
79
|
store.setContent(await getPersisted());
|
|
71
80
|
} catch {
|
|
72
81
|
store.setContent([initialTables, initialValues]);
|
|
73
82
|
}
|
|
74
|
-
})
|
|
75
|
-
return persister;
|
|
76
|
-
},
|
|
83
|
+
}),
|
|
77
84
|
startAutoLoad: async (initialTables = {}, initialValues = {}) => {
|
|
78
85
|
persister.stopAutoLoad();
|
|
79
86
|
await persister.load(initialTables, initialValues);
|
|
80
87
|
listening = 1;
|
|
81
88
|
listeningHandle = addPersisterListener(
|
|
82
|
-
async (getContent, getTransactionChanges) =>
|
|
89
|
+
async (getContent, getTransactionChanges) =>
|
|
83
90
|
await loadLock(async () => {
|
|
84
91
|
if (getTransactionChanges) {
|
|
85
92
|
store.setTransactionChanges(getTransactionChanges());
|
|
@@ -88,8 +95,7 @@ const createCustomPersister = (
|
|
|
88
95
|
store.setContent(getContent?.() ?? (await getPersisted()));
|
|
89
96
|
} catch {}
|
|
90
97
|
}
|
|
91
|
-
})
|
|
92
|
-
},
|
|
98
|
+
}),
|
|
93
99
|
);
|
|
94
100
|
return persister;
|
|
95
101
|
},
|
|
@@ -102,27 +108,29 @@ const createCustomPersister = (
|
|
|
102
108
|
return persister;
|
|
103
109
|
},
|
|
104
110
|
save: async (getTransactionChanges) => {
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
111
|
+
/* istanbul ignore else */
|
|
112
|
+
if (loadSave != 1) {
|
|
113
|
+
loadSave = 2;
|
|
114
|
+
{
|
|
115
|
+
saves++;
|
|
116
|
+
}
|
|
117
|
+
await persister.schedule(async () => {
|
|
112
118
|
try {
|
|
113
119
|
await setPersisted(store.getContent, getTransactionChanges);
|
|
114
120
|
} catch {}
|
|
115
121
|
loadSave = 0;
|
|
116
|
-
}
|
|
117
|
-
}
|
|
122
|
+
});
|
|
123
|
+
}
|
|
118
124
|
return persister;
|
|
119
125
|
},
|
|
120
126
|
startAutoSave: async () => {
|
|
121
127
|
await persister.stopAutoSave().save();
|
|
122
128
|
listenerId = store.addDidFinishTransactionListener(
|
|
123
129
|
(_store, getTransactionChanges) => {
|
|
124
|
-
const
|
|
125
|
-
|
|
130
|
+
const [tableChanges, valueChanges] = getTransactionChanges();
|
|
131
|
+
if (!objIsEmpty(tableChanges) || !objIsEmpty(valueChanges)) {
|
|
132
|
+
persister.save(() => [tableChanges, valueChanges]);
|
|
133
|
+
}
|
|
126
134
|
},
|
|
127
135
|
);
|
|
128
136
|
return persister;
|
|
@@ -38,6 +38,11 @@ const isString = (thing) => getTypeOf(thing) == STRING;
|
|
|
38
38
|
const isArray = (thing) => Array.isArray(thing);
|
|
39
39
|
const promiseAll = async (promises) => promise.all(promises);
|
|
40
40
|
|
|
41
|
+
const collHas = (coll, keyOrValue) => coll?.has(keyOrValue) ?? false;
|
|
42
|
+
const collValues = (coll) => [...(coll?.values() ?? [])];
|
|
43
|
+
const collForEach = (coll, cb) => coll?.forEach(cb);
|
|
44
|
+
const collDel = (coll, keyOrValue) => coll?.delete(keyOrValue);
|
|
45
|
+
|
|
41
46
|
const object = Object;
|
|
42
47
|
const objIds = object.keys;
|
|
43
48
|
const objFreeze = object.freeze;
|
|
@@ -57,11 +62,6 @@ const objValues = (obj) => object.values(obj);
|
|
|
57
62
|
const objSize = (obj) => arrayLength(objIds(obj));
|
|
58
63
|
const objIsEmpty = (obj) => isObject(obj) && objSize(obj) == 0;
|
|
59
64
|
|
|
60
|
-
const collHas = (coll, keyOrValue) => coll?.has(keyOrValue) ?? false;
|
|
61
|
-
const collValues = (coll) => [...(coll?.values() ?? [])];
|
|
62
|
-
const collForEach = (coll, cb) => coll?.forEach(cb);
|
|
63
|
-
const collDel = (coll, keyOrValue) => coll?.delete(keyOrValue);
|
|
64
|
-
|
|
65
65
|
const mapNew = (entries) => new Map(entries);
|
|
66
66
|
const mapKeys = (map) => [...(map?.keys() ?? [])];
|
|
67
67
|
const mapGet = (map, key) => map?.get(key);
|
|
@@ -98,9 +98,7 @@ const setAdd = (set, value) => set?.add(value);
|
|
|
98
98
|
const SELECT_STAR_FROM = 'SELECT*FROM';
|
|
99
99
|
const FROM_PRAGMA_TABLE = 'FROM pragma_table_';
|
|
100
100
|
const WHERE = 'WHERE';
|
|
101
|
-
const
|
|
102
|
-
WHERE + ` schema='main'AND type='table'AND name!='sqlite_schema'`;
|
|
103
|
-
const getCommandFunctions = (cmd) => {
|
|
101
|
+
const getCommandFunctions = (cmd, managedTableNames) => {
|
|
104
102
|
const schemaMap = mapNew();
|
|
105
103
|
const canSelect = (tableName, rowIdColumnName) =>
|
|
106
104
|
!isUndefined(mapGet(mapGet(schemaMap, tableName), rowIdColumnName));
|
|
@@ -111,7 +109,12 @@ const getCommandFunctions = (cmd) => {
|
|
|
111
109
|
await promiseAll(
|
|
112
110
|
arrayMap(
|
|
113
111
|
await cmd(
|
|
114
|
-
'SELECT name ' +
|
|
112
|
+
'SELECT name ' +
|
|
113
|
+
FROM_PRAGMA_TABLE +
|
|
114
|
+
`list WHERE schema='main'AND type='table'AND name IN(` +
|
|
115
|
+
getPlaceholders(managedTableNames) +
|
|
116
|
+
`)`,
|
|
117
|
+
managedTableNames,
|
|
115
118
|
),
|
|
116
119
|
async ({name: tableName}) => [
|
|
117
120
|
tableName,
|
|
@@ -245,15 +248,19 @@ const getCommandFunctions = (cmd) => {
|
|
|
245
248
|
const insertSlots = [];
|
|
246
249
|
const insertBinds = [];
|
|
247
250
|
const deleteRowIds = [];
|
|
251
|
+
const allColumnNames = arrayFilter(
|
|
252
|
+
mapKeys(mapGet(schemaMap, tableName)),
|
|
253
|
+
(columnName) => columnName != rowIdColumnName,
|
|
254
|
+
);
|
|
248
255
|
objMap(table, (row, rowId) => {
|
|
249
256
|
arrayPush(
|
|
250
257
|
insertSlots,
|
|
251
|
-
`(?${strRepeat(',?', arrayLength(
|
|
258
|
+
`(?${strRepeat(',?', arrayLength(allColumnNames))})`,
|
|
252
259
|
);
|
|
253
260
|
arrayPush(
|
|
254
261
|
insertBinds,
|
|
255
262
|
rowId,
|
|
256
|
-
...arrayMap(
|
|
263
|
+
...arrayMap(allColumnNames, (cellId) => row[cellId]),
|
|
257
264
|
);
|
|
258
265
|
arrayPush(deleteRowIds, rowId);
|
|
259
266
|
});
|
|
@@ -263,10 +270,24 @@ const getCommandFunctions = (cmd) => {
|
|
|
263
270
|
'(' +
|
|
264
271
|
escapeId(rowIdColumnName) +
|
|
265
272
|
arrayJoin(
|
|
266
|
-
arrayMap(
|
|
273
|
+
arrayMap(
|
|
274
|
+
allColumnNames,
|
|
275
|
+
(columnName) => COMMA + escapeId(columnName),
|
|
276
|
+
),
|
|
267
277
|
) +
|
|
268
278
|
')VALUES' +
|
|
269
|
-
arrayJoin(insertSlots, COMMA)
|
|
279
|
+
arrayJoin(insertSlots, COMMA) +
|
|
280
|
+
'ON CONFLICT(' +
|
|
281
|
+
escapeId(rowIdColumnName) +
|
|
282
|
+
')DO UPDATE SET' +
|
|
283
|
+
arrayJoin(
|
|
284
|
+
arrayMap(
|
|
285
|
+
allColumnNames,
|
|
286
|
+
(columnName) =>
|
|
287
|
+
escapeId(columnName) + '=excluded.' + escapeId(columnName),
|
|
288
|
+
),
|
|
289
|
+
COMMA,
|
|
290
|
+
),
|
|
270
291
|
insertBinds,
|
|
271
292
|
);
|
|
272
293
|
await cmd(
|
|
@@ -275,19 +296,21 @@ const getCommandFunctions = (cmd) => {
|
|
|
275
296
|
WHERE +
|
|
276
297
|
escapeId(rowIdColumnName) +
|
|
277
298
|
'NOT IN(' +
|
|
278
|
-
|
|
279
|
-
arrayMap(deleteRowIds, () => '?'),
|
|
280
|
-
COMMA,
|
|
281
|
-
) +
|
|
299
|
+
getPlaceholders(deleteRowIds) +
|
|
282
300
|
')',
|
|
283
301
|
deleteRowIds,
|
|
284
302
|
);
|
|
285
|
-
} else {
|
|
303
|
+
} else if (collHas(schemaMap, tableName)) {
|
|
286
304
|
await cmd('DELETE FROM' + escapeId(tableName));
|
|
287
305
|
}
|
|
288
306
|
};
|
|
289
307
|
return [refreshSchema, loadSingleRow, saveSingleRow, loadTable, saveTable];
|
|
290
308
|
};
|
|
309
|
+
const getPlaceholders = (array) =>
|
|
310
|
+
arrayJoin(
|
|
311
|
+
arrayMap(array, () => '?'),
|
|
312
|
+
COMMA,
|
|
313
|
+
);
|
|
291
314
|
|
|
292
315
|
const createCustomPersister = (
|
|
293
316
|
store,
|
|
@@ -324,27 +347,28 @@ const createCustomPersister = (
|
|
|
324
347
|
{
|
|
325
348
|
loads++;
|
|
326
349
|
}
|
|
327
|
-
await
|
|
328
|
-
|
|
350
|
+
await persister.schedule(async () => {
|
|
351
|
+
await actions();
|
|
352
|
+
loadSave = 0;
|
|
353
|
+
});
|
|
329
354
|
}
|
|
355
|
+
return persister;
|
|
330
356
|
};
|
|
331
357
|
const persister = {
|
|
332
|
-
load: async (initialTables, initialValues) =>
|
|
358
|
+
load: async (initialTables, initialValues) =>
|
|
333
359
|
await loadLock(async () => {
|
|
334
360
|
try {
|
|
335
361
|
store.setContent(await getPersisted());
|
|
336
362
|
} catch {
|
|
337
363
|
store.setContent([initialTables, initialValues]);
|
|
338
364
|
}
|
|
339
|
-
})
|
|
340
|
-
return persister;
|
|
341
|
-
},
|
|
365
|
+
}),
|
|
342
366
|
startAutoLoad: async (initialTables = {}, initialValues = {}) => {
|
|
343
367
|
persister.stopAutoLoad();
|
|
344
368
|
await persister.load(initialTables, initialValues);
|
|
345
369
|
listening = 1;
|
|
346
370
|
listeningHandle = addPersisterListener(
|
|
347
|
-
async (getContent, getTransactionChanges) =>
|
|
371
|
+
async (getContent, getTransactionChanges) =>
|
|
348
372
|
await loadLock(async () => {
|
|
349
373
|
if (getTransactionChanges) {
|
|
350
374
|
store.setTransactionChanges(getTransactionChanges());
|
|
@@ -353,8 +377,7 @@ const createCustomPersister = (
|
|
|
353
377
|
store.setContent(getContent?.() ?? (await getPersisted()));
|
|
354
378
|
} catch {}
|
|
355
379
|
}
|
|
356
|
-
})
|
|
357
|
-
},
|
|
380
|
+
}),
|
|
358
381
|
);
|
|
359
382
|
return persister;
|
|
360
383
|
},
|
|
@@ -367,27 +390,29 @@ const createCustomPersister = (
|
|
|
367
390
|
return persister;
|
|
368
391
|
},
|
|
369
392
|
save: async (getTransactionChanges) => {
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
393
|
+
/* istanbul ignore else */
|
|
394
|
+
if (loadSave != 1) {
|
|
395
|
+
loadSave = 2;
|
|
396
|
+
{
|
|
397
|
+
saves++;
|
|
398
|
+
}
|
|
399
|
+
await persister.schedule(async () => {
|
|
377
400
|
try {
|
|
378
401
|
await setPersisted(store.getContent, getTransactionChanges);
|
|
379
402
|
} catch {}
|
|
380
403
|
loadSave = 0;
|
|
381
|
-
}
|
|
382
|
-
}
|
|
404
|
+
});
|
|
405
|
+
}
|
|
383
406
|
return persister;
|
|
384
407
|
},
|
|
385
408
|
startAutoSave: async () => {
|
|
386
409
|
await persister.stopAutoSave().save();
|
|
387
410
|
listenerId = store.addDidFinishTransactionListener(
|
|
388
411
|
(_store, getTransactionChanges) => {
|
|
389
|
-
const
|
|
390
|
-
|
|
412
|
+
const [tableChanges, valueChanges] = getTransactionChanges();
|
|
413
|
+
if (!objIsEmpty(tableChanges) || !objIsEmpty(valueChanges)) {
|
|
414
|
+
persister.save(() => [tableChanges, valueChanges]);
|
|
415
|
+
}
|
|
391
416
|
},
|
|
392
417
|
);
|
|
393
418
|
return persister;
|
|
@@ -414,10 +439,13 @@ const createJsonSqlitePersister = (
|
|
|
414
439
|
cmd,
|
|
415
440
|
addPersisterListener,
|
|
416
441
|
delPersisterListener,
|
|
417
|
-
|
|
442
|
+
[storeTableName],
|
|
443
|
+
managedTableNames,
|
|
418
444
|
) => {
|
|
419
|
-
const [refreshSchema, loadSingleRow, saveSingleRow] =
|
|
420
|
-
|
|
445
|
+
const [refreshSchema, loadSingleRow, saveSingleRow] = getCommandFunctions(
|
|
446
|
+
cmd,
|
|
447
|
+
managedTableNames,
|
|
448
|
+
);
|
|
421
449
|
const getPersisted = async () => {
|
|
422
450
|
await refreshSchema();
|
|
423
451
|
return jsonParse(
|
|
@@ -445,97 +473,28 @@ const createJsonSqlitePersister = (
|
|
|
445
473
|
return persister;
|
|
446
474
|
};
|
|
447
475
|
|
|
448
|
-
const ROW_ID_COLUMN_NAME = 'rowIdColumnName';
|
|
449
|
-
const TABLE_ID = 'tableId';
|
|
450
|
-
const TABLE_NAME = 'tableName';
|
|
451
|
-
const DELETE_EMPTY_COLUMNS = 'deleteEmptyColumns';
|
|
452
|
-
const DELETE_EMPTY_TABLE = 'deleteEmptyTable';
|
|
453
|
-
const DEFAULTED_VALUES_CONFIG = {
|
|
454
|
-
load: 0,
|
|
455
|
-
save: 0,
|
|
456
|
-
[TABLE_NAME]: TINYBASE + '_values',
|
|
457
|
-
};
|
|
458
|
-
const getDefaultedTableConfigMap = (
|
|
459
|
-
configsObj,
|
|
460
|
-
defaultObj,
|
|
461
|
-
tableField,
|
|
462
|
-
filter,
|
|
463
|
-
) => {
|
|
464
|
-
const configMap = mapNew();
|
|
465
|
-
objMap(configsObj, (configObj, id) => {
|
|
466
|
-
const defaultedConfig = arraySlice(
|
|
467
|
-
objValues(
|
|
468
|
-
objMerge(
|
|
469
|
-
defaultObj,
|
|
470
|
-
isString(configObj) ? {[tableField]: configObj} : configObj,
|
|
471
|
-
),
|
|
472
|
-
),
|
|
473
|
-
0,
|
|
474
|
-
objSize(defaultObj),
|
|
475
|
-
);
|
|
476
|
-
if (!isUndefined(defaultedConfig[0]) && !filter(id, defaultedConfig[0])) {
|
|
477
|
-
mapSet(configMap, id, defaultedConfig);
|
|
478
|
-
}
|
|
479
|
-
});
|
|
480
|
-
return configMap;
|
|
481
|
-
};
|
|
482
|
-
const getDefaultedConfig = ({
|
|
483
|
-
tables: {load = {}, save = {}} = {},
|
|
484
|
-
values = {},
|
|
485
|
-
}) => {
|
|
486
|
-
const valuesConfig = arraySlice(
|
|
487
|
-
objValues(objMerge(DEFAULTED_VALUES_CONFIG, values)),
|
|
488
|
-
0,
|
|
489
|
-
objSize(DEFAULTED_VALUES_CONFIG),
|
|
490
|
-
);
|
|
491
|
-
const valuesTable = valuesConfig[2];
|
|
492
|
-
return [
|
|
493
|
-
getDefaultedTableConfigMap(
|
|
494
|
-
load,
|
|
495
|
-
{
|
|
496
|
-
[TABLE_ID]: null,
|
|
497
|
-
[ROW_ID_COLUMN_NAME]: DEFAULT_ROW_ID_COLUMN_NAME,
|
|
498
|
-
},
|
|
499
|
-
TABLE_ID,
|
|
500
|
-
(tableName) => tableName == valuesTable,
|
|
501
|
-
),
|
|
502
|
-
getDefaultedTableConfigMap(
|
|
503
|
-
save,
|
|
504
|
-
{
|
|
505
|
-
[TABLE_NAME]: null,
|
|
506
|
-
[ROW_ID_COLUMN_NAME]: DEFAULT_ROW_ID_COLUMN_NAME,
|
|
507
|
-
[DELETE_EMPTY_COLUMNS]: 0,
|
|
508
|
-
[DELETE_EMPTY_TABLE]: 0,
|
|
509
|
-
},
|
|
510
|
-
TABLE_NAME,
|
|
511
|
-
(_, tableName) => tableName == valuesTable,
|
|
512
|
-
),
|
|
513
|
-
valuesConfig,
|
|
514
|
-
];
|
|
515
|
-
};
|
|
516
|
-
|
|
517
476
|
const createTabularSqlitePersister = (
|
|
518
477
|
store,
|
|
519
478
|
cmd,
|
|
520
479
|
addPersisterListener,
|
|
521
480
|
delPersisterListener,
|
|
522
|
-
|
|
523
|
-
) => {
|
|
524
|
-
const [
|
|
481
|
+
[
|
|
525
482
|
tablesLoadConfig,
|
|
526
483
|
tablesSaveConfig,
|
|
527
484
|
[valuesLoad, valuesSave, valuesTableName],
|
|
528
|
-
]
|
|
485
|
+
],
|
|
486
|
+
managedTableNames,
|
|
487
|
+
) => {
|
|
529
488
|
const [refreshSchema, loadSingleRow, saveSingleRow, loadTable, saveTable] =
|
|
530
|
-
getCommandFunctions(cmd);
|
|
531
|
-
const
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
489
|
+
getCommandFunctions(cmd, managedTableNames);
|
|
490
|
+
const saveTables = async (tables) =>
|
|
491
|
+
await promiseAll(
|
|
492
|
+
mapMap(
|
|
493
|
+
tablesSaveConfig,
|
|
494
|
+
async (
|
|
535
495
|
[tableName, rowIdColumnName, deleteEmptyColumns, deleteEmptyTable],
|
|
536
496
|
tableId,
|
|
537
497
|
) =>
|
|
538
|
-
async () =>
|
|
539
498
|
await saveTable(
|
|
540
499
|
tableName,
|
|
541
500
|
rowIdColumnName,
|
|
@@ -543,16 +502,16 @@ const createTabularSqlitePersister = (
|
|
|
543
502
|
deleteEmptyTable,
|
|
544
503
|
tables[tableId],
|
|
545
504
|
),
|
|
505
|
+
),
|
|
546
506
|
);
|
|
547
|
-
const
|
|
507
|
+
const saveValues = async (values) =>
|
|
548
508
|
valuesSave
|
|
549
|
-
?
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
)
|
|
509
|
+
? await saveSingleRow(
|
|
510
|
+
valuesTableName,
|
|
511
|
+
DEFAULT_ROW_ID_COLUMN_NAME,
|
|
512
|
+
SINGLE_ROW_ID,
|
|
513
|
+
values,
|
|
514
|
+
)
|
|
556
515
|
: null;
|
|
557
516
|
const loadTables = async () =>
|
|
558
517
|
objNew(
|
|
@@ -583,11 +542,9 @@ const createTabularSqlitePersister = (
|
|
|
583
542
|
};
|
|
584
543
|
const setPersisted = async (getContent) => {
|
|
585
544
|
const [tables, values] = getContent();
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
getSaveValuesAction(values),
|
|
590
|
-
);
|
|
545
|
+
await refreshSchema();
|
|
546
|
+
await saveTables(tables);
|
|
547
|
+
await saveValues(values);
|
|
591
548
|
};
|
|
592
549
|
const persister = createCustomPersister(
|
|
593
550
|
store,
|
|
@@ -601,10 +558,97 @@ const createTabularSqlitePersister = (
|
|
|
601
558
|
|
|
602
559
|
const JSON$1 = 'json';
|
|
603
560
|
const AUTO_LOAD_INTERVAL_SECONDS = 'autoLoadIntervalSeconds';
|
|
561
|
+
const STORE_TABLE_NAME = 'storeTableName';
|
|
562
|
+
const ROW_ID_COLUMN_NAME = 'rowIdColumnName';
|
|
563
|
+
const TABLE_ID = 'tableId';
|
|
564
|
+
const TABLE_NAME = 'tableName';
|
|
565
|
+
const DELETE_EMPTY_COLUMNS = 'deleteEmptyColumns';
|
|
566
|
+
const DELETE_EMPTY_TABLE = 'deleteEmptyTable';
|
|
604
567
|
const DEFAULT_CONFIG = {
|
|
605
568
|
mode: JSON$1,
|
|
606
569
|
[AUTO_LOAD_INTERVAL_SECONDS]: 1,
|
|
607
570
|
};
|
|
571
|
+
const DEFAULT_TABULAR_VALUES_CONFIG = {
|
|
572
|
+
load: 0,
|
|
573
|
+
save: 0,
|
|
574
|
+
[TABLE_NAME]: TINYBASE + '_values',
|
|
575
|
+
};
|
|
576
|
+
const getDefaultedConfig = (configOrStoreTableName) =>
|
|
577
|
+
objMerge(
|
|
578
|
+
DEFAULT_CONFIG,
|
|
579
|
+
isString(configOrStoreTableName)
|
|
580
|
+
? {[STORE_TABLE_NAME]: configOrStoreTableName}
|
|
581
|
+
: configOrStoreTableName ?? {},
|
|
582
|
+
);
|
|
583
|
+
const getDefaultedTabularConfigMap = (
|
|
584
|
+
configsObj,
|
|
585
|
+
defaultObj,
|
|
586
|
+
tableField,
|
|
587
|
+
filter,
|
|
588
|
+
) => {
|
|
589
|
+
const configMap = mapNew();
|
|
590
|
+
objMap(configsObj, (configObj, id) => {
|
|
591
|
+
const defaultedConfig = arraySlice(
|
|
592
|
+
objValues(
|
|
593
|
+
objMerge(
|
|
594
|
+
defaultObj,
|
|
595
|
+
isString(configObj) ? {[tableField]: configObj} : configObj,
|
|
596
|
+
),
|
|
597
|
+
),
|
|
598
|
+
0,
|
|
599
|
+
objSize(defaultObj),
|
|
600
|
+
);
|
|
601
|
+
if (!isUndefined(defaultedConfig[0]) && !filter(id, defaultedConfig[0])) {
|
|
602
|
+
mapSet(configMap, id, defaultedConfig);
|
|
603
|
+
}
|
|
604
|
+
});
|
|
605
|
+
return configMap;
|
|
606
|
+
};
|
|
607
|
+
const getConfigStructures = (configOrStoreTableName) => {
|
|
608
|
+
const config = getDefaultedConfig(configOrStoreTableName);
|
|
609
|
+
const autoLoadIntervalSeconds = config[AUTO_LOAD_INTERVAL_SECONDS];
|
|
610
|
+
if (config.mode == JSON$1) {
|
|
611
|
+
const {storeTableName = TINYBASE} = config;
|
|
612
|
+
return [
|
|
613
|
+
1,
|
|
614
|
+
autoLoadIntervalSeconds,
|
|
615
|
+
[storeTableName],
|
|
616
|
+
setNew(storeTableName),
|
|
617
|
+
];
|
|
618
|
+
}
|
|
619
|
+
const {tables: {load = {}, save = {}} = {}, values = {}} = config;
|
|
620
|
+
const valuesConfig = arraySlice(
|
|
621
|
+
objValues(objMerge(DEFAULT_TABULAR_VALUES_CONFIG, values)),
|
|
622
|
+
0,
|
|
623
|
+
objSize(DEFAULT_TABULAR_VALUES_CONFIG),
|
|
624
|
+
);
|
|
625
|
+
const valuesTable = valuesConfig[2];
|
|
626
|
+
const managedTableNames = setNew(valuesTable);
|
|
627
|
+
const tabularConfig = [
|
|
628
|
+
getDefaultedTabularConfigMap(
|
|
629
|
+
load,
|
|
630
|
+
{[TABLE_ID]: null, [ROW_ID_COLUMN_NAME]: DEFAULT_ROW_ID_COLUMN_NAME},
|
|
631
|
+
TABLE_ID,
|
|
632
|
+
(tableName) =>
|
|
633
|
+
setAdd(managedTableNames, tableName) && tableName == valuesTable,
|
|
634
|
+
),
|
|
635
|
+
getDefaultedTabularConfigMap(
|
|
636
|
+
save,
|
|
637
|
+
{
|
|
638
|
+
[TABLE_NAME]: null,
|
|
639
|
+
[ROW_ID_COLUMN_NAME]: DEFAULT_ROW_ID_COLUMN_NAME,
|
|
640
|
+
[DELETE_EMPTY_COLUMNS]: 0,
|
|
641
|
+
[DELETE_EMPTY_TABLE]: 0,
|
|
642
|
+
},
|
|
643
|
+
TABLE_NAME,
|
|
644
|
+
(_, tableName) =>
|
|
645
|
+
setAdd(managedTableNames, tableName) && tableName == valuesTable,
|
|
646
|
+
),
|
|
647
|
+
valuesConfig,
|
|
648
|
+
];
|
|
649
|
+
return [0, autoLoadIntervalSeconds, tabularConfig, managedTableNames];
|
|
650
|
+
};
|
|
651
|
+
|
|
608
652
|
const PRAGMA = 'pragma ';
|
|
609
653
|
const DATA_VERSION = 'data_version';
|
|
610
654
|
const SCHEMA_VERSION = 'schema_version';
|
|
@@ -612,17 +656,17 @@ const createSqlitePersister = (
|
|
|
612
656
|
store,
|
|
613
657
|
configOrStoreTableName,
|
|
614
658
|
cmd,
|
|
615
|
-
|
|
616
|
-
|
|
659
|
+
addUpdateListener,
|
|
660
|
+
delUpdateListener,
|
|
617
661
|
) => {
|
|
618
|
-
const config = objMerge(
|
|
619
|
-
DEFAULT_CONFIG,
|
|
620
|
-
isString(configOrStoreTableName)
|
|
621
|
-
? {storeTableName: configOrStoreTableName}
|
|
622
|
-
: configOrStoreTableName ?? {},
|
|
623
|
-
);
|
|
624
662
|
let dataVersion;
|
|
625
663
|
let schemaVersion;
|
|
664
|
+
const [
|
|
665
|
+
isJson,
|
|
666
|
+
autoLoadIntervalSeconds,
|
|
667
|
+
defaultedConfig,
|
|
668
|
+
managedTableNamesSet,
|
|
669
|
+
] = getConfigStructures(configOrStoreTableName);
|
|
626
670
|
const addPersisterListener = (listener) => [
|
|
627
671
|
setInterval(async () => {
|
|
628
672
|
try {
|
|
@@ -641,19 +685,24 @@ const createSqlitePersister = (
|
|
|
641
685
|
schemaVersion = newSchemaVersion;
|
|
642
686
|
}
|
|
643
687
|
} catch {}
|
|
644
|
-
},
|
|
645
|
-
|
|
688
|
+
}, autoLoadIntervalSeconds * 1e3),
|
|
689
|
+
addUpdateListener((tableName) =>
|
|
690
|
+
managedTableNamesSet.has(tableName) ? listener() : 0,
|
|
691
|
+
),
|
|
646
692
|
];
|
|
647
693
|
const delPersisterListener = ([interval, listeningHandle]) => {
|
|
648
694
|
clearInterval(interval);
|
|
649
695
|
dataVersion = schemaVersion = null;
|
|
650
|
-
|
|
696
|
+
delUpdateListener(listeningHandle);
|
|
651
697
|
};
|
|
652
|
-
return (
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
698
|
+
return (isJson ? createJsonSqlitePersister : createTabularSqlitePersister)(
|
|
699
|
+
store,
|
|
700
|
+
cmd,
|
|
701
|
+
addPersisterListener,
|
|
702
|
+
delPersisterListener,
|
|
703
|
+
defaultedConfig,
|
|
704
|
+
collValues(managedTableNamesSet),
|
|
705
|
+
);
|
|
657
706
|
};
|
|
658
707
|
|
|
659
708
|
const createSqliteWasmPersister = (
|
|
@@ -669,7 +718,12 @@ const createSqliteWasmPersister = (
|
|
|
669
718
|
db
|
|
670
719
|
.exec(sql, {bind: args, rowMode: 'object', returnValue: 'resultRows'})
|
|
671
720
|
.map((row) => ({...row})),
|
|
672
|
-
(listener) =>
|
|
721
|
+
(listener) =>
|
|
722
|
+
sqlite3.capi.sqlite3_update_hook(
|
|
723
|
+
db,
|
|
724
|
+
(_, _2, _3, tableName) => listener(tableName),
|
|
725
|
+
0,
|
|
726
|
+
),
|
|
673
727
|
() => sqlite3.capi.sqlite3_update_hook(db, () => 0, 0),
|
|
674
728
|
);
|
|
675
729
|
|