@evolu/common 8.7.0 → 8.9.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (302) hide show
  1. package/dist/src/Array.d.ts +21 -21
  2. package/dist/src/Array.js +5 -5
  3. package/dist/src/Assert.d.ts +498 -141
  4. package/dist/src/Assert.d.ts.map +1 -1
  5. package/dist/src/Assert.js +648 -99
  6. package/dist/src/{Buffer.d.ts → Binary.d.ts} +85 -12
  7. package/dist/src/Binary.d.ts.map +1 -0
  8. package/dist/src/{Buffer.js → Binary.js} +206 -24
  9. package/dist/src/Console.d.ts +2 -10
  10. package/dist/src/Console.d.ts.map +1 -1
  11. package/dist/src/Console.js +6 -12
  12. package/dist/src/Crypto.d.ts +5 -5
  13. package/dist/src/Crypto.js +1 -1
  14. package/dist/src/Eq.d.ts +35 -40
  15. package/dist/src/Eq.d.ts.map +1 -1
  16. package/dist/src/Eq.js +51 -87
  17. package/dist/src/Function.d.ts +9 -14
  18. package/dist/src/Function.d.ts.map +1 -1
  19. package/dist/src/Function.js +7 -9
  20. package/dist/src/Http.d.ts +6 -7
  21. package/dist/src/Http.d.ts.map +1 -1
  22. package/dist/src/LeakDetector.d.ts.map +1 -1
  23. package/dist/src/LeakDetector.js +1 -0
  24. package/dist/src/LockManager.d.ts +1 -1
  25. package/dist/src/LockManager.js +1 -1
  26. package/dist/src/Lookup.d.ts +3 -2
  27. package/dist/src/Lookup.d.ts.map +1 -1
  28. package/dist/src/Lookup.js +4 -3
  29. package/dist/src/Number.d.ts +1 -1
  30. package/dist/src/Number.d.ts.map +1 -1
  31. package/dist/src/Number.js +1 -1
  32. package/dist/src/Object.d.ts +4 -4
  33. package/dist/src/Object.d.ts.map +1 -1
  34. package/dist/src/Object.js +5 -4
  35. package/dist/src/Option.d.ts +1 -2
  36. package/dist/src/Option.d.ts.map +1 -1
  37. package/dist/src/Option.js +1 -2
  38. package/dist/src/Platform.js +2 -0
  39. package/dist/src/Polyfills.d.ts +6 -0
  40. package/dist/src/Polyfills.d.ts.map +1 -1
  41. package/dist/src/Polyfills.js +10 -1
  42. package/dist/src/Random.d.ts +1 -1
  43. package/dist/src/Result.d.ts +49 -54
  44. package/dist/src/Result.d.ts.map +1 -1
  45. package/dist/src/Result.js +17 -22
  46. package/dist/src/Set.d.ts +6 -6
  47. package/dist/src/Set.js +2 -2
  48. package/dist/src/Sqlite.js +1 -1
  49. package/dist/src/String.js +3 -2
  50. package/dist/src/Task.d.ts +32 -32
  51. package/dist/src/Task.d.ts.map +1 -1
  52. package/dist/src/Task.js +20 -22
  53. package/dist/src/Test.d.ts +31 -3
  54. package/dist/src/Test.d.ts.map +1 -1
  55. package/dist/src/Test.js +46 -3
  56. package/dist/src/Time.d.ts +3 -11
  57. package/dist/src/Time.d.ts.map +1 -1
  58. package/dist/src/Time.js +10 -18
  59. package/dist/src/Type.d.ts +87 -85
  60. package/dist/src/Type.d.ts.map +1 -1
  61. package/dist/src/Type.js +70 -63
  62. package/dist/src/Types.d.ts +12 -12
  63. package/dist/src/Types.js +1 -1
  64. package/dist/src/WebSocket.d.ts +4 -7
  65. package/dist/src/WebSocket.d.ts.map +1 -1
  66. package/dist/src/Worker.d.ts +1 -1
  67. package/dist/src/Worker.js +7 -7
  68. package/dist/src/index.d.ts +1 -1
  69. package/dist/src/index.js +1 -1
  70. package/dist/src/intl/_en.d.ts.map +1 -1
  71. package/dist/src/intl/_en.js +1 -1
  72. package/dist/src/intl/ar.d.ts.map +1 -1
  73. package/dist/src/intl/ar.js +1 -1
  74. package/dist/src/intl/bn.d.ts.map +1 -1
  75. package/dist/src/intl/bn.js +1 -1
  76. package/dist/src/intl/ca.d.ts.map +1 -1
  77. package/dist/src/intl/ca.js +1 -1
  78. package/dist/src/intl/cs.d.ts.map +1 -1
  79. package/dist/src/intl/cs.js +1 -1
  80. package/dist/src/intl/da.d.ts.map +1 -1
  81. package/dist/src/intl/da.js +1 -1
  82. package/dist/src/intl/de.d.ts.map +1 -1
  83. package/dist/src/intl/de.js +1 -1
  84. package/dist/src/intl/el.d.ts.map +1 -1
  85. package/dist/src/intl/el.js +1 -1
  86. package/dist/src/intl/es.d.ts.map +1 -1
  87. package/dist/src/intl/es.js +1 -1
  88. package/dist/src/intl/fa.d.ts.map +1 -1
  89. package/dist/src/intl/fa.js +1 -1
  90. package/dist/src/intl/fi.d.ts.map +1 -1
  91. package/dist/src/intl/fi.js +1 -1
  92. package/dist/src/intl/fil.d.ts.map +1 -1
  93. package/dist/src/intl/fil.js +1 -1
  94. package/dist/src/intl/fr.d.ts.map +1 -1
  95. package/dist/src/intl/fr.js +1 -1
  96. package/dist/src/intl/he.d.ts.map +1 -1
  97. package/dist/src/intl/he.js +1 -1
  98. package/dist/src/intl/hi.d.ts.map +1 -1
  99. package/dist/src/intl/hi.js +1 -1
  100. package/dist/src/intl/hr.d.ts.map +1 -1
  101. package/dist/src/intl/hr.js +1 -1
  102. package/dist/src/intl/hu.d.ts.map +1 -1
  103. package/dist/src/intl/hu.js +1 -1
  104. package/dist/src/intl/id.d.ts.map +1 -1
  105. package/dist/src/intl/id.js +1 -1
  106. package/dist/src/intl/it.d.ts.map +1 -1
  107. package/dist/src/intl/it.js +1 -1
  108. package/dist/src/intl/ja.d.ts.map +1 -1
  109. package/dist/src/intl/ja.js +1 -1
  110. package/dist/src/intl/ko.d.ts.map +1 -1
  111. package/dist/src/intl/ko.js +1 -1
  112. package/dist/src/intl/ml.d.ts.map +1 -1
  113. package/dist/src/intl/ml.js +1 -1
  114. package/dist/src/intl/mr.d.ts.map +1 -1
  115. package/dist/src/intl/mr.js +1 -1
  116. package/dist/src/intl/ms.d.ts.map +1 -1
  117. package/dist/src/intl/ms.js +1 -1
  118. package/dist/src/intl/nb.d.ts.map +1 -1
  119. package/dist/src/intl/nb.js +1 -1
  120. package/dist/src/intl/nl.d.ts.map +1 -1
  121. package/dist/src/intl/nl.js +1 -1
  122. package/dist/src/intl/pa.d.ts.map +1 -1
  123. package/dist/src/intl/pa.js +1 -1
  124. package/dist/src/intl/pl.d.ts.map +1 -1
  125. package/dist/src/intl/pl.js +1 -1
  126. package/dist/src/intl/pt-BR.d.ts.map +1 -1
  127. package/dist/src/intl/pt-BR.js +1 -1
  128. package/dist/src/intl/pt.d.ts.map +1 -1
  129. package/dist/src/intl/pt.js +1 -1
  130. package/dist/src/intl/ro.d.ts.map +1 -1
  131. package/dist/src/intl/ro.js +1 -1
  132. package/dist/src/intl/sk.d.ts.map +1 -1
  133. package/dist/src/intl/sk.js +1 -1
  134. package/dist/src/intl/sl.d.ts.map +1 -1
  135. package/dist/src/intl/sl.js +1 -1
  136. package/dist/src/intl/sv.d.ts.map +1 -1
  137. package/dist/src/intl/sv.js +1 -1
  138. package/dist/src/intl/sw.d.ts.map +1 -1
  139. package/dist/src/intl/sw.js +1 -1
  140. package/dist/src/intl/ta.d.ts.map +1 -1
  141. package/dist/src/intl/ta.js +1 -1
  142. package/dist/src/intl/te.d.ts.map +1 -1
  143. package/dist/src/intl/te.js +1 -1
  144. package/dist/src/intl/th.d.ts.map +1 -1
  145. package/dist/src/intl/th.js +1 -1
  146. package/dist/src/intl/tr.d.ts.map +1 -1
  147. package/dist/src/intl/tr.js +1 -1
  148. package/dist/src/intl/uk.d.ts.map +1 -1
  149. package/dist/src/intl/uk.js +1 -1
  150. package/dist/src/intl/ur.d.ts.map +1 -1
  151. package/dist/src/intl/ur.js +1 -1
  152. package/dist/src/intl/vi.d.ts.map +1 -1
  153. package/dist/src/intl/vi.js +1 -1
  154. package/dist/src/intl/zh-CN.d.ts.map +1 -1
  155. package/dist/src/intl/zh-CN.js +1 -1
  156. package/dist/src/intl/zh-TW.d.ts.map +1 -1
  157. package/dist/src/intl/zh-TW.js +1 -1
  158. package/dist/src/local-first/Evolu.d.ts +12 -12
  159. package/dist/src/local-first/Evolu.d.ts.map +1 -1
  160. package/dist/src/local-first/Evolu.js +2 -2
  161. package/dist/src/local-first/Protocol.d.ts +14 -76
  162. package/dist/src/local-first/Protocol.d.ts.map +1 -1
  163. package/dist/src/local-first/Protocol.js +29 -206
  164. package/dist/src/local-first/Query.d.ts +11 -11
  165. package/dist/src/local-first/Query.js +6 -6
  166. package/dist/src/local-first/Relay.d.ts +2 -2
  167. package/dist/src/local-first/Schema.d.ts +3 -5
  168. package/dist/src/local-first/Schema.d.ts.map +1 -1
  169. package/dist/src/local-first/Schema.js +2 -4
  170. package/dist/src/local-first/Shared.d.ts.map +1 -1
  171. package/dist/src/local-first/Shared.js +5 -5
  172. package/dist/src/local-first/Storage.js +4 -4
  173. package/dist/src/local-first/Timestamp.d.ts +9 -0
  174. package/dist/src/local-first/Timestamp.d.ts.map +1 -1
  175. package/dist/src/local-first/Timestamp.js +13 -10
  176. package/package.json +7 -4
  177. package/src/Array.test.ts +809 -0
  178. package/src/Array.ts +21 -21
  179. package/src/Assert.test.ts +1232 -0
  180. package/src/Assert.ts +1023 -227
  181. package/src/BigInt.test.ts +28 -0
  182. package/src/Binary.test.ts +1128 -0
  183. package/src/{Buffer.ts → Binary.ts} +273 -46
  184. package/src/Brand.test.ts +90 -0
  185. package/src/Cache.test.ts +183 -0
  186. package/src/Callbacks.test.ts +66 -0
  187. package/src/Console.test.ts +809 -0
  188. package/src/Console.ts +9 -17
  189. package/src/Crypto.test.ts +138 -0
  190. package/src/Crypto.ts +5 -5
  191. package/src/Eq.test.ts +333 -0
  192. package/src/Eq.ts +110 -176
  193. package/src/Error.test.ts +118 -0
  194. package/src/Function.test.ts +204 -0
  195. package/src/Function.ts +10 -15
  196. package/src/Http.test.ts +816 -0
  197. package/src/Http.ts +6 -7
  198. package/src/LeakDetector.test.ts +210 -0
  199. package/src/LeakDetector.ts +1 -0
  200. package/src/LockManager.ts +2 -2
  201. package/src/Lookup.test.ts +418 -0
  202. package/src/Lookup.ts +4 -3
  203. package/src/Microtask.test.ts +140 -0
  204. package/src/Number.test.ts +218 -0
  205. package/src/Number.ts +2 -2
  206. package/src/Object.test.ts +293 -0
  207. package/src/Object.ts +5 -4
  208. package/src/Option.test.ts +104 -0
  209. package/src/Option.ts +1 -2
  210. package/src/Order.test.ts +56 -0
  211. package/src/Platform.ts +2 -0
  212. package/src/Polyfills.ts +9 -4
  213. package/src/Random.test.ts +89 -0
  214. package/src/Random.ts +1 -1
  215. package/src/Ref.test.ts +139 -0
  216. package/src/RefCount.test.ts +184 -0
  217. package/src/Relation.test.ts +505 -0
  218. package/src/Resource.test.ts +4623 -0
  219. package/src/Result.test.ts +1829 -0
  220. package/src/Result.ts +49 -54
  221. package/src/Schedule.test.ts +1554 -0
  222. package/src/Set.test.ts +279 -0
  223. package/src/Set.ts +6 -6
  224. package/src/Sqlite.ts +1 -1
  225. package/src/Store.test.ts +288 -0
  226. package/src/String.test.ts +54 -0
  227. package/src/String.ts +3 -3
  228. package/src/Task.test.ts +10820 -0
  229. package/src/Task.ts +38 -43
  230. package/src/Test.test.ts +88 -0
  231. package/src/Test.ts +49 -3
  232. package/src/Time.test.ts +926 -0
  233. package/src/Time.ts +13 -21
  234. package/src/Type.base64.test.ts +88 -0
  235. package/src/Type.test.ts +20465 -0
  236. package/src/Type.ts +114 -111
  237. package/src/Types.test.ts +324 -0
  238. package/src/Types.ts +13 -13
  239. package/src/WebSocket.ts +4 -7
  240. package/src/Worker.test.ts +755 -0
  241. package/src/Worker.ts +13 -18
  242. package/src/index.ts +1 -1
  243. package/src/intl/_en.ts +1 -1
  244. package/src/intl/ar.ts +1 -1
  245. package/src/intl/bn.ts +1 -1
  246. package/src/intl/ca.ts +1 -1
  247. package/src/intl/cs.ts +1 -1
  248. package/src/intl/da.ts +1 -1
  249. package/src/intl/de.ts +1 -1
  250. package/src/intl/el.ts +1 -1
  251. package/src/intl/es.ts +1 -1
  252. package/src/intl/fa.ts +1 -1
  253. package/src/intl/fi.ts +1 -1
  254. package/src/intl/fil.ts +1 -1
  255. package/src/intl/fr.ts +1 -1
  256. package/src/intl/he.ts +1 -1
  257. package/src/intl/hi.ts +1 -1
  258. package/src/intl/hr.ts +1 -1
  259. package/src/intl/hu.ts +1 -1
  260. package/src/intl/id.ts +1 -1
  261. package/src/intl/intl.test.ts +3106 -0
  262. package/src/intl/it.ts +1 -1
  263. package/src/intl/ja.ts +1 -1
  264. package/src/intl/ko.ts +1 -1
  265. package/src/intl/ml.ts +1 -1
  266. package/src/intl/mr.ts +1 -1
  267. package/src/intl/ms.ts +1 -1
  268. package/src/intl/nb.ts +1 -1
  269. package/src/intl/nl.ts +1 -1
  270. package/src/intl/pa.ts +1 -1
  271. package/src/intl/pl.ts +1 -1
  272. package/src/intl/pt-BR.ts +1 -1
  273. package/src/intl/pt.ts +1 -1
  274. package/src/intl/ro.ts +1 -1
  275. package/src/intl/sk.ts +1 -1
  276. package/src/intl/sl.ts +1 -1
  277. package/src/intl/sv.ts +1 -1
  278. package/src/intl/sw.ts +1 -1
  279. package/src/intl/ta.ts +1 -1
  280. package/src/intl/te.ts +1 -1
  281. package/src/intl/th.ts +1 -1
  282. package/src/intl/tr.ts +1 -1
  283. package/src/intl/uk.ts +1 -1
  284. package/src/intl/ur.ts +1 -1
  285. package/src/intl/vi.ts +1 -1
  286. package/src/intl/zh-CN.ts +1 -1
  287. package/src/intl/zh-TW.ts +1 -1
  288. package/src/local-first/Evolu.test.ts +1921 -0
  289. package/src/local-first/Evolu.ts +18 -14
  290. package/src/local-first/Owner.test.ts +83 -0
  291. package/src/local-first/Protocol.test.ts +1037 -0
  292. package/src/local-first/Protocol.ts +58 -261
  293. package/src/local-first/Query.test.ts +349 -0
  294. package/src/local-first/Query.ts +11 -11
  295. package/src/local-first/Relay.ts +2 -2
  296. package/src/local-first/Schema.ts +3 -5
  297. package/src/local-first/Shared.test.ts +1828 -0
  298. package/src/local-first/Shared.ts +9 -8
  299. package/src/local-first/Storage.ts +4 -4
  300. package/src/local-first/Timestamp.test.ts +374 -0
  301. package/src/local-first/Timestamp.ts +22 -10
  302. package/dist/src/Buffer.d.ts.map +0 -1
@@ -180,18 +180,31 @@ import {
180
180
  isNonEmptyArray,
181
181
  type NonEmptyReadonlyArray,
182
182
  } from "../Array.ts";
183
- import { assert, assertNonNullable, assertNotUndefined } from "../Assert.ts";
183
+ import {
184
+ assert,
185
+ assertNonNullable,
186
+ assertNotUndefined,
187
+ assertSame,
188
+ } from "../Assert.ts";
184
189
  import type { Brand } from "../Brand.ts";
185
190
  import {
186
191
  type Buffer,
187
- bytesToHex,
188
- bytesToUtf8,
189
192
  createBuffer,
193
+ createRunLengthEncoder,
194
+ decodeFlags,
190
195
  decodeJsonValue,
196
+ decodeLength,
197
+ decodeNonNegativeInt,
198
+ decodeNumber,
199
+ decodeRle,
200
+ decodeString,
201
+ encodeFlags,
191
202
  encodeJsonValue,
192
- hexToBytes,
193
- utf8ToBytes,
194
- } from "../Buffer.ts";
203
+ encodeLength,
204
+ encodeNonNegativeInt,
205
+ encodeNumber,
206
+ encodeString,
207
+ } from "../Binary.ts";
195
208
  import type { ConsoleDep } from "../Console.ts";
196
209
  import {
197
210
  createPadmePadding,
@@ -208,10 +221,11 @@ import { eqArrayNumber } from "../Eq.ts";
208
221
  import { computeBalancedBuckets } from "../Number.ts";
209
222
  import { createMutableRecord, objectToEntries } from "../Object.ts";
210
223
  import { err, ok, type Result } from "../Result.ts";
211
- import { SqliteValue } from "../Sqlite.ts";
224
+ import type { SqliteValue } from "../Sqlite.ts";
212
225
  import { AbortError, type Task } from "../Task.ts";
213
226
  import { Millis } from "../Time.ts";
214
227
  import {
228
+ assertType,
215
229
  Base64Url,
216
230
  base64UrlToUint8Array,
217
231
  between,
@@ -263,6 +277,10 @@ import {
263
277
  Counter,
264
278
  eqTimestamp,
265
279
  NodeId,
280
+ type NodeIdBytes,
281
+ nodeIdBytesLength,
282
+ nodeIdBytesToNodeId,
283
+ nodeIdToNodeIdBytes,
266
284
  Timestamp,
267
285
  TimestampBytes,
268
286
  timestampBytesLength,
@@ -270,8 +288,6 @@ import {
270
288
  timestampToTimestampBytes,
271
289
  } from "./Timestamp.ts";
272
290
 
273
- const jsonBuffer = createBuffer();
274
-
275
291
  const minProtocolMessageMaxSize = 1_000_000;
276
292
  const maxProtocolMessageMaxSize = 100_000_000;
277
293
 
@@ -427,7 +443,7 @@ export interface ProtocolVersionError
427
443
 
428
444
  /** Error for invalid or corrupted protocol message data. */
429
445
  export interface ProtocolInvalidDataError extends Typed<"ProtocolInvalidDataError"> {
430
- readonly data: globalThis.Uint8Array;
446
+ readonly data: Uint8Array;
431
447
  readonly error: unknown;
432
448
  }
433
449
 
@@ -836,13 +852,13 @@ export const createTimestampsBuffer = (): TimestampsBuffer => {
836
852
  encodeNonNegativeInt(buffer, value);
837
853
  });
838
854
  const nodeIdEncoder = createRunLengthEncoder<NodeId>((buffer, value) => {
839
- encodeNodeId(buffer, value);
855
+ buffer.extend(nodeIdToNodeIdBytes(value));
840
856
  });
841
857
 
842
858
  return {
843
859
  add: (timestamp) => {
844
860
  const delta = timestamp.millis - previousMillis;
845
- assert(NonNegativeInt.is(delta), "The delta must be NonNegativeInt");
861
+ assertType(NonNegativeInt, delta);
846
862
 
847
863
  count++;
848
864
  syncCount();
@@ -876,40 +892,6 @@ export const createTimestampsBuffer = (): TimestampsBuffer => {
876
892
  };
877
893
  };
878
894
 
879
- interface RunLengthEncoder<T> {
880
- add: (value: T) => void;
881
- getLength: () => NonNegativeInt;
882
- unwrap: () => Uint8Array;
883
- }
884
-
885
- const createRunLengthEncoder = <T>(
886
- encodeValue: (buffer: Buffer, value: T) => void,
887
- ): RunLengthEncoder<T> => {
888
- const buffer = createBuffer();
889
- let previousLength = zeroNonNegativeInt;
890
- let previousValue = null as T | null;
891
- let runLength = zeroNonNegativeInt;
892
-
893
- return {
894
- add: (value) => {
895
- if (value === previousValue) {
896
- runLength++;
897
- buffer.truncate(previousLength);
898
- } else {
899
- previousValue = value;
900
- runLength = NonNegativeInt.orThrow(1);
901
- }
902
- previousLength = buffer.getLength();
903
- encodeValue(buffer, value);
904
- encodeNonNegativeInt(buffer, runLength);
905
- },
906
-
907
- getLength: () => buffer.getLength(),
908
-
909
- unwrap: () => buffer.unwrap(),
910
- };
911
- };
912
-
913
895
  export interface ApplyProtocolMessageAsClientOptions {
914
896
  writeKey?: OwnerWriteKey;
915
897
 
@@ -1123,7 +1105,7 @@ export const applyProtocolMessageAsRelay =
1123
1105
  }
1124
1106
 
1125
1107
  const messageType = input.shift() as MessageType;
1126
- assert(messageType === MessageType.Request, "Invalid MessageType");
1108
+ assertSame(messageType, MessageType.Request);
1127
1109
 
1128
1110
  const hasWriteKey = input.shift();
1129
1111
  let writeKey: OwnerWriteKey | undefined;
@@ -1715,7 +1697,9 @@ const decodeTimestamps = (
1715
1697
  return counter.value;
1716
1698
  });
1717
1699
 
1718
- const nodeIds = decodeRle(buffer, length, (): NodeId => decodeNodeId(buffer));
1700
+ const nodeIds = decodeRle(buffer, length, (): NodeId =>
1701
+ nodeIdBytesToNodeId(buffer.shiftN(nodeIdBytesLength) as NodeIdBytes),
1702
+ );
1719
1703
 
1720
1704
  const timestamps = createMutableArray<Timestamp>(length);
1721
1705
  for (let i = 0; i < length; i++) {
@@ -1729,118 +1713,11 @@ const decodeTimestamps = (
1729
1713
  return timestamps;
1730
1714
  };
1731
1715
 
1732
- export const decodeRle = <T>(
1733
- buffer: Buffer,
1734
- length: NonNegativeInt,
1735
- decodeValue: () => T,
1736
- ): ReadonlyArray<T> => {
1737
- const values = createMutableArray<T>(length);
1738
- let index = 0;
1739
- while (index < length) {
1740
- const value = decodeValue();
1741
- const runLength = decodeNonNegativeInt(buffer);
1742
-
1743
- // Prevent infinite loop on malformed input.
1744
- if (runLength === 0) {
1745
- throw new ProtocolDecodeError(
1746
- "Invalid RLE encoding: runLength must be positive",
1747
- );
1748
- }
1749
- const remaining = length - index;
1750
-
1751
- // Prevent CPU/memory amplification via oversized runLength.
1752
- if (runLength > remaining) {
1753
- throw new ProtocolDecodeError(
1754
- `Invalid RLE encoding: runLength ${runLength} exceeds remaining ${remaining}`,
1755
- );
1756
- }
1757
- for (let i = 0; i < runLength; i++) {
1758
- values[index] = value;
1759
- index++;
1760
- }
1761
- }
1762
- return values;
1763
- };
1764
-
1765
1716
  const decodeId = (buffer: Buffer): Id => {
1766
1717
  const bytes = buffer.shiftN(idBytesTypeValueLength);
1767
1718
  return idBytesToId(bytes as IdBytes);
1768
1719
  };
1769
1720
 
1770
- /**
1771
- * Evolu uses MessagePack to handle finite numbers except for NonNegativeInt.
1772
- * For NonNegativeInt, Evolu provides more efficient encoding.
1773
- */
1774
- export const encodeNumber = (buffer: Buffer, number: FiniteNumber): void => {
1775
- encodeJsonValue(buffer, number);
1776
- };
1777
-
1778
- export const decodeNumber = (buffer: Buffer): FiniteNumber => {
1779
- const numberResult = FiniteNumber.fromUnknown(decodeJsonValue(buffer));
1780
- if (!numberResult.ok) throw new ProtocolDecodeError(numberResult.error.type);
1781
- return numberResult.value;
1782
- };
1783
-
1784
- /**
1785
- * Encodes an array of boolean flags into a single byte.
1786
- *
1787
- * Each element in the array corresponds to a bit (0-7). Array can have 0-8
1788
- * elements.
1789
- *
1790
- * ### Example
1791
- *
1792
- * ```ts
1793
- * import { assertEqual, createBuffer } from "@evolu/common";
1794
- * import { encodeFlags } from "@evolu/common/local-first";
1795
- *
1796
- * const buffer = createBuffer();
1797
- * encodeFlags(buffer, [true, false, true]);
1798
- *
1799
- * assertEqual(buffer.unwrap(), new Uint8Array([0b101]));
1800
- * ```
1801
- */
1802
- export const encodeFlags = (
1803
- buffer: Buffer,
1804
- flags: ReadonlyArray<boolean>,
1805
- ): void => {
1806
- let byte = 0;
1807
- for (let i = 0; i < flags.length && i < 8; i++) {
1808
- if (flags[i]) {
1809
- byte |= 1 << i;
1810
- }
1811
- }
1812
- buffer.extend([byte]);
1813
- };
1814
-
1815
- /**
1816
- * Decodes a byte into an array of boolean flags.
1817
- *
1818
- * ### Example
1819
- *
1820
- * ```ts
1821
- * import { assertEqual, createBuffer, PositiveInt } from "@evolu/common";
1822
- * import { decodeFlags } from "@evolu/common/local-first";
1823
- *
1824
- * const buffer = createBuffer([0b101]);
1825
- * const flags = decodeFlags(buffer, PositiveInt.orThrow(3));
1826
- *
1827
- * assertEqual(flags, [true, false, true]);
1828
- * assertEqual(buffer.getLength(), 0);
1829
- * ```
1830
- */
1831
- export const decodeFlags = (
1832
- buffer: Buffer,
1833
- count: PositiveInt,
1834
- ): ReadonlyArray<boolean> => {
1835
- const byte = buffer.shift();
1836
- const length = globalThis.Math.min(count, 8);
1837
- const flags = createMutableArray<boolean>(length);
1838
- for (let i = 0; i < length; i++) {
1839
- flags[i] = (byte & (1 << i)) !== 0;
1840
- }
1841
- return flags;
1842
- };
1843
-
1844
1721
  /**
1845
1722
  * Encodes and encrypts a {@link DbChange} using the provided owner's encryption
1846
1723
  * key. Returns an encrypted binary representation as {@link EncryptedDbChange}.
@@ -1972,91 +1849,30 @@ export const decryptAndDecodeDbChange = (
1972
1849
  };
1973
1850
 
1974
1851
  /**
1975
- * Encodes a non-negative integer into a variable-length integer format. It's
1976
- * more efficient than encoding via {@link encodeNumber}.
1852
+ * Decodes a ProtocolMessage into a readable JSON object for debugging.
1977
1853
  *
1978
- * https://en.wikipedia.org/wiki/Variable-length_quantity
1979
- */
1980
- export const encodeNonNegativeInt = (
1981
- buffer: Buffer,
1982
- int: NonNegativeInt,
1983
- ): void => {
1984
- if (int === 0) {
1985
- buffer.extend([0]);
1986
- return;
1987
- }
1988
-
1989
- let remaining = BigInt(int);
1990
- const bytes: Array<number> = [];
1991
-
1992
- while (remaining !== 0n) {
1993
- const byte = globalThis.Number(remaining & 127n);
1994
- bytes.push(byte);
1995
- remaining >>= 7n;
1996
- }
1997
-
1998
- for (let i = 0; i < bytes.length - 1; i++) {
1999
- bytes[i] |= 128;
2000
- }
2001
-
2002
- buffer.extend(bytes);
2003
- };
2004
-
2005
- /**
2006
- * Decodes a non-negative integer from a variable-length integer format.
1854
+ * Note: This is a stub for future implementation. It should use:
1855
+ *
1856
+ * - DecodeVersionAndOwner
1857
+ * - DecodeError or decodeWriteKeys (depending on context)
1858
+ * - DecodeMessages
1859
+ * - DecodeRanges
2007
1860
  *
2008
- * https://en.wikipedia.org/wiki/Variable-length_quantity
1861
+ * If you want to help, please contribute to this function.
2009
1862
  */
2010
- export const decodeNonNegativeInt = (buffer: Buffer): NonNegativeInt => {
2011
- let result = 0n;
2012
- let shift = 0n;
2013
- let byte;
2014
-
2015
- // 8 is the smallest required count
2016
- for (let byteCount = 0; byteCount < 8; byteCount++) {
2017
- byte = buffer.shift();
2018
- result |= BigInt(byte & 127) << shift;
2019
- if ((byte & 128) === 0) break;
2020
- shift += 7n;
2021
- }
2022
-
2023
- const int = NonNegativeInt.fromUnknown(globalThis.Number(result));
2024
- if (!int.ok) throw new ProtocolDecodeError(int.error.type);
2025
-
2026
- return int.value;
2027
- };
2028
-
2029
- export const encodeLength = (buffer: Buffer, value: ArrayLike<any>): void => {
2030
- encodeNonNegativeInt(buffer, NonNegativeInt.orThrow(value.length));
2031
- };
2032
-
2033
- export const decodeLength = decodeNonNegativeInt;
2034
-
2035
- export const encodeString = (buffer: Buffer, value: string): void => {
2036
- const bytes = utf8ToBytes(value);
2037
- encodeLength(buffer, bytes);
2038
- buffer.extend(bytes);
2039
- };
2040
-
2041
- export const decodeString = (buffer: Buffer): string => {
2042
- const length = decodeLength(buffer);
2043
- const bytes = buffer.shiftN(length);
2044
- return bytesToUtf8(bytes);
2045
- };
2046
-
2047
- export const encodeNodeId = (buffer: Buffer, nodeId: NodeId): void => {
2048
- buffer.extend(hexToBytes(nodeId));
2049
- };
2050
-
2051
- export const decodeNodeId = (buffer: Buffer): NodeId => {
2052
- const bytes = buffer.shiftN(NonNegativeInt.orThrow(8));
2053
- return bytesToHex(bytes) as NodeId;
1863
+ export const decodeProtocolMessageToJson = (
1864
+ _protocolMessage: ProtocolMessage,
1865
+ _isInitiator: boolean,
1866
+ ): unknown => {
1867
+ // TODO: Implement using
1868
+ // - decodeVersionAndOwner
1869
+ // -- decodeError or decodeWriteKeys (should be refactored out),
1870
+ // -- decodeMessages, and decodeRanges.
1871
+ // This is a stub for PRs and community contributions.
1872
+ throw new Error("decodeProtocolMessageToJson is not implemented yet.");
2054
1873
  };
2055
1874
 
2056
1875
  // Small ints are encoded into ProtocolValueType, saving one byte per int.
2057
- const isSmallInt: Predicate<number> = (value: number) =>
2058
- value >= 0 && value < 20;
2059
-
2060
1876
  export const ProtocolValueType = {
2061
1877
  // 0-19 small ints
2062
1878
 
@@ -2163,7 +1979,7 @@ export const encodeSqliteValue = (buffer: Buffer, value: SqliteValue): void => {
2163
1979
  case "number": {
2164
1980
  // Negative zero is a non-negative integer in JavaScript, but integer
2165
1981
  // encoding would lose its observable sign.
2166
- if (!globalThis.Object.is(value, -0) && NonNegativeInt.is(value)) {
1982
+ if (!Object.is(value, -0) && NonNegativeInt.is(value)) {
2167
1983
  if (isSmallInt(value)) {
2168
1984
  encodeNonNegativeInt(buffer, value);
2169
1985
  return;
@@ -2213,9 +2029,9 @@ export const decodeSqliteValue = (buffer: Buffer): SqliteValue => {
2213
2029
 
2214
2030
  case ProtocolValueType.Json: {
2215
2031
  const length = decodeLength(buffer);
2216
- const lengthBeforeDecoding = buffer.getLength();
2217
- const value = decodeJsonValue(buffer);
2218
- if (lengthBeforeDecoding - buffer.getLength() !== length) {
2032
+ const jsonValueBuffer = createBuffer(buffer.shiftN(length));
2033
+ const value = decodeJsonValue(jsonValueBuffer);
2034
+ if (jsonValueBuffer.getLength() !== 0) {
2219
2035
  throw new ProtocolDecodeError("Invalid JSON MessagePack length");
2220
2036
  }
2221
2037
  return JSON.stringify(value);
@@ -2246,26 +2062,7 @@ export const decodeSqliteValue = (buffer: Buffer): SqliteValue => {
2246
2062
  }
2247
2063
  };
2248
2064
 
2249
- /**
2250
- * Decodes a ProtocolMessage into a readable JSON object for debugging.
2251
- *
2252
- * Note: This is a stub for future implementation. It should use:
2253
- *
2254
- * - DecodeVersionAndOwner
2255
- * - DecodeError or decodeWriteKeys (depending on context)
2256
- * - DecodeMessages
2257
- * - DecodeRanges
2258
- *
2259
- * If you want to help, please contribute to this function.
2260
- */
2261
- export const decodeProtocolMessageToJson = (
2262
- _protocolMessage: ProtocolMessage,
2263
- _isInitiator: boolean,
2264
- ): unknown => {
2265
- // TODO: Implement using
2266
- // - decodeVersionAndOwner
2267
- // -- decodeError or decodeWriteKeys (should be refactored out),
2268
- // -- decodeMessages, and decodeRanges.
2269
- // This is a stub for PRs and community contributions.
2270
- throw new Error("decodeProtocolMessageToJson is not implemented yet.");
2271
- };
2065
+ const jsonBuffer = createBuffer();
2066
+
2067
+ const isSmallInt: Predicate<number> = (value: number) =>
2068
+ value >= 0 && value < 20;