tinybase 6.1.0-beta.4 → 6.1.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.
- package/@types/persisters/index.d.ts +82 -40
- package/@types/persisters/persister-automerge/index.d.ts +4 -4
- package/@types/persisters/persister-automerge/with-schemas/index.d.ts +4 -4
- package/@types/persisters/persister-browser/index.d.ts +4 -4
- package/@types/persisters/persister-browser/with-schemas/index.d.ts +4 -4
- package/@types/persisters/persister-cr-sqlite-wasm/index.d.ts +3 -3
- package/@types/persisters/persister-cr-sqlite-wasm/with-schemas/index.d.ts +3 -3
- package/@types/persisters/persister-electric-sql/index.d.ts +3 -3
- package/@types/persisters/persister-electric-sql/with-schemas/index.d.ts +3 -3
- package/@types/persisters/persister-expo-sqlite/index.d.ts +3 -3
- package/@types/persisters/persister-expo-sqlite/with-schemas/index.d.ts +3 -3
- package/@types/persisters/persister-file/index.d.ts +2 -2
- package/@types/persisters/persister-file/with-schemas/index.d.ts +2 -2
- package/@types/persisters/persister-indexed-db/index.d.ts +2 -2
- package/@types/persisters/persister-indexed-db/with-schemas/index.d.ts +2 -2
- package/@types/persisters/persister-libsql/index.d.ts +3 -3
- package/@types/persisters/persister-libsql/with-schemas/index.d.ts +3 -3
- package/@types/persisters/persister-partykit-client/index.d.ts +2 -2
- package/@types/persisters/persister-partykit-client/with-schemas/index.d.ts +2 -2
- package/@types/persisters/persister-pglite/index.d.ts +3 -3
- package/@types/persisters/persister-pglite/with-schemas/index.d.ts +3 -3
- package/@types/persisters/persister-postgres/index.d.ts +3 -3
- package/@types/persisters/persister-postgres/with-schemas/index.d.ts +3 -3
- package/@types/persisters/persister-powersync/index.d.ts +3 -3
- package/@types/persisters/persister-powersync/with-schemas/index.d.ts +3 -3
- package/@types/persisters/persister-remote/index.d.ts +2 -2
- package/@types/persisters/persister-remote/with-schemas/index.d.ts +2 -2
- package/@types/persisters/persister-sqlite-bun/index.d.ts +3 -3
- package/@types/persisters/persister-sqlite-bun/with-schemas/index.d.ts +3 -3
- package/@types/persisters/persister-sqlite-wasm/index.d.ts +3 -3
- package/@types/persisters/persister-sqlite-wasm/with-schemas/index.d.ts +3 -3
- package/@types/persisters/persister-sqlite3/index.d.ts +3 -3
- package/@types/persisters/persister-sqlite3/with-schemas/index.d.ts +3 -3
- package/@types/persisters/persister-yjs/index.d.ts +4 -4
- package/@types/persisters/persister-yjs/with-schemas/index.d.ts +4 -4
- package/@types/persisters/with-schemas/index.d.ts +86 -42
- package/@types/synchronizers/index.d.ts +18 -16
- package/@types/synchronizers/synchronizer-broadcast-channel/index.d.ts +3 -3
- package/@types/synchronizers/synchronizer-broadcast-channel/with-schemas/index.d.ts +3 -3
- package/@types/synchronizers/synchronizer-local/index.d.ts +2 -2
- package/@types/synchronizers/synchronizer-local/with-schemas/index.d.ts +2 -2
- package/@types/synchronizers/synchronizer-ws-client/index.d.ts +5 -5
- package/@types/synchronizers/synchronizer-ws-client/with-schemas/index.d.ts +5 -5
- package/@types/synchronizers/synchronizer-ws-server/index.d.ts +37 -37
- package/@types/synchronizers/synchronizer-ws-server/with-schemas/index.d.ts +37 -37
- package/@types/synchronizers/synchronizer-ws-server-simple/index.d.ts +7 -7
- package/@types/synchronizers/synchronizer-ws-server-simple/with-schemas/index.d.ts +7 -7
- package/@types/synchronizers/with-schemas/index.d.ts +18 -16
- package/@types/ui-react/index.d.ts +2 -2
- package/@types/ui-react/with-schemas/index.d.ts +2 -2
- package/index.js +23 -17
- package/mergeable-store/index.js +23 -17
- package/mergeable-store/with-schemas/index.js +23 -17
- package/min/index.js +1 -1
- package/min/index.js.gz +0 -0
- package/min/mergeable-store/index.js +1 -1
- package/min/mergeable-store/index.js.gz +0 -0
- package/min/mergeable-store/with-schemas/index.js +1 -1
- package/min/mergeable-store/with-schemas/index.js.gz +0 -0
- package/min/persisters/index.js +1 -1
- package/min/persisters/index.js.gz +0 -0
- package/min/persisters/persister-automerge/index.js +1 -1
- package/min/persisters/persister-automerge/index.js.gz +0 -0
- package/min/persisters/persister-automerge/with-schemas/index.js +1 -1
- package/min/persisters/persister-automerge/with-schemas/index.js.gz +0 -0
- package/min/persisters/persister-browser/index.js +1 -1
- package/min/persisters/persister-browser/index.js.gz +0 -0
- package/min/persisters/persister-browser/with-schemas/index.js +1 -1
- package/min/persisters/persister-browser/with-schemas/index.js.gz +0 -0
- package/min/persisters/persister-cr-sqlite-wasm/index.js +1 -1
- package/min/persisters/persister-cr-sqlite-wasm/index.js.gz +0 -0
- package/min/persisters/persister-cr-sqlite-wasm/with-schemas/index.js +1 -1
- package/min/persisters/persister-cr-sqlite-wasm/with-schemas/index.js.gz +0 -0
- package/min/persisters/persister-durable-object-storage/index.js +1 -1
- package/min/persisters/persister-durable-object-storage/index.js.gz +0 -0
- package/min/persisters/persister-durable-object-storage/with-schemas/index.js +1 -1
- package/min/persisters/persister-durable-object-storage/with-schemas/index.js.gz +0 -0
- package/min/persisters/persister-electric-sql/index.js +1 -1
- package/min/persisters/persister-electric-sql/index.js.gz +0 -0
- package/min/persisters/persister-electric-sql/with-schemas/index.js +1 -1
- package/min/persisters/persister-electric-sql/with-schemas/index.js.gz +0 -0
- package/min/persisters/persister-expo-sqlite/index.js +1 -1
- package/min/persisters/persister-expo-sqlite/index.js.gz +0 -0
- package/min/persisters/persister-expo-sqlite/with-schemas/index.js +1 -1
- package/min/persisters/persister-expo-sqlite/with-schemas/index.js.gz +0 -0
- package/min/persisters/persister-file/index.js +1 -1
- package/min/persisters/persister-file/index.js.gz +0 -0
- package/min/persisters/persister-file/with-schemas/index.js +1 -1
- package/min/persisters/persister-file/with-schemas/index.js.gz +0 -0
- package/min/persisters/persister-indexed-db/index.js +1 -1
- package/min/persisters/persister-indexed-db/index.js.gz +0 -0
- package/min/persisters/persister-indexed-db/with-schemas/index.js +1 -1
- package/min/persisters/persister-indexed-db/with-schemas/index.js.gz +0 -0
- package/min/persisters/persister-libsql/index.js +1 -1
- package/min/persisters/persister-libsql/index.js.gz +0 -0
- package/min/persisters/persister-libsql/with-schemas/index.js +1 -1
- package/min/persisters/persister-libsql/with-schemas/index.js.gz +0 -0
- package/min/persisters/persister-partykit-client/index.js +1 -1
- package/min/persisters/persister-partykit-client/index.js.gz +0 -0
- package/min/persisters/persister-partykit-client/with-schemas/index.js +1 -1
- package/min/persisters/persister-partykit-client/with-schemas/index.js.gz +0 -0
- package/min/persisters/persister-pglite/index.js +1 -1
- package/min/persisters/persister-pglite/index.js.gz +0 -0
- package/min/persisters/persister-pglite/with-schemas/index.js +1 -1
- package/min/persisters/persister-pglite/with-schemas/index.js.gz +0 -0
- package/min/persisters/persister-postgres/index.js +1 -1
- package/min/persisters/persister-postgres/index.js.gz +0 -0
- package/min/persisters/persister-postgres/with-schemas/index.js +1 -1
- package/min/persisters/persister-postgres/with-schemas/index.js.gz +0 -0
- package/min/persisters/persister-powersync/index.js +1 -1
- package/min/persisters/persister-powersync/index.js.gz +0 -0
- package/min/persisters/persister-powersync/with-schemas/index.js +1 -1
- package/min/persisters/persister-powersync/with-schemas/index.js.gz +0 -0
- package/min/persisters/persister-remote/index.js +1 -1
- package/min/persisters/persister-remote/index.js.gz +0 -0
- package/min/persisters/persister-remote/with-schemas/index.js +1 -1
- package/min/persisters/persister-remote/with-schemas/index.js.gz +0 -0
- package/min/persisters/persister-sqlite-bun/index.js +1 -1
- package/min/persisters/persister-sqlite-bun/index.js.gz +0 -0
- package/min/persisters/persister-sqlite-bun/with-schemas/index.js +1 -1
- package/min/persisters/persister-sqlite-bun/with-schemas/index.js.gz +0 -0
- package/min/persisters/persister-sqlite-wasm/index.js +1 -1
- package/min/persisters/persister-sqlite-wasm/index.js.gz +0 -0
- package/min/persisters/persister-sqlite-wasm/with-schemas/index.js +1 -1
- package/min/persisters/persister-sqlite-wasm/with-schemas/index.js.gz +0 -0
- package/min/persisters/persister-sqlite3/index.js +1 -1
- package/min/persisters/persister-sqlite3/index.js.gz +0 -0
- package/min/persisters/persister-sqlite3/with-schemas/index.js +1 -1
- package/min/persisters/persister-sqlite3/with-schemas/index.js.gz +0 -0
- package/min/persisters/persister-yjs/index.js +1 -1
- package/min/persisters/persister-yjs/index.js.gz +0 -0
- package/min/persisters/persister-yjs/with-schemas/index.js +1 -1
- package/min/persisters/persister-yjs/with-schemas/index.js.gz +0 -0
- package/min/persisters/with-schemas/index.js +1 -1
- package/min/persisters/with-schemas/index.js.gz +0 -0
- package/min/store/index.js +1 -1
- package/min/store/index.js.gz +0 -0
- package/min/store/with-schemas/index.js +1 -1
- package/min/store/with-schemas/index.js.gz +0 -0
- package/min/synchronizers/index.js +1 -1
- package/min/synchronizers/index.js.gz +0 -0
- package/min/synchronizers/synchronizer-broadcast-channel/index.js +1 -1
- package/min/synchronizers/synchronizer-broadcast-channel/index.js.gz +0 -0
- package/min/synchronizers/synchronizer-broadcast-channel/with-schemas/index.js +1 -1
- package/min/synchronizers/synchronizer-broadcast-channel/with-schemas/index.js.gz +0 -0
- package/min/synchronizers/synchronizer-local/index.js +1 -1
- package/min/synchronizers/synchronizer-local/index.js.gz +0 -0
- package/min/synchronizers/synchronizer-local/with-schemas/index.js +1 -1
- package/min/synchronizers/synchronizer-local/with-schemas/index.js.gz +0 -0
- package/min/synchronizers/synchronizer-ws-client/index.js +1 -1
- package/min/synchronizers/synchronizer-ws-client/index.js.gz +0 -0
- package/min/synchronizers/synchronizer-ws-client/with-schemas/index.js +1 -1
- package/min/synchronizers/synchronizer-ws-client/with-schemas/index.js.gz +0 -0
- package/min/synchronizers/synchronizer-ws-server/index.js +1 -1
- package/min/synchronizers/synchronizer-ws-server/index.js.gz +0 -0
- package/min/synchronizers/synchronizer-ws-server/with-schemas/index.js +1 -1
- package/min/synchronizers/synchronizer-ws-server/with-schemas/index.js.gz +0 -0
- package/min/synchronizers/synchronizer-ws-server-durable-object/index.js +1 -1
- package/min/synchronizers/synchronizer-ws-server-durable-object/index.js.gz +0 -0
- package/min/synchronizers/synchronizer-ws-server-durable-object/with-schemas/index.js +1 -1
- package/min/synchronizers/synchronizer-ws-server-durable-object/with-schemas/index.js.gz +0 -0
- package/min/synchronizers/synchronizer-ws-server-simple/index.js +1 -1
- package/min/synchronizers/synchronizer-ws-server-simple/index.js.gz +0 -0
- package/min/synchronizers/synchronizer-ws-server-simple/with-schemas/index.js +1 -1
- package/min/synchronizers/synchronizer-ws-server-simple/with-schemas/index.js.gz +0 -0
- package/min/synchronizers/with-schemas/index.js +1 -1
- package/min/synchronizers/with-schemas/index.js.gz +0 -0
- package/min/ui-react-inspector/index.js +1 -1
- package/min/ui-react-inspector/index.js.gz +0 -0
- package/min/ui-react-inspector/with-schemas/index.js +1 -1
- package/min/ui-react-inspector/with-schemas/index.js.gz +0 -0
- package/min/with-schemas/index.js +1 -1
- package/min/with-schemas/index.js.gz +0 -0
- package/package.json +8 -4
- package/persisters/index.js +293 -161
- package/persisters/persister-automerge/index.js +55 -50
- package/persisters/persister-automerge/with-schemas/index.js +55 -50
- package/persisters/persister-browser/index.js +56 -55
- package/persisters/persister-browser/with-schemas/index.js +56 -55
- package/persisters/persister-cr-sqlite-wasm/index.js +181 -134
- package/persisters/persister-cr-sqlite-wasm/with-schemas/index.js +181 -134
- package/persisters/persister-durable-object-storage/index.js +58 -53
- package/persisters/persister-durable-object-storage/with-schemas/index.js +58 -53
- package/persisters/persister-electric-sql/index.js +181 -134
- package/persisters/persister-electric-sql/with-schemas/index.js +181 -134
- package/persisters/persister-expo-sqlite/index.js +181 -134
- package/persisters/persister-expo-sqlite/with-schemas/index.js +181 -134
- package/persisters/persister-file/index.js +55 -50
- package/persisters/persister-file/with-schemas/index.js +55 -50
- package/persisters/persister-indexed-db/index.js +82 -78
- package/persisters/persister-indexed-db/with-schemas/index.js +82 -78
- package/persisters/persister-libsql/index.js +182 -135
- package/persisters/persister-libsql/with-schemas/index.js +182 -135
- package/persisters/persister-partykit-client/index.js +56 -51
- package/persisters/persister-partykit-client/with-schemas/index.js +56 -51
- package/persisters/persister-pglite/index.js +299 -173
- package/persisters/persister-pglite/with-schemas/index.js +299 -173
- package/persisters/persister-postgres/index.js +296 -171
- package/persisters/persister-postgres/with-schemas/index.js +296 -171
- package/persisters/persister-powersync/index.js +189 -138
- package/persisters/persister-powersync/with-schemas/index.js +189 -138
- package/persisters/persister-remote/index.js +55 -50
- package/persisters/persister-remote/with-schemas/index.js +55 -50
- package/persisters/persister-sqlite-bun/index.js +182 -135
- package/persisters/persister-sqlite-bun/with-schemas/index.js +182 -135
- package/persisters/persister-sqlite-wasm/index.js +182 -135
- package/persisters/persister-sqlite-wasm/with-schemas/index.js +182 -135
- package/persisters/persister-sqlite3/index.js +181 -134
- package/persisters/persister-sqlite3/with-schemas/index.js +181 -134
- package/persisters/persister-yjs/index.js +55 -50
- package/persisters/persister-yjs/with-schemas/index.js +55 -50
- package/persisters/with-schemas/index.js +293 -161
- package/readme.md +2 -2
- package/releases.md +29 -1
- package/store/index.js +20 -15
- package/store/with-schemas/index.js +20 -15
- package/synchronizers/index.js +68 -63
- package/synchronizers/synchronizer-broadcast-channel/index.js +68 -63
- package/synchronizers/synchronizer-broadcast-channel/with-schemas/index.js +68 -63
- package/synchronizers/synchronizer-local/index.js +68 -63
- package/synchronizers/synchronizer-local/with-schemas/index.js +68 -63
- package/synchronizers/synchronizer-ws-client/index.js +68 -63
- package/synchronizers/synchronizer-ws-client/with-schemas/index.js +68 -63
- package/synchronizers/synchronizer-ws-server/index.js +79 -70
- package/synchronizers/synchronizer-ws-server/with-schemas/index.js +79 -70
- package/synchronizers/synchronizer-ws-server-durable-object/index.js +69 -51
- package/synchronizers/synchronizer-ws-server-durable-object/with-schemas/index.js +69 -51
- package/synchronizers/synchronizer-ws-server-simple/index.js +1 -1
- package/synchronizers/synchronizer-ws-server-simple/with-schemas/index.js +1 -1
- package/synchronizers/with-schemas/index.js +68 -63
- package/ui-react-inspector/index.js +68 -60
- package/ui-react-inspector/with-schemas/index.js +68 -60
- package/with-schemas/index.js +23 -17
|
@@ -3,10 +3,14 @@ const TINYBASE = 'tinybase';
|
|
|
3
3
|
const EMPTY_STRING = '';
|
|
4
4
|
const COMMA = ',';
|
|
5
5
|
const STRING = getTypeOf(EMPTY_STRING);
|
|
6
|
+
const TRUE = 'true';
|
|
6
7
|
const UNDEFINED = '\uFFFC';
|
|
7
8
|
const strMatch = (str, regex) => str?.match(regex);
|
|
9
|
+
const strReplace = (str, searchValue, replaceValue) =>
|
|
10
|
+
str.replace(searchValue, replaceValue);
|
|
8
11
|
|
|
9
12
|
const promise = Promise;
|
|
13
|
+
const GLOBAL = globalThis;
|
|
10
14
|
const isUndefined = (thing) => thing == void 0;
|
|
11
15
|
const ifNotUndefined = (value, then, otherwise) =>
|
|
12
16
|
isUndefined(value) ? otherwise?.() : then(value);
|
|
@@ -15,10 +19,19 @@ const isArray = (thing) => Array.isArray(thing);
|
|
|
15
19
|
const slice = (arrayOrString, start, end) => arrayOrString.slice(start, end);
|
|
16
20
|
const size = (arrayOrString) => arrayOrString.length;
|
|
17
21
|
const test = (regex, subject) => regex.test(subject);
|
|
22
|
+
const noop = () => {};
|
|
18
23
|
const promiseAll = async (promises) => promise.all(promises);
|
|
19
24
|
const errorNew = (message) => {
|
|
20
25
|
throw new Error(message);
|
|
21
26
|
};
|
|
27
|
+
const tryCatch = async (action, then1, then2) => {
|
|
28
|
+
try {
|
|
29
|
+
return await action();
|
|
30
|
+
} catch (error) {
|
|
31
|
+
/* istanbul ignore next */
|
|
32
|
+
then1?.(error);
|
|
33
|
+
}
|
|
34
|
+
};
|
|
22
35
|
|
|
23
36
|
const arrayForEach = (array, cb) => array.forEach(cb);
|
|
24
37
|
const arrayJoin = (array, sep = EMPTY_STRING) => array.join(sep);
|
|
@@ -37,6 +50,17 @@ const collClear = (coll) => coll.clear();
|
|
|
37
50
|
const collForEach = (coll, cb) => coll?.forEach(cb);
|
|
38
51
|
const collDel = (coll, keyOrValue) => coll?.delete(keyOrValue);
|
|
39
52
|
|
|
53
|
+
const textEncoder = /* @__PURE__ */ new GLOBAL.TextEncoder();
|
|
54
|
+
const getHash = (value) => {
|
|
55
|
+
let hash = 2166136261;
|
|
56
|
+
arrayForEach(textEncoder.encode(value), (char) => {
|
|
57
|
+
hash ^= char;
|
|
58
|
+
hash +=
|
|
59
|
+
(hash << 1) + (hash << 4) + (hash << 7) + (hash << 8) + (hash << 24);
|
|
60
|
+
});
|
|
61
|
+
return hash >>> 0;
|
|
62
|
+
};
|
|
63
|
+
|
|
40
64
|
const object = Object;
|
|
41
65
|
const getPrototypeOf = (obj) => object.getPrototypeOf(obj);
|
|
42
66
|
const objEntries = object.entries;
|
|
@@ -75,32 +99,10 @@ const jsonStringWithUndefined = (obj) =>
|
|
|
75
99
|
const jsonParseWithUndefined = (str) =>
|
|
76
100
|
jsonParse(str, (_key, value) => (value === UNDEFINED ? void 0 : value));
|
|
77
101
|
|
|
78
|
-
const SINGLE_ROW_ID = '_';
|
|
79
|
-
const DEFAULT_ROW_ID_COLUMN_NAME = '_id';
|
|
80
|
-
const SELECT = 'SELECT';
|
|
81
|
-
const WHERE = 'WHERE';
|
|
82
|
-
const TABLE = 'TABLE';
|
|
83
|
-
const ALTER_TABLE = 'ALTER ' + TABLE;
|
|
84
|
-
const DELETE_FROM = 'DELETE FROM';
|
|
85
|
-
const SELECT_STAR_FROM = SELECT + '*FROM';
|
|
86
|
-
const getWrappedCommand = (executeCommand, onSqlCommand) =>
|
|
87
|
-
onSqlCommand
|
|
88
|
-
? async (sql, params) => {
|
|
89
|
-
onSqlCommand(sql, params);
|
|
90
|
-
return await executeCommand(sql, params);
|
|
91
|
-
}
|
|
92
|
-
: executeCommand;
|
|
93
|
-
const escapeId = (str) => `"${str.replace(/"/g, '""')}"`;
|
|
94
|
-
const escapeColumnNames = (...columnNames) =>
|
|
95
|
-
arrayJoin(arrayMap(columnNames, escapeId), COMMA);
|
|
96
|
-
const getPlaceholders = (array, offset = [1]) =>
|
|
97
|
-
arrayJoin(
|
|
98
|
-
arrayMap(array, () => '$' + offset[0]++),
|
|
99
|
-
COMMA,
|
|
100
|
-
);
|
|
101
|
-
|
|
102
102
|
const mapNew = (entries) => new Map(entries);
|
|
103
103
|
const mapGet = (map, key) => map?.get(key);
|
|
104
|
+
const mapForEach = (map, cb) =>
|
|
105
|
+
collForEach(map, (value, key) => cb(key, value));
|
|
104
106
|
const mapMap = (coll, cb) =>
|
|
105
107
|
arrayMap([...(coll?.entries() ?? [])], ([key, value]) => cb(value, key));
|
|
106
108
|
const mapSet = (map, key, value) =>
|
|
@@ -135,6 +137,43 @@ const visitTree = (node, path, ensureLeaf, pruneLeaf, p = 0) =>
|
|
|
135
137
|
},
|
|
136
138
|
);
|
|
137
139
|
|
|
140
|
+
const SINGLE_ROW_ID = '_';
|
|
141
|
+
const DEFAULT_ROW_ID_COLUMN_NAME = '_id';
|
|
142
|
+
const SELECT = 'SELECT';
|
|
143
|
+
const WHERE = 'WHERE';
|
|
144
|
+
const TABLE = 'TABLE';
|
|
145
|
+
const INSERT = 'INSERT';
|
|
146
|
+
const DELETE = 'DELETE';
|
|
147
|
+
const UPDATE = 'UPDATE';
|
|
148
|
+
const ALTER_TABLE = 'ALTER ' + TABLE;
|
|
149
|
+
const FROM = 'FROM';
|
|
150
|
+
const DELETE_FROM = DELETE + ' ' + FROM;
|
|
151
|
+
const SELECT_STAR_FROM = SELECT + '*' + FROM;
|
|
152
|
+
const CREATE = 'CREATE ';
|
|
153
|
+
const CREATE_TABLE = CREATE + TABLE;
|
|
154
|
+
const OR_REPLACE = 'OR REPLACE ';
|
|
155
|
+
const FUNCTION = 'FUNCTION';
|
|
156
|
+
const TABLE_NAME_PLACEHOLDER = '$tableName';
|
|
157
|
+
const getWrappedCommand = (executeCommand, onSqlCommand) =>
|
|
158
|
+
onSqlCommand
|
|
159
|
+
? async (sql, params) => {
|
|
160
|
+
onSqlCommand(sql, params);
|
|
161
|
+
return await executeCommand(sql, params);
|
|
162
|
+
}
|
|
163
|
+
: executeCommand;
|
|
164
|
+
const escapeId = (str) => `"${strReplace(str, /"/g, '""')}"`;
|
|
165
|
+
const escapeIds = (...ids) => escapeId(arrayJoin(ids, '_'));
|
|
166
|
+
const escapeColumnNames = (...columnNames) =>
|
|
167
|
+
arrayJoin(arrayMap(columnNames, escapeId), COMMA);
|
|
168
|
+
const getPlaceholders = (array, offset = [1]) =>
|
|
169
|
+
arrayJoin(
|
|
170
|
+
arrayMap(array, () => '$' + offset[0]++),
|
|
171
|
+
COMMA,
|
|
172
|
+
);
|
|
173
|
+
const getWhereCondition = (tableName, condition = TRUE) =>
|
|
174
|
+
WHERE +
|
|
175
|
+
`(${strReplace(condition, TABLE_NAME_PLACEHOLDER, escapeId(tableName))})`;
|
|
176
|
+
|
|
138
177
|
const setNew = (entryOrEntries) =>
|
|
139
178
|
new Set(
|
|
140
179
|
isArray(entryOrEntries) || isUndefined(entryOrEntries)
|
|
@@ -155,6 +194,7 @@ const TABLE_ID = 'tableId';
|
|
|
155
194
|
const TABLE_NAME = 'tableName';
|
|
156
195
|
const DELETE_EMPTY_COLUMNS = 'deleteEmptyColumns';
|
|
157
196
|
const DELETE_EMPTY_TABLE = 'deleteEmptyTable';
|
|
197
|
+
const CONDITION = 'condition';
|
|
158
198
|
const DEFAULT_CONFIG = {
|
|
159
199
|
mode: JSON$1,
|
|
160
200
|
[AUTO_LOAD_INTERVAL_SECONDS]: 1,
|
|
@@ -222,29 +262,42 @@ const getConfigStructures = (configOrStoreTableName) => {
|
|
|
222
262
|
const valuesTable = valuesConfig[2];
|
|
223
263
|
const managedTableNames = setNew(valuesTable);
|
|
224
264
|
const excludedTableNames = setNew(valuesTable);
|
|
225
|
-
const
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
265
|
+
const tablesLoadConfig = getDefaultedTabularConfigMap(
|
|
266
|
+
load,
|
|
267
|
+
{
|
|
268
|
+
[TABLE_ID]: null,
|
|
269
|
+
[ROW_ID_COLUMN_NAME]: DEFAULT_ROW_ID_COLUMN_NAME,
|
|
270
|
+
[CONDITION]: TRUE,
|
|
271
|
+
},
|
|
272
|
+
TABLE_ID,
|
|
273
|
+
(tableName) => collHas(excludedTableNames, tableName),
|
|
274
|
+
(tableName) => setAdd(managedTableNames, tableName),
|
|
275
|
+
);
|
|
276
|
+
const tablesSaveConfig = getDefaultedTabularConfigMap(
|
|
277
|
+
save,
|
|
278
|
+
{
|
|
279
|
+
[TABLE_NAME]: null,
|
|
280
|
+
[ROW_ID_COLUMN_NAME]: DEFAULT_ROW_ID_COLUMN_NAME,
|
|
281
|
+
[DELETE_EMPTY_COLUMNS]: 0,
|
|
282
|
+
[DELETE_EMPTY_TABLE]: 0,
|
|
283
|
+
[CONDITION]: null,
|
|
284
|
+
},
|
|
285
|
+
TABLE_NAME,
|
|
286
|
+
(_, tableName) => collHas(excludedTableNames, tableName),
|
|
287
|
+
(_, tableName) => setAdd(managedTableNames, tableName),
|
|
288
|
+
);
|
|
289
|
+
mapForEach(
|
|
290
|
+
tablesSaveConfig,
|
|
291
|
+
(_, tableSaveConfig) =>
|
|
292
|
+
(tableSaveConfig[4] ??=
|
|
293
|
+
mapGet(tablesLoadConfig, tableSaveConfig[0])?.[2] ?? TRUE),
|
|
294
|
+
);
|
|
295
|
+
return [
|
|
296
|
+
0,
|
|
297
|
+
autoLoadIntervalSeconds,
|
|
298
|
+
[tablesLoadConfig, tablesSaveConfig, valuesConfig],
|
|
299
|
+
managedTableNames,
|
|
246
300
|
];
|
|
247
|
-
return [0, autoLoadIntervalSeconds, tabularConfig, managedTableNames];
|
|
248
301
|
};
|
|
249
302
|
|
|
250
303
|
const INTEGER = /^\d+$/;
|
|
@@ -403,12 +456,7 @@ const createCustomPersister = (
|
|
|
403
456
|
while (
|
|
404
457
|
!isUndefined((action = arrayShift(mapGet(scheduleActions, scheduleId))))
|
|
405
458
|
) {
|
|
406
|
-
|
|
407
|
-
await action();
|
|
408
|
-
} catch (error) {
|
|
409
|
-
/* istanbul ignore next */
|
|
410
|
-
onIgnoredError?.(error);
|
|
411
|
-
}
|
|
459
|
+
await tryCatch(action, onIgnoredError);
|
|
412
460
|
}
|
|
413
461
|
mapSet(scheduleRunning, scheduleId, 0);
|
|
414
462
|
}
|
|
@@ -428,21 +476,23 @@ const createCustomPersister = (
|
|
|
428
476
|
setStatus(1 /* Loading */);
|
|
429
477
|
loads++;
|
|
430
478
|
await schedule(async () => {
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
479
|
+
await tryCatch(
|
|
480
|
+
async () => {
|
|
481
|
+
const content = await getPersisted();
|
|
482
|
+
if (isArray(content)) {
|
|
483
|
+
setContentOrChanges(content);
|
|
484
|
+
} else if (initialContent) {
|
|
485
|
+
setDefaultContent(initialContent);
|
|
486
|
+
} else {
|
|
487
|
+
errorNew(`Content is not an array: ${content}`);
|
|
488
|
+
}
|
|
489
|
+
},
|
|
490
|
+
() => {
|
|
491
|
+
if (initialContent) {
|
|
492
|
+
setDefaultContent(initialContent);
|
|
493
|
+
}
|
|
494
|
+
},
|
|
495
|
+
);
|
|
446
496
|
setStatus(0 /* Idle */);
|
|
447
497
|
});
|
|
448
498
|
}
|
|
@@ -451,29 +501,33 @@ const createCustomPersister = (
|
|
|
451
501
|
const startAutoLoad = async (initialContent) => {
|
|
452
502
|
stopAutoLoad();
|
|
453
503
|
await load(initialContent);
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
504
|
+
await tryCatch(
|
|
505
|
+
async () =>
|
|
506
|
+
(autoLoadHandle = await addPersisterListener(
|
|
507
|
+
async (content, changes) => {
|
|
508
|
+
if (changes || content) {
|
|
509
|
+
/* istanbul ignore else */
|
|
510
|
+
if (status != 2 /* Saving */) {
|
|
511
|
+
setStatus(1 /* Loading */);
|
|
512
|
+
loads++;
|
|
513
|
+
setContentOrChanges(changes ?? content);
|
|
514
|
+
setStatus(0 /* Idle */);
|
|
515
|
+
}
|
|
516
|
+
} else {
|
|
517
|
+
await load();
|
|
518
|
+
}
|
|
519
|
+
},
|
|
520
|
+
)),
|
|
521
|
+
onIgnoredError,
|
|
522
|
+
);
|
|
472
523
|
return persister;
|
|
473
524
|
};
|
|
474
|
-
const stopAutoLoad = () => {
|
|
525
|
+
const stopAutoLoad = async () => {
|
|
475
526
|
if (autoLoadHandle) {
|
|
476
|
-
|
|
527
|
+
await tryCatch(
|
|
528
|
+
() => delPersisterListener(autoLoadHandle),
|
|
529
|
+
onIgnoredError,
|
|
530
|
+
);
|
|
477
531
|
autoLoadHandle = void 0;
|
|
478
532
|
}
|
|
479
533
|
return persister;
|
|
@@ -485,12 +539,7 @@ const createCustomPersister = (
|
|
|
485
539
|
setStatus(2 /* Saving */);
|
|
486
540
|
saves++;
|
|
487
541
|
await schedule(async () => {
|
|
488
|
-
|
|
489
|
-
await setPersisted(getContent, changes);
|
|
490
|
-
} catch (error) {
|
|
491
|
-
/* istanbul ignore next */
|
|
492
|
-
onIgnoredError?.(error);
|
|
493
|
-
}
|
|
542
|
+
await tryCatch(() => setPersisted(getContent, changes), onIgnoredError);
|
|
494
543
|
setStatus(0 /* Idle */);
|
|
495
544
|
});
|
|
496
545
|
}
|
|
@@ -507,7 +556,7 @@ const createCustomPersister = (
|
|
|
507
556
|
});
|
|
508
557
|
return persister;
|
|
509
558
|
};
|
|
510
|
-
const stopAutoSave = () => {
|
|
559
|
+
const stopAutoSave = async () => {
|
|
511
560
|
if (autoSaveListenerId) {
|
|
512
561
|
store.delListener(autoSaveListenerId);
|
|
513
562
|
autoSaveListenerId = void 0;
|
|
@@ -528,9 +577,10 @@ const createCustomPersister = (
|
|
|
528
577
|
return persister;
|
|
529
578
|
};
|
|
530
579
|
const getStore = () => store;
|
|
531
|
-
const destroy = () => {
|
|
580
|
+
const destroy = async () => {
|
|
532
581
|
arrayClear(mapGet(scheduleActions, scheduleId));
|
|
533
|
-
|
|
582
|
+
await persister.stopAutoLoad();
|
|
583
|
+
return await persister.stopAutoSave();
|
|
534
584
|
};
|
|
535
585
|
const getStats = () => ({loads, saves});
|
|
536
586
|
const persister = {
|
|
@@ -574,13 +624,15 @@ const getCommandFunctions = (
|
|
|
574
624
|
({tn, cn}) => setAdd(mapEnsure(schemaMap, tn, setNew), cn),
|
|
575
625
|
);
|
|
576
626
|
};
|
|
577
|
-
const loadTable = async (tableName, rowIdColumnName) =>
|
|
627
|
+
const loadTable = async (tableName, rowIdColumnName, condition) =>
|
|
578
628
|
canSelect(tableName, rowIdColumnName)
|
|
579
629
|
? objNew(
|
|
580
630
|
arrayFilter(
|
|
581
631
|
arrayMap(
|
|
582
632
|
await databaseExecuteCommand(
|
|
583
|
-
SELECT_STAR_FROM +
|
|
633
|
+
SELECT_STAR_FROM +
|
|
634
|
+
escapeId(tableName) +
|
|
635
|
+
getWhereCondition(tableName, condition),
|
|
584
636
|
),
|
|
585
637
|
(row) => [
|
|
586
638
|
row[rowIdColumnName],
|
|
@@ -600,6 +652,7 @@ const getCommandFunctions = (
|
|
|
600
652
|
deleteEmptyColumns,
|
|
601
653
|
deleteEmptyTable,
|
|
602
654
|
partial = false,
|
|
655
|
+
condition = TRUE,
|
|
603
656
|
) => {
|
|
604
657
|
const settingColumnNameSet = setNew();
|
|
605
658
|
objMap(content ?? {}, (contentRow) =>
|
|
@@ -611,6 +664,7 @@ const getCommandFunctions = (
|
|
|
611
664
|
if (
|
|
612
665
|
!partial &&
|
|
613
666
|
deleteEmptyTable &&
|
|
667
|
+
condition == TRUE &&
|
|
614
668
|
arrayIsEmpty(settingColumnNames) &&
|
|
615
669
|
collHas(schemaMap, tableName)
|
|
616
670
|
) {
|
|
@@ -623,8 +677,7 @@ const getCommandFunctions = (
|
|
|
623
677
|
if (!arrayIsEmpty(settingColumnNames)) {
|
|
624
678
|
if (!collHas(schemaMap, tableName)) {
|
|
625
679
|
await databaseExecuteCommand(
|
|
626
|
-
|
|
627
|
-
TABLE +
|
|
680
|
+
CREATE_TABLE +
|
|
628
681
|
escapeId(tableName) +
|
|
629
682
|
`(${escapeId(rowIdColumnName)}${columnType} PRIMARY KEY${arrayJoin(
|
|
630
683
|
arrayMap(
|
|
@@ -687,7 +740,9 @@ const getCommandFunctions = (
|
|
|
687
740
|
if (partial) {
|
|
688
741
|
if (isUndefined(content)) {
|
|
689
742
|
await databaseExecuteCommand(
|
|
690
|
-
DELETE_FROM +
|
|
743
|
+
DELETE_FROM +
|
|
744
|
+
escapeId(tableName) +
|
|
745
|
+
getWhereCondition(tableName, condition),
|
|
691
746
|
);
|
|
692
747
|
} else {
|
|
693
748
|
await promiseAll(
|
|
@@ -696,9 +751,8 @@ const getCommandFunctions = (
|
|
|
696
751
|
await databaseExecuteCommand(
|
|
697
752
|
DELETE_FROM +
|
|
698
753
|
escapeId(tableName) +
|
|
699
|
-
|
|
700
|
-
escapeId(rowIdColumnName)
|
|
701
|
-
'=$1',
|
|
754
|
+
getWhereCondition(tableName, condition) +
|
|
755
|
+
`AND(${escapeId(rowIdColumnName)}=$1)`,
|
|
702
756
|
[rowId],
|
|
703
757
|
);
|
|
704
758
|
} else if (!arrayIsEmpty(settingColumnNames)) {
|
|
@@ -742,14 +796,15 @@ const getCommandFunctions = (
|
|
|
742
796
|
await databaseExecuteCommand(
|
|
743
797
|
DELETE_FROM +
|
|
744
798
|
escapeId(tableName) +
|
|
745
|
-
|
|
746
|
-
escapeId(rowIdColumnName)
|
|
747
|
-
`NOT IN(${getPlaceholders(deleteRowIds)})`,
|
|
799
|
+
getWhereCondition(tableName, condition) + // eslint-disable-next-line max-len
|
|
800
|
+
`AND${escapeId(rowIdColumnName)}NOT IN(${getPlaceholders(deleteRowIds)})`,
|
|
748
801
|
deleteRowIds,
|
|
749
802
|
);
|
|
750
803
|
} else if (collHas(schemaMap, tableName)) {
|
|
751
804
|
await databaseExecuteCommand(
|
|
752
|
-
DELETE_FROM +
|
|
805
|
+
DELETE_FROM +
|
|
806
|
+
escapeId(tableName) +
|
|
807
|
+
getWhereCondition(tableName, condition),
|
|
753
808
|
);
|
|
754
809
|
}
|
|
755
810
|
}
|
|
@@ -757,11 +812,7 @@ const getCommandFunctions = (
|
|
|
757
812
|
const transaction = async (actions) => {
|
|
758
813
|
let result;
|
|
759
814
|
await databaseExecuteCommand('BEGIN');
|
|
760
|
-
|
|
761
|
-
result = await actions();
|
|
762
|
-
} catch (error) {
|
|
763
|
-
onIgnoredError?.(error);
|
|
764
|
-
}
|
|
815
|
+
await tryCatch(async () => (result = await actions()), onIgnoredError);
|
|
765
816
|
await databaseExecuteCommand('END');
|
|
766
817
|
return result;
|
|
767
818
|
};
|
|
@@ -776,7 +827,8 @@ const defaultUpsert = async (
|
|
|
776
827
|
) => {
|
|
777
828
|
const offset = [1];
|
|
778
829
|
await executeCommand(
|
|
779
|
-
|
|
830
|
+
INSERT +
|
|
831
|
+
' INTO' +
|
|
780
832
|
escapeId(tableName) +
|
|
781
833
|
'(' +
|
|
782
834
|
escapeColumnNames(rowIdColumnName, ...changingColumnNames) +
|
|
@@ -791,7 +843,7 @@ const defaultUpsert = async (
|
|
|
791
843
|
) +
|
|
792
844
|
'ON CONFLICT(' +
|
|
793
845
|
escapeId(rowIdColumnName) +
|
|
794
|
-
|
|
846
|
+
`)DO ${UPDATE} SET` +
|
|
795
847
|
arrayJoin(
|
|
796
848
|
arrayMap(
|
|
797
849
|
changingColumnNames,
|
|
@@ -813,7 +865,7 @@ const createJsonPersister = (
|
|
|
813
865
|
addPersisterListener,
|
|
814
866
|
delPersisterListener,
|
|
815
867
|
onIgnoredError,
|
|
816
|
-
|
|
868
|
+
extraDestroy,
|
|
817
869
|
persist,
|
|
818
870
|
[storeTableName, storeIdColumnName, storeColumnName],
|
|
819
871
|
managedTableNames,
|
|
@@ -832,8 +884,8 @@ const createJsonPersister = (
|
|
|
832
884
|
columnType,
|
|
833
885
|
upsert,
|
|
834
886
|
);
|
|
835
|
-
const getPersisted =
|
|
836
|
-
|
|
887
|
+
const getPersisted = () =>
|
|
888
|
+
transaction(async () => {
|
|
837
889
|
await refreshSchema();
|
|
838
890
|
return jsonParseWithUndefined(
|
|
839
891
|
(await loadTable(storeTableName, storeIdColumnName))[SINGLE_ROW_ID]?.[
|
|
@@ -841,8 +893,8 @@ const createJsonPersister = (
|
|
|
841
893
|
] ?? 'null',
|
|
842
894
|
);
|
|
843
895
|
});
|
|
844
|
-
const setPersisted =
|
|
845
|
-
|
|
896
|
+
const setPersisted = (getContent) =>
|
|
897
|
+
transaction(async () => {
|
|
846
898
|
await refreshSchema();
|
|
847
899
|
await saveTable(
|
|
848
900
|
storeTableName,
|
|
@@ -856,9 +908,10 @@ const createJsonPersister = (
|
|
|
856
908
|
true,
|
|
857
909
|
);
|
|
858
910
|
});
|
|
859
|
-
const destroy = () => {
|
|
860
|
-
persister.stopAutoLoad()
|
|
861
|
-
|
|
911
|
+
const destroy = async () => {
|
|
912
|
+
await persister.stopAutoLoad();
|
|
913
|
+
await persister.stopAutoSave();
|
|
914
|
+
extraDestroy();
|
|
862
915
|
return persister;
|
|
863
916
|
};
|
|
864
917
|
const persister = createCustomPersister(
|
|
@@ -882,7 +935,7 @@ const createTabularPersister = (
|
|
|
882
935
|
addPersisterListener,
|
|
883
936
|
delPersisterListener,
|
|
884
937
|
onIgnoredError,
|
|
885
|
-
|
|
938
|
+
extraDestroy,
|
|
886
939
|
persist,
|
|
887
940
|
[
|
|
888
941
|
tablesLoadConfig,
|
|
@@ -909,12 +962,18 @@ const createTabularPersister = (
|
|
|
909
962
|
encode,
|
|
910
963
|
decode,
|
|
911
964
|
);
|
|
912
|
-
const saveTables =
|
|
913
|
-
|
|
965
|
+
const saveTables = (tables, partial) =>
|
|
966
|
+
promiseAll(
|
|
914
967
|
mapMap(
|
|
915
968
|
tablesSaveConfig,
|
|
916
969
|
async (
|
|
917
|
-
[
|
|
970
|
+
[
|
|
971
|
+
tableName,
|
|
972
|
+
rowIdColumnName,
|
|
973
|
+
deleteEmptyColumns,
|
|
974
|
+
deleteEmptyTable,
|
|
975
|
+
condition,
|
|
976
|
+
],
|
|
918
977
|
tableId,
|
|
919
978
|
) => {
|
|
920
979
|
if (!partial || objHas(tables, tableId)) {
|
|
@@ -925,6 +984,7 @@ const createTabularPersister = (
|
|
|
925
984
|
deleteEmptyColumns,
|
|
926
985
|
deleteEmptyTable,
|
|
927
986
|
partial,
|
|
987
|
+
condition,
|
|
928
988
|
);
|
|
929
989
|
}
|
|
930
990
|
},
|
|
@@ -947,9 +1007,9 @@ const createTabularPersister = (
|
|
|
947
1007
|
await promiseAll(
|
|
948
1008
|
mapMap(
|
|
949
1009
|
tablesLoadConfig,
|
|
950
|
-
async ([tableId, rowIdColumnName], tableName) => [
|
|
1010
|
+
async ([tableId, rowIdColumnName, condition], tableName) => [
|
|
951
1011
|
tableId,
|
|
952
|
-
await loadTable(tableName, rowIdColumnName),
|
|
1012
|
+
await loadTable(tableName, rowIdColumnName, condition),
|
|
953
1013
|
],
|
|
954
1014
|
),
|
|
955
1015
|
),
|
|
@@ -962,8 +1022,8 @@ const createTabularPersister = (
|
|
|
962
1022
|
SINGLE_ROW_ID
|
|
963
1023
|
]
|
|
964
1024
|
: {};
|
|
965
|
-
const getPersisted =
|
|
966
|
-
|
|
1025
|
+
const getPersisted = () =>
|
|
1026
|
+
transaction(async () => {
|
|
967
1027
|
await refreshSchema();
|
|
968
1028
|
const tables = await loadTables();
|
|
969
1029
|
const values = await loadValues();
|
|
@@ -971,8 +1031,8 @@ const createTabularPersister = (
|
|
|
971
1031
|
? [tables, values]
|
|
972
1032
|
: void 0;
|
|
973
1033
|
});
|
|
974
|
-
const setPersisted =
|
|
975
|
-
|
|
1034
|
+
const setPersisted = (getContent, changes) =>
|
|
1035
|
+
transaction(async () => {
|
|
976
1036
|
await refreshSchema();
|
|
977
1037
|
if (!isUndefined(changes)) {
|
|
978
1038
|
await saveTables(changes[0], true);
|
|
@@ -983,9 +1043,10 @@ const createTabularPersister = (
|
|
|
983
1043
|
await saveValues(values);
|
|
984
1044
|
}
|
|
985
1045
|
});
|
|
986
|
-
const destroy = () => {
|
|
987
|
-
persister.stopAutoLoad()
|
|
988
|
-
|
|
1046
|
+
const destroy = async () => {
|
|
1047
|
+
await persister.stopAutoLoad();
|
|
1048
|
+
await persister.stopAutoSave();
|
|
1049
|
+
extraDestroy();
|
|
989
1050
|
return persister;
|
|
990
1051
|
};
|
|
991
1052
|
const persister = createCustomPersister(
|
|
@@ -1003,10 +1064,9 @@ const createTabularPersister = (
|
|
|
1003
1064
|
return persister;
|
|
1004
1065
|
};
|
|
1005
1066
|
|
|
1006
|
-
const
|
|
1067
|
+
const TABLE_CREATED = 'c';
|
|
1068
|
+
const DATA_CHANGED = 'd';
|
|
1007
1069
|
const EVENT_REGEX = /^([cd]:)(.+)/;
|
|
1008
|
-
const CHANGE_DATA_TRIGGER = TINYBASE + '_data';
|
|
1009
|
-
const CREATE_TABLE_TRIGGER = TINYBASE + '_table';
|
|
1010
1070
|
const createCustomPostgreSqlPersister = (
|
|
1011
1071
|
store,
|
|
1012
1072
|
configOrStoreTableName,
|
|
@@ -1024,53 +1084,125 @@ const createCustomPostgreSqlPersister = (
|
|
|
1024
1084
|
const [isJson, , defaultedConfig, managedTableNamesSet] = getConfigStructures(
|
|
1025
1085
|
configOrStoreTableName,
|
|
1026
1086
|
);
|
|
1027
|
-
const
|
|
1087
|
+
const configHash =
|
|
1088
|
+
EMPTY_STRING + getHash(jsonStringWithUndefined(defaultedConfig));
|
|
1089
|
+
const channel = TINYBASE + '_' + configHash;
|
|
1090
|
+
const createFunction = async (
|
|
1091
|
+
name,
|
|
1092
|
+
body,
|
|
1093
|
+
returnPrefix = '',
|
|
1094
|
+
declarations = '',
|
|
1095
|
+
) => {
|
|
1096
|
+
const escapedFunctionName = escapeIds(TINYBASE, name, configHash);
|
|
1028
1097
|
await executeCommand(
|
|
1029
|
-
|
|
1030
|
-
|
|
1098
|
+
CREATE +
|
|
1099
|
+
OR_REPLACE +
|
|
1100
|
+
FUNCTION +
|
|
1101
|
+
escapedFunctionName +
|
|
1102
|
+
`()RETURNS ${returnPrefix}trigger AS $$ ${declarations}BEGIN ${body}END;$$ LANGUAGE plpgsql;`,
|
|
1031
1103
|
);
|
|
1104
|
+
return escapedFunctionName;
|
|
1032
1105
|
};
|
|
1033
|
-
const
|
|
1106
|
+
const createTrigger = async (
|
|
1107
|
+
prefix,
|
|
1108
|
+
escapedTriggerName,
|
|
1109
|
+
body,
|
|
1110
|
+
escapedFunctionName,
|
|
1111
|
+
) => {
|
|
1034
1112
|
await executeCommand(
|
|
1035
|
-
|
|
1036
|
-
|
|
1113
|
+
CREATE +
|
|
1114
|
+
prefix +
|
|
1115
|
+
'TRIGGER' +
|
|
1116
|
+
escapedTriggerName +
|
|
1117
|
+
body +
|
|
1118
|
+
'EXECUTE ' +
|
|
1119
|
+
FUNCTION +
|
|
1120
|
+
escapedFunctionName +
|
|
1121
|
+
`()`,
|
|
1037
1122
|
);
|
|
1038
|
-
|
|
1039
|
-
|
|
1040
|
-
|
|
1041
|
-
|
|
1042
|
-
|
|
1043
|
-
|
|
1044
|
-
|
|
1123
|
+
return escapedTriggerName;
|
|
1124
|
+
};
|
|
1125
|
+
const notify = (message) => `PERFORM pg_notify('${channel}',${message});`;
|
|
1126
|
+
const when = (tableName, newOrOldOrBoth) =>
|
|
1127
|
+
isJson
|
|
1128
|
+
? TRUE
|
|
1129
|
+
: newOrOldOrBoth === 2
|
|
1130
|
+
? when(tableName, 0) + ' OR ' + when(tableName, 1)
|
|
1131
|
+
: strReplace(
|
|
1132
|
+
mapGet(defaultedConfig[0], tableName)?.[2] ?? TRUE,
|
|
1133
|
+
TABLE_NAME_PLACEHOLDER,
|
|
1134
|
+
newOrOldOrBoth == 0 ? 'NEW' : 'OLD',
|
|
1135
|
+
);
|
|
1136
|
+
const addDataChangedTriggers = (tableName, dataChangedFunction) =>
|
|
1137
|
+
promiseAll(
|
|
1138
|
+
arrayMap([INSERT, DELETE, UPDATE], (action, newOrOldOrBoth) =>
|
|
1139
|
+
createTrigger(
|
|
1140
|
+
OR_REPLACE,
|
|
1141
|
+
escapeIds(TINYBASE, DATA_CHANGED, configHash, tableName, action),
|
|
1142
|
+
`AFTER ${action} ON${escapeId(tableName)}FOR EACH ROW WHEN(${when(
|
|
1143
|
+
tableName,
|
|
1144
|
+
newOrOldOrBoth,
|
|
1145
|
+
)})`,
|
|
1146
|
+
dataChangedFunction,
|
|
1147
|
+
),
|
|
1148
|
+
),
|
|
1149
|
+
);
|
|
1150
|
+
const addPersisterListener = async (listener) => {
|
|
1151
|
+
const tableCreatedFunctionName = await createFunction(
|
|
1152
|
+
TABLE_CREATED,
|
|
1045
1153
|
// eslint-disable-next-line max-len
|
|
1046
|
-
`
|
|
1154
|
+
`FOR row IN SELECT object_identity FROM pg_event_trigger_ddl_commands()${WHERE} command_tag='${CREATE_TABLE}' LOOP ${notify(`'c:'||SPLIT_PART(row.object_identity,'.',2)`)}END LOOP;`,
|
|
1155
|
+
'event_',
|
|
1156
|
+
'DECLARE row record;',
|
|
1157
|
+
);
|
|
1158
|
+
await createTrigger(
|
|
1159
|
+
'EVENT ',
|
|
1160
|
+
escapeIds(TINYBASE, TABLE_CREATED, configHash),
|
|
1161
|
+
`ON ddl_command_end WHEN TAG IN('${CREATE_TABLE}')`,
|
|
1162
|
+
tableCreatedFunctionName,
|
|
1163
|
+
);
|
|
1164
|
+
const dataChangedFunctionName = await createFunction(
|
|
1165
|
+
DATA_CHANGED,
|
|
1166
|
+
notify(`'d:'||TG_TABLE_NAME`) + `RETURN NULL;`,
|
|
1047
1167
|
);
|
|
1048
1168
|
await promiseAll(
|
|
1049
1169
|
arrayMap(collValues(managedTableNamesSet), async (tableName) => {
|
|
1050
1170
|
await executeCommand(
|
|
1051
|
-
|
|
1052
|
-
|
|
1171
|
+
CREATE_TABLE +
|
|
1172
|
+
` IF NOT EXISTS${escapeId(tableName)}("_id"text PRIMARY KEY)`,
|
|
1053
1173
|
);
|
|
1054
|
-
await
|
|
1174
|
+
return await addDataChangedTriggers(tableName, dataChangedFunctionName);
|
|
1055
1175
|
}),
|
|
1056
1176
|
);
|
|
1057
|
-
|
|
1058
|
-
|
|
1059
|
-
|
|
1060
|
-
|
|
1177
|
+
const listenerHandle = await addChangeListener(
|
|
1178
|
+
channel,
|
|
1179
|
+
(prefixAndTableName) =>
|
|
1180
|
+
ifNotUndefined(
|
|
1061
1181
|
strMatch(prefixAndTableName, EVENT_REGEX),
|
|
1062
1182
|
async ([, eventType, tableName]) => {
|
|
1063
1183
|
if (collHas(managedTableNamesSet, tableName)) {
|
|
1064
1184
|
if (eventType == 'c:') {
|
|
1065
|
-
await
|
|
1185
|
+
await addDataChangedTriggers(
|
|
1186
|
+
tableName,
|
|
1187
|
+
dataChangedFunctionName,
|
|
1188
|
+
);
|
|
1066
1189
|
}
|
|
1067
1190
|
listener();
|
|
1068
1191
|
}
|
|
1069
1192
|
},
|
|
1070
1193
|
),
|
|
1071
1194
|
);
|
|
1195
|
+
return [
|
|
1196
|
+
listenerHandle,
|
|
1197
|
+
[tableCreatedFunctionName, dataChangedFunctionName],
|
|
1198
|
+
];
|
|
1199
|
+
};
|
|
1200
|
+
const delPersisterListener = async ([listenerHandle, functionNames]) => {
|
|
1201
|
+
delChangeListener(listenerHandle);
|
|
1202
|
+
await executeCommand(
|
|
1203
|
+
`DROP FUNCTION IF EXISTS${arrayJoin(functionNames, ',')}CASCADE`,
|
|
1204
|
+
);
|
|
1072
1205
|
};
|
|
1073
|
-
const delPersisterListener = delChangeListener;
|
|
1074
1206
|
return (isJson ? createJsonPersister : createTabularPersister)(
|
|
1075
1207
|
store,
|
|
1076
1208
|
executeCommand,
|
|
@@ -1083,8 +1215,8 @@ const createCustomPostgreSqlPersister = (
|
|
|
1083
1215
|
collValues(managedTableNamesSet),
|
|
1084
1216
|
async (executeCommand2, managedTableNames) =>
|
|
1085
1217
|
await executeCommand2(
|
|
1086
|
-
// eslint-disable-next-line max-len
|
|
1087
|
-
|
|
1218
|
+
SELECT + // eslint-disable-next-line max-len
|
|
1219
|
+
` table_name tn,column_name cn FROM information_schema.columns ${WHERE} table_schema='public'AND table_name IN(${getPlaceholders(managedTableNames)})`,
|
|
1088
1220
|
managedTableNames,
|
|
1089
1221
|
),
|
|
1090
1222
|
thing,
|
|
@@ -1107,17 +1239,11 @@ const createPglitePersister = async (
|
|
|
1107
1239
|
store,
|
|
1108
1240
|
configOrStoreTableName,
|
|
1109
1241
|
async (sql, params = []) => (await pglite.query(sql, params)).rows,
|
|
1110
|
-
|
|
1111
|
-
|
|
1112
|
-
try {
|
|
1113
|
-
await unlisten();
|
|
1114
|
-
} catch (e) {
|
|
1115
|
-
onIgnoredError?.(e);
|
|
1116
|
-
}
|
|
1117
|
-
},
|
|
1242
|
+
(channel, listener) => pglite.listen(channel, listener),
|
|
1243
|
+
(unlisten) => tryCatch(unlisten, onIgnoredError),
|
|
1118
1244
|
onSqlCommand,
|
|
1119
1245
|
onIgnoredError,
|
|
1120
|
-
|
|
1246
|
+
noop,
|
|
1121
1247
|
3,
|
|
1122
1248
|
// StoreOrMergeableStore,
|
|
1123
1249
|
pglite,
|