@evolu/common 8.11.0 → 8.13.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 (72) hide show
  1. package/dist/src/Bytes.d.ts +39 -2
  2. package/dist/src/Bytes.d.ts.map +1 -1
  3. package/dist/src/Bytes.js +50 -2
  4. package/dist/src/Callbacks.d.ts +12 -1
  5. package/dist/src/Callbacks.d.ts.map +1 -1
  6. package/dist/src/Callbacks.js +3 -0
  7. package/dist/src/Error.d.ts +10 -4
  8. package/dist/src/Error.d.ts.map +1 -1
  9. package/dist/src/Error.js +10 -4
  10. package/dist/src/Object.d.ts +65 -0
  11. package/dist/src/Object.d.ts.map +1 -1
  12. package/dist/src/Object.js +142 -0
  13. package/dist/src/Resource.d.ts +0 -5
  14. package/dist/src/Resource.d.ts.map +1 -1
  15. package/dist/src/Resource.js +6 -13
  16. package/dist/src/Sqlite.d.ts.map +1 -1
  17. package/dist/src/Sqlite.js +7 -0
  18. package/dist/src/Task.d.ts +10 -8
  19. package/dist/src/Task.d.ts.map +1 -1
  20. package/dist/src/Task.js +41 -5
  21. package/dist/src/Worker.d.ts +3 -3
  22. package/dist/src/index.d.ts +1 -1
  23. package/dist/src/index.d.ts.map +1 -1
  24. package/dist/src/index.js +1 -1
  25. package/dist/src/local-first/Db.d.ts +8 -3
  26. package/dist/src/local-first/Db.d.ts.map +1 -1
  27. package/dist/src/local-first/Db.js +56 -19
  28. package/dist/src/local-first/Evolu.d.ts +142 -24
  29. package/dist/src/local-first/Evolu.d.ts.map +1 -1
  30. package/dist/src/local-first/Evolu.js +109 -8
  31. package/dist/src/local-first/Owner.d.ts +9 -0
  32. package/dist/src/local-first/Owner.d.ts.map +1 -1
  33. package/dist/src/local-first/Owner.js +9 -0
  34. package/dist/src/local-first/Protocol.d.ts +18 -7
  35. package/dist/src/local-first/Protocol.d.ts.map +1 -1
  36. package/dist/src/local-first/Protocol.js +45 -28
  37. package/dist/src/local-first/Relay.d.ts.map +1 -1
  38. package/dist/src/local-first/Relay.js +4 -2
  39. package/dist/src/local-first/Schema.d.ts +18 -3
  40. package/dist/src/local-first/Schema.d.ts.map +1 -1
  41. package/dist/src/local-first/Shared.d.ts +523 -133
  42. package/dist/src/local-first/Shared.d.ts.map +1 -1
  43. package/dist/src/local-first/Shared.js +696 -256
  44. package/dist/src/local-first/Storage.d.ts +19 -15
  45. package/dist/src/local-first/Storage.d.ts.map +1 -1
  46. package/dist/src/local-first/Storage.js +4 -2
  47. package/package.json +1 -1
  48. package/src/Bytes.test.ts +27 -0
  49. package/src/Bytes.ts +58 -2
  50. package/src/Callbacks.test.ts +20 -0
  51. package/src/Callbacks.ts +17 -1
  52. package/src/Error.ts +10 -4
  53. package/src/Object.test.ts +296 -0
  54. package/src/Object.ts +163 -0
  55. package/src/Resource.test.ts +20 -16
  56. package/src/Resource.ts +6 -20
  57. package/src/Sqlite.ts +7 -0
  58. package/src/Task.test.ts +233 -62
  59. package/src/Task.ts +47 -13
  60. package/src/Worker.ts +3 -3
  61. package/src/index.ts +6 -1
  62. package/src/local-first/Db.ts +88 -18
  63. package/src/local-first/Evolu.test.ts +589 -2
  64. package/src/local-first/Evolu.ts +285 -36
  65. package/src/local-first/Owner.ts +9 -0
  66. package/src/local-first/Protocol.test.ts +59 -60
  67. package/src/local-first/Protocol.ts +67 -47
  68. package/src/local-first/Relay.ts +4 -2
  69. package/src/local-first/Schema.ts +20 -3
  70. package/src/local-first/Shared.test.ts +2633 -646
  71. package/src/local-first/Shared.ts +1192 -364
  72. package/src/local-first/Storage.ts +24 -23
@@ -9,8 +9,7 @@ import type { NonEmptyReadonlyArray } from "../Array.ts";
9
9
  import { firstInArray, isNonEmptyArray } from "../Array.ts";
10
10
  import { assert, assertNonNullable } from "../Assert.ts";
11
11
  import type { Brand } from "../Brand.ts";
12
- import { concatBytes } from "../Bytes.ts";
13
- import type { DecryptWithXChaCha20Poly1305Error } from "../Crypto.ts";
12
+ import { concatByteArrays } from "../Bytes.ts";
14
13
  import { decrement } from "../Number.ts";
15
14
  import type { RandomDep } from "../Random.ts";
16
15
  import { err, ok } from "../Result.ts";
@@ -39,11 +38,9 @@ import {
39
38
  import type { Awaitable } from "../Types.ts";
40
39
  import type { Owner, OwnerError, OwnerIdBytes } from "./Owner.ts";
41
40
  import { OwnerId, OwnerWriteKey } from "./Owner.ts";
42
- import type {
43
- ProtocolInvalidDataError,
44
- ProtocolTimestampMismatchError,
45
- } from "./Protocol.ts";
41
+ import type { ProtocolQuotaError } from "./Protocol.ts";
46
42
  import { systemColumnsWithId } from "./Schema.ts";
43
+ import type { syncStateToOwnerSyncStatus } from "./Shared.ts";
47
44
  import {
48
45
  createTimestamp,
49
46
  orderTimestampBytes,
@@ -72,9 +69,10 @@ export interface StorageConfig {
72
69
  * The callback returns a boolean rather than an error because error handling
73
70
  * and logging are the responsibility of the callback implementation.
74
71
  *
75
- * Relay deployments configure this callback. Client applications can observe
76
- * a denied relay write as a `ProtocolQuotaError` by subscribing once to the
77
- * shared `EvoluErrorDep.evoluError` store returned by `createEvoluDeps`.
72
+ * Relay deployments configure this callback. Client applications observe a
73
+ * denied relay write as a {@link ProtocolQuotaError} in the `failure` of that
74
+ * relay's route, which {@link syncStateToOwnerSyncStatus} reports as the
75
+ * owner's `Error` status.
78
76
  *
79
77
  * ### Example
80
78
  *
@@ -109,7 +107,7 @@ export interface StorageConfig {
109
107
  */
110
108
  readonly isOwnerWithinQuota: (
111
109
  ownerId: OwnerId,
112
- requiredBytes: PositiveInt,
110
+ requiredBytes: NonNegativeInt,
113
111
  ) => Awaitable<boolean>;
114
112
  }
115
113
 
@@ -194,7 +192,10 @@ export interface Storage {
194
192
  * Write encrypted {@link CrdtMessage}s to storage.
195
193
  *
196
194
  * Stores none of the messages and returns the cause when the batch cannot be
197
- * accepted.
195
+ * accepted. A client storage that cannot decrypt, verify, or decode a message
196
+ * skips it and stores the rest, as the built-in client storage does, because
197
+ * the peer offers the message again in every round, and rejecting the batch
198
+ * would end each round.
198
199
  *
199
200
  * Must use a mutex per ownerId to ensure sequential processing and proper
200
201
  * protocol logic handling during sync operations.
@@ -234,19 +235,17 @@ export interface StorageQuotaError
234
235
  /**
235
236
  * Expected reasons why {@link Storage.writeMessages} stored none of a batch.
236
237
  *
237
- * Each implementation returns the members that apply to it. The built-in relay
238
- * storage currently stores opaque encrypted messages and rejects batches over
239
- * quota. The built-in client storage decrypts and validates incoming messages
240
- * before updating its clock and database tables. The contract permits quota
241
- * checks on either side.
238
+ * The built-in relay storage stores opaque encrypted messages and rejects
239
+ * batches over quota. The built-in client storage decrypts and validates
240
+ * incoming messages before updating its clock and database tables. It skips a
241
+ * message that fails instead of rejecting its batch, and sync state shows it as
242
+ * the route's `skippedError` without ending the sync round, so a message is
243
+ * never a reason to reject a batch. The contract permits quota checks on either
244
+ * side.
242
245
  *
243
246
  * @group Core
244
247
  */
245
- export type StorageWriteMessagesError =
246
- | DecryptWithXChaCha20Poly1305Error
247
- | ProtocolInvalidDataError
248
- | ProtocolTimestampMismatchError
249
- | StorageQuotaError;
248
+ export type StorageWriteMessagesError = StorageQuotaError;
250
249
 
251
250
  /**
252
251
  * A cryptographic hash used for efficiently comparing collections of
@@ -581,7 +580,9 @@ export const createBaseSqliteStorage = (
581
580
  },
582
581
 
583
582
  getExistingTimestamps: (ownerIdBytes, timestampsBytes) => {
584
- const concatenatedTimestamps = concatBytes(...timestampsBytes);
583
+ // A batch can hold hundreds of thousands of timestamps, too many to spread
584
+ // into concatBytes.
585
+ const concatenatedTimestamps = concatByteArrays(timestampsBytes);
585
586
 
586
587
  const result = deps.sqlite.exec<{
587
588
  timestampBytes: TimestampBytes;
@@ -1808,7 +1809,7 @@ export const updateOwnerUsage =
1808
1809
  (deps: SqliteDep) =>
1809
1810
  (
1810
1811
  ownerIdBytes: OwnerIdBytes,
1811
- storedBytes: PositiveInt,
1812
+ storedBytes: NonNegativeInt,
1812
1813
  firstTimestamp: TimestampBytes,
1813
1814
  lastTimestamp: TimestampBytes,
1814
1815
  ): void => {