tinybase 8.5.0 → 9.0.0-beta.0

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 (161) hide show
  1. package/@types/_internal/queries/with-schemas/index.d.ts +1 -2
  2. package/@types/_internal/ui/with-schemas/index.d.ts +8 -16
  3. package/@types/persisters/index.d.ts +32 -12
  4. package/@types/persisters/persister-durable-object-sql-storage/index.d.ts +9 -8
  5. package/@types/persisters/persister-durable-object-sql-storage/with-schemas/index.d.ts +10 -10
  6. package/@types/persisters/with-schemas/index.d.ts +56 -20
  7. package/@types/queries/index.d.ts +1 -7
  8. package/@types/queries/with-schemas/index.d.ts +5 -15
  9. package/@types/store/index.d.ts +1 -2
  10. package/@types/store/with-schemas/index.d.ts +19 -29
  11. package/@types/synchronizers/synchronizer-ws-client/index.d.ts +9 -3
  12. package/@types/synchronizers/synchronizer-ws-client/with-schemas/index.d.ts +10 -3
  13. package/@types/synchronizers/synchronizer-ws-server/index.d.ts +15 -2
  14. package/@types/synchronizers/synchronizer-ws-server/with-schemas/index.d.ts +17 -2
  15. package/@types/synchronizers/synchronizer-ws-server-durable-object/index.d.ts +51 -0
  16. package/@types/synchronizers/synchronizer-ws-server-durable-object/with-schemas/index.d.ts +51 -0
  17. package/@types/ui-react/with-schemas/index.d.ts +3 -6
  18. package/@types/ui-react-dom/index.d.ts +10 -10
  19. package/@types/ui-react-dom/with-schemas/index.d.ts +16 -22
  20. package/@types/ui-react-dom-charts/index.d.ts +7 -7
  21. package/@types/ui-react-dom-charts/with-schemas/index.d.ts +10 -11
  22. package/@types/ui-react-inspector/index.d.ts +1 -1
  23. package/@types/ui-react-inspector/with-schemas/index.d.ts +1 -1
  24. package/@types/ui-solid/with-schemas/index.d.ts +4 -8
  25. package/@types/ui-solid-dom/index.d.ts +10 -10
  26. package/@types/ui-solid-dom/with-schemas/index.d.ts +16 -22
  27. package/@types/ui-solid-inspector/index.d.ts +1 -1
  28. package/@types/ui-solid-inspector/with-schemas/index.d.ts +1 -1
  29. package/@types/ui-svelte-dom/index.d.ts +10 -10
  30. package/@types/ui-svelte-dom/with-schemas/index.d.ts +16 -22
  31. package/@types/ui-svelte-inspector/index.d.ts +1 -1
  32. package/@types/ui-svelte-inspector/with-schemas/index.d.ts +1 -1
  33. package/index.js +21 -19
  34. package/indexes/index.js +6 -8
  35. package/indexes/with-schemas/index.js +6 -8
  36. package/metrics/index.js +6 -8
  37. package/metrics/with-schemas/index.js +6 -8
  38. package/min/index.js +1 -1
  39. package/min/index.js.gz +0 -0
  40. package/min/omni/index.js +1 -1
  41. package/min/omni/index.js.gz +0 -0
  42. package/min/omni/with-schemas/index.js +1 -1
  43. package/min/omni/with-schemas/index.js.gz +0 -0
  44. package/min/persisters/index.js +1 -1
  45. package/min/persisters/index.js.gz +0 -0
  46. package/min/persisters/persister-cr-sqlite-wasm/index.js +1 -1
  47. package/min/persisters/persister-cr-sqlite-wasm/index.js.gz +0 -0
  48. package/min/persisters/persister-cr-sqlite-wasm/with-schemas/index.js +1 -1
  49. package/min/persisters/persister-cr-sqlite-wasm/with-schemas/index.js.gz +0 -0
  50. package/min/persisters/persister-durable-object-sql-storage/index.js +1 -1
  51. package/min/persisters/persister-durable-object-sql-storage/index.js.gz +0 -0
  52. package/min/persisters/persister-durable-object-sql-storage/with-schemas/index.js +1 -1
  53. package/min/persisters/persister-durable-object-sql-storage/with-schemas/index.js.gz +0 -0
  54. package/min/persisters/persister-electric-sql/index.js +1 -1
  55. package/min/persisters/persister-electric-sql/index.js.gz +0 -0
  56. package/min/persisters/persister-electric-sql/with-schemas/index.js +1 -1
  57. package/min/persisters/persister-electric-sql/with-schemas/index.js.gz +0 -0
  58. package/min/persisters/persister-expo-sqlite/index.js +1 -1
  59. package/min/persisters/persister-expo-sqlite/index.js.gz +0 -0
  60. package/min/persisters/persister-expo-sqlite/with-schemas/index.js +1 -1
  61. package/min/persisters/persister-expo-sqlite/with-schemas/index.js.gz +0 -0
  62. package/min/persisters/persister-libsql/index.js +1 -1
  63. package/min/persisters/persister-libsql/index.js.gz +0 -0
  64. package/min/persisters/persister-libsql/with-schemas/index.js +1 -1
  65. package/min/persisters/persister-libsql/with-schemas/index.js.gz +0 -0
  66. package/min/persisters/persister-pglite/index.js +1 -1
  67. package/min/persisters/persister-pglite/index.js.gz +0 -0
  68. package/min/persisters/persister-pglite/with-schemas/index.js +1 -1
  69. package/min/persisters/persister-pglite/with-schemas/index.js.gz +0 -0
  70. package/min/persisters/persister-postgres/index.js +1 -1
  71. package/min/persisters/persister-postgres/index.js.gz +0 -0
  72. package/min/persisters/persister-postgres/with-schemas/index.js +1 -1
  73. package/min/persisters/persister-postgres/with-schemas/index.js.gz +0 -0
  74. package/min/persisters/persister-powersync/index.js +1 -1
  75. package/min/persisters/persister-powersync/index.js.gz +0 -0
  76. package/min/persisters/persister-powersync/with-schemas/index.js +1 -1
  77. package/min/persisters/persister-powersync/with-schemas/index.js.gz +0 -0
  78. package/min/persisters/persister-react-native-sqlite/index.js +1 -1
  79. package/min/persisters/persister-react-native-sqlite/index.js.gz +0 -0
  80. package/min/persisters/persister-react-native-sqlite/with-schemas/index.js +1 -1
  81. package/min/persisters/persister-react-native-sqlite/with-schemas/index.js.gz +0 -0
  82. package/min/persisters/persister-sqlite-bun/index.js +1 -1
  83. package/min/persisters/persister-sqlite-bun/index.js.gz +0 -0
  84. package/min/persisters/persister-sqlite-bun/with-schemas/index.js +1 -1
  85. package/min/persisters/persister-sqlite-bun/with-schemas/index.js.gz +0 -0
  86. package/min/persisters/persister-sqlite-wasm/index.js +1 -1
  87. package/min/persisters/persister-sqlite-wasm/index.js.gz +0 -0
  88. package/min/persisters/persister-sqlite-wasm/with-schemas/index.js +1 -1
  89. package/min/persisters/persister-sqlite-wasm/with-schemas/index.js.gz +0 -0
  90. package/min/persisters/persister-sqlite3/index.js +1 -1
  91. package/min/persisters/persister-sqlite3/index.js.gz +0 -0
  92. package/min/persisters/persister-sqlite3/with-schemas/index.js +1 -1
  93. package/min/persisters/persister-sqlite3/with-schemas/index.js.gz +0 -0
  94. package/min/persisters/with-schemas/index.js +1 -1
  95. package/min/persisters/with-schemas/index.js.gz +0 -0
  96. package/min/queries/index.js +1 -1
  97. package/min/queries/index.js.gz +0 -0
  98. package/min/queries/with-schemas/index.js +1 -1
  99. package/min/queries/with-schemas/index.js.gz +0 -0
  100. package/min/synchronizers/synchronizer-ws-client/index.js +1 -1
  101. package/min/synchronizers/synchronizer-ws-client/index.js.gz +0 -0
  102. package/min/synchronizers/synchronizer-ws-client/with-schemas/index.js +1 -1
  103. package/min/synchronizers/synchronizer-ws-client/with-schemas/index.js.gz +0 -0
  104. package/min/synchronizers/synchronizer-ws-server/index.js +1 -1
  105. package/min/synchronizers/synchronizer-ws-server/index.js.gz +0 -0
  106. package/min/synchronizers/synchronizer-ws-server/with-schemas/index.js +1 -1
  107. package/min/synchronizers/synchronizer-ws-server/with-schemas/index.js.gz +0 -0
  108. package/min/synchronizers/synchronizer-ws-server-durable-object/index.js +1 -1
  109. package/min/synchronizers/synchronizer-ws-server-durable-object/index.js.gz +0 -0
  110. package/min/synchronizers/synchronizer-ws-server-durable-object/with-schemas/index.js +1 -1
  111. package/min/synchronizers/synchronizer-ws-server-durable-object/with-schemas/index.js.gz +0 -0
  112. package/min/with-schemas/index.js +1 -1
  113. package/min/with-schemas/index.js.gz +0 -0
  114. package/omni/index.js +311 -141
  115. package/omni/with-schemas/index.js +311 -141
  116. package/package.json +7 -7
  117. package/persisters/index.js +129 -37
  118. package/persisters/persister-cr-sqlite-wasm/index.js +129 -37
  119. package/persisters/persister-cr-sqlite-wasm/with-schemas/index.js +129 -37
  120. package/persisters/persister-durable-object-sql-storage/index.js +271 -110
  121. package/persisters/persister-durable-object-sql-storage/with-schemas/index.js +271 -110
  122. package/persisters/persister-electric-sql/index.js +129 -37
  123. package/persisters/persister-electric-sql/with-schemas/index.js +129 -37
  124. package/persisters/persister-expo-sqlite/index.js +129 -37
  125. package/persisters/persister-expo-sqlite/with-schemas/index.js +129 -37
  126. package/persisters/persister-libsql/index.js +129 -37
  127. package/persisters/persister-libsql/with-schemas/index.js +129 -37
  128. package/persisters/persister-pglite/index.js +130 -37
  129. package/persisters/persister-pglite/with-schemas/index.js +130 -37
  130. package/persisters/persister-postgres/index.js +130 -37
  131. package/persisters/persister-postgres/with-schemas/index.js +130 -37
  132. package/persisters/persister-powersync/index.js +182 -117
  133. package/persisters/persister-powersync/with-schemas/index.js +182 -117
  134. package/persisters/persister-react-native-sqlite/index.js +129 -37
  135. package/persisters/persister-react-native-sqlite/with-schemas/index.js +129 -37
  136. package/persisters/persister-sqlite-bun/index.js +129 -37
  137. package/persisters/persister-sqlite-bun/with-schemas/index.js +129 -37
  138. package/persisters/persister-sqlite-wasm/index.js +129 -37
  139. package/persisters/persister-sqlite-wasm/with-schemas/index.js +129 -37
  140. package/persisters/persister-sqlite3/index.js +129 -37
  141. package/persisters/persister-sqlite3/with-schemas/index.js +129 -37
  142. package/persisters/with-schemas/index.js +129 -37
  143. package/queries/index.js +21 -19
  144. package/queries/with-schemas/index.js +21 -19
  145. package/readme.md +14 -14
  146. package/relationships/index.js +6 -8
  147. package/relationships/with-schemas/index.js +6 -8
  148. package/releases.md +57 -57
  149. package/synchronizers/synchronizer-ws-client/index.js +116 -42
  150. package/synchronizers/synchronizer-ws-client/with-schemas/index.js +116 -42
  151. package/synchronizers/synchronizer-ws-server/index.js +109 -28
  152. package/synchronizers/synchronizer-ws-server/with-schemas/index.js +109 -28
  153. package/synchronizers/synchronizer-ws-server-durable-object/index.js +122 -38
  154. package/synchronizers/synchronizer-ws-server-durable-object/with-schemas/index.js +122 -38
  155. package/ui-svelte/index.js +1 -1
  156. package/ui-svelte/with-schemas/index.js +1 -1
  157. package/ui-svelte-dom/index.js +2 -2
  158. package/ui-svelte-dom/with-schemas/index.js +2 -2
  159. package/ui-svelte-inspector/index.js +2 -2
  160. package/ui-svelte-inspector/with-schemas/index.js +2 -2
  161. package/with-schemas/index.js +21 -19
@@ -48,6 +48,7 @@ const tryCatch = async (action, then1, then2) => {
48
48
  }
49
49
  };
50
50
 
51
+ const arrayHas = (array, value) => array.includes(value);
51
52
  const arrayForEach = (array, cb) => array.forEach(cb);
52
53
  const arrayJoin = (array, sep = EMPTY_STRING) => array.join(sep);
53
54
  const arrayMap = (array, cb) => array.map(cb);
@@ -57,14 +58,6 @@ const arrayClear = (array, to) => array.splice(0, to);
57
58
  const arrayPush = (array, ...values) => array.push(...values);
58
59
  const arrayShift = (array) => array.shift();
59
60
 
60
- const collSize = (coll) => coll?.size ?? 0;
61
- const collHas = (coll, keyOrValue) => coll?.has(keyOrValue) ?? false;
62
- const collIsEmpty = (coll) => isUndefined(coll) || collSize(coll) == 0;
63
- const collValues = (coll) => [...(coll?.values() ?? [])];
64
- const collClear = (coll) => coll.clear();
65
- const collForEach = (coll, cb) => coll?.forEach(cb);
66
- const collDel = (coll, keyOrValue) => coll?.delete(keyOrValue);
67
-
68
61
  const object = Object;
69
62
  const getPrototypeOf = (obj) => object.getPrototypeOf(obj);
70
63
  const objEntries = object.entries;
@@ -96,14 +89,6 @@ const objValues = (obj) => object.values(obj);
96
89
  const objSize = (obj) => size(objIds(obj));
97
90
  const objIsEmpty = (obj) => isObject(obj) && objSize(obj) == 0;
98
91
 
99
- const setNew = (entryOrEntries) =>
100
- new Set(
101
- isArray(entryOrEntries) || isUndefined(entryOrEntries)
102
- ? entryOrEntries
103
- : [entryOrEntries],
104
- );
105
- const setAdd = (set, value) => set?.add(value);
106
-
107
92
  const SINGLE_ROW_ID = '_';
108
93
  const DEFAULT_ROW_ID_COLUMN_NAME = '_id';
109
94
  const SELECT = 'SELECT';
@@ -122,7 +107,6 @@ const SCHEMA_VERSION = 'schema_version';
122
107
  const PRAGMA_TABLE = 'pragma_table_';
123
108
  const CREATE = 'CREATE ';
124
109
  const CREATE_TABLE = CREATE + TABLE;
125
- const OR_REPLACE = 'OR REPLACE ';
126
110
  const TABLE_NAME_PLACEHOLDER = '$tableName';
127
111
  const getWrappedCommand = (executeCommand, onSqlCommand) =>
128
112
  onSqlCommand
@@ -147,6 +131,14 @@ const getWhereCondition = (tableName, condition = TRUE) =>
147
131
  WHERE +
148
132
  `(${strReplace(condition, TABLE_NAME_PLACEHOLDER, escapeId(tableName))})`;
149
133
 
134
+ const collSize = (coll) => coll?.size ?? 0;
135
+ const collHas = (coll, keyOrValue) => coll?.has(keyOrValue) ?? false;
136
+ const collIsEmpty = (coll) => isUndefined(coll) || collSize(coll) == 0;
137
+ const collValues = (coll) => [...(coll?.values() ?? [])];
138
+ const collClear = (coll) => coll.clear();
139
+ const collForEach = (coll, cb) => coll?.forEach(cb);
140
+ const collDel = (coll, keyOrValue) => coll?.delete(keyOrValue);
141
+
150
142
  const map = Map;
151
143
  const mapNew = (entries) => new map(entries);
152
144
  const mapGet = (map2, key) => map2?.get(key);
@@ -186,6 +178,14 @@ const visitTree = (node, path, ensureLeaf, pruneLeaf, p = 0) =>
186
178
  },
187
179
  );
188
180
 
181
+ const setNew = (entryOrEntries) =>
182
+ new Set(
183
+ isArray(entryOrEntries) || isUndefined(entryOrEntries)
184
+ ? entryOrEntries
185
+ : [entryOrEntries],
186
+ );
187
+ const setAdd = (set, value) => set?.add(value);
188
+
189
189
  const COLUMN_NAME = 'ColumnName';
190
190
  const STORE = 'store';
191
191
  const JSON$1 = 'json';
@@ -208,6 +208,8 @@ const DEFAULT_TABULAR_VALUES_CONFIG = {
208
208
  save: 0,
209
209
  [TABLE_NAME]: TINYBASE + '_values',
210
210
  };
211
+ const getValuesIn = (config) => (isArray(config) ? config : void 0);
212
+ const hasValues = (config) => isTrue(config) || isArray(config);
211
213
  const getDefaultedConfig = (configOrStoreTableName) =>
212
214
  objMerge(
213
215
  DEFAULT_CONFIG,
@@ -258,11 +260,15 @@ const getConfigStructures = (configOrStoreTableName) => {
258
260
  ];
259
261
  }
260
262
  const {tables: {load = {}, save = {}} = {}, values = {}} = config;
261
- const valuesConfig = slice(
262
- objValues(objMerge(DEFAULT_TABULAR_VALUES_CONFIG, values)),
263
- 0,
264
- objSize(DEFAULT_TABULAR_VALUES_CONFIG),
265
- );
263
+ const valuesConfigObj = objMerge(DEFAULT_TABULAR_VALUES_CONFIG, values);
264
+ const {load: valuesLoad, save: valuesSave} = valuesConfigObj;
265
+ const valuesConfig = [
266
+ hasValues(valuesLoad),
267
+ hasValues(valuesSave),
268
+ valuesConfigObj[TABLE_NAME],
269
+ getValuesIn(valuesLoad),
270
+ getValuesIn(valuesSave),
271
+ ];
266
272
  const valuesTable = valuesConfig[2];
267
273
  const managedTableNames = setNew(valuesTable);
268
274
  const excludedTableNames = setNew(valuesTable);
@@ -671,8 +677,18 @@ const getCommandFunctions = (
671
677
  ({tn, cn}) => setAdd(mapEnsure(schemaMap, tn, setNew), cn),
672
678
  );
673
679
  };
674
- const loadTable = async (tableName, rowIdColumnName, condition) =>
675
- canSelect(tableName, rowIdColumnName)
680
+ const loadTable = async (
681
+ tableName,
682
+ rowIdColumnName,
683
+ condition,
684
+ contentSubIds,
685
+ ) => {
686
+ const contentSubIdSet = isUndefined(contentSubIds)
687
+ ? void 0
688
+ : setNew(contentSubIds);
689
+ const includeContentSubId = (contentSubId) =>
690
+ isUndefined(contentSubIdSet) || collHas(contentSubIdSet, contentSubId);
691
+ return canSelect(tableName, rowIdColumnName)
676
692
  ? objNew(
677
693
  arrayFilter(
678
694
  arrayMap(
@@ -681,17 +697,35 @@ const getCommandFunctions = (
681
697
  escapeId(tableName) +
682
698
  getWhereCondition(tableName, condition),
683
699
  ),
684
- (row) => [
685
- row[rowIdColumnName],
686
- decode
700
+ (row) => {
701
+ const rowId = row[rowIdColumnName];
702
+ const rowContent = decode
687
703
  ? objMap(objDel(row, rowIdColumnName), decode)
688
- : objDel(row, rowIdColumnName),
689
- ],
704
+ : objDel(row, rowIdColumnName);
705
+ return [
706
+ rowId,
707
+ isUndefined(contentSubIdSet)
708
+ ? rowContent
709
+ : objNew(
710
+ arrayFilter(
711
+ objToArray(
712
+ rowContent,
713
+ (cellOrValue, contentSubId) => [
714
+ contentSubId,
715
+ cellOrValue,
716
+ ],
717
+ ),
718
+ ([contentSubId]) => includeContentSubId(contentSubId),
719
+ ),
720
+ ),
721
+ ];
722
+ },
690
723
  ),
691
724
  (entry) => !isUndefined(entry[0]) && !objIsEmpty(entry[1]),
692
725
  ),
693
726
  )
694
727
  : {};
728
+ };
695
729
  const saveTable = async (
696
730
  tableName,
697
731
  rowIdColumnName,
@@ -700,15 +734,23 @@ const getCommandFunctions = (
700
734
  deleteEmptyTable,
701
735
  partial = false,
702
736
  condition = TRUE,
737
+ contentSubIds,
703
738
  ) => {
739
+ const contentSubIdSet = isUndefined(contentSubIds)
740
+ ? void 0
741
+ : setNew(contentSubIds);
742
+ const includeContentSubId = (contentSubId) =>
743
+ isUndefined(contentSubIdSet) || collHas(contentSubIdSet, contentSubId);
704
744
  const settingColumnNameSet = setNew();
705
745
  objMap(content ?? {}, (contentRow) =>
706
- arrayMap(objIds(contentRow ?? {}), (cellOrValueId) =>
707
- setAdd(settingColumnNameSet, cellOrValueId),
746
+ arrayMap(
747
+ arrayFilter(objIds(contentRow ?? {}), includeContentSubId),
748
+ (cellOrValueId) => setAdd(settingColumnNameSet, cellOrValueId),
708
749
  ),
709
750
  );
710
751
  const settingColumnNames = collValues(settingColumnNameSet);
711
752
  if (
753
+ isUndefined(contentSubIdSet) &&
712
754
  !partial &&
713
755
  deleteEmptyTable &&
714
756
  condition == TRUE &&
@@ -720,7 +762,13 @@ const getCommandFunctions = (
720
762
  return;
721
763
  }
722
764
  const currentColumnNames = mapGet(schemaMap, tableName);
723
- const unaccountedColumnNames = setNew(collValues(currentColumnNames));
765
+ const unaccountedColumnNames = setNew(
766
+ arrayFilter(
767
+ collValues(currentColumnNames),
768
+ (columnName) =>
769
+ columnName == rowIdColumnName || includeContentSubId(columnName),
770
+ ),
771
+ );
724
772
  if (!arrayIsEmpty(settingColumnNames)) {
725
773
  if (!collHas(schemaMap, tableName)) {
726
774
  await databaseExecuteCommand(
@@ -786,11 +834,13 @@ const getCommandFunctions = (
786
834
  ]);
787
835
  if (partial) {
788
836
  if (isUndefined(content)) {
789
- await databaseExecuteCommand(
790
- DELETE_FROM +
791
- escapeId(tableName) +
792
- getWhereCondition(tableName, condition),
793
- );
837
+ if (isUndefined(contentSubIdSet)) {
838
+ await databaseExecuteCommand(
839
+ DELETE_FROM +
840
+ escapeId(tableName) +
841
+ getWhereCondition(tableName, condition),
842
+ );
843
+ }
794
844
  } else {
795
845
  await promiseAll(
796
846
  objToArray(content, async (row, rowId) => {
@@ -803,18 +853,24 @@ const getCommandFunctions = (
803
853
  [rowId],
804
854
  );
805
855
  } else if (!arrayIsEmpty(settingColumnNames)) {
806
- await upsert(
807
- databaseExecuteCommand,
808
- tableName,
809
- rowIdColumnName,
856
+ const changingColumnNames = arrayFilter(
810
857
  objIds(row),
811
- {
812
- [rowId]: encode
813
- ? arrayMap(objValues(row), encode)
814
- : objValues(row),
815
- },
816
- currentColumnNames,
858
+ includeContentSubId,
817
859
  );
860
+ if (!arrayIsEmpty(changingColumnNames)) {
861
+ await upsert(
862
+ databaseExecuteCommand,
863
+ tableName,
864
+ rowIdColumnName,
865
+ changingColumnNames,
866
+ {
867
+ [rowId]: arrayMap(changingColumnNames, (cellId) =>
868
+ encode ? encode(row[cellId]) : row[cellId],
869
+ ),
870
+ },
871
+ currentColumnNames,
872
+ );
873
+ }
818
874
  }
819
875
  }),
820
876
  );
@@ -823,7 +879,9 @@ const getCommandFunctions = (
823
879
  if (!arrayIsEmpty(settingColumnNames)) {
824
880
  const changingColumnNames = arrayFilter(
825
881
  collValues(mapGet(schemaMap, tableName)),
826
- (changingColumnName) => changingColumnName != rowIdColumnName,
882
+ (changingColumnName) =>
883
+ changingColumnName != rowIdColumnName &&
884
+ includeContentSubId(changingColumnName),
827
885
  );
828
886
  const rows = {};
829
887
  const deleteRowIds = [];
@@ -839,6 +897,7 @@ const getCommandFunctions = (
839
897
  rowIdColumnName,
840
898
  changingColumnNames,
841
899
  rows,
900
+ currentColumnNames,
842
901
  );
843
902
  await databaseExecuteCommand(
844
903
  DELETE_FROM +
@@ -847,7 +906,10 @@ const getCommandFunctions = (
847
906
  `AND${escapeId(rowIdColumnName)}NOT IN(${getPlaceholders(deleteRowIds)})`,
848
907
  deleteRowIds,
849
908
  );
850
- } else if (collHas(schemaMap, tableName)) {
909
+ } else if (
910
+ isUndefined(contentSubIdSet) &&
911
+ collHas(schemaMap, tableName)
912
+ ) {
851
913
  await databaseExecuteCommand(
852
914
  DELETE_FROM +
853
915
  escapeId(tableName) +
@@ -986,7 +1048,13 @@ const createTabularPersister = (
986
1048
  [
987
1049
  tablesLoadConfig,
988
1050
  tablesSaveConfig,
989
- [valuesLoad, valuesSave, valuesTableName],
1051
+ [
1052
+ valuesLoad,
1053
+ valuesSave,
1054
+ valuesTableName,
1055
+ valuesLoadValueIds,
1056
+ valuesSaveValueIds,
1057
+ ],
990
1058
  ],
991
1059
  managedTableNames,
992
1060
  querySchema,
@@ -1036,15 +1104,33 @@ const createTabularPersister = (
1036
1104
  },
1037
1105
  ),
1038
1106
  );
1107
+ const getValuesSubset = (values, valueIds, partial) =>
1108
+ objNew(
1109
+ partial == true
1110
+ ? arrayFilter(
1111
+ objToArray(values, (value, valueId) => [valueId, value]),
1112
+ ([valueId]) => arrayHas(valueIds, valueId),
1113
+ )
1114
+ : arrayFilter(
1115
+ arrayMap(valueIds, (valueId) => [valueId, values[valueId]]),
1116
+ ([, value]) => !isUndefined(value),
1117
+ ),
1118
+ );
1039
1119
  const saveValues = async (values, partial) =>
1040
1120
  valuesSave
1041
1121
  ? await saveTable(
1042
1122
  valuesTableName,
1043
1123
  DEFAULT_ROW_ID_COLUMN_NAME,
1044
- {[SINGLE_ROW_ID]: values},
1124
+ {
1125
+ [SINGLE_ROW_ID]: isUndefined(valuesSaveValueIds)
1126
+ ? values
1127
+ : getValuesSubset(values, valuesSaveValueIds, partial),
1128
+ },
1045
1129
  true,
1046
1130
  true,
1047
1131
  partial,
1132
+ void 0,
1133
+ valuesSaveValueIds,
1048
1134
  )
1049
1135
  : null;
1050
1136
  const loadTables = async () =>
@@ -1064,9 +1150,14 @@ const createTabularPersister = (
1064
1150
  );
1065
1151
  const loadValues = async () =>
1066
1152
  valuesLoad
1067
- ? (await loadTable(valuesTableName, DEFAULT_ROW_ID_COLUMN_NAME))[
1068
- SINGLE_ROW_ID
1069
- ]
1153
+ ? (
1154
+ await loadTable(
1155
+ valuesTableName,
1156
+ DEFAULT_ROW_ID_COLUMN_NAME,
1157
+ void 0,
1158
+ valuesLoadValueIds,
1159
+ )
1160
+ )[SINGLE_ROW_ID]
1070
1161
  : {};
1071
1162
  const getPersisted = () =>
1072
1163
  transaction(async () => {
@@ -1241,83 +1332,57 @@ const createPowerSyncPersister = (
1241
1332
  // StoreOnly,
1242
1333
  powerSync,
1243
1334
  'getPowerSync',
1244
- viewUpsert,
1335
+ powerSyncUpdateThenInsert,
1245
1336
  );
1246
1337
  };
1247
- const viewUpsert = async (
1338
+ const powerSyncUpdateThenInsert = async (
1248
1339
  executeCommand,
1249
1340
  tableName,
1250
1341
  rowIdColumnName,
1251
1342
  changingColumnNames,
1252
1343
  rows,
1253
- currentColumnNames,
1254
1344
  ) => {
1255
- const offset = [1];
1256
- const changingColumnNamesSet = setNew(changingColumnNames);
1257
- const unchangingColumnNames = currentColumnNames
1258
- ? arrayFilter(
1259
- [...currentColumnNames],
1260
- (currentColumnName) =>
1261
- currentColumnName != rowIdColumnName &&
1262
- !collHas(changingColumnNamesSet, currentColumnName),
1263
- )
1264
- : [];
1265
- if (!arrayIsEmpty(unchangingColumnNames)) {
1266
- const ids = objIds(rows);
1267
- const unchangingData = objNew(
1268
- arrayMap(
1345
+ const assignments = arrayJoin(
1346
+ arrayMap(
1347
+ changingColumnNames,
1348
+ (columnName, index) => escapeId(columnName) + '=$' + (index + 1),
1349
+ ),
1350
+ COMMA,
1351
+ );
1352
+ for (const [id, row] of objToArray(rows, (row2, id2) => [id2, row2])) {
1353
+ const rowParams = arrayMap(row, (value) => value ?? null);
1354
+ if (
1355
+ arrayIsEmpty(
1269
1356
  await executeCommand(
1270
- SELECT +
1271
- escapeColumnNames(rowIdColumnName, ...unchangingColumnNames) +
1272
- FROM +
1357
+ UPDATE +
1273
1358
  escapeId(tableName) +
1359
+ ' SET' +
1360
+ assignments +
1361
+ ' ' +
1274
1362
  WHERE +
1275
1363
  escapeId(rowIdColumnName) +
1276
- 'IN(' +
1277
- getPlaceholders(ids) +
1278
- ')',
1279
- ids,
1280
- ),
1281
- (unchangingRow) => [unchangingRow[rowIdColumnName], unchangingRow],
1282
- ),
1283
- );
1284
- arrayForEach(ids, (id) =>
1285
- arrayPush(
1286
- rows[id],
1287
- ...arrayMap(
1288
- unchangingColumnNames,
1289
- (unchangingColumnName) =>
1290
- unchangingData?.[id]?.[unchangingColumnName] ?? null,
1364
+ '=$' +
1365
+ (row.length + 1) +
1366
+ ' RETURNING' +
1367
+ escapeId(rowIdColumnName),
1368
+ [...rowParams, id],
1291
1369
  ),
1292
- ),
1293
- );
1370
+ )
1371
+ ) {
1372
+ const offset = [1];
1373
+ await executeCommand(
1374
+ INSERT +
1375
+ ' INTO' +
1376
+ escapeId(tableName) +
1377
+ '(' +
1378
+ escapeColumnNames(rowIdColumnName, ...changingColumnNames) +
1379
+ ')VALUES(' +
1380
+ getPlaceholders([id, ...row], offset) +
1381
+ ')',
1382
+ [id, ...rowParams],
1383
+ );
1384
+ }
1294
1385
  }
1295
- await executeCommand(
1296
- INSERT +
1297
- ' ' +
1298
- OR_REPLACE +
1299
- 'INTO' +
1300
- escapeId(tableName) +
1301
- '(' +
1302
- escapeColumnNames(
1303
- rowIdColumnName,
1304
- ...changingColumnNames,
1305
- ...unchangingColumnNames,
1306
- ) +
1307
- ')VALUES' +
1308
- arrayJoin(
1309
- objToArray(
1310
- rows,
1311
- (row) =>
1312
- '($' + offset[0]++ + ',' + getPlaceholders(row, offset) + ')',
1313
- ),
1314
- COMMA,
1315
- ),
1316
- objToArray(rows, (row, id) => [
1317
- id,
1318
- ...arrayMap(row, (value) => value ?? null),
1319
- ]).flat(),
1320
- );
1321
1386
  };
1322
1387
 
1323
1388
  export {createPowerSyncPersister};