@syncular/testkit 0.0.0 → 0.0.2-136

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (48) hide show
  1. package/dist/assertions.d.ts +61 -0
  2. package/dist/assertions.d.ts.map +1 -0
  3. package/dist/assertions.js +239 -0
  4. package/dist/assertions.js.map +1 -0
  5. package/dist/faults.d.ts +40 -0
  6. package/dist/faults.d.ts.map +1 -0
  7. package/dist/faults.js +136 -0
  8. package/dist/faults.js.map +1 -0
  9. package/dist/fixtures.d.ts +100 -0
  10. package/dist/fixtures.d.ts.map +1 -0
  11. package/dist/fixtures.js +541 -0
  12. package/dist/fixtures.js.map +1 -0
  13. package/dist/hono-node-server.d.ts +10 -0
  14. package/dist/hono-node-server.d.ts.map +1 -0
  15. package/dist/hono-node-server.js +63 -0
  16. package/dist/hono-node-server.js.map +1 -0
  17. package/dist/http-fixtures.d.ts +57 -0
  18. package/dist/http-fixtures.d.ts.map +1 -0
  19. package/dist/http-fixtures.js +107 -0
  20. package/dist/http-fixtures.js.map +1 -0
  21. package/dist/index.d.ts +10 -0
  22. package/dist/index.d.ts.map +1 -0
  23. package/dist/index.js +10 -0
  24. package/dist/index.js.map +1 -0
  25. package/dist/project-scoped-tasks.d.ts +40 -0
  26. package/dist/project-scoped-tasks.d.ts.map +1 -0
  27. package/dist/project-scoped-tasks.js +245 -0
  28. package/dist/project-scoped-tasks.js.map +1 -0
  29. package/dist/runtime-process.d.ts +11 -0
  30. package/dist/runtime-process.d.ts.map +1 -0
  31. package/dist/runtime-process.js +92 -0
  32. package/dist/runtime-process.js.map +1 -0
  33. package/dist/sync-http.d.ts +48 -0
  34. package/dist/sync-http.d.ts.map +1 -0
  35. package/dist/sync-http.js +30 -0
  36. package/dist/sync-http.js.map +1 -0
  37. package/dist/sync-response.d.ts +7 -0
  38. package/dist/sync-response.d.ts.map +1 -0
  39. package/dist/sync-response.js +19 -0
  40. package/dist/sync-response.js.map +1 -0
  41. package/package.json +12 -12
  42. package/src/faults.ts +0 -3
  43. package/src/fixtures.ts +0 -3
  44. package/src/index.ts +3 -0
  45. package/src/project-scoped-tasks.ts +51 -1
  46. package/src/runtime-process.ts +133 -0
  47. package/src/sync-http.ts +100 -0
  48. package/src/sync-response.ts +45 -0
@@ -0,0 +1,61 @@
1
+ import type { OutboxCommitStatus, SyncClientDb } from '@syncular/client';
2
+ import type { SyncCoreDb } from '@syncular/server';
3
+ import type { Kysely } from 'kysely';
4
+ export declare function outboxCount(db: Kysely<SyncClientDb>): Promise<number>;
5
+ export declare function conflictCount(db: Kysely<SyncClientDb>): Promise<number>;
6
+ export declare function serverCommitCount(db: Kysely<SyncCoreDb>): Promise<number>;
7
+ export declare function serverChangeCount(db: Kysely<SyncCoreDb>): Promise<number>;
8
+ export declare function assertOutboxEmpty(db: Kysely<SyncClientDb>): Promise<void>;
9
+ export declare function assertOutboxHas(db: Kysely<SyncClientDb>, expectedCount: number): Promise<void>;
10
+ export declare function assertOutboxStatus(db: Kysely<SyncClientDb>, status: OutboxCommitStatus, expectedCount: number): Promise<void>;
11
+ export declare function assertConflictCount(db: Kysely<SyncClientDb>, expectedCount: number): Promise<void>;
12
+ export declare function assertConflictExists(db: Kysely<SyncClientDb>, options: {
13
+ clientCommitId: string;
14
+ resultStatus?: 'conflict' | 'error';
15
+ resolved?: boolean;
16
+ }): Promise<void>;
17
+ export declare function assertRowExists<DB extends SyncClientDb, T extends keyof DB & string>(db: Kysely<DB>, table: T, rowId: string, expected?: Partial<DB[T]>, idColumn?: string): Promise<void>;
18
+ export declare function assertRowNotExists<DB extends SyncClientDb, T extends keyof DB & string>(db: Kysely<DB>, table: T, rowId: string, idColumn?: string): Promise<void>;
19
+ export declare function assertRowVersion<DB extends SyncClientDb, T extends keyof DB & string>(db: Kysely<DB>, table: T, rowId: string, expectedVersion: number, versionColumn?: string, idColumn?: string): Promise<void>;
20
+ export declare function assertSubscriptionCursor(db: Kysely<SyncClientDb>, subscriptionId: string, expectedCursor: number, stateId?: string): Promise<void>;
21
+ export declare function assertSubscriptionStatus(db: Kysely<SyncClientDb>, subscriptionId: string, expectedStatus: 'active' | 'revoked', stateId?: string): Promise<void>;
22
+ export declare function assertServerCommitCount(db: Kysely<SyncCoreDb>, expectedCount: number): Promise<void>;
23
+ export declare function assertServerChangeCount(db: Kysely<SyncCoreDb>, expectedCount: number): Promise<void>;
24
+ export declare function assertServerChangeExists(db: Kysely<SyncCoreDb>, options: {
25
+ table: string;
26
+ rowId: string;
27
+ op?: 'upsert' | 'delete';
28
+ commitSeq?: number;
29
+ }): Promise<void>;
30
+ export declare function assertServerClientCursor(db: Kysely<SyncCoreDb>, clientId: string, expectedCursor: number): Promise<void>;
31
+ export declare function waitForOutboxEmpty(db: Kysely<SyncClientDb>, timeoutMs?: number): Promise<void>;
32
+ export declare function waitForAckedCommits(db: Kysely<SyncClientDb>, expectedCount: number, timeoutMs?: number): Promise<void>;
33
+ export declare const assertOutbox: {
34
+ empty: typeof assertOutboxEmpty;
35
+ count: typeof assertOutboxHas;
36
+ status: typeof assertOutboxStatus;
37
+ };
38
+ export declare const assertConflicts: {
39
+ count: typeof assertConflictCount;
40
+ exists: typeof assertConflictExists;
41
+ };
42
+ export declare const assertRows: {
43
+ exists: typeof assertRowExists;
44
+ missing: typeof assertRowNotExists;
45
+ version: typeof assertRowVersion;
46
+ };
47
+ export declare const assertServer: {
48
+ commits: typeof assertServerCommitCount;
49
+ changes: typeof assertServerChangeCount;
50
+ changeExists: typeof assertServerChangeExists;
51
+ clientCursor: typeof assertServerClientCursor;
52
+ };
53
+ export declare const assertSubscription: {
54
+ cursor: typeof assertSubscriptionCursor;
55
+ status: typeof assertSubscriptionStatus;
56
+ };
57
+ export declare const waitForSync: {
58
+ outboxEmpty: typeof waitForOutboxEmpty;
59
+ ackedCommits: typeof waitForAckedCommits;
60
+ };
61
+ //# sourceMappingURL=assertions.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"assertions.d.ts","sourceRoot":"","sources":["../src/assertions.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,239 @@
1
+ import { isDeepStrictEqual } from 'node:util';
2
+ function formatValue(value) {
3
+ if (typeof value === 'string') {
4
+ return value;
5
+ }
6
+ try {
7
+ return JSON.stringify(value);
8
+ }
9
+ catch {
10
+ return String(value);
11
+ }
12
+ }
13
+ function fail(message) {
14
+ throw new Error(message);
15
+ }
16
+ function assertEqual(actual, expected, message) {
17
+ if (!isDeepStrictEqual(actual, expected)) {
18
+ fail(`${message} (expected=${formatValue(expected)} actual=${formatValue(actual)})`);
19
+ }
20
+ }
21
+ function assertDefined(value, message) {
22
+ if (value == null) {
23
+ fail(message);
24
+ }
25
+ }
26
+ export async function outboxCount(db) {
27
+ const count = await db
28
+ .selectFrom('sync_outbox_commits')
29
+ .select(({ fn }) => fn.countAll().as('count'))
30
+ .executeTakeFirstOrThrow();
31
+ return Number(count.count);
32
+ }
33
+ export async function conflictCount(db) {
34
+ const count = await db
35
+ .selectFrom('sync_conflicts')
36
+ .where('resolved_at', 'is', null)
37
+ .select(({ fn }) => fn.countAll().as('count'))
38
+ .executeTakeFirstOrThrow();
39
+ return Number(count.count);
40
+ }
41
+ export async function serverCommitCount(db) {
42
+ const count = await db
43
+ .selectFrom('sync_commits')
44
+ .select(({ fn }) => fn.countAll().as('count'))
45
+ .executeTakeFirstOrThrow();
46
+ return Number(count.count);
47
+ }
48
+ export async function serverChangeCount(db) {
49
+ const count = await db
50
+ .selectFrom('sync_changes')
51
+ .select(({ fn }) => fn.countAll().as('count'))
52
+ .executeTakeFirstOrThrow();
53
+ return Number(count.count);
54
+ }
55
+ export async function assertOutboxEmpty(db) {
56
+ const count = await outboxCount(db);
57
+ assertEqual(count, 0, 'Outbox is not empty');
58
+ }
59
+ export async function assertOutboxHas(db, expectedCount) {
60
+ const count = await outboxCount(db);
61
+ assertEqual(count, expectedCount, 'Unexpected outbox commit count');
62
+ }
63
+ export async function assertOutboxStatus(db, status, expectedCount) {
64
+ const count = await db
65
+ .selectFrom('sync_outbox_commits')
66
+ .where('status', '=', status)
67
+ .select(({ fn }) => fn.countAll().as('count'))
68
+ .executeTakeFirstOrThrow();
69
+ assertEqual(Number(count.count), expectedCount, `Unexpected outbox count for status=${status}`);
70
+ }
71
+ export async function assertConflictCount(db, expectedCount) {
72
+ const count = await conflictCount(db);
73
+ assertEqual(count, expectedCount, 'Unexpected unresolved conflict count');
74
+ }
75
+ export async function assertConflictExists(db, options) {
76
+ let query = db
77
+ .selectFrom('sync_conflicts')
78
+ .where('client_commit_id', '=', options.clientCommitId);
79
+ if (options.resultStatus) {
80
+ query = query.where('result_status', '=', options.resultStatus);
81
+ }
82
+ if (options.resolved !== undefined) {
83
+ query = options.resolved
84
+ ? query.where('resolved_at', 'is not', null)
85
+ : query.where('resolved_at', 'is', null);
86
+ }
87
+ const conflict = await query.selectAll().executeTakeFirst();
88
+ assertDefined(conflict, `Expected conflict for client_commit_id=${options.clientCommitId}`);
89
+ }
90
+ export async function assertRowExists(db, table, rowId, expected, idColumn = 'id') {
91
+ const row = await db
92
+ .selectFrom(table)
93
+ // @ts-expect-error - dynamic column name
94
+ .where(idColumn, '=', rowId)
95
+ .selectAll()
96
+ .executeTakeFirst();
97
+ assertDefined(row, `Expected row ${rowId} to exist in table ${table}`);
98
+ if (!expected) {
99
+ return;
100
+ }
101
+ const rowRecord = row;
102
+ for (const [key, value] of Object.entries(expected)) {
103
+ assertEqual(rowRecord[key], value, `Unexpected value for ${table}.${key} (row ${rowId})`);
104
+ }
105
+ }
106
+ export async function assertRowNotExists(db, table, rowId, idColumn = 'id') {
107
+ const row = await db
108
+ .selectFrom(table)
109
+ // @ts-expect-error - dynamic column name
110
+ .where(idColumn, '=', rowId)
111
+ .selectAll()
112
+ .executeTakeFirst();
113
+ if (row !== undefined) {
114
+ fail(`Expected row ${rowId} to be absent in table ${table}`);
115
+ }
116
+ }
117
+ export async function assertRowVersion(db, table, rowId, expectedVersion, versionColumn = 'server_version', idColumn = 'id') {
118
+ const row = await db
119
+ .selectFrom(table)
120
+ // @ts-expect-error - dynamic column name
121
+ .where(idColumn, '=', rowId)
122
+ .select(versionColumn)
123
+ .executeTakeFirst();
124
+ assertDefined(row, `Expected row ${rowId} to exist in table ${table}`);
125
+ const rowRecord = row;
126
+ assertEqual(rowRecord[versionColumn], expectedVersion, `Unexpected version for ${table}.${rowId}`);
127
+ }
128
+ export async function assertSubscriptionCursor(db, subscriptionId, expectedCursor, stateId = 'default') {
129
+ const sub = await db
130
+ .selectFrom('sync_subscription_state')
131
+ .where('state_id', '=', stateId)
132
+ .where('subscription_id', '=', subscriptionId)
133
+ .select(['cursor'])
134
+ .executeTakeFirst();
135
+ assertDefined(sub, `Expected subscription state row for ${stateId}/${subscriptionId}`);
136
+ assertEqual(sub.cursor, expectedCursor, `Unexpected cursor for subscription ${subscriptionId}`);
137
+ }
138
+ export async function assertSubscriptionStatus(db, subscriptionId, expectedStatus, stateId = 'default') {
139
+ const sub = await db
140
+ .selectFrom('sync_subscription_state')
141
+ .where('state_id', '=', stateId)
142
+ .where('subscription_id', '=', subscriptionId)
143
+ .select(['status'])
144
+ .executeTakeFirst();
145
+ assertDefined(sub, `Expected subscription state row for ${stateId}/${subscriptionId}`);
146
+ assertEqual(sub.status, expectedStatus, `Unexpected status for subscription ${subscriptionId}`);
147
+ }
148
+ export async function assertServerCommitCount(db, expectedCount) {
149
+ const count = await serverCommitCount(db);
150
+ assertEqual(count, expectedCount, 'Unexpected server commit count');
151
+ }
152
+ export async function assertServerChangeCount(db, expectedCount) {
153
+ const count = await serverChangeCount(db);
154
+ assertEqual(count, expectedCount, 'Unexpected server change count');
155
+ }
156
+ export async function assertServerChangeExists(db, options) {
157
+ let query = db
158
+ .selectFrom('sync_changes')
159
+ .where('table', '=', options.table)
160
+ .where('row_id', '=', options.rowId);
161
+ if (options.op) {
162
+ query = query.where('op', '=', options.op);
163
+ }
164
+ if (options.commitSeq) {
165
+ query = query.where('commit_seq', '=', options.commitSeq);
166
+ }
167
+ const change = await query.selectAll().executeTakeFirst();
168
+ assertDefined(change, `Expected server change for table=${options.table} rowId=${options.rowId}`);
169
+ }
170
+ export async function assertServerClientCursor(db, clientId, expectedCursor) {
171
+ const cursor = await db
172
+ .selectFrom('sync_client_cursors')
173
+ .where('client_id', '=', clientId)
174
+ .select(['cursor'])
175
+ .executeTakeFirst();
176
+ assertDefined(cursor, `Expected sync_client_cursors row for ${clientId}`);
177
+ assertEqual(cursor.cursor, expectedCursor, `Unexpected cursor for ${clientId}`);
178
+ }
179
+ async function waitFor(condition, options) {
180
+ const timeoutMs = options?.timeoutMs ?? 5000;
181
+ const intervalMs = options?.intervalMs ?? 50;
182
+ const message = options?.message ?? 'Condition not met within timeout';
183
+ const startTime = Date.now();
184
+ while (Date.now() - startTime < timeoutMs) {
185
+ if (await condition()) {
186
+ return;
187
+ }
188
+ await new Promise((resolve) => setTimeout(resolve, intervalMs));
189
+ }
190
+ fail(message);
191
+ }
192
+ export async function waitForOutboxEmpty(db, timeoutMs = 5000) {
193
+ await waitFor(async () => {
194
+ const count = await outboxCount(db);
195
+ return count === 0;
196
+ }, { timeoutMs, message: 'Outbox not empty within timeout' });
197
+ }
198
+ export async function waitForAckedCommits(db, expectedCount, timeoutMs = 5000) {
199
+ await waitFor(async () => {
200
+ const count = await db
201
+ .selectFrom('sync_outbox_commits')
202
+ .where('status', '=', 'acked')
203
+ .select(({ fn }) => fn.countAll().as('count'))
204
+ .executeTakeFirstOrThrow();
205
+ return Number(count.count) >= expectedCount;
206
+ }, {
207
+ timeoutMs,
208
+ message: `Expected ${expectedCount} acked commits within timeout`,
209
+ });
210
+ }
211
+ export const assertOutbox = {
212
+ empty: assertOutboxEmpty,
213
+ count: assertOutboxHas,
214
+ status: assertOutboxStatus,
215
+ };
216
+ export const assertConflicts = {
217
+ count: assertConflictCount,
218
+ exists: assertConflictExists,
219
+ };
220
+ export const assertRows = {
221
+ exists: assertRowExists,
222
+ missing: assertRowNotExists,
223
+ version: assertRowVersion,
224
+ };
225
+ export const assertServer = {
226
+ commits: assertServerCommitCount,
227
+ changes: assertServerChangeCount,
228
+ changeExists: assertServerChangeExists,
229
+ clientCursor: assertServerClientCursor,
230
+ };
231
+ export const assertSubscription = {
232
+ cursor: assertSubscriptionCursor,
233
+ status: assertSubscriptionStatus,
234
+ };
235
+ export const waitForSync = {
236
+ outboxEmpty: waitForOutboxEmpty,
237
+ ackedCommits: waitForAckedCommits,
238
+ };
239
+ //# sourceMappingURL=assertions.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"assertions.js","sourceRoot":"","sources":["../src/assertions.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,40 @@
1
+ import type { SyncCombinedRequest, SyncPullResponse, SyncPushResponse, SyncTransport } from '@syncular/core';
2
+ export interface FaultTransportOptions {
3
+ failAfter?: number;
4
+ failWith?: Error;
5
+ latencyMs?: number;
6
+ flaky?: number;
7
+ failOnPush?: boolean;
8
+ failOnPull?: boolean;
9
+ failOnFetch?: boolean;
10
+ onFail?: (operation: 'push' | 'pull' | 'fetch', error: Error) => void;
11
+ onSuccess?: (operation: 'push' | 'pull' | 'fetch') => void;
12
+ }
13
+ export interface FaultTransportState {
14
+ pushCount: number;
15
+ pullCount: number;
16
+ fetchCount: number;
17
+ failureCount: number;
18
+ }
19
+ export interface FaultTransportResult {
20
+ transport: SyncTransport;
21
+ getState: () => FaultTransportState;
22
+ reset: () => void;
23
+ setOptions: (options: Partial<FaultTransportOptions>) => void;
24
+ }
25
+ export declare function withFaults(baseTransport: SyncTransport, options?: FaultTransportOptions): FaultTransportResult;
26
+ export declare function createMockTransport(options?: {
27
+ pullResponse?: SyncPullResponse;
28
+ pushResponse?: SyncPushResponse;
29
+ chunkData?: Uint8Array;
30
+ }): SyncTransport;
31
+ export interface RecordingTransportResult {
32
+ transport: SyncTransport;
33
+ syncRequests: SyncCombinedRequest[];
34
+ fetchRequests: {
35
+ chunkId: string;
36
+ }[];
37
+ clear: () => void;
38
+ }
39
+ export declare function withRecording(baseTransport: SyncTransport): RecordingTransportResult;
40
+ //# sourceMappingURL=faults.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"faults.d.ts","sourceRoot":"","sources":["../src/faults.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,mBAAmB,EACnB,gBAAgB,EAChB,gBAAgB,EAChB,aAAa,EAEd,MAAM,gBAAgB,CAAC;AAExB,MAAM,WAAW,qBAAqB;IACpC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,EAAE,KAAK,CAAC;IACjB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,MAAM,CAAC,EAAE,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,EAAE,KAAK,EAAE,KAAK,KAAK,IAAI,CAAC;IACtE,SAAS,CAAC,EAAE,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,KAAK,IAAI,CAAC;CAC5D;AAED,MAAM,WAAW,mBAAmB;IAClC,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;IACnB,YAAY,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,oBAAoB;IACnC,SAAS,EAAE,aAAa,CAAC;IACzB,QAAQ,EAAE,MAAM,mBAAmB,CAAC;IACpC,KAAK,EAAE,MAAM,IAAI,CAAC;IAClB,UAAU,EAAE,CAAC,OAAO,EAAE,OAAO,CAAC,qBAAqB,CAAC,KAAK,IAAI,CAAC;CAC/D;AAED,wBAAgB,UAAU,CACxB,aAAa,EAAE,aAAa,EAC5B,OAAO,GAAE,qBAA0B,GAClC,oBAAoB,CAgHtB;AAED,wBAAgB,mBAAmB,CAAC,OAAO,CAAC,EAAE;IAC5C,YAAY,CAAC,EAAE,gBAAgB,CAAC;IAChC,YAAY,CAAC,EAAE,gBAAgB,CAAC;IAChC,SAAS,CAAC,EAAE,UAAU,CAAC;CACxB,GAAG,aAAa,CAkChB;AAED,MAAM,WAAW,wBAAwB;IACvC,SAAS,EAAE,aAAa,CAAC;IACzB,YAAY,EAAE,mBAAmB,EAAE,CAAC;IACpC,aAAa,EAAE;QAAE,OAAO,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC;IACrC,KAAK,EAAE,MAAM,IAAI,CAAC;CACnB;AAED,wBAAgB,aAAa,CAC3B,aAAa,EAAE,aAAa,GAC3B,wBAAwB,CAyB1B"}
package/dist/faults.js ADDED
@@ -0,0 +1,136 @@
1
+ export function withFaults(baseTransport, options = {}) {
2
+ let currentOptions = { ...options };
3
+ const state = {
4
+ pushCount: 0,
5
+ pullCount: 0,
6
+ fetchCount: 0,
7
+ failureCount: 0,
8
+ };
9
+ const defaultError = new Error('Simulated transport error');
10
+ const maybeDelay = async () => {
11
+ if (currentOptions.latencyMs && currentOptions.latencyMs > 0) {
12
+ await new Promise((resolve) => setTimeout(resolve, currentOptions.latencyMs));
13
+ }
14
+ };
15
+ const shouldFail = (operation, count) => {
16
+ if (operation === 'push' && currentOptions.failOnPull) {
17
+ return false;
18
+ }
19
+ if (operation === 'pull' && currentOptions.failOnPush) {
20
+ return false;
21
+ }
22
+ if (operation === 'fetch' && !currentOptions.failOnFetch) {
23
+ if (currentOptions.failOnPush || currentOptions.failOnPull) {
24
+ return false;
25
+ }
26
+ }
27
+ if (currentOptions.failAfter !== undefined &&
28
+ count >= currentOptions.failAfter) {
29
+ return true;
30
+ }
31
+ if (currentOptions.flaky !== undefined && currentOptions.flaky > 0) {
32
+ return Math.random() < currentOptions.flaky;
33
+ }
34
+ return false;
35
+ };
36
+ const getError = () => currentOptions.failWith ?? defaultError;
37
+ const transport = {
38
+ async sync(request, transportOptions) {
39
+ await maybeDelay();
40
+ const operation = request.push ? 'push' : 'pull';
41
+ const count = operation === 'push' ? state.pushCount : state.pullCount;
42
+ if (shouldFail(operation, count)) {
43
+ const error = getError();
44
+ state.failureCount++;
45
+ currentOptions.onFail?.(operation, error);
46
+ throw error;
47
+ }
48
+ if (operation === 'push') {
49
+ state.pushCount++;
50
+ }
51
+ else {
52
+ state.pullCount++;
53
+ }
54
+ const result = await baseTransport.sync(request, transportOptions);
55
+ currentOptions.onSuccess?.(operation);
56
+ return result;
57
+ },
58
+ async fetchSnapshotChunk(request, transportOptions) {
59
+ await maybeDelay();
60
+ if (shouldFail('fetch', state.fetchCount)) {
61
+ const error = getError();
62
+ state.failureCount++;
63
+ currentOptions.onFail?.('fetch', error);
64
+ throw error;
65
+ }
66
+ state.fetchCount++;
67
+ const result = await baseTransport.fetchSnapshotChunk(request, transportOptions);
68
+ currentOptions.onSuccess?.('fetch');
69
+ return result;
70
+ },
71
+ };
72
+ return {
73
+ transport,
74
+ getState: () => ({ ...state }),
75
+ reset: () => {
76
+ state.pushCount = 0;
77
+ state.pullCount = 0;
78
+ state.fetchCount = 0;
79
+ state.failureCount = 0;
80
+ },
81
+ setOptions: (newOptions) => {
82
+ currentOptions = { ...currentOptions, ...newOptions };
83
+ },
84
+ };
85
+ }
86
+ export function createMockTransport(options) {
87
+ return {
88
+ async sync(request) {
89
+ const result = { ok: true };
90
+ if (request.push) {
91
+ result.push = options?.pushResponse ?? {
92
+ ok: true,
93
+ status: 'applied',
94
+ results: request.push.operations.map((_, i) => ({
95
+ opIndex: i,
96
+ status: 'applied',
97
+ })),
98
+ };
99
+ }
100
+ if (request.pull) {
101
+ result.pull = options?.pullResponse ?? {
102
+ ok: true,
103
+ subscriptions: [],
104
+ };
105
+ }
106
+ return result;
107
+ },
108
+ async fetchSnapshotChunk() {
109
+ return options?.chunkData ?? new Uint8Array();
110
+ },
111
+ };
112
+ }
113
+ export function withRecording(baseTransport) {
114
+ const syncRequests = [];
115
+ const fetchRequests = [];
116
+ const transport = {
117
+ async sync(request, options) {
118
+ syncRequests.push(structuredClone(request));
119
+ return baseTransport.sync(request, options);
120
+ },
121
+ async fetchSnapshotChunk(request, options) {
122
+ fetchRequests.push({ ...request });
123
+ return baseTransport.fetchSnapshotChunk(request, options);
124
+ },
125
+ };
126
+ return {
127
+ transport,
128
+ syncRequests,
129
+ fetchRequests,
130
+ clear: () => {
131
+ syncRequests.length = 0;
132
+ fetchRequests.length = 0;
133
+ },
134
+ };
135
+ }
136
+ //# sourceMappingURL=faults.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"faults.js","sourceRoot":"","sources":["../src/faults.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,100 @@
1
+ import { ClientTableRegistry, enqueueOutboxCommit, type SyncClientDb, type SyncClientPlugin, SyncEngine, type SyncOnceOptions, type SyncOnceResult, type SyncPullOnceOptions, type SyncPullResponse, type SyncPushOnceOptions, type SyncPushOnceResult } from '@syncular/client';
2
+ import { type SyncSubscriptionRequest, type SyncTransport } from '@syncular/core';
3
+ import { type ServerSyncDialect, type SyncCoreDb, TableRegistry } from '@syncular/server';
4
+ import type { Kysely } from 'kysely';
5
+ export type ServerDialect = 'sqlite' | 'pglite';
6
+ export type ClientDialect = 'bun-sqlite' | 'pglite';
7
+ export type TestSqliteDbDialect = 'bun-sqlite' | 'sqlite3' | 'libsql';
8
+ export type TestClientDialect = ClientDialect | 'sqlite3' | 'libsql';
9
+ export interface TasksServerDb extends SyncCoreDb {
10
+ tasks: {
11
+ id: string;
12
+ title: string;
13
+ completed: number;
14
+ user_id: string;
15
+ server_version: number;
16
+ };
17
+ }
18
+ export interface TasksClientDb extends SyncClientDb {
19
+ tasks: {
20
+ id: string;
21
+ title: string;
22
+ completed: number;
23
+ user_id: string;
24
+ server_version: number;
25
+ };
26
+ }
27
+ export interface TestServer {
28
+ db: Kysely<TasksServerDb>;
29
+ dialect: ServerSyncDialect;
30
+ handlers: TableRegistry<TasksServerDb>;
31
+ destroy: () => Promise<void>;
32
+ }
33
+ export interface TestClient {
34
+ mode: 'raw';
35
+ db: Kysely<TasksClientDb>;
36
+ transport: SyncTransport;
37
+ handlers: ClientTableRegistry<TasksClientDb>;
38
+ actorId: string;
39
+ clientId: string;
40
+ enqueue: (args: Parameters<typeof enqueueOutboxCommit<TasksClientDb>>[1]) => Promise<{
41
+ id: string;
42
+ clientCommitId: string;
43
+ }>;
44
+ push: (options?: Omit<SyncPushOnceOptions, 'clientId' | 'actorId'>) => Promise<SyncPushOnceResult>;
45
+ pull: (options: Omit<SyncPullOnceOptions, 'clientId' | 'actorId'>) => Promise<SyncPullResponse>;
46
+ syncOnce: (options: Omit<SyncOnceOptions, 'clientId' | 'actorId'>) => Promise<SyncOnceResult>;
47
+ destroy: () => Promise<void>;
48
+ }
49
+ export interface EngineTestClient extends Omit<TestClient, 'mode'> {
50
+ mode: 'engine';
51
+ engine: SyncEngine<TasksClientDb>;
52
+ startEngine: () => Promise<void>;
53
+ stopEngine: () => void;
54
+ syncEngine: () => Promise<Awaited<ReturnType<SyncEngine<TasksClientDb>['sync']>>>;
55
+ refreshOutboxStats: () => Promise<Awaited<ReturnType<SyncEngine<TasksClientDb>['refreshOutboxStats']>>>;
56
+ }
57
+ export interface CreateTestClientOptions {
58
+ actorId: string;
59
+ clientId: string;
60
+ }
61
+ export interface CreateEngineTestClientOptions extends CreateTestClientOptions {
62
+ clientDialect?: TestClientDialect;
63
+ plugins?: SyncClientPlugin[];
64
+ subscriptions?: Array<Omit<SyncSubscriptionRequest, 'cursor'>>;
65
+ pollIntervalMs?: number;
66
+ realtimeEnabled?: boolean;
67
+ }
68
+ export interface CreateSyncFixtureOptions {
69
+ serverDialect: ServerDialect;
70
+ defaultClientDialect?: TestClientDialect;
71
+ defaultMode?: 'raw' | 'engine';
72
+ defaultSubscriptions?: Array<Omit<SyncSubscriptionRequest, 'cursor'>>;
73
+ pollIntervalMs?: number;
74
+ realtimeEnabled?: boolean;
75
+ }
76
+ export interface CreateSyncClientOptions {
77
+ actorId: string;
78
+ clientId: string;
79
+ mode?: 'raw' | 'engine';
80
+ clientDialect?: TestClientDialect;
81
+ plugins?: SyncClientPlugin[];
82
+ subscriptions?: Array<Omit<SyncSubscriptionRequest, 'cursor'>>;
83
+ }
84
+ export interface SyncFixture {
85
+ server: TestServer;
86
+ createClient: (options: CreateSyncClientOptions) => Promise<TestClient | EngineTestClient>;
87
+ destroyAll: () => Promise<void>;
88
+ }
89
+ export declare function createTestServer(serverDialect: ServerDialect): Promise<TestServer>;
90
+ export declare function createTestSqliteServer(dialect: TestSqliteDbDialect): Promise<TestServer>;
91
+ export declare function createTestClient(clientDialect: TestClientDialect, server: TestServer, options: CreateTestClientOptions): Promise<TestClient>;
92
+ export declare function createEngineTestClient(server: TestServer, options: CreateEngineTestClientOptions): Promise<EngineTestClient>;
93
+ export declare function createSyncFixture(options: CreateSyncFixtureOptions): Promise<SyncFixture>;
94
+ export declare function seedServerData(server: TestServer, options: {
95
+ userId: string;
96
+ count: number;
97
+ }): Promise<void>;
98
+ export declare function destroyTestClient(client: Pick<TestClient, 'destroy'> | Pick<EngineTestClient, 'destroy'>): Promise<void>;
99
+ export declare function destroyTestServer(server: Pick<TestServer, 'destroy'>): Promise<void>;
100
+ //# sourceMappingURL=fixtures.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fixtures.d.ts","sourceRoot":"","sources":["../src/fixtures.ts"],"names":[],"mappings":"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"}