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.
Files changed (233) hide show
  1. package/@types/persisters/index.d.ts +82 -40
  2. package/@types/persisters/persister-automerge/index.d.ts +4 -4
  3. package/@types/persisters/persister-automerge/with-schemas/index.d.ts +4 -4
  4. package/@types/persisters/persister-browser/index.d.ts +4 -4
  5. package/@types/persisters/persister-browser/with-schemas/index.d.ts +4 -4
  6. package/@types/persisters/persister-cr-sqlite-wasm/index.d.ts +3 -3
  7. package/@types/persisters/persister-cr-sqlite-wasm/with-schemas/index.d.ts +3 -3
  8. package/@types/persisters/persister-electric-sql/index.d.ts +3 -3
  9. package/@types/persisters/persister-electric-sql/with-schemas/index.d.ts +3 -3
  10. package/@types/persisters/persister-expo-sqlite/index.d.ts +3 -3
  11. package/@types/persisters/persister-expo-sqlite/with-schemas/index.d.ts +3 -3
  12. package/@types/persisters/persister-file/index.d.ts +2 -2
  13. package/@types/persisters/persister-file/with-schemas/index.d.ts +2 -2
  14. package/@types/persisters/persister-indexed-db/index.d.ts +2 -2
  15. package/@types/persisters/persister-indexed-db/with-schemas/index.d.ts +2 -2
  16. package/@types/persisters/persister-libsql/index.d.ts +3 -3
  17. package/@types/persisters/persister-libsql/with-schemas/index.d.ts +3 -3
  18. package/@types/persisters/persister-partykit-client/index.d.ts +2 -2
  19. package/@types/persisters/persister-partykit-client/with-schemas/index.d.ts +2 -2
  20. package/@types/persisters/persister-pglite/index.d.ts +3 -3
  21. package/@types/persisters/persister-pglite/with-schemas/index.d.ts +3 -3
  22. package/@types/persisters/persister-postgres/index.d.ts +3 -3
  23. package/@types/persisters/persister-postgres/with-schemas/index.d.ts +3 -3
  24. package/@types/persisters/persister-powersync/index.d.ts +3 -3
  25. package/@types/persisters/persister-powersync/with-schemas/index.d.ts +3 -3
  26. package/@types/persisters/persister-remote/index.d.ts +2 -2
  27. package/@types/persisters/persister-remote/with-schemas/index.d.ts +2 -2
  28. package/@types/persisters/persister-sqlite-bun/index.d.ts +3 -3
  29. package/@types/persisters/persister-sqlite-bun/with-schemas/index.d.ts +3 -3
  30. package/@types/persisters/persister-sqlite-wasm/index.d.ts +3 -3
  31. package/@types/persisters/persister-sqlite-wasm/with-schemas/index.d.ts +3 -3
  32. package/@types/persisters/persister-sqlite3/index.d.ts +3 -3
  33. package/@types/persisters/persister-sqlite3/with-schemas/index.d.ts +3 -3
  34. package/@types/persisters/persister-yjs/index.d.ts +4 -4
  35. package/@types/persisters/persister-yjs/with-schemas/index.d.ts +4 -4
  36. package/@types/persisters/with-schemas/index.d.ts +86 -42
  37. package/@types/synchronizers/index.d.ts +18 -16
  38. package/@types/synchronizers/synchronizer-broadcast-channel/index.d.ts +3 -3
  39. package/@types/synchronizers/synchronizer-broadcast-channel/with-schemas/index.d.ts +3 -3
  40. package/@types/synchronizers/synchronizer-local/index.d.ts +2 -2
  41. package/@types/synchronizers/synchronizer-local/with-schemas/index.d.ts +2 -2
  42. package/@types/synchronizers/synchronizer-ws-client/index.d.ts +5 -5
  43. package/@types/synchronizers/synchronizer-ws-client/with-schemas/index.d.ts +5 -5
  44. package/@types/synchronizers/synchronizer-ws-server/index.d.ts +37 -37
  45. package/@types/synchronizers/synchronizer-ws-server/with-schemas/index.d.ts +37 -37
  46. package/@types/synchronizers/synchronizer-ws-server-simple/index.d.ts +7 -7
  47. package/@types/synchronizers/synchronizer-ws-server-simple/with-schemas/index.d.ts +7 -7
  48. package/@types/synchronizers/with-schemas/index.d.ts +18 -16
  49. package/@types/ui-react/index.d.ts +2 -2
  50. package/@types/ui-react/with-schemas/index.d.ts +2 -2
  51. package/index.js +23 -17
  52. package/mergeable-store/index.js +23 -17
  53. package/mergeable-store/with-schemas/index.js +23 -17
  54. package/min/index.js +1 -1
  55. package/min/index.js.gz +0 -0
  56. package/min/mergeable-store/index.js +1 -1
  57. package/min/mergeable-store/index.js.gz +0 -0
  58. package/min/mergeable-store/with-schemas/index.js +1 -1
  59. package/min/mergeable-store/with-schemas/index.js.gz +0 -0
  60. package/min/persisters/index.js +1 -1
  61. package/min/persisters/index.js.gz +0 -0
  62. package/min/persisters/persister-automerge/index.js +1 -1
  63. package/min/persisters/persister-automerge/index.js.gz +0 -0
  64. package/min/persisters/persister-automerge/with-schemas/index.js +1 -1
  65. package/min/persisters/persister-automerge/with-schemas/index.js.gz +0 -0
  66. package/min/persisters/persister-browser/index.js +1 -1
  67. package/min/persisters/persister-browser/index.js.gz +0 -0
  68. package/min/persisters/persister-browser/with-schemas/index.js +1 -1
  69. package/min/persisters/persister-browser/with-schemas/index.js.gz +0 -0
  70. package/min/persisters/persister-cr-sqlite-wasm/index.js +1 -1
  71. package/min/persisters/persister-cr-sqlite-wasm/index.js.gz +0 -0
  72. package/min/persisters/persister-cr-sqlite-wasm/with-schemas/index.js +1 -1
  73. package/min/persisters/persister-cr-sqlite-wasm/with-schemas/index.js.gz +0 -0
  74. package/min/persisters/persister-durable-object-storage/index.js +1 -1
  75. package/min/persisters/persister-durable-object-storage/index.js.gz +0 -0
  76. package/min/persisters/persister-durable-object-storage/with-schemas/index.js +1 -1
  77. package/min/persisters/persister-durable-object-storage/with-schemas/index.js.gz +0 -0
  78. package/min/persisters/persister-electric-sql/index.js +1 -1
  79. package/min/persisters/persister-electric-sql/index.js.gz +0 -0
  80. package/min/persisters/persister-electric-sql/with-schemas/index.js +1 -1
  81. package/min/persisters/persister-electric-sql/with-schemas/index.js.gz +0 -0
  82. package/min/persisters/persister-expo-sqlite/index.js +1 -1
  83. package/min/persisters/persister-expo-sqlite/index.js.gz +0 -0
  84. package/min/persisters/persister-expo-sqlite/with-schemas/index.js +1 -1
  85. package/min/persisters/persister-expo-sqlite/with-schemas/index.js.gz +0 -0
  86. package/min/persisters/persister-file/index.js +1 -1
  87. package/min/persisters/persister-file/index.js.gz +0 -0
  88. package/min/persisters/persister-file/with-schemas/index.js +1 -1
  89. package/min/persisters/persister-file/with-schemas/index.js.gz +0 -0
  90. package/min/persisters/persister-indexed-db/index.js +1 -1
  91. package/min/persisters/persister-indexed-db/index.js.gz +0 -0
  92. package/min/persisters/persister-indexed-db/with-schemas/index.js +1 -1
  93. package/min/persisters/persister-indexed-db/with-schemas/index.js.gz +0 -0
  94. package/min/persisters/persister-libsql/index.js +1 -1
  95. package/min/persisters/persister-libsql/index.js.gz +0 -0
  96. package/min/persisters/persister-libsql/with-schemas/index.js +1 -1
  97. package/min/persisters/persister-libsql/with-schemas/index.js.gz +0 -0
  98. package/min/persisters/persister-partykit-client/index.js +1 -1
  99. package/min/persisters/persister-partykit-client/index.js.gz +0 -0
  100. package/min/persisters/persister-partykit-client/with-schemas/index.js +1 -1
  101. package/min/persisters/persister-partykit-client/with-schemas/index.js.gz +0 -0
  102. package/min/persisters/persister-pglite/index.js +1 -1
  103. package/min/persisters/persister-pglite/index.js.gz +0 -0
  104. package/min/persisters/persister-pglite/with-schemas/index.js +1 -1
  105. package/min/persisters/persister-pglite/with-schemas/index.js.gz +0 -0
  106. package/min/persisters/persister-postgres/index.js +1 -1
  107. package/min/persisters/persister-postgres/index.js.gz +0 -0
  108. package/min/persisters/persister-postgres/with-schemas/index.js +1 -1
  109. package/min/persisters/persister-postgres/with-schemas/index.js.gz +0 -0
  110. package/min/persisters/persister-powersync/index.js +1 -1
  111. package/min/persisters/persister-powersync/index.js.gz +0 -0
  112. package/min/persisters/persister-powersync/with-schemas/index.js +1 -1
  113. package/min/persisters/persister-powersync/with-schemas/index.js.gz +0 -0
  114. package/min/persisters/persister-remote/index.js +1 -1
  115. package/min/persisters/persister-remote/index.js.gz +0 -0
  116. package/min/persisters/persister-remote/with-schemas/index.js +1 -1
  117. package/min/persisters/persister-remote/with-schemas/index.js.gz +0 -0
  118. package/min/persisters/persister-sqlite-bun/index.js +1 -1
  119. package/min/persisters/persister-sqlite-bun/index.js.gz +0 -0
  120. package/min/persisters/persister-sqlite-bun/with-schemas/index.js +1 -1
  121. package/min/persisters/persister-sqlite-bun/with-schemas/index.js.gz +0 -0
  122. package/min/persisters/persister-sqlite-wasm/index.js +1 -1
  123. package/min/persisters/persister-sqlite-wasm/index.js.gz +0 -0
  124. package/min/persisters/persister-sqlite-wasm/with-schemas/index.js +1 -1
  125. package/min/persisters/persister-sqlite-wasm/with-schemas/index.js.gz +0 -0
  126. package/min/persisters/persister-sqlite3/index.js +1 -1
  127. package/min/persisters/persister-sqlite3/index.js.gz +0 -0
  128. package/min/persisters/persister-sqlite3/with-schemas/index.js +1 -1
  129. package/min/persisters/persister-sqlite3/with-schemas/index.js.gz +0 -0
  130. package/min/persisters/persister-yjs/index.js +1 -1
  131. package/min/persisters/persister-yjs/index.js.gz +0 -0
  132. package/min/persisters/persister-yjs/with-schemas/index.js +1 -1
  133. package/min/persisters/persister-yjs/with-schemas/index.js.gz +0 -0
  134. package/min/persisters/with-schemas/index.js +1 -1
  135. package/min/persisters/with-schemas/index.js.gz +0 -0
  136. package/min/store/index.js +1 -1
  137. package/min/store/index.js.gz +0 -0
  138. package/min/store/with-schemas/index.js +1 -1
  139. package/min/store/with-schemas/index.js.gz +0 -0
  140. package/min/synchronizers/index.js +1 -1
  141. package/min/synchronizers/index.js.gz +0 -0
  142. package/min/synchronizers/synchronizer-broadcast-channel/index.js +1 -1
  143. package/min/synchronizers/synchronizer-broadcast-channel/index.js.gz +0 -0
  144. package/min/synchronizers/synchronizer-broadcast-channel/with-schemas/index.js +1 -1
  145. package/min/synchronizers/synchronizer-broadcast-channel/with-schemas/index.js.gz +0 -0
  146. package/min/synchronizers/synchronizer-local/index.js +1 -1
  147. package/min/synchronizers/synchronizer-local/index.js.gz +0 -0
  148. package/min/synchronizers/synchronizer-local/with-schemas/index.js +1 -1
  149. package/min/synchronizers/synchronizer-local/with-schemas/index.js.gz +0 -0
  150. package/min/synchronizers/synchronizer-ws-client/index.js +1 -1
  151. package/min/synchronizers/synchronizer-ws-client/index.js.gz +0 -0
  152. package/min/synchronizers/synchronizer-ws-client/with-schemas/index.js +1 -1
  153. package/min/synchronizers/synchronizer-ws-client/with-schemas/index.js.gz +0 -0
  154. package/min/synchronizers/synchronizer-ws-server/index.js +1 -1
  155. package/min/synchronizers/synchronizer-ws-server/index.js.gz +0 -0
  156. package/min/synchronizers/synchronizer-ws-server/with-schemas/index.js +1 -1
  157. package/min/synchronizers/synchronizer-ws-server/with-schemas/index.js.gz +0 -0
  158. package/min/synchronizers/synchronizer-ws-server-durable-object/index.js +1 -1
  159. package/min/synchronizers/synchronizer-ws-server-durable-object/index.js.gz +0 -0
  160. package/min/synchronizers/synchronizer-ws-server-durable-object/with-schemas/index.js +1 -1
  161. package/min/synchronizers/synchronizer-ws-server-durable-object/with-schemas/index.js.gz +0 -0
  162. package/min/synchronizers/synchronizer-ws-server-simple/index.js +1 -1
  163. package/min/synchronizers/synchronizer-ws-server-simple/index.js.gz +0 -0
  164. package/min/synchronizers/synchronizer-ws-server-simple/with-schemas/index.js +1 -1
  165. package/min/synchronizers/synchronizer-ws-server-simple/with-schemas/index.js.gz +0 -0
  166. package/min/synchronizers/with-schemas/index.js +1 -1
  167. package/min/synchronizers/with-schemas/index.js.gz +0 -0
  168. package/min/ui-react-inspector/index.js +1 -1
  169. package/min/ui-react-inspector/index.js.gz +0 -0
  170. package/min/ui-react-inspector/with-schemas/index.js +1 -1
  171. package/min/ui-react-inspector/with-schemas/index.js.gz +0 -0
  172. package/min/with-schemas/index.js +1 -1
  173. package/min/with-schemas/index.js.gz +0 -0
  174. package/package.json +8 -4
  175. package/persisters/index.js +293 -161
  176. package/persisters/persister-automerge/index.js +55 -50
  177. package/persisters/persister-automerge/with-schemas/index.js +55 -50
  178. package/persisters/persister-browser/index.js +56 -55
  179. package/persisters/persister-browser/with-schemas/index.js +56 -55
  180. package/persisters/persister-cr-sqlite-wasm/index.js +181 -134
  181. package/persisters/persister-cr-sqlite-wasm/with-schemas/index.js +181 -134
  182. package/persisters/persister-durable-object-storage/index.js +58 -53
  183. package/persisters/persister-durable-object-storage/with-schemas/index.js +58 -53
  184. package/persisters/persister-electric-sql/index.js +181 -134
  185. package/persisters/persister-electric-sql/with-schemas/index.js +181 -134
  186. package/persisters/persister-expo-sqlite/index.js +181 -134
  187. package/persisters/persister-expo-sqlite/with-schemas/index.js +181 -134
  188. package/persisters/persister-file/index.js +55 -50
  189. package/persisters/persister-file/with-schemas/index.js +55 -50
  190. package/persisters/persister-indexed-db/index.js +82 -78
  191. package/persisters/persister-indexed-db/with-schemas/index.js +82 -78
  192. package/persisters/persister-libsql/index.js +182 -135
  193. package/persisters/persister-libsql/with-schemas/index.js +182 -135
  194. package/persisters/persister-partykit-client/index.js +56 -51
  195. package/persisters/persister-partykit-client/with-schemas/index.js +56 -51
  196. package/persisters/persister-pglite/index.js +299 -173
  197. package/persisters/persister-pglite/with-schemas/index.js +299 -173
  198. package/persisters/persister-postgres/index.js +296 -171
  199. package/persisters/persister-postgres/with-schemas/index.js +296 -171
  200. package/persisters/persister-powersync/index.js +189 -138
  201. package/persisters/persister-powersync/with-schemas/index.js +189 -138
  202. package/persisters/persister-remote/index.js +55 -50
  203. package/persisters/persister-remote/with-schemas/index.js +55 -50
  204. package/persisters/persister-sqlite-bun/index.js +182 -135
  205. package/persisters/persister-sqlite-bun/with-schemas/index.js +182 -135
  206. package/persisters/persister-sqlite-wasm/index.js +182 -135
  207. package/persisters/persister-sqlite-wasm/with-schemas/index.js +182 -135
  208. package/persisters/persister-sqlite3/index.js +181 -134
  209. package/persisters/persister-sqlite3/with-schemas/index.js +181 -134
  210. package/persisters/persister-yjs/index.js +55 -50
  211. package/persisters/persister-yjs/with-schemas/index.js +55 -50
  212. package/persisters/with-schemas/index.js +293 -161
  213. package/readme.md +2 -2
  214. package/releases.md +29 -1
  215. package/store/index.js +20 -15
  216. package/store/with-schemas/index.js +20 -15
  217. package/synchronizers/index.js +68 -63
  218. package/synchronizers/synchronizer-broadcast-channel/index.js +68 -63
  219. package/synchronizers/synchronizer-broadcast-channel/with-schemas/index.js +68 -63
  220. package/synchronizers/synchronizer-local/index.js +68 -63
  221. package/synchronizers/synchronizer-local/with-schemas/index.js +68 -63
  222. package/synchronizers/synchronizer-ws-client/index.js +68 -63
  223. package/synchronizers/synchronizer-ws-client/with-schemas/index.js +68 -63
  224. package/synchronizers/synchronizer-ws-server/index.js +79 -70
  225. package/synchronizers/synchronizer-ws-server/with-schemas/index.js +79 -70
  226. package/synchronizers/synchronizer-ws-server-durable-object/index.js +69 -51
  227. package/synchronizers/synchronizer-ws-server-durable-object/with-schemas/index.js +69 -51
  228. package/synchronizers/synchronizer-ws-server-simple/index.js +1 -1
  229. package/synchronizers/synchronizer-ws-server-simple/with-schemas/index.js +1 -1
  230. package/synchronizers/with-schemas/index.js +68 -63
  231. package/ui-react-inspector/index.js +68 -60
  232. package/ui-react-inspector/with-schemas/index.js +68 -60
  233. 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 tabularConfig = [
226
- getDefaultedTabularConfigMap(
227
- load,
228
- {[TABLE_ID]: null, [ROW_ID_COLUMN_NAME]: DEFAULT_ROW_ID_COLUMN_NAME},
229
- TABLE_ID,
230
- (tableName) => collHas(excludedTableNames, tableName),
231
- (tableName) => setAdd(managedTableNames, tableName),
232
- ),
233
- getDefaultedTabularConfigMap(
234
- save,
235
- {
236
- [TABLE_NAME]: null,
237
- [ROW_ID_COLUMN_NAME]: DEFAULT_ROW_ID_COLUMN_NAME,
238
- [DELETE_EMPTY_COLUMNS]: 0,
239
- [DELETE_EMPTY_TABLE]: 0,
240
- },
241
- TABLE_NAME,
242
- (_, tableName) => collHas(excludedTableNames, tableName),
243
- (_, tableName) => setAdd(managedTableNames, tableName),
244
- ),
245
- valuesConfig,
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
- try {
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
- try {
432
- const content = await getPersisted();
433
- if (isArray(content)) {
434
- setContentOrChanges(content);
435
- } else if (initialContent) {
436
- setDefaultContent(initialContent);
437
- } else {
438
- errorNew(`Content is not an array: ${content}`);
439
- }
440
- } catch (error) {
441
- onIgnoredError?.(error);
442
- if (initialContent) {
443
- setDefaultContent(initialContent);
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
- try {
455
- autoLoadHandle = await addPersisterListener(async (content, changes) => {
456
- if (changes || content) {
457
- /* istanbul ignore else */
458
- if (status != 2 /* Saving */) {
459
- setStatus(1 /* Loading */);
460
- loads++;
461
- setContentOrChanges(changes ?? content);
462
- setStatus(0 /* Idle */);
463
- }
464
- } else {
465
- await load();
466
- }
467
- });
468
- } catch (error) {
469
- /* istanbul ignore next */
470
- onIgnoredError?.(error);
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
- delPersisterListener(autoLoadHandle);
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
- try {
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
- return stopAutoLoad().stopAutoSave();
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 + escapeId(tableName),
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
- 'CREATE ' +
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 + escapeId(tableName) + WHERE + ' true',
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
- WHERE +
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
- WHERE +
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 + escapeId(tableName) + WHERE + ' true',
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
- try {
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
- 'INSERT INTO' +
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
- ')DO UPDATE SET' +
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
- destroyImpl,
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 = async () =>
836
- await transaction(async () => {
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 = async (getContent) =>
845
- await transaction(async () => {
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().stopAutoSave();
861
- destroyImpl();
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
- destroyImpl,
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 = async (tables, partial) =>
913
- await promiseAll(
965
+ const saveTables = (tables, partial) =>
966
+ promiseAll(
914
967
  mapMap(
915
968
  tablesSaveConfig,
916
969
  async (
917
- [tableName, rowIdColumnName, deleteEmptyColumns, deleteEmptyTable],
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 = async () =>
966
- await transaction(async () => {
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 = async (getContent, changes) =>
975
- await transaction(async () => {
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().stopAutoSave();
988
- destroyImpl();
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 EVENT_CHANNEL = TINYBASE;
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 addDataTrigger = async (tableName) => {
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
- // eslint-disable-next-line max-len
1030
- `CREATE OR REPLACE TRIGGER ${escapeId(CHANGE_DATA_TRIGGER + '_' + tableName)} AFTER INSERT OR UPDATE OR DELETE ON ${escapeId(tableName)} EXECUTE FUNCTION ${CHANGE_DATA_TRIGGER}()`,
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 addPersisterListener = async (listener) => {
1106
+ const createTrigger = async (
1107
+ prefix,
1108
+ escapedTriggerName,
1109
+ body,
1110
+ escapedFunctionName,
1111
+ ) => {
1034
1112
  await executeCommand(
1035
- // eslint-disable-next-line max-len
1036
- `CREATE OR REPLACE FUNCTION ${CREATE_TABLE_TRIGGER}()RETURNS event_trigger AS $t2$ DECLARE row record; BEGIN FOR row IN SELECT object_identity FROM pg_event_trigger_ddl_commands()WHERE command_tag='CREATE TABLE' LOOP PERFORM pg_notify('${EVENT_CHANNEL}','c:'||SPLIT_PART(row.object_identity,'.',2));END LOOP;END;$t2$ LANGUAGE plpgsql;`,
1113
+ CREATE +
1114
+ prefix +
1115
+ 'TRIGGER' +
1116
+ escapedTriggerName +
1117
+ body +
1118
+ 'EXECUTE ' +
1119
+ FUNCTION +
1120
+ escapedFunctionName +
1121
+ `()`,
1037
1122
  );
1038
- try {
1039
- await executeCommand(
1040
- // eslint-disable-next-line max-len
1041
- `CREATE EVENT TRIGGER ${CREATE_TABLE_TRIGGER} ON ddl_command_end WHEN TAG IN('CREATE TABLE')EXECUTE FUNCTION ${CREATE_TABLE_TRIGGER}();`,
1042
- );
1043
- } catch {}
1044
- await executeCommand(
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
- `CREATE OR REPLACE FUNCTION ${CHANGE_DATA_TRIGGER}()RETURNS trigger AS $t1$ BEGIN PERFORM pg_notify('${EVENT_CHANNEL}','d:'||TG_TABLE_NAME);RETURN NULL;END;$t1$ LANGUAGE plpgsql;`,
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
- // eslint-disable-next-line max-len
1052
- `CREATE TABLE IF NOT EXISTS ${escapeId(tableName)}("_id"text PRIMARY KEY)`,
1171
+ CREATE_TABLE +
1172
+ ` IF NOT EXISTS${escapeId(tableName)}("_id"text PRIMARY KEY)`,
1053
1173
  );
1054
- await addDataTrigger(tableName);
1174
+ return await addDataChangedTriggers(tableName, dataChangedFunctionName);
1055
1175
  }),
1056
1176
  );
1057
- return await addChangeListener(
1058
- EVENT_CHANNEL,
1059
- async (prefixAndTableName) =>
1060
- await ifNotUndefined(
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 addDataTrigger(tableName);
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
- `${SELECT} table_name tn,column_name cn FROM information_schema.columns ${WHERE} table_schema='public'AND table_name IN(${getPlaceholders(managedTableNames)})`,
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
- async (channel, listener) => await pglite.listen(channel, listener),
1111
- async (unlisten) => {
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
- () => 0,
1246
+ noop,
1121
1247
  3,
1122
1248
  // StoreOrMergeableStore,
1123
1249
  pglite,