@ddd-ts-kit/testing 0.10.0 → 0.12.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 +21 -0
- package/dist/contracts/cache-purger-contract.d.ts +19 -0
- package/dist/contracts/cache-purger-contract.d.ts.map +1 -0
- package/dist/contracts/cache-purger-contract.js +69 -0
- package/dist/contracts/cache-purger-contract.js.map +1 -0
- package/dist/contracts/job-store/a-job.d.ts +24 -0
- package/dist/contracts/job-store/a-job.d.ts.map +1 -0
- package/dist/contracts/job-store/a-job.js +28 -0
- package/dist/contracts/job-store/a-job.js.map +1 -0
- package/dist/contracts/job-store/claim-suite.d.ts +15 -0
- package/dist/contracts/job-store/claim-suite.d.ts.map +1 -0
- package/dist/contracts/job-store/claim-suite.js +126 -0
- package/dist/contracts/job-store/claim-suite.js.map +1 -0
- package/dist/contracts/job-store/job-fixtures.d.ts +5 -0
- package/dist/contracts/job-store/job-fixtures.d.ts.map +1 -0
- package/dist/contracts/job-store/job-fixtures.js +5 -0
- package/dist/contracts/job-store/job-fixtures.js.map +1 -0
- package/dist/contracts/job-store/job-store-under-contract.d.ts +61 -0
- package/dist/contracts/job-store/job-store-under-contract.d.ts.map +1 -0
- package/dist/contracts/job-store/job-store-under-contract.js +2 -0
- package/dist/contracts/job-store/job-store-under-contract.js.map +1 -0
- package/dist/contracts/job-store/keep-suite.d.ts +11 -0
- package/dist/contracts/job-store/keep-suite.d.ts.map +1 -0
- package/dist/contracts/job-store/keep-suite.js +55 -0
- package/dist/contracts/job-store/keep-suite.js.map +1 -0
- package/dist/contracts/job-store/later.d.ts +3 -0
- package/dist/contracts/job-store/later.d.ts.map +1 -0
- package/dist/contracts/job-store/later.js +6 -0
- package/dist/contracts/job-store/later.js.map +1 -0
- package/dist/contracts/job-store/report-suite.d.ts +12 -0
- package/dist/contracts/job-store/report-suite.d.ts.map +1 -0
- package/dist/contracts/job-store/report-suite.js +82 -0
- package/dist/contracts/job-store/report-suite.js.map +1 -0
- package/dist/contracts/job-store/transaction-suite.d.ts +23 -0
- package/dist/contracts/job-store/transaction-suite.d.ts.map +1 -0
- package/dist/contracts/job-store/transaction-suite.js +68 -0
- package/dist/contracts/job-store/transaction-suite.js.map +1 -0
- package/dist/contracts/job-store-contract.d.ts +24 -0
- package/dist/contracts/job-store-contract.d.ts.map +1 -0
- package/dist/contracts/job-store-contract.js +22 -0
- package/dist/contracts/job-store-contract.js.map +1 -0
- package/dist/contracts/process-store-contract.d.ts +28 -0
- package/dist/contracts/process-store-contract.d.ts.map +1 -0
- package/dist/contracts/process-store-contract.js +81 -0
- package/dist/contracts/process-store-contract.js.map +1 -0
- package/dist/contracts.d.ts +4 -0
- package/dist/contracts.d.ts.map +1 -1
- package/dist/contracts.js +3 -0
- package/dist/contracts.js.map +1 -1
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -1
- package/dist/processes/command-matcher.d.ts +8 -0
- package/dist/processes/command-matcher.d.ts.map +1 -0
- package/dist/processes/command-matcher.js +2 -0
- package/dist/processes/command-matcher.js.map +1 -0
- package/dist/processes/given-process.d.ts +18 -0
- package/dist/processes/given-process.d.ts.map +1 -0
- package/dist/processes/given-process.js +17 -0
- package/dist/processes/given-process.js.map +1 -0
- package/dist/processes/process-outcome.d.ts +20 -0
- package/dist/processes/process-outcome.d.ts.map +1 -0
- package/dist/processes/process-outcome.js +67 -0
- package/dist/processes/process-outcome.js.map +1 -0
- package/dist/scenarios/event-mismatches.d.ts.map +1 -1
- package/dist/scenarios/event-mismatches.js +1 -18
- package/dist/scenarios/event-mismatches.js.map +1 -1
- package/dist/scenarios/subset-differences.d.ts +3 -0
- package/dist/scenarios/subset-differences.d.ts.map +1 -0
- package/dist/scenarios/subset-differences.js +21 -0
- package/dist/scenarios/subset-differences.js.map +1 -0
- package/package.json +6 -5
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
import { ContractSuite } from '../contract-suite.js';
|
|
2
|
+
import { aJob } from './a-job.js';
|
|
3
|
+
import { LEASE_MS, NOW, QUEUE } from './job-fixtures.js';
|
|
4
|
+
import { later } from './later.js';
|
|
5
|
+
const FIRST = { id: 'job-1', attempt: 1 };
|
|
6
|
+
/** What a worker reports of an attempt: progress and checkpoint, success, failure, release. Only the attempt that holds the job is heard. */
|
|
7
|
+
export class ReportSuite extends ContractSuite {
|
|
8
|
+
tests() {
|
|
9
|
+
this.progressAndOutcomes();
|
|
10
|
+
this.deadAndRevived();
|
|
11
|
+
this.releasedAndStale();
|
|
12
|
+
}
|
|
13
|
+
progressAndOutcomes() {
|
|
14
|
+
this.it('shows the progress and hands the checkpoint to the next attempt', async () => {
|
|
15
|
+
await this.claimFirst();
|
|
16
|
+
this.expect(await this.subject.update(FIRST, { progress: { done: 40, total: 120 } }, later(LEASE_MS))).toBe(true);
|
|
17
|
+
this.expect(await this.subject.update(FIRST, { checkpoint: { after: 'c-1' } }, later(LEASE_MS))).toBe(true);
|
|
18
|
+
this.expect((await this.subject.find('job-1'))?.progress).toEqual({ done: 40, total: 120 });
|
|
19
|
+
const [resumed] = await this.claim(later(LEASE_MS));
|
|
20
|
+
this.expect([resumed?.attempt, resumed?.checkpoint]).toEqual([2, { after: 'c-1' }]);
|
|
21
|
+
});
|
|
22
|
+
this.it('finishes a job that succeeded: never handed out again', async () => {
|
|
23
|
+
await this.claimFirst();
|
|
24
|
+
this.expect(await this.subject.complete(FIRST, later(5_000))).toBe(true);
|
|
25
|
+
const job = await this.subject.find('job-1');
|
|
26
|
+
this.expect([job?.status, job?.finishedAt]).toEqual(['succeeded', later(5_000)]);
|
|
27
|
+
this.expect(await this.claim(later(LEASE_MS * 10))).toEqual([]);
|
|
28
|
+
this.expect(await this.subject.stats(QUEUE)).toEqual({ waiting: 0, running: 0, dead: 0 });
|
|
29
|
+
});
|
|
30
|
+
this.it('retries a failed job at its instant, not before, with its error code', async () => {
|
|
31
|
+
await this.claimFirst();
|
|
32
|
+
this.expect(await this.subject.fail(FIRST, { errorCode: 'LEDGER_DOWN', retryAt: later(5_000), at: NOW })).toBe(true);
|
|
33
|
+
const waiting = await this.subject.find('job-1');
|
|
34
|
+
this.expect([waiting?.status, waiting?.lastErrorCode, waiting?.runAt]).toEqual([
|
|
35
|
+
'waiting',
|
|
36
|
+
'LEDGER_DOWN',
|
|
37
|
+
later(5_000),
|
|
38
|
+
]);
|
|
39
|
+
this.expect(await this.claim(later(4_999))).toEqual([]);
|
|
40
|
+
this.expect((await this.claim(later(5_000)))[0]?.attempt).toBe(2);
|
|
41
|
+
});
|
|
42
|
+
}
|
|
43
|
+
deadAndRevived() {
|
|
44
|
+
this.it('sets a dead job aside, then revives it with a fresh attempt budget', async () => {
|
|
45
|
+
await this.claimFirst();
|
|
46
|
+
await this.subject.fail(FIRST, { errorCode: 'LEDGER_DOWN', retryAt: null, at: NOW });
|
|
47
|
+
this.expect((await this.subject.find('job-1'))?.status).toBe('dead');
|
|
48
|
+
this.expect(await this.subject.stats(QUEUE)).toEqual({ waiting: 0, running: 0, dead: 1 });
|
|
49
|
+
this.expect(await this.claim(later(LEASE_MS * 10))).toEqual([]);
|
|
50
|
+
this.expect(await this.subject.retryDead([], later(1_000))).toBe(0);
|
|
51
|
+
this.expect(await this.subject.retryDead(['job-1', 'unknown'], later(1_000))).toBe(1);
|
|
52
|
+
const [revived] = await this.claim(later(1_000));
|
|
53
|
+
this.expect(revived?.attempt).toBe(1);
|
|
54
|
+
});
|
|
55
|
+
}
|
|
56
|
+
releasedAndStale() {
|
|
57
|
+
this.it('takes a released job back without counting the attempt', async () => {
|
|
58
|
+
await this.claimFirst();
|
|
59
|
+
this.expect(await this.subject.release(FIRST, NOW)).toBe(true);
|
|
60
|
+
this.expect((await this.subject.find('job-1'))?.status).toBe('waiting');
|
|
61
|
+
this.expect((await this.claim(NOW))[0]?.attempt).toBe(1);
|
|
62
|
+
});
|
|
63
|
+
this.it('ignores an attempt whose lease was taken over', async () => {
|
|
64
|
+
await this.claimFirst();
|
|
65
|
+
await this.claim(later(LEASE_MS));
|
|
66
|
+
this.expect(await this.subject.update(FIRST, { progress: { done: 1 } }, later(LEASE_MS * 2))).toBe(false);
|
|
67
|
+
this.expect(await this.subject.complete(FIRST, later(LEASE_MS))).toBe(false);
|
|
68
|
+
this.expect(await this.subject.fail(FIRST, { errorCode: 'X', retryAt: null, at: NOW })).toBe(false);
|
|
69
|
+
this.expect(await this.subject.release(FIRST, NOW)).toBe(false);
|
|
70
|
+
this.expect((await this.subject.find('job-1'))?.status).toBe('running');
|
|
71
|
+
this.expect(await this.subject.complete({ id: 'job-1', attempt: 2 }, later(LEASE_MS))).toBe(true);
|
|
72
|
+
});
|
|
73
|
+
}
|
|
74
|
+
async claimFirst() {
|
|
75
|
+
await this.subject.add(aJob('job-1'));
|
|
76
|
+
await this.claim(NOW);
|
|
77
|
+
}
|
|
78
|
+
claim(now) {
|
|
79
|
+
return this.subject.claim({ queue: QUEUE, limit: 10, now, leaseMs: LEASE_MS });
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
//# sourceMappingURL=report-suite.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"report-suite.js","sourceRoot":"","sources":["../../../src/contracts/job-store/report-suite.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { ContractSuite } from '../contract-suite.js';
|
|
2
|
+
import type { JobStoreUnderContract } from './job-store-under-contract.js';
|
|
3
|
+
/** The unit of work the store is used in, as the kernel port states it. */
|
|
4
|
+
export interface UnitOfWorkOfTheStore {
|
|
5
|
+
run<T>(work: () => Promise<T>): Promise<T>;
|
|
6
|
+
}
|
|
7
|
+
interface StoreInUnitOfWork {
|
|
8
|
+
readonly store: JobStoreUnderContract;
|
|
9
|
+
readonly unitOfWork: UnitOfWorkOfTheStore;
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* A job added inside a unit of work exists if and only if the unit of work committed; a job
|
|
13
|
+
* cancelled or revived inside one is cancelled or revived if and only if it committed.
|
|
14
|
+
*/
|
|
15
|
+
export declare class TransactionSuite extends ContractSuite<StoreInUnitOfWork> {
|
|
16
|
+
protected tests(): void;
|
|
17
|
+
private adds;
|
|
18
|
+
private cancels;
|
|
19
|
+
private revives;
|
|
20
|
+
private claimed;
|
|
21
|
+
}
|
|
22
|
+
export {};
|
|
23
|
+
//# sourceMappingURL=transaction-suite.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"transaction-suite.d.ts","sourceRoot":"","sources":["../../../src/contracts/job-store/transaction-suite.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AAIrD,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,+BAA+B,CAAC;AAE3E,2EAA2E;AAC3E,MAAM,WAAW,oBAAoB;IACnC,GAAG,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC;CAC5C;AAED,UAAU,iBAAiB;IACzB,QAAQ,CAAC,KAAK,EAAE,qBAAqB,CAAC;IACtC,QAAQ,CAAC,UAAU,EAAE,oBAAoB,CAAC;CAC3C;AAID;;;GAGG;AACH,qBAAa,gBAAiB,SAAQ,aAAa,CAAC,iBAAiB,CAAC;IACpE,SAAS,CAAC,KAAK,IAAI,IAAI,CAItB;IAED,OAAO,CAAC,IAAI;IAqBZ,OAAO,CAAC,OAAO;IAyBf,OAAO,CAAC,OAAO;YAmBD,OAAO;CAKtB"}
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import { ContractSuite } from '../contract-suite.js';
|
|
2
|
+
import { failureOf } from '../failure-of.js';
|
|
3
|
+
import { aJob } from './a-job.js';
|
|
4
|
+
import { LEASE_MS, NOW, QUEUE } from './job-fixtures.js';
|
|
5
|
+
class CommandRefused extends Error {
|
|
6
|
+
}
|
|
7
|
+
/**
|
|
8
|
+
* A job added inside a unit of work exists if and only if the unit of work committed; a job
|
|
9
|
+
* cancelled or revived inside one is cancelled or revived if and only if it committed.
|
|
10
|
+
*/
|
|
11
|
+
export class TransactionSuite extends ContractSuite {
|
|
12
|
+
tests() {
|
|
13
|
+
this.adds();
|
|
14
|
+
this.cancels();
|
|
15
|
+
this.revives();
|
|
16
|
+
}
|
|
17
|
+
adds() {
|
|
18
|
+
this.it('leaves no job behind a unit of work that rolled back', async () => {
|
|
19
|
+
const failure = await failureOf(() => this.subject.unitOfWork.run(async () => {
|
|
20
|
+
await this.subject.store.add(aJob('job-1'));
|
|
21
|
+
throw new CommandRefused();
|
|
22
|
+
}));
|
|
23
|
+
this.expect(failure instanceof CommandRefused).toBe(true);
|
|
24
|
+
this.expect(await this.subject.store.find('job-1')).toBe(undefined);
|
|
25
|
+
this.expect(await this.claimed()).toEqual([]);
|
|
26
|
+
});
|
|
27
|
+
this.it('keeps the job of a unit of work that committed', async () => {
|
|
28
|
+
await this.subject.unitOfWork.run(() => this.subject.store.add(aJob('job-1')));
|
|
29
|
+
this.expect(await this.claimed()).toEqual(['job-1']);
|
|
30
|
+
});
|
|
31
|
+
}
|
|
32
|
+
cancels() {
|
|
33
|
+
this.it('leaves the job waiting when the unit of work that cancelled it rolled back', async () => {
|
|
34
|
+
await this.subject.store.add(aJob('job-1'));
|
|
35
|
+
await failureOf(() => this.subject.unitOfWork.run(async () => {
|
|
36
|
+
this.expect(await this.subject.store.cancel('job-1', NOW)).toBe(true);
|
|
37
|
+
throw new CommandRefused();
|
|
38
|
+
}));
|
|
39
|
+
this.expect((await this.subject.store.find('job-1'))?.status).toBe('waiting');
|
|
40
|
+
this.expect(await this.claimed()).toEqual(['job-1']);
|
|
41
|
+
});
|
|
42
|
+
this.it('cancels the job once the unit of work committed', async () => {
|
|
43
|
+
await this.subject.store.add(aJob('job-1'));
|
|
44
|
+
const cancelled = await this.subject.unitOfWork.run(() => this.subject.store.cancel('job-1', NOW));
|
|
45
|
+
this.expect([cancelled, (await this.subject.store.find('job-1'))?.status]).toEqual([true, 'cancelled']);
|
|
46
|
+
this.expect(await this.claimed()).toEqual([]);
|
|
47
|
+
});
|
|
48
|
+
}
|
|
49
|
+
revives() {
|
|
50
|
+
this.it('leaves the job dead when the unit of work that revived it rolled back', async () => {
|
|
51
|
+
await this.subject.store.add(aJob('job-1'));
|
|
52
|
+
await this.claimed();
|
|
53
|
+
await this.subject.store.fail({ id: 'job-1', attempt: 1 }, { errorCode: 'X', retryAt: null, at: NOW });
|
|
54
|
+
await failureOf(() => this.subject.unitOfWork.run(async () => {
|
|
55
|
+
this.expect(await this.subject.store.retryDead(['job-1'], NOW)).toBe(1);
|
|
56
|
+
throw new CommandRefused();
|
|
57
|
+
}));
|
|
58
|
+
this.expect((await this.subject.store.find('job-1'))?.status).toBe('dead');
|
|
59
|
+
this.expect(await this.subject.unitOfWork.run(() => this.subject.store.retryDead(['job-1'], NOW))).toBe(1);
|
|
60
|
+
this.expect((await this.subject.store.find('job-1'))?.status).toBe('waiting');
|
|
61
|
+
});
|
|
62
|
+
}
|
|
63
|
+
async claimed() {
|
|
64
|
+
const jobs = await this.subject.store.claim({ queue: QUEUE, limit: 10, now: NOW, leaseMs: LEASE_MS });
|
|
65
|
+
return jobs.map((job) => job.id);
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
//# sourceMappingURL=transaction-suite.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"transaction-suite.js","sourceRoot":"","sources":["../../../src/contracts/job-store/transaction-suite.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import type { Awaitable } from './awaitable.js';
|
|
2
|
+
import type { ContractRunner } from './contract-runner.js';
|
|
3
|
+
import type { JobStoreUnderContract } from './job-store/job-store-under-contract.js';
|
|
4
|
+
import { type UnitOfWorkOfTheStore } from './job-store/transaction-suite.js';
|
|
5
|
+
export interface JobStoreContractOptions {
|
|
6
|
+
readonly name: string;
|
|
7
|
+
/** A fresh, empty store; called before each test. */
|
|
8
|
+
createStore(): Awaitable<JobStoreUnderContract>;
|
|
9
|
+
/**
|
|
10
|
+
* The unit of work the store is used in, over the same database and the same context as the
|
|
11
|
+
* store just created: the contract then proves that a job added inside it exists if and only
|
|
12
|
+
* if it committed.
|
|
13
|
+
*/
|
|
14
|
+
readonly unitOfWork?: () => UnitOfWorkOfTheStore;
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* What every `JobStore` guarantees, whatever it runs on: due jobs handed out earliest first and
|
|
18
|
+
* each to one claim, a lease that brings back the job of a worker that died, reports heard only
|
|
19
|
+
* from the attempt that holds the job, retries, dead jobs and their revival, cancellation,
|
|
20
|
+
* idempotency keys, housekeeping, and the enqueue sharing the fate of the unit of work.
|
|
21
|
+
* The claims of the contract ask for a lease of `30000` milliseconds.
|
|
22
|
+
*/
|
|
23
|
+
export declare function jobStoreContract(runner: ContractRunner, options: JobStoreContractOptions): void;
|
|
24
|
+
//# sourceMappingURL=job-store-contract.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"job-store-contract.d.ts","sourceRoot":"","sources":["../../src/contracts/job-store-contract.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAChD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAE3D,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,yCAAyC,CAAC;AAGrF,OAAO,EAAoB,KAAK,oBAAoB,EAAE,MAAM,kCAAkC,CAAC;AAE/F,MAAM,WAAW,uBAAuB;IACtC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,qDAAqD;IACrD,WAAW,IAAI,SAAS,CAAC,qBAAqB,CAAC,CAAC;IAChD;;;;OAIG;IACH,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,oBAAoB,CAAC;CAClD;AAED;;;;;;GAMG;AACH,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,cAAc,EAAE,OAAO,EAAE,uBAAuB,GAAG,IAAI,CAc/F"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { ClaimSuite } from './job-store/claim-suite.js';
|
|
2
|
+
import { KeepSuite } from './job-store/keep-suite.js';
|
|
3
|
+
import { ReportSuite } from './job-store/report-suite.js';
|
|
4
|
+
import { TransactionSuite } from './job-store/transaction-suite.js';
|
|
5
|
+
/**
|
|
6
|
+
* What every `JobStore` guarantees, whatever it runs on: due jobs handed out earliest first and
|
|
7
|
+
* each to one claim, a lease that brings back the job of a worker that died, reports heard only
|
|
8
|
+
* from the attempt that holds the job, retries, dead jobs and their revival, cancellation,
|
|
9
|
+
* idempotency keys, housekeeping, and the enqueue sharing the fate of the unit of work.
|
|
10
|
+
* The claims of the contract ask for a lease of `30000` milliseconds.
|
|
11
|
+
*/
|
|
12
|
+
export function jobStoreContract(runner, options) {
|
|
13
|
+
const create = () => options.createStore();
|
|
14
|
+
new ClaimSuite(runner, create).describe(`${options.name} (job store contract: claims)`);
|
|
15
|
+
new ReportSuite(runner, create).describe(`${options.name} (job store contract: reports of an attempt)`);
|
|
16
|
+
new KeepSuite(runner, create).describe(`${options.name} (job store contract: cancellation and housekeeping)`);
|
|
17
|
+
const { unitOfWork } = options;
|
|
18
|
+
if (unitOfWork !== undefined) {
|
|
19
|
+
new TransactionSuite(runner, async () => ({ store: await create(), unitOfWork: unitOfWork() })).describe(`${options.name} (job store contract: in a unit of work)`);
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
//# sourceMappingURL=job-store-contract.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"job-store-contract.js","sourceRoot":"","sources":["../../src/contracts/job-store-contract.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,UAAU,EAAE,MAAM,4BAA4B,CAAC;AAExD,OAAO,EAAE,SAAS,EAAE,MAAM,2BAA2B,CAAC;AACtD,OAAO,EAAE,WAAW,EAAE,MAAM,6BAA6B,CAAC;AAC1D,OAAO,EAAE,gBAAgB,EAA6B,MAAM,kCAAkC,CAAC;AAc/F;;;;;;GAMG;AACH,MAAM,UAAU,gBAAgB,CAAC,MAAsB,EAAE,OAAgC;IACvF,MAAM,MAAM,GAAG,GAAqC,EAAE,CAAC,OAAO,CAAC,WAAW,EAAE,CAAC;IAE7E,IAAI,UAAU,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,QAAQ,CAAC,GAAG,OAAO,CAAC,IAAI,+BAA+B,CAAC,CAAC;IACxF,IAAI,WAAW,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,QAAQ,CAAC,GAAG,OAAO,CAAC,IAAI,8CAA8C,CAAC,CAAC;IACxG,IAAI,SAAS,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,QAAQ,CAAC,GAAG,OAAO,CAAC,IAAI,sDAAsD,CAAC,CAAC;IAE9G,MAAM,EAAE,UAAU,EAAE,GAAG,OAAO,CAAC;IAE/B,IAAI,UAAU,KAAK,SAAS,EAAE,CAAC;QAC7B,IAAI,gBAAgB,CAAC,MAAM,EAAE,KAAK,IAAI,EAAE,CAAC,CAAC,EAAE,KAAK,EAAE,MAAM,MAAM,EAAE,EAAE,UAAU,EAAE,UAAU,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,CACtG,GAAG,OAAO,CAAC,IAAI,0CAA0C,CAC1D,CAAC;IACJ,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import type { StoredProcess } from '@ddd-ts-kit/kernel';
|
|
2
|
+
import type { Awaitable } from './awaitable.js';
|
|
3
|
+
import type { ContractRunner } from './contract-runner.js';
|
|
4
|
+
/** The process store port of the kernel, restated so that a store of any package fits. */
|
|
5
|
+
export interface ProcessStoreUnderContract {
|
|
6
|
+
load(name: string, id: string): Promise<StoredProcess | undefined>;
|
|
7
|
+
save(process: StoredProcess): Promise<void>;
|
|
8
|
+
}
|
|
9
|
+
/** The unit of work the store is used in, as the kernel port states it. */
|
|
10
|
+
interface UnitOfWorkOfTheStore {
|
|
11
|
+
run<T>(work: () => Promise<T>): Promise<T>;
|
|
12
|
+
}
|
|
13
|
+
export interface ProcessStoreContractOptions {
|
|
14
|
+
readonly name: string;
|
|
15
|
+
/** A fresh, empty store; called before each test. */
|
|
16
|
+
createStore(): Awaitable<ProcessStoreUnderContract>;
|
|
17
|
+
/** The unit of work over the same context as the store just created: the contract then proves that a rolled back save leaves nothing. */
|
|
18
|
+
readonly unitOfWork?: () => UnitOfWorkOfTheStore;
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* What every `ProcessStore` guarantees: an instance comes back as saved, JSON state, armed
|
|
22
|
+
* timeouts and end included; a save at a version that is not the next one is refused with the
|
|
23
|
+
* code `CONCURRENCY_CONFLICT`, also when two first saves race; and, in a unit of work, a save
|
|
24
|
+
* shares its fate.
|
|
25
|
+
*/
|
|
26
|
+
export declare function processStoreContract(runner: ContractRunner, options: ProcessStoreContractOptions): void;
|
|
27
|
+
export {};
|
|
28
|
+
//# sourceMappingURL=process-store-contract.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"process-store-contract.d.ts","sourceRoot":"","sources":["../../src/contracts/process-store-contract.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AACxD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAChD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAI3D,0FAA0F;AAC1F,MAAM,WAAW,yBAAyB;IACxC,IAAI,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,aAAa,GAAG,SAAS,CAAC,CAAC;IACnE,IAAI,CAAC,OAAO,EAAE,aAAa,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CAC7C;AAED,2EAA2E;AAC3E,UAAU,oBAAoB;IAC5B,GAAG,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC;CAC5C;AAED,MAAM,WAAW,2BAA2B;IAC1C,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,qDAAqD;IACrD,WAAW,IAAI,SAAS,CAAC,yBAAyB,CAAC,CAAC;IACpD,yIAAyI;IACzI,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,oBAAoB,CAAC;CAClD;AAED;;;;;GAKG;AACH,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,cAAc,EAAE,OAAO,EAAE,2BAA2B,GAAG,IAAI,CAEvG"}
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
import { ContractSuite } from './contract-suite.js';
|
|
2
|
+
import { failureOf } from './failure-of.js';
|
|
3
|
+
/**
|
|
4
|
+
* What every `ProcessStore` guarantees: an instance comes back as saved, JSON state, armed
|
|
5
|
+
* timeouts and end included; a save at a version that is not the next one is refused with the
|
|
6
|
+
* code `CONCURRENCY_CONFLICT`, also when two first saves race; and, in a unit of work, a save
|
|
7
|
+
* shares its fate.
|
|
8
|
+
*/
|
|
9
|
+
export function processStoreContract(runner, options) {
|
|
10
|
+
new ProcessStoreSuite(runner, options).describe(`${options.name} (process store contract)`);
|
|
11
|
+
}
|
|
12
|
+
const NAME = 'billing.dunning';
|
|
13
|
+
class ProcessStoreSuite extends ContractSuite {
|
|
14
|
+
options;
|
|
15
|
+
constructor(runner, options) {
|
|
16
|
+
super(runner, () => options.createStore());
|
|
17
|
+
this.options = options;
|
|
18
|
+
}
|
|
19
|
+
tests() {
|
|
20
|
+
this.keeps();
|
|
21
|
+
this.refusesStaleVersions();
|
|
22
|
+
if (this.options.unitOfWork !== undefined) {
|
|
23
|
+
this.sharesTheUnitOfWork(this.options.unitOfWork);
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
keeps() {
|
|
27
|
+
this.it('knows no instance before it is saved, and gives one back as saved', async () => {
|
|
28
|
+
this.expect(await this.subject.load(NAME, 'invoice-1')).toBe(undefined);
|
|
29
|
+
await this.subject.save(anInstance(1));
|
|
30
|
+
this.expect(await this.subject.load(NAME, 'invoice-1')).toEqual(anInstance(1));
|
|
31
|
+
this.expect(await this.subject.load('billing.collection', 'invoice-1')).toBe(undefined);
|
|
32
|
+
});
|
|
33
|
+
this.it('keeps the next versions, the end and the timeouts', async () => {
|
|
34
|
+
await this.subject.save(anInstance(1));
|
|
35
|
+
await this.subject.save({ ...anInstance(2), ended: true, timeouts: {} });
|
|
36
|
+
this.expect(await this.subject.load(NAME, 'invoice-1')).toEqual({ ...anInstance(2), ended: true, timeouts: {} });
|
|
37
|
+
});
|
|
38
|
+
}
|
|
39
|
+
refusesStaleVersions() {
|
|
40
|
+
this.it('refuses a version that is not the next one', async () => {
|
|
41
|
+
await this.subject.save(anInstance(1));
|
|
42
|
+
const failures = [
|
|
43
|
+
await failureOf(() => this.subject.save(anInstance(1))),
|
|
44
|
+
await failureOf(() => this.subject.save(anInstance(3))),
|
|
45
|
+
];
|
|
46
|
+
this.expect(failures.map(codeOf)).toEqual(['CONCURRENCY_CONFLICT', 'CONCURRENCY_CONFLICT']);
|
|
47
|
+
this.expect((await this.subject.load(NAME, 'invoice-1'))?.version).toBe(1);
|
|
48
|
+
});
|
|
49
|
+
this.it('lets one of two first saves of an instance win', async () => {
|
|
50
|
+
const outcomes = await Promise.all([
|
|
51
|
+
failureOf(() => this.subject.save(anInstance(1))),
|
|
52
|
+
failureOf(() => this.subject.save({ ...anInstance(1), state: { stage: 'other' } })),
|
|
53
|
+
]);
|
|
54
|
+
this.expect(outcomes.filter((failure) => failure === undefined).length).toBe(1);
|
|
55
|
+
this.expect(outcomes.map(codeOf).filter((code) => code !== undefined)).toEqual(['CONCURRENCY_CONFLICT']);
|
|
56
|
+
});
|
|
57
|
+
}
|
|
58
|
+
sharesTheUnitOfWork(unitOfWork) {
|
|
59
|
+
this.it('leaves nothing behind a unit of work that rolled back', async () => {
|
|
60
|
+
await failureOf(() => unitOfWork().run(async () => {
|
|
61
|
+
await this.subject.save(anInstance(1));
|
|
62
|
+
throw new Error('the step failed');
|
|
63
|
+
}));
|
|
64
|
+
this.expect(await this.subject.load(NAME, 'invoice-1')).toBe(undefined);
|
|
65
|
+
});
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
function anInstance(version) {
|
|
69
|
+
return {
|
|
70
|
+
name: NAME,
|
|
71
|
+
id: 'invoice-1',
|
|
72
|
+
state: { stage: 'reminded', reminders: [1, 2], amount: 12.5, note: null },
|
|
73
|
+
version,
|
|
74
|
+
ended: false,
|
|
75
|
+
timeouts: { 'second-reminder': 'job-7' },
|
|
76
|
+
};
|
|
77
|
+
}
|
|
78
|
+
function codeOf(failure) {
|
|
79
|
+
return typeof failure === 'object' && failure !== null ? Reflect.get(failure, 'code') : undefined;
|
|
80
|
+
}
|
|
81
|
+
//# sourceMappingURL=process-store-contract.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"process-store-contract.js","sourceRoot":"","sources":["../../src/contracts/process-store-contract.ts"],"names":[],"mappings":"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"}
|
package/dist/contracts.d.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
export type { Awaitable } from './contracts/awaitable.js';
|
|
2
2
|
export { cacheContract, type CacheContractOptions } from './contracts/cache-contract.js';
|
|
3
|
+
export { cachePurgerContract, type CachePurgerContractOptions, type CachePurgerUnderContract, } from './contracts/cache-purger-contract.js';
|
|
3
4
|
export type { ContractRunner } from './contracts/contract-runner.js';
|
|
4
5
|
export { ContractSuite } from './contracts/contract-suite.js';
|
|
5
6
|
export { criteriaContract, type CriteriaContractOptions, type ReadModelUnderContract, } from './contracts/criteria-contract.js';
|
|
@@ -18,6 +19,8 @@ export { jobSchedulerContract, type JobSchedulerContractOptions, type JobSchedul
|
|
|
18
19
|
export { eventStoreContract, type EventStoreContractOptions } from './contracts/event-store-contract.js';
|
|
19
20
|
export type { EventStoreUnderContract } from './contracts/event-store/event-store-under-contract.js';
|
|
20
21
|
export { eventStoreUnitOfWorkContract, type EventStoreUnitOfWorkContractOptions, } from './contracts/event-store-unit-of-work-contract.js';
|
|
22
|
+
export { jobStoreContract, type JobStoreContractOptions } from './contracts/job-store-contract.js';
|
|
23
|
+
export type { JobStoreUnderContract } from './contracts/job-store/job-store-under-contract.js';
|
|
21
24
|
export { lockContract, type LockContractOptions } from './contracts/lock-contract.js';
|
|
22
25
|
export { loggerContract, type LoggerContractOptions } from './contracts/logger-contract.js';
|
|
23
26
|
export type { CreateLogger } from './contracts/logger/create-logger.js';
|
|
@@ -25,6 +28,7 @@ export type { LoggedLine } from './contracts/logger/logged-line.js';
|
|
|
25
28
|
export type { LoggerContractSetup } from './contracts/logger/logger-contract-setup.js';
|
|
26
29
|
export type { LoggerUnderContract } from './contracts/logger/logger-under-contract.js';
|
|
27
30
|
export { outboxStoreContract, type OutboxStoreContractOptions, type OutboxStoreUnderContract, } from './contracts/outbox-store-contract.js';
|
|
31
|
+
export { processStoreContract, type ProcessStoreContractOptions, type ProcessStoreUnderContract, } from './contracts/process-store-contract.js';
|
|
28
32
|
export { processedEventStoreContract, type ProcessedEventStoreContractOptions, } from './contracts/processed-event-store-contract.js';
|
|
29
33
|
export { rateLimiterContract, type RateLimiterContractOptions } from './contracts/rate-limiter-contract.js';
|
|
30
34
|
export { readModelStoreContract, type ReadModelStoreContractOptions } from './contracts/read-model-store-contract.js';
|
package/dist/contracts.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"contracts.d.ts","sourceRoot":"","sources":["../src/contracts.ts"],"names":[],"mappings":"AAAA,YAAY,EAAE,SAAS,EAAE,MAAM,0BAA0B,CAAC;AAC1D,OAAO,EAAE,aAAa,EAAE,KAAK,oBAAoB,EAAE,MAAM,+BAA+B,CAAC;AACzF,YAAY,EAAE,cAAc,EAAE,MAAM,gCAAgC,CAAC;AACrE,OAAO,EAAE,aAAa,EAAE,MAAM,+BAA+B,CAAC;AAC9D,OAAO,EACL,gBAAgB,EAChB,KAAK,uBAAuB,EAC5B,KAAK,sBAAsB,GAC5B,MAAM,kCAAkC,CAAC;AAC1C,YAAY,EAAE,YAAY,EAAE,MAAM,uCAAuC,CAAC;AAC1E,OAAO,EAAE,0BAA0B,EAAE,MAAM,sDAAsD,CAAC;AAClG,YAAY,EAAE,mBAAmB,EAAE,MAAM,+CAA+C,CAAC;AACzF,OAAO,EAAE,oBAAoB,EAAE,MAAM,gDAAgD,CAAC;AACtF,OAAO,EACL,gBAAgB,EAChB,KAAK,uBAAuB,EAC5B,KAAK,qBAAqB,GAC3B,MAAM,mCAAmC,CAAC;AAC3C,OAAO,EAAE,mBAAmB,EAAE,MAAM,sCAAsC,CAAC;AAC3E,YAAY,EAAE,0BAA0B,EAAE,MAAM,2DAA2D,CAAC;AAC5G,OAAO,EAAE,YAAY,EAAE,MAAM,2CAA2C,CAAC;AACzE,OAAO,EAAE,eAAe,EAAE,MAAM,+CAA+C,CAAC;AAChF,YAAY,EAAE,gBAAgB,EAAE,MAAM,+CAA+C,CAAC;AACtF,YAAY,EAAE,aAAa,EAAE,MAAM,4CAA4C,CAAC;AAChF,OAAO,EACL,oBAAoB,EACpB,KAAK,2BAA2B,EAChC,KAAK,yBAAyB,GAC/B,MAAM,uCAAuC,CAAC;AAC/C,OAAO,EAAE,kBAAkB,EAAE,KAAK,yBAAyB,EAAE,MAAM,qCAAqC,CAAC;AACzG,YAAY,EAAE,uBAAuB,EAAE,MAAM,uDAAuD,CAAC;AACrG,OAAO,EACL,4BAA4B,EAC5B,KAAK,mCAAmC,GACzC,MAAM,kDAAkD,CAAC;AAC1D,OAAO,EAAE,YAAY,EAAE,KAAK,mBAAmB,EAAE,MAAM,8BAA8B,CAAC;AACtF,OAAO,EAAE,cAAc,EAAE,KAAK,qBAAqB,EAAE,MAAM,gCAAgC,CAAC;AAC5F,YAAY,EAAE,YAAY,EAAE,MAAM,qCAAqC,CAAC;AACxE,YAAY,EAAE,UAAU,EAAE,MAAM,mCAAmC,CAAC;AACpE,YAAY,EAAE,mBAAmB,EAAE,MAAM,6CAA6C,CAAC;AACvF,YAAY,EAAE,mBAAmB,EAAE,MAAM,6CAA6C,CAAC;AACvF,OAAO,EACL,mBAAmB,EACnB,KAAK,0BAA0B,EAC/B,KAAK,wBAAwB,GAC9B,MAAM,sCAAsC,CAAC;AAC9C,OAAO,EACL,2BAA2B,EAC3B,KAAK,kCAAkC,GACxC,MAAM,+CAA+C,CAAC;AACvD,OAAO,EAAE,mBAAmB,EAAE,KAAK,0BAA0B,EAAE,MAAM,sCAAsC,CAAC;AAC5G,OAAO,EAAE,sBAAsB,EAAE,KAAK,6BAA6B,EAAE,MAAM,0CAA0C,CAAC;AACtH,YAAY,EAAE,2BAA2B,EAAE,MAAM,2DAA2D,CAAC;AAC7G,OAAO,EAAE,aAAa,EAAE,MAAM,2CAA2C,CAAC;AAC1E,OAAO,EAAE,kBAAkB,EAAE,KAAK,yBAAyB,EAAE,MAAM,oCAAoC,CAAC;AACxG,OAAO,EACL,uBAAuB,EACvB,KAAK,8BAA8B,GACpC,MAAM,0CAA0C,CAAC;AAClD,OAAO,EAAE,kBAAkB,EAAE,KAAK,yBAAyB,EAAE,MAAM,sCAAsC,CAAC;AAC1G,YAAY,EAAE,uBAAuB,EAAE,MAAM,yDAAyD,CAAC"}
|
|
1
|
+
{"version":3,"file":"contracts.d.ts","sourceRoot":"","sources":["../src/contracts.ts"],"names":[],"mappings":"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"}
|
package/dist/contracts.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
export { cacheContract } from './contracts/cache-contract.js';
|
|
2
|
+
export { cachePurgerContract, } from './contracts/cache-purger-contract.js';
|
|
2
3
|
export { ContractSuite } from './contracts/contract-suite.js';
|
|
3
4
|
export { criteriaContract, } from './contracts/criteria-contract.js';
|
|
4
5
|
export { criteriaContractDefinition } from './contracts/criteria/criteria-contract-definition.js';
|
|
@@ -10,9 +11,11 @@ export { followWithFetch } from './contracts/file-storage/follow-with-fetch.js';
|
|
|
10
11
|
export { jobSchedulerContract, } from './contracts/job-scheduler-contract.js';
|
|
11
12
|
export { eventStoreContract } from './contracts/event-store-contract.js';
|
|
12
13
|
export { eventStoreUnitOfWorkContract, } from './contracts/event-store-unit-of-work-contract.js';
|
|
14
|
+
export { jobStoreContract } from './contracts/job-store-contract.js';
|
|
13
15
|
export { lockContract } from './contracts/lock-contract.js';
|
|
14
16
|
export { loggerContract } from './contracts/logger-contract.js';
|
|
15
17
|
export { outboxStoreContract, } from './contracts/outbox-store-contract.js';
|
|
18
|
+
export { processStoreContract, } from './contracts/process-store-contract.js';
|
|
16
19
|
export { processedEventStoreContract, } from './contracts/processed-event-store-contract.js';
|
|
17
20
|
export { rateLimiterContract } from './contracts/rate-limiter-contract.js';
|
|
18
21
|
export { readModelStoreContract } from './contracts/read-model-store-contract.js';
|
package/dist/contracts.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"contracts.js","sourceRoot":"","sources":["../src/contracts.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,aAAa,EAA6B,MAAM,+BAA+B,CAAC;
|
|
1
|
+
{"version":3,"file":"contracts.js","sourceRoot":"","sources":["../src/contracts.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,aAAa,EAA6B,MAAM,+BAA+B,CAAC;AACzF,OAAO,EACL,mBAAmB,GAGpB,MAAM,sCAAsC,CAAC;AAE9C,OAAO,EAAE,aAAa,EAAE,MAAM,+BAA+B,CAAC;AAC9D,OAAO,EACL,gBAAgB,GAGjB,MAAM,kCAAkC,CAAC;AAE1C,OAAO,EAAE,0BAA0B,EAAE,MAAM,sDAAsD,CAAC;AAElG,OAAO,EAAE,oBAAoB,EAAE,MAAM,gDAAgD,CAAC;AACtF,OAAO,EACL,gBAAgB,GAGjB,MAAM,mCAAmC,CAAC;AAC3C,OAAO,EAAE,mBAAmB,EAAE,MAAM,sCAAsC,CAAC;AAE3E,OAAO,EAAE,YAAY,EAAE,MAAM,2CAA2C,CAAC;AACzE,OAAO,EAAE,eAAe,EAAE,MAAM,+CAA+C,CAAC;AAGhF,OAAO,EACL,oBAAoB,GAGrB,MAAM,uCAAuC,CAAC;AAC/C,OAAO,EAAE,kBAAkB,EAAkC,MAAM,qCAAqC,CAAC;AAEzG,OAAO,EACL,4BAA4B,GAE7B,MAAM,kDAAkD,CAAC;AAC1D,OAAO,EAAE,gBAAgB,EAAgC,MAAM,mCAAmC,CAAC;AAEnG,OAAO,EAAE,YAAY,EAA4B,MAAM,8BAA8B,CAAC;AACtF,OAAO,EAAE,cAAc,EAA8B,MAAM,gCAAgC,CAAC;AAK5F,OAAO,EACL,mBAAmB,GAGpB,MAAM,sCAAsC,CAAC;AAC9C,OAAO,EACL,oBAAoB,GAGrB,MAAM,uCAAuC,CAAC;AAC/C,OAAO,EACL,2BAA2B,GAE5B,MAAM,+CAA+C,CAAC;AACvD,OAAO,EAAE,mBAAmB,EAAmC,MAAM,sCAAsC,CAAC;AAC5G,OAAO,EAAE,sBAAsB,EAAsC,MAAM,0CAA0C,CAAC;AAEtH,OAAO,EAAE,aAAa,EAAE,MAAM,2CAA2C,CAAC;AAC1E,OAAO,EAAE,kBAAkB,EAAkC,MAAM,oCAAoC,CAAC;AACxG,OAAO,EACL,uBAAuB,GAExB,MAAM,0CAA0C,CAAC;AAClD,OAAO,EAAE,kBAAkB,EAAkC,MAAM,sCAAsC,CAAC"}
|
package/dist/index.d.ts
CHANGED
|
@@ -15,6 +15,9 @@ export { scoped } from './execution/scoped.js';
|
|
|
15
15
|
export { asTenant } from './execution/as-tenant.js';
|
|
16
16
|
export { SessionBuilder } from './execution/session-builder.js';
|
|
17
17
|
export { createTestBuses, type TestBuses, type TestBusesOptions } from './harness/create-test-buses.js';
|
|
18
|
+
export type { CommandMatcher } from './processes/command-matcher.js';
|
|
19
|
+
export { givenProcess, type ProcessScenario } from './processes/given-process.js';
|
|
20
|
+
export { ProcessOutcome } from './processes/process-outcome.js';
|
|
18
21
|
export { expectSnapshotEquivalence } from './event-sourcing/expect-snapshot-equivalence.js';
|
|
19
22
|
export { givenEvents } from './event-sourcing/given-events.js';
|
|
20
23
|
export type { SnapshotEquivalence } from './event-sourcing/snapshot-equivalence.js';
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,oBAAoB,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AAC5E,YAAY,EAAE,SAAS,EAAE,MAAM,yBAAyB,CAAC;AACzD,OAAO,EAAE,OAAO,EAAE,MAAM,uBAAuB,CAAC;AAChD,YAAY,EAAE,QAAQ,EAAE,MAAM,wBAAwB,CAAC;AACvD,OAAO,EAAE,aAAa,EAAE,MAAM,8BAA8B,CAAC;AAC7D,OAAO,EAAE,cAAc,EAAE,MAAM,+BAA+B,CAAC;AAC/D,OAAO,EAAE,IAAI,EAAE,MAAM,oBAAoB,CAAC;AAC1C,YAAY,EAAE,UAAU,EAAE,MAAM,0BAA0B,CAAC;AAC3D,OAAO,EAAE,OAAO,EAAE,MAAM,uBAAuB,CAAC;AAChD,OAAO,EAAE,cAAc,EAAE,QAAQ,EAAE,MAAM,wBAAwB,CAAC;AAClE,OAAO,EAAE,QAAQ,EAAE,MAAM,0BAA0B,CAAC;AACpD,OAAO,EAAE,kBAAkB,EAAE,MAAM,qCAAqC,CAAC;AACzE,OAAO,EAAE,uBAAuB,EAAE,MAAM,0CAA0C,CAAC;AACnF,OAAO,EAAE,MAAM,EAAE,MAAM,uBAAuB,CAAC;AAC/C,OAAO,EAAE,QAAQ,EAAE,MAAM,0BAA0B,CAAC;AACpD,OAAO,EAAE,cAAc,EAAE,MAAM,gCAAgC,CAAC;AAChE,OAAO,EAAE,eAAe,EAAE,KAAK,SAAS,EAAE,KAAK,gBAAgB,EAAE,MAAM,gCAAgC,CAAC;AACxG,OAAO,EAAE,yBAAyB,EAAE,MAAM,iDAAiD,CAAC;AAC5F,OAAO,EAAE,WAAW,EAAE,MAAM,kCAAkC,CAAC;AAC/D,YAAY,EAAE,mBAAmB,EAAE,MAAM,0CAA0C,CAAC;AACpF,OAAO,EAAE,aAAa,EAAE,MAAM,8BAA8B,CAAC;AAC7D,YAAY,EAAE,aAAa,EAAE,MAAM,8BAA8B,CAAC;AAClE,OAAO,EAAE,kBAAkB,EAAE,KAAK,yBAAyB,EAAE,MAAM,wCAAwC,CAAC;AAC5G,OAAO,EAAE,SAAS,EAAE,MAAM,6BAA6B,CAAC;AACxD,OAAO,EAAE,cAAc,EAAE,MAAM,+BAA+B,CAAC;AAC/D,YAAY,EAAE,YAAY,EAAE,MAAM,8BAA8B,CAAC;AACjE,YAAY,EAAE,aAAa,EAAE,MAAM,+BAA+B,CAAC;AACnE,YAAY,EAAE,YAAY,EAAE,MAAM,8BAA8B,CAAC;AACjE,YAAY,EAAE,WAAW,EAAE,MAAM,6BAA6B,CAAC;AAC/D,OAAO,EAAE,KAAK,EAAE,MAAM,sBAAsB,CAAC;AAC7C,YAAY,EAAE,OAAO,EAAE,MAAM,wBAAwB,CAAC;AACtD,OAAO,EAAE,QAAQ,EAAE,KAAK,QAAQ,EAAE,MAAM,yBAAyB,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,oBAAoB,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AAC5E,YAAY,EAAE,SAAS,EAAE,MAAM,yBAAyB,CAAC;AACzD,OAAO,EAAE,OAAO,EAAE,MAAM,uBAAuB,CAAC;AAChD,YAAY,EAAE,QAAQ,EAAE,MAAM,wBAAwB,CAAC;AACvD,OAAO,EAAE,aAAa,EAAE,MAAM,8BAA8B,CAAC;AAC7D,OAAO,EAAE,cAAc,EAAE,MAAM,+BAA+B,CAAC;AAC/D,OAAO,EAAE,IAAI,EAAE,MAAM,oBAAoB,CAAC;AAC1C,YAAY,EAAE,UAAU,EAAE,MAAM,0BAA0B,CAAC;AAC3D,OAAO,EAAE,OAAO,EAAE,MAAM,uBAAuB,CAAC;AAChD,OAAO,EAAE,cAAc,EAAE,QAAQ,EAAE,MAAM,wBAAwB,CAAC;AAClE,OAAO,EAAE,QAAQ,EAAE,MAAM,0BAA0B,CAAC;AACpD,OAAO,EAAE,kBAAkB,EAAE,MAAM,qCAAqC,CAAC;AACzE,OAAO,EAAE,uBAAuB,EAAE,MAAM,0CAA0C,CAAC;AACnF,OAAO,EAAE,MAAM,EAAE,MAAM,uBAAuB,CAAC;AAC/C,OAAO,EAAE,QAAQ,EAAE,MAAM,0BAA0B,CAAC;AACpD,OAAO,EAAE,cAAc,EAAE,MAAM,gCAAgC,CAAC;AAChE,OAAO,EAAE,eAAe,EAAE,KAAK,SAAS,EAAE,KAAK,gBAAgB,EAAE,MAAM,gCAAgC,CAAC;AACxG,YAAY,EAAE,cAAc,EAAE,MAAM,gCAAgC,CAAC;AACrE,OAAO,EAAE,YAAY,EAAE,KAAK,eAAe,EAAE,MAAM,8BAA8B,CAAC;AAClF,OAAO,EAAE,cAAc,EAAE,MAAM,gCAAgC,CAAC;AAChE,OAAO,EAAE,yBAAyB,EAAE,MAAM,iDAAiD,CAAC;AAC5F,OAAO,EAAE,WAAW,EAAE,MAAM,kCAAkC,CAAC;AAC/D,YAAY,EAAE,mBAAmB,EAAE,MAAM,0CAA0C,CAAC;AACpF,OAAO,EAAE,aAAa,EAAE,MAAM,8BAA8B,CAAC;AAC7D,YAAY,EAAE,aAAa,EAAE,MAAM,8BAA8B,CAAC;AAClE,OAAO,EAAE,kBAAkB,EAAE,KAAK,yBAAyB,EAAE,MAAM,wCAAwC,CAAC;AAC5G,OAAO,EAAE,SAAS,EAAE,MAAM,6BAA6B,CAAC;AACxD,OAAO,EAAE,cAAc,EAAE,MAAM,+BAA+B,CAAC;AAC/D,YAAY,EAAE,YAAY,EAAE,MAAM,8BAA8B,CAAC;AACjE,YAAY,EAAE,aAAa,EAAE,MAAM,+BAA+B,CAAC;AACnE,YAAY,EAAE,YAAY,EAAE,MAAM,8BAA8B,CAAC;AACjE,YAAY,EAAE,WAAW,EAAE,MAAM,6BAA6B,CAAC;AAC/D,OAAO,EAAE,KAAK,EAAE,MAAM,sBAAsB,CAAC;AAC7C,YAAY,EAAE,OAAO,EAAE,MAAM,wBAAwB,CAAC;AACtD,OAAO,EAAE,QAAQ,EAAE,KAAK,QAAQ,EAAE,MAAM,yBAAyB,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -12,6 +12,8 @@ export { scoped } from './execution/scoped.js';
|
|
|
12
12
|
export { asTenant } from './execution/as-tenant.js';
|
|
13
13
|
export { SessionBuilder } from './execution/session-builder.js';
|
|
14
14
|
export { createTestBuses } from './harness/create-test-buses.js';
|
|
15
|
+
export { givenProcess } from './processes/given-process.js';
|
|
16
|
+
export { ProcessOutcome } from './processes/process-outcome.js';
|
|
15
17
|
export { expectSnapshotEquivalence } from './event-sourcing/expect-snapshot-equivalence.js';
|
|
16
18
|
export { givenEvents } from './event-sourcing/given-events.js';
|
|
17
19
|
export { expectRefusal } from './refusals/expect-refusal.js';
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,oBAAoB,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AAE5E,OAAO,EAAE,OAAO,EAAE,MAAM,uBAAuB,CAAC;AAEhD,OAAO,EAAE,aAAa,EAAE,MAAM,8BAA8B,CAAC;AAC7D,OAAO,EAAE,cAAc,EAAE,MAAM,+BAA+B,CAAC;AAC/D,OAAO,EAAE,IAAI,EAAE,MAAM,oBAAoB,CAAC;AAE1C,OAAO,EAAE,OAAO,EAAE,MAAM,uBAAuB,CAAC;AAChD,OAAO,EAAE,cAAc,EAAE,QAAQ,EAAE,MAAM,wBAAwB,CAAC;AAClE,OAAO,EAAE,QAAQ,EAAE,MAAM,0BAA0B,CAAC;AACpD,OAAO,EAAE,kBAAkB,EAAE,MAAM,qCAAqC,CAAC;AACzE,OAAO,EAAE,uBAAuB,EAAE,MAAM,0CAA0C,CAAC;AACnF,OAAO,EAAE,MAAM,EAAE,MAAM,uBAAuB,CAAC;AAC/C,OAAO,EAAE,QAAQ,EAAE,MAAM,0BAA0B,CAAC;AACpD,OAAO,EAAE,cAAc,EAAE,MAAM,gCAAgC,CAAC;AAChE,OAAO,EAAE,eAAe,EAAyC,MAAM,gCAAgC,CAAC;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,oBAAoB,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AAE5E,OAAO,EAAE,OAAO,EAAE,MAAM,uBAAuB,CAAC;AAEhD,OAAO,EAAE,aAAa,EAAE,MAAM,8BAA8B,CAAC;AAC7D,OAAO,EAAE,cAAc,EAAE,MAAM,+BAA+B,CAAC;AAC/D,OAAO,EAAE,IAAI,EAAE,MAAM,oBAAoB,CAAC;AAE1C,OAAO,EAAE,OAAO,EAAE,MAAM,uBAAuB,CAAC;AAChD,OAAO,EAAE,cAAc,EAAE,QAAQ,EAAE,MAAM,wBAAwB,CAAC;AAClE,OAAO,EAAE,QAAQ,EAAE,MAAM,0BAA0B,CAAC;AACpD,OAAO,EAAE,kBAAkB,EAAE,MAAM,qCAAqC,CAAC;AACzE,OAAO,EAAE,uBAAuB,EAAE,MAAM,0CAA0C,CAAC;AACnF,OAAO,EAAE,MAAM,EAAE,MAAM,uBAAuB,CAAC;AAC/C,OAAO,EAAE,QAAQ,EAAE,MAAM,0BAA0B,CAAC;AACpD,OAAO,EAAE,cAAc,EAAE,MAAM,gCAAgC,CAAC;AAChE,OAAO,EAAE,eAAe,EAAyC,MAAM,gCAAgC,CAAC;AAExG,OAAO,EAAE,YAAY,EAAwB,MAAM,8BAA8B,CAAC;AAClF,OAAO,EAAE,cAAc,EAAE,MAAM,gCAAgC,CAAC;AAChE,OAAO,EAAE,yBAAyB,EAAE,MAAM,iDAAiD,CAAC;AAC5F,OAAO,EAAE,WAAW,EAAE,MAAM,kCAAkC,CAAC;AAE/D,OAAO,EAAE,aAAa,EAAE,MAAM,8BAA8B,CAAC;AAE7D,OAAO,EAAE,kBAAkB,EAAkC,MAAM,wCAAwC,CAAC;AAC5G,OAAO,EAAE,SAAS,EAAE,MAAM,6BAA6B,CAAC;AACxD,OAAO,EAAE,cAAc,EAAE,MAAM,+BAA+B,CAAC;AAK/D,OAAO,EAAE,KAAK,EAAE,MAAM,sBAAsB,CAAC;AAE7C,OAAO,EAAE,QAAQ,EAAiB,MAAM,yBAAyB,CAAC"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { Command } from '@ddd-ts-kit/kernel';
|
|
2
|
+
type CommandClass = abstract new (...args: never[]) => Command<unknown>;
|
|
3
|
+
/** How an expected command is described: its class, or the properties that matter (a subset). */
|
|
4
|
+
export type CommandMatcher = CommandClass | {
|
|
5
|
+
readonly [property: string]: unknown;
|
|
6
|
+
};
|
|
7
|
+
export {};
|
|
8
|
+
//# sourceMappingURL=command-matcher.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"command-matcher.d.ts","sourceRoot":"","sources":["../../src/processes/command-matcher.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,oBAAoB,CAAC;AAElD,KAAK,YAAY,GAAG,QAAQ,MAAM,GAAG,IAAI,EAAE,KAAK,EAAE,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;AAExE,iGAAiG;AACjG,MAAM,MAAM,cAAc,GAAG,YAAY,GAAG;IAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAA;CAAE,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"command-matcher.js","sourceRoot":"","sources":["../../src/processes/command-matcher.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import type { ProcessDecision } from '@ddd-ts-kit/kernel';
|
|
2
|
+
import { ProcessOutcome } from './process-outcome.js';
|
|
3
|
+
/** A step of a process, from the state it starts in. */
|
|
4
|
+
export interface ProcessScenario<State> {
|
|
5
|
+
when(step: (current: State | undefined) => ProcessDecision<State> | undefined): ProcessOutcome<State>;
|
|
6
|
+
}
|
|
7
|
+
/**
|
|
8
|
+
* Starts the spec of a step of a process manager from a state, or from none for an instance
|
|
9
|
+
* that does not exist yet: the step is a function of the state and of what happened, so it is
|
|
10
|
+
* tested without a store, a queue or a bus.
|
|
11
|
+
*
|
|
12
|
+
* givenProcess<ReminderState>(undefined)
|
|
13
|
+
* .when((current) => reminders.booked(event, current))
|
|
14
|
+
* .thenState({ appointmentId: 'a-1', stage: 'waiting' })
|
|
15
|
+
* .thenTimeouts([{ name: 'reminder-due', at: dueAt }]);
|
|
16
|
+
*/
|
|
17
|
+
export declare function givenProcess<State>(current: State | undefined): ProcessScenario<State>;
|
|
18
|
+
//# sourceMappingURL=given-process.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"given-process.d.ts","sourceRoot":"","sources":["../../src/processes/given-process.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AAC1D,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAEtD,wDAAwD;AACxD,MAAM,WAAW,eAAe,CAAC,KAAK;IACpC,IAAI,CAAC,IAAI,EAAE,CAAC,OAAO,EAAE,KAAK,GAAG,SAAS,KAAK,eAAe,CAAC,KAAK,CAAC,GAAG,SAAS,GAAG,cAAc,CAAC,KAAK,CAAC,CAAC;CACvG;AAED;;;;;;;;;GASG;AACH,wBAAgB,YAAY,CAAC,KAAK,EAAE,OAAO,EAAE,KAAK,GAAG,SAAS,GAAG,eAAe,CAAC,KAAK,CAAC,CAItF"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { ProcessOutcome } from './process-outcome.js';
|
|
2
|
+
/**
|
|
3
|
+
* Starts the spec of a step of a process manager from a state, or from none for an instance
|
|
4
|
+
* that does not exist yet: the step is a function of the state and of what happened, so it is
|
|
5
|
+
* tested without a store, a queue or a bus.
|
|
6
|
+
*
|
|
7
|
+
* givenProcess<ReminderState>(undefined)
|
|
8
|
+
* .when((current) => reminders.booked(event, current))
|
|
9
|
+
* .thenState({ appointmentId: 'a-1', stage: 'waiting' })
|
|
10
|
+
* .thenTimeouts([{ name: 'reminder-due', at: dueAt }]);
|
|
11
|
+
*/
|
|
12
|
+
export function givenProcess(current) {
|
|
13
|
+
return {
|
|
14
|
+
when: (step) => new ProcessOutcome(step(current)),
|
|
15
|
+
};
|
|
16
|
+
}
|
|
17
|
+
//# sourceMappingURL=given-process.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"given-process.js","sourceRoot":"","sources":["../../src/processes/given-process.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAOtD;;;;;;;;;GASG;AACH,MAAM,UAAU,YAAY,CAAQ,OAA0B;IAC5D,OAAO;QACL,IAAI,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,cAAc,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;KAClD,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import type { ProcessDecision, ProcessTimeout } from '@ddd-ts-kit/kernel';
|
|
2
|
+
import type { CommandMatcher } from './command-matcher.js';
|
|
3
|
+
/** What one step of a process decided, asserted without a store, a queue or a bus. Each assertion answers the outcome, to chain. */
|
|
4
|
+
export declare class ProcessOutcome<State> {
|
|
5
|
+
private readonly decision;
|
|
6
|
+
constructor(decision: ProcessDecision<State> | undefined);
|
|
7
|
+
/** The step ignored what it was given: no state saved, nothing sent. */
|
|
8
|
+
thenIgnored(): this;
|
|
9
|
+
/** Also asserts that the state survives the JSON the runner stores it as: a `Date` or a class instance does not. */
|
|
10
|
+
thenState(expected: State): this;
|
|
11
|
+
/** Exactly these commands, in order: each by its class or the properties that matter. */
|
|
12
|
+
thenCommands(expected: readonly CommandMatcher[]): this;
|
|
13
|
+
thenTimeouts(expected: readonly ProcessTimeout[]): this;
|
|
14
|
+
/** The names of the timeouts the step disarms. */
|
|
15
|
+
thenCancelled(expected: readonly string[]): this;
|
|
16
|
+
thenEnded(): this;
|
|
17
|
+
private decided;
|
|
18
|
+
private holds;
|
|
19
|
+
}
|
|
20
|
+
//# sourceMappingURL=process-outcome.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"process-outcome.d.ts","sourceRoot":"","sources":["../../src/processes/process-outcome.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AAG1E,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAE3D,oIAAoI;AACpI,qBAAa,cAAc,CAAC,KAAK;IACnB,OAAO,CAAC,QAAQ,CAAC,QAAQ;IAArC,YAA6B,QAAQ,EAAE,eAAe,CAAC,KAAK,CAAC,GAAG,SAAS,EAAI;IAE7E,wEAAwE;IACxE,WAAW,IAAI,IAAI,CAElB;IAED,oHAAoH;IACpH,SAAS,CAAC,QAAQ,EAAE,KAAK,GAAG,IAAI,CAa/B;IAED,yFAAyF;IACzF,YAAY,CAAC,QAAQ,EAAE,SAAS,cAAc,EAAE,GAAG,IAAI,CAStD;IAED,YAAY,CAAC,QAAQ,EAAE,SAAS,cAAc,EAAE,GAAG,IAAI,CAOtD;IAED,kDAAkD;IAClD,aAAa,CAAC,QAAQ,EAAE,SAAS,MAAM,EAAE,GAAG,IAAI,CAO/C;IAED,SAAS,IAAI,IAAI,CAEhB;IAED,OAAO,CAAC,OAAO;IAQf,OAAO,CAAC,KAAK;CAOd"}
|