tinybase 8.6.0-beta.0 → 9.0.0-beta.1

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 (253) 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/mergeable-store/index.d.ts +4 -4
  4. package/@types/mergeable-store/with-schemas/index.d.ts +41 -17
  5. package/@types/persisters/index.d.ts +34 -13
  6. package/@types/persisters/persister-durable-object-sql-storage/index.d.ts +9 -8
  7. package/@types/persisters/persister-durable-object-sql-storage/with-schemas/index.d.ts +10 -10
  8. package/@types/persisters/with-schemas/index.d.ts +72 -30
  9. package/@types/queries/index.d.ts +5 -7
  10. package/@types/queries/with-schemas/index.d.ts +9 -15
  11. package/@types/store/index.d.ts +1 -2
  12. package/@types/store/with-schemas/index.d.ts +19 -29
  13. package/@types/synchronizers/synchronizer-ws-client/index.d.ts +9 -3
  14. package/@types/synchronizers/synchronizer-ws-client/with-schemas/index.d.ts +10 -3
  15. package/@types/synchronizers/synchronizer-ws-server/index.d.ts +15 -2
  16. package/@types/synchronizers/synchronizer-ws-server/with-schemas/index.d.ts +17 -2
  17. package/@types/synchronizers/synchronizer-ws-server-durable-object/index.d.ts +51 -0
  18. package/@types/synchronizers/synchronizer-ws-server-durable-object/with-schemas/index.d.ts +51 -0
  19. package/@types/ui-react/with-schemas/index.d.ts +3 -6
  20. package/@types/ui-react-dom/with-schemas/index.d.ts +6 -12
  21. package/@types/ui-react-dom-charts/with-schemas/index.d.ts +3 -4
  22. package/@types/ui-solid/with-schemas/index.d.ts +4 -8
  23. package/@types/ui-solid-dom/with-schemas/index.d.ts +6 -12
  24. package/@types/ui-svelte-dom/with-schemas/index.d.ts +6 -12
  25. package/index.js +67 -25
  26. package/indexes/index.js +6 -8
  27. package/indexes/with-schemas/index.js +6 -8
  28. package/mergeable-store/index.js +46 -6
  29. package/mergeable-store/with-schemas/index.js +46 -6
  30. package/metrics/index.js +6 -8
  31. package/metrics/with-schemas/index.js +6 -8
  32. package/min/index.js +1 -1
  33. package/min/index.js.gz +0 -0
  34. package/min/mergeable-store/index.js +1 -1
  35. package/min/mergeable-store/index.js.gz +0 -0
  36. package/min/mergeable-store/with-schemas/index.js +1 -1
  37. package/min/mergeable-store/with-schemas/index.js.gz +0 -0
  38. package/min/omni/index.js +1 -1
  39. package/min/omni/index.js.gz +0 -0
  40. package/min/omni/with-schemas/index.js +1 -1
  41. package/min/omni/with-schemas/index.js.gz +0 -0
  42. package/min/persisters/index.js +1 -1
  43. package/min/persisters/index.js.gz +0 -0
  44. package/min/persisters/persister-automerge/index.js +1 -1
  45. package/min/persisters/persister-automerge/index.js.gz +0 -0
  46. package/min/persisters/persister-automerge/with-schemas/index.js +1 -1
  47. package/min/persisters/persister-automerge/with-schemas/index.js.gz +0 -0
  48. package/min/persisters/persister-browser/index.js +1 -1
  49. package/min/persisters/persister-browser/index.js.gz +0 -0
  50. package/min/persisters/persister-browser/with-schemas/index.js +1 -1
  51. package/min/persisters/persister-browser/with-schemas/index.js.gz +0 -0
  52. package/min/persisters/persister-cr-sqlite-wasm/index.js +1 -1
  53. package/min/persisters/persister-cr-sqlite-wasm/index.js.gz +0 -0
  54. package/min/persisters/persister-cr-sqlite-wasm/with-schemas/index.js +1 -1
  55. package/min/persisters/persister-cr-sqlite-wasm/with-schemas/index.js.gz +0 -0
  56. package/min/persisters/persister-durable-object-sql-storage/index.js +1 -1
  57. package/min/persisters/persister-durable-object-sql-storage/index.js.gz +0 -0
  58. package/min/persisters/persister-durable-object-sql-storage/with-schemas/index.js +1 -1
  59. package/min/persisters/persister-durable-object-sql-storage/with-schemas/index.js.gz +0 -0
  60. package/min/persisters/persister-durable-object-storage/index.js +1 -1
  61. package/min/persisters/persister-durable-object-storage/index.js.gz +0 -0
  62. package/min/persisters/persister-durable-object-storage/with-schemas/index.js +1 -1
  63. package/min/persisters/persister-durable-object-storage/with-schemas/index.js.gz +0 -0
  64. package/min/persisters/persister-electric-sql/index.js +1 -1
  65. package/min/persisters/persister-electric-sql/index.js.gz +0 -0
  66. package/min/persisters/persister-electric-sql/with-schemas/index.js +1 -1
  67. package/min/persisters/persister-electric-sql/with-schemas/index.js.gz +0 -0
  68. package/min/persisters/persister-expo-sqlite/index.js +1 -1
  69. package/min/persisters/persister-expo-sqlite/index.js.gz +0 -0
  70. package/min/persisters/persister-expo-sqlite/with-schemas/index.js +1 -1
  71. package/min/persisters/persister-expo-sqlite/with-schemas/index.js.gz +0 -0
  72. package/min/persisters/persister-file/index.js +1 -1
  73. package/min/persisters/persister-file/index.js.gz +0 -0
  74. package/min/persisters/persister-file/with-schemas/index.js +1 -1
  75. package/min/persisters/persister-file/with-schemas/index.js.gz +0 -0
  76. package/min/persisters/persister-indexed-db/index.js +1 -1
  77. package/min/persisters/persister-indexed-db/index.js.gz +0 -0
  78. package/min/persisters/persister-indexed-db/with-schemas/index.js +1 -1
  79. package/min/persisters/persister-indexed-db/with-schemas/index.js.gz +0 -0
  80. package/min/persisters/persister-libsql/index.js +1 -1
  81. package/min/persisters/persister-libsql/index.js.gz +0 -0
  82. package/min/persisters/persister-libsql/with-schemas/index.js +1 -1
  83. package/min/persisters/persister-libsql/with-schemas/index.js.gz +0 -0
  84. package/min/persisters/persister-partykit-client/index.js +1 -1
  85. package/min/persisters/persister-partykit-client/index.js.gz +0 -0
  86. package/min/persisters/persister-partykit-client/with-schemas/index.js +1 -1
  87. package/min/persisters/persister-partykit-client/with-schemas/index.js.gz +0 -0
  88. package/min/persisters/persister-pglite/index.js +1 -1
  89. package/min/persisters/persister-pglite/index.js.gz +0 -0
  90. package/min/persisters/persister-pglite/with-schemas/index.js +1 -1
  91. package/min/persisters/persister-pglite/with-schemas/index.js.gz +0 -0
  92. package/min/persisters/persister-postgres/index.js +1 -1
  93. package/min/persisters/persister-postgres/index.js.gz +0 -0
  94. package/min/persisters/persister-postgres/with-schemas/index.js +1 -1
  95. package/min/persisters/persister-postgres/with-schemas/index.js.gz +0 -0
  96. package/min/persisters/persister-powersync/index.js +1 -1
  97. package/min/persisters/persister-powersync/index.js.gz +0 -0
  98. package/min/persisters/persister-powersync/with-schemas/index.js +1 -1
  99. package/min/persisters/persister-powersync/with-schemas/index.js.gz +0 -0
  100. package/min/persisters/persister-react-native-mmkv/index.js +1 -1
  101. package/min/persisters/persister-react-native-mmkv/index.js.gz +0 -0
  102. package/min/persisters/persister-react-native-mmkv/with-schemas/index.js +1 -1
  103. package/min/persisters/persister-react-native-mmkv/with-schemas/index.js.gz +0 -0
  104. package/min/persisters/persister-react-native-sqlite/index.js +1 -1
  105. package/min/persisters/persister-react-native-sqlite/index.js.gz +0 -0
  106. package/min/persisters/persister-react-native-sqlite/with-schemas/index.js +1 -1
  107. package/min/persisters/persister-react-native-sqlite/with-schemas/index.js.gz +0 -0
  108. package/min/persisters/persister-remote/index.js +1 -1
  109. package/min/persisters/persister-remote/index.js.gz +0 -0
  110. package/min/persisters/persister-remote/with-schemas/index.js +1 -1
  111. package/min/persisters/persister-remote/with-schemas/index.js.gz +0 -0
  112. package/min/persisters/persister-sqlite-bun/index.js +1 -1
  113. package/min/persisters/persister-sqlite-bun/index.js.gz +0 -0
  114. package/min/persisters/persister-sqlite-bun/with-schemas/index.js +1 -1
  115. package/min/persisters/persister-sqlite-bun/with-schemas/index.js.gz +0 -0
  116. package/min/persisters/persister-sqlite-wasm/index.js +1 -1
  117. package/min/persisters/persister-sqlite-wasm/index.js.gz +0 -0
  118. package/min/persisters/persister-sqlite-wasm/with-schemas/index.js +1 -1
  119. package/min/persisters/persister-sqlite-wasm/with-schemas/index.js.gz +0 -0
  120. package/min/persisters/persister-sqlite3/index.js +1 -1
  121. package/min/persisters/persister-sqlite3/index.js.gz +0 -0
  122. package/min/persisters/persister-sqlite3/with-schemas/index.js +1 -1
  123. package/min/persisters/persister-sqlite3/with-schemas/index.js.gz +0 -0
  124. package/min/persisters/persister-yjs/index.js +1 -1
  125. package/min/persisters/persister-yjs/index.js.gz +0 -0
  126. package/min/persisters/persister-yjs/with-schemas/index.js +1 -1
  127. package/min/persisters/persister-yjs/with-schemas/index.js.gz +0 -0
  128. package/min/persisters/with-schemas/index.js +1 -1
  129. package/min/persisters/with-schemas/index.js.gz +0 -0
  130. package/min/queries/index.js +1 -1
  131. package/min/queries/index.js.gz +0 -0
  132. package/min/queries/with-schemas/index.js +1 -1
  133. package/min/queries/with-schemas/index.js.gz +0 -0
  134. package/min/store/index.js +1 -1
  135. package/min/store/index.js.gz +0 -0
  136. package/min/store/with-schemas/index.js +1 -1
  137. package/min/store/with-schemas/index.js.gz +0 -0
  138. package/min/synchronizers/index.js +1 -1
  139. package/min/synchronizers/index.js.gz +0 -0
  140. package/min/synchronizers/synchronizer-broadcast-channel/index.js +1 -1
  141. package/min/synchronizers/synchronizer-broadcast-channel/index.js.gz +0 -0
  142. package/min/synchronizers/synchronizer-broadcast-channel/with-schemas/index.js +1 -1
  143. package/min/synchronizers/synchronizer-broadcast-channel/with-schemas/index.js.gz +0 -0
  144. package/min/synchronizers/synchronizer-local/index.js +1 -1
  145. package/min/synchronizers/synchronizer-local/index.js.gz +0 -0
  146. package/min/synchronizers/synchronizer-local/with-schemas/index.js +1 -1
  147. package/min/synchronizers/synchronizer-local/with-schemas/index.js.gz +0 -0
  148. package/min/synchronizers/synchronizer-ws-client/index.js +1 -1
  149. package/min/synchronizers/synchronizer-ws-client/index.js.gz +0 -0
  150. package/min/synchronizers/synchronizer-ws-client/with-schemas/index.js +1 -1
  151. package/min/synchronizers/synchronizer-ws-client/with-schemas/index.js.gz +0 -0
  152. package/min/synchronizers/synchronizer-ws-server/index.js +1 -1
  153. package/min/synchronizers/synchronizer-ws-server/index.js.gz +0 -0
  154. package/min/synchronizers/synchronizer-ws-server/with-schemas/index.js +1 -1
  155. package/min/synchronizers/synchronizer-ws-server/with-schemas/index.js.gz +0 -0
  156. package/min/synchronizers/synchronizer-ws-server-durable-object/index.js +1 -1
  157. package/min/synchronizers/synchronizer-ws-server-durable-object/index.js.gz +0 -0
  158. package/min/synchronizers/synchronizer-ws-server-durable-object/with-schemas/index.js +1 -1
  159. package/min/synchronizers/synchronizer-ws-server-durable-object/with-schemas/index.js.gz +0 -0
  160. package/min/synchronizers/with-schemas/index.js +1 -1
  161. package/min/synchronizers/with-schemas/index.js.gz +0 -0
  162. package/min/ui-react-inspector/index.js +1 -1
  163. package/min/ui-react-inspector/index.js.gz +0 -0
  164. package/min/ui-react-inspector/with-schemas/index.js +1 -1
  165. package/min/ui-react-inspector/with-schemas/index.js.gz +0 -0
  166. package/min/ui-solid-inspector/index.js +1 -1
  167. package/min/ui-solid-inspector/index.js.gz +0 -0
  168. package/min/ui-solid-inspector/with-schemas/index.js +1 -1
  169. package/min/ui-solid-inspector/with-schemas/index.js.gz +0 -0
  170. package/min/ui-svelte-inspector/index.js +1 -1
  171. package/min/ui-svelte-inspector/index.js.gz +0 -0
  172. package/min/ui-svelte-inspector/with-schemas/index.js +1 -1
  173. package/min/ui-svelte-inspector/with-schemas/index.js.gz +0 -0
  174. package/min/with-schemas/index.js +1 -1
  175. package/min/with-schemas/index.js.gz +0 -0
  176. package/omni/index.js +364 -155
  177. package/omni/with-schemas/index.js +364 -155
  178. package/package.json +8 -8
  179. package/persisters/index.js +133 -40
  180. package/persisters/persister-automerge/index.js +4 -3
  181. package/persisters/persister-automerge/with-schemas/index.js +4 -3
  182. package/persisters/persister-browser/index.js +4 -3
  183. package/persisters/persister-browser/with-schemas/index.js +4 -3
  184. package/persisters/persister-cr-sqlite-wasm/index.js +133 -40
  185. package/persisters/persister-cr-sqlite-wasm/with-schemas/index.js +133 -40
  186. package/persisters/persister-durable-object-sql-storage/index.js +275 -113
  187. package/persisters/persister-durable-object-sql-storage/with-schemas/index.js +275 -113
  188. package/persisters/persister-durable-object-storage/index.js +4 -3
  189. package/persisters/persister-durable-object-storage/with-schemas/index.js +4 -3
  190. package/persisters/persister-electric-sql/index.js +133 -40
  191. package/persisters/persister-electric-sql/with-schemas/index.js +133 -40
  192. package/persisters/persister-expo-sqlite/index.js +133 -40
  193. package/persisters/persister-expo-sqlite/with-schemas/index.js +133 -40
  194. package/persisters/persister-file/index.js +4 -3
  195. package/persisters/persister-file/with-schemas/index.js +4 -3
  196. package/persisters/persister-indexed-db/index.js +4 -3
  197. package/persisters/persister-indexed-db/with-schemas/index.js +4 -3
  198. package/persisters/persister-libsql/index.js +133 -40
  199. package/persisters/persister-libsql/with-schemas/index.js +133 -40
  200. package/persisters/persister-partykit-client/index.js +4 -3
  201. package/persisters/persister-partykit-client/with-schemas/index.js +4 -3
  202. package/persisters/persister-pglite/index.js +134 -40
  203. package/persisters/persister-pglite/with-schemas/index.js +134 -40
  204. package/persisters/persister-postgres/index.js +134 -40
  205. package/persisters/persister-postgres/with-schemas/index.js +134 -40
  206. package/persisters/persister-powersync/index.js +186 -120
  207. package/persisters/persister-powersync/with-schemas/index.js +186 -120
  208. package/persisters/persister-react-native-mmkv/index.js +4 -3
  209. package/persisters/persister-react-native-mmkv/with-schemas/index.js +4 -3
  210. package/persisters/persister-react-native-sqlite/index.js +133 -40
  211. package/persisters/persister-react-native-sqlite/with-schemas/index.js +133 -40
  212. package/persisters/persister-remote/index.js +4 -3
  213. package/persisters/persister-remote/with-schemas/index.js +4 -3
  214. package/persisters/persister-sqlite-bun/index.js +133 -40
  215. package/persisters/persister-sqlite-bun/with-schemas/index.js +133 -40
  216. package/persisters/persister-sqlite-wasm/index.js +133 -40
  217. package/persisters/persister-sqlite-wasm/with-schemas/index.js +133 -40
  218. package/persisters/persister-sqlite3/index.js +133 -40
  219. package/persisters/persister-sqlite3/with-schemas/index.js +133 -40
  220. package/persisters/persister-yjs/index.js +4 -3
  221. package/persisters/persister-yjs/with-schemas/index.js +4 -3
  222. package/persisters/with-schemas/index.js +133 -40
  223. package/queries/index.js +21 -19
  224. package/queries/with-schemas/index.js +21 -19
  225. package/readme.md +14 -14
  226. package/relationships/index.js +6 -8
  227. package/relationships/with-schemas/index.js +6 -8
  228. package/releases.md +72 -57
  229. package/store/index.js +33 -2
  230. package/store/with-schemas/index.js +33 -2
  231. package/synchronizers/index.js +4 -3
  232. package/synchronizers/synchronizer-broadcast-channel/index.js +4 -3
  233. package/synchronizers/synchronizer-broadcast-channel/with-schemas/index.js +4 -3
  234. package/synchronizers/synchronizer-local/index.js +4 -3
  235. package/synchronizers/synchronizer-local/with-schemas/index.js +4 -3
  236. package/synchronizers/synchronizer-ws-client/index.js +120 -45
  237. package/synchronizers/synchronizer-ws-client/with-schemas/index.js +120 -45
  238. package/synchronizers/synchronizer-ws-server/index.js +116 -36
  239. package/synchronizers/synchronizer-ws-server/with-schemas/index.js +116 -36
  240. package/synchronizers/synchronizer-ws-server-durable-object/index.js +125 -41
  241. package/synchronizers/synchronizer-ws-server-durable-object/with-schemas/index.js +125 -41
  242. package/synchronizers/with-schemas/index.js +4 -3
  243. package/ui-react-inspector/index.js +36 -5
  244. package/ui-react-inspector/with-schemas/index.js +36 -5
  245. package/ui-solid-inspector/index.js +36 -5
  246. package/ui-solid-inspector/with-schemas/index.js +36 -5
  247. package/ui-svelte/index.js +1 -1
  248. package/ui-svelte/with-schemas/index.js +1 -1
  249. package/ui-svelte-dom/index.js +2 -2
  250. package/ui-svelte-dom/with-schemas/index.js +2 -2
  251. package/ui-svelte-inspector/index.js +38 -7
  252. package/ui-svelte-inspector/with-schemas/index.js +38 -7
  253. package/with-schemas/index.js +67 -25
@@ -79,6 +79,7 @@ const startInterval = (callback, sec, immediate) => {
79
79
  const stopInterval = clearInterval;
80
80
  const startTimeout = (callback, sec = 0) =>
81
81
  setTimeout(callback, sec * THOUSAND);
82
+ const stopTimeout = clearTimeout;
82
83
  const mathMax = math.max;
83
84
  const mathMin = math.min;
84
85
  const mathFloor = math.floor;
@@ -378,14 +379,12 @@ const getDefinableFunctions = (
378
379
  const newRowValue = hasRow(tableId, rowId)
379
380
  ? validateRowValue(getRowValue(getCell, rowId))
380
381
  : void 0;
381
- if (
382
- !(
383
- oldRowValue === newRowValue ||
384
- (isArray(oldRowValue) &&
385
- isArray(newRowValue) &&
386
- arrayIsEqual(oldRowValue, newRowValue))
387
- )
388
- ) {
382
+ if (!(
383
+ oldRowValue === newRowValue ||
384
+ (isArray(oldRowValue) &&
385
+ isArray(newRowValue) &&
386
+ arrayIsEqual(oldRowValue, newRowValue))
387
+ )) {
389
388
  mapSet(changedRowValues, rowId, [oldRowValue, newRowValue]);
390
389
  }
391
390
  if (!isUndefined(getSortKey)) {
@@ -1279,8 +1278,10 @@ const createStore = () => {
1279
1278
  const changedRowIds = mapNew();
1280
1279
  const changedCellIds = mapNew();
1281
1280
  const changedCells = mapNew();
1281
+ const defaultedCells = mapNew();
1282
1282
  const changedValueIds = mapNew();
1283
1283
  const changedValues = mapNew();
1284
+ const defaultedValues = setNew();
1284
1285
  const invalidCells = mapNew();
1285
1286
  const invalidValues = mapNew();
1286
1287
  const tablesSchemaMap = mapNew();
@@ -1454,6 +1455,16 @@ const createStore = () => {
1454
1455
  collForEach(rowDefaulted, (cell, cellId) => {
1455
1456
  if (!objHas(row, cellId)) {
1456
1457
  row[cellId] = cell;
1458
+ ifNotUndefined(rowId, (rowId2) =>
1459
+ setAdd(
1460
+ mapEnsure(
1461
+ mapEnsure(defaultedCells, tableId, mapNew),
1462
+ rowId2,
1463
+ setNew,
1464
+ ),
1465
+ cellId,
1466
+ ),
1467
+ );
1457
1468
  }
1458
1469
  });
1459
1470
  collForEach(rowNonDefaulted, (cellId) => {
@@ -1470,6 +1481,7 @@ const createStore = () => {
1470
1481
  collForEach(valuesDefaulted, (value, valueId) => {
1471
1482
  if (!objHas(values, valueId)) {
1472
1483
  values[valueId] = value;
1484
+ setAdd(defaultedValues, valueId);
1473
1485
  }
1474
1486
  });
1475
1487
  collForEach(valuesNonDefaulted, (valueId) => {
@@ -1873,18 +1885,34 @@ const createStore = () => {
1873
1885
  );
1874
1886
  };
1875
1887
  const cellChanged = (tableId, rowId, cellId, oldCell, newCell) => {
1888
+ const defaulted =
1889
+ collHas(mapGet(mapGet(defaultedCells, tableId), rowId), cellId) &&
1890
+ isUndefined(oldCell)
1891
+ ? 1
1892
+ : 0;
1876
1893
  mapEnsure(
1877
1894
  mapEnsure(mapEnsure(changedCells, tableId, mapNew), rowId, mapNew),
1878
1895
  cellId,
1879
1896
  () => [oldCell, 0],
1880
1897
  )[1] = newCell;
1881
- internalListeners[3]?.(tableId, rowId, cellId, newCell, mutating);
1898
+ internalListeners[3]?.(
1899
+ tableId,
1900
+ rowId,
1901
+ cellId,
1902
+ newCell,
1903
+ mutating,
1904
+ defaulted,
1905
+ );
1906
+ collDel(mapGet(mapGet(defaultedCells, tableId), rowId), cellId);
1882
1907
  };
1883
1908
  const valueIdsChanged = (valueId, addedOrRemoved) =>
1884
1909
  idsChanged(changedValueIds, valueId, addedOrRemoved);
1885
1910
  const valueChanged = (valueId, oldValue, newValue) => {
1911
+ const defaulted =
1912
+ collHas(defaultedValues, valueId) && isUndefined(oldValue) ? 1 : 0;
1886
1913
  mapEnsure(changedValues, valueId, () => [oldValue, 0])[1] = newValue;
1887
- internalListeners[4]?.(valueId, newValue, mutating);
1914
+ internalListeners[4]?.(valueId, newValue, mutating, defaulted);
1915
+ collDel(defaultedValues, valueId);
1888
1916
  };
1889
1917
  const cellInvalid = (tableId, rowId, cellId, invalidCell, defaultedCell) => {
1890
1918
  arrayPush(
@@ -2672,9 +2700,11 @@ const createStore = () => {
2672
2700
  changedRowIds,
2673
2701
  changedCellIds,
2674
2702
  changedCells,
2703
+ defaultedCells,
2675
2704
  invalidCells,
2676
2705
  changedValueIds,
2677
2706
  changedValues,
2707
+ defaultedValues,
2678
2708
  invalidValues,
2679
2709
  ],
2680
2710
  collClear,
@@ -3179,7 +3209,14 @@ const createMergeableStore = (uniqueId, getNow) => {
3179
3209
  collClear(touchedCells);
3180
3210
  collClear(touchedValues);
3181
3211
  };
3182
- const cellChanged = (tableId, rowId, cellId, newCell, mutating) => {
3212
+ const cellChanged = (
3213
+ tableId,
3214
+ rowId,
3215
+ cellId,
3216
+ newCell,
3217
+ mutating,
3218
+ defaulted,
3219
+ ) => {
3183
3220
  setAdd(
3184
3221
  mapEnsure(mapEnsure(touchedCells, tableId, mapNew), rowId, setNew),
3185
3222
  cellId,
@@ -3197,7 +3234,9 @@ const createMergeableStore = (uniqueId, getNow) => {
3197
3234
  {
3198
3235
  [cellId]: [
3199
3236
  newCell,
3200
- defaultingContent ? EMPTY_STRING : getNextHlc(),
3237
+ defaultingContent || defaulted
3238
+ ? EMPTY_STRING
3239
+ : getNextHlc(),
3201
3240
  ],
3202
3241
  },
3203
3242
  ],
@@ -3210,7 +3249,7 @@ const createMergeableStore = (uniqueId, getNow) => {
3210
3249
  ]);
3211
3250
  }
3212
3251
  };
3213
- const valueChanged = (valueId, newValue, mutating) => {
3252
+ const valueChanged = (valueId, newValue, mutating, defaulted) => {
3214
3253
  setAdd(touchedValues, valueId);
3215
3254
  if (listeningToRawStoreChanges || mutating) {
3216
3255
  if (mutating) {
@@ -3222,7 +3261,7 @@ const createMergeableStore = (uniqueId, getNow) => {
3222
3261
  {
3223
3262
  [valueId]: [
3224
3263
  newValue,
3225
- defaultingContent ? EMPTY_STRING : getNextHlc(),
3264
+ defaultingContent || defaulted ? EMPTY_STRING : getNextHlc(),
3226
3265
  ],
3227
3266
  },
3228
3267
  ],
@@ -3911,13 +3950,14 @@ const createCustomPersister = (
3911
3950
  const content = await getPersisted();
3912
3951
  if (isArray(content)) {
3913
3952
  setContentOrChanges(content);
3914
- } else if (initialContent) {
3953
+ } else if (isUndefined(content) && initialContent) {
3915
3954
  setDefaultContent(initialContent);
3916
- } else {
3955
+ } else if (!isUndefined(content)) {
3917
3956
  errorNew(`Content is not an array: ${content}`);
3918
3957
  }
3919
3958
  },
3920
- () => {
3959
+ (error) => {
3960
+ onIgnoredError?.(error);
3921
3961
  if (initialContent) {
3922
3962
  setDefaultContent(initialContent);
3923
3963
  }
@@ -4123,6 +4163,8 @@ const DEFAULT_TABULAR_VALUES_CONFIG = {
4123
4163
  save: 0,
4124
4164
  [TABLE_NAME]: TINYBASE + '_values',
4125
4165
  };
4166
+ const getValuesIn = (config) => (isArray(config) ? config : void 0);
4167
+ const hasValues = (config) => isTrue(config) || isArray(config);
4126
4168
  const getDefaultedConfig = (configOrStoreTableName) =>
4127
4169
  objMerge(
4128
4170
  DEFAULT_CONFIG,
@@ -4173,11 +4215,15 @@ const getConfigStructures = (configOrStoreTableName) => {
4173
4215
  ];
4174
4216
  }
4175
4217
  const {tables: {load = {}, save = {}} = {}, values = {}} = config;
4176
- const valuesConfig = slice(
4177
- objValues(objMerge(DEFAULT_TABULAR_VALUES_CONFIG, values)),
4178
- 0,
4179
- objSize(DEFAULT_TABULAR_VALUES_CONFIG),
4180
- );
4218
+ const valuesConfigObj = objMerge(DEFAULT_TABULAR_VALUES_CONFIG, values);
4219
+ const {load: valuesLoad, save: valuesSave} = valuesConfigObj;
4220
+ const valuesConfig = [
4221
+ hasValues(valuesLoad),
4222
+ hasValues(valuesSave),
4223
+ valuesConfigObj[TABLE_NAME],
4224
+ getValuesIn(valuesLoad),
4225
+ getValuesIn(valuesSave),
4226
+ ];
4181
4227
  const valuesTable = valuesConfig[2];
4182
4228
  const managedTableNames = setNew(valuesTable);
4183
4229
  const excludedTableNames = setNew(valuesTable);
@@ -4239,8 +4285,18 @@ const getCommandFunctions = (
4239
4285
  ({tn, cn}) => setAdd(mapEnsure(schemaMap, tn, setNew), cn),
4240
4286
  );
4241
4287
  };
4242
- const loadTable = async (tableName, rowIdColumnName, condition) =>
4243
- canSelect(tableName, rowIdColumnName)
4288
+ const loadTable = async (
4289
+ tableName,
4290
+ rowIdColumnName,
4291
+ condition,
4292
+ contentSubIds,
4293
+ ) => {
4294
+ const contentSubIdSet = isUndefined(contentSubIds)
4295
+ ? void 0
4296
+ : setNew(contentSubIds);
4297
+ const includeContentSubId = (contentSubId) =>
4298
+ isUndefined(contentSubIdSet) || collHas(contentSubIdSet, contentSubId);
4299
+ return canSelect(tableName, rowIdColumnName)
4244
4300
  ? objNew(
4245
4301
  arrayFilter(
4246
4302
  arrayMap(
@@ -4249,17 +4305,35 @@ const getCommandFunctions = (
4249
4305
  escapeId(tableName) +
4250
4306
  getWhereCondition(tableName, condition),
4251
4307
  ),
4252
- (row) => [
4253
- row[rowIdColumnName],
4254
- decode
4308
+ (row) => {
4309
+ const rowId = row[rowIdColumnName];
4310
+ const rowContent = decode
4255
4311
  ? objMap(objDel(row, rowIdColumnName), decode)
4256
- : objDel(row, rowIdColumnName),
4257
- ],
4312
+ : objDel(row, rowIdColumnName);
4313
+ return [
4314
+ rowId,
4315
+ isUndefined(contentSubIdSet)
4316
+ ? rowContent
4317
+ : objNew(
4318
+ arrayFilter(
4319
+ objToArray(
4320
+ rowContent,
4321
+ (cellOrValue, contentSubId) => [
4322
+ contentSubId,
4323
+ cellOrValue,
4324
+ ],
4325
+ ),
4326
+ ([contentSubId]) => includeContentSubId(contentSubId),
4327
+ ),
4328
+ ),
4329
+ ];
4330
+ },
4258
4331
  ),
4259
4332
  (entry) => !isUndefined(entry[0]) && !objIsEmpty(entry[1]),
4260
4333
  ),
4261
4334
  )
4262
4335
  : {};
4336
+ };
4263
4337
  const saveTable = async (
4264
4338
  tableName,
4265
4339
  rowIdColumnName,
@@ -4268,15 +4342,23 @@ const getCommandFunctions = (
4268
4342
  deleteEmptyTable,
4269
4343
  partial = false,
4270
4344
  condition = TRUE,
4345
+ contentSubIds,
4271
4346
  ) => {
4347
+ const contentSubIdSet = isUndefined(contentSubIds)
4348
+ ? void 0
4349
+ : setNew(contentSubIds);
4350
+ const includeContentSubId = (contentSubId) =>
4351
+ isUndefined(contentSubIdSet) || collHas(contentSubIdSet, contentSubId);
4272
4352
  const settingColumnNameSet = setNew();
4273
4353
  objMap(content ?? {}, (contentRow) =>
4274
- arrayMap(objIds(contentRow ?? {}), (cellOrValueId) =>
4275
- setAdd(settingColumnNameSet, cellOrValueId),
4354
+ arrayMap(
4355
+ arrayFilter(objIds(contentRow ?? {}), includeContentSubId),
4356
+ (cellOrValueId) => setAdd(settingColumnNameSet, cellOrValueId),
4276
4357
  ),
4277
4358
  );
4278
4359
  const settingColumnNames = collValues(settingColumnNameSet);
4279
4360
  if (
4361
+ isUndefined(contentSubIdSet) &&
4280
4362
  !partial &&
4281
4363
  deleteEmptyTable &&
4282
4364
  condition == TRUE &&
@@ -4288,7 +4370,13 @@ const getCommandFunctions = (
4288
4370
  return;
4289
4371
  }
4290
4372
  const currentColumnNames = mapGet(schemaMap, tableName);
4291
- const unaccountedColumnNames = setNew(collValues(currentColumnNames));
4373
+ const unaccountedColumnNames = setNew(
4374
+ arrayFilter(
4375
+ collValues(currentColumnNames),
4376
+ (columnName) =>
4377
+ columnName == rowIdColumnName || includeContentSubId(columnName),
4378
+ ),
4379
+ );
4292
4380
  if (!arrayIsEmpty(settingColumnNames)) {
4293
4381
  if (!collHas(schemaMap, tableName)) {
4294
4382
  await databaseExecuteCommand(
@@ -4354,11 +4442,13 @@ const getCommandFunctions = (
4354
4442
  ]);
4355
4443
  if (partial) {
4356
4444
  if (isUndefined(content)) {
4357
- await databaseExecuteCommand(
4358
- DELETE_FROM +
4359
- escapeId(tableName) +
4360
- getWhereCondition(tableName, condition),
4361
- );
4445
+ if (isUndefined(contentSubIdSet)) {
4446
+ await databaseExecuteCommand(
4447
+ DELETE_FROM +
4448
+ escapeId(tableName) +
4449
+ getWhereCondition(tableName, condition),
4450
+ );
4451
+ }
4362
4452
  } else {
4363
4453
  await promiseAll(
4364
4454
  objToArray(content, async (row, rowId) => {
@@ -4371,18 +4461,24 @@ const getCommandFunctions = (
4371
4461
  [rowId],
4372
4462
  );
4373
4463
  } else if (!arrayIsEmpty(settingColumnNames)) {
4374
- await upsert(
4375
- databaseExecuteCommand,
4376
- tableName,
4377
- rowIdColumnName,
4464
+ const changingColumnNames = arrayFilter(
4378
4465
  objIds(row),
4379
- {
4380
- [rowId]: encode
4381
- ? arrayMap(objValues(row), encode)
4382
- : objValues(row),
4383
- },
4384
- currentColumnNames,
4466
+ includeContentSubId,
4385
4467
  );
4468
+ if (!arrayIsEmpty(changingColumnNames)) {
4469
+ await upsert(
4470
+ databaseExecuteCommand,
4471
+ tableName,
4472
+ rowIdColumnName,
4473
+ changingColumnNames,
4474
+ {
4475
+ [rowId]: arrayMap(changingColumnNames, (cellId) =>
4476
+ encode ? encode(row[cellId]) : row[cellId],
4477
+ ),
4478
+ },
4479
+ currentColumnNames,
4480
+ );
4481
+ }
4386
4482
  }
4387
4483
  }),
4388
4484
  );
@@ -4391,7 +4487,9 @@ const getCommandFunctions = (
4391
4487
  if (!arrayIsEmpty(settingColumnNames)) {
4392
4488
  const changingColumnNames = arrayFilter(
4393
4489
  collValues(mapGet(schemaMap, tableName)),
4394
- (changingColumnName) => changingColumnName != rowIdColumnName,
4490
+ (changingColumnName) =>
4491
+ changingColumnName != rowIdColumnName &&
4492
+ includeContentSubId(changingColumnName),
4395
4493
  );
4396
4494
  const rows = {};
4397
4495
  const deleteRowIds = [];
@@ -4407,6 +4505,7 @@ const getCommandFunctions = (
4407
4505
  rowIdColumnName,
4408
4506
  changingColumnNames,
4409
4507
  rows,
4508
+ currentColumnNames,
4410
4509
  );
4411
4510
  await databaseExecuteCommand(
4412
4511
  DELETE_FROM +
@@ -4415,7 +4514,10 @@ const getCommandFunctions = (
4415
4514
  `AND${escapeId(rowIdColumnName)}NOT IN(${getPlaceholders(deleteRowIds)})`,
4416
4515
  deleteRowIds,
4417
4516
  );
4418
- } else if (collHas(schemaMap, tableName)) {
4517
+ } else if (
4518
+ isUndefined(contentSubIdSet) &&
4519
+ collHas(schemaMap, tableName)
4520
+ ) {
4419
4521
  await databaseExecuteCommand(
4420
4522
  DELETE_FROM +
4421
4523
  escapeId(tableName) +
@@ -4554,7 +4656,13 @@ const createTabularPersister = (
4554
4656
  [
4555
4657
  tablesLoadConfig,
4556
4658
  tablesSaveConfig,
4557
- [valuesLoad, valuesSave, valuesTableName],
4659
+ [
4660
+ valuesLoad,
4661
+ valuesSave,
4662
+ valuesTableName,
4663
+ valuesLoadValueIds,
4664
+ valuesSaveValueIds,
4665
+ ],
4558
4666
  ],
4559
4667
  managedTableNames,
4560
4668
  querySchema,
@@ -4604,15 +4712,33 @@ const createTabularPersister = (
4604
4712
  },
4605
4713
  ),
4606
4714
  );
4715
+ const getValuesSubset = (values, valueIds, partial) =>
4716
+ objNew(
4717
+ partial == true
4718
+ ? arrayFilter(
4719
+ objToArray(values, (value, valueId) => [valueId, value]),
4720
+ ([valueId]) => arrayHas(valueIds, valueId),
4721
+ )
4722
+ : arrayFilter(
4723
+ arrayMap(valueIds, (valueId) => [valueId, values[valueId]]),
4724
+ ([, value]) => !isUndefined(value),
4725
+ ),
4726
+ );
4607
4727
  const saveValues = async (values, partial) =>
4608
4728
  valuesSave
4609
4729
  ? await saveTable(
4610
4730
  valuesTableName,
4611
4731
  DEFAULT_ROW_ID_COLUMN_NAME,
4612
- {[SINGLE_ROW_ID]: values},
4732
+ {
4733
+ [SINGLE_ROW_ID]: isUndefined(valuesSaveValueIds)
4734
+ ? values
4735
+ : getValuesSubset(values, valuesSaveValueIds, partial),
4736
+ },
4613
4737
  true,
4614
4738
  true,
4615
4739
  partial,
4740
+ void 0,
4741
+ valuesSaveValueIds,
4616
4742
  )
4617
4743
  : null;
4618
4744
  const loadTables = async () =>
@@ -4632,9 +4758,14 @@ const createTabularPersister = (
4632
4758
  );
4633
4759
  const loadValues = async () =>
4634
4760
  valuesLoad
4635
- ? (await loadTable(valuesTableName, DEFAULT_ROW_ID_COLUMN_NAME))[
4636
- SINGLE_ROW_ID
4637
- ]
4761
+ ? (
4762
+ await loadTable(
4763
+ valuesTableName,
4764
+ DEFAULT_ROW_ID_COLUMN_NAME,
4765
+ void 0,
4766
+ valuesLoadValueIds,
4767
+ )
4768
+ )[SINGLE_ROW_ID]
4638
4769
  : {};
4639
4770
  const getPersisted = () =>
4640
4771
  transaction(async () => {
@@ -5859,83 +5990,57 @@ const createPowerSyncPersister = (
5859
5990
  // StoreOnly,
5860
5991
  powerSync,
5861
5992
  'getPowerSync',
5862
- viewUpsert,
5993
+ powerSyncUpdateThenInsert,
5863
5994
  );
5864
5995
  };
5865
- const viewUpsert = async (
5996
+ const powerSyncUpdateThenInsert = async (
5866
5997
  executeCommand,
5867
5998
  tableName,
5868
5999
  rowIdColumnName,
5869
6000
  changingColumnNames,
5870
6001
  rows,
5871
- currentColumnNames,
5872
6002
  ) => {
5873
- const offset = [1];
5874
- const changingColumnNamesSet = setNew(changingColumnNames);
5875
- const unchangingColumnNames = currentColumnNames
5876
- ? arrayFilter(
5877
- [...currentColumnNames],
5878
- (currentColumnName) =>
5879
- currentColumnName != rowIdColumnName &&
5880
- !collHas(changingColumnNamesSet, currentColumnName),
5881
- )
5882
- : [];
5883
- if (!arrayIsEmpty(unchangingColumnNames)) {
5884
- const ids = objIds(rows);
5885
- const unchangingData = objNew(
5886
- arrayMap(
6003
+ const assignments = arrayJoin(
6004
+ arrayMap(
6005
+ changingColumnNames,
6006
+ (columnName, index) => escapeId(columnName) + '=$' + (index + 1),
6007
+ ),
6008
+ COMMA,
6009
+ );
6010
+ for (const [id, row] of objToArray(rows, (row2, id2) => [id2, row2])) {
6011
+ const rowParams = arrayMap(row, (value) => value ?? null);
6012
+ if (
6013
+ arrayIsEmpty(
5887
6014
  await executeCommand(
5888
- SELECT +
5889
- escapeColumnNames(rowIdColumnName, ...unchangingColumnNames) +
5890
- FROM +
6015
+ UPDATE +
5891
6016
  escapeId(tableName) +
6017
+ ' SET' +
6018
+ assignments +
6019
+ ' ' +
5892
6020
  WHERE +
5893
6021
  escapeId(rowIdColumnName) +
5894
- 'IN(' +
5895
- getPlaceholders(ids) +
5896
- ')',
5897
- ids,
5898
- ),
5899
- (unchangingRow) => [unchangingRow[rowIdColumnName], unchangingRow],
5900
- ),
5901
- );
5902
- arrayForEach(ids, (id) =>
5903
- arrayPush(
5904
- rows[id],
5905
- ...arrayMap(
5906
- unchangingColumnNames,
5907
- (unchangingColumnName) =>
5908
- unchangingData?.[id]?.[unchangingColumnName] ?? null,
6022
+ '=$' +
6023
+ (row.length + 1) +
6024
+ ' RETURNING' +
6025
+ escapeId(rowIdColumnName),
6026
+ [...rowParams, id],
5909
6027
  ),
5910
- ),
5911
- );
6028
+ )
6029
+ ) {
6030
+ const offset = [1];
6031
+ await executeCommand(
6032
+ INSERT +
6033
+ ' INTO' +
6034
+ escapeId(tableName) +
6035
+ '(' +
6036
+ escapeColumnNames(rowIdColumnName, ...changingColumnNames) +
6037
+ ')VALUES(' +
6038
+ getPlaceholders([id, ...row], offset) +
6039
+ ')',
6040
+ [id, ...rowParams],
6041
+ );
6042
+ }
5912
6043
  }
5913
- await executeCommand(
5914
- INSERT +
5915
- ' ' +
5916
- OR_REPLACE +
5917
- 'INTO' +
5918
- escapeId(tableName) +
5919
- '(' +
5920
- escapeColumnNames(
5921
- rowIdColumnName,
5922
- ...changingColumnNames,
5923
- ...unchangingColumnNames,
5924
- ) +
5925
- ')VALUES' +
5926
- arrayJoin(
5927
- objToArray(
5928
- rows,
5929
- (row) =>
5930
- '($' + offset[0]++ + ',' + getPlaceholders(row, offset) + ')',
5931
- ),
5932
- COMMA,
5933
- ),
5934
- objToArray(rows, (row, id) => [
5935
- id,
5936
- ...arrayMap(row, (value) => value ?? null),
5937
- ]).flat(),
5938
- );
5939
6044
  };
5940
6045
 
5941
6046
  const STORAGE = 'storage';
@@ -6316,9 +6421,9 @@ const PARAMS_TABLE = '_';
6316
6421
  const PARAM_LISTENER_PREFIX = 'p';
6317
6422
  const createQueries = getCreateFunction((store) => {
6318
6423
  const createStore = store._[0];
6319
- const preStore = createStore();
6320
6424
  const paramStore = createStore();
6321
6425
  const resultStore = createStore();
6426
+ const preStores = mapNew();
6322
6427
  const resultStores = mapNew();
6323
6428
  const redefiningQueryIds = setNew();
6324
6429
  const routedResultListeners = mapNew();
@@ -6361,12 +6466,13 @@ const createQueries = getCreateFunction((store) => {
6361
6466
  );
6362
6467
  const getResultStore = (queryId) =>
6363
6468
  mapEnsure(resultStores, queryId, createStore);
6364
- const addPreStoreListener = (preStore2, queryId, ...listenerIds) =>
6469
+ const getPreStore = (queryId) => mapEnsure(preStores, queryId, createStore);
6470
+ const addPreStoreListener = (preStore, queryId, ...listenerIds) =>
6365
6471
  arrayForEach(listenerIds, (listenerId) =>
6366
6472
  setAdd(
6367
6473
  mapEnsure(
6368
6474
  mapEnsure(preStoreListenerIds, queryId, mapNew),
6369
- preStore2,
6475
+ preStore,
6370
6476
  setNew,
6371
6477
  ),
6372
6478
  listenerId,
@@ -6376,16 +6482,17 @@ const createQueries = getCreateFunction((store) => {
6376
6482
  ifNotUndefined(
6377
6483
  mapGet(preStoreListenerIds, queryId),
6378
6484
  (queryPreStoreListenerIds) => {
6379
- mapForEach(queryPreStoreListenerIds, (preStore2, listenerIds) =>
6485
+ mapForEach(queryPreStoreListenerIds, (preStore, listenerIds) =>
6380
6486
  collForEach(listenerIds, (listenerId) =>
6381
- preStore2.delListener(listenerId),
6487
+ preStore.delListener(listenerId),
6382
6488
  ),
6383
6489
  );
6384
6490
  collClear(queryPreStoreListenerIds);
6385
6491
  },
6386
6492
  );
6387
- arrayForEach([getResultStore(queryId), preStore], (store2) =>
6388
- store2.delTable(queryId),
6493
+ arrayForEach(
6494
+ [getResultStore(queryId), mapGet(preStores, queryId)],
6495
+ (store2) => store2?.delTable(queryId),
6389
6496
  );
6390
6497
  };
6391
6498
  const addSourceStoreListeners = (
@@ -6613,10 +6720,12 @@ const createQueries = getCreateFunction((store) => {
6613
6720
  ),
6614
6721
  );
6615
6722
  const groups = mapNew(groupEntries);
6616
- let selectJoinWhereStore = preStore;
6617
- if (collIsEmpty(groups) && arrayIsEmpty(havings)) {
6618
- selectJoinWhereStore = resultStore2;
6619
- } else {
6723
+ const hasGroupsOrHavings =
6724
+ !collIsEmpty(groups) || !arrayIsEmpty(havings);
6725
+ const selectJoinWhereStore = hasGroupsOrHavings
6726
+ ? getPreStore(queryId)
6727
+ : resultStore2;
6728
+ if (hasGroupsOrHavings) {
6620
6729
  synchronizeTransactions(queryId, selectJoinWhereStore, resultStore2);
6621
6730
  const groupedSelectedCellIds = mapNew();
6622
6731
  mapForEach(groups, (groupedCellId, [selectedCellId, aggregators]) =>
@@ -7529,20 +7638,87 @@ const createLocalSynchronizer = (store, onSend, onReceive, onIgnoredError) => {
7529
7638
  };
7530
7639
 
7531
7640
  const MESSAGE_SEPARATOR = '\n';
7641
+ const FRAGMENT = /^(.+)\n(\d+)\n(\d+)\n([\s\S]*)$/;
7532
7642
  const ifPayloadValid = (payload, then) => {
7533
7643
  const splitAt = payload.indexOf(MESSAGE_SEPARATOR);
7534
7644
  if (splitAt !== -1) {
7535
7645
  then(slice(payload, 0, splitAt), slice(payload, splitAt + 1));
7536
7646
  }
7537
7647
  };
7538
- const receivePayload = (payload, receive) =>
7539
- ifPayloadValid(payload, (fromClientId, remainder) =>
7540
- receive(fromClientId, ...jsonParseWithUndefined(remainder)),
7541
- );
7648
+ const receivePayloadRemainder = (fromClientId, remainder, receive) =>
7649
+ receive(fromClientId, ...jsonParseWithUndefined(remainder));
7650
+ const createPayloadReceiver = (receive, fragmentTimeoutSeconds = 1) => {
7651
+ const buffer = mapNew();
7652
+ const setPendingTimeout = (bufferKey) =>
7653
+ startTimeout(() => collDel(buffer, bufferKey), fragmentTimeoutSeconds);
7654
+ const delPending = (bufferKey, pending) => {
7655
+ stopTimeout(pending[3]);
7656
+ collDel(buffer, bufferKey);
7657
+ };
7658
+ return (payload) =>
7659
+ ifPayloadValid(payload, (fromClientId, remainder) => {
7660
+ const [, messageId, indexStr, totalStr, fragment] =
7661
+ strMatch(remainder, FRAGMENT) ?? [];
7662
+ if (messageId) {
7663
+ const index = parseInt(indexStr);
7664
+ const total = parseInt(totalStr);
7665
+ if (total > 0 && index >= 0 && index < total) {
7666
+ const bufferKey = fromClientId + MESSAGE_SEPARATOR + messageId;
7667
+ const pending = mapEnsure(buffer, bufferKey, () => [
7668
+ [],
7669
+ total,
7670
+ total,
7671
+ setPendingTimeout(bufferKey),
7672
+ ]);
7673
+ const [fragments] = pending;
7674
+ if (total == pending[2] && isUndefined(fragments[index])) {
7675
+ stopTimeout(pending[3]);
7676
+ pending[3] = setPendingTimeout(bufferKey);
7677
+ fragments[index] = fragment;
7678
+ pending[1]--;
7679
+ }
7680
+ if (pending[1] == 0) {
7681
+ delPending(bufferKey, pending);
7682
+ receivePayloadRemainder(
7683
+ fromClientId,
7684
+ arrayJoin(fragments),
7685
+ receive,
7686
+ );
7687
+ }
7688
+ }
7689
+ } else {
7690
+ receivePayloadRemainder(fromClientId, remainder, receive);
7691
+ }
7692
+ });
7693
+ };
7542
7694
  const createPayload = (toClientId, ...args) =>
7543
- createRawPayload(toClientId ?? EMPTY_STRING, jsonStringWithUndefined(args));
7695
+ createRawPayload(toClientId, jsonStringWithUndefined(args));
7544
7696
  const createRawPayload = (clientId, remainder) =>
7545
7697
  clientId + MESSAGE_SEPARATOR + remainder;
7698
+ const createPayloads = (toClientId, requestId, message, body, fragmentSize) => {
7699
+ const clientId = toClientId ?? EMPTY_STRING;
7700
+ const remainder = jsonStringWithUndefined([requestId, message, body]);
7701
+ const maxFragmentSize = mathFloor(fragmentSize ?? 0);
7702
+ if (
7703
+ isUndefined(fragmentSize) ||
7704
+ maxFragmentSize < 1 ||
7705
+ size(remainder) <= maxFragmentSize
7706
+ ) {
7707
+ return [createRawPayload(clientId, remainder)];
7708
+ }
7709
+ const fragments = strMatch(
7710
+ remainder,
7711
+ new RegExp(`.{1,${maxFragmentSize}}`, 'g'),
7712
+ );
7713
+ const total = size(fragments ?? []);
7714
+ const messageId = getUniqueId();
7715
+ return arrayMap(fragments ?? [], (fragment, index) =>
7716
+ createRawPayload(
7717
+ clientId,
7718
+ arrayJoin([messageId, index, total, fragment], MESSAGE_SEPARATOR),
7719
+ ),
7720
+ );
7721
+ };
7546
7722
 
7547
7723
  const createWsSynchronizer = async (
7548
7724
  store,
@@ -7551,17 +7727,23 @@ const createWsSynchronizer = async (
7551
7727
  onSend,
7552
7728
  onReceive,
7553
7729
  onIgnoredError,
7730
+ fragmentSize,
7554
7731
  ) => {
7555
7732
  const addEventListener = (event, handler) => {
7556
7733
  webSocket.addEventListener(event, handler);
7557
7734
  return () => webSocket.removeEventListener(event, handler);
7558
7735
  };
7559
- const registerReceive = (receive) =>
7560
- addEventListener(MESSAGE, ({data}) =>
7561
- receivePayload(data.toString(UTF8), receive),
7736
+ const registerReceive = (receive) => {
7737
+ const receivePayload = createPayloadReceiver(
7738
+ receive,
7739
+ requestTimeoutSeconds,
7562
7740
  );
7741
+ addEventListener(MESSAGE, ({data}) => receivePayload(data.toString(UTF8)));
7742
+ };
7563
7743
  const send = (toClientId, ...args) =>
7564
- webSocket.send(createPayload(toClientId, ...args));
7744
+ arrayForEach(createPayloads(toClientId, ...args, fragmentSize), (payload) =>
7745
+ webSocket.send(payload),
7746
+ );
7565
7747
  const destroy = () => {
7566
7748
  webSocket.close();
7567
7749
  };
@@ -7616,18 +7798,27 @@ class WsServerDurableObject extends DurableObject {
7616
7798
  await ifNotUndefined(
7617
7799
  await this.createPersister(),
7618
7800
  async (persister) => {
7801
+ const requestTimeoutSeconds = this.getRequestTimeoutSeconds();
7619
7802
  const synchronizer = createCustomSynchronizer(
7620
7803
  persister.getStore(),
7621
7804
  (toClientId, requestId, message, body) =>
7622
- this.#handleMessage(
7623
- SERVER_CLIENT_ID$1,
7624
- createPayload(toClientId, requestId, message, body),
7805
+ arrayForEach(
7806
+ createPayloads(
7807
+ toClientId,
7808
+ requestId,
7809
+ message,
7810
+ body,
7811
+ this.getFragmentSize(),
7812
+ ),
7813
+ (payload) => this.#handleMessage(SERVER_CLIENT_ID$1, payload),
7625
7814
  ),
7626
7815
  (receive) =>
7627
- (this.#serverClientSend = (payload) =>
7628
- receivePayload(payload, receive)),
7816
+ (this.#serverClientSend = createPayloadReceiver(
7817
+ receive,
7818
+ requestTimeoutSeconds,
7819
+ )),
7629
7820
  noop,
7630
- 1,
7821
+ requestTimeoutSeconds,
7631
7822
  );
7632
7823
  await persister.load();
7633
7824
  await persister.startAutoSave();
@@ -7702,6 +7893,12 @@ class WsServerDurableObject extends DurableObject {
7702
7893
  (client) => this.ctx.getTags(client)[0],
7703
7894
  );
7704
7895
  }
7896
+ getFragmentSize() {
7897
+ return void 0;
7898
+ }
7899
+ getRequestTimeoutSeconds() {
7900
+ return 1;
7901
+ }
7705
7902
  onPathId(_pathId, _addedOrRemoved) {}
7706
7903
  onClientId(_pathId, _clientId, _addedOrRemoved) {}
7707
7904
  onMessage(_fromClientId, _toClientId, _remainder) {}
@@ -7762,6 +7959,8 @@ const createWsServer = (
7762
7959
  webSocketServer,
7763
7960
  createPersisterForPath,
7764
7961
  onIgnoredError,
7962
+ requestTimeoutSeconds = 1,
7963
+ fragmentSize,
7765
7964
  ) => {
7766
7965
  const pathIdListeners = mapNew();
7767
7966
  const clientIdListeners = mapNew();
@@ -7786,12 +7985,24 @@ const createWsServer = (
7786
7985
  serverClient[2 /* Synchronizer */] = createCustomSynchronizer(
7787
7986
  serverClient[1 /* Persister */].getStore(),
7788
7987
  (toClientId, requestId, message, body) =>
7789
- messageHandler(createPayload(toClientId, requestId, message, body)),
7790
- (receive) =>
7791
- (serverClient[3 /* Send */] = (payload) =>
7792
- receivePayload(payload, receive)),
7988
+ arrayForEach(
7989
+ createPayloads(
7990
+ toClientId,
7991
+ requestId,
7992
+ message,
7993
+ body,
7994
+ fragmentSize,
7995
+ ),
7996
+ messageHandler,
7997
+ ),
7998
+ (receive) => {
7999
+ serverClient[3 /* Send */] = createPayloadReceiver(
8000
+ receive,
8001
+ requestTimeoutSeconds,
8002
+ );
8003
+ },
7793
8004
  noop,
7794
- 1,
8005
+ requestTimeoutSeconds,
7795
8006
  void 0,
7796
8007
  void 0,
7797
8008
  onIgnoredError,
@@ -7803,14 +8014,12 @@ const createWsServer = (
7803
8014
  },
7804
8015
  );
7805
8016
  const startServerClient = async (serverClient) => {
7806
- serverClient[0 /* State */] = 2 /* Starting */;
7807
- await serverClient[1 /* Persister */].schedule(
7808
- serverClient[1 /* Persister */].startAutoLoad,
7809
- serverClient[1 /* Persister */].startAutoSave,
7810
- serverClient[2 /* Synchronizer */].startSync,
7811
- );
8017
+ serverClient[0 /* State */] = 2; /* Starting */
8018
+ await serverClient[1 /* Persister */].startAutoLoad();
8019
+ await serverClient[1 /* Persister */].startAutoSave();
8020
+ await serverClient[2 /* Synchronizer */].startSync();
7812
8021
  serverClient[5 /* Then */](serverClient[1 /* Persister */].getStore());
7813
- serverClient[0 /* State */] = 0 /* Ready */;
8022
+ serverClient[0 /* State */] = 0; /* Ready */
7814
8023
  };
7815
8024
  const stopServerClient = async (serverClient) => {
7816
8025
  await serverClient[1 /* Persister */]?.destroy();