tinybase 4.0.3 → 4.0.4

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 (165) hide show
  1. package/lib/cjs/persisters/persister-automerge.cjs +1 -1
  2. package/lib/cjs/persisters/persister-automerge.cjs.gz +0 -0
  3. package/lib/cjs/persisters/persister-browser.cjs +1 -1
  4. package/lib/cjs/persisters/persister-browser.cjs.gz +0 -0
  5. package/lib/cjs/persisters/persister-cr-sqlite-wasm.cjs +1 -1
  6. package/lib/cjs/persisters/persister-cr-sqlite-wasm.cjs.gz +0 -0
  7. package/lib/cjs/persisters/persister-expo-sqlite.cjs +1 -1
  8. package/lib/cjs/persisters/persister-expo-sqlite.cjs.gz +0 -0
  9. package/lib/cjs/persisters/persister-file.cjs +1 -1
  10. package/lib/cjs/persisters/persister-file.cjs.gz +0 -0
  11. package/lib/cjs/persisters/persister-remote.cjs +1 -1
  12. package/lib/cjs/persisters/persister-remote.cjs.gz +0 -0
  13. package/lib/cjs/persisters/persister-sqlite-wasm.cjs +1 -1
  14. package/lib/cjs/persisters/persister-sqlite-wasm.cjs.gz +0 -0
  15. package/lib/cjs/persisters/persister-sqlite3.cjs +1 -1
  16. package/lib/cjs/persisters/persister-sqlite3.cjs.gz +0 -0
  17. package/lib/cjs/persisters/persister-yjs.cjs +1 -1
  18. package/lib/cjs/persisters/persister-yjs.cjs.gz +0 -0
  19. package/lib/cjs/persisters.cjs +1 -1
  20. package/lib/cjs/persisters.cjs.gz +0 -0
  21. package/lib/cjs/tinybase.cjs +1 -1
  22. package/lib/cjs/tinybase.cjs.gz +0 -0
  23. package/lib/cjs-es6/persisters/persister-automerge.cjs +1 -1
  24. package/lib/cjs-es6/persisters/persister-automerge.cjs.gz +0 -0
  25. package/lib/cjs-es6/persisters/persister-browser.cjs +1 -1
  26. package/lib/cjs-es6/persisters/persister-browser.cjs.gz +0 -0
  27. package/lib/cjs-es6/persisters/persister-cr-sqlite-wasm.cjs +1 -1
  28. package/lib/cjs-es6/persisters/persister-cr-sqlite-wasm.cjs.gz +0 -0
  29. package/lib/cjs-es6/persisters/persister-expo-sqlite.cjs +1 -1
  30. package/lib/cjs-es6/persisters/persister-expo-sqlite.cjs.gz +0 -0
  31. package/lib/cjs-es6/persisters/persister-file.cjs +1 -1
  32. package/lib/cjs-es6/persisters/persister-file.cjs.gz +0 -0
  33. package/lib/cjs-es6/persisters/persister-remote.cjs +1 -1
  34. package/lib/cjs-es6/persisters/persister-remote.cjs.gz +0 -0
  35. package/lib/cjs-es6/persisters/persister-sqlite-wasm.cjs +1 -1
  36. package/lib/cjs-es6/persisters/persister-sqlite-wasm.cjs.gz +0 -0
  37. package/lib/cjs-es6/persisters/persister-sqlite3.cjs +1 -1
  38. package/lib/cjs-es6/persisters/persister-sqlite3.cjs.gz +0 -0
  39. package/lib/cjs-es6/persisters/persister-yjs.cjs +1 -1
  40. package/lib/cjs-es6/persisters/persister-yjs.cjs.gz +0 -0
  41. package/lib/cjs-es6/persisters.cjs +1 -1
  42. package/lib/cjs-es6/persisters.cjs.gz +0 -0
  43. package/lib/cjs-es6/tinybase.cjs +1 -1
  44. package/lib/cjs-es6/tinybase.cjs.gz +0 -0
  45. package/lib/debug/persisters/persister-automerge.js +56 -18
  46. package/lib/debug/persisters/persister-browser.js +55 -22
  47. package/lib/debug/persisters/persister-cr-sqlite-wasm.js +106 -62
  48. package/lib/debug/persisters/persister-expo-sqlite.js +111 -62
  49. package/lib/debug/persisters/persister-file.js +51 -18
  50. package/lib/debug/persisters/persister-remote.js +51 -17
  51. package/lib/debug/persisters/persister-sqlite-wasm.js +106 -62
  52. package/lib/debug/persisters/persister-sqlite3.js +111 -62
  53. package/lib/debug/persisters/persister-yjs.js +63 -27
  54. package/lib/debug/persisters.js +49 -17
  55. package/lib/debug/tinybase.js +35 -17
  56. package/lib/es6/persisters/persister-automerge.js +1 -1
  57. package/lib/es6/persisters/persister-automerge.js.gz +0 -0
  58. package/lib/es6/persisters/persister-browser.js +1 -1
  59. package/lib/es6/persisters/persister-browser.js.gz +0 -0
  60. package/lib/es6/persisters/persister-cr-sqlite-wasm.js +1 -1
  61. package/lib/es6/persisters/persister-cr-sqlite-wasm.js.gz +0 -0
  62. package/lib/es6/persisters/persister-expo-sqlite.js +1 -1
  63. package/lib/es6/persisters/persister-expo-sqlite.js.gz +0 -0
  64. package/lib/es6/persisters/persister-file.js +1 -1
  65. package/lib/es6/persisters/persister-file.js.gz +0 -0
  66. package/lib/es6/persisters/persister-remote.js +1 -1
  67. package/lib/es6/persisters/persister-remote.js.gz +0 -0
  68. package/lib/es6/persisters/persister-sqlite-wasm.js +1 -1
  69. package/lib/es6/persisters/persister-sqlite-wasm.js.gz +0 -0
  70. package/lib/es6/persisters/persister-sqlite3.js +1 -1
  71. package/lib/es6/persisters/persister-sqlite3.js.gz +0 -0
  72. package/lib/es6/persisters/persister-yjs.js +1 -1
  73. package/lib/es6/persisters/persister-yjs.js.gz +0 -0
  74. package/lib/es6/persisters.js +1 -1
  75. package/lib/es6/persisters.js.gz +0 -0
  76. package/lib/es6/tinybase.js +1 -1
  77. package/lib/es6/tinybase.js.gz +0 -0
  78. package/lib/persisters/persister-automerge.js +1 -1
  79. package/lib/persisters/persister-automerge.js.gz +0 -0
  80. package/lib/persisters/persister-browser.js +1 -1
  81. package/lib/persisters/persister-browser.js.gz +0 -0
  82. package/lib/persisters/persister-cr-sqlite-wasm.js +1 -1
  83. package/lib/persisters/persister-cr-sqlite-wasm.js.gz +0 -0
  84. package/lib/persisters/persister-expo-sqlite.js +1 -1
  85. package/lib/persisters/persister-expo-sqlite.js.gz +0 -0
  86. package/lib/persisters/persister-file.js +1 -1
  87. package/lib/persisters/persister-file.js.gz +0 -0
  88. package/lib/persisters/persister-remote.js +1 -1
  89. package/lib/persisters/persister-remote.js.gz +0 -0
  90. package/lib/persisters/persister-sqlite-wasm.js +1 -1
  91. package/lib/persisters/persister-sqlite-wasm.js.gz +0 -0
  92. package/lib/persisters/persister-sqlite3.js +1 -1
  93. package/lib/persisters/persister-sqlite3.js.gz +0 -0
  94. package/lib/persisters/persister-yjs.js +1 -1
  95. package/lib/persisters/persister-yjs.js.gz +0 -0
  96. package/lib/persisters.js +1 -1
  97. package/lib/persisters.js.gz +0 -0
  98. package/lib/tinybase.js +1 -1
  99. package/lib/tinybase.js.gz +0 -0
  100. package/lib/types/persisters/persister-automerge.d.ts +4 -0
  101. package/lib/types/persisters/persister-browser.d.ts +8 -0
  102. package/lib/types/persisters/persister-cr-sqlite-wasm.d.ts +10 -2
  103. package/lib/types/persisters/persister-expo-sqlite.d.ts +8 -0
  104. package/lib/types/persisters/persister-file.d.ts +8 -1
  105. package/lib/types/persisters/persister-remote.d.ts +4 -0
  106. package/lib/types/persisters/persister-sqlite-wasm.d.ts +8 -0
  107. package/lib/types/persisters/persister-sqlite3.d.ts +8 -0
  108. package/lib/types/persisters/persister-yjs.d.ts +4 -0
  109. package/lib/types/persisters.d.ts +16 -3
  110. package/lib/types/with-schemas/persisters/persister-automerge.d.ts +5 -0
  111. package/lib/types/with-schemas/persisters/persister-browser.d.ts +10 -0
  112. package/lib/types/with-schemas/persisters/persister-cr-sqlite-wasm.d.ts +12 -2
  113. package/lib/types/with-schemas/persisters/persister-expo-sqlite.d.ts +10 -0
  114. package/lib/types/with-schemas/persisters/persister-file.d.ts +9 -1
  115. package/lib/types/with-schemas/persisters/persister-remote.d.ts +5 -0
  116. package/lib/types/with-schemas/persisters/persister-sqlite-wasm.d.ts +10 -0
  117. package/lib/types/with-schemas/persisters/persister-sqlite3.d.ts +10 -0
  118. package/lib/types/with-schemas/persisters/persister-yjs.d.ts +5 -0
  119. package/lib/types/with-schemas/persisters.d.ts +17 -3
  120. package/lib/umd/persisters/persister-automerge.js +1 -1
  121. package/lib/umd/persisters/persister-automerge.js.gz +0 -0
  122. package/lib/umd/persisters/persister-browser.js +1 -1
  123. package/lib/umd/persisters/persister-browser.js.gz +0 -0
  124. package/lib/umd/persisters/persister-cr-sqlite-wasm.js +1 -1
  125. package/lib/umd/persisters/persister-cr-sqlite-wasm.js.gz +0 -0
  126. package/lib/umd/persisters/persister-expo-sqlite.js +1 -1
  127. package/lib/umd/persisters/persister-expo-sqlite.js.gz +0 -0
  128. package/lib/umd/persisters/persister-file.js +1 -1
  129. package/lib/umd/persisters/persister-file.js.gz +0 -0
  130. package/lib/umd/persisters/persister-remote.js +1 -1
  131. package/lib/umd/persisters/persister-remote.js.gz +0 -0
  132. package/lib/umd/persisters/persister-sqlite-wasm.js +1 -1
  133. package/lib/umd/persisters/persister-sqlite-wasm.js.gz +0 -0
  134. package/lib/umd/persisters/persister-sqlite3.js +1 -1
  135. package/lib/umd/persisters/persister-sqlite3.js.gz +0 -0
  136. package/lib/umd/persisters/persister-yjs.js +1 -1
  137. package/lib/umd/persisters/persister-yjs.js.gz +0 -0
  138. package/lib/umd/persisters.js +1 -1
  139. package/lib/umd/persisters.js.gz +0 -0
  140. package/lib/umd/tinybase.js +1 -1
  141. package/lib/umd/tinybase.js.gz +0 -0
  142. package/lib/umd-es6/persisters/persister-automerge.js +1 -1
  143. package/lib/umd-es6/persisters/persister-automerge.js.gz +0 -0
  144. package/lib/umd-es6/persisters/persister-browser.js +1 -1
  145. package/lib/umd-es6/persisters/persister-browser.js.gz +0 -0
  146. package/lib/umd-es6/persisters/persister-cr-sqlite-wasm.js +1 -1
  147. package/lib/umd-es6/persisters/persister-cr-sqlite-wasm.js.gz +0 -0
  148. package/lib/umd-es6/persisters/persister-expo-sqlite.js +1 -1
  149. package/lib/umd-es6/persisters/persister-expo-sqlite.js.gz +0 -0
  150. package/lib/umd-es6/persisters/persister-file.js +1 -1
  151. package/lib/umd-es6/persisters/persister-file.js.gz +0 -0
  152. package/lib/umd-es6/persisters/persister-remote.js +1 -1
  153. package/lib/umd-es6/persisters/persister-remote.js.gz +0 -0
  154. package/lib/umd-es6/persisters/persister-sqlite-wasm.js +1 -1
  155. package/lib/umd-es6/persisters/persister-sqlite-wasm.js.gz +0 -0
  156. package/lib/umd-es6/persisters/persister-sqlite3.js +1 -1
  157. package/lib/umd-es6/persisters/persister-sqlite3.js.gz +0 -0
  158. package/lib/umd-es6/persisters/persister-yjs.js +1 -1
  159. package/lib/umd-es6/persisters/persister-yjs.js.gz +0 -0
  160. package/lib/umd-es6/persisters.js +1 -1
  161. package/lib/umd-es6/persisters.js.gz +0 -0
  162. package/lib/umd-es6/tinybase.js +1 -1
  163. package/lib/umd-es6/tinybase.js.gz +0 -0
  164. package/package.json +5 -5
  165. package/readme.md +2 -2
@@ -83,7 +83,7 @@ const escapeId = (str) => `"${str.replace(/"/g, '""')}"`;
83
83
  const SELECT_STAR_FROM = 'SELECT*FROM';
84
84
  const FROM_PRAGMA_TABLE = 'FROM pragma_table_';
85
85
  const WHERE = 'WHERE';
86
- const getCommandFunctions = (cmd, managedTableNames) => {
86
+ const getCommandFunctions = (cmd, managedTableNames, onIgnoredError) => {
87
87
  const schemaMap = mapNew();
88
88
  const canSelect = (tableName, rowIdColumnName) =>
89
89
  !isUndefined(mapGet(mapGet(schemaMap, tableName), rowIdColumnName));
@@ -281,7 +281,18 @@ const getCommandFunctions = (cmd, managedTableNames) => {
281
281
  }
282
282
  }
283
283
  };
284
- return [refreshSchema, loadTable, saveTable];
284
+ const transaction = async (actions) => {
285
+ let result;
286
+ await cmd('BEGIN');
287
+ try {
288
+ result = await actions();
289
+ } catch (error) {
290
+ onIgnoredError?.(error);
291
+ }
292
+ await cmd('END');
293
+ return result;
294
+ };
295
+ return [refreshSchema, loadTable, saveTable, transaction];
285
296
  };
286
297
  const upsert = async (
287
298
  cmd,
@@ -331,32 +342,41 @@ const jsonString = (obj) =>
331
342
  );
332
343
  const jsonParse = JSON.parse;
333
344
 
345
+ const scheduleRunning = mapNew();
346
+ const scheduleActions = mapNew();
334
347
  const createCustomPersister = (
335
348
  store,
336
349
  getPersisted,
337
350
  setPersisted,
338
351
  addPersisterListener,
339
352
  delPersisterListener,
353
+ onIgnoredError,
354
+ scheduleId = [],
340
355
  ) => {
341
356
  let listenerId;
342
357
  let loadSave = 0;
343
358
  let loads = 0;
344
359
  let saves = 0;
345
- let running = 0;
346
360
  let listening = 0;
347
361
  let action;
348
362
  let listeningHandle;
349
- const scheduledActions = [];
363
+ mapEnsure(scheduleRunning, scheduleId, () => 0);
364
+ mapEnsure(scheduleActions, scheduleId, () => []);
350
365
  const run = async () => {
351
366
  /* istanbul ignore else */
352
- if (!running) {
353
- running = 1;
354
- while (!isUndefined((action = arrayShift(scheduledActions)))) {
367
+ if (!mapGet(scheduleRunning, scheduleId)) {
368
+ mapSet(scheduleRunning, scheduleId, 1);
369
+ while (
370
+ !isUndefined((action = arrayShift(mapGet(scheduleActions, scheduleId))))
371
+ ) {
355
372
  try {
356
373
  await action();
357
- } catch {}
374
+ } catch (error) {
375
+ /* istanbul ignore next */
376
+ onIgnoredError?.(error);
377
+ }
358
378
  }
359
- running = 0;
379
+ mapSet(scheduleRunning, scheduleId, 0);
360
380
  }
361
381
  };
362
382
  const loadLock = async (actions) => {
@@ -387,16 +407,22 @@ const createCustomPersister = (
387
407
  await persister.load(initialTables, initialValues);
388
408
  listening = 1;
389
409
  listeningHandle = addPersisterListener(
390
- async (getContent, getTransactionChanges) =>
391
- await loadLock(async () => {
392
- if (getTransactionChanges) {
393
- store.setTransactionChanges(getTransactionChanges());
394
- } else {
410
+ async (getContent, getTransactionChanges) => {
411
+ if (getTransactionChanges) {
412
+ const transactionChanges = getTransactionChanges();
413
+ await loadLock(async () =>
414
+ store.setTransactionChanges(transactionChanges),
415
+ );
416
+ } else {
417
+ await loadLock(async () => {
395
418
  try {
396
419
  store.setContent(getContent?.() ?? (await getPersisted()));
397
- } catch {}
398
- }
399
- }),
420
+ } catch (error) {
421
+ onIgnoredError?.(error);
422
+ }
423
+ });
424
+ }
425
+ },
400
426
  );
401
427
  return persister;
402
428
  },
@@ -418,7 +444,10 @@ const createCustomPersister = (
418
444
  await persister.schedule(async () => {
419
445
  try {
420
446
  await setPersisted(store.getContent, getTransactionChanges);
421
- } catch {}
447
+ } catch (error) {
448
+ /* istanbul ignore next */
449
+ onIgnoredError?.(error);
450
+ }
422
451
  loadSave = 0;
423
452
  });
424
453
  }
@@ -441,7 +470,7 @@ const createCustomPersister = (
441
470
  return persister;
442
471
  },
443
472
  schedule: async (...actions) => {
444
- arrayPush(scheduledActions, ...actions);
473
+ arrayPush(mapGet(scheduleActions, scheduleId), ...actions);
445
474
  await run();
446
475
  return persister;
447
476
  },
@@ -458,28 +487,30 @@ const createJsonSqlitePersister = (
458
487
  cmd,
459
488
  addPersisterListener,
460
489
  delPersisterListener,
490
+ onIgnoredError,
461
491
  [storeTableName],
462
492
  managedTableNames,
493
+ scheduleId,
463
494
  ) => {
464
- const [refreshSchema, loadTable, saveTable] = getCommandFunctions(
465
- cmd,
466
- managedTableNames,
467
- );
468
- const getPersisted = async () => {
469
- await refreshSchema();
470
- return jsonParse(
471
- (await loadTable(storeTableName, DEFAULT_ROW_ID_COLUMN_NAME))[
472
- SINGLE_ROW_ID
473
- ]?.[STORE_COLUMN],
474
- );
475
- };
495
+ const [refreshSchema, loadTable, saveTable, transaction] =
496
+ getCommandFunctions(cmd, managedTableNames, onIgnoredError);
497
+ const getPersisted = async () =>
498
+ await transaction(async () => {
499
+ await refreshSchema();
500
+ return jsonParse(
501
+ (await loadTable(storeTableName, DEFAULT_ROW_ID_COLUMN_NAME))[
502
+ SINGLE_ROW_ID
503
+ ]?.[STORE_COLUMN] ?? 'null',
504
+ );
505
+ });
476
506
  const setPersisted = async (getContent) =>
477
- persister.schedule(refreshSchema, async () => {
507
+ await transaction(async () => {
508
+ await refreshSchema();
478
509
  await saveTable(
479
510
  storeTableName,
480
511
  DEFAULT_ROW_ID_COLUMN_NAME,
481
512
  {
482
- [SINGLE_ROW_ID]: {[STORE_COLUMN]: jsonString(getContent())},
513
+ [SINGLE_ROW_ID]: {[STORE_COLUMN]: jsonString(getContent() ?? null)},
483
514
  },
484
515
  true,
485
516
  true,
@@ -491,6 +522,8 @@ const createJsonSqlitePersister = (
491
522
  setPersisted,
492
523
  addPersisterListener,
493
524
  delPersisterListener,
525
+ onIgnoredError,
526
+ scheduleId,
494
527
  );
495
528
  return persister;
496
529
  };
@@ -500,17 +533,17 @@ const createTabularSqlitePersister = (
500
533
  cmd,
501
534
  addPersisterListener,
502
535
  delPersisterListener,
536
+ onIgnoredError,
503
537
  [
504
538
  tablesLoadConfig,
505
539
  tablesSaveConfig,
506
540
  [valuesLoad, valuesSave, valuesTableName],
507
541
  ],
508
542
  managedTableNames,
543
+ scheduleId,
509
544
  ) => {
510
- const [refreshSchema, loadTable, saveTable] = getCommandFunctions(
511
- cmd,
512
- managedTableNames,
513
- );
545
+ const [refreshSchema, loadTable, saveTable, transaction] =
546
+ getCommandFunctions(cmd, managedTableNames, onIgnoredError);
514
547
  const saveTables = async (tables, partial) =>
515
548
  await promiseAll(
516
549
  mapMap(
@@ -565,32 +598,36 @@ const createTabularSqlitePersister = (
565
598
  SINGLE_ROW_ID
566
599
  ]
567
600
  : {};
568
- const getPersisted = async () => {
569
- await refreshSchema();
570
- const tables = await loadTables();
571
- const values = await loadValues();
572
- return !objIsEmpty(tables) || !isUndefined(values)
573
- ? [tables, values]
574
- : void 0;
575
- };
576
- const setPersisted = async (getContent, getTransactionChanges) => {
577
- await refreshSchema();
578
- if (!isUndefined(getTransactionChanges)) {
579
- const [tableChanges, valueChanges] = getTransactionChanges();
580
- await saveTables(tableChanges, true);
581
- await saveValues(valueChanges, true);
582
- } else {
583
- const [tables, values] = getContent();
584
- await saveTables(tables);
585
- await saveValues(values);
586
- }
587
- };
601
+ const getPersisted = async () =>
602
+ await transaction(async () => {
603
+ await refreshSchema();
604
+ const tables = await loadTables();
605
+ const values = await loadValues();
606
+ return !objIsEmpty(tables) || !isUndefined(values)
607
+ ? [tables, values]
608
+ : void 0;
609
+ });
610
+ const setPersisted = async (getContent, getTransactionChanges) =>
611
+ await transaction(async () => {
612
+ await refreshSchema();
613
+ if (!isUndefined(getTransactionChanges)) {
614
+ const [tableChanges, valueChanges] = getTransactionChanges();
615
+ await saveTables(tableChanges, true);
616
+ await saveValues(valueChanges, true);
617
+ } else {
618
+ const [tables, values] = getContent();
619
+ await saveTables(tables);
620
+ await saveValues(values);
621
+ }
622
+ });
588
623
  const persister = createCustomPersister(
589
624
  store,
590
625
  getPersisted,
591
626
  setPersisted,
592
627
  addPersisterListener,
593
628
  delPersisterListener,
629
+ onIgnoredError,
630
+ scheduleId,
594
631
  );
595
632
  return persister;
596
633
  };
@@ -697,7 +734,9 @@ const createSqlitePersister = (
697
734
  cmd,
698
735
  addUpdateListener,
699
736
  delUpdateListener,
700
- logSql,
737
+ onSqlCommand,
738
+ onIgnoredError,
739
+ scheduleId,
701
740
  ) => {
702
741
  let dataVersion;
703
742
  let schemaVersion;
@@ -737,16 +776,18 @@ const createSqlitePersister = (
737
776
  };
738
777
  return (isJson ? createJsonSqlitePersister : createTabularSqlitePersister)(
739
778
  store,
740
- logSql
779
+ onSqlCommand
741
780
  ? async (sql, args) => {
742
- logSql(sql, args);
781
+ onSqlCommand(sql, args);
743
782
  return await cmd(sql, args);
744
783
  }
745
784
  : cmd,
746
785
  addPersisterListener,
747
786
  delPersisterListener,
787
+ onIgnoredError,
748
788
  defaultedConfig,
749
789
  collValues(managedTableNamesSet),
790
+ scheduleId,
750
791
  );
751
792
  };
752
793
 
@@ -755,7 +796,8 @@ const createSqliteWasmPersister = (
755
796
  sqlite3,
756
797
  db,
757
798
  configOrStoreTableName,
758
- logSql,
799
+ onSqlCommand,
800
+ onIgnoredError,
759
801
  ) =>
760
802
  createSqlitePersister(
761
803
  store,
@@ -771,7 +813,9 @@ const createSqliteWasmPersister = (
771
813
  0,
772
814
  ),
773
815
  () => sqlite3.capi.sqlite3_update_hook(db, () => 0, 0),
774
- logSql,
816
+ onSqlCommand,
817
+ onIgnoredError,
818
+ db,
775
819
  );
776
820
 
777
821
  export {createSqliteWasmPersister};
@@ -84,7 +84,7 @@ const escapeId = (str) => `"${str.replace(/"/g, '""')}"`;
84
84
  const SELECT_STAR_FROM = 'SELECT*FROM';
85
85
  const FROM_PRAGMA_TABLE = 'FROM pragma_table_';
86
86
  const WHERE = 'WHERE';
87
- const getCommandFunctions = (cmd, managedTableNames) => {
87
+ const getCommandFunctions = (cmd, managedTableNames, onIgnoredError) => {
88
88
  const schemaMap = mapNew();
89
89
  const canSelect = (tableName, rowIdColumnName) =>
90
90
  !isUndefined(mapGet(mapGet(schemaMap, tableName), rowIdColumnName));
@@ -282,7 +282,18 @@ const getCommandFunctions = (cmd, managedTableNames) => {
282
282
  }
283
283
  }
284
284
  };
285
- return [refreshSchema, loadTable, saveTable];
285
+ const transaction = async (actions) => {
286
+ let result;
287
+ await cmd('BEGIN');
288
+ try {
289
+ result = await actions();
290
+ } catch (error) {
291
+ onIgnoredError?.(error);
292
+ }
293
+ await cmd('END');
294
+ return result;
295
+ };
296
+ return [refreshSchema, loadTable, saveTable, transaction];
286
297
  };
287
298
  const upsert = async (
288
299
  cmd,
@@ -332,32 +343,41 @@ const jsonString = (obj) =>
332
343
  );
333
344
  const jsonParse = JSON.parse;
334
345
 
346
+ const scheduleRunning = mapNew();
347
+ const scheduleActions = mapNew();
335
348
  const createCustomPersister = (
336
349
  store,
337
350
  getPersisted,
338
351
  setPersisted,
339
352
  addPersisterListener,
340
353
  delPersisterListener,
354
+ onIgnoredError,
355
+ scheduleId = [],
341
356
  ) => {
342
357
  let listenerId;
343
358
  let loadSave = 0;
344
359
  let loads = 0;
345
360
  let saves = 0;
346
- let running = 0;
347
361
  let listening = 0;
348
362
  let action;
349
363
  let listeningHandle;
350
- const scheduledActions = [];
364
+ mapEnsure(scheduleRunning, scheduleId, () => 0);
365
+ mapEnsure(scheduleActions, scheduleId, () => []);
351
366
  const run = async () => {
352
367
  /* istanbul ignore else */
353
- if (!running) {
354
- running = 1;
355
- while (!isUndefined((action = arrayShift(scheduledActions)))) {
368
+ if (!mapGet(scheduleRunning, scheduleId)) {
369
+ mapSet(scheduleRunning, scheduleId, 1);
370
+ while (
371
+ !isUndefined((action = arrayShift(mapGet(scheduleActions, scheduleId))))
372
+ ) {
356
373
  try {
357
374
  await action();
358
- } catch {}
375
+ } catch (error) {
376
+ /* istanbul ignore next */
377
+ onIgnoredError?.(error);
378
+ }
359
379
  }
360
- running = 0;
380
+ mapSet(scheduleRunning, scheduleId, 0);
361
381
  }
362
382
  };
363
383
  const loadLock = async (actions) => {
@@ -388,16 +408,22 @@ const createCustomPersister = (
388
408
  await persister.load(initialTables, initialValues);
389
409
  listening = 1;
390
410
  listeningHandle = addPersisterListener(
391
- async (getContent, getTransactionChanges) =>
392
- await loadLock(async () => {
393
- if (getTransactionChanges) {
394
- store.setTransactionChanges(getTransactionChanges());
395
- } else {
411
+ async (getContent, getTransactionChanges) => {
412
+ if (getTransactionChanges) {
413
+ const transactionChanges = getTransactionChanges();
414
+ await loadLock(async () =>
415
+ store.setTransactionChanges(transactionChanges),
416
+ );
417
+ } else {
418
+ await loadLock(async () => {
396
419
  try {
397
420
  store.setContent(getContent?.() ?? (await getPersisted()));
398
- } catch {}
399
- }
400
- }),
421
+ } catch (error) {
422
+ onIgnoredError?.(error);
423
+ }
424
+ });
425
+ }
426
+ },
401
427
  );
402
428
  return persister;
403
429
  },
@@ -419,7 +445,10 @@ const createCustomPersister = (
419
445
  await persister.schedule(async () => {
420
446
  try {
421
447
  await setPersisted(store.getContent, getTransactionChanges);
422
- } catch {}
448
+ } catch (error) {
449
+ /* istanbul ignore next */
450
+ onIgnoredError?.(error);
451
+ }
423
452
  loadSave = 0;
424
453
  });
425
454
  }
@@ -442,7 +471,7 @@ const createCustomPersister = (
442
471
  return persister;
443
472
  },
444
473
  schedule: async (...actions) => {
445
- arrayPush(scheduledActions, ...actions);
474
+ arrayPush(mapGet(scheduleActions, scheduleId), ...actions);
446
475
  await run();
447
476
  return persister;
448
477
  },
@@ -459,28 +488,30 @@ const createJsonSqlitePersister = (
459
488
  cmd,
460
489
  addPersisterListener,
461
490
  delPersisterListener,
491
+ onIgnoredError,
462
492
  [storeTableName],
463
493
  managedTableNames,
494
+ scheduleId,
464
495
  ) => {
465
- const [refreshSchema, loadTable, saveTable] = getCommandFunctions(
466
- cmd,
467
- managedTableNames,
468
- );
469
- const getPersisted = async () => {
470
- await refreshSchema();
471
- return jsonParse(
472
- (await loadTable(storeTableName, DEFAULT_ROW_ID_COLUMN_NAME))[
473
- SINGLE_ROW_ID
474
- ]?.[STORE_COLUMN],
475
- );
476
- };
496
+ const [refreshSchema, loadTable, saveTable, transaction] =
497
+ getCommandFunctions(cmd, managedTableNames, onIgnoredError);
498
+ const getPersisted = async () =>
499
+ await transaction(async () => {
500
+ await refreshSchema();
501
+ return jsonParse(
502
+ (await loadTable(storeTableName, DEFAULT_ROW_ID_COLUMN_NAME))[
503
+ SINGLE_ROW_ID
504
+ ]?.[STORE_COLUMN] ?? 'null',
505
+ );
506
+ });
477
507
  const setPersisted = async (getContent) =>
478
- persister.schedule(refreshSchema, async () => {
508
+ await transaction(async () => {
509
+ await refreshSchema();
479
510
  await saveTable(
480
511
  storeTableName,
481
512
  DEFAULT_ROW_ID_COLUMN_NAME,
482
513
  {
483
- [SINGLE_ROW_ID]: {[STORE_COLUMN]: jsonString(getContent())},
514
+ [SINGLE_ROW_ID]: {[STORE_COLUMN]: jsonString(getContent() ?? null)},
484
515
  },
485
516
  true,
486
517
  true,
@@ -492,6 +523,8 @@ const createJsonSqlitePersister = (
492
523
  setPersisted,
493
524
  addPersisterListener,
494
525
  delPersisterListener,
526
+ onIgnoredError,
527
+ scheduleId,
495
528
  );
496
529
  return persister;
497
530
  };
@@ -501,17 +534,17 @@ const createTabularSqlitePersister = (
501
534
  cmd,
502
535
  addPersisterListener,
503
536
  delPersisterListener,
537
+ onIgnoredError,
504
538
  [
505
539
  tablesLoadConfig,
506
540
  tablesSaveConfig,
507
541
  [valuesLoad, valuesSave, valuesTableName],
508
542
  ],
509
543
  managedTableNames,
544
+ scheduleId,
510
545
  ) => {
511
- const [refreshSchema, loadTable, saveTable] = getCommandFunctions(
512
- cmd,
513
- managedTableNames,
514
- );
546
+ const [refreshSchema, loadTable, saveTable, transaction] =
547
+ getCommandFunctions(cmd, managedTableNames, onIgnoredError);
515
548
  const saveTables = async (tables, partial) =>
516
549
  await promiseAll(
517
550
  mapMap(
@@ -566,32 +599,36 @@ const createTabularSqlitePersister = (
566
599
  SINGLE_ROW_ID
567
600
  ]
568
601
  : {};
569
- const getPersisted = async () => {
570
- await refreshSchema();
571
- const tables = await loadTables();
572
- const values = await loadValues();
573
- return !objIsEmpty(tables) || !isUndefined(values)
574
- ? [tables, values]
575
- : void 0;
576
- };
577
- const setPersisted = async (getContent, getTransactionChanges) => {
578
- await refreshSchema();
579
- if (!isUndefined(getTransactionChanges)) {
580
- const [tableChanges, valueChanges] = getTransactionChanges();
581
- await saveTables(tableChanges, true);
582
- await saveValues(valueChanges, true);
583
- } else {
584
- const [tables, values] = getContent();
585
- await saveTables(tables);
586
- await saveValues(values);
587
- }
588
- };
602
+ const getPersisted = async () =>
603
+ await transaction(async () => {
604
+ await refreshSchema();
605
+ const tables = await loadTables();
606
+ const values = await loadValues();
607
+ return !objIsEmpty(tables) || !isUndefined(values)
608
+ ? [tables, values]
609
+ : void 0;
610
+ });
611
+ const setPersisted = async (getContent, getTransactionChanges) =>
612
+ await transaction(async () => {
613
+ await refreshSchema();
614
+ if (!isUndefined(getTransactionChanges)) {
615
+ const [tableChanges, valueChanges] = getTransactionChanges();
616
+ await saveTables(tableChanges, true);
617
+ await saveValues(valueChanges, true);
618
+ } else {
619
+ const [tables, values] = getContent();
620
+ await saveTables(tables);
621
+ await saveValues(values);
622
+ }
623
+ });
589
624
  const persister = createCustomPersister(
590
625
  store,
591
626
  getPersisted,
592
627
  setPersisted,
593
628
  addPersisterListener,
594
629
  delPersisterListener,
630
+ onIgnoredError,
631
+ scheduleId,
595
632
  );
596
633
  return persister;
597
634
  };
@@ -698,7 +735,9 @@ const createSqlitePersister = (
698
735
  cmd,
699
736
  addUpdateListener,
700
737
  delUpdateListener,
701
- logSql,
738
+ onSqlCommand,
739
+ onIgnoredError,
740
+ scheduleId,
702
741
  ) => {
703
742
  let dataVersion;
704
743
  let schemaVersion;
@@ -738,21 +777,29 @@ const createSqlitePersister = (
738
777
  };
739
778
  return (isJson ? createJsonSqlitePersister : createTabularSqlitePersister)(
740
779
  store,
741
- logSql
780
+ onSqlCommand
742
781
  ? async (sql, args) => {
743
- logSql(sql, args);
782
+ onSqlCommand(sql, args);
744
783
  return await cmd(sql, args);
745
784
  }
746
785
  : cmd,
747
786
  addPersisterListener,
748
787
  delPersisterListener,
788
+ onIgnoredError,
749
789
  defaultedConfig,
750
790
  collValues(managedTableNamesSet),
791
+ scheduleId,
751
792
  );
752
793
  };
753
794
 
754
795
  const CHANGE = 'change';
755
- const createSqlite3Persister = (store, db, configOrStoreTableName, logSql) =>
796
+ const createSqlite3Persister = (
797
+ store,
798
+ db,
799
+ configOrStoreTableName,
800
+ onSqlCommand,
801
+ onIgnoredError,
802
+ ) =>
756
803
  createSqlitePersister(
757
804
  store,
758
805
  configOrStoreTableName,
@@ -768,7 +815,9 @@ const createSqlite3Persister = (store, db, configOrStoreTableName, logSql) =>
768
815
  return observer;
769
816
  },
770
817
  (observer) => db.off(CHANGE, observer),
771
- logSql,
818
+ onSqlCommand,
819
+ onIgnoredError,
820
+ db,
772
821
  );
773
822
 
774
823
  export {createSqlite3Persister};