@korajs/test 1.0.0-beta.12 → 1.0.0-beta.14

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.
package/dist/index.d.cts CHANGED
@@ -1,84 +1,27 @@
1
- import * as _korajs_server from '@korajs/server';
2
- import { ServerTransport, MemoryServerStore, OperationValidator } from '@korajs/server';
3
- import { SchemaDefinition, OperationTransform, Operation, BlobRef, KoraEventEmitter, VersionVector } from '@korajs/core';
4
1
  import * as _korajs_sync from '@korajs/sync';
5
- import { SyncTransport, SyncEngine, ChaosConfig } from '@korajs/sync';
2
+ import { SyncTransport, SyncEncryptionConfig, SyncEngine, ChaosConfig } from '@korajs/sync';
6
3
  export { ChaosConfig, ChaosTransport } from '@korajs/sync';
7
- import { ContentAddressedBlobStore, Store, MemoryBlobStore, CollectionAccessor, BlobManifest, ReceiveBlobResult } from '@korajs/store';
4
+ import * as _korajs_server from '@korajs/server';
5
+ import { ServerTransport, ServerStore, MemoryServerStore, KoraSyncServerConfig, OperationValidator, KoraSyncServer } from '@korajs/server';
6
+ import { KoraEventEmitter, SchemaDefinition, OperationTransform, BlobRef, VersionVector, Operation } from '@korajs/core';
7
+ import { Store, MemoryBlobStore, CollectionAccessor, BlobManifest, ReceiveBlobResult, ContentAddressedBlobStore } from '@korajs/store';
8
8
  import { AuthSyncBinding, AuthSyncState } from '@korajs/core/bindings';
9
9
 
10
- /**
11
- * A linked client/server transport pair, as consumed by {@link TestDevice}.
12
- */
13
- interface TransportPair {
14
- client: SyncTransport;
15
- serverTransport: ServerTransport;
10
+ /** What a device needs from its server: a way to open a session on it. */
11
+ interface TestDeviceServer {
12
+ handleConnection(transport: _korajs_server.ServerTransport): string;
16
13
  }
17
14
  /**
18
- * Wraps a transport pair so that every sync message exchanged between the two
19
- * ends is encoded to protobuf bytes and decoded back — a faithful stand-in for
20
- * a real network hop that uses the protobuf wire format.
21
- *
22
- * Both directions are wrapped, so operations, handshakes, batches, and acks all
23
- * travel as bytes rather than shared object references.
24
- *
25
- * @param pair - The underlying (in-memory) transport pair to wrap
26
- * @returns A transport pair that routes messages through the protobuf codec
15
+ * End-to-end encryption of a test device's sync traffic. Devices that must read each
16
+ * other's operations share the passphrase AND the key-derivation salt (shared key
17
+ * distribution, ENC-1, is not built yet).
27
18
  */
28
- declare function wrapTransportPairWithProtobufWire(pair: TransportPair): TransportPair;
29
-
30
- /**
31
- * In-memory test server wrapping KoraSyncServer with MemoryServerStore.
32
- * Handles client connections via memory transports.
33
- */
34
- interface TestServerOptions {
35
- /** Handshake schema version advertised by the server. Defaults to `schema.version`. */
36
- schemaVersion?: number;
37
- /** Inclusive client schema versions accepted at handshake. */
38
- supportedSchemaVersions?: {
39
- min: number;
40
- max: number;
41
- };
42
- /** Transform accepted legacy operations into the server schema before validation. */
43
- operationTransforms?: OperationTransform[];
44
- /** Enable central blob storage: the server persists and serves uploaded blob bytes. */
45
- blobStorage?: boolean;
46
- /** Adjudicate untrusted client operations before materialization. */
47
- validateOperation?: OperationValidator;
19
+ interface TestDeviceEncryption {
20
+ config: SyncEncryptionConfig;
21
+ salt: Uint8Array;
22
+ /** PBKDF2 iterations (lower in tests for speed). */
23
+ iterations?: number;
48
24
  }
49
- declare class TestServer {
50
- readonly store: MemoryServerStore;
51
- /** The server's central blob store, present when `blobStorage` was enabled. */
52
- readonly blobStore: ContentAddressedBlobStore | null;
53
- private readonly syncServer;
54
- constructor(schema: SchemaDefinition, options?: TestServerOptions);
55
- /**
56
- * Register a client connection transport with the server.
57
- * Returns the session ID assigned by the server.
58
- */
59
- handleConnection(transport: ServerTransport): string;
60
- /**
61
- * Get all operations stored on the server.
62
- */
63
- getAllOperations(): Operation[];
64
- /**
65
- * Get the number of connected clients.
66
- */
67
- getConnectionCount(): number;
68
- /**
69
- * Retransmit relay batches connected clients have not acknowledged. Lets a test
70
- * deterministically trigger the redelivery that the server also runs on a timer,
71
- * without depending on wall-clock time. `staleMs` of 0 resends every pending relay.
72
- */
73
- retransmitPendingRelays(staleMs?: number): void;
74
- /** Every blob reference still reachable from live records on the server. */
75
- getLiveBlobRefs(): Promise<BlobRef[]>;
76
- /**
77
- * Shut down the server and close all sessions.
78
- */
79
- close(): Promise<void>;
80
- }
81
-
82
25
  /**
83
26
  * Options for creating a TestDevice.
84
27
  */
@@ -88,7 +31,7 @@ interface TestDeviceOptions {
88
31
  /** Schema definition */
89
32
  schema: SchemaDefinition;
90
33
  /** Test server to connect to */
91
- server: TestServer;
34
+ server: TestDeviceServer;
92
35
  /** Transport factory — creates a linked client/server transport pair */
93
36
  createTransportPair: () => {
94
37
  client: SyncTransport;
@@ -98,8 +41,35 @@ interface TestDeviceOptions {
98
41
  tmpDir: string;
99
42
  /** Client handshake schema version. Defaults to `schema.version`. */
100
43
  syncSchemaVersion?: number;
101
- /** Transforms applied to inbound operations before local apply. */
44
+ /** Schema transforms: the store folds every operation's view (transforms at fold time). */
102
45
  operationTransforms?: OperationTransform[];
46
+ /** The store's local `maxOperationBytes` (RT-86). Default: the store default (256 KiB). */
47
+ maxOperationBytes?: number;
48
+ /** A pinned store node id (`StoreConfig.nodeId`), as `createKoraAuthSync` sets the device id. */
49
+ nodeId?: string;
50
+ /** What the device does with records that leave its scope. Defaults to the engine default ('retain'). */
51
+ scopeExit?: 'retain' | 'retract';
52
+ /**
53
+ * The signed-in user, as an auth-aware app knows it (RT-42). When set, the store binds
54
+ * its node to that user at open and on {@link TestDevice.authChanged}, and the sync
55
+ * engine never uploads another user's node on this user's session.
56
+ */
57
+ principal?: () => string | null;
58
+ /**
59
+ * Let the sync engine reconnect on its own, as over a real WebSocket: a `connect()`
60
+ * after the session closed opens a new transport pair to the server. Off by default
61
+ * (a closed pair stays closed until the next {@link TestDevice.sync}).
62
+ */
63
+ reconnectable?: boolean;
64
+ /**
65
+ * Run the device on the beta.12 pairwise pipeline (`experimental.legacyMerge`)
66
+ * instead of the W7 fold. Used by the comparison harness.
67
+ */
68
+ legacyMerge?: boolean;
69
+ /** Encrypt sync traffic end to end (protocol v2 envelope). */
70
+ encryption?: TestDeviceEncryption;
71
+ /** Upload batch size of the sync engine (default: the engine's). */
72
+ batchSize?: number;
103
73
  }
104
74
  /**
105
75
  * A virtual device in a test network.
@@ -116,12 +86,18 @@ declare class TestDevice {
116
86
  readonly blobStore: MemoryBlobStore;
117
87
  private readonly schema;
118
88
  private readonly server;
89
+ private readonly encryption;
90
+ private readonly batchSize;
91
+ private encryptor;
119
92
  private readonly mergeEngine;
120
93
  private readonly createTransportPair;
121
94
  private readonly adapter;
122
95
  private readonly dbPath;
123
96
  private readonly syncSchemaVersion;
124
97
  private readonly operationTransforms;
98
+ private readonly scopeExit;
99
+ private readonly principal;
100
+ private readonly reconnectable;
125
101
  private applyPipeline;
126
102
  private syncEngine;
127
103
  private blobChunkProvider;
@@ -134,6 +110,11 @@ declare class TestDevice {
134
110
  * Open the store (must be called before sync or collection operations).
135
111
  */
136
112
  open(): Promise<void>;
113
+ /**
114
+ * The signed-in user changed (RT-42), as an auth binding reports it: like createApp,
115
+ * end the live session and bind the store to the new user before the next write.
116
+ */
117
+ authChanged(): Promise<void>;
137
118
  /**
138
119
  * Connect to the test server and perform initial sync.
139
120
  * If already connected, flushes any pending operations.
@@ -225,6 +206,92 @@ declare class TestDevice {
225
206
  private waitForPendingOps;
226
207
  }
227
208
 
209
+ /**
210
+ * A linked client/server transport pair, as consumed by {@link TestDevice}.
211
+ */
212
+ interface TransportPair {
213
+ client: SyncTransport;
214
+ serverTransport: ServerTransport;
215
+ }
216
+ /**
217
+ * Wraps a transport pair so that every sync message exchanged between the two
218
+ * ends is encoded to protobuf bytes and decoded back — a faithful stand-in for
219
+ * a real network hop that uses the protobuf wire format.
220
+ *
221
+ * Both directions are wrapped, so operations, handshakes, batches, and acks all
222
+ * travel as bytes rather than shared object references.
223
+ *
224
+ * @param pair - The underlying (in-memory) transport pair to wrap
225
+ * @returns A transport pair that routes messages through the protobuf codec
226
+ */
227
+ declare function wrapTransportPairWithProtobufWire(pair: TransportPair): TransportPair;
228
+
229
+ /**
230
+ * In-memory test server wrapping KoraSyncServer with MemoryServerStore.
231
+ * Handles client connections via memory transports.
232
+ */
233
+ interface TestServerOptions<S extends ServerStore = MemoryServerStore> {
234
+ /**
235
+ * The server store (SQLite, Postgres, a memory store with options). Defaults to a
236
+ * fresh {@link MemoryServerStore}. Await {@link TestServer.ready} before use: the
237
+ * schema is set asynchronously.
238
+ */
239
+ store?: S;
240
+ /** End-to-end encryption policy of the sync server (protocol v2). */
241
+ encryption?: KoraSyncServerConfig['encryption'];
242
+ /** Handshake schema version advertised by the server. Defaults to `schema.version`. */
243
+ schemaVersion?: number;
244
+ /** Inclusive client schema versions accepted at handshake. */
245
+ supportedSchemaVersions?: {
246
+ min: number;
247
+ max: number;
248
+ };
249
+ /** Transform accepted legacy operations into the server schema before validation. */
250
+ operationTransforms?: OperationTransform[];
251
+ /** Enable central blob storage: the server persists and serves uploaded blob bytes. */
252
+ blobStorage?: boolean;
253
+ /** Adjudicate untrusted client operations before materialization. */
254
+ validateOperation?: OperationValidator;
255
+ }
256
+ declare class TestServer<S extends ServerStore = MemoryServerStore> {
257
+ readonly store: S;
258
+ /** Resolves once the store has the schema (needed before a SQL store is used). */
259
+ readonly ready: Promise<void>;
260
+ /** The server's central blob store, present when `blobStorage` was enabled. */
261
+ readonly blobStore: ContentAddressedBlobStore | null;
262
+ private readonly syncServer;
263
+ constructor(schema: SchemaDefinition, options?: TestServerOptions<S>);
264
+ /**
265
+ * Register a client connection transport with the server.
266
+ * Returns the session ID assigned by the server.
267
+ */
268
+ handleConnection(transport: ServerTransport): string;
269
+ /**
270
+ * Get all operations stored on the server.
271
+ */
272
+ getAllOperations(): Operation[];
273
+ /** The trusted server-side write API (route context): writes authored by the server node. */
274
+ getKoraContext(): ReturnType<KoraSyncServer['getKoraContext']>;
275
+ /** The node ids the server's stores fold with and advertise in the handshake. */
276
+ get authoritativeNodeIds(): string[];
277
+ /**
278
+ * Get the number of connected clients.
279
+ */
280
+ getConnectionCount(): number;
281
+ /**
282
+ * Retransmit relay batches connected clients have not acknowledged. Lets a test
283
+ * deterministically trigger the redelivery that the server also runs on a timer,
284
+ * without depending on wall-clock time. `staleMs` of 0 resends every pending relay.
285
+ */
286
+ retransmitPendingRelays(staleMs?: number): void;
287
+ /** Every blob reference still reachable from live records on the server. */
288
+ getLiveBlobRefs(): Promise<BlobRef[]>;
289
+ /**
290
+ * Shut down the server and close all sessions.
291
+ */
292
+ close(): Promise<void>;
293
+ }
294
+
228
295
  /**
229
296
  * Options for creating a test network.
230
297
  */
@@ -247,13 +314,26 @@ interface TestNetworkOptions {
247
314
  blobStorage?: boolean;
248
315
  /** Adjudicate untrusted client operations on the server before materialization. */
249
316
  validateOperation?: _korajs_server.OperationValidator;
317
+ /** Devices use the beta.12 pairwise pipeline (`experimental.legacyMerge`). */
318
+ legacyMerge?: boolean;
319
+ /**
320
+ * The server's store (SQLite, Postgres). Defaults to a fresh memory store. The
321
+ * network closes it.
322
+ */
323
+ serverStore?: _korajs_server.ServerStore;
324
+ /** Every device encrypts its sync traffic with this shared key material. */
325
+ encryption?: TestDeviceEncryption;
326
+ /** The sync server's encryption policy. */
327
+ serverEncryption?: _korajs_server.KoraSyncServerConfig['encryption'];
328
+ /** Every device store's local `maxOperationBytes` (RT-86). */
329
+ deviceMaxOperationBytes?: number;
250
330
  }
251
331
  /**
252
332
  * A test network with a server and multiple devices.
253
333
  */
254
334
  interface TestNetwork {
255
335
  /** The test server */
256
- server: TestServer;
336
+ server: TestServer<_korajs_server.ServerStore>;
257
337
  /** All devices in the network */
258
338
  devices: TestDevice[];
259
339
  /** Temporary directory for DB files */
@@ -410,4 +490,4 @@ declare function createTransportMetrics(): {
410
490
  wrapTransport(pair: TransportPair): TransportPair;
411
491
  };
412
492
 
413
- export { type CollectionDifference, type ConvergenceResult, type FieldDifference, type MixedTestDeviceConfig, type TestAuthBinding, TestDevice, type TestDeviceOptions, type TestNetwork, type TestNetworkOptions, TestServer, type TestServerOptions, type TestTransferMetrics, type TransportPair, checkConvergence, createMixedTestNetwork, createTestAuthBinding, createTestNetwork, createTransportMetrics, expectConverged, expectConvergedEventually, wrapTransportPairWithProtobufWire, wrapTransportPairWithServerClock };
493
+ export { type CollectionDifference, type ConvergenceResult, type FieldDifference, type MixedTestDeviceConfig, type TestAuthBinding, TestDevice, type TestDeviceEncryption, type TestDeviceOptions, type TestDeviceServer, type TestNetwork, type TestNetworkOptions, TestServer, type TestServerOptions, type TestTransferMetrics, type TransportPair, checkConvergence, createMixedTestNetwork, createTestAuthBinding, createTestNetwork, createTransportMetrics, expectConverged, expectConvergedEventually, wrapTransportPairWithProtobufWire, wrapTransportPairWithServerClock };
package/dist/index.d.ts CHANGED
@@ -1,84 +1,27 @@
1
- import * as _korajs_server from '@korajs/server';
2
- import { ServerTransport, MemoryServerStore, OperationValidator } from '@korajs/server';
3
- import { SchemaDefinition, OperationTransform, Operation, BlobRef, KoraEventEmitter, VersionVector } from '@korajs/core';
4
1
  import * as _korajs_sync from '@korajs/sync';
5
- import { SyncTransport, SyncEngine, ChaosConfig } from '@korajs/sync';
2
+ import { SyncTransport, SyncEncryptionConfig, SyncEngine, ChaosConfig } from '@korajs/sync';
6
3
  export { ChaosConfig, ChaosTransport } from '@korajs/sync';
7
- import { ContentAddressedBlobStore, Store, MemoryBlobStore, CollectionAccessor, BlobManifest, ReceiveBlobResult } from '@korajs/store';
4
+ import * as _korajs_server from '@korajs/server';
5
+ import { ServerTransport, ServerStore, MemoryServerStore, KoraSyncServerConfig, OperationValidator, KoraSyncServer } from '@korajs/server';
6
+ import { KoraEventEmitter, SchemaDefinition, OperationTransform, BlobRef, VersionVector, Operation } from '@korajs/core';
7
+ import { Store, MemoryBlobStore, CollectionAccessor, BlobManifest, ReceiveBlobResult, ContentAddressedBlobStore } from '@korajs/store';
8
8
  import { AuthSyncBinding, AuthSyncState } from '@korajs/core/bindings';
9
9
 
10
- /**
11
- * A linked client/server transport pair, as consumed by {@link TestDevice}.
12
- */
13
- interface TransportPair {
14
- client: SyncTransport;
15
- serverTransport: ServerTransport;
10
+ /** What a device needs from its server: a way to open a session on it. */
11
+ interface TestDeviceServer {
12
+ handleConnection(transport: _korajs_server.ServerTransport): string;
16
13
  }
17
14
  /**
18
- * Wraps a transport pair so that every sync message exchanged between the two
19
- * ends is encoded to protobuf bytes and decoded back — a faithful stand-in for
20
- * a real network hop that uses the protobuf wire format.
21
- *
22
- * Both directions are wrapped, so operations, handshakes, batches, and acks all
23
- * travel as bytes rather than shared object references.
24
- *
25
- * @param pair - The underlying (in-memory) transport pair to wrap
26
- * @returns A transport pair that routes messages through the protobuf codec
15
+ * End-to-end encryption of a test device's sync traffic. Devices that must read each
16
+ * other's operations share the passphrase AND the key-derivation salt (shared key
17
+ * distribution, ENC-1, is not built yet).
27
18
  */
28
- declare function wrapTransportPairWithProtobufWire(pair: TransportPair): TransportPair;
29
-
30
- /**
31
- * In-memory test server wrapping KoraSyncServer with MemoryServerStore.
32
- * Handles client connections via memory transports.
33
- */
34
- interface TestServerOptions {
35
- /** Handshake schema version advertised by the server. Defaults to `schema.version`. */
36
- schemaVersion?: number;
37
- /** Inclusive client schema versions accepted at handshake. */
38
- supportedSchemaVersions?: {
39
- min: number;
40
- max: number;
41
- };
42
- /** Transform accepted legacy operations into the server schema before validation. */
43
- operationTransforms?: OperationTransform[];
44
- /** Enable central blob storage: the server persists and serves uploaded blob bytes. */
45
- blobStorage?: boolean;
46
- /** Adjudicate untrusted client operations before materialization. */
47
- validateOperation?: OperationValidator;
19
+ interface TestDeviceEncryption {
20
+ config: SyncEncryptionConfig;
21
+ salt: Uint8Array;
22
+ /** PBKDF2 iterations (lower in tests for speed). */
23
+ iterations?: number;
48
24
  }
49
- declare class TestServer {
50
- readonly store: MemoryServerStore;
51
- /** The server's central blob store, present when `blobStorage` was enabled. */
52
- readonly blobStore: ContentAddressedBlobStore | null;
53
- private readonly syncServer;
54
- constructor(schema: SchemaDefinition, options?: TestServerOptions);
55
- /**
56
- * Register a client connection transport with the server.
57
- * Returns the session ID assigned by the server.
58
- */
59
- handleConnection(transport: ServerTransport): string;
60
- /**
61
- * Get all operations stored on the server.
62
- */
63
- getAllOperations(): Operation[];
64
- /**
65
- * Get the number of connected clients.
66
- */
67
- getConnectionCount(): number;
68
- /**
69
- * Retransmit relay batches connected clients have not acknowledged. Lets a test
70
- * deterministically trigger the redelivery that the server also runs on a timer,
71
- * without depending on wall-clock time. `staleMs` of 0 resends every pending relay.
72
- */
73
- retransmitPendingRelays(staleMs?: number): void;
74
- /** Every blob reference still reachable from live records on the server. */
75
- getLiveBlobRefs(): Promise<BlobRef[]>;
76
- /**
77
- * Shut down the server and close all sessions.
78
- */
79
- close(): Promise<void>;
80
- }
81
-
82
25
  /**
83
26
  * Options for creating a TestDevice.
84
27
  */
@@ -88,7 +31,7 @@ interface TestDeviceOptions {
88
31
  /** Schema definition */
89
32
  schema: SchemaDefinition;
90
33
  /** Test server to connect to */
91
- server: TestServer;
34
+ server: TestDeviceServer;
92
35
  /** Transport factory — creates a linked client/server transport pair */
93
36
  createTransportPair: () => {
94
37
  client: SyncTransport;
@@ -98,8 +41,35 @@ interface TestDeviceOptions {
98
41
  tmpDir: string;
99
42
  /** Client handshake schema version. Defaults to `schema.version`. */
100
43
  syncSchemaVersion?: number;
101
- /** Transforms applied to inbound operations before local apply. */
44
+ /** Schema transforms: the store folds every operation's view (transforms at fold time). */
102
45
  operationTransforms?: OperationTransform[];
46
+ /** The store's local `maxOperationBytes` (RT-86). Default: the store default (256 KiB). */
47
+ maxOperationBytes?: number;
48
+ /** A pinned store node id (`StoreConfig.nodeId`), as `createKoraAuthSync` sets the device id. */
49
+ nodeId?: string;
50
+ /** What the device does with records that leave its scope. Defaults to the engine default ('retain'). */
51
+ scopeExit?: 'retain' | 'retract';
52
+ /**
53
+ * The signed-in user, as an auth-aware app knows it (RT-42). When set, the store binds
54
+ * its node to that user at open and on {@link TestDevice.authChanged}, and the sync
55
+ * engine never uploads another user's node on this user's session.
56
+ */
57
+ principal?: () => string | null;
58
+ /**
59
+ * Let the sync engine reconnect on its own, as over a real WebSocket: a `connect()`
60
+ * after the session closed opens a new transport pair to the server. Off by default
61
+ * (a closed pair stays closed until the next {@link TestDevice.sync}).
62
+ */
63
+ reconnectable?: boolean;
64
+ /**
65
+ * Run the device on the beta.12 pairwise pipeline (`experimental.legacyMerge`)
66
+ * instead of the W7 fold. Used by the comparison harness.
67
+ */
68
+ legacyMerge?: boolean;
69
+ /** Encrypt sync traffic end to end (protocol v2 envelope). */
70
+ encryption?: TestDeviceEncryption;
71
+ /** Upload batch size of the sync engine (default: the engine's). */
72
+ batchSize?: number;
103
73
  }
104
74
  /**
105
75
  * A virtual device in a test network.
@@ -116,12 +86,18 @@ declare class TestDevice {
116
86
  readonly blobStore: MemoryBlobStore;
117
87
  private readonly schema;
118
88
  private readonly server;
89
+ private readonly encryption;
90
+ private readonly batchSize;
91
+ private encryptor;
119
92
  private readonly mergeEngine;
120
93
  private readonly createTransportPair;
121
94
  private readonly adapter;
122
95
  private readonly dbPath;
123
96
  private readonly syncSchemaVersion;
124
97
  private readonly operationTransforms;
98
+ private readonly scopeExit;
99
+ private readonly principal;
100
+ private readonly reconnectable;
125
101
  private applyPipeline;
126
102
  private syncEngine;
127
103
  private blobChunkProvider;
@@ -134,6 +110,11 @@ declare class TestDevice {
134
110
  * Open the store (must be called before sync or collection operations).
135
111
  */
136
112
  open(): Promise<void>;
113
+ /**
114
+ * The signed-in user changed (RT-42), as an auth binding reports it: like createApp,
115
+ * end the live session and bind the store to the new user before the next write.
116
+ */
117
+ authChanged(): Promise<void>;
137
118
  /**
138
119
  * Connect to the test server and perform initial sync.
139
120
  * If already connected, flushes any pending operations.
@@ -225,6 +206,92 @@ declare class TestDevice {
225
206
  private waitForPendingOps;
226
207
  }
227
208
 
209
+ /**
210
+ * A linked client/server transport pair, as consumed by {@link TestDevice}.
211
+ */
212
+ interface TransportPair {
213
+ client: SyncTransport;
214
+ serverTransport: ServerTransport;
215
+ }
216
+ /**
217
+ * Wraps a transport pair so that every sync message exchanged between the two
218
+ * ends is encoded to protobuf bytes and decoded back — a faithful stand-in for
219
+ * a real network hop that uses the protobuf wire format.
220
+ *
221
+ * Both directions are wrapped, so operations, handshakes, batches, and acks all
222
+ * travel as bytes rather than shared object references.
223
+ *
224
+ * @param pair - The underlying (in-memory) transport pair to wrap
225
+ * @returns A transport pair that routes messages through the protobuf codec
226
+ */
227
+ declare function wrapTransportPairWithProtobufWire(pair: TransportPair): TransportPair;
228
+
229
+ /**
230
+ * In-memory test server wrapping KoraSyncServer with MemoryServerStore.
231
+ * Handles client connections via memory transports.
232
+ */
233
+ interface TestServerOptions<S extends ServerStore = MemoryServerStore> {
234
+ /**
235
+ * The server store (SQLite, Postgres, a memory store with options). Defaults to a
236
+ * fresh {@link MemoryServerStore}. Await {@link TestServer.ready} before use: the
237
+ * schema is set asynchronously.
238
+ */
239
+ store?: S;
240
+ /** End-to-end encryption policy of the sync server (protocol v2). */
241
+ encryption?: KoraSyncServerConfig['encryption'];
242
+ /** Handshake schema version advertised by the server. Defaults to `schema.version`. */
243
+ schemaVersion?: number;
244
+ /** Inclusive client schema versions accepted at handshake. */
245
+ supportedSchemaVersions?: {
246
+ min: number;
247
+ max: number;
248
+ };
249
+ /** Transform accepted legacy operations into the server schema before validation. */
250
+ operationTransforms?: OperationTransform[];
251
+ /** Enable central blob storage: the server persists and serves uploaded blob bytes. */
252
+ blobStorage?: boolean;
253
+ /** Adjudicate untrusted client operations before materialization. */
254
+ validateOperation?: OperationValidator;
255
+ }
256
+ declare class TestServer<S extends ServerStore = MemoryServerStore> {
257
+ readonly store: S;
258
+ /** Resolves once the store has the schema (needed before a SQL store is used). */
259
+ readonly ready: Promise<void>;
260
+ /** The server's central blob store, present when `blobStorage` was enabled. */
261
+ readonly blobStore: ContentAddressedBlobStore | null;
262
+ private readonly syncServer;
263
+ constructor(schema: SchemaDefinition, options?: TestServerOptions<S>);
264
+ /**
265
+ * Register a client connection transport with the server.
266
+ * Returns the session ID assigned by the server.
267
+ */
268
+ handleConnection(transport: ServerTransport): string;
269
+ /**
270
+ * Get all operations stored on the server.
271
+ */
272
+ getAllOperations(): Operation[];
273
+ /** The trusted server-side write API (route context): writes authored by the server node. */
274
+ getKoraContext(): ReturnType<KoraSyncServer['getKoraContext']>;
275
+ /** The node ids the server's stores fold with and advertise in the handshake. */
276
+ get authoritativeNodeIds(): string[];
277
+ /**
278
+ * Get the number of connected clients.
279
+ */
280
+ getConnectionCount(): number;
281
+ /**
282
+ * Retransmit relay batches connected clients have not acknowledged. Lets a test
283
+ * deterministically trigger the redelivery that the server also runs on a timer,
284
+ * without depending on wall-clock time. `staleMs` of 0 resends every pending relay.
285
+ */
286
+ retransmitPendingRelays(staleMs?: number): void;
287
+ /** Every blob reference still reachable from live records on the server. */
288
+ getLiveBlobRefs(): Promise<BlobRef[]>;
289
+ /**
290
+ * Shut down the server and close all sessions.
291
+ */
292
+ close(): Promise<void>;
293
+ }
294
+
228
295
  /**
229
296
  * Options for creating a test network.
230
297
  */
@@ -247,13 +314,26 @@ interface TestNetworkOptions {
247
314
  blobStorage?: boolean;
248
315
  /** Adjudicate untrusted client operations on the server before materialization. */
249
316
  validateOperation?: _korajs_server.OperationValidator;
317
+ /** Devices use the beta.12 pairwise pipeline (`experimental.legacyMerge`). */
318
+ legacyMerge?: boolean;
319
+ /**
320
+ * The server's store (SQLite, Postgres). Defaults to a fresh memory store. The
321
+ * network closes it.
322
+ */
323
+ serverStore?: _korajs_server.ServerStore;
324
+ /** Every device encrypts its sync traffic with this shared key material. */
325
+ encryption?: TestDeviceEncryption;
326
+ /** The sync server's encryption policy. */
327
+ serverEncryption?: _korajs_server.KoraSyncServerConfig['encryption'];
328
+ /** Every device store's local `maxOperationBytes` (RT-86). */
329
+ deviceMaxOperationBytes?: number;
250
330
  }
251
331
  /**
252
332
  * A test network with a server and multiple devices.
253
333
  */
254
334
  interface TestNetwork {
255
335
  /** The test server */
256
- server: TestServer;
336
+ server: TestServer<_korajs_server.ServerStore>;
257
337
  /** All devices in the network */
258
338
  devices: TestDevice[];
259
339
  /** Temporary directory for DB files */
@@ -410,4 +490,4 @@ declare function createTransportMetrics(): {
410
490
  wrapTransport(pair: TransportPair): TransportPair;
411
491
  };
412
492
 
413
- export { type CollectionDifference, type ConvergenceResult, type FieldDifference, type MixedTestDeviceConfig, type TestAuthBinding, TestDevice, type TestDeviceOptions, type TestNetwork, type TestNetworkOptions, TestServer, type TestServerOptions, type TestTransferMetrics, type TransportPair, checkConvergence, createMixedTestNetwork, createTestAuthBinding, createTestNetwork, createTransportMetrics, expectConverged, expectConvergedEventually, wrapTransportPairWithProtobufWire, wrapTransportPairWithServerClock };
493
+ export { type CollectionDifference, type ConvergenceResult, type FieldDifference, type MixedTestDeviceConfig, type TestAuthBinding, TestDevice, type TestDeviceEncryption, type TestDeviceOptions, type TestDeviceServer, type TestNetwork, type TestNetworkOptions, TestServer, type TestServerOptions, type TestTransferMetrics, type TransportPair, checkConvergence, createMixedTestNetwork, createTestAuthBinding, createTestNetwork, createTransportMetrics, expectConverged, expectConvergedEventually, wrapTransportPairWithProtobufWire, wrapTransportPairWithServerClock };