@korajs/sync 0.3.1 → 0.4.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.
@@ -0,0 +1,385 @@
1
+ import { KoraError, Operation, OperationType, HLCTimestamp, AtomicOp } from '@korajs/core';
2
+
3
+ /**
4
+ * Encryption types for the Kora.js sync layer.
5
+ *
6
+ * These types define the configuration and wire format for end-to-end
7
+ * encryption of operation data during sync. Only `data` and `previousData`
8
+ * fields are encrypted — metadata stays in cleartext for routing and ordering.
9
+ */
10
+ /**
11
+ * Supported encryption algorithms. Currently only AES-256-GCM is supported,
12
+ * but the type is extensible for future algorithms.
13
+ */
14
+ type SyncEncryptionAlgorithm = 'aes-256-gcm';
15
+ /**
16
+ * Configuration for sync-layer encryption.
17
+ *
18
+ * When enabled, the sync engine encrypts `data` and `previousData` fields
19
+ * of every operation before sending over the wire. The server never sees
20
+ * plaintext user data.
21
+ *
22
+ * @example
23
+ * ```typescript
24
+ * const app = createApp({
25
+ * schema,
26
+ * sync: {
27
+ * url: 'wss://my-server.com/kora',
28
+ * encryption: {
29
+ * enabled: true,
30
+ * key: 'my-secure-passphrase'
31
+ * }
32
+ * }
33
+ * })
34
+ * ```
35
+ */
36
+ interface SyncEncryptionConfig {
37
+ /** Whether encryption is enabled. When false, all other fields are ignored. */
38
+ enabled: boolean;
39
+ /**
40
+ * Passphrase or async key provider function.
41
+ *
42
+ * - If a string, used as a passphrase for PBKDF2 key derivation.
43
+ * - If a function, called to retrieve the passphrase (e.g., from a vault or user prompt).
44
+ */
45
+ key: string | (() => Promise<string>);
46
+ /**
47
+ * Encryption algorithm. Defaults to 'aes-256-gcm'.
48
+ * Currently only AES-256-GCM is supported.
49
+ */
50
+ algorithm?: SyncEncryptionAlgorithm;
51
+ }
52
+ /**
53
+ * Encrypted payload structure embedded in operation `data` and `previousData`
54
+ * fields when encryption is enabled.
55
+ *
56
+ * This structure replaces the original field values on the wire. The server
57
+ * stores and relays these opaque payloads without being able to read the
58
+ * plaintext contents.
59
+ */
60
+ interface EncryptedPayload {
61
+ /** Encryption key version. Supports key rotation: older operations may use older key versions. */
62
+ v: number;
63
+ /** Base64-encoded initialization vector (12 bytes for AES-GCM). Unique per operation field. */
64
+ iv: string;
65
+ /** Base64-encoded ciphertext (AES-256-GCM output including authentication tag). */
66
+ ct: string;
67
+ /** Encryption algorithm identifier. */
68
+ alg: SyncEncryptionAlgorithm;
69
+ }
70
+ /**
71
+ * A versioned encryption key with its associated salt for key derivation.
72
+ *
73
+ * Key versions enable rotation: when the passphrase changes, a new key version
74
+ * is created. Operations encrypted with older key versions include their version
75
+ * number in the {@link EncryptedPayload}, allowing the decryptor to select the
76
+ * correct key.
77
+ */
78
+ interface VersionedKey {
79
+ /** Key version number (monotonically increasing, starting at 1). */
80
+ version: number;
81
+ /** The derived CryptoKey for AES-256-GCM operations. */
82
+ key: CryptoKey;
83
+ /** The salt used during PBKDF2 key derivation. Required to re-derive the same key. */
84
+ salt: Uint8Array;
85
+ }
86
+
87
+ /**
88
+ * Internal sync engine states. Used for state machine transitions.
89
+ */
90
+ declare const SYNC_STATES: readonly ["disconnected", "connecting", "handshaking", "syncing", "streaming", "error"];
91
+ type SyncState = (typeof SYNC_STATES)[number];
92
+ /**
93
+ * Developer-facing sync status. Simplified view of the internal state.
94
+ */
95
+ declare const SYNC_STATUSES: readonly ["connected", "syncing", "synced", "offline", "error"];
96
+ type SyncStatus = (typeof SYNC_STATUSES)[number];
97
+ /**
98
+ * Sync status information exposed to developers.
99
+ */
100
+ interface SyncStatusInfo {
101
+ /** Current developer-facing status */
102
+ status: SyncStatus;
103
+ /** Number of operations waiting to be sent */
104
+ pendingOperations: number;
105
+ /** Timestamp of last successful sync (null if never synced) */
106
+ lastSyncedAt: number | null;
107
+ /** Timestamp of last successful push to the server (null if never pushed) */
108
+ lastSuccessfulPush: number | null;
109
+ /** Timestamp of last successful pull from the server (null if never pulled) */
110
+ lastSuccessfulPull: number | null;
111
+ /** Number of merge conflicts encountered during this session */
112
+ conflicts: number;
113
+ }
114
+ /**
115
+ * Per-collection sync scope map. Maps collection names to field-value filters.
116
+ * Empty filter `{}` means no restriction (all records visible).
117
+ * Missing collection means hidden (no records visible for that collection).
118
+ */
119
+ type SyncScopeMap = Record<string, Record<string, unknown>>;
120
+ /**
121
+ * Sync configuration provided by the developer.
122
+ */
123
+ interface SyncConfig {
124
+ /** WebSocket or HTTP URL for the sync server */
125
+ url: string;
126
+ /** Transport type to use. Defaults to 'websocket'. */
127
+ transport?: 'websocket' | 'http';
128
+ /** Auth provider function. Called before each connection attempt. */
129
+ auth?: () => Promise<{
130
+ token: string;
131
+ }>;
132
+ /** Sync scopes per collection. Limits which records sync to this client. */
133
+ scopes?: Record<string, (ctx: SyncScopeContext) => Record<string, unknown>>;
134
+ /**
135
+ * Pre-computed per-collection sync scope map. Sent to the server in the handshake.
136
+ * Built automatically by createApp from schema scope declarations + flat scope values.
137
+ */
138
+ scopeMap?: SyncScopeMap;
139
+ /** Number of operations per batch. Defaults to 100. */
140
+ batchSize?: number;
141
+ /** Initial reconnection delay in ms. Defaults to 1000. */
142
+ reconnectInterval?: number;
143
+ /** Maximum reconnection delay in ms. Defaults to 30000. */
144
+ maxReconnectInterval?: number;
145
+ /** Schema version of this client. */
146
+ schemaVersion?: number;
147
+ /**
148
+ * End-to-end encryption configuration.
149
+ * When enabled, `data` and `previousData` fields are encrypted before sending
150
+ * over the wire. The server never sees plaintext user data.
151
+ */
152
+ encryption?: SyncEncryptionConfig;
153
+ }
154
+ /**
155
+ * Context passed to sync scope functions.
156
+ */
157
+ interface SyncScopeContext {
158
+ userId?: string;
159
+ [key: string]: unknown;
160
+ }
161
+ /**
162
+ * Interface for persisting the outbound operation queue.
163
+ * Operations must survive page refreshes and be sent when connection is re-established.
164
+ */
165
+ interface QueueStorage {
166
+ /** Load all queued operations from persistent storage */
167
+ load(): Promise<Operation[]>;
168
+ /** Persist an operation to the queue */
169
+ enqueue(op: Operation): Promise<void>;
170
+ /** Remove acknowledged operations by their IDs */
171
+ dequeue(ids: string[]): Promise<void>;
172
+ /** Return number of operations in storage */
173
+ count(): Promise<number>;
174
+ }
175
+ /**
176
+ * Thrown when an operation violates sync scope constraints.
177
+ * This can happen when:
178
+ * - A client tries to push an operation outside its configured scope
179
+ * - The server rejects an operation because it falls outside the client's scope
180
+ */
181
+ declare class ScopeViolationError extends KoraError {
182
+ readonly operationId: string;
183
+ readonly collection: string;
184
+ readonly scope: Record<string, unknown>;
185
+ constructor(operationId: string, collection: string, scope: Record<string, unknown>, message?: string);
186
+ }
187
+ /**
188
+ * Thrown when a sync scope configuration is invalid.
189
+ */
190
+ declare class InvalidScopeError extends KoraError {
191
+ constructor(message: string, context?: Record<string, unknown>);
192
+ }
193
+
194
+ type WireFormat = 'json' | 'protobuf';
195
+ /**
196
+ * Wire-format operation. Plain object (no Map) for JSON serialization.
197
+ * Maps 1:1 with Operation, but uses Record instead of Map for version vectors.
198
+ */
199
+ interface SerializedOperation {
200
+ id: string;
201
+ nodeId: string;
202
+ type: OperationType;
203
+ collection: string;
204
+ recordId: string;
205
+ data: Record<string, unknown> | null;
206
+ previousData: Record<string, unknown> | null;
207
+ timestamp: HLCTimestamp;
208
+ sequenceNumber: number;
209
+ causalDeps: string[];
210
+ schemaVersion: number;
211
+ /** Atomic operation intents, present only when atomic ops were used. */
212
+ atomicOps?: Record<string, AtomicOp>;
213
+ /** Groups this operation with others in an atomic transaction. */
214
+ transactionId?: string;
215
+ /** Human-readable name for the mutation group. For DevTools display. */
216
+ mutationName?: string;
217
+ }
218
+ /**
219
+ * Handshake message sent by client to initiate sync.
220
+ */
221
+ interface HandshakeMessage {
222
+ type: 'handshake';
223
+ messageId: string;
224
+ nodeId: string;
225
+ /** Version vector as plain object (nodeId -> sequence number) */
226
+ versionVector: Record<string, number>;
227
+ schemaVersion: number;
228
+ authToken?: string;
229
+ supportedWireFormats?: WireFormat[];
230
+ /** Per-collection sync scope filters. Limits which records are synced to this client. */
231
+ syncScope?: Record<string, Record<string, unknown>>;
232
+ }
233
+ /**
234
+ * Server response to a handshake.
235
+ */
236
+ interface HandshakeResponseMessage {
237
+ type: 'handshake-response';
238
+ messageId: string;
239
+ nodeId: string;
240
+ versionVector: Record<string, number>;
241
+ schemaVersion: number;
242
+ accepted: boolean;
243
+ rejectReason?: string;
244
+ selectedWireFormat?: WireFormat;
245
+ /** The server-accepted per-collection sync scope. Confirms what data will be synced. */
246
+ acceptedScope?: Record<string, Record<string, unknown>>;
247
+ }
248
+ /**
249
+ * Batch of operations sent during delta exchange or streaming.
250
+ */
251
+ interface OperationBatchMessage {
252
+ type: 'operation-batch';
253
+ messageId: string;
254
+ operations: SerializedOperation[];
255
+ /** True if this is the last batch in the delta exchange phase */
256
+ isFinal: boolean;
257
+ /** Index of this batch (0-based) for ordering */
258
+ batchIndex: number;
259
+ }
260
+ /**
261
+ * Acknowledgment of a received message.
262
+ */
263
+ interface AcknowledgmentMessage {
264
+ type: 'acknowledgment';
265
+ messageId: string;
266
+ acknowledgedMessageId: string;
267
+ lastSequenceNumber: number;
268
+ }
269
+ /**
270
+ * Error message from the server or client.
271
+ */
272
+ interface ErrorMessage {
273
+ type: 'error';
274
+ messageId: string;
275
+ code: string;
276
+ message: string;
277
+ retriable: boolean;
278
+ }
279
+ /**
280
+ * Awareness state for a single client (cursor position, user info).
281
+ * Wire-format representation for JSON transport.
282
+ * Ephemeral -- not persisted, only shared with connected peers.
283
+ */
284
+ interface AwarenessStateWire {
285
+ user: {
286
+ name: string;
287
+ color: string;
288
+ avatar?: string;
289
+ };
290
+ cursor?: {
291
+ collection: string;
292
+ recordId: string;
293
+ field: string;
294
+ anchor: number;
295
+ head: number;
296
+ };
297
+ }
298
+ /**
299
+ * Awareness update message. Carries ephemeral presence data (cursors, user info).
300
+ * Processed separately from operation sync -- never persisted.
301
+ */
302
+ interface AwarenessUpdateMessage {
303
+ type: 'awareness-update';
304
+ messageId: string;
305
+ /** Client ID of the sender */
306
+ clientId: number;
307
+ /** Map of clientId -> state (null means removal) */
308
+ states: Record<string, AwarenessStateWire | null>;
309
+ }
310
+ /**
311
+ * Union of all sync protocol messages.
312
+ */
313
+ type SyncMessage = HandshakeMessage | HandshakeResponseMessage | OperationBatchMessage | AcknowledgmentMessage | ErrorMessage | AwarenessUpdateMessage;
314
+ /**
315
+ * Check if an unknown value is a valid SyncMessage.
316
+ */
317
+ declare function isSyncMessage(value: unknown): value is SyncMessage;
318
+ /**
319
+ * Check if a value is a HandshakeMessage.
320
+ */
321
+ declare function isHandshakeMessage(value: unknown): value is HandshakeMessage;
322
+ /**
323
+ * Check if a value is a HandshakeResponseMessage.
324
+ */
325
+ declare function isHandshakeResponseMessage(value: unknown): value is HandshakeResponseMessage;
326
+ /**
327
+ * Check if a value is an OperationBatchMessage.
328
+ */
329
+ declare function isOperationBatchMessage(value: unknown): value is OperationBatchMessage;
330
+ /**
331
+ * Check if a value is an AcknowledgmentMessage.
332
+ */
333
+ declare function isAcknowledgmentMessage(value: unknown): value is AcknowledgmentMessage;
334
+ /**
335
+ * Check if a value is an ErrorMessage.
336
+ */
337
+ declare function isErrorMessage(value: unknown): value is ErrorMessage;
338
+ /**
339
+ * Check if a value is an AwarenessUpdateMessage.
340
+ */
341
+ declare function isAwarenessUpdateMessage(value: unknown): value is AwarenessUpdateMessage;
342
+
343
+ /**
344
+ * Options for transport connection.
345
+ */
346
+ interface TransportOptions {
347
+ /** Authentication token sent during connection */
348
+ authToken?: string;
349
+ /** Additional headers (for HTTP-based transports) */
350
+ headers?: Record<string, string>;
351
+ }
352
+ /**
353
+ * Transport-level error handler.
354
+ */
355
+ type TransportErrorHandler = (error: Error) => void;
356
+ /**
357
+ * Transport-level close handler.
358
+ */
359
+ type TransportCloseHandler = (reason: string) => void;
360
+ /**
361
+ * Transport-level message handler.
362
+ */
363
+ type TransportMessageHandler = (message: SyncMessage) => void;
364
+ /**
365
+ * Abstract transport interface for sync communication.
366
+ * Implementations can use WebSocket, HTTP, Bluetooth, or any other transport.
367
+ */
368
+ interface SyncTransport {
369
+ /** Connect to the sync server at the given URL */
370
+ connect(url: string, options?: TransportOptions): Promise<void>;
371
+ /** Disconnect from the server */
372
+ disconnect(): Promise<void>;
373
+ /** Send a sync message */
374
+ send(message: SyncMessage): void;
375
+ /** Register a handler for incoming messages */
376
+ onMessage(handler: TransportMessageHandler): void;
377
+ /** Register a handler for connection close events */
378
+ onClose(handler: TransportCloseHandler): void;
379
+ /** Register a handler for transport errors */
380
+ onError(handler: TransportErrorHandler): void;
381
+ /** Returns true if the transport is currently connected */
382
+ isConnected(): boolean;
383
+ }
384
+
385
+ export { type AcknowledgmentMessage as A, isSyncMessage as B, type EncryptedPayload as E, type HandshakeMessage as H, InvalidScopeError as I, type OperationBatchMessage as O, type QueueStorage as Q, type SyncScopeMap as S, type TransportOptions as T, type VersionedKey as V, type WireFormat as W, type SyncMessage as a, type SerializedOperation as b, type SyncTransport as c, type TransportMessageHandler as d, type TransportCloseHandler as e, type TransportErrorHandler as f, type SyncEncryptionConfig as g, type SyncState as h, type SyncStatusInfo as i, type SyncConfig as j, type AwarenessStateWire as k, type AwarenessUpdateMessage as l, type ErrorMessage as m, type HandshakeResponseMessage as n, SYNC_STATES as o, SYNC_STATUSES as p, ScopeViolationError as q, type SyncEncryptionAlgorithm as r, type SyncScopeContext as s, type SyncStatus as t, isAcknowledgmentMessage as u, isAwarenessUpdateMessage as v, isErrorMessage as w, isHandshakeMessage as x, isHandshakeResponseMessage as y, isOperationBatchMessage as z };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@korajs/sync",
3
- "version": "0.3.1",
3
+ "version": "0.4.0",
4
4
  "description": "Sync protocol and transports for Kora.js with delta sync, causal ordering, and automatic reconnection",
5
5
  "type": "module",
6
6
  "main": "./dist/index.cjs",
@@ -33,8 +33,8 @@
33
33
  ],
34
34
  "dependencies": {
35
35
  "protobufjs": "^8.0.1",
36
- "@korajs/core": "0.3.1",
37
- "@korajs/merge": "0.3.1"
36
+ "@korajs/core": "0.4.0",
37
+ "@korajs/merge": "0.4.0"
38
38
  },
39
39
  "devDependencies": {
40
40
  "@fast-check/vitest": "0.2.0",
@@ -1,215 +0,0 @@
1
- import { Operation, OperationType, HLCTimestamp } from '@korajs/core';
2
-
3
- /**
4
- * Internal sync engine states. Used for state machine transitions.
5
- */
6
- declare const SYNC_STATES: readonly ["disconnected", "connecting", "handshaking", "syncing", "streaming", "error"];
7
- type SyncState = (typeof SYNC_STATES)[number];
8
- /**
9
- * Developer-facing sync status. Simplified view of the internal state.
10
- */
11
- declare const SYNC_STATUSES: readonly ["connected", "syncing", "synced", "offline", "error"];
12
- type SyncStatus = (typeof SYNC_STATUSES)[number];
13
- /**
14
- * Sync status information exposed to developers.
15
- */
16
- interface SyncStatusInfo {
17
- /** Current developer-facing status */
18
- status: SyncStatus;
19
- /** Number of operations waiting to be sent */
20
- pendingOperations: number;
21
- /** Timestamp of last successful sync (null if never synced) */
22
- lastSyncedAt: number | null;
23
- }
24
- /**
25
- * Sync configuration provided by the developer.
26
- */
27
- interface SyncConfig {
28
- /** WebSocket or HTTP URL for the sync server */
29
- url: string;
30
- /** Transport type to use. Defaults to 'websocket'. */
31
- transport?: 'websocket' | 'http';
32
- /** Auth provider function. Called before each connection attempt. */
33
- auth?: () => Promise<{
34
- token: string;
35
- }>;
36
- /** Sync scopes per collection. Limits which records sync to this client. */
37
- scopes?: Record<string, (ctx: SyncScopeContext) => Record<string, unknown>>;
38
- /** Number of operations per batch. Defaults to 100. */
39
- batchSize?: number;
40
- /** Initial reconnection delay in ms. Defaults to 1000. */
41
- reconnectInterval?: number;
42
- /** Maximum reconnection delay in ms. Defaults to 30000. */
43
- maxReconnectInterval?: number;
44
- /** Schema version of this client. */
45
- schemaVersion?: number;
46
- }
47
- /**
48
- * Context passed to sync scope functions.
49
- */
50
- interface SyncScopeContext {
51
- userId?: string;
52
- [key: string]: unknown;
53
- }
54
- /**
55
- * Interface for persisting the outbound operation queue.
56
- * Operations must survive page refreshes and be sent when connection is re-established.
57
- */
58
- interface QueueStorage {
59
- /** Load all queued operations from persistent storage */
60
- load(): Promise<Operation[]>;
61
- /** Persist an operation to the queue */
62
- enqueue(op: Operation): Promise<void>;
63
- /** Remove acknowledged operations by their IDs */
64
- dequeue(ids: string[]): Promise<void>;
65
- /** Return number of operations in storage */
66
- count(): Promise<number>;
67
- }
68
-
69
- type WireFormat = 'json' | 'protobuf';
70
- /**
71
- * Wire-format operation. Plain object (no Map) for JSON serialization.
72
- * Maps 1:1 with Operation, but uses Record instead of Map for version vectors.
73
- */
74
- interface SerializedOperation {
75
- id: string;
76
- nodeId: string;
77
- type: OperationType;
78
- collection: string;
79
- recordId: string;
80
- data: Record<string, unknown> | null;
81
- previousData: Record<string, unknown> | null;
82
- timestamp: HLCTimestamp;
83
- sequenceNumber: number;
84
- causalDeps: string[];
85
- schemaVersion: number;
86
- }
87
- /**
88
- * Handshake message sent by client to initiate sync.
89
- */
90
- interface HandshakeMessage {
91
- type: 'handshake';
92
- messageId: string;
93
- nodeId: string;
94
- /** Version vector as plain object (nodeId -> sequence number) */
95
- versionVector: Record<string, number>;
96
- schemaVersion: number;
97
- authToken?: string;
98
- supportedWireFormats?: WireFormat[];
99
- }
100
- /**
101
- * Server response to a handshake.
102
- */
103
- interface HandshakeResponseMessage {
104
- type: 'handshake-response';
105
- messageId: string;
106
- nodeId: string;
107
- versionVector: Record<string, number>;
108
- schemaVersion: number;
109
- accepted: boolean;
110
- rejectReason?: string;
111
- selectedWireFormat?: WireFormat;
112
- }
113
- /**
114
- * Batch of operations sent during delta exchange or streaming.
115
- */
116
- interface OperationBatchMessage {
117
- type: 'operation-batch';
118
- messageId: string;
119
- operations: SerializedOperation[];
120
- /** True if this is the last batch in the delta exchange phase */
121
- isFinal: boolean;
122
- /** Index of this batch (0-based) for ordering */
123
- batchIndex: number;
124
- }
125
- /**
126
- * Acknowledgment of a received message.
127
- */
128
- interface AcknowledgmentMessage {
129
- type: 'acknowledgment';
130
- messageId: string;
131
- acknowledgedMessageId: string;
132
- lastSequenceNumber: number;
133
- }
134
- /**
135
- * Error message from the server or client.
136
- */
137
- interface ErrorMessage {
138
- type: 'error';
139
- messageId: string;
140
- code: string;
141
- message: string;
142
- retriable: boolean;
143
- }
144
- /**
145
- * Union of all sync protocol messages.
146
- */
147
- type SyncMessage = HandshakeMessage | HandshakeResponseMessage | OperationBatchMessage | AcknowledgmentMessage | ErrorMessage;
148
- /**
149
- * Check if an unknown value is a valid SyncMessage.
150
- */
151
- declare function isSyncMessage(value: unknown): value is SyncMessage;
152
- /**
153
- * Check if a value is a HandshakeMessage.
154
- */
155
- declare function isHandshakeMessage(value: unknown): value is HandshakeMessage;
156
- /**
157
- * Check if a value is a HandshakeResponseMessage.
158
- */
159
- declare function isHandshakeResponseMessage(value: unknown): value is HandshakeResponseMessage;
160
- /**
161
- * Check if a value is an OperationBatchMessage.
162
- */
163
- declare function isOperationBatchMessage(value: unknown): value is OperationBatchMessage;
164
- /**
165
- * Check if a value is an AcknowledgmentMessage.
166
- */
167
- declare function isAcknowledgmentMessage(value: unknown): value is AcknowledgmentMessage;
168
- /**
169
- * Check if a value is an ErrorMessage.
170
- */
171
- declare function isErrorMessage(value: unknown): value is ErrorMessage;
172
-
173
- /**
174
- * Options for transport connection.
175
- */
176
- interface TransportOptions {
177
- /** Authentication token sent during connection */
178
- authToken?: string;
179
- /** Additional headers (for HTTP-based transports) */
180
- headers?: Record<string, string>;
181
- }
182
- /**
183
- * Transport-level error handler.
184
- */
185
- type TransportErrorHandler = (error: Error) => void;
186
- /**
187
- * Transport-level close handler.
188
- */
189
- type TransportCloseHandler = (reason: string) => void;
190
- /**
191
- * Transport-level message handler.
192
- */
193
- type TransportMessageHandler = (message: SyncMessage) => void;
194
- /**
195
- * Abstract transport interface for sync communication.
196
- * Implementations can use WebSocket, HTTP, Bluetooth, or any other transport.
197
- */
198
- interface SyncTransport {
199
- /** Connect to the sync server at the given URL */
200
- connect(url: string, options?: TransportOptions): Promise<void>;
201
- /** Disconnect from the server */
202
- disconnect(): Promise<void>;
203
- /** Send a sync message */
204
- send(message: SyncMessage): void;
205
- /** Register a handler for incoming messages */
206
- onMessage(handler: TransportMessageHandler): void;
207
- /** Register a handler for connection close events */
208
- onClose(handler: TransportCloseHandler): void;
209
- /** Register a handler for transport errors */
210
- onError(handler: TransportErrorHandler): void;
211
- /** Returns true if the transport is currently connected */
212
- isConnected(): boolean;
213
- }
214
-
215
- export { type AcknowledgmentMessage as A, type ErrorMessage as E, type HandshakeMessage as H, type OperationBatchMessage as O, type QueueStorage as Q, type SyncMessage as S, type TransportOptions as T, type WireFormat as W, type SerializedOperation as a, type SyncTransport as b, type TransportMessageHandler as c, type TransportCloseHandler as d, type TransportErrorHandler as e, type SyncConfig as f, type SyncStatusInfo as g, type SyncState as h, type HandshakeResponseMessage as i, SYNC_STATES as j, SYNC_STATUSES as k, type SyncScopeContext as l, type SyncStatus as m, isAcknowledgmentMessage as n, isErrorMessage as o, isHandshakeMessage as p, isHandshakeResponseMessage as q, isOperationBatchMessage as r, isSyncMessage as s };