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 THOUSAND = 1e3;
11
15
  const startInterval = (callback, sec, immediate) => {
12
16
  return setInterval(callback, sec * THOUSAND);
@@ -24,6 +28,14 @@ const promiseAll = async (promises) => promise.all(promises);
24
28
  const errorNew = (message) => {
25
29
  throw new Error(message);
26
30
  };
31
+ const tryCatch = async (action, then1, then2) => {
32
+ try {
33
+ return await action();
34
+ } catch (error) {
35
+ /* istanbul ignore next */
36
+ then1?.(error);
37
+ }
38
+ };
27
39
 
28
40
  const arrayForEach = (array, cb) => array.forEach(cb);
29
41
  const arrayJoin = (array, sep = EMPTY_STRING) => array.join(sep);
@@ -75,6 +87,8 @@ const objIsEmpty = (obj) => isObject(obj) && objSize(obj) == 0;
75
87
 
76
88
  const mapNew = (entries) => new Map(entries);
77
89
  const mapGet = (map, key) => map?.get(key);
90
+ const mapForEach = (map, cb) =>
91
+ collForEach(map, (value, key) => cb(key, value));
78
92
  const mapMap = (coll, cb) =>
79
93
  arrayMap([...(coll?.entries() ?? [])], ([key, value]) => cb(value, key));
80
94
  const mapSet = (map, key, value) =>
@@ -283,12 +297,7 @@ const createCustomPersister = (
283
297
  while (
284
298
  !isUndefined((action = arrayShift(mapGet(scheduleActions, scheduleId))))
285
299
  ) {
286
- try {
287
- await action();
288
- } catch (error) {
289
- /* istanbul ignore next */
290
- onIgnoredError?.(error);
291
- }
300
+ await tryCatch(action, onIgnoredError);
292
301
  }
293
302
  mapSet(scheduleRunning, scheduleId, 0);
294
303
  }
@@ -308,21 +317,23 @@ const createCustomPersister = (
308
317
  setStatus(1 /* Loading */);
309
318
  loads++;
310
319
  await schedule(async () => {
311
- try {
312
- const content = await getPersisted();
313
- if (isArray(content)) {
314
- setContentOrChanges(content);
315
- } else if (initialContent) {
316
- setDefaultContent(initialContent);
317
- } else {
318
- errorNew(`Content is not an array: ${content}`);
319
- }
320
- } catch (error) {
321
- onIgnoredError?.(error);
322
- if (initialContent) {
323
- setDefaultContent(initialContent);
324
- }
325
- }
320
+ await tryCatch(
321
+ async () => {
322
+ const content = await getPersisted();
323
+ if (isArray(content)) {
324
+ setContentOrChanges(content);
325
+ } else if (initialContent) {
326
+ setDefaultContent(initialContent);
327
+ } else {
328
+ errorNew(`Content is not an array: ${content}`);
329
+ }
330
+ },
331
+ () => {
332
+ if (initialContent) {
333
+ setDefaultContent(initialContent);
334
+ }
335
+ },
336
+ );
326
337
  setStatus(0 /* Idle */);
327
338
  });
328
339
  }
@@ -331,29 +342,33 @@ const createCustomPersister = (
331
342
  const startAutoLoad = async (initialContent) => {
332
343
  stopAutoLoad();
333
344
  await load(initialContent);
334
- try {
335
- autoLoadHandle = await addPersisterListener(async (content, changes) => {
336
- if (changes || content) {
337
- /* istanbul ignore else */
338
- if (status != 2 /* Saving */) {
339
- setStatus(1 /* Loading */);
340
- loads++;
341
- setContentOrChanges(changes ?? content);
342
- setStatus(0 /* Idle */);
343
- }
344
- } else {
345
- await load();
346
- }
347
- });
348
- } catch (error) {
349
- /* istanbul ignore next */
350
- onIgnoredError?.(error);
351
- }
345
+ await tryCatch(
346
+ async () =>
347
+ (autoLoadHandle = await addPersisterListener(
348
+ async (content, changes) => {
349
+ if (changes || content) {
350
+ /* istanbul ignore else */
351
+ if (status != 2 /* Saving */) {
352
+ setStatus(1 /* Loading */);
353
+ loads++;
354
+ setContentOrChanges(changes ?? content);
355
+ setStatus(0 /* Idle */);
356
+ }
357
+ } else {
358
+ await load();
359
+ }
360
+ },
361
+ )),
362
+ onIgnoredError,
363
+ );
352
364
  return persister;
353
365
  };
354
- const stopAutoLoad = () => {
366
+ const stopAutoLoad = async () => {
355
367
  if (autoLoadHandle) {
356
- delPersisterListener(autoLoadHandle);
368
+ await tryCatch(
369
+ () => delPersisterListener(autoLoadHandle),
370
+ onIgnoredError,
371
+ );
357
372
  autoLoadHandle = void 0;
358
373
  }
359
374
  return persister;
@@ -365,12 +380,7 @@ const createCustomPersister = (
365
380
  setStatus(2 /* Saving */);
366
381
  saves++;
367
382
  await schedule(async () => {
368
- try {
369
- await setPersisted(getContent, changes);
370
- } catch (error) {
371
- /* istanbul ignore next */
372
- onIgnoredError?.(error);
373
- }
383
+ await tryCatch(() => setPersisted(getContent, changes), onIgnoredError);
374
384
  setStatus(0 /* Idle */);
375
385
  });
376
386
  }
@@ -387,7 +397,7 @@ const createCustomPersister = (
387
397
  });
388
398
  return persister;
389
399
  };
390
- const stopAutoSave = () => {
400
+ const stopAutoSave = async () => {
391
401
  if (autoSaveListenerId) {
392
402
  store.delListener(autoSaveListenerId);
393
403
  autoSaveListenerId = void 0;
@@ -408,9 +418,10 @@ const createCustomPersister = (
408
418
  return persister;
409
419
  };
410
420
  const getStore = () => store;
411
- const destroy = () => {
421
+ const destroy = async () => {
412
422
  arrayClear(mapGet(scheduleActions, scheduleId));
413
- return stopAutoLoad().stopAutoSave();
423
+ await persister.stopAutoLoad();
424
+ return await persister.stopAutoSave();
414
425
  };
415
426
  const getStats = () => ({loads, saves});
416
427
  const persister = {
@@ -434,6 +445,17 @@ const createCustomPersister = (
434
445
  return objFreeze(persister);
435
446
  };
436
447
 
448
+ const textEncoder = /* @__PURE__ */ new GLOBAL.TextEncoder();
449
+ const getHash = (value) => {
450
+ let hash = 2166136261;
451
+ arrayForEach(textEncoder.encode(value), (char) => {
452
+ hash ^= char;
453
+ hash +=
454
+ (hash << 1) + (hash << 4) + (hash << 7) + (hash << 8) + (hash << 24);
455
+ });
456
+ return hash >>> 0;
457
+ };
458
+
437
459
  const jsonString = JSON.stringify;
438
460
  const jsonParse = JSON.parse;
439
461
  const jsonStringWithUndefined = (obj) =>
@@ -446,14 +468,22 @@ const DEFAULT_ROW_ID_COLUMN_NAME = '_id';
446
468
  const SELECT = 'SELECT';
447
469
  const WHERE = 'WHERE';
448
470
  const TABLE = 'TABLE';
471
+ const INSERT = 'INSERT';
472
+ const DELETE = 'DELETE';
473
+ const UPDATE = 'UPDATE';
449
474
  const ALTER_TABLE = 'ALTER ' + TABLE;
450
- const DELETE_FROM = 'DELETE FROM';
451
- const SELECT_STAR_FROM = SELECT + '*FROM';
475
+ const FROM = 'FROM';
476
+ const DELETE_FROM = DELETE + ' ' + FROM;
477
+ const SELECT_STAR_FROM = SELECT + '*' + FROM;
452
478
  const PRAGMA = 'pragma_';
453
479
  const DATA_VERSION = 'data_version';
454
480
  const SCHEMA_VERSION = 'schema_version';
455
- const FROM = 'FROM ';
456
481
  const PRAGMA_TABLE = 'pragma_table_';
482
+ const CREATE = 'CREATE ';
483
+ const CREATE_TABLE = CREATE + TABLE;
484
+ const OR_REPLACE = 'OR REPLACE ';
485
+ const FUNCTION = 'FUNCTION';
486
+ const TABLE_NAME_PLACEHOLDER = '$tableName';
457
487
  const getWrappedCommand = (executeCommand, onSqlCommand) =>
458
488
  onSqlCommand
459
489
  ? async (sql, params) => {
@@ -461,7 +491,8 @@ const getWrappedCommand = (executeCommand, onSqlCommand) =>
461
491
  return await executeCommand(sql, params);
462
492
  }
463
493
  : executeCommand;
464
- const escapeId = (str) => `"${str.replace(/"/g, '""')}"`;
494
+ const escapeId = (str) => `"${strReplace(str, /"/g, '""')}"`;
495
+ const escapeIds = (...ids) => escapeId(arrayJoin(ids, '_'));
465
496
  const escapeColumnNames = (...columnNames) =>
466
497
  arrayJoin(arrayMap(columnNames, escapeId), COMMA);
467
498
  const getPlaceholders = (array, offset = [1]) =>
@@ -469,6 +500,9 @@ const getPlaceholders = (array, offset = [1]) =>
469
500
  arrayMap(array, () => '$' + offset[0]++),
470
501
  COMMA,
471
502
  );
503
+ const getWhereCondition = (tableName, condition = TRUE) =>
504
+ WHERE +
505
+ `(${strReplace(condition, TABLE_NAME_PLACEHOLDER, escapeId(tableName))})`;
472
506
 
473
507
  const COLUMN_NAME = 'ColumnName';
474
508
  const STORE = 'store';
@@ -482,6 +516,7 @@ const TABLE_ID = 'tableId';
482
516
  const TABLE_NAME = 'tableName';
483
517
  const DELETE_EMPTY_COLUMNS = 'deleteEmptyColumns';
484
518
  const DELETE_EMPTY_TABLE = 'deleteEmptyTable';
519
+ const CONDITION = 'condition';
485
520
  const DEFAULT_CONFIG = {
486
521
  mode: JSON$1,
487
522
  [AUTO_LOAD_INTERVAL_SECONDS]: 1,
@@ -549,29 +584,42 @@ const getConfigStructures = (configOrStoreTableName) => {
549
584
  const valuesTable = valuesConfig[2];
550
585
  const managedTableNames = setNew(valuesTable);
551
586
  const excludedTableNames = setNew(valuesTable);
552
- const tabularConfig = [
553
- getDefaultedTabularConfigMap(
554
- load,
555
- {[TABLE_ID]: null, [ROW_ID_COLUMN_NAME]: DEFAULT_ROW_ID_COLUMN_NAME},
556
- TABLE_ID,
557
- (tableName) => collHas(excludedTableNames, tableName),
558
- (tableName) => setAdd(managedTableNames, tableName),
559
- ),
560
- getDefaultedTabularConfigMap(
561
- save,
562
- {
563
- [TABLE_NAME]: null,
564
- [ROW_ID_COLUMN_NAME]: DEFAULT_ROW_ID_COLUMN_NAME,
565
- [DELETE_EMPTY_COLUMNS]: 0,
566
- [DELETE_EMPTY_TABLE]: 0,
567
- },
568
- TABLE_NAME,
569
- (_, tableName) => collHas(excludedTableNames, tableName),
570
- (_, tableName) => setAdd(managedTableNames, tableName),
571
- ),
572
- valuesConfig,
587
+ const tablesLoadConfig = getDefaultedTabularConfigMap(
588
+ load,
589
+ {
590
+ [TABLE_ID]: null,
591
+ [ROW_ID_COLUMN_NAME]: DEFAULT_ROW_ID_COLUMN_NAME,
592
+ [CONDITION]: TRUE,
593
+ },
594
+ TABLE_ID,
595
+ (tableName) => collHas(excludedTableNames, tableName),
596
+ (tableName) => setAdd(managedTableNames, tableName),
597
+ );
598
+ const tablesSaveConfig = getDefaultedTabularConfigMap(
599
+ save,
600
+ {
601
+ [TABLE_NAME]: null,
602
+ [ROW_ID_COLUMN_NAME]: DEFAULT_ROW_ID_COLUMN_NAME,
603
+ [DELETE_EMPTY_COLUMNS]: 0,
604
+ [DELETE_EMPTY_TABLE]: 0,
605
+ [CONDITION]: null,
606
+ },
607
+ TABLE_NAME,
608
+ (_, tableName) => collHas(excludedTableNames, tableName),
609
+ (_, tableName) => setAdd(managedTableNames, tableName),
610
+ );
611
+ mapForEach(
612
+ tablesSaveConfig,
613
+ (_, tableSaveConfig) =>
614
+ (tableSaveConfig[4] ??=
615
+ mapGet(tablesLoadConfig, tableSaveConfig[0])?.[2] ?? TRUE),
616
+ );
617
+ return [
618
+ 0,
619
+ autoLoadIntervalSeconds,
620
+ [tablesLoadConfig, tablesSaveConfig, valuesConfig],
621
+ managedTableNames,
573
622
  ];
574
- return [0, autoLoadIntervalSeconds, tabularConfig, managedTableNames];
575
623
  };
576
624
 
577
625
  const getCommandFunctions = (
@@ -594,13 +642,15 @@ const getCommandFunctions = (
594
642
  ({tn, cn}) => setAdd(mapEnsure(schemaMap, tn, setNew), cn),
595
643
  );
596
644
  };
597
- const loadTable = async (tableName, rowIdColumnName) =>
645
+ const loadTable = async (tableName, rowIdColumnName, condition) =>
598
646
  canSelect(tableName, rowIdColumnName)
599
647
  ? objNew(
600
648
  arrayFilter(
601
649
  arrayMap(
602
650
  await databaseExecuteCommand(
603
- SELECT_STAR_FROM + escapeId(tableName),
651
+ SELECT_STAR_FROM +
652
+ escapeId(tableName) +
653
+ getWhereCondition(tableName, condition),
604
654
  ),
605
655
  (row) => [
606
656
  row[rowIdColumnName],
@@ -620,6 +670,7 @@ const getCommandFunctions = (
620
670
  deleteEmptyColumns,
621
671
  deleteEmptyTable,
622
672
  partial = false,
673
+ condition = TRUE,
623
674
  ) => {
624
675
  const settingColumnNameSet = setNew();
625
676
  objMap(content ?? {}, (contentRow) =>
@@ -631,6 +682,7 @@ const getCommandFunctions = (
631
682
  if (
632
683
  !partial &&
633
684
  deleteEmptyTable &&
685
+ condition == TRUE &&
634
686
  arrayIsEmpty(settingColumnNames) &&
635
687
  collHas(schemaMap, tableName)
636
688
  ) {
@@ -643,8 +695,7 @@ const getCommandFunctions = (
643
695
  if (!arrayIsEmpty(settingColumnNames)) {
644
696
  if (!collHas(schemaMap, tableName)) {
645
697
  await databaseExecuteCommand(
646
- 'CREATE ' +
647
- TABLE +
698
+ CREATE_TABLE +
648
699
  escapeId(tableName) +
649
700
  `(${escapeId(rowIdColumnName)}${columnType} PRIMARY KEY${arrayJoin(
650
701
  arrayMap(
@@ -707,7 +758,9 @@ const getCommandFunctions = (
707
758
  if (partial) {
708
759
  if (isUndefined(content)) {
709
760
  await databaseExecuteCommand(
710
- DELETE_FROM + escapeId(tableName) + WHERE + ' true',
761
+ DELETE_FROM +
762
+ escapeId(tableName) +
763
+ getWhereCondition(tableName, condition),
711
764
  );
712
765
  } else {
713
766
  await promiseAll(
@@ -716,9 +769,8 @@ const getCommandFunctions = (
716
769
  await databaseExecuteCommand(
717
770
  DELETE_FROM +
718
771
  escapeId(tableName) +
719
- WHERE +
720
- escapeId(rowIdColumnName) +
721
- '=$1',
772
+ getWhereCondition(tableName, condition) +
773
+ `AND(${escapeId(rowIdColumnName)}=$1)`,
722
774
  [rowId],
723
775
  );
724
776
  } else if (!arrayIsEmpty(settingColumnNames)) {
@@ -762,14 +814,15 @@ const getCommandFunctions = (
762
814
  await databaseExecuteCommand(
763
815
  DELETE_FROM +
764
816
  escapeId(tableName) +
765
- WHERE +
766
- escapeId(rowIdColumnName) +
767
- `NOT IN(${getPlaceholders(deleteRowIds)})`,
817
+ getWhereCondition(tableName, condition) + // eslint-disable-next-line max-len
818
+ `AND${escapeId(rowIdColumnName)}NOT IN(${getPlaceholders(deleteRowIds)})`,
768
819
  deleteRowIds,
769
820
  );
770
821
  } else if (collHas(schemaMap, tableName)) {
771
822
  await databaseExecuteCommand(
772
- DELETE_FROM + escapeId(tableName) + WHERE + ' true',
823
+ DELETE_FROM +
824
+ escapeId(tableName) +
825
+ getWhereCondition(tableName, condition),
773
826
  );
774
827
  }
775
828
  }
@@ -777,11 +830,7 @@ const getCommandFunctions = (
777
830
  const transaction = async (actions) => {
778
831
  let result;
779
832
  await databaseExecuteCommand('BEGIN');
780
- try {
781
- result = await actions();
782
- } catch (error) {
783
- onIgnoredError?.(error);
784
- }
833
+ await tryCatch(async () => (result = await actions()), onIgnoredError);
785
834
  await databaseExecuteCommand('END');
786
835
  return result;
787
836
  };
@@ -796,7 +845,8 @@ const defaultUpsert = async (
796
845
  ) => {
797
846
  const offset = [1];
798
847
  await executeCommand(
799
- 'INSERT INTO' +
848
+ INSERT +
849
+ ' INTO' +
800
850
  escapeId(tableName) +
801
851
  '(' +
802
852
  escapeColumnNames(rowIdColumnName, ...changingColumnNames) +
@@ -811,7 +861,7 @@ const defaultUpsert = async (
811
861
  ) +
812
862
  'ON CONFLICT(' +
813
863
  escapeId(rowIdColumnName) +
814
- ')DO UPDATE SET' +
864
+ `)DO ${UPDATE} SET` +
815
865
  arrayJoin(
816
866
  arrayMap(
817
867
  changingColumnNames,
@@ -833,7 +883,7 @@ const createJsonPersister = (
833
883
  addPersisterListener,
834
884
  delPersisterListener,
835
885
  onIgnoredError,
836
- destroyImpl,
886
+ extraDestroy,
837
887
  persist,
838
888
  [storeTableName, storeIdColumnName, storeColumnName],
839
889
  managedTableNames,
@@ -852,8 +902,8 @@ const createJsonPersister = (
852
902
  columnType,
853
903
  upsert,
854
904
  );
855
- const getPersisted = async () =>
856
- await transaction(async () => {
905
+ const getPersisted = () =>
906
+ transaction(async () => {
857
907
  await refreshSchema();
858
908
  return jsonParseWithUndefined(
859
909
  (await loadTable(storeTableName, storeIdColumnName))[SINGLE_ROW_ID]?.[
@@ -861,8 +911,8 @@ const createJsonPersister = (
861
911
  ] ?? 'null',
862
912
  );
863
913
  });
864
- const setPersisted = async (getContent) =>
865
- await transaction(async () => {
914
+ const setPersisted = (getContent) =>
915
+ transaction(async () => {
866
916
  await refreshSchema();
867
917
  await saveTable(
868
918
  storeTableName,
@@ -876,9 +926,10 @@ const createJsonPersister = (
876
926
  true,
877
927
  );
878
928
  });
879
- const destroy = () => {
880
- persister.stopAutoLoad().stopAutoSave();
881
- destroyImpl();
929
+ const destroy = async () => {
930
+ await persister.stopAutoLoad();
931
+ await persister.stopAutoSave();
932
+ extraDestroy();
882
933
  return persister;
883
934
  };
884
935
  const persister = createCustomPersister(
@@ -902,7 +953,7 @@ const createTabularPersister = (
902
953
  addPersisterListener,
903
954
  delPersisterListener,
904
955
  onIgnoredError,
905
- destroyImpl,
956
+ extraDestroy,
906
957
  persist,
907
958
  [
908
959
  tablesLoadConfig,
@@ -929,12 +980,18 @@ const createTabularPersister = (
929
980
  encode,
930
981
  decode,
931
982
  );
932
- const saveTables = async (tables, partial) =>
933
- await promiseAll(
983
+ const saveTables = (tables, partial) =>
984
+ promiseAll(
934
985
  mapMap(
935
986
  tablesSaveConfig,
936
987
  async (
937
- [tableName, rowIdColumnName, deleteEmptyColumns, deleteEmptyTable],
988
+ [
989
+ tableName,
990
+ rowIdColumnName,
991
+ deleteEmptyColumns,
992
+ deleteEmptyTable,
993
+ condition,
994
+ ],
938
995
  tableId,
939
996
  ) => {
940
997
  if (!partial || objHas(tables, tableId)) {
@@ -945,6 +1002,7 @@ const createTabularPersister = (
945
1002
  deleteEmptyColumns,
946
1003
  deleteEmptyTable,
947
1004
  partial,
1005
+ condition,
948
1006
  );
949
1007
  }
950
1008
  },
@@ -967,9 +1025,9 @@ const createTabularPersister = (
967
1025
  await promiseAll(
968
1026
  mapMap(
969
1027
  tablesLoadConfig,
970
- async ([tableId, rowIdColumnName], tableName) => [
1028
+ async ([tableId, rowIdColumnName, condition], tableName) => [
971
1029
  tableId,
972
- await loadTable(tableName, rowIdColumnName),
1030
+ await loadTable(tableName, rowIdColumnName, condition),
973
1031
  ],
974
1032
  ),
975
1033
  ),
@@ -982,8 +1040,8 @@ const createTabularPersister = (
982
1040
  SINGLE_ROW_ID
983
1041
  ]
984
1042
  : {};
985
- const getPersisted = async () =>
986
- await transaction(async () => {
1043
+ const getPersisted = () =>
1044
+ transaction(async () => {
987
1045
  await refreshSchema();
988
1046
  const tables = await loadTables();
989
1047
  const values = await loadValues();
@@ -991,8 +1049,8 @@ const createTabularPersister = (
991
1049
  ? [tables, values]
992
1050
  : void 0;
993
1051
  });
994
- const setPersisted = async (getContent, changes) =>
995
- await transaction(async () => {
1052
+ const setPersisted = (getContent, changes) =>
1053
+ transaction(async () => {
996
1054
  await refreshSchema();
997
1055
  if (!isUndefined(changes)) {
998
1056
  await saveTables(changes[0], true);
@@ -1003,9 +1061,10 @@ const createTabularPersister = (
1003
1061
  await saveValues(values);
1004
1062
  }
1005
1063
  });
1006
- const destroy = () => {
1007
- persister.stopAutoLoad().stopAutoSave();
1008
- destroyImpl();
1064
+ const destroy = async () => {
1065
+ await persister.stopAutoLoad();
1066
+ await persister.stopAutoSave();
1067
+ extraDestroy();
1009
1068
  return persister;
1010
1069
  };
1011
1070
  const persister = createCustomPersister(
@@ -1023,10 +1082,9 @@ const createTabularPersister = (
1023
1082
  return persister;
1024
1083
  };
1025
1084
 
1026
- const EVENT_CHANNEL = TINYBASE;
1085
+ const TABLE_CREATED = 'c';
1086
+ const DATA_CHANGED = 'd';
1027
1087
  const EVENT_REGEX = /^([cd]:)(.+)/;
1028
- const CHANGE_DATA_TRIGGER = TINYBASE + '_data';
1029
- const CREATE_TABLE_TRIGGER = TINYBASE + '_table';
1030
1088
  const createCustomPostgreSqlPersister = (
1031
1089
  store,
1032
1090
  configOrStoreTableName,
@@ -1044,53 +1102,125 @@ const createCustomPostgreSqlPersister = (
1044
1102
  const [isJson, , defaultedConfig, managedTableNamesSet] = getConfigStructures(
1045
1103
  configOrStoreTableName,
1046
1104
  );
1047
- const addDataTrigger = async (tableName) => {
1105
+ const configHash =
1106
+ EMPTY_STRING + getHash(jsonStringWithUndefined(defaultedConfig));
1107
+ const channel = TINYBASE + '_' + configHash;
1108
+ const createFunction = async (
1109
+ name,
1110
+ body,
1111
+ returnPrefix = '',
1112
+ declarations = '',
1113
+ ) => {
1114
+ const escapedFunctionName = escapeIds(TINYBASE, name, configHash);
1048
1115
  await executeCommand(
1049
- // eslint-disable-next-line max-len
1050
- `CREATE OR REPLACE TRIGGER ${escapeId(CHANGE_DATA_TRIGGER + '_' + tableName)} AFTER INSERT OR UPDATE OR DELETE ON ${escapeId(tableName)} EXECUTE FUNCTION ${CHANGE_DATA_TRIGGER}()`,
1116
+ CREATE +
1117
+ OR_REPLACE +
1118
+ FUNCTION +
1119
+ escapedFunctionName +
1120
+ `()RETURNS ${returnPrefix}trigger AS $$ ${declarations}BEGIN ${body}END;$$ LANGUAGE plpgsql;`,
1051
1121
  );
1122
+ return escapedFunctionName;
1052
1123
  };
1053
- const addPersisterListener = async (listener) => {
1124
+ const createTrigger = async (
1125
+ prefix,
1126
+ escapedTriggerName,
1127
+ body,
1128
+ escapedFunctionName,
1129
+ ) => {
1054
1130
  await executeCommand(
1055
- // eslint-disable-next-line max-len
1056
- `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;`,
1131
+ CREATE +
1132
+ prefix +
1133
+ 'TRIGGER' +
1134
+ escapedTriggerName +
1135
+ body +
1136
+ 'EXECUTE ' +
1137
+ FUNCTION +
1138
+ escapedFunctionName +
1139
+ `()`,
1057
1140
  );
1058
- try {
1059
- await executeCommand(
1060
- // eslint-disable-next-line max-len
1061
- `CREATE EVENT TRIGGER ${CREATE_TABLE_TRIGGER} ON ddl_command_end WHEN TAG IN('CREATE TABLE')EXECUTE FUNCTION ${CREATE_TABLE_TRIGGER}();`,
1062
- );
1063
- } catch {}
1064
- await executeCommand(
1141
+ return escapedTriggerName;
1142
+ };
1143
+ const notify = (message) => `PERFORM pg_notify('${channel}',${message});`;
1144
+ const when = (tableName, newOrOldOrBoth) =>
1145
+ isJson
1146
+ ? TRUE
1147
+ : newOrOldOrBoth === 2
1148
+ ? when(tableName, 0) + ' OR ' + when(tableName, 1)
1149
+ : strReplace(
1150
+ mapGet(defaultedConfig[0], tableName)?.[2] ?? TRUE,
1151
+ TABLE_NAME_PLACEHOLDER,
1152
+ newOrOldOrBoth == 0 ? 'NEW' : 'OLD',
1153
+ );
1154
+ const addDataChangedTriggers = (tableName, dataChangedFunction) =>
1155
+ promiseAll(
1156
+ arrayMap([INSERT, DELETE, UPDATE], (action, newOrOldOrBoth) =>
1157
+ createTrigger(
1158
+ OR_REPLACE,
1159
+ escapeIds(TINYBASE, DATA_CHANGED, configHash, tableName, action),
1160
+ `AFTER ${action} ON${escapeId(tableName)}FOR EACH ROW WHEN(${when(
1161
+ tableName,
1162
+ newOrOldOrBoth,
1163
+ )})`,
1164
+ dataChangedFunction,
1165
+ ),
1166
+ ),
1167
+ );
1168
+ const addPersisterListener = async (listener) => {
1169
+ const tableCreatedFunctionName = await createFunction(
1170
+ TABLE_CREATED,
1065
1171
  // eslint-disable-next-line max-len
1066
- `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;`,
1172
+ `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;`,
1173
+ 'event_',
1174
+ 'DECLARE row record;',
1175
+ );
1176
+ await createTrigger(
1177
+ 'EVENT ',
1178
+ escapeIds(TINYBASE, TABLE_CREATED, configHash),
1179
+ `ON ddl_command_end WHEN TAG IN('${CREATE_TABLE}')`,
1180
+ tableCreatedFunctionName,
1181
+ );
1182
+ const dataChangedFunctionName = await createFunction(
1183
+ DATA_CHANGED,
1184
+ notify(`'d:'||TG_TABLE_NAME`) + `RETURN NULL;`,
1067
1185
  );
1068
1186
  await promiseAll(
1069
1187
  arrayMap(collValues(managedTableNamesSet), async (tableName) => {
1070
1188
  await executeCommand(
1071
- // eslint-disable-next-line max-len
1072
- `CREATE TABLE IF NOT EXISTS ${escapeId(tableName)}("_id"text PRIMARY KEY)`,
1189
+ CREATE_TABLE +
1190
+ ` IF NOT EXISTS${escapeId(tableName)}("_id"text PRIMARY KEY)`,
1073
1191
  );
1074
- await addDataTrigger(tableName);
1192
+ return await addDataChangedTriggers(tableName, dataChangedFunctionName);
1075
1193
  }),
1076
1194
  );
1077
- return await addChangeListener(
1078
- EVENT_CHANNEL,
1079
- async (prefixAndTableName) =>
1080
- await ifNotUndefined(
1195
+ const listenerHandle = await addChangeListener(
1196
+ channel,
1197
+ (prefixAndTableName) =>
1198
+ ifNotUndefined(
1081
1199
  strMatch(prefixAndTableName, EVENT_REGEX),
1082
1200
  async ([, eventType, tableName]) => {
1083
1201
  if (collHas(managedTableNamesSet, tableName)) {
1084
1202
  if (eventType == 'c:') {
1085
- await addDataTrigger(tableName);
1203
+ await addDataChangedTriggers(
1204
+ tableName,
1205
+ dataChangedFunctionName,
1206
+ );
1086
1207
  }
1087
1208
  listener();
1088
1209
  }
1089
1210
  },
1090
1211
  ),
1091
1212
  );
1213
+ return [
1214
+ listenerHandle,
1215
+ [tableCreatedFunctionName, dataChangedFunctionName],
1216
+ ];
1217
+ };
1218
+ const delPersisterListener = async ([listenerHandle, functionNames]) => {
1219
+ delChangeListener(listenerHandle);
1220
+ await executeCommand(
1221
+ `DROP FUNCTION IF EXISTS${arrayJoin(functionNames, ',')}CASCADE`,
1222
+ );
1092
1223
  };
1093
- const delPersisterListener = delChangeListener;
1094
1224
  return (isJson ? createJsonPersister : createTabularPersister)(
1095
1225
  store,
1096
1226
  executeCommand,
@@ -1103,8 +1233,8 @@ const createCustomPostgreSqlPersister = (
1103
1233
  collValues(managedTableNamesSet),
1104
1234
  async (executeCommand2, managedTableNames) =>
1105
1235
  await executeCommand2(
1106
- // eslint-disable-next-line max-len
1107
- `${SELECT} table_name tn,column_name cn FROM information_schema.columns ${WHERE} table_schema='public'AND table_name IN(${getPlaceholders(managedTableNames)})`,
1236
+ SELECT + // eslint-disable-next-line max-len
1237
+ ` table_name tn,column_name cn FROM information_schema.columns ${WHERE} table_schema='public'AND table_name IN(${getPlaceholders(managedTableNames)})`,
1108
1238
  managedTableNames,
1109
1239
  ),
1110
1240
  thing,
@@ -1143,22 +1273,24 @@ const createCustomSqlitePersister = (
1143
1273
  const addPersisterListener = (listener) => {
1144
1274
  let interval;
1145
1275
  const startPolling = () =>
1146
- (interval = startInterval(async () => {
1147
- try {
1148
- const [{d, s, c}] = await executeCommand(
1149
- // eslint-disable-next-line max-len
1150
- `${SELECT} ${DATA_VERSION} d,${SCHEMA_VERSION} s,TOTAL_CHANGES() c FROM ${PRAGMA}${DATA_VERSION} JOIN ${PRAGMA}${SCHEMA_VERSION}`,
1151
- );
1152
- if (d != dataVersion || s != schemaVersion || c != totalChanges) {
1153
- if (dataVersion != null) {
1154
- listener();
1276
+ (interval = startInterval(
1277
+ () =>
1278
+ tryCatch(async () => {
1279
+ const [{d, s, c}] = await executeCommand(
1280
+ SELECT + // eslint-disable-next-line max-len
1281
+ ` ${DATA_VERSION} d,${SCHEMA_VERSION} s,TOTAL_CHANGES() c FROM ${PRAGMA}${DATA_VERSION} JOIN ${PRAGMA}${SCHEMA_VERSION}`,
1282
+ );
1283
+ if (d != dataVersion || s != schemaVersion || c != totalChanges) {
1284
+ if (dataVersion != null) {
1285
+ listener();
1286
+ }
1287
+ dataVersion = d;
1288
+ schemaVersion = s;
1289
+ totalChanges = c;
1155
1290
  }
1156
- dataVersion = d;
1157
- schemaVersion = s;
1158
- totalChanges = c;
1159
- }
1160
- } catch {}
1161
- }, autoLoadIntervalSeconds));
1291
+ }),
1292
+ autoLoadIntervalSeconds,
1293
+ ));
1162
1294
  const stopPolling = () => {
1163
1295
  dataVersion = schemaVersion = totalChanges = null;
1164
1296
  stopInterval(interval);
@@ -1190,8 +1322,8 @@ const createCustomSqlitePersister = (
1190
1322
  collValues(managedTableNamesSet),
1191
1323
  async (executeCommand2, managedTableNames) =>
1192
1324
  await executeCommand2(
1193
- // eslint-disable-next-line max-len
1194
- `${SELECT} t.name tn,c.name cn ${FROM}${PRAGMA_TABLE}list()t,${PRAGMA_TABLE}info(t.name)c ${WHERE} t.schema='main'AND t.type IN('table','view')AND t.name IN(${getPlaceholders(managedTableNames)})ORDER BY t.name,c.name`,
1325
+ SELECT + // eslint-disable-next-line max-len
1326
+ ` t.name tn,c.name cn FROM ${PRAGMA_TABLE}list()t,${PRAGMA_TABLE}info(t.name)c ${WHERE} t.schema='main'AND t.type IN('table','view')AND t.name IN(${getPlaceholders(managedTableNames)})ORDER BY t.name,c.name`,
1195
1327
  managedTableNames,
1196
1328
  ),
1197
1329
  thing,