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