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
@@ -18,6 +18,7 @@ const GLOBAL = globalThis;
18
18
  const THOUSAND = 1e3;
19
19
  const startTimeout = (callback, sec = 0) =>
20
20
  setTimeout(callback, sec * THOUSAND);
21
+ const stopTimeout = clearTimeout;
21
22
  const mathFloor = math.floor;
22
23
  const mathRandom = math.random;
23
24
  const isNullish = (thing) => thing == null;
@@ -44,6 +45,7 @@ const tryCatch = async (action, then1, then2) => {
44
45
  };
45
46
 
46
47
  const arrayForEach = (array, cb) => array.forEach(cb);
48
+ const arrayJoin = (array, sep = EMPTY_STRING) => array.join(sep);
47
49
  const arrayMap = (array, cb) => array.map(cb);
48
50
  const arrayIsEmpty = (array) => size(array) == 0;
49
51
  const arrayReduce = (array, cb, initial) => array.reduce(cb, initial);
@@ -85,38 +87,6 @@ const objEnsure = (obj, id, getDefaultValue) => {
85
87
  return obj[id];
86
88
  };
87
89
 
88
- const jsonString = JSON.stringify;
89
- const jsonParse = JSON.parse;
90
- const jsonStringWithUndefined = (obj) =>
91
- jsonString(obj, (_key, value) => (isUndefined(value) ? UNDEFINED : value));
92
- const jsonParseWithUndefined = (str) =>
93
- // JSON.parse reviver removes properties with undefined values
94
- replaceUndefinedString(jsonParse(str));
95
- const replaceUndefinedString = (obj) =>
96
- obj === UNDEFINED
97
- ? void 0
98
- : isArray(obj)
99
- ? arrayMap(obj, replaceUndefinedString)
100
- : isObject(obj)
101
- ? objMap(obj, replaceUndefinedString)
102
- : obj;
103
-
104
- const MESSAGE_SEPARATOR = '\n';
105
- const ifPayloadValid = (payload, then) => {
106
- const splitAt = payload.indexOf(MESSAGE_SEPARATOR);
107
- if (splitAt !== -1) {
108
- then(slice(payload, 0, splitAt), slice(payload, splitAt + 1));
109
- }
110
- };
111
- const receivePayload = (payload, receive) =>
112
- ifPayloadValid(payload, (fromClientId, remainder) =>
113
- receive(fromClientId, ...jsonParseWithUndefined(remainder)),
114
- );
115
- const createPayload = (toClientId, ...args) =>
116
- createRawPayload(toClientId ?? EMPTY_STRING, jsonStringWithUndefined(args));
117
- const createRawPayload = (clientId, remainder) =>
118
- clientId + MESSAGE_SEPARATOR + remainder;
119
-
120
90
  const collSize = (coll) => coll?.size ?? 0;
121
91
  const collHas = (coll, keyOrValue) => coll?.has(keyOrValue) ?? false;
122
92
  const collIsEmpty = (coll) => isUndefined(coll) || collSize(coll) == 0;
@@ -174,6 +144,105 @@ const getUniqueId = (length = 16) =>
174
144
  EMPTY_STRING,
175
145
  );
176
146
 
147
+ const jsonString = JSON.stringify;
148
+ const jsonParse = JSON.parse;
149
+ const jsonStringWithUndefined = (obj) =>
150
+ jsonString(obj, (_key, value) => (isUndefined(value) ? UNDEFINED : value));
151
+ const jsonParseWithUndefined = (str) =>
152
+ // JSON.parse reviver removes properties with undefined values
153
+ replaceUndefinedString(jsonParse(str));
154
+ const replaceUndefinedString = (obj) =>
155
+ obj === UNDEFINED
156
+ ? void 0
157
+ : isArray(obj)
158
+ ? arrayMap(obj, replaceUndefinedString)
159
+ : isObject(obj)
160
+ ? objMap(obj, replaceUndefinedString)
161
+ : obj;
162
+
163
+ const MESSAGE_SEPARATOR = '\n';
164
+ const FRAGMENT = /^(.+)\n(\d+)\n(\d+)\n([\s\S]*)$/;
165
+ const ifPayloadValid = (payload, then) => {
166
+ const splitAt = payload.indexOf(MESSAGE_SEPARATOR);
167
+ if (splitAt !== -1) {
168
+ then(slice(payload, 0, splitAt), slice(payload, splitAt + 1));
169
+ }
170
+ };
171
+ const receivePayloadRemainder = (fromClientId, remainder, receive) =>
172
+ receive(fromClientId, ...jsonParseWithUndefined(remainder));
173
+ const createPayloadReceiver = (receive, fragmentTimeoutSeconds = 1) => {
174
+ const buffer = mapNew();
175
+ const setPendingTimeout = (bufferKey) =>
176
+ startTimeout(() => collDel(buffer, bufferKey), fragmentTimeoutSeconds);
177
+ const delPending = (bufferKey, pending) => {
178
+ stopTimeout(pending[3]);
179
+ collDel(buffer, bufferKey);
180
+ };
181
+ return (payload) =>
182
+ ifPayloadValid(payload, (fromClientId, remainder) => {
183
+ const [, messageId, indexStr, totalStr, fragment] =
184
+ strMatch(remainder, FRAGMENT) ?? [];
185
+ if (messageId) {
186
+ const index = parseInt(indexStr);
187
+ const total = parseInt(totalStr);
188
+ if (total > 0 && index >= 0 && index < total) {
189
+ const bufferKey = fromClientId + MESSAGE_SEPARATOR + messageId;
190
+ const pending = mapEnsure(buffer, bufferKey, () => [
191
+ [],
192
+ total,
193
+ total,
194
+ setPendingTimeout(bufferKey),
195
+ ]);
196
+ const [fragments] = pending;
197
+ if (total == pending[2] && isUndefined(fragments[index])) {
198
+ stopTimeout(pending[3]);
199
+ pending[3] = setPendingTimeout(bufferKey);
200
+ fragments[index] = fragment;
201
+ pending[1]--;
202
+ }
203
+ if (pending[1] == 0) {
204
+ delPending(bufferKey, pending);
205
+ receivePayloadRemainder(
206
+ fromClientId,
207
+ arrayJoin(fragments),
208
+ receive,
209
+ );
210
+ }
211
+ }
212
+ } else {
213
+ receivePayloadRemainder(fromClientId, remainder, receive);
214
+ }
215
+ });
216
+ };
217
+ const createPayload = (toClientId, ...args) =>
218
+ createRawPayload(toClientId, jsonStringWithUndefined(args));
219
+ const createRawPayload = (clientId, remainder) =>
220
+ clientId + MESSAGE_SEPARATOR + remainder;
221
+ const createPayloads = (toClientId, requestId, message, body, fragmentSize) => {
222
+ const clientId = toClientId ?? EMPTY_STRING;
223
+ const remainder = jsonStringWithUndefined([requestId, message, body]);
224
+ const maxFragmentSize = mathFloor(fragmentSize ?? 0);
225
+ if (
226
+ isUndefined(fragmentSize) ||
227
+ maxFragmentSize < 1 ||
228
+ size(remainder) <= maxFragmentSize
229
+ ) {
230
+ return [createRawPayload(clientId, remainder)];
231
+ }
232
+ const fragments = strMatch(
233
+ remainder,
234
+ new RegExp(`.{1,${maxFragmentSize}}`, 'g'),
235
+ );
236
+ const total = size(fragments ?? []);
237
+ const messageId = getUniqueId();
238
+ return arrayMap(fragments ?? [], (fragment, index) =>
239
+ createRawPayload(
240
+ clientId,
241
+ arrayJoin([messageId, index, total, fragment], MESSAGE_SEPARATOR),
242
+ ),
243
+ );
244
+ };
245
+
177
246
  const stampNew = (value, hlc) => (hlc ? [value, hlc] : [value]);
178
247
  const getLatestHlc = (hlc1, hlc2) =>
179
248
  /* istanbul ignore next */
@@ -375,13 +444,13 @@ const createCustomPersister = (
375
444
  const content = await getPersisted();
376
445
  if (isArray(content)) {
377
446
  setContentOrChanges(content);
378
- } else if (initialContent) {
447
+ } else if (isUndefined(content) && initialContent) {
379
448
  setDefaultContent(initialContent);
380
- } else {
449
+ } else if (!isUndefined(content)) {
381
450
  errorNew(`Content is not an array: ${content}`);
382
451
  }
383
452
  },
384
- () => {
453
+ (error) => {
385
454
  if (initialContent) {
386
455
  setDefaultContent(initialContent);
387
456
  }
@@ -759,18 +828,27 @@ class WsServerDurableObject extends DurableObject {
759
828
  await ifNotUndefined(
760
829
  await this.createPersister(),
761
830
  async (persister) => {
831
+ const requestTimeoutSeconds = this.getRequestTimeoutSeconds();
762
832
  const synchronizer = createCustomSynchronizer(
763
833
  persister.getStore(),
764
834
  (toClientId, requestId, message, body) =>
765
- this.#handleMessage(
766
- SERVER_CLIENT_ID,
767
- createPayload(toClientId, requestId, message, body),
835
+ arrayForEach(
836
+ createPayloads(
837
+ toClientId,
838
+ requestId,
839
+ message,
840
+ body,
841
+ this.getFragmentSize(),
842
+ ),
843
+ (payload) => this.#handleMessage(SERVER_CLIENT_ID, payload),
768
844
  ),
769
845
  (receive) =>
770
- (this.#serverClientSend = (payload) =>
771
- receivePayload(payload, receive)),
846
+ (this.#serverClientSend = createPayloadReceiver(
847
+ receive,
848
+ requestTimeoutSeconds,
849
+ )),
772
850
  noop,
773
- 1,
851
+ requestTimeoutSeconds,
774
852
  );
775
853
  await persister.load();
776
854
  await persister.startAutoSave();
@@ -845,6 +923,12 @@ class WsServerDurableObject extends DurableObject {
845
923
  (client) => this.ctx.getTags(client)[0],
846
924
  );
847
925
  }
926
+ getFragmentSize() {
927
+ return void 0;
928
+ }
929
+ getRequestTimeoutSeconds() {
930
+ return 1;
931
+ }
848
932
  onPathId(_pathId, _addedOrRemoved) {}
849
933
  onClientId(_pathId, _clientId, _addedOrRemoved) {}
850
934
  onMessage(_fromClientId, _toClientId, _remainder) {}
@@ -18,6 +18,7 @@ const GLOBAL = globalThis;
18
18
  const THOUSAND = 1e3;
19
19
  const startTimeout = (callback, sec = 0) =>
20
20
  setTimeout(callback, sec * THOUSAND);
21
+ const stopTimeout = clearTimeout;
21
22
  const mathFloor = math.floor;
22
23
  const mathRandom = math.random;
23
24
  const isNullish = (thing) => thing == null;
@@ -44,6 +45,7 @@ const tryCatch = async (action, then1, then2) => {
44
45
  };
45
46
 
46
47
  const arrayForEach = (array, cb) => array.forEach(cb);
48
+ const arrayJoin = (array, sep = EMPTY_STRING) => array.join(sep);
47
49
  const arrayMap = (array, cb) => array.map(cb);
48
50
  const arrayIsEmpty = (array) => size(array) == 0;
49
51
  const arrayReduce = (array, cb, initial) => array.reduce(cb, initial);
@@ -85,38 +87,6 @@ const objEnsure = (obj, id, getDefaultValue) => {
85
87
  return obj[id];
86
88
  };
87
89
 
88
- const jsonString = JSON.stringify;
89
- const jsonParse = JSON.parse;
90
- const jsonStringWithUndefined = (obj) =>
91
- jsonString(obj, (_key, value) => (isUndefined(value) ? UNDEFINED : value));
92
- const jsonParseWithUndefined = (str) =>
93
- // JSON.parse reviver removes properties with undefined values
94
- replaceUndefinedString(jsonParse(str));
95
- const replaceUndefinedString = (obj) =>
96
- obj === UNDEFINED
97
- ? void 0
98
- : isArray(obj)
99
- ? arrayMap(obj, replaceUndefinedString)
100
- : isObject(obj)
101
- ? objMap(obj, replaceUndefinedString)
102
- : obj;
103
-
104
- const MESSAGE_SEPARATOR = '\n';
105
- const ifPayloadValid = (payload, then) => {
106
- const splitAt = payload.indexOf(MESSAGE_SEPARATOR);
107
- if (splitAt !== -1) {
108
- then(slice(payload, 0, splitAt), slice(payload, splitAt + 1));
109
- }
110
- };
111
- const receivePayload = (payload, receive) =>
112
- ifPayloadValid(payload, (fromClientId, remainder) =>
113
- receive(fromClientId, ...jsonParseWithUndefined(remainder)),
114
- );
115
- const createPayload = (toClientId, ...args) =>
116
- createRawPayload(toClientId ?? EMPTY_STRING, jsonStringWithUndefined(args));
117
- const createRawPayload = (clientId, remainder) =>
118
- clientId + MESSAGE_SEPARATOR + remainder;
119
-
120
90
  const collSize = (coll) => coll?.size ?? 0;
121
91
  const collHas = (coll, keyOrValue) => coll?.has(keyOrValue) ?? false;
122
92
  const collIsEmpty = (coll) => isUndefined(coll) || collSize(coll) == 0;
@@ -174,6 +144,105 @@ const getUniqueId = (length = 16) =>
174
144
  EMPTY_STRING,
175
145
  );
176
146
 
147
+ const jsonString = JSON.stringify;
148
+ const jsonParse = JSON.parse;
149
+ const jsonStringWithUndefined = (obj) =>
150
+ jsonString(obj, (_key, value) => (isUndefined(value) ? UNDEFINED : value));
151
+ const jsonParseWithUndefined = (str) =>
152
+ // JSON.parse reviver removes properties with undefined values
153
+ replaceUndefinedString(jsonParse(str));
154
+ const replaceUndefinedString = (obj) =>
155
+ obj === UNDEFINED
156
+ ? void 0
157
+ : isArray(obj)
158
+ ? arrayMap(obj, replaceUndefinedString)
159
+ : isObject(obj)
160
+ ? objMap(obj, replaceUndefinedString)
161
+ : obj;
162
+
163
+ const MESSAGE_SEPARATOR = '\n';
164
+ const FRAGMENT = /^(.+)\n(\d+)\n(\d+)\n([\s\S]*)$/;
165
+ const ifPayloadValid = (payload, then) => {
166
+ const splitAt = payload.indexOf(MESSAGE_SEPARATOR);
167
+ if (splitAt !== -1) {
168
+ then(slice(payload, 0, splitAt), slice(payload, splitAt + 1));
169
+ }
170
+ };
171
+ const receivePayloadRemainder = (fromClientId, remainder, receive) =>
172
+ receive(fromClientId, ...jsonParseWithUndefined(remainder));
173
+ const createPayloadReceiver = (receive, fragmentTimeoutSeconds = 1) => {
174
+ const buffer = mapNew();
175
+ const setPendingTimeout = (bufferKey) =>
176
+ startTimeout(() => collDel(buffer, bufferKey), fragmentTimeoutSeconds);
177
+ const delPending = (bufferKey, pending) => {
178
+ stopTimeout(pending[3]);
179
+ collDel(buffer, bufferKey);
180
+ };
181
+ return (payload) =>
182
+ ifPayloadValid(payload, (fromClientId, remainder) => {
183
+ const [, messageId, indexStr, totalStr, fragment] =
184
+ strMatch(remainder, FRAGMENT) ?? [];
185
+ if (messageId) {
186
+ const index = parseInt(indexStr);
187
+ const total = parseInt(totalStr);
188
+ if (total > 0 && index >= 0 && index < total) {
189
+ const bufferKey = fromClientId + MESSAGE_SEPARATOR + messageId;
190
+ const pending = mapEnsure(buffer, bufferKey, () => [
191
+ [],
192
+ total,
193
+ total,
194
+ setPendingTimeout(bufferKey),
195
+ ]);
196
+ const [fragments] = pending;
197
+ if (total == pending[2] && isUndefined(fragments[index])) {
198
+ stopTimeout(pending[3]);
199
+ pending[3] = setPendingTimeout(bufferKey);
200
+ fragments[index] = fragment;
201
+ pending[1]--;
202
+ }
203
+ if (pending[1] == 0) {
204
+ delPending(bufferKey, pending);
205
+ receivePayloadRemainder(
206
+ fromClientId,
207
+ arrayJoin(fragments),
208
+ receive,
209
+ );
210
+ }
211
+ }
212
+ } else {
213
+ receivePayloadRemainder(fromClientId, remainder, receive);
214
+ }
215
+ });
216
+ };
217
+ const createPayload = (toClientId, ...args) =>
218
+ createRawPayload(toClientId, jsonStringWithUndefined(args));
219
+ const createRawPayload = (clientId, remainder) =>
220
+ clientId + MESSAGE_SEPARATOR + remainder;
221
+ const createPayloads = (toClientId, requestId, message, body, fragmentSize) => {
222
+ const clientId = toClientId ?? EMPTY_STRING;
223
+ const remainder = jsonStringWithUndefined([requestId, message, body]);
224
+ const maxFragmentSize = mathFloor(fragmentSize ?? 0);
225
+ if (
226
+ isUndefined(fragmentSize) ||
227
+ maxFragmentSize < 1 ||
228
+ size(remainder) <= maxFragmentSize
229
+ ) {
230
+ return [createRawPayload(clientId, remainder)];
231
+ }
232
+ const fragments = strMatch(
233
+ remainder,
234
+ new RegExp(`.{1,${maxFragmentSize}}`, 'g'),
235
+ );
236
+ const total = size(fragments ?? []);
237
+ const messageId = getUniqueId();
238
+ return arrayMap(fragments ?? [], (fragment, index) =>
239
+ createRawPayload(
240
+ clientId,
241
+ arrayJoin([messageId, index, total, fragment], MESSAGE_SEPARATOR),
242
+ ),
243
+ );
244
+ };
245
+
177
246
  const stampNew = (value, hlc) => (hlc ? [value, hlc] : [value]);
178
247
  const getLatestHlc = (hlc1, hlc2) =>
179
248
  /* istanbul ignore next */
@@ -375,13 +444,13 @@ const createCustomPersister = (
375
444
  const content = await getPersisted();
376
445
  if (isArray(content)) {
377
446
  setContentOrChanges(content);
378
- } else if (initialContent) {
447
+ } else if (isUndefined(content) && initialContent) {
379
448
  setDefaultContent(initialContent);
380
- } else {
449
+ } else if (!isUndefined(content)) {
381
450
  errorNew(`Content is not an array: ${content}`);
382
451
  }
383
452
  },
384
- () => {
453
+ (error) => {
385
454
  if (initialContent) {
386
455
  setDefaultContent(initialContent);
387
456
  }
@@ -759,18 +828,27 @@ class WsServerDurableObject extends DurableObject {
759
828
  await ifNotUndefined(
760
829
  await this.createPersister(),
761
830
  async (persister) => {
831
+ const requestTimeoutSeconds = this.getRequestTimeoutSeconds();
762
832
  const synchronizer = createCustomSynchronizer(
763
833
  persister.getStore(),
764
834
  (toClientId, requestId, message, body) =>
765
- this.#handleMessage(
766
- SERVER_CLIENT_ID,
767
- createPayload(toClientId, requestId, message, body),
835
+ arrayForEach(
836
+ createPayloads(
837
+ toClientId,
838
+ requestId,
839
+ message,
840
+ body,
841
+ this.getFragmentSize(),
842
+ ),
843
+ (payload) => this.#handleMessage(SERVER_CLIENT_ID, payload),
768
844
  ),
769
845
  (receive) =>
770
- (this.#serverClientSend = (payload) =>
771
- receivePayload(payload, receive)),
846
+ (this.#serverClientSend = createPayloadReceiver(
847
+ receive,
848
+ requestTimeoutSeconds,
849
+ )),
772
850
  noop,
773
- 1,
851
+ requestTimeoutSeconds,
774
852
  );
775
853
  await persister.load();
776
854
  await persister.startAutoSave();
@@ -845,6 +923,12 @@ class WsServerDurableObject extends DurableObject {
845
923
  (client) => this.ctx.getTags(client)[0],
846
924
  );
847
925
  }
926
+ getFragmentSize() {
927
+ return void 0;
928
+ }
929
+ getRequestTimeoutSeconds() {
930
+ return 1;
931
+ }
848
932
  onPathId(_pathId, _addedOrRemoved) {}
849
933
  onClientId(_pathId, _clientId, _addedOrRemoved) {}
850
934
  onMessage(_fromClientId, _toClientId, _remainder) {}
@@ -331,13 +331,14 @@ const createCustomPersister = (
331
331
  const content = await getPersisted();
332
332
  if (isArray(content)) {
333
333
  setContentOrChanges(content);
334
- } else if (initialContent) {
334
+ } else if (isUndefined(content) && initialContent) {
335
335
  setDefaultContent(initialContent);
336
- } else {
336
+ } else if (!isUndefined(content)) {
337
337
  errorNew(`Content is not an array: ${content}`);
338
338
  }
339
339
  },
340
- () => {
340
+ (error) => {
341
+ onIgnoredError?.(error);
341
342
  if (initialContent) {
342
343
  setDefaultContent(initialContent);
343
344
  }
@@ -930,13 +930,13 @@ const createCustomPersister = (
930
930
  const content = await getPersisted();
931
931
  if (isArray(content)) {
932
932
  setContentOrChanges(content);
933
- } else if (initialContent) {
933
+ } else if (isUndefined(content) && initialContent) {
934
934
  setDefaultContent(initialContent);
935
- } else {
935
+ } else if (!isUndefined(content)) {
936
936
  errorNew(`Content is not an array: ${content}`);
937
937
  }
938
938
  },
939
- () => {
939
+ (error) => {
940
940
  if (initialContent) {
941
941
  setDefaultContent(initialContent);
942
942
  }
@@ -1189,8 +1189,10 @@ const createStore = () => {
1189
1189
  const changedRowIds = mapNew();
1190
1190
  const changedCellIds = mapNew();
1191
1191
  const changedCells = mapNew();
1192
+ const defaultedCells = mapNew();
1192
1193
  const changedValueIds = mapNew();
1193
1194
  const changedValues = mapNew();
1195
+ const defaultedValues = setNew();
1194
1196
  const invalidCells = mapNew();
1195
1197
  const invalidValues = mapNew();
1196
1198
  const tablesSchemaMap = mapNew();
@@ -1364,6 +1366,16 @@ const createStore = () => {
1364
1366
  collForEach(rowDefaulted, (cell, cellId) => {
1365
1367
  if (!objHas(row, cellId)) {
1366
1368
  row[cellId] = cell;
1369
+ ifNotUndefined(rowId, (rowId2) =>
1370
+ setAdd(
1371
+ mapEnsure(
1372
+ mapEnsure(defaultedCells, tableId, mapNew),
1373
+ rowId2,
1374
+ setNew,
1375
+ ),
1376
+ cellId,
1377
+ ),
1378
+ );
1367
1379
  }
1368
1380
  });
1369
1381
  collForEach(rowNonDefaulted, (cellId) => {
@@ -1380,6 +1392,7 @@ const createStore = () => {
1380
1392
  collForEach(valuesDefaulted, (value, valueId) => {
1381
1393
  if (!objHas(values, valueId)) {
1382
1394
  values[valueId] = value;
1395
+ setAdd(defaultedValues, valueId);
1383
1396
  }
1384
1397
  });
1385
1398
  collForEach(valuesNonDefaulted, (valueId) => {
@@ -1783,18 +1796,34 @@ const createStore = () => {
1783
1796
  );
1784
1797
  };
1785
1798
  const cellChanged = (tableId, rowId, cellId, oldCell, newCell) => {
1799
+ const defaulted =
1800
+ collHas(mapGet(mapGet(defaultedCells, tableId), rowId), cellId) &&
1801
+ isUndefined(oldCell)
1802
+ ? 1
1803
+ : 0;
1786
1804
  mapEnsure(
1787
1805
  mapEnsure(mapEnsure(changedCells, tableId, mapNew), rowId, mapNew),
1788
1806
  cellId,
1789
1807
  () => [oldCell, 0],
1790
1808
  )[1] = newCell;
1791
- internalListeners[3]?.(tableId, rowId, cellId, newCell, mutating);
1809
+ internalListeners[3]?.(
1810
+ tableId,
1811
+ rowId,
1812
+ cellId,
1813
+ newCell,
1814
+ mutating,
1815
+ defaulted,
1816
+ );
1817
+ collDel(mapGet(mapGet(defaultedCells, tableId), rowId), cellId);
1792
1818
  };
1793
1819
  const valueIdsChanged = (valueId, addedOrRemoved) =>
1794
1820
  idsChanged(changedValueIds, valueId, addedOrRemoved);
1795
1821
  const valueChanged = (valueId, oldValue, newValue) => {
1822
+ const defaulted =
1823
+ collHas(defaultedValues, valueId) && isUndefined(oldValue) ? 1 : 0;
1796
1824
  mapEnsure(changedValues, valueId, () => [oldValue, 0])[1] = newValue;
1797
- internalListeners[4]?.(valueId, newValue, mutating);
1825
+ internalListeners[4]?.(valueId, newValue, mutating, defaulted);
1826
+ collDel(defaultedValues, valueId);
1798
1827
  };
1799
1828
  const cellInvalid = (tableId, rowId, cellId, invalidCell, defaultedCell) => {
1800
1829
  arrayPush(
@@ -2582,9 +2611,11 @@ const createStore = () => {
2582
2611
  changedRowIds,
2583
2612
  changedCellIds,
2584
2613
  changedCells,
2614
+ defaultedCells,
2585
2615
  invalidCells,
2586
2616
  changedValueIds,
2587
2617
  changedValues,
2618
+ defaultedValues,
2588
2619
  invalidValues,
2589
2620
  ],
2590
2621
  collClear,
@@ -930,13 +930,13 @@ const createCustomPersister = (
930
930
  const content = await getPersisted();
931
931
  if (isArray(content)) {
932
932
  setContentOrChanges(content);
933
- } else if (initialContent) {
933
+ } else if (isUndefined(content) && initialContent) {
934
934
  setDefaultContent(initialContent);
935
- } else {
935
+ } else if (!isUndefined(content)) {
936
936
  errorNew(`Content is not an array: ${content}`);
937
937
  }
938
938
  },
939
- () => {
939
+ (error) => {
940
940
  if (initialContent) {
941
941
  setDefaultContent(initialContent);
942
942
  }
@@ -1189,8 +1189,10 @@ const createStore = () => {
1189
1189
  const changedRowIds = mapNew();
1190
1190
  const changedCellIds = mapNew();
1191
1191
  const changedCells = mapNew();
1192
+ const defaultedCells = mapNew();
1192
1193
  const changedValueIds = mapNew();
1193
1194
  const changedValues = mapNew();
1195
+ const defaultedValues = setNew();
1194
1196
  const invalidCells = mapNew();
1195
1197
  const invalidValues = mapNew();
1196
1198
  const tablesSchemaMap = mapNew();
@@ -1364,6 +1366,16 @@ const createStore = () => {
1364
1366
  collForEach(rowDefaulted, (cell, cellId) => {
1365
1367
  if (!objHas(row, cellId)) {
1366
1368
  row[cellId] = cell;
1369
+ ifNotUndefined(rowId, (rowId2) =>
1370
+ setAdd(
1371
+ mapEnsure(
1372
+ mapEnsure(defaultedCells, tableId, mapNew),
1373
+ rowId2,
1374
+ setNew,
1375
+ ),
1376
+ cellId,
1377
+ ),
1378
+ );
1367
1379
  }
1368
1380
  });
1369
1381
  collForEach(rowNonDefaulted, (cellId) => {
@@ -1380,6 +1392,7 @@ const createStore = () => {
1380
1392
  collForEach(valuesDefaulted, (value, valueId) => {
1381
1393
  if (!objHas(values, valueId)) {
1382
1394
  values[valueId] = value;
1395
+ setAdd(defaultedValues, valueId);
1383
1396
  }
1384
1397
  });
1385
1398
  collForEach(valuesNonDefaulted, (valueId) => {
@@ -1783,18 +1796,34 @@ const createStore = () => {
1783
1796
  );
1784
1797
  };
1785
1798
  const cellChanged = (tableId, rowId, cellId, oldCell, newCell) => {
1799
+ const defaulted =
1800
+ collHas(mapGet(mapGet(defaultedCells, tableId), rowId), cellId) &&
1801
+ isUndefined(oldCell)
1802
+ ? 1
1803
+ : 0;
1786
1804
  mapEnsure(
1787
1805
  mapEnsure(mapEnsure(changedCells, tableId, mapNew), rowId, mapNew),
1788
1806
  cellId,
1789
1807
  () => [oldCell, 0],
1790
1808
  )[1] = newCell;
1791
- internalListeners[3]?.(tableId, rowId, cellId, newCell, mutating);
1809
+ internalListeners[3]?.(
1810
+ tableId,
1811
+ rowId,
1812
+ cellId,
1813
+ newCell,
1814
+ mutating,
1815
+ defaulted,
1816
+ );
1817
+ collDel(mapGet(mapGet(defaultedCells, tableId), rowId), cellId);
1792
1818
  };
1793
1819
  const valueIdsChanged = (valueId, addedOrRemoved) =>
1794
1820
  idsChanged(changedValueIds, valueId, addedOrRemoved);
1795
1821
  const valueChanged = (valueId, oldValue, newValue) => {
1822
+ const defaulted =
1823
+ collHas(defaultedValues, valueId) && isUndefined(oldValue) ? 1 : 0;
1796
1824
  mapEnsure(changedValues, valueId, () => [oldValue, 0])[1] = newValue;
1797
- internalListeners[4]?.(valueId, newValue, mutating);
1825
+ internalListeners[4]?.(valueId, newValue, mutating, defaulted);
1826
+ collDel(defaultedValues, valueId);
1798
1827
  };
1799
1828
  const cellInvalid = (tableId, rowId, cellId, invalidCell, defaultedCell) => {
1800
1829
  arrayPush(
@@ -2582,9 +2611,11 @@ const createStore = () => {
2582
2611
  changedRowIds,
2583
2612
  changedCellIds,
2584
2613
  changedCells,
2614
+ defaultedCells,
2585
2615
  invalidCells,
2586
2616
  changedValueIds,
2587
2617
  changedValues,
2618
+ defaultedValues,
2588
2619
  invalidValues,
2589
2620
  ],
2590
2621
  collClear,