@syncular/testkit 0.9.0 → 0.10.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.
package/README.md CHANGED
@@ -193,6 +193,12 @@ production. A `ValidationRejection` with structured details reaches
193
193
  tests can assert field focus and correction routing without displaying server
194
194
  diagnostics.
195
195
 
196
+ Pass `commitValidator` to test aggregate invariants with the same
197
+ transaction-scoped candidate view as production. Throw
198
+ `CommitValidationRejection` to select the operation that correction UI should
199
+ focus. The test server uses real SQLite transaction serialization and shares
200
+ the callback across loopback and socket rounds.
201
+
196
202
  ## React
197
203
 
198
204
  `@syncular/react`'s `SyncProvider` already takes any `SyncClient`, so
@@ -15,7 +15,7 @@
15
15
  * await sync.dispose();
16
16
  */
17
17
  import type { ClientSchema, SyncClientConfig } from '@syncular/client';
18
- import type { ResolveScopes, ValidatorRegistry } from '@syncular/server';
18
+ import type { CommitValidator, ResolveScopes, ValidatorRegistry } from '@syncular/server';
19
19
  import { type TestClient } from './client.js';
20
20
  import { type VirtualClock } from './clock.js';
21
21
  import { type TestServer } from './server.js';
@@ -39,6 +39,8 @@ export interface CreateTestSyncOptions {
39
39
  readonly resolveScopes?: ResolveScopes;
40
40
  /** Optional §6.7 write validators, executed by the real test server. */
41
41
  readonly validators?: ValidatorRegistry;
42
+ /** Optional §6.8 whole-commit validator, executed by the real test server. */
43
+ readonly commitValidator?: CommitValidator;
42
44
  /** Epoch ms the shared virtual clock starts at (default 1_750_000_000_000). */
43
45
  readonly startMs?: number;
44
46
  }
@@ -31,6 +31,9 @@ export async function createTestSync(options) {
31
31
  ...(options.validators !== undefined
32
32
  ? { validators: options.validators }
33
33
  : {}),
34
+ ...(options.commitValidator !== undefined
35
+ ? { commitValidator: options.commitValidator }
36
+ : {}),
34
37
  });
35
38
  const clients = [];
36
39
  let autoId = 0;
package/dist/server.d.ts CHANGED
@@ -8,7 +8,7 @@
8
8
  * directly.
9
9
  */
10
10
  import { type ClientSchema } from '@syncular/client';
11
- import { MemorySegmentStore, type RealtimeHub, type ResolveScopes, SqliteServerStorage, type SyncRequestContext, type ValidatorRegistry } from '@syncular/server';
11
+ import { type CommitValidator, MemorySegmentStore, type RealtimeHub, type ResolveScopes, SqliteServerStorage, type SyncRequestContext, type ValidatorRegistry } from '@syncular/server';
12
12
  import type { VirtualClock } from './clock.js';
13
13
  /** Default partition every actor lives in (apps override via options). */
14
14
  export declare const DEFAULT_PARTITION = "test";
@@ -29,6 +29,8 @@ export interface TestServerOptions {
29
29
  readonly resolveScopes?: ResolveScopes;
30
30
  /** Optional §6.7 validators, shared by HTTP-like and socket rounds. */
31
31
  readonly validators?: ValidatorRegistry;
32
+ /** Optional §6.8 whole-commit validator, shared by both transports. */
33
+ readonly commitValidator?: CommitValidator;
32
34
  }
33
35
  /**
34
36
  * The server half of a test sync. `ctxFor(actorId)` builds the per-request
package/dist/server.js CHANGED
@@ -48,6 +48,9 @@ export function createTestServer(options) {
48
48
  ...(options.validators !== undefined
49
49
  ? { validators: options.validators }
50
50
  : {}),
51
+ ...(options.commitValidator !== undefined
52
+ ? { commitValidator: options.commitValidator }
53
+ : {}),
51
54
  });
52
55
  return {
53
56
  storage,
@@ -64,6 +67,9 @@ export function createTestServer(options) {
64
67
  ...(options.validators !== undefined
65
68
  ? { validators: options.validators }
66
69
  : {}),
70
+ ...(options.commitValidator !== undefined
71
+ ? { commitValidator: options.commitValidator }
72
+ : {}),
67
73
  clock: clockFn,
68
74
  realtime: hub,
69
75
  }),
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@syncular/testkit",
3
- "version": "0.9.0",
3
+ "version": "0.10.0",
4
4
  "description": "Syncular test kit: in-process loopback server + clients for integration scenarios",
5
5
  "license": "Apache-2.0",
6
6
  "author": "Benjamin Kniffler",
@@ -64,8 +64,8 @@
64
64
  "test": "bun test --preload ./test/setup.ts"
65
65
  },
66
66
  "dependencies": {
67
- "@syncular/server": "0.9.0",
68
- "@syncular/client": "0.9.0"
67
+ "@syncular/server": "0.10.0",
68
+ "@syncular/client": "0.10.0"
69
69
  },
70
70
  "peerDependencies": {
71
71
  "react": ">=18.0.0"
@@ -77,8 +77,8 @@
77
77
  },
78
78
  "devDependencies": {
79
79
  "@happy-dom/global-registrator": "^15.11.0",
80
- "@syncular/core": "0.9.0",
81
- "@syncular/react": "0.9.0",
80
+ "@syncular/core": "0.10.0",
81
+ "@syncular/react": "0.10.0",
82
82
  "@testing-library/react": "^16.1.0",
83
83
  "@types/react": "^18.3.0",
84
84
  "react": "^18.3.1",
@@ -16,7 +16,11 @@
16
16
  */
17
17
 
18
18
  import type { ClientSchema, SyncClientConfig } from '@syncular/client';
19
- import type { ResolveScopes, ValidatorRegistry } from '@syncular/server';
19
+ import type {
20
+ CommitValidator,
21
+ ResolveScopes,
22
+ ValidatorRegistry,
23
+ } from '@syncular/server';
20
24
  import { buildTestClient, type TestClient } from './client';
21
25
  import { createVirtualClock, type VirtualClock } from './clock';
22
26
  import {
@@ -46,6 +50,8 @@ export interface CreateTestSyncOptions {
46
50
  readonly resolveScopes?: ResolveScopes;
47
51
  /** Optional §6.7 write validators, executed by the real test server. */
48
52
  readonly validators?: ValidatorRegistry;
53
+ /** Optional §6.8 whole-commit validator, executed by the real test server. */
54
+ readonly commitValidator?: CommitValidator;
49
55
  /** Epoch ms the shared virtual clock starts at (default 1_750_000_000_000). */
50
56
  readonly startMs?: number;
51
57
  }
@@ -103,6 +109,9 @@ export async function createTestSync(
103
109
  ...(options.validators !== undefined
104
110
  ? { validators: options.validators }
105
111
  : {}),
112
+ ...(options.commitValidator !== undefined
113
+ ? { commitValidator: options.commitValidator }
114
+ : {}),
106
115
  });
107
116
 
108
117
  const clients: TestClient[] = [];
package/src/server.ts CHANGED
@@ -10,6 +10,7 @@
10
10
 
11
11
  import { type ClientSchema, compileClientSchema } from '@syncular/client';
12
12
  import {
13
+ type CommitValidator,
13
14
  createRealtimeHub,
14
15
  MemorySegmentStore,
15
16
  type RealtimeHub,
@@ -53,6 +54,8 @@ export interface TestServerOptions {
53
54
  readonly resolveScopes?: ResolveScopes;
54
55
  /** Optional §6.7 validators, shared by HTTP-like and socket rounds. */
55
56
  readonly validators?: ValidatorRegistry;
57
+ /** Optional §6.8 whole-commit validator, shared by both transports. */
58
+ readonly commitValidator?: CommitValidator;
56
59
  }
57
60
 
58
61
  /**
@@ -85,6 +88,9 @@ export function createTestServer(options: TestServerOptions): TestServer {
85
88
  ...(options.validators !== undefined
86
89
  ? { validators: options.validators }
87
90
  : {}),
91
+ ...(options.commitValidator !== undefined
92
+ ? { commitValidator: options.commitValidator }
93
+ : {}),
88
94
  });
89
95
  return {
90
96
  storage,
@@ -101,6 +107,9 @@ export function createTestServer(options: TestServerOptions): TestServer {
101
107
  ...(options.validators !== undefined
102
108
  ? { validators: options.validators }
103
109
  : {}),
110
+ ...(options.commitValidator !== undefined
111
+ ? { commitValidator: options.commitValidator }
112
+ : {}),
104
113
  clock: clockFn,
105
114
  realtime: hub,
106
115
  }),