tinybase 10.0.0-beta.0 → 10.0.0-beta.2

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 (185) hide show
  1. package/@types/common/index.d.ts +1 -0
  2. package/@types/common/with-schemas/index.d.ts +1 -0
  3. package/@types/indexes/index.d.ts +4 -3
  4. package/@types/indexes/with-schemas/index.d.ts +4 -3
  5. package/@types/metrics/index.d.ts +1 -0
  6. package/@types/metrics/with-schemas/index.d.ts +1 -0
  7. package/@types/omni/index.d.ts +1 -0
  8. package/@types/omni/with-schemas/index.d.ts +1 -0
  9. package/@types/persisters/index.d.ts +1 -0
  10. package/@types/persisters/persister-partykit-server/index.d.ts +17 -0
  11. package/@types/persisters/persister-partykit-server/with-schemas/index.d.ts +17 -0
  12. package/@types/persisters/persister-tinyjoin/index.d.ts +197 -0
  13. package/@types/persisters/persister-tinyjoin/with-schemas/index.d.ts +221 -0
  14. package/@types/persisters/with-schemas/index.d.ts +1 -0
  15. package/@types/queries/index.d.ts +3 -0
  16. package/@types/queries/with-schemas/index.d.ts +3 -0
  17. package/@types/relationships/index.d.ts +1 -0
  18. package/@types/relationships/with-schemas/index.d.ts +1 -0
  19. package/@types/store/index.d.ts +4 -0
  20. package/@types/store/with-schemas/index.d.ts +4 -0
  21. package/@types/ui-react/index.d.ts +2 -0
  22. package/@types/ui-react/with-schemas/index.d.ts +1 -0
  23. package/@types/ui-react-dom-charts/index.d.ts +7 -0
  24. package/@types/ui-react-dom-charts/with-schemas/index.d.ts +7 -0
  25. package/@types/ui-solid/index.d.ts +2 -0
  26. package/@types/ui-solid/with-schemas/index.d.ts +1 -0
  27. package/@types/ui-svelte/index.d.ts +23 -0
  28. package/@types/ui-svelte/with-schemas/index.d.ts +23 -0
  29. package/@types/ui-svelte-dom/index.d.ts +10 -0
  30. package/@types/ui-svelte-dom/with-schemas/index.d.ts +10 -0
  31. package/@types/ui-svelte-inspector/index.d.ts +1 -0
  32. package/@types/ui-svelte-inspector/with-schemas/index.d.ts +1 -0
  33. package/checkpoints/index.js +4 -2
  34. package/checkpoints/with-schemas/index.js +4 -2
  35. package/index.js +37 -4
  36. package/metrics/index.js +2 -1
  37. package/metrics/with-schemas/index.js +2 -1
  38. package/min/checkpoints/index.js +1 -1
  39. package/min/checkpoints/index.js.gz +0 -0
  40. package/min/checkpoints/with-schemas/index.js +1 -1
  41. package/min/checkpoints/with-schemas/index.js.gz +0 -0
  42. package/min/index.js +1 -1
  43. package/min/index.js.gz +0 -0
  44. package/min/metrics/index.js +1 -1
  45. package/min/metrics/index.js.gz +0 -0
  46. package/min/metrics/with-schemas/index.js +1 -1
  47. package/min/metrics/with-schemas/index.js.gz +0 -0
  48. package/min/omni/index.js +1 -1
  49. package/min/omni/index.js.gz +0 -0
  50. package/min/omni/with-schemas/index.js +1 -1
  51. package/min/omni/with-schemas/index.js.gz +0 -0
  52. package/min/persisters/index.js +1 -1
  53. package/min/persisters/index.js.gz +0 -0
  54. package/min/persisters/persister-better-sqlite3/index.js +1 -1
  55. package/min/persisters/persister-better-sqlite3/index.js.gz +0 -0
  56. package/min/persisters/persister-better-sqlite3/with-schemas/index.js +1 -1
  57. package/min/persisters/persister-better-sqlite3/with-schemas/index.js.gz +0 -0
  58. package/min/persisters/persister-capacitor-sqlite/index.js +1 -1
  59. package/min/persisters/persister-capacitor-sqlite/index.js.gz +0 -0
  60. package/min/persisters/persister-capacitor-sqlite/with-schemas/index.js +1 -1
  61. package/min/persisters/persister-capacitor-sqlite/with-schemas/index.js.gz +0 -0
  62. package/min/persisters/persister-cr-sqlite-wasm/index.js +1 -1
  63. package/min/persisters/persister-cr-sqlite-wasm/index.js.gz +0 -0
  64. package/min/persisters/persister-cr-sqlite-wasm/with-schemas/index.js +1 -1
  65. package/min/persisters/persister-cr-sqlite-wasm/with-schemas/index.js.gz +0 -0
  66. package/min/persisters/persister-durable-object-sql-storage/index.js +1 -1
  67. package/min/persisters/persister-durable-object-sql-storage/index.js.gz +0 -0
  68. package/min/persisters/persister-durable-object-sql-storage/with-schemas/index.js +1 -1
  69. package/min/persisters/persister-durable-object-sql-storage/with-schemas/index.js.gz +0 -0
  70. package/min/persisters/persister-electric-sql/index.js +1 -1
  71. package/min/persisters/persister-electric-sql/index.js.gz +0 -0
  72. package/min/persisters/persister-electric-sql/with-schemas/index.js +1 -1
  73. package/min/persisters/persister-electric-sql/with-schemas/index.js.gz +0 -0
  74. package/min/persisters/persister-expo-sqlite/index.js +1 -1
  75. package/min/persisters/persister-expo-sqlite/index.js.gz +0 -0
  76. package/min/persisters/persister-expo-sqlite/with-schemas/index.js +1 -1
  77. package/min/persisters/persister-expo-sqlite/with-schemas/index.js.gz +0 -0
  78. package/min/persisters/persister-libsql/index.js +1 -1
  79. package/min/persisters/persister-libsql/index.js.gz +0 -0
  80. package/min/persisters/persister-libsql/with-schemas/index.js +1 -1
  81. package/min/persisters/persister-libsql/with-schemas/index.js.gz +0 -0
  82. package/min/persisters/persister-pg/index.js +1 -1
  83. package/min/persisters/persister-pg/index.js.gz +0 -0
  84. package/min/persisters/persister-pg/with-schemas/index.js +1 -1
  85. package/min/persisters/persister-pg/with-schemas/index.js.gz +0 -0
  86. package/min/persisters/persister-pglite/index.js +1 -1
  87. package/min/persisters/persister-pglite/index.js.gz +0 -0
  88. package/min/persisters/persister-pglite/with-schemas/index.js +1 -1
  89. package/min/persisters/persister-pglite/with-schemas/index.js.gz +0 -0
  90. package/min/persisters/persister-postgres/index.js +1 -1
  91. package/min/persisters/persister-postgres/index.js.gz +0 -0
  92. package/min/persisters/persister-postgres/with-schemas/index.js +1 -1
  93. package/min/persisters/persister-postgres/with-schemas/index.js.gz +0 -0
  94. package/min/persisters/persister-powersync/index.js +1 -1
  95. package/min/persisters/persister-powersync/index.js.gz +0 -0
  96. package/min/persisters/persister-powersync/with-schemas/index.js +1 -1
  97. package/min/persisters/persister-powersync/with-schemas/index.js.gz +0 -0
  98. package/min/persisters/persister-react-native-sqlite/index.js +1 -1
  99. package/min/persisters/persister-react-native-sqlite/index.js.gz +0 -0
  100. package/min/persisters/persister-react-native-sqlite/with-schemas/index.js +1 -1
  101. package/min/persisters/persister-react-native-sqlite/with-schemas/index.js.gz +0 -0
  102. package/min/persisters/persister-sqlite-bun/index.js +1 -1
  103. package/min/persisters/persister-sqlite-bun/index.js.gz +0 -0
  104. package/min/persisters/persister-sqlite-bun/with-schemas/index.js +1 -1
  105. package/min/persisters/persister-sqlite-bun/with-schemas/index.js.gz +0 -0
  106. package/min/persisters/persister-sqlite-node/index.js +1 -1
  107. package/min/persisters/persister-sqlite-node/index.js.gz +0 -0
  108. package/min/persisters/persister-sqlite-node/with-schemas/index.js +1 -1
  109. package/min/persisters/persister-sqlite-node/with-schemas/index.js.gz +0 -0
  110. package/min/persisters/persister-sqlite-wasm/index.js +1 -1
  111. package/min/persisters/persister-sqlite-wasm/index.js.gz +0 -0
  112. package/min/persisters/persister-sqlite-wasm/with-schemas/index.js +1 -1
  113. package/min/persisters/persister-sqlite-wasm/with-schemas/index.js.gz +0 -0
  114. package/min/persisters/persister-sqlite3/index.js +1 -1
  115. package/min/persisters/persister-sqlite3/index.js.gz +0 -0
  116. package/min/persisters/persister-sqlite3/with-schemas/index.js +1 -1
  117. package/min/persisters/persister-sqlite3/with-schemas/index.js.gz +0 -0
  118. package/min/persisters/persister-tinyjoin/index.js +1 -0
  119. package/min/persisters/persister-tinyjoin/index.js.gz +0 -0
  120. package/min/persisters/persister-tinyjoin/with-schemas/index.js +1 -0
  121. package/min/persisters/persister-tinyjoin/with-schemas/index.js.gz +0 -0
  122. package/min/persisters/with-schemas/index.js +1 -1
  123. package/min/persisters/with-schemas/index.js.gz +0 -0
  124. package/min/queries/index.js +1 -1
  125. package/min/queries/index.js.gz +0 -0
  126. package/min/queries/with-schemas/index.js +1 -1
  127. package/min/queries/with-schemas/index.js.gz +0 -0
  128. package/min/relationships/index.js +1 -1
  129. package/min/relationships/index.js.gz +0 -0
  130. package/min/relationships/with-schemas/index.js +1 -1
  131. package/min/relationships/with-schemas/index.js.gz +0 -0
  132. package/min/synchronizers/synchronizer-local/index.js +1 -1
  133. package/min/synchronizers/synchronizer-local/index.js.gz +0 -0
  134. package/min/synchronizers/synchronizer-local/with-schemas/index.js +1 -1
  135. package/min/synchronizers/synchronizer-local/with-schemas/index.js.gz +0 -0
  136. package/min/with-schemas/index.js +1 -1
  137. package/min/with-schemas/index.js.gz +0 -0
  138. package/omni/index.js +205 -94
  139. package/omni/with-schemas/index.js +205 -94
  140. package/package.json +54 -14
  141. package/persisters/index.js +28 -13
  142. package/persisters/persister-better-sqlite3/index.js +70 -55
  143. package/persisters/persister-better-sqlite3/with-schemas/index.js +70 -55
  144. package/persisters/persister-capacitor-sqlite/index.js +70 -55
  145. package/persisters/persister-capacitor-sqlite/with-schemas/index.js +70 -55
  146. package/persisters/persister-cr-sqlite-wasm/index.js +70 -55
  147. package/persisters/persister-cr-sqlite-wasm/with-schemas/index.js +70 -55
  148. package/persisters/persister-durable-object-sql-storage/index.js +28 -13
  149. package/persisters/persister-durable-object-sql-storage/with-schemas/index.js +28 -13
  150. package/persisters/persister-electric-sql/index.js +70 -55
  151. package/persisters/persister-electric-sql/with-schemas/index.js +70 -55
  152. package/persisters/persister-expo-sqlite/index.js +70 -55
  153. package/persisters/persister-expo-sqlite/with-schemas/index.js +70 -55
  154. package/persisters/persister-libsql/index.js +91 -78
  155. package/persisters/persister-libsql/with-schemas/index.js +91 -78
  156. package/persisters/persister-pg/index.js +77 -62
  157. package/persisters/persister-pg/with-schemas/index.js +77 -62
  158. package/persisters/persister-pglite/index.js +28 -13
  159. package/persisters/persister-pglite/with-schemas/index.js +28 -13
  160. package/persisters/persister-postgres/index.js +28 -13
  161. package/persisters/persister-postgres/with-schemas/index.js +28 -13
  162. package/persisters/persister-powersync/index.js +81 -66
  163. package/persisters/persister-powersync/with-schemas/index.js +81 -66
  164. package/persisters/persister-react-native-sqlite/index.js +70 -55
  165. package/persisters/persister-react-native-sqlite/with-schemas/index.js +70 -55
  166. package/persisters/persister-sqlite-bun/index.js +70 -55
  167. package/persisters/persister-sqlite-bun/with-schemas/index.js +70 -55
  168. package/persisters/persister-sqlite-node/index.js +70 -55
  169. package/persisters/persister-sqlite-node/with-schemas/index.js +70 -55
  170. package/persisters/persister-sqlite-wasm/index.js +70 -55
  171. package/persisters/persister-sqlite-wasm/with-schemas/index.js +70 -55
  172. package/persisters/persister-sqlite3/index.js +70 -55
  173. package/persisters/persister-sqlite3/with-schemas/index.js +70 -55
  174. package/persisters/persister-tinyjoin/index.js +1710 -0
  175. package/persisters/persister-tinyjoin/with-schemas/index.js +1710 -0
  176. package/persisters/with-schemas/index.js +28 -13
  177. package/queries/index.js +2 -1
  178. package/queries/with-schemas/index.js +2 -1
  179. package/readme.md +3 -3
  180. package/relationships/index.js +39 -9
  181. package/relationships/with-schemas/index.js +39 -9
  182. package/releases.md +20 -1
  183. package/synchronizers/synchronizer-local/index.js +1 -1
  184. package/synchronizers/synchronizer-local/with-schemas/index.js +1 -1
  185. package/with-schemas/index.js +37 -4
@@ -1012,7 +1012,8 @@ const createCheckpoints = getCreateFunction(
1012
1012
  cellOrValueIsEqual(oldNew[0], newCell) &&
1013
1013
  collIsEmpty(mapSet(row, cellId)) &&
1014
1014
  collIsEmpty(mapSet(table, rowId)) &&
1015
- collIsEmpty(mapSet(cellsDelta, tableId))
1015
+ collIsEmpty(mapSet(cellsDelta, tableId)) &&
1016
+ collIsEmpty(valuesDelta)
1016
1017
  ) {
1017
1018
  storeUnchanged();
1018
1019
  }
@@ -1032,7 +1033,8 @@ const createCheckpoints = getCreateFunction(
1032
1033
  oldNew[1] = newValue;
1033
1034
  if (
1034
1035
  cellOrValueIsEqual(oldNew[0], newValue) &&
1035
- collIsEmpty(mapSet(valuesDelta, valueId))
1036
+ collIsEmpty(mapSet(valuesDelta, valueId)) &&
1037
+ collIsEmpty(cellsDelta)
1036
1038
  ) {
1037
1039
  storeUnchanged();
1038
1040
  }
@@ -4274,7 +4276,8 @@ const numericAggregators = mapNew([
4274
4276
  [
4275
4277
  (numbers, length) => arraySum(numbers) / length,
4276
4278
  (metric, add, length) => metric + (add - metric) / (length + 1),
4277
- (metric, remove, length) => metric + (metric - remove) / (length - 1),
4279
+ (metric, remove, length) =>
4280
+ length > 1 ? metric + (metric - remove) / (length - 1) : void 0,
4278
4281
  (metric, add, remove, length) => metric + (add - remove) / length,
4279
4282
  ],
4280
4283
  ],
@@ -5160,10 +5163,74 @@ const getPlaceholders = (array, getPlaceholder, offset = [1]) =>
5160
5163
  arrayMap(array, () => getPlaceholder(offset)),
5161
5164
  COMMA,
5162
5165
  );
5163
- const getWhereCondition = (tableName, condition = TRUE) =>
5164
- WHERE + `(${replaceTableName(condition, escapeId(tableName))})`;
5166
+ const getWhere = (tableName, condition = TRUE, extraCondition) => {
5167
+ const conditions = arrayFilter(
5168
+ [
5169
+ condition == TRUE
5170
+ ? void 0
5171
+ : `(${replaceTableName(condition, escapeId(tableName))})`,
5172
+ extraCondition,
5173
+ ],
5174
+ (condition2) => !isUndefined(condition2),
5175
+ );
5176
+ return isEmpty(conditions)
5177
+ ? EMPTY_STRING
5178
+ : WHERE + arrayJoin(conditions, 'AND');
5179
+ };
5165
5180
  const replaceTableName = (condition, tableName) =>
5166
5181
  strReplace(condition, TABLE_NAME_PLACEHOLDER_REGEX, tableName);
5182
+ const updateThenInsertUpsert = async (
5183
+ executeCommand,
5184
+ tableName,
5185
+ rowIdColumnName,
5186
+ changingColumnNames,
5187
+ rows,
5188
+ getPlaceholder,
5189
+ ) => {
5190
+ const updateOffset = [1];
5191
+ const assignments = arrayJoin(
5192
+ arrayMap(
5193
+ changingColumnNames,
5194
+ (columnName) => escapeId(columnName) + '=' + getPlaceholder(updateOffset),
5195
+ ),
5196
+ COMMA,
5197
+ );
5198
+ const rowIdPlaceholder = getPlaceholder(updateOffset);
5199
+ for (const [id, row] of objToArray(rows, (row2, id2) => [id2, row2])) {
5200
+ const rowParams = arrayMap(row, (value) => value ?? null);
5201
+ if (
5202
+ isEmpty(
5203
+ await executeCommand(
5204
+ UPDATE +
5205
+ escapeId(tableName) +
5206
+ ' SET' +
5207
+ assignments +
5208
+ ' ' +
5209
+ WHERE +
5210
+ escapeId(rowIdColumnName) +
5211
+ '=' +
5212
+ rowIdPlaceholder +
5213
+ ' RETURNING' +
5214
+ escapeId(rowIdColumnName),
5215
+ [...rowParams, id],
5216
+ ),
5217
+ )
5218
+ ) {
5219
+ const offset = [1];
5220
+ await executeCommand(
5221
+ INSERT +
5222
+ ' INTO' +
5223
+ escapeId(tableName) +
5224
+ '(' +
5225
+ escapeColumnNames(rowIdColumnName, ...changingColumnNames) +
5226
+ ')VALUES(' +
5227
+ getPlaceholders([id, ...row], getPlaceholder, offset) +
5228
+ ')',
5229
+ [id, ...rowParams],
5230
+ );
5231
+ }
5232
+ }
5233
+ };
5167
5234
 
5168
5235
  const COLUMN_NAME = 'ColumnName';
5169
5236
  const STORE = 'store';
@@ -5336,7 +5403,7 @@ const getCommandFunctions = (
5336
5403
  await executeCommand(
5337
5404
  SELECT_STAR_FROM +
5338
5405
  escapeId(tableName) +
5339
- getWhereCondition(tableName, condition),
5406
+ getWhere(tableName, condition),
5340
5407
  ),
5341
5408
  (row) => {
5342
5409
  const rowId = row[rowIdColumnName];
@@ -5492,9 +5559,7 @@ const getCommandFunctions = (
5492
5559
  if (isUndefined(content)) {
5493
5560
  if (isUndefined(contentSubIdSet)) {
5494
5561
  await executeCommand(
5495
- DELETE_FROM +
5496
- escapeId(tableName) +
5497
- getWhereCondition(tableName, condition),
5562
+ DELETE_FROM + escapeId(tableName) + getWhere(tableName, condition),
5498
5563
  );
5499
5564
  }
5500
5565
  } else {
@@ -5504,8 +5569,11 @@ const getCommandFunctions = (
5504
5569
  await executeCommand(
5505
5570
  DELETE_FROM +
5506
5571
  escapeId(tableName) +
5507
- getWhereCondition(tableName, condition) +
5508
- `AND(${escapeId(rowIdColumnName)}=${getPlaceholder([1])})`,
5572
+ getWhere(
5573
+ tableName,
5574
+ condition,
5575
+ `(${escapeId(rowIdColumnName)}=${getPlaceholder([1])})`,
5576
+ ),
5509
5577
  [rowId],
5510
5578
  );
5511
5579
  } else if (!isEmpty(settingColumnNames)) {
@@ -5564,8 +5632,12 @@ const getCommandFunctions = (
5564
5632
  await executeCommand(
5565
5633
  DELETE_FROM +
5566
5634
  escapeId(tableName) +
5567
- getWhereCondition(tableName, condition) + // eslint-disable-next-line max-len
5568
- `AND${escapeId(rowIdColumnName)}NOT IN(${getPlaceholders(deleteRowIds, getPlaceholder)})`,
5635
+ getWhere(
5636
+ tableName,
5637
+ condition,
5638
+ // eslint-disable-next-line max-len
5639
+ `${escapeId(rowIdColumnName)}NOT IN(${getPlaceholders(deleteRowIds, getPlaceholder)})`,
5640
+ ),
5569
5641
  deleteRowIds,
5570
5642
  );
5571
5643
  } else if (
@@ -5573,9 +5645,7 @@ const getCommandFunctions = (
5573
5645
  collHas(schemaMap, tableName)
5574
5646
  ) {
5575
5647
  await executeCommand(
5576
- DELETE_FROM +
5577
- escapeId(tableName) +
5578
- getWhereCondition(tableName, condition),
5648
+ DELETE_FROM + escapeId(tableName) + getWhere(tableName, condition),
5579
5649
  );
5580
5650
  }
5581
5651
  }
@@ -7346,30 +7416,28 @@ const createLibSqlPersister = (
7346
7416
  client,
7347
7417
  'getClient',
7348
7418
  void 0,
7349
- client.protocol == 'file'
7350
- ? void 0
7351
- : async (actions) => {
7352
- onSqlCommand?.('BEGIN');
7353
- const transaction = await client.transaction('write');
7354
- return await tryFinallyAsync(
7355
- async () => {
7356
- try {
7357
- const result = await actions(async (sql, args = []) => {
7358
- onSqlCommand?.(sql, args);
7359
- return (await transaction.execute({sql, args})).rows;
7360
- });
7361
- await transaction.commit();
7362
- onSqlCommand?.('END');
7363
- return result;
7364
- } catch (error) {
7365
- await tryCatch(() => transaction.rollback());
7366
- onSqlCommand?.('ROLLBACK');
7367
- throw error;
7368
- }
7369
- },
7370
- () => transaction.close(),
7371
- );
7419
+ async (actions) => {
7420
+ onSqlCommand?.('BEGIN');
7421
+ const transaction = await client.transaction('write');
7422
+ return await tryFinallyAsync(
7423
+ async () => {
7424
+ try {
7425
+ const result = await actions(async (sql, args) => {
7426
+ onSqlCommand?.(sql, args);
7427
+ return (await transaction.execute({sql, args: args ?? []})).rows;
7428
+ });
7429
+ await transaction.commit();
7430
+ onSqlCommand?.('END');
7431
+ return result;
7432
+ } catch (error) {
7433
+ await tryCatch(() => transaction.rollback());
7434
+ onSqlCommand?.('ROLLBACK');
7435
+ throw error;
7436
+ }
7372
7437
  },
7438
+ () => transaction.close(),
7439
+ );
7440
+ },
7373
7441
  );
7374
7442
 
7375
7443
  const SET_CHANGES = 's';
@@ -7960,60 +8028,8 @@ const createPowerSyncPersister = (
7960
8028
  // StoreOnly,
7961
8029
  powerSync,
7962
8030
  'getPowerSync',
7963
- powerSyncUpdateThenInsert,
7964
- );
7965
- };
7966
- const powerSyncUpdateThenInsert = async (
7967
- executeCommand,
7968
- tableName,
7969
- rowIdColumnName,
7970
- changingColumnNames,
7971
- rows,
7972
- getPlaceholder,
7973
- ) => {
7974
- const updateOffset = [1];
7975
- const assignments = arrayJoin(
7976
- arrayMap(
7977
- changingColumnNames,
7978
- (columnName) => escapeId(columnName) + '=' + getPlaceholder(updateOffset),
7979
- ),
7980
- COMMA,
8031
+ updateThenInsertUpsert,
7981
8032
  );
7982
- const rowIdPlaceholder = getPlaceholder(updateOffset);
7983
- for (const [id, row] of objToArray(rows, (row2, id2) => [id2, row2])) {
7984
- const rowParams = arrayMap(row, (value) => value ?? null);
7985
- if (
7986
- isEmpty(
7987
- await executeCommand(
7988
- UPDATE +
7989
- escapeId(tableName) +
7990
- ' SET' +
7991
- assignments +
7992
- ' ' +
7993
- WHERE +
7994
- escapeId(rowIdColumnName) +
7995
- '=' +
7996
- rowIdPlaceholder +
7997
- ' RETURNING' +
7998
- escapeId(rowIdColumnName),
7999
- [...rowParams, id],
8000
- ),
8001
- )
8002
- ) {
8003
- const offset = [1];
8004
- await executeCommand(
8005
- INSERT +
8006
- ' INTO' +
8007
- escapeId(tableName) +
8008
- '(' +
8009
- escapeColumnNames(rowIdColumnName, ...changingColumnNames) +
8010
- ')VALUES(' +
8011
- getPlaceholders([id, ...row], getPlaceholder, offset) +
8012
- ')',
8013
- [id, ...rowParams],
8014
- );
8015
- }
8016
- }
8017
8033
  };
8018
8034
 
8019
8035
  const createReactNativeMmkvPersister = (
@@ -8362,6 +8378,70 @@ const createSupabasePersister = (
8362
8378
  );
8363
8379
  };
8364
8380
 
8381
+ const LIMIT_0 = 'LIMIT 0';
8382
+ const createTinyJoinPersister = (
8383
+ store,
8384
+ tinyJoin,
8385
+ configOrStoreTableName,
8386
+ onSqlCommand,
8387
+ onIgnoredError,
8388
+ ) => {
8389
+ const executeCommand = getWrappedCommand(
8390
+ async (sql, params = []) => (await tinyJoin.query(sql, params)).rows,
8391
+ onSqlCommand,
8392
+ );
8393
+ const [isJson, , defaultedConfig, managedTableNamesSet] = getConfigStructures(
8394
+ configOrStoreTableName,
8395
+ );
8396
+ if (!isJson && store.isMergeable()) {
8397
+ errorThrow(ERROR_STORE_TYPE);
8398
+ }
8399
+ const managedTableNames = collValues(managedTableNamesSet);
8400
+ const querySchema = async () => {
8401
+ const schema = [];
8402
+ await promiseAll(
8403
+ arrayMap(managedTableNames, async (tn) => {
8404
+ const sql = SELECT_STAR_FROM + escapeId(tn) + LIMIT_0;
8405
+ onSqlCommand?.(sql);
8406
+ await tryCatchIgnore(async () =>
8407
+ arrayForEach((await tinyJoin.query(sql)).fields, ({name}) =>
8408
+ arrayPush(schema, {tn, cn: name}),
8409
+ ),
8410
+ );
8411
+ }),
8412
+ );
8413
+ return schema;
8414
+ };
8415
+ const addPersisterListener = (listener) =>
8416
+ tinyJoin.subscribe(
8417
+ {tables: managedTableNames},
8418
+ () => void tryCatchIgnore(listener, onIgnoredError),
8419
+ );
8420
+ const delPersisterListener = (unsubscribe) => unsubscribe();
8421
+ const executeTransaction = (actions) => actions(executeCommand);
8422
+ return (isJson ? createJsonPersister : createTabularPersister)(
8423
+ store,
8424
+ executeCommand,
8425
+ addPersisterListener,
8426
+ delPersisterListener,
8427
+ onIgnoredError,
8428
+ noop,
8429
+ 3,
8430
+ // StoreOrMergeableStore,
8431
+ defaultedConfig,
8432
+ managedTableNames,
8433
+ querySchema,
8434
+ tinyJoin,
8435
+ 'getTinyJoin',
8436
+ 'text',
8437
+ numberedPlaceholder,
8438
+ updateThenInsertUpsert,
8439
+ (cellOrValue) => jsonString(cellOrValue),
8440
+ (field) => jsonParse(field),
8441
+ executeTransaction,
8442
+ );
8443
+ };
8444
+
8365
8445
  const DELETE = 'delete';
8366
8446
  const getYMap = (yMap) =>
8367
8447
  yMap instanceof Map$1 ? yMap : errorThrow(ERROR_CONTENT);
@@ -9737,11 +9817,21 @@ const createRelationships = getCreateFunction((store) => {
9737
9817
  remoteTableId,
9738
9818
  getRemoteRowId2,
9739
9819
  ) => {
9820
+ mapForEach(mapGet(linkedRowIdsListeners, relationshipId), (firstRowId) =>
9821
+ getLinkedRowIdsCache(relationshipId, firstRowId),
9822
+ );
9740
9823
  mapSet(remoteTableIds, relationshipId, remoteTableId);
9741
9824
  setDefinitionAndListen(
9742
9825
  relationshipId,
9743
9826
  localTableId,
9744
- (change, changedRemoteRowIds) => {
9827
+ (
9828
+ change,
9829
+ changedRemoteRowIds,
9830
+ _changedSortKeys,
9831
+ _rowValues,
9832
+ _sortKeys,
9833
+ force,
9834
+ ) => {
9745
9835
  const changedLocalRows = setNew();
9746
9836
  const changedRemoteRows = setNew();
9747
9837
  const changedLinkedRows = setNew();
@@ -9786,6 +9876,26 @@ const createRelationships = getCreateFunction((store) => {
9786
9876
  },
9787
9877
  );
9788
9878
  change();
9879
+ if (force) {
9880
+ mapForEach(
9881
+ mapGet(linkedRowIdsListeners, relationshipId),
9882
+ (firstRowId) => {
9883
+ const oldLinkedRowIds = getLinkedRowIds(
9884
+ relationshipId,
9885
+ firstRowId,
9886
+ );
9887
+ delLinkedRowIdsCache(relationshipId, firstRowId);
9888
+ if (
9889
+ !arrayIsEqual(
9890
+ oldLinkedRowIds,
9891
+ getLinkedRowIds(relationshipId, firstRowId),
9892
+ )
9893
+ ) {
9894
+ setAdd(changedLinkedRows, firstRowId);
9895
+ }
9896
+ },
9897
+ );
9898
+ }
9789
9899
  collForEach(changedLocalRows, (localRowId) =>
9790
9900
  callListeners(remoteRowIdListeners, [relationshipId, localRowId]),
9791
9901
  );
@@ -10810,7 +10920,7 @@ const createLocalSynchronizer = (store, onSend, onReceive, onIgnoredError) => {
10810
10920
  send,
10811
10921
  registerReceive,
10812
10922
  destroy,
10813
- 0.01,
10923
+ 0.05,
10814
10924
  onSend,
10815
10925
  onReceive,
10816
10926
  onIgnoredError,
@@ -12716,6 +12826,7 @@ export {
12716
12826
  createSqliteWasmPersister,
12717
12827
  createStore,
12718
12828
  createSupabasePersister,
12829
+ createTinyJoinPersister,
12719
12830
  createWsServer,
12720
12831
  createWsServerSimple,
12721
12832
  createWsSynchronizer,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "tinybase",
3
- "version": "10.0.0-beta.0",
3
+ "version": "10.0.0-beta.2",
4
4
  "author": "jamesgpearce",
5
5
  "repository": {
6
6
  "type": "git",
@@ -35,36 +35,37 @@
35
35
  "peerDependencies": {
36
36
  "@automerge/automerge-repo": "^2.5.6",
37
37
  "@capacitor-community/sqlite": "^8.1.1",
38
- "@cloudflare/workers-types": "^5.20260902.1",
38
+ "@cloudflare/workers-types": "^5.20260911.1",
39
39
  "@electric-sql/pglite": "^0.5.8",
40
- "@libsql/client": "^0.17.4",
41
- "@powersync/common": "^2.2.0",
40
+ "@libsql/client": "^0.18.0",
41
+ "@powersync/common": "^2.2.1",
42
42
  "@sinclair/typebox": "^0.34.52",
43
- "@sqlite.org/sqlite-wasm": "^3.53.0-build1",
44
- "@supabase/supabase-js": "^2.114.0",
43
+ "@sqlite.org/sqlite-wasm": "^3.53.4-build1",
44
+ "@supabase/supabase-js": "^2.116.0",
45
45
  "@vlcn.io/crsqlite-wasm": "^0.16.0",
46
46
  "arktype": "^2.2.3",
47
47
  "better-sqlite3": "^13.0.3",
48
- "bun": "^1.4.0",
49
- "effect": "^3.22.1",
48
+ "bun": "^1.4.2",
49
+ "effect": "^3.22.2",
50
50
  "electric-sql": "^0.12.1",
51
- "expo": "^57.0.19",
52
- "expo-sqlite": "^57.0.2",
51
+ "expo": "^57.0.22",
52
+ "expo-sqlite": "^57.0.3",
53
53
  "partykit": "^0.0.115",
54
54
  "partysocket": "^1.3.0",
55
55
  "pg": "^8.23.0",
56
56
  "postgres": "^3.4.9",
57
- "react": "^19.2.8",
58
- "react-dom": "^19.2.8",
57
+ "react": "^19.3.0",
58
+ "react-dom": "^19.3.0",
59
59
  "react-native-mmkv": "^4.3.2",
60
60
  "react-native-sqlite-storage": "^6.0.1",
61
61
  "solid-js": "^1.9.15",
62
62
  "sqlite3": "^6.0.1",
63
63
  "svelte": "^5.57.0",
64
- "valibot": "^1.4.2",
64
+ "tinyjoin": "^0.1.0",
65
+ "valibot": "^1.5.0",
65
66
  "ws": "^8.21.3",
66
67
  "yjs": "^13.6.32",
67
- "zod": "^4.5.4"
68
+ "zod": "^4.6.2"
68
69
  },
69
70
  "peerDependenciesMeta": {
70
71
  "@automerge/automerge-repo": {
@@ -151,6 +152,9 @@
151
152
  "svelte": {
152
153
  "optional": true
153
154
  },
155
+ "tinyjoin": {
156
+ "optional": true
157
+ },
154
158
  "valibot": {
155
159
  "optional": true
156
160
  },
@@ -384,6 +388,12 @@
384
388
  "persisters/persister-supabase/with-schemas": [
385
389
  "./@types/persisters/persister-supabase/with-schemas/index.d.ts"
386
390
  ],
391
+ "persisters/persister-tinyjoin": [
392
+ "./@types/persisters/persister-tinyjoin/index.d.ts"
393
+ ],
394
+ "persisters/persister-tinyjoin/with-schemas": [
395
+ "./@types/persisters/persister-tinyjoin/with-schemas/index.d.ts"
396
+ ],
387
397
  "persisters/persister-yjs": [
388
398
  "./@types/persisters/persister-yjs/index.d.ts"
389
399
  ],
@@ -762,6 +772,12 @@
762
772
  "min/persisters/persister-supabase/with-schemas": [
763
773
  "./@types/persisters/persister-supabase/with-schemas/index.d.ts"
764
774
  ],
775
+ "min/persisters/persister-tinyjoin": [
776
+ "./@types/persisters/persister-tinyjoin/index.d.ts"
777
+ ],
778
+ "min/persisters/persister-tinyjoin/with-schemas": [
779
+ "./@types/persisters/persister-tinyjoin/with-schemas/index.d.ts"
780
+ ],
765
781
  "min/persisters/persister-yjs": [
766
782
  "./@types/persisters/persister-yjs/index.d.ts"
767
783
  ],
@@ -1353,6 +1369,18 @@
1353
1369
  "default": "./persisters/persister-supabase/index.js"
1354
1370
  }
1355
1371
  },
1372
+ "./persisters/persister-tinyjoin": {
1373
+ "default": {
1374
+ "types": "./@types/persisters/persister-tinyjoin/index.d.ts",
1375
+ "default": "./persisters/persister-tinyjoin/index.js"
1376
+ }
1377
+ },
1378
+ "./persisters/persister-tinyjoin/with-schemas": {
1379
+ "default": {
1380
+ "types": "./@types/persisters/persister-tinyjoin/with-schemas/index.d.ts",
1381
+ "default": "./persisters/persister-tinyjoin/index.js"
1382
+ }
1383
+ },
1356
1384
  "./persisters/persister-yjs": {
1357
1385
  "default": {
1358
1386
  "types": "./@types/persisters/persister-yjs/index.d.ts",
@@ -2093,6 +2121,18 @@
2093
2121
  "default": "./min/persisters/persister-supabase/index.js"
2094
2122
  }
2095
2123
  },
2124
+ "./min/persisters/persister-tinyjoin": {
2125
+ "default": {
2126
+ "types": "./@types/persisters/persister-tinyjoin/index.d.ts",
2127
+ "default": "./min/persisters/persister-tinyjoin/index.js"
2128
+ }
2129
+ },
2130
+ "./min/persisters/persister-tinyjoin/with-schemas": {
2131
+ "default": {
2132
+ "types": "./@types/persisters/persister-tinyjoin/with-schemas/index.d.ts",
2133
+ "default": "./min/persisters/persister-tinyjoin/index.js"
2134
+ }
2135
+ },
2096
2136
  "./min/persisters/persister-yjs": {
2097
2137
  "default": {
2098
2138
  "types": "./@types/persisters/persister-yjs/index.d.ts",
@@ -883,8 +883,20 @@ const getPlaceholders = (array, getPlaceholder, offset = [1]) =>
883
883
  arrayMap(array, () => getPlaceholder(offset)),
884
884
  COMMA,
885
885
  );
886
- const getWhereCondition = (tableName, condition = TRUE) =>
887
- WHERE + `(${replaceTableName(condition, escapeId(tableName))})`;
886
+ const getWhere = (tableName, condition = TRUE, extraCondition) => {
887
+ const conditions = arrayFilter(
888
+ [
889
+ condition == TRUE
890
+ ? void 0
891
+ : `(${replaceTableName(condition, escapeId(tableName))})`,
892
+ extraCondition,
893
+ ],
894
+ (condition2) => !isUndefined(condition2),
895
+ );
896
+ return isEmpty(conditions)
897
+ ? EMPTY_STRING
898
+ : WHERE + arrayJoin(conditions, 'AND');
899
+ };
888
900
  const replaceTableName = (condition, tableName) =>
889
901
  strReplace(condition, TABLE_NAME_PLACEHOLDER_REGEX, tableName);
890
902
 
@@ -1059,7 +1071,7 @@ const getCommandFunctions = (
1059
1071
  await executeCommand(
1060
1072
  SELECT_STAR_FROM +
1061
1073
  escapeId(tableName) +
1062
- getWhereCondition(tableName, condition),
1074
+ getWhere(tableName, condition),
1063
1075
  ),
1064
1076
  (row) => {
1065
1077
  const rowId = row[rowIdColumnName];
@@ -1215,9 +1227,7 @@ const getCommandFunctions = (
1215
1227
  if (isUndefined(content)) {
1216
1228
  if (isUndefined(contentSubIdSet)) {
1217
1229
  await executeCommand(
1218
- DELETE_FROM +
1219
- escapeId(tableName) +
1220
- getWhereCondition(tableName, condition),
1230
+ DELETE_FROM + escapeId(tableName) + getWhere(tableName, condition),
1221
1231
  );
1222
1232
  }
1223
1233
  } else {
@@ -1227,8 +1237,11 @@ const getCommandFunctions = (
1227
1237
  await executeCommand(
1228
1238
  DELETE_FROM +
1229
1239
  escapeId(tableName) +
1230
- getWhereCondition(tableName, condition) +
1231
- `AND(${escapeId(rowIdColumnName)}=${getPlaceholder([1])})`,
1240
+ getWhere(
1241
+ tableName,
1242
+ condition,
1243
+ `(${escapeId(rowIdColumnName)}=${getPlaceholder([1])})`,
1244
+ ),
1232
1245
  [rowId],
1233
1246
  );
1234
1247
  } else if (!isEmpty(settingColumnNames)) {
@@ -1287,8 +1300,12 @@ const getCommandFunctions = (
1287
1300
  await executeCommand(
1288
1301
  DELETE_FROM +
1289
1302
  escapeId(tableName) +
1290
- getWhereCondition(tableName, condition) + // eslint-disable-next-line max-len
1291
- `AND${escapeId(rowIdColumnName)}NOT IN(${getPlaceholders(deleteRowIds, getPlaceholder)})`,
1303
+ getWhere(
1304
+ tableName,
1305
+ condition,
1306
+ // eslint-disable-next-line max-len
1307
+ `${escapeId(rowIdColumnName)}NOT IN(${getPlaceholders(deleteRowIds, getPlaceholder)})`,
1308
+ ),
1292
1309
  deleteRowIds,
1293
1310
  );
1294
1311
  } else if (
@@ -1296,9 +1313,7 @@ const getCommandFunctions = (
1296
1313
  collHas(schemaMap, tableName)
1297
1314
  ) {
1298
1315
  await executeCommand(
1299
- DELETE_FROM +
1300
- escapeId(tableName) +
1301
- getWhereCondition(tableName, condition),
1316
+ DELETE_FROM + escapeId(tableName) + getWhere(tableName, condition),
1302
1317
  );
1303
1318
  }
1304
1319
  }