@evolu/common 6.0.1-preview.20 → 6.0.1-preview.22

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.
@@ -20,7 +20,7 @@
20
20
  * transfer, ownership, real-time broadcasting, request-response semantics, and
21
21
  * error handling.
22
22
  *
23
- * ### Message Structure
23
+ * ### Message structure
24
24
  *
25
25
  * | Field | Notes |
26
26
  * | :----------------------------- | :------------------------ |
@@ -43,7 +43,7 @@
43
43
  * | - {@link NonNegativeInt} | Number of ranges. |
44
44
  * | - {@link Range} | |
45
45
  *
46
- * ### WriteKey Validation
46
+ * ### WriteKey validation
47
47
  *
48
48
  * The initiator sends a hasWriteKey flag and optionally a WriteKey. The
49
49
  * WriteKey is required when sending messages as a secure token proving the
@@ -79,33 +79,33 @@
79
79
  * initiator. In relay-to-relay or P2P sync, both sides may require the
80
80
  * {@link OwnerWriteKey} depending on who is the initiator.
81
81
  *
82
- * ### Protocol Errors
82
+ * ### Protocol errors
83
83
  *
84
84
  * The protocol uses error codes in the header to signal issues:
85
85
  *
86
86
  * - {@link ProtocolWriteKeyError}: The provided WriteKey is invalid or missing.
87
- * - {@link ProtocolWriteError}: A write operation failed (e.g., due to storage
88
- * limits or billing).
89
- * - {@link ProtocolSyncError}: A generic or unexpected synchronization failure
87
+ * - {@link ProtocolWriteError}: A serious relay-side write failure occurred.
88
+ * - {@link ProtocolSyncError}: A serious relay-side synchronization failure
90
89
  * occurred.
90
+ * - {@link ProtocolQuotaExceededError}: Storage or billing quota exceeded.
91
91
  * - {@link ProtocolUnsupportedVersionError}: Protocol version mismatch.
92
92
  * - {@link ProtocolInvalidDataError}: The message is malformed or corrupted.
93
93
  *
94
94
  * All protocol errors except `ProtocolInvalidDataError` include the `OwnerId`
95
95
  * to allow clients to associate errors with the correct owner.
96
96
  *
97
- * ### Message Size Limit
97
+ * ### Message size limit
98
98
  *
99
99
  * The protocol enforces a strict maximum size for all messages, defined by
100
- * {@link maxProtocolMessageSize}. This ensures every {@link ProtocolMessage} is
100
+ * {@link ProtocolMessageMaxSize}. This ensures every {@link ProtocolMessage} is
101
101
  * less than or equal to this limit, enabling stateless transports, simplified
102
102
  * relay implementation, and predictable memory usage. When all messages don't
103
103
  * fit within the limit, the protocol automatically continues synchronization in
104
104
  * subsequent rounds using range-based reconciliation.
105
105
  *
106
- * Individual database mutations are limited to `maxMutationSize` (640KB), which
107
- * is smaller than the protocol message limit to ensure efficient sync with
108
- * {@link maxProtocolMessageRangesSize}.
106
+ * Database mutations are limited to 640KB, which is smaller than the protocol
107
+ * message limit to ensure efficient sync with
108
+ * {@link defaultProtocolMessageRangesMaxSize}.
109
109
  *
110
110
  * ### Why Binary?
111
111
  *
@@ -148,6 +148,15 @@
148
148
  * Version negotiation is per-owner, allowing Evolu Protocol to evolve safely
149
149
  * over time and provide clear feedback about version mismatches.
150
150
  *
151
+ * ### Credible exit
152
+ *
153
+ * The protocol specification is intentionally non-configurable to ensure
154
+ * universal compatibility. This design allows applications (users) to switch
155
+ * between any compliant relay without negotiation or compatibility checks
156
+ * beyond version matching. Relays are generic infrastructure that any
157
+ * application can use interchangeably making exit from any single provider
158
+ * technically feasible and economically viable.
159
+ *
151
160
  * @module
152
161
  */
153
162
  import { NonEmptyReadonlyArray } from "../Array.js";
@@ -160,10 +169,51 @@ import { NonNegativeInt, PositiveInt } from "../Type.js";
160
169
  import { Owner, OwnerId, OwnerWriteKey } from "./Owner.js";
161
170
  import { BaseRange, CrdtMessage, DbChange, EncryptedCrdtMessage, EncryptedDbChange, FingerprintRange, RangeType, SkipRange, StorageDep } from "./Storage.js";
162
171
  import { NodeId, Timestamp } from "./Timestamp.js";
163
- /** Maximum size of the entire protocol message in bytes. */
164
- export declare const maxProtocolMessageSize: PositiveInt;
165
- /** Maximum size of the ranges in bytes. */
166
- export declare const maxProtocolMessageRangesSize: PositiveInt;
172
+ /**
173
+ * Protocol message maximum size.
174
+ *
175
+ * Defines the upper limit for how large a single protocol message can be.
176
+ * Implementations must enforce a maximum size between 1MB and 100MB to ensure
177
+ * compatibility across all Evolu implementations (the maximum size of mutation
178
+ * change is hardcoded and enforced hence the maximum size can't be smaller).
179
+ *
180
+ * Larger maximum sizes can be configured by relays to reduce roundtrips. For
181
+ * example, a dedicated relay with ample resources could configure a 100MB
182
+ * maximum to minimize roundtrips for large syncs.
183
+ *
184
+ * Only relays can safely configure larger sizes, as clients will handle them.
185
+ * Increasing this value on the client side would break compatibility with
186
+ * relays that enforce smaller limits.
187
+ */
188
+ export declare const ProtocolMessageMaxSize: import("../Type.js").BrandType<import("../Type.js").Type<"Brand", number & Brand<"Int">, number, import("../Type.js").IntError, number, import("../Type.js").NumberError>, "Between1000000-100000000", import("../Type.js").BetweenError<1000000, 100000000>, import("../Type.js").IntError | import("../Type.js").NumberError>;
189
+ export type ProtocolMessageMaxSize = typeof ProtocolMessageMaxSize.Type;
190
+ /**
191
+ * Default {@link ProtocolMessageMaxSize} (1MB).
192
+ *
193
+ * The standard size used across Evolu implementations. Relays with more
194
+ * resources can configure larger sizes to reduce roundtrips.
195
+ */
196
+ export declare const defaultProtocolMessageMaxSize: ProtocolMessageMaxSize;
197
+ /**
198
+ * Protocol message ranges maximum size.
199
+ *
200
+ * Defines the upper limit for how large the ranges section of a protocol
201
+ * message can be. Implementations must enforce a maximum size between 3KB and
202
+ * 100KB to ensure compatibility.
203
+ *
204
+ * The upper bound is set to ensure ranges fit within the default 1MB
205
+ * {@link defaultProtocolMessageMaxSize}, maintaining compatibility between all
206
+ * clients and relays.
207
+ */
208
+ export declare const ProtocolMessageRangesMaxSize: import("../Type.js").BrandType<import("../Type.js").Type<"Brand", number & Brand<"Int">, number, import("../Type.js").IntError, number, import("../Type.js").NumberError>, "Between3000-100000", import("../Type.js").BetweenError<3000, 100000>, import("../Type.js").IntError | import("../Type.js").NumberError>;
209
+ export type ProtocolMessageRangesMaxSize = typeof ProtocolMessageRangesMaxSize.Type;
210
+ /**
211
+ * Default {@link ProtocolMessageRangesMaxSize} (30KB).
212
+ *
213
+ * The standard size used across Evolu implementations. Relays with more
214
+ * resources can configure larger sizes to reduce roundtrips.
215
+ */
216
+ export declare const defaultProtocolMessageRangesMaxSize: ProtocolMessageRangesMaxSize;
167
217
  /** Evolu Protocol Message. */
168
218
  export type ProtocolMessage = Uint8Array & Brand<"ProtocolMessage">;
169
219
  /** Evolu Protocol version. */
@@ -194,9 +244,11 @@ export declare const ProtocolErrorCode: {
194
244
  readonly WriteError: 2;
195
245
  /** A code for {@link ProtocolSyncError}. */
196
246
  readonly SyncError: 3;
247
+ /** A code for {@link ProtocolQuotaExceededError}. */
248
+ readonly QuotaExceededError: 4;
197
249
  };
198
250
  type ProtocolErrorCode = (typeof ProtocolErrorCode)[keyof typeof ProtocolErrorCode];
199
- export type ProtocolError = ProtocolUnsupportedVersionError | ProtocolInvalidDataError | ProtocolWriteKeyError | ProtocolWriteError | ProtocolSyncError | ProtocolTimestampMismatchError;
251
+ export type ProtocolError = ProtocolUnsupportedVersionError | ProtocolInvalidDataError | ProtocolWriteKeyError | ProtocolWriteError | ProtocolSyncError | ProtocolQuotaExceededError | ProtocolTimestampMismatchError;
200
252
  /** Base interface for all protocol errors. */
201
253
  export interface ProtocolErrorBase {
202
254
  readonly ownerId: OwnerId;
@@ -222,19 +274,29 @@ export interface ProtocolWriteKeyError extends ProtocolErrorBase {
222
274
  readonly type: "ProtocolWriteKeyError";
223
275
  }
224
276
  /**
225
- * Error when a write fails due to storage limits or billing requirements.
226
- * Indicates the need to expand capacity or resolve payment issues.
277
+ * Error indicating a serious relay-side write failure. Clients should log this
278
+ * error and show a generic sync error to the user.
227
279
  */
228
280
  export interface ProtocolWriteError extends ProtocolErrorBase {
229
281
  readonly type: "ProtocolWriteError";
230
282
  }
231
283
  /**
232
- * Error indicating a synchronization failure during the protocol exchange. Used
233
- * for unexpected or generic sync errors not covered by other error types.
284
+ * Error indicating a serious relay-side synchronization failure. Clients should
285
+ * log this error and show a generic sync error to the user.
234
286
  */
235
287
  export interface ProtocolSyncError extends ProtocolErrorBase {
236
288
  readonly type: "ProtocolSyncError";
237
289
  }
290
+ /**
291
+ * Error when storage or billing quota is exceeded. Clients should prompt the
292
+ * user to upgrade their plan or expand capacity.
293
+ *
294
+ * TODO: Add callback to relay config to check quota and return this error when
295
+ * limits are reached.
296
+ */
297
+ export interface ProtocolQuotaExceededError extends ProtocolErrorBase {
298
+ readonly type: "ProtocolQuotaExceededError";
299
+ }
238
300
  /**
239
301
  * Error when embedded timestamp doesn't match expected timestamp in
240
302
  * EncryptedDbChange. Indicates potential tampering or corruption of CRDT
@@ -248,11 +310,11 @@ export interface ProtocolTimestampMismatchError {
248
310
  /**
249
311
  * Creates a {@link ProtocolMessage} from CRDT messages.
250
312
  *
251
- * If the message size would exceed {@link maxProtocolMessageSize}, the protocol
252
- * ensures all messages will be sent in the next round(s) even over
313
+ * If the message size would exceed {@link defaultProtocolMessageMaxSize}, the
314
+ * protocol ensures all messages will be sent in the next round(s) even over
253
315
  * unidirectional and stateless transports.
254
316
  */
255
- export declare const createProtocolMessageFromCrdtMessages: (deps: RandomBytesDep & SymmetricCryptoDep) => (owner: Owner, messages: NonEmptyReadonlyArray<CrdtMessage>, maxSize?: PositiveInt) => ProtocolMessage;
317
+ export declare const createProtocolMessageFromCrdtMessages: (deps: RandomBytesDep & SymmetricCryptoDep) => (owner: Owner, messages: NonEmptyReadonlyArray<CrdtMessage>, maxSize?: ProtocolMessageMaxSize) => ProtocolMessage;
256
318
  /** Creates a {@link ProtocolMessage} for sync. */
257
319
  export declare const createProtocolMessageForSync: (deps: StorageDep) => (ownerId: OwnerId, subscriptionFlag?: SubscriptionFlag) => ProtocolMessage | null;
258
320
  export declare const createProtocolMessageForUnsubscribe: (ownerId: OwnerId) => ProtocolMessage;
@@ -270,8 +332,8 @@ export interface ProtocolMessageBuffer {
270
332
  readonly getSize: () => PositiveInt;
271
333
  }
272
334
  export declare const createProtocolMessageBuffer: (ownerId: OwnerId, options: {
273
- readonly totalMaxSize?: PositiveInt | undefined;
274
- readonly rangesMaxSize?: PositiveInt | undefined;
335
+ readonly totalMaxSize?: ProtocolMessageMaxSize | undefined;
336
+ readonly rangesMaxSize?: ProtocolMessageRangesMaxSize | undefined;
275
337
  readonly version?: NonNegativeInt;
276
338
  } & ({
277
339
  readonly messageType: typeof MessageType.Request;
@@ -299,8 +361,7 @@ export interface ApplyProtocolMessageAsClientOptions {
299
361
  getWriteKey?: (ownerId: OwnerId) => OwnerWriteKey | null;
300
362
  /** For testing purposes only; should not be used in production. */
301
363
  version?: NonNegativeInt;
302
- totalMaxSize?: PositiveInt;
303
- rangesMaxSize?: PositiveInt;
364
+ rangesMaxSize?: ProtocolMessageRangesMaxSize;
304
365
  }
305
366
  /**
306
367
  * Result type for {@link applyProtocolMessageAsClient} that distinguishes
@@ -314,7 +375,7 @@ export type ApplyProtocolMessageAsClientResult = {
314
375
  } | {
315
376
  readonly type: "broadcast";
316
377
  };
317
- export declare const applyProtocolMessageAsClient: (deps: StorageDep) => (inputMessage: Uint8Array, options?: ApplyProtocolMessageAsClientOptions) => Promise<Result<ApplyProtocolMessageAsClientResult, ProtocolInvalidDataError | ProtocolSyncError | ProtocolUnsupportedVersionError | ProtocolWriteError | ProtocolWriteKeyError>>;
378
+ export declare const applyProtocolMessageAsClient: (deps: StorageDep) => (inputMessage: Uint8Array, options?: ApplyProtocolMessageAsClientOptions) => Promise<Result<ApplyProtocolMessageAsClientResult, ProtocolInvalidDataError | ProtocolSyncError | ProtocolUnsupportedVersionError | ProtocolWriteError | ProtocolWriteKeyError | ProtocolQuotaExceededError>>;
318
379
  export interface ApplyProtocolMessageAsRelayOptions {
319
380
  /** To subscribe an owner for broadcasting. */
320
381
  subscribe?: (ownerId: OwnerId) => void;
@@ -322,8 +383,8 @@ export interface ApplyProtocolMessageAsRelayOptions {
322
383
  unsubscribe?: (ownerId: OwnerId) => void;
323
384
  /** To broadcast a protocol message to all subscribers. */
324
385
  broadcast?: (ownerId: OwnerId, message: ProtocolMessage) => void;
325
- totalMaxSize?: PositiveInt;
326
- rangesMaxSize?: PositiveInt;
386
+ totalMaxSize?: ProtocolMessageMaxSize;
387
+ rangesMaxSize?: ProtocolMessageRangesMaxSize;
327
388
  }
328
389
  /**
329
390
  * Result type for {@link applyProtocolMessageAsRelay}.
@@ -1 +1 @@
1
- {"version":3,"file":"Protocol.d.ts","sourceRoot":"","sources":["../../../src/Evolu/Protocol.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"Protocol.d.ts","sourceRoot":"","sources":["../../../src/Evolu/Protocol.ts"],"names":[],"mappings":"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"}
@@ -1,4 +1,3 @@
1
- /* eslint-disable jsdoc/no-undefined-types */
2
1
  /**
3
2
  * Evolu Protocol
4
3
  *
@@ -21,7 +20,7 @@
21
20
  * transfer, ownership, real-time broadcasting, request-response semantics, and
22
21
  * error handling.
23
22
  *
24
- * ### Message Structure
23
+ * ### Message structure
25
24
  *
26
25
  * | Field | Notes |
27
26
  * | :----------------------------- | :------------------------ |
@@ -44,7 +43,7 @@
44
43
  * | - {@link NonNegativeInt} | Number of ranges. |
45
44
  * | - {@link Range} | |
46
45
  *
47
- * ### WriteKey Validation
46
+ * ### WriteKey validation
48
47
  *
49
48
  * The initiator sends a hasWriteKey flag and optionally a WriteKey. The
50
49
  * WriteKey is required when sending messages as a secure token proving the
@@ -80,33 +79,33 @@
80
79
  * initiator. In relay-to-relay or P2P sync, both sides may require the
81
80
  * {@link OwnerWriteKey} depending on who is the initiator.
82
81
  *
83
- * ### Protocol Errors
82
+ * ### Protocol errors
84
83
  *
85
84
  * The protocol uses error codes in the header to signal issues:
86
85
  *
87
86
  * - {@link ProtocolWriteKeyError}: The provided WriteKey is invalid or missing.
88
- * - {@link ProtocolWriteError}: A write operation failed (e.g., due to storage
89
- * limits or billing).
90
- * - {@link ProtocolSyncError}: A generic or unexpected synchronization failure
87
+ * - {@link ProtocolWriteError}: A serious relay-side write failure occurred.
88
+ * - {@link ProtocolSyncError}: A serious relay-side synchronization failure
91
89
  * occurred.
90
+ * - {@link ProtocolQuotaExceededError}: Storage or billing quota exceeded.
92
91
  * - {@link ProtocolUnsupportedVersionError}: Protocol version mismatch.
93
92
  * - {@link ProtocolInvalidDataError}: The message is malformed or corrupted.
94
93
  *
95
94
  * All protocol errors except `ProtocolInvalidDataError` include the `OwnerId`
96
95
  * to allow clients to associate errors with the correct owner.
97
96
  *
98
- * ### Message Size Limit
97
+ * ### Message size limit
99
98
  *
100
99
  * The protocol enforces a strict maximum size for all messages, defined by
101
- * {@link maxProtocolMessageSize}. This ensures every {@link ProtocolMessage} is
100
+ * {@link ProtocolMessageMaxSize}. This ensures every {@link ProtocolMessage} is
102
101
  * less than or equal to this limit, enabling stateless transports, simplified
103
102
  * relay implementation, and predictable memory usage. When all messages don't
104
103
  * fit within the limit, the protocol automatically continues synchronization in
105
104
  * subsequent rounds using range-based reconciliation.
106
105
  *
107
- * Individual database mutations are limited to `maxMutationSize` (640KB), which
108
- * is smaller than the protocol message limit to ensure efficient sync with
109
- * {@link maxProtocolMessageRangesSize}.
106
+ * Database mutations are limited to 640KB, which is smaller than the protocol
107
+ * message limit to ensure efficient sync with
108
+ * {@link defaultProtocolMessageRangesMaxSize}.
110
109
  *
111
110
  * ### Why Binary?
112
111
  *
@@ -149,6 +148,15 @@
149
148
  * Version negotiation is per-owner, allowing Evolu Protocol to evolve safely
150
149
  * over time and provide clear feedback about version mismatches.
151
150
  *
151
+ * ### Credible exit
152
+ *
153
+ * The protocol specification is intentionally non-configurable to ensure
154
+ * universal compatibility. This design allows applications (users) to switch
155
+ * between any compliant relay without negotiation or compatibility checks
156
+ * beyond version matching. Relays are generic infrastructure that any
157
+ * application can use interchangeably making exit from any single provider
158
+ * technically feasible and economically viable.
159
+ *
152
160
  * @module
153
161
  */
154
162
  import { Packr } from "msgpackr";
@@ -160,21 +168,62 @@ import { eqArrayNumber } from "../Eq.js";
160
168
  import { computeBalancedBuckets } from "../Number.js";
161
169
  import { objectToEntries } from "../Object.js";
162
170
  import { err, ok } from "../Result.js";
163
- import { Base64Url, base64UrlToUint8Array, DateIso, Id, idBytesToId, idBytesTypeValueLength, idToIdBytes, Json, jsonToJsonValue, NonNegativeInt, Number, uint8ArrayToBase64Url, } from "../Type.js";
171
+ import { Base64Url, base64UrlToUint8Array, between, DateIso, Id, idBytesToId, idBytesTypeValueLength, idToIdBytes, Int, Json, jsonToJsonValue, NonNegativeInt, Number, uint8ArrayToBase64Url, } from "../Type.js";
164
172
  import { ownerIdToOwnerIdBytes, ownerWriteKeyLength, } from "./Owner.js";
165
173
  import { fingerprintSize, InfiniteUpperBound, RangeType, } from "./Storage.js";
166
174
  import { Counter, eqTimestamp, Millis, timestampBytesLength, timestampBytesToTimestamp, timestampToTimestampBytes, } from "./Timestamp.js";
167
175
  /**
168
- * MessagePack serializer for standard compatibility and compact encoding.
176
+ * Evolu uses MessagePack for numbers and JSONs.
169
177
  *
170
178
  * - `variableMapSize: true` - More compact maps, ~5-10% slower encoding
171
179
  * - `useRecords: false` - Standard MessagePack without extensions
172
180
  */
173
181
  const packr = new Packr({ variableMapSize: true, useRecords: false });
174
- /** Maximum size of the entire protocol message in bytes. */
175
- export const maxProtocolMessageSize = 1_000_000;
176
- /** Maximum size of the ranges in bytes. */
177
- export const maxProtocolMessageRangesSize = 30_000;
182
+ const minProtocolMessageMaxSize = 1_000_000;
183
+ const maxProtocolMessageMaxSize = 100_000_000;
184
+ /**
185
+ * Protocol message maximum size.
186
+ *
187
+ * Defines the upper limit for how large a single protocol message can be.
188
+ * Implementations must enforce a maximum size between 1MB and 100MB to ensure
189
+ * compatibility across all Evolu implementations (the maximum size of mutation
190
+ * change is hardcoded and enforced hence the maximum size can't be smaller).
191
+ *
192
+ * Larger maximum sizes can be configured by relays to reduce roundtrips. For
193
+ * example, a dedicated relay with ample resources could configure a 100MB
194
+ * maximum to minimize roundtrips for large syncs.
195
+ *
196
+ * Only relays can safely configure larger sizes, as clients will handle them.
197
+ * Increasing this value on the client side would break compatibility with
198
+ * relays that enforce smaller limits.
199
+ */
200
+ export const ProtocolMessageMaxSize = between(minProtocolMessageMaxSize, maxProtocolMessageMaxSize)(Int);
201
+ /**
202
+ * Default {@link ProtocolMessageMaxSize} (1MB).
203
+ *
204
+ * The standard size used across Evolu implementations. Relays with more
205
+ * resources can configure larger sizes to reduce roundtrips.
206
+ */
207
+ export const defaultProtocolMessageMaxSize = minProtocolMessageMaxSize;
208
+ /**
209
+ * Protocol message ranges maximum size.
210
+ *
211
+ * Defines the upper limit for how large the ranges section of a protocol
212
+ * message can be. Implementations must enforce a maximum size between 3KB and
213
+ * 100KB to ensure compatibility.
214
+ *
215
+ * The upper bound is set to ensure ranges fit within the default 1MB
216
+ * {@link defaultProtocolMessageMaxSize}, maintaining compatibility between all
217
+ * clients and relays.
218
+ */
219
+ export const ProtocolMessageRangesMaxSize = between(3_000, 100_000)(Int);
220
+ /**
221
+ * Default {@link ProtocolMessageRangesMaxSize} (30KB).
222
+ *
223
+ * The standard size used across Evolu implementations. Relays with more
224
+ * resources can configure larger sizes to reduce roundtrips.
225
+ */
226
+ export const defaultProtocolMessageRangesMaxSize = 30_000;
178
227
  /** Evolu Protocol version. */
179
228
  export const protocolVersion = 0;
180
229
  export const MessageType = {
@@ -201,18 +250,20 @@ export const ProtocolErrorCode = {
201
250
  WriteError: 2,
202
251
  /** A code for {@link ProtocolSyncError}. */
203
252
  SyncError: 3,
253
+ /** A code for {@link ProtocolQuotaExceededError}. */
254
+ QuotaExceededError: 4,
204
255
  };
205
256
  /**
206
257
  * Creates a {@link ProtocolMessage} from CRDT messages.
207
258
  *
208
- * If the message size would exceed {@link maxProtocolMessageSize}, the protocol
209
- * ensures all messages will be sent in the next round(s) even over
259
+ * If the message size would exceed {@link defaultProtocolMessageMaxSize}, the
260
+ * protocol ensures all messages will be sent in the next round(s) even over
210
261
  * unidirectional and stateless transports.
211
262
  */
212
263
  export const createProtocolMessageFromCrdtMessages = (deps) => (owner, messages, maxSize) => {
213
264
  const buffer = createProtocolMessageBuffer(owner.id, {
214
265
  messageType: MessageType.Request,
215
- totalMaxSize: maxSize ?? maxProtocolMessageSize,
266
+ totalMaxSize: maxSize ?? defaultProtocolMessageMaxSize,
216
267
  writeKey: owner.writeKey,
217
268
  });
218
269
  let notAllMessagesSent = false;
@@ -236,8 +287,8 @@ export const createProtocolMessageFromCrdtMessages = (deps) => (owner, messages,
236
287
  *
237
288
  * The ideal approach would be to send three ranges (skip, fingerprint,
238
289
  * skip) where the fingerprint of unsent messages would act as narrow sync
239
- * probe. I think we can send {@link zeroFingerprint} which can be
240
- * interpreted as an indication that the other side should reply with
290
+ * probe. I think we can send `zeroFingerprint` which can be interpreted
291
+ * as an indication that the other side should reply with
241
292
  * {@link TimestampsRange}, so no need to restart syncing.
242
293
  *
243
294
  * For now, using a random fingerprint avoids extra complexity and is good
@@ -272,7 +323,7 @@ export const createProtocolMessageForUnsubscribe = (ownerId) => createProtocolMe
272
323
  subscriptionFlag: SubscriptionFlags.Unsubscribe,
273
324
  }).unwrap();
274
325
  export const createProtocolMessageBuffer = (ownerId, options) => {
275
- const { totalMaxSize = maxProtocolMessageSize, rangesMaxSize = maxProtocolMessageRangesSize, version = protocolVersion, } = options;
326
+ const { totalMaxSize = defaultProtocolMessageMaxSize, rangesMaxSize = defaultProtocolMessageRangesMaxSize, version = protocolVersion, } = options;
276
327
  const buffers = {
277
328
  header: createBuffer(),
278
329
  messages: {
@@ -507,6 +558,11 @@ export const applyProtocolMessageAsClient = (deps) => async (inputMessage, optio
507
558
  type: "ProtocolSyncError",
508
559
  ownerId,
509
560
  });
561
+ case ProtocolErrorCode.QuotaExceededError:
562
+ return err({
563
+ type: "ProtocolQuotaExceededError",
564
+ ownerId,
565
+ });
510
566
  default:
511
567
  throw new ProtocolDecodeError(`Invalid ProtocolErrorCode: ${errorCode}`);
512
568
  }
@@ -537,7 +593,6 @@ export const applyProtocolMessageAsClient = (deps) => async (inputMessage, optio
537
593
  const output = createProtocolMessageBuffer(ownerId, {
538
594
  messageType: MessageType.Request,
539
595
  writeKey,
540
- totalMaxSize: options.totalMaxSize,
541
596
  rangesMaxSize: options.rangesMaxSize,
542
597
  });
543
598
  const syncResult = sync(deps)(ranges, output, ownerIdBytes);
@@ -1,14 +1,81 @@
1
- import { ConsoleConfig } from "../Console.js";
1
+ import { ConsoleConfig, ConsoleDep } from "../Console.js";
2
2
  import { TimingSafeEqualDep } from "../Crypto.js";
3
+ import { LazyValue } from "../Function.js";
3
4
  import { Result } from "../Result.js";
4
5
  import { SqliteError } from "../Sqlite.js";
5
6
  import { SimpleName } from "../Type.js";
7
+ import { OwnerId } from "./Owner.js";
8
+ import { ProtocolInvalidDataError } from "./Protocol.js";
6
9
  import { CreateSqliteStorageBaseOptions, SqliteStorageDeps, Storage } from "./Storage.js";
7
10
  export interface Relay extends Disposable {
8
11
  }
9
12
  export interface RelayConfig extends ConsoleConfig {
13
+ /**
14
+ * The relay name.
15
+ *
16
+ * Implementations can use this for identification purposes (e.g., database
17
+ * file name, logging).
18
+ */
10
19
  readonly name?: SimpleName;
20
+ /**
21
+ * Optional callback to authenticate an {@link OwnerId} with the relay.
22
+ *
23
+ * If this callback is not provided, all owners are allowed.
24
+ *
25
+ * If provided, the callback receives the OwnerId and should return a promise
26
+ * that resolves to `true` to allow access, or `false` to deny.
27
+ *
28
+ * The callback returns a boolean rather than an error type because error
29
+ * handling and logging are the responsibility of the callback implementation,
30
+ * not the relay. This prevents leaking authentication implementation details
31
+ * into the generic relay interface.
32
+ *
33
+ * OwnerId is used for authentication rather than short-lived tokens because
34
+ * this only controls relay access, not write permissions. Since all data is
35
+ * encrypted on the relay, OwnerId exposure is safe.
36
+ *
37
+ * Owners specify which relays to connect to via {@link TransportConfig}. In
38
+ * WebSocket-based implementations, this check occurs before accepting the
39
+ * connection, with the OwnerId typically extracted from the URL path (e.g.,
40
+ * `ws://localhost:4000/<ownerId>`).
41
+ *
42
+ * ### Example
43
+ *
44
+ * ```ts
45
+ * const relay = await createNodeJsRelay(deps)({
46
+ * authenticateOwner: async (ownerId) => {
47
+ * const isRegistered = await db.checkOwner(ownerId);
48
+ * if (!isRegistered) {
49
+ * logger.warn("Unauthorized access attempt", { ownerId });
50
+ * }
51
+ * return isRegistered;
52
+ * },
53
+ * });
54
+ * ```
55
+ */
56
+ readonly authenticateOwner?: (ownerId: OwnerId) => Promise<boolean>;
11
57
  }
12
- export type RelaySqliteStorageDeps = SqliteStorageDeps & TimingSafeEqualDep;
13
- export declare const createRelayStorage: (deps: RelaySqliteStorageDeps) => (options: CreateSqliteStorageBaseOptions) => Result<Storage, SqliteError>;
58
+ export declare const createRelaySqliteStorage: (deps: SqliteStorageDeps & TimingSafeEqualDep) => (options: CreateSqliteStorageBaseOptions) => Result<Storage, SqliteError>;
59
+ export interface RelayLogger {
60
+ readonly started: (enableLogging: boolean, port: number) => void;
61
+ readonly storageError: (error: unknown) => void;
62
+ readonly upgradeSocketError: (error: Error) => void;
63
+ readonly invalidOrMissingOwnerIdInUrl: (url: string | undefined) => void;
64
+ readonly unauthorizedOwner: (ownerId: OwnerId) => void;
65
+ readonly authenticateOwnerError: (error: unknown) => void;
66
+ readonly connectionEstablished: (totalConnectionCount: number) => void;
67
+ readonly connectionWebSocketError: (error: Error) => void;
68
+ readonly relayOptionSubscribe: (ownerId: OwnerId, getSubscriberCount: LazyValue<number>) => void;
69
+ readonly relayOptionUnsubscribe: (ownerId: OwnerId, getSubscriberCount: LazyValue<number>) => void;
70
+ readonly relayOptionBroadcast: (ownerId: OwnerId, broadcastCount: number, subscriberCount: number) => void;
71
+ readonly messageLength: (messageLength: number) => void;
72
+ readonly applyProtocolMessageAsRelayError: (error: ProtocolInvalidDataError) => void;
73
+ readonly responseLength: (responseLength: number) => void;
74
+ readonly applyProtocolMessageAsRelayUnknownError: (error: unknown) => void;
75
+ readonly connectionClosed: (totalConnectionCount: number) => void;
76
+ readonly shuttingDown: () => void;
77
+ readonly webSocketServerDisposed: () => void;
78
+ readonly httpServerDisposed: () => void;
79
+ }
80
+ export declare const createRelayLogger: (deps: ConsoleDep) => RelayLogger;
14
81
  //# sourceMappingURL=Relay.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"Relay.d.ts","sourceRoot":"","sources":["../../../src/Evolu/Relay.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAC9C,OAAO,EAAE,kBAAkB,EAAE,MAAM,cAAc,CAAC;AAClD,OAAO,EAAW,MAAM,EAAE,MAAM,cAAc,CAAC;AAC/C,OAAO,EAAO,WAAW,EAAE,MAAM,cAAc,CAAC;AAChD,OAAO,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAExC,OAAO,EAEL,8BAA8B,EAE9B,iBAAiB,EACjB,OAAO,EACR,MAAM,cAAc,CAAC;AAGtB,MAAM,WAAW,KAAM,SAAQ,UAAU;CAAG;AAE5C,MAAM,WAAW,WAAY,SAAQ,aAAa;IAChD,QAAQ,CAAC,IAAI,CAAC,EAAE,UAAU,CAAC;CAC5B;AAED,MAAM,MAAM,sBAAsB,GAAG,iBAAiB,GAAG,kBAAkB,CAAC;AAE5E,eAAO,MAAM,kBAAkB,GAC5B,MAAM,sBAAsB,MAC5B,SAAS,8BAA8B,KAAG,MAAM,CAAC,OAAO,EAAE,WAAW,CAiKrE,CAAC"}
1
+ {"version":3,"file":"Relay.d.ts","sourceRoot":"","sources":["../../../src/Evolu/Relay.ts"],"names":[],"mappings":"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"}