@syncular/testkit 0.0.6-96 → 0.1.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/dist/audit.d.ts +22 -0
- package/dist/audit.d.ts.map +1 -0
- package/dist/audit.js +40 -0
- package/dist/audit.js.map +1 -0
- package/dist/client-bridge.d.ts +77 -0
- package/dist/client-bridge.d.ts.map +1 -0
- package/dist/client-bridge.js +540 -0
- package/dist/client-bridge.js.map +1 -0
- package/dist/deterministic.js.map +1 -1
- package/dist/disposable.js.map +1 -1
- package/dist/faults.d.ts +14 -2
- package/dist/faults.d.ts.map +1 -1
- package/dist/faults.js +104 -42
- package/dist/faults.js.map +1 -1
- package/dist/hono-node-server.js +2 -2
- package/dist/hono-node-server.js.map +1 -1
- package/dist/http-fixtures.d.ts +1 -30
- package/dist/http-fixtures.d.ts.map +1 -1
- package/dist/http-fixtures.js +6 -66
- package/dist/http-fixtures.js.map +1 -1
- package/dist/index.d.ts +2 -4
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +14 -16
- package/dist/index.js.map +1 -1
- package/dist/project-scoped-tasks.d.ts.map +1 -1
- package/dist/project-scoped-tasks.js +6 -4
- package/dist/project-scoped-tasks.js.map +1 -1
- package/dist/realtime-ws.js +1 -1
- package/dist/realtime-ws.js.map +1 -1
- package/dist/runtime-process.js +1 -1
- package/dist/runtime-process.js.map +1 -1
- package/dist/sync-builders.d.ts +5 -3
- package/dist/sync-builders.d.ts.map +1 -1
- package/dist/sync-builders.js +9 -3
- package/dist/sync-builders.js.map +1 -1
- package/dist/sync-http.js +1 -1
- package/dist/sync-http.js.map +1 -1
- package/dist/sync-parse.js.map +1 -1
- package/dist/sync-response.d.ts +3 -4
- package/dist/sync-response.d.ts.map +1 -1
- package/dist/sync-response.js.map +1 -1
- package/package.json +15 -16
- package/src/audit.ts +74 -0
- package/src/client-bridge.ts +841 -0
- package/src/faults.ts +178 -55
- package/src/hono-node-server.ts +1 -1
- package/src/http-fixtures.ts +6 -127
- package/src/index.ts +2 -4
- package/src/project-scoped-tasks.ts +6 -4
- package/src/sync-builders.ts +14 -6
- package/src/sync-response.ts +3 -5
- package/dist/assertions.d.ts +0 -61
- package/dist/assertions.d.ts.map +0 -1
- package/dist/assertions.js +0 -239
- package/dist/assertions.js.map +0 -1
- package/dist/fixtures.d.ts +0 -104
- package/dist/fixtures.d.ts.map +0 -1
- package/dist/fixtures.js +0 -558
- package/dist/fixtures.js.map +0 -1
- package/dist/resources.d.ts +0 -25
- package/dist/resources.d.ts.map +0 -1
- package/dist/resources.js +0 -64
- package/dist/resources.js.map +0 -1
- package/dist/scenario-flow.d.ts +0 -39
- package/dist/scenario-flow.d.ts.map +0 -1
- package/dist/scenario-flow.js +0 -41
- package/dist/scenario-flow.js.map +0 -1
- package/src/assertions.ts +0 -432
- package/src/fixtures.ts +0 -867
- package/src/resources.ts +0 -186
- package/src/scenario-flow.ts +0 -143
package/dist/resources.js
DELETED
|
@@ -1,64 +0,0 @@
|
|
|
1
|
-
import { createAsyncDisposableResource, withAsyncDisposableFactory, } from './disposable.js';
|
|
2
|
-
import { createEngineTestClient, createSyncFixture, createTestClient, createTestServer, createTestSqliteServer, } from './fixtures.js';
|
|
3
|
-
import { createHttpClientFixture, createHttpServerFixture, } from './http-fixtures.js';
|
|
4
|
-
export async function createTestServerResource(serverDialect) {
|
|
5
|
-
const server = await createTestServer(serverDialect);
|
|
6
|
-
return createAsyncDisposableResource(server, () => server.destroy());
|
|
7
|
-
}
|
|
8
|
-
export async function withTestServer(serverDialect, run) {
|
|
9
|
-
return withAsyncDisposableFactory(() => createTestServerResource(serverDialect), run);
|
|
10
|
-
}
|
|
11
|
-
export async function createTestSqliteServerResource(dialect) {
|
|
12
|
-
const server = await createTestSqliteServer(dialect);
|
|
13
|
-
return createAsyncDisposableResource(server, () => server.destroy());
|
|
14
|
-
}
|
|
15
|
-
export async function withTestSqliteServer(dialect, run) {
|
|
16
|
-
return withAsyncDisposableFactory(() => createTestSqliteServerResource(dialect), run);
|
|
17
|
-
}
|
|
18
|
-
export async function createTestClientResource(clientDialect, server, options) {
|
|
19
|
-
const client = await createTestClient(clientDialect, server, options);
|
|
20
|
-
return createAsyncDisposableResource(client, () => client.destroy());
|
|
21
|
-
}
|
|
22
|
-
export async function withTestClient(clientDialect, server, options, run) {
|
|
23
|
-
return withAsyncDisposableFactory(() => createTestClientResource(clientDialect, server, options), run);
|
|
24
|
-
}
|
|
25
|
-
export async function createEngineTestClientResource(server, options) {
|
|
26
|
-
const client = await createEngineTestClient(server, options);
|
|
27
|
-
return createAsyncDisposableResource(client, () => client.destroy());
|
|
28
|
-
}
|
|
29
|
-
export async function withEngineTestClient(server, options, run) {
|
|
30
|
-
return withAsyncDisposableFactory(() => createEngineTestClientResource(server, options), run);
|
|
31
|
-
}
|
|
32
|
-
export async function createSyncFixtureResource(options) {
|
|
33
|
-
const fixture = await createSyncFixture(options);
|
|
34
|
-
return createAsyncDisposableResource(fixture, () => fixture.destroyAll());
|
|
35
|
-
}
|
|
36
|
-
export async function withSyncFixture(options, run) {
|
|
37
|
-
return withAsyncDisposableFactory(() => createSyncFixtureResource(options), run);
|
|
38
|
-
}
|
|
39
|
-
export async function createHttpServerFixtureResource(options) {
|
|
40
|
-
const fixture = await createHttpServerFixture(options);
|
|
41
|
-
return createAsyncDisposableResource(fixture, () => fixture.destroy());
|
|
42
|
-
}
|
|
43
|
-
export async function withHttpServerFixture(options, run) {
|
|
44
|
-
return withAsyncDisposableFactory(() => createHttpServerFixtureResource(options), run);
|
|
45
|
-
}
|
|
46
|
-
export async function createHttpClientFixtureResource(options) {
|
|
47
|
-
const fixture = await createHttpClientFixture(options);
|
|
48
|
-
return createAsyncDisposableResource(fixture, () => fixture.destroy());
|
|
49
|
-
}
|
|
50
|
-
export async function withHttpClientFixture(options, run) {
|
|
51
|
-
return withAsyncDisposableFactory(() => createHttpClientFixtureResource(options), run);
|
|
52
|
-
}
|
|
53
|
-
export async function createEngineSessionResource(client, options = {}) {
|
|
54
|
-
if (options.start ?? true) {
|
|
55
|
-
await client.startEngine();
|
|
56
|
-
}
|
|
57
|
-
return createAsyncDisposableResource(client, () => {
|
|
58
|
-
client.stopEngine();
|
|
59
|
-
});
|
|
60
|
-
}
|
|
61
|
-
export async function withEngineSession(client, run, options = {}) {
|
|
62
|
-
return withAsyncDisposableFactory(() => createEngineSessionResource(client, options), run);
|
|
63
|
-
}
|
|
64
|
-
//# sourceMappingURL=resources.js.map
|
package/dist/resources.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"resources.js","sourceRoot":"","sources":["../src/resources.ts"],"names":[],"mappings":"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"}
|
package/dist/scenario-flow.d.ts
DELETED
|
@@ -1,39 +0,0 @@
|
|
|
1
|
-
import { type ClientHandlerCollection, enqueueOutboxCommit, type SyncClientDb, type SyncOnceOptions, type SyncOnceResult, type SyncPullOnceOptions, type SyncPullResponse, type SyncPushOnceOptions, type SyncPushOnceResult } from '@syncular/client';
|
|
2
|
-
import type { SyncCombinedRequest, SyncCombinedResponse, SyncTransport } from '@syncular/core';
|
|
3
|
-
import type { Kysely } from 'kysely';
|
|
4
|
-
export interface ScenarioFlowClient<DB extends SyncClientDb> {
|
|
5
|
-
db: Kysely<DB>;
|
|
6
|
-
transport: SyncTransport;
|
|
7
|
-
handlers: ClientHandlerCollection<DB>;
|
|
8
|
-
clientId: string;
|
|
9
|
-
actorId?: string;
|
|
10
|
-
}
|
|
11
|
-
export interface PushThenPullOptions<DB extends SyncClientDb> {
|
|
12
|
-
enqueue?: Parameters<typeof enqueueOutboxCommit<DB>>[1];
|
|
13
|
-
push?: Omit<SyncPushOnceOptions, 'clientId' | 'actorId'>;
|
|
14
|
-
pull: Omit<SyncPullOnceOptions, 'clientId' | 'actorId'>;
|
|
15
|
-
}
|
|
16
|
-
export interface PushThenPullResult<DB extends SyncClientDb> {
|
|
17
|
-
enqueueResult?: {
|
|
18
|
-
id: string;
|
|
19
|
-
clientCommitId: string;
|
|
20
|
-
};
|
|
21
|
-
pushResult: SyncPushOnceResult;
|
|
22
|
-
pullResult: SyncPullResponse;
|
|
23
|
-
client: ScenarioFlowClient<DB>;
|
|
24
|
-
}
|
|
25
|
-
export interface ScenarioFlow<DB extends SyncClientDb> {
|
|
26
|
-
client: ScenarioFlowClient<DB>;
|
|
27
|
-
enqueue: (args: Parameters<typeof enqueueOutboxCommit<DB>>[1]) => Promise<{
|
|
28
|
-
id: string;
|
|
29
|
-
clientCommitId: string;
|
|
30
|
-
}>;
|
|
31
|
-
push: (options?: Omit<SyncPushOnceOptions, 'clientId' | 'actorId'>) => Promise<SyncPushOnceResult>;
|
|
32
|
-
pull: (options: Omit<SyncPullOnceOptions, 'clientId' | 'actorId'>) => Promise<SyncPullResponse>;
|
|
33
|
-
sync: (options: Omit<SyncOnceOptions, 'clientId' | 'actorId'>) => Promise<SyncOnceResult>;
|
|
34
|
-
transportSync: (request: Omit<SyncCombinedRequest, 'clientId'>) => Promise<SyncCombinedResponse>;
|
|
35
|
-
pushThenPull: (options: PushThenPullOptions<DB>) => Promise<PushThenPullResult<DB>>;
|
|
36
|
-
}
|
|
37
|
-
export declare function createScenarioFlow<DB extends SyncClientDb>(client: ScenarioFlowClient<DB>): ScenarioFlow<DB>;
|
|
38
|
-
export declare function runPushPullCycle<DB extends SyncClientDb>(client: ScenarioFlowClient<DB>, options: PushThenPullOptions<DB>): Promise<PushThenPullResult<DB>>;
|
|
39
|
-
//# sourceMappingURL=scenario-flow.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"scenario-flow.d.ts","sourceRoot":"","sources":["../src/scenario-flow.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,uBAAuB,EAC5B,mBAAmB,EACnB,KAAK,YAAY,EACjB,KAAK,eAAe,EACpB,KAAK,cAAc,EACnB,KAAK,mBAAmB,EACxB,KAAK,gBAAgB,EACrB,KAAK,mBAAmB,EACxB,KAAK,kBAAkB,EAIxB,MAAM,kBAAkB,CAAC;AAC1B,OAAO,KAAK,EACV,mBAAmB,EACnB,oBAAoB,EACpB,aAAa,EACd,MAAM,gBAAgB,CAAC;AACxB,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAErC,MAAM,WAAW,kBAAkB,CAAC,EAAE,SAAS,YAAY;IACzD,EAAE,EAAE,MAAM,CAAC,EAAE,CAAC,CAAC;IACf,SAAS,EAAE,aAAa,CAAC;IACzB,QAAQ,EAAE,uBAAuB,CAAC,EAAE,CAAC,CAAC;IACtC,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,mBAAmB,CAAC,EAAE,SAAS,YAAY;IAC1D,OAAO,CAAC,EAAE,UAAU,CAAC,OAAO,mBAAmB,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IACxD,IAAI,CAAC,EAAE,IAAI,CAAC,mBAAmB,EAAE,UAAU,GAAG,SAAS,CAAC,CAAC;IACzD,IAAI,EAAE,IAAI,CAAC,mBAAmB,EAAE,UAAU,GAAG,SAAS,CAAC,CAAC;CACzD;AAED,MAAM,WAAW,kBAAkB,CAAC,EAAE,SAAS,YAAY;IACzD,aAAa,CAAC,EAAE;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,cAAc,EAAE,MAAM,CAAA;KAAE,CAAC;IACvD,UAAU,EAAE,kBAAkB,CAAC;IAC/B,UAAU,EAAE,gBAAgB,CAAC;IAC7B,MAAM,EAAE,kBAAkB,CAAC,EAAE,CAAC,CAAC;CAChC;AAED,MAAM,WAAW,YAAY,CAAC,EAAE,SAAS,YAAY;IACnD,MAAM,EAAE,kBAAkB,CAAC,EAAE,CAAC,CAAC;IAC/B,OAAO,EAAE,CACP,IAAI,EAAE,UAAU,CAAC,OAAO,mBAAmB,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,KAChD,OAAO,CAAC;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,cAAc,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IACrD,IAAI,EAAE,CACJ,OAAO,CAAC,EAAE,IAAI,CAAC,mBAAmB,EAAE,UAAU,GAAG,SAAS,CAAC,KACxD,OAAO,CAAC,kBAAkB,CAAC,CAAC;IACjC,IAAI,EAAE,CACJ,OAAO,EAAE,IAAI,CAAC,mBAAmB,EAAE,UAAU,GAAG,SAAS,CAAC,KACvD,OAAO,CAAC,gBAAgB,CAAC,CAAC;IAC/B,IAAI,EAAE,CACJ,OAAO,EAAE,IAAI,CAAC,eAAe,EAAE,UAAU,GAAG,SAAS,CAAC,KACnD,OAAO,CAAC,cAAc,CAAC,CAAC;IAC7B,aAAa,EAAE,CACb,OAAO,EAAE,IAAI,CAAC,mBAAmB,EAAE,UAAU,CAAC,KAC3C,OAAO,CAAC,oBAAoB,CAAC,CAAC;IACnC,YAAY,EAAE,CACZ,OAAO,EAAE,mBAAmB,CAAC,EAAE,CAAC,KAC7B,OAAO,CAAC,kBAAkB,CAAC,EAAE,CAAC,CAAC,CAAC;CACtC;AAgBD,wBAAgB,kBAAkB,CAAC,EAAE,SAAS,YAAY,EACxD,MAAM,EAAE,kBAAkB,CAAC,EAAE,CAAC,GAC7B,YAAY,CAAC,EAAE,CAAC,CAuDlB;AAED,wBAAsB,gBAAgB,CAAC,EAAE,SAAS,YAAY,EAC5D,MAAM,EAAE,kBAAkB,CAAC,EAAE,CAAC,EAC9B,OAAO,EAAE,mBAAmB,CAAC,EAAE,CAAC,GAC/B,OAAO,CAAC,kBAAkB,CAAC,EAAE,CAAC,CAAC,CAEjC"}
|
package/dist/scenario-flow.js
DELETED
|
@@ -1,41 +0,0 @@
|
|
|
1
|
-
import { enqueueOutboxCommit, syncOnce, syncPullOnce, syncPushOnce, } from '@syncular/client';
|
|
2
|
-
function withClientIdentity(values, client) {
|
|
3
|
-
return {
|
|
4
|
-
...values,
|
|
5
|
-
clientId: client.clientId,
|
|
6
|
-
...(client.actorId ? { actorId: client.actorId } : {}),
|
|
7
|
-
};
|
|
8
|
-
}
|
|
9
|
-
export function createScenarioFlow(client) {
|
|
10
|
-
const enqueue = (args) => enqueueOutboxCommit(client.db, args);
|
|
11
|
-
const push = (options) => syncPushOnce(client.db, client.transport, withClientIdentity(options ?? {}, client));
|
|
12
|
-
const pull = (options) => syncPullOnce(client.db, client.transport, client.handlers, withClientIdentity(options, client));
|
|
13
|
-
const sync = (options) => syncOnce(client.db, client.transport, client.handlers, withClientIdentity(options, client));
|
|
14
|
-
const transportSync = (request) => client.transport.sync({ clientId: client.clientId, ...request });
|
|
15
|
-
const pushThenPull = async (options) => {
|
|
16
|
-
const enqueueResult = options.enqueue
|
|
17
|
-
? await enqueueOutboxCommit(client.db, options.enqueue)
|
|
18
|
-
: undefined;
|
|
19
|
-
const pushResult = await push(options.push);
|
|
20
|
-
const pullResult = await pull(options.pull);
|
|
21
|
-
return {
|
|
22
|
-
enqueueResult,
|
|
23
|
-
pushResult,
|
|
24
|
-
pullResult,
|
|
25
|
-
client,
|
|
26
|
-
};
|
|
27
|
-
};
|
|
28
|
-
return {
|
|
29
|
-
client,
|
|
30
|
-
enqueue,
|
|
31
|
-
push,
|
|
32
|
-
pull,
|
|
33
|
-
sync,
|
|
34
|
-
transportSync,
|
|
35
|
-
pushThenPull,
|
|
36
|
-
};
|
|
37
|
-
}
|
|
38
|
-
export async function runPushPullCycle(client, options) {
|
|
39
|
-
return createScenarioFlow(client).pushThenPull(options);
|
|
40
|
-
}
|
|
41
|
-
//# sourceMappingURL=scenario-flow.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"scenario-flow.js","sourceRoot":"","sources":["../src/scenario-flow.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,mBAAmB,EAQnB,QAAQ,EACR,YAAY,EACZ,YAAY,GACb,MAAM,kBAAkB,CAAC;AAmD1B,SAAS,kBAAkB,CAIzB,MAAS,EACT,MAA8B,EACc;IAC5C,OAAO;QACL,GAAG,MAAM;QACT,QAAQ,EAAE,MAAM,CAAC,QAAQ;QACzB,GAAG,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,MAAM,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;KACvD,CAAC;AAAA,CACH;AAED,MAAM,UAAU,kBAAkB,CAChC,MAA8B,EACZ;IAClB,MAAM,OAAO,GAAgC,CAAC,IAAI,EAAE,EAAE,CACpD,mBAAmB,CAAC,MAAM,CAAC,EAAE,EAAE,IAAI,CAAC,CAAC;IAEvC,MAAM,IAAI,GAA6B,CAAC,OAAO,EAAE,EAAE,CACjD,YAAY,CACV,MAAM,CAAC,EAAE,EACT,MAAM,CAAC,SAAS,EAChB,kBAAkB,CAAC,OAAO,IAAI,EAAE,EAAE,MAAM,CAAC,CAC1C,CAAC;IAEJ,MAAM,IAAI,GAA6B,CAAC,OAAO,EAAE,EAAE,CACjD,YAAY,CACV,MAAM,CAAC,EAAE,EACT,MAAM,CAAC,SAAS,EAChB,MAAM,CAAC,QAAQ,EACf,kBAAkB,CAAC,OAAO,EAAE,MAAM,CAAC,CACpC,CAAC;IAEJ,MAAM,IAAI,GAA6B,CAAC,OAAO,EAAE,EAAE,CACjD,QAAQ,CACN,MAAM,CAAC,EAAE,EACT,MAAM,CAAC,SAAS,EAChB,MAAM,CAAC,QAAQ,EACf,kBAAkB,CAAC,OAAO,EAAE,MAAM,CAAC,CACpC,CAAC;IAEJ,MAAM,aAAa,GAAsC,CAAC,OAAO,EAAE,EAAE,CACnE,MAAM,CAAC,SAAS,CAAC,IAAI,CAAC,EAAE,QAAQ,EAAE,MAAM,CAAC,QAAQ,EAAE,GAAG,OAAO,EAAE,CAAC,CAAC;IAEnE,MAAM,YAAY,GAAqC,KAAK,EAAE,OAAO,EAAE,EAAE,CAAC;QACxE,MAAM,aAAa,GAAG,OAAO,CAAC,OAAO;YACnC,CAAC,CAAC,MAAM,mBAAmB,CAAC,MAAM,CAAC,EAAE,EAAE,OAAO,CAAC,OAAO,CAAC;YACvD,CAAC,CAAC,SAAS,CAAC;QAEd,MAAM,UAAU,GAAG,MAAM,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;QAC5C,MAAM,UAAU,GAAG,MAAM,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;QAE5C,OAAO;YACL,aAAa;YACb,UAAU;YACV,UAAU;YACV,MAAM;SACP,CAAC;IAAA,CACH,CAAC;IAEF,OAAO;QACL,MAAM;QACN,OAAO;QACP,IAAI;QACJ,IAAI;QACJ,IAAI;QACJ,aAAa;QACb,YAAY;KACb,CAAC;AAAA,CACH;AAED,MAAM,CAAC,KAAK,UAAU,gBAAgB,CACpC,MAA8B,EAC9B,OAAgC,EACC;IACjC,OAAO,kBAAkB,CAAC,MAAM,CAAC,CAAC,YAAY,CAAC,OAAO,CAAC,CAAC;AAAA,CACzD"}
|
package/src/assertions.ts
DELETED
|
@@ -1,432 +0,0 @@
|
|
|
1
|
-
import { isDeepStrictEqual } from 'node:util';
|
|
2
|
-
import type { OutboxCommitStatus, SyncClientDb } from '@syncular/client';
|
|
3
|
-
import type { SyncCoreDb } from '@syncular/server';
|
|
4
|
-
import type { Kysely } from 'kysely';
|
|
5
|
-
|
|
6
|
-
function formatValue(value: unknown): string {
|
|
7
|
-
if (typeof value === 'string') {
|
|
8
|
-
return value;
|
|
9
|
-
}
|
|
10
|
-
|
|
11
|
-
try {
|
|
12
|
-
return JSON.stringify(value);
|
|
13
|
-
} catch {
|
|
14
|
-
return String(value);
|
|
15
|
-
}
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
function fail(message: string): never {
|
|
19
|
-
throw new Error(message);
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
function assertEqual(
|
|
23
|
-
actual: unknown,
|
|
24
|
-
expected: unknown,
|
|
25
|
-
message: string
|
|
26
|
-
): void {
|
|
27
|
-
if (!isDeepStrictEqual(actual, expected)) {
|
|
28
|
-
fail(
|
|
29
|
-
`${message} (expected=${formatValue(expected)} actual=${formatValue(actual)})`
|
|
30
|
-
);
|
|
31
|
-
}
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
function assertDefined<T>(
|
|
35
|
-
value: T | null | undefined,
|
|
36
|
-
message: string
|
|
37
|
-
): asserts value is T {
|
|
38
|
-
if (value == null) {
|
|
39
|
-
fail(message);
|
|
40
|
-
}
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
export async function outboxCount(db: Kysely<SyncClientDb>): Promise<number> {
|
|
44
|
-
const count = await db
|
|
45
|
-
.selectFrom('sync_outbox_commits')
|
|
46
|
-
.select(({ fn }) => fn.countAll().as('count'))
|
|
47
|
-
.executeTakeFirstOrThrow();
|
|
48
|
-
|
|
49
|
-
return Number(count.count);
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
export async function conflictCount(db: Kysely<SyncClientDb>): Promise<number> {
|
|
53
|
-
const count = await db
|
|
54
|
-
.selectFrom('sync_conflicts')
|
|
55
|
-
.where('resolved_at', 'is', null)
|
|
56
|
-
.select(({ fn }) => fn.countAll().as('count'))
|
|
57
|
-
.executeTakeFirstOrThrow();
|
|
58
|
-
|
|
59
|
-
return Number(count.count);
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
export async function serverCommitCount(
|
|
63
|
-
db: Kysely<SyncCoreDb>
|
|
64
|
-
): Promise<number> {
|
|
65
|
-
const count = await db
|
|
66
|
-
.selectFrom('sync_commits')
|
|
67
|
-
.select(({ fn }) => fn.countAll().as('count'))
|
|
68
|
-
.executeTakeFirstOrThrow();
|
|
69
|
-
|
|
70
|
-
return Number(count.count);
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
export async function serverChangeCount(
|
|
74
|
-
db: Kysely<SyncCoreDb>
|
|
75
|
-
): Promise<number> {
|
|
76
|
-
const count = await db
|
|
77
|
-
.selectFrom('sync_changes')
|
|
78
|
-
.select(({ fn }) => fn.countAll().as('count'))
|
|
79
|
-
.executeTakeFirstOrThrow();
|
|
80
|
-
|
|
81
|
-
return Number(count.count);
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
export async function assertOutboxEmpty(
|
|
85
|
-
db: Kysely<SyncClientDb>
|
|
86
|
-
): Promise<void> {
|
|
87
|
-
const count = await outboxCount(db);
|
|
88
|
-
assertEqual(count, 0, 'Outbox is not empty');
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
export async function assertOutboxHas(
|
|
92
|
-
db: Kysely<SyncClientDb>,
|
|
93
|
-
expectedCount: number
|
|
94
|
-
): Promise<void> {
|
|
95
|
-
const count = await outboxCount(db);
|
|
96
|
-
assertEqual(count, expectedCount, 'Unexpected outbox commit count');
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
export async function assertOutboxStatus(
|
|
100
|
-
db: Kysely<SyncClientDb>,
|
|
101
|
-
status: OutboxCommitStatus,
|
|
102
|
-
expectedCount: number
|
|
103
|
-
): Promise<void> {
|
|
104
|
-
const count = await db
|
|
105
|
-
.selectFrom('sync_outbox_commits')
|
|
106
|
-
.where('status', '=', status)
|
|
107
|
-
.select(({ fn }) => fn.countAll().as('count'))
|
|
108
|
-
.executeTakeFirstOrThrow();
|
|
109
|
-
|
|
110
|
-
assertEqual(
|
|
111
|
-
Number(count.count),
|
|
112
|
-
expectedCount,
|
|
113
|
-
`Unexpected outbox count for status=${status}`
|
|
114
|
-
);
|
|
115
|
-
}
|
|
116
|
-
|
|
117
|
-
export async function assertConflictCount(
|
|
118
|
-
db: Kysely<SyncClientDb>,
|
|
119
|
-
expectedCount: number
|
|
120
|
-
): Promise<void> {
|
|
121
|
-
const count = await conflictCount(db);
|
|
122
|
-
assertEqual(count, expectedCount, 'Unexpected unresolved conflict count');
|
|
123
|
-
}
|
|
124
|
-
|
|
125
|
-
export async function assertConflictExists(
|
|
126
|
-
db: Kysely<SyncClientDb>,
|
|
127
|
-
options: {
|
|
128
|
-
clientCommitId: string;
|
|
129
|
-
resultStatus?: 'conflict' | 'error';
|
|
130
|
-
resolved?: boolean;
|
|
131
|
-
}
|
|
132
|
-
): Promise<void> {
|
|
133
|
-
let query = db
|
|
134
|
-
.selectFrom('sync_conflicts')
|
|
135
|
-
.where('client_commit_id', '=', options.clientCommitId);
|
|
136
|
-
|
|
137
|
-
if (options.resultStatus) {
|
|
138
|
-
query = query.where('result_status', '=', options.resultStatus);
|
|
139
|
-
}
|
|
140
|
-
|
|
141
|
-
if (options.resolved !== undefined) {
|
|
142
|
-
query = options.resolved
|
|
143
|
-
? query.where('resolved_at', 'is not', null)
|
|
144
|
-
: query.where('resolved_at', 'is', null);
|
|
145
|
-
}
|
|
146
|
-
|
|
147
|
-
const conflict = await query.selectAll().executeTakeFirst();
|
|
148
|
-
assertDefined(
|
|
149
|
-
conflict,
|
|
150
|
-
`Expected conflict for client_commit_id=${options.clientCommitId}`
|
|
151
|
-
);
|
|
152
|
-
}
|
|
153
|
-
|
|
154
|
-
export async function assertRowExists<
|
|
155
|
-
DB extends SyncClientDb,
|
|
156
|
-
T extends keyof DB & string,
|
|
157
|
-
>(
|
|
158
|
-
db: Kysely<DB>,
|
|
159
|
-
table: T,
|
|
160
|
-
rowId: string,
|
|
161
|
-
expected?: Partial<DB[T]>,
|
|
162
|
-
idColumn = 'id'
|
|
163
|
-
): Promise<void> {
|
|
164
|
-
const row = await db
|
|
165
|
-
.selectFrom(table)
|
|
166
|
-
// @ts-expect-error - dynamic column name
|
|
167
|
-
.where(idColumn, '=', rowId)
|
|
168
|
-
.selectAll()
|
|
169
|
-
.executeTakeFirst();
|
|
170
|
-
|
|
171
|
-
assertDefined(row, `Expected row ${rowId} to exist in table ${table}`);
|
|
172
|
-
|
|
173
|
-
if (!expected) {
|
|
174
|
-
return;
|
|
175
|
-
}
|
|
176
|
-
|
|
177
|
-
const rowRecord = row as Record<string, unknown>;
|
|
178
|
-
for (const [key, value] of Object.entries(expected)) {
|
|
179
|
-
assertEqual(
|
|
180
|
-
rowRecord[key],
|
|
181
|
-
value,
|
|
182
|
-
`Unexpected value for ${table}.${key} (row ${rowId})`
|
|
183
|
-
);
|
|
184
|
-
}
|
|
185
|
-
}
|
|
186
|
-
|
|
187
|
-
export async function assertRowNotExists<
|
|
188
|
-
DB extends SyncClientDb,
|
|
189
|
-
T extends keyof DB & string,
|
|
190
|
-
>(db: Kysely<DB>, table: T, rowId: string, idColumn = 'id'): Promise<void> {
|
|
191
|
-
const row = await db
|
|
192
|
-
.selectFrom(table)
|
|
193
|
-
// @ts-expect-error - dynamic column name
|
|
194
|
-
.where(idColumn, '=', rowId)
|
|
195
|
-
.selectAll()
|
|
196
|
-
.executeTakeFirst();
|
|
197
|
-
|
|
198
|
-
if (row !== undefined) {
|
|
199
|
-
fail(`Expected row ${rowId} to be absent in table ${table}`);
|
|
200
|
-
}
|
|
201
|
-
}
|
|
202
|
-
|
|
203
|
-
export async function assertRowVersion<
|
|
204
|
-
DB extends SyncClientDb,
|
|
205
|
-
T extends keyof DB & string,
|
|
206
|
-
>(
|
|
207
|
-
db: Kysely<DB>,
|
|
208
|
-
table: T,
|
|
209
|
-
rowId: string,
|
|
210
|
-
expectedVersion: number,
|
|
211
|
-
versionColumn = 'server_version',
|
|
212
|
-
idColumn = 'id'
|
|
213
|
-
): Promise<void> {
|
|
214
|
-
const row = await db
|
|
215
|
-
.selectFrom(table)
|
|
216
|
-
// @ts-expect-error - dynamic column name
|
|
217
|
-
.where(idColumn, '=', rowId)
|
|
218
|
-
.select(versionColumn)
|
|
219
|
-
.executeTakeFirst();
|
|
220
|
-
|
|
221
|
-
assertDefined(row, `Expected row ${rowId} to exist in table ${table}`);
|
|
222
|
-
const rowRecord = row as Record<string, unknown>;
|
|
223
|
-
assertEqual(
|
|
224
|
-
rowRecord[versionColumn],
|
|
225
|
-
expectedVersion,
|
|
226
|
-
`Unexpected version for ${table}.${rowId}`
|
|
227
|
-
);
|
|
228
|
-
}
|
|
229
|
-
|
|
230
|
-
export async function assertSubscriptionCursor(
|
|
231
|
-
db: Kysely<SyncClientDb>,
|
|
232
|
-
subscriptionId: string,
|
|
233
|
-
expectedCursor: number,
|
|
234
|
-
stateId = 'default'
|
|
235
|
-
): Promise<void> {
|
|
236
|
-
const sub = await db
|
|
237
|
-
.selectFrom('sync_subscription_state')
|
|
238
|
-
.where('state_id', '=', stateId)
|
|
239
|
-
.where('subscription_id', '=', subscriptionId)
|
|
240
|
-
.select(['cursor'])
|
|
241
|
-
.executeTakeFirst();
|
|
242
|
-
|
|
243
|
-
assertDefined(
|
|
244
|
-
sub,
|
|
245
|
-
`Expected subscription state row for ${stateId}/${subscriptionId}`
|
|
246
|
-
);
|
|
247
|
-
assertEqual(
|
|
248
|
-
sub.cursor,
|
|
249
|
-
expectedCursor,
|
|
250
|
-
`Unexpected cursor for subscription ${subscriptionId}`
|
|
251
|
-
);
|
|
252
|
-
}
|
|
253
|
-
|
|
254
|
-
export async function assertSubscriptionStatus(
|
|
255
|
-
db: Kysely<SyncClientDb>,
|
|
256
|
-
subscriptionId: string,
|
|
257
|
-
expectedStatus: 'active' | 'revoked',
|
|
258
|
-
stateId = 'default'
|
|
259
|
-
): Promise<void> {
|
|
260
|
-
const sub = await db
|
|
261
|
-
.selectFrom('sync_subscription_state')
|
|
262
|
-
.where('state_id', '=', stateId)
|
|
263
|
-
.where('subscription_id', '=', subscriptionId)
|
|
264
|
-
.select(['status'])
|
|
265
|
-
.executeTakeFirst();
|
|
266
|
-
|
|
267
|
-
assertDefined(
|
|
268
|
-
sub,
|
|
269
|
-
`Expected subscription state row for ${stateId}/${subscriptionId}`
|
|
270
|
-
);
|
|
271
|
-
assertEqual(
|
|
272
|
-
sub.status,
|
|
273
|
-
expectedStatus,
|
|
274
|
-
`Unexpected status for subscription ${subscriptionId}`
|
|
275
|
-
);
|
|
276
|
-
}
|
|
277
|
-
|
|
278
|
-
export async function assertServerCommitCount(
|
|
279
|
-
db: Kysely<SyncCoreDb>,
|
|
280
|
-
expectedCount: number
|
|
281
|
-
): Promise<void> {
|
|
282
|
-
const count = await serverCommitCount(db);
|
|
283
|
-
assertEqual(count, expectedCount, 'Unexpected server commit count');
|
|
284
|
-
}
|
|
285
|
-
|
|
286
|
-
export async function assertServerChangeCount(
|
|
287
|
-
db: Kysely<SyncCoreDb>,
|
|
288
|
-
expectedCount: number
|
|
289
|
-
): Promise<void> {
|
|
290
|
-
const count = await serverChangeCount(db);
|
|
291
|
-
assertEqual(count, expectedCount, 'Unexpected server change count');
|
|
292
|
-
}
|
|
293
|
-
|
|
294
|
-
export async function assertServerChangeExists(
|
|
295
|
-
db: Kysely<SyncCoreDb>,
|
|
296
|
-
options: {
|
|
297
|
-
table: string;
|
|
298
|
-
rowId: string;
|
|
299
|
-
op?: 'upsert' | 'delete';
|
|
300
|
-
commitSeq?: number;
|
|
301
|
-
}
|
|
302
|
-
): Promise<void> {
|
|
303
|
-
let query = db
|
|
304
|
-
.selectFrom('sync_changes')
|
|
305
|
-
.where('table', '=', options.table)
|
|
306
|
-
.where('row_id', '=', options.rowId);
|
|
307
|
-
|
|
308
|
-
if (options.op) {
|
|
309
|
-
query = query.where('op', '=', options.op);
|
|
310
|
-
}
|
|
311
|
-
|
|
312
|
-
if (options.commitSeq) {
|
|
313
|
-
query = query.where('commit_seq', '=', options.commitSeq);
|
|
314
|
-
}
|
|
315
|
-
|
|
316
|
-
const change = await query.selectAll().executeTakeFirst();
|
|
317
|
-
assertDefined(
|
|
318
|
-
change,
|
|
319
|
-
`Expected server change for table=${options.table} rowId=${options.rowId}`
|
|
320
|
-
);
|
|
321
|
-
}
|
|
322
|
-
|
|
323
|
-
export async function assertServerClientCursor(
|
|
324
|
-
db: Kysely<SyncCoreDb>,
|
|
325
|
-
clientId: string,
|
|
326
|
-
expectedCursor: number
|
|
327
|
-
): Promise<void> {
|
|
328
|
-
const cursor = await db
|
|
329
|
-
.selectFrom('sync_client_cursors')
|
|
330
|
-
.where('client_id', '=', clientId)
|
|
331
|
-
.select(['cursor'])
|
|
332
|
-
.executeTakeFirst();
|
|
333
|
-
|
|
334
|
-
assertDefined(cursor, `Expected sync_client_cursors row for ${clientId}`);
|
|
335
|
-
assertEqual(
|
|
336
|
-
cursor.cursor,
|
|
337
|
-
expectedCursor,
|
|
338
|
-
`Unexpected cursor for ${clientId}`
|
|
339
|
-
);
|
|
340
|
-
}
|
|
341
|
-
|
|
342
|
-
async function waitFor(
|
|
343
|
-
condition: () => Promise<boolean>,
|
|
344
|
-
options?: {
|
|
345
|
-
timeoutMs?: number;
|
|
346
|
-
intervalMs?: number;
|
|
347
|
-
message?: string;
|
|
348
|
-
}
|
|
349
|
-
): Promise<void> {
|
|
350
|
-
const timeoutMs = options?.timeoutMs ?? 5000;
|
|
351
|
-
const intervalMs = options?.intervalMs ?? 50;
|
|
352
|
-
const message = options?.message ?? 'Condition not met within timeout';
|
|
353
|
-
|
|
354
|
-
const startTime = Date.now();
|
|
355
|
-
|
|
356
|
-
while (Date.now() - startTime < timeoutMs) {
|
|
357
|
-
if (await condition()) {
|
|
358
|
-
return;
|
|
359
|
-
}
|
|
360
|
-
await new Promise((resolve) => setTimeout(resolve, intervalMs));
|
|
361
|
-
}
|
|
362
|
-
|
|
363
|
-
fail(message);
|
|
364
|
-
}
|
|
365
|
-
|
|
366
|
-
export async function waitForOutboxEmpty(
|
|
367
|
-
db: Kysely<SyncClientDb>,
|
|
368
|
-
timeoutMs = 5000
|
|
369
|
-
): Promise<void> {
|
|
370
|
-
await waitFor(
|
|
371
|
-
async () => {
|
|
372
|
-
const count = await outboxCount(db);
|
|
373
|
-
return count === 0;
|
|
374
|
-
},
|
|
375
|
-
{ timeoutMs, message: 'Outbox not empty within timeout' }
|
|
376
|
-
);
|
|
377
|
-
}
|
|
378
|
-
|
|
379
|
-
export async function waitForAckedCommits(
|
|
380
|
-
db: Kysely<SyncClientDb>,
|
|
381
|
-
expectedCount: number,
|
|
382
|
-
timeoutMs = 5000
|
|
383
|
-
): Promise<void> {
|
|
384
|
-
await waitFor(
|
|
385
|
-
async () => {
|
|
386
|
-
const count = await db
|
|
387
|
-
.selectFrom('sync_outbox_commits')
|
|
388
|
-
.where('status', '=', 'acked')
|
|
389
|
-
.select(({ fn }) => fn.countAll().as('count'))
|
|
390
|
-
.executeTakeFirstOrThrow();
|
|
391
|
-
return Number(count.count) >= expectedCount;
|
|
392
|
-
},
|
|
393
|
-
{
|
|
394
|
-
timeoutMs,
|
|
395
|
-
message: `Expected ${expectedCount} acked commits within timeout`,
|
|
396
|
-
}
|
|
397
|
-
);
|
|
398
|
-
}
|
|
399
|
-
|
|
400
|
-
export const assertOutbox = {
|
|
401
|
-
empty: assertOutboxEmpty,
|
|
402
|
-
count: assertOutboxHas,
|
|
403
|
-
status: assertOutboxStatus,
|
|
404
|
-
};
|
|
405
|
-
|
|
406
|
-
export const assertConflicts = {
|
|
407
|
-
count: assertConflictCount,
|
|
408
|
-
exists: assertConflictExists,
|
|
409
|
-
};
|
|
410
|
-
|
|
411
|
-
export const assertRows = {
|
|
412
|
-
exists: assertRowExists,
|
|
413
|
-
missing: assertRowNotExists,
|
|
414
|
-
version: assertRowVersion,
|
|
415
|
-
};
|
|
416
|
-
|
|
417
|
-
export const assertServer = {
|
|
418
|
-
commits: assertServerCommitCount,
|
|
419
|
-
changes: assertServerChangeCount,
|
|
420
|
-
changeExists: assertServerChangeExists,
|
|
421
|
-
clientCursor: assertServerClientCursor,
|
|
422
|
-
};
|
|
423
|
-
|
|
424
|
-
export const assertSubscription = {
|
|
425
|
-
cursor: assertSubscriptionCursor,
|
|
426
|
-
status: assertSubscriptionStatus,
|
|
427
|
-
};
|
|
428
|
-
|
|
429
|
-
export const waitForSync = {
|
|
430
|
-
outboxEmpty: waitForOutboxEmpty,
|
|
431
|
-
ackedCommits: waitForAckedCommits,
|
|
432
|
-
};
|