@dudousxd/nestjs-durable-testing 0.20.0 → 0.21.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/index.d.ts CHANGED
@@ -1,4 +1,5 @@
1
1
  import { AdmissionBackend, StateStore, RunStatus, WorkflowEngine, InMemoryStateStore, InMemoryTransport, RunResult, WorkflowRef, StartOptions, WorkflowRun, StepCheckpoint, Transport } from '@dudousxd/nestjs-durable-core';
2
+ export { RUN_HISTORY_FIXTURE_VERSION } from '@dudousxd/nestjs-durable-core';
2
3
 
3
4
  /**
4
5
  * Builds an {@link AdmissionBackend} bound to the given test clock. Implementations that hold their
@@ -184,6 +185,34 @@ interface RunHistory {
184
185
  run: WorkflowRun;
185
186
  checkpoints: StepCheckpoint[];
186
187
  }
188
+
189
+ /**
190
+ * Capture a run's replayable history (the run row + its full checkpoint timeline) from anything with
191
+ * the read API: a `WorkflowEngine`, or a bare `StateStore` (the CLI's `durable export` uses the
192
+ * store). The fixture half of the {@link assertReplayable} loop: capture a representative run,
193
+ * commit it with {@link serializeRunHistory}, and assert it in CI via {@link parseRunHistory}.
194
+ * Returns `null` for an unknown run.
195
+ */
196
+ declare function captureHistory(source: {
197
+ getRun(runId: string): Promise<WorkflowRun | null | undefined>;
198
+ listCheckpoints(runId: string): Promise<StepCheckpoint[]>;
199
+ }, runId: string): Promise<RunHistory | null>;
200
+ /**
201
+ * Serialize a captured history as a pretty-printed JSON fixture (with a trailing newline, so it
202
+ * commits cleanly). Read it back with {@link parseRunHistory}.
203
+ */
204
+ declare function serializeRunHistory(history: RunHistory): string;
205
+ /**
206
+ * Parse a committed fixture (what {@link serializeRunHistory} / `durable export` writes) back into a
207
+ * {@link RunHistory}, reviving the `Date` fields JSON flattened to ISO strings, so
208
+ * `assertReplayable(register, parseRunHistory(readFileSync('fixture.json', 'utf8')))` just works.
209
+ *
210
+ * Throws on a fixture whose `version` is not {@link RUN_HISTORY_FIXTURE_VERSION}: a fixture written
211
+ * in another format would otherwise replay against the wrong shape. A fixture with NO `version` (a
212
+ * hand-built `{ run, checkpoints }`, the shape these docs showed before the marker existed) is read
213
+ * as version 1.
214
+ */
215
+ declare function parseRunHistory(json: string): RunHistory;
187
216
  /**
188
217
  * Replay a recorded run's history against the CURRENT workflow code and throw if they diverged.
189
218
  *
@@ -288,4 +317,4 @@ declare function aggregationFixture(): StepCheckpoint[];
288
317
  */
289
318
  declare function registerCheckpointAggregationCases(t: (label: string, fn: () => Promise<void>) => void, getStore: () => StateStore, run: (over?: Partial<WorkflowRun>) => WorkflowRun): void;
290
319
 
291
- export { type AdmissionBackendFactory, DURABLE_CANONICAL_COLUMNS, type DurableColumnMap, type DurableColumnMismatch, type HandleableTransport, MutableClock, type RunHistory, type StateStoreContext, type StateStoreFactory, StateStoreUnavailableError, type TestEngine, aggregationFixture, assertDurableColumns, assertOutput, assertReplayable, assertRunStatus, assertStepAttempts, assertStepsRan, assertTransportConformance, createTestEngine, failOnce, failTimes, preserveColumnExpectation, recordedSteps, registerCheckpointAggregationCases, runAdmissionBackendContract, runStateStoreContract };
320
+ export { type AdmissionBackendFactory, DURABLE_CANONICAL_COLUMNS, type DurableColumnMap, type DurableColumnMismatch, type HandleableTransport, MutableClock, type RunHistory, type StateStoreContext, type StateStoreFactory, StateStoreUnavailableError, type TestEngine, aggregationFixture, assertDurableColumns, assertOutput, assertReplayable, assertRunStatus, assertStepAttempts, assertStepsRan, assertTransportConformance, captureHistory, createTestEngine, failOnce, failTimes, parseRunHistory, preserveColumnExpectation, recordedSteps, registerCheckpointAggregationCases, runAdmissionBackendContract, runStateStoreContract, serializeRunHistory };
package/dist/index.js CHANGED
@@ -375,7 +375,50 @@ function createTestEngine() {
375
375
  __name(createTestEngine, "createTestEngine");
376
376
 
377
377
  // src/replay.ts
378
- import { InMemoryStateStore as InMemoryStateStore2, WorkflowEngine as WorkflowEngine2 } from "@dudousxd/nestjs-durable-core";
378
+ import { InMemoryStateStore as InMemoryStateStore2, RUN_HISTORY_FIXTURE_VERSION, WorkflowEngine as WorkflowEngine2 } from "@dudousxd/nestjs-durable-core";
379
+ async function captureHistory(source, runId) {
380
+ const run2 = await source.getRun(runId);
381
+ if (!run2) return null;
382
+ return {
383
+ run: run2,
384
+ checkpoints: await source.listCheckpoints(runId)
385
+ };
386
+ }
387
+ __name(captureHistory, "captureHistory");
388
+ function serializeRunHistory(history) {
389
+ return `${JSON.stringify({
390
+ version: RUN_HISTORY_FIXTURE_VERSION,
391
+ ...history
392
+ }, null, 2)}
393
+ `;
394
+ }
395
+ __name(serializeRunHistory, "serializeRunHistory");
396
+ function parseRunHistory(json) {
397
+ const raw = JSON.parse(json);
398
+ if (!raw || typeof raw !== "object" || !raw.run || !Array.isArray(raw.checkpoints)) {
399
+ throw new Error("not a run history fixture: expected { run, checkpoints }");
400
+ }
401
+ if (raw.version !== void 0 && raw.version !== RUN_HISTORY_FIXTURE_VERSION) {
402
+ throw new Error(`unsupported run history fixture version ${JSON.stringify(raw.version)} (this kit reads version ${RUN_HISTORY_FIXTURE_VERSION}); re-export the fixture or upgrade @dudousxd/nestjs-durable-testing`);
403
+ }
404
+ const date = /* @__PURE__ */ __name((v) => new Date(v), "date");
405
+ const run2 = {
406
+ ...raw.run,
407
+ createdAt: date(raw.run.createdAt),
408
+ updatedAt: date(raw.run.updatedAt)
409
+ };
410
+ const checkpoints = raw.checkpoints.map((cp2) => ({
411
+ ...cp2,
412
+ enqueuedAt: date(cp2.enqueuedAt),
413
+ startedAt: date(cp2.startedAt),
414
+ finishedAt: date(cp2.finishedAt)
415
+ }));
416
+ return {
417
+ run: run2,
418
+ checkpoints
419
+ };
420
+ }
421
+ __name(parseRunHistory, "parseRunHistory");
379
422
  async function assertReplayable(register, history) {
380
423
  const store = new InMemoryStateStore2();
381
424
  await store.createRun({
@@ -2314,6 +2357,18 @@ function runStateStoreContract(name, makeStore) {
2314
2357
  await store.releaseRunLock("r1");
2315
2358
  expect3(await store.tryLockRun("r1", "C", 9e3, 2600)).toBe(true);
2316
2359
  });
2360
+ t("releaseRunLock with an owner clears only a lease that owner still holds", async () => {
2361
+ await store.createRun(run({
2362
+ id: "r1"
2363
+ }));
2364
+ expect3(await store.tryLockRun("r1", "A", 2e3, 1e3)).toBe(true);
2365
+ expect3(await store.tryLockRun("r1", "B", 4e3, 2500)).toBe(true);
2366
+ await store.releaseRunLock("r1", "A");
2367
+ expect3(await store.tryLockRun("r1", "C", 9e3, 3e3)).toBe(false);
2368
+ expect3((await store.getRun("r1"))?.lockedBy).toBe("B");
2369
+ await store.releaseRunLock("r1", "B");
2370
+ expect3(await store.tryLockRun("r1", "C", 9e3, 3e3)).toBe(true);
2371
+ });
2317
2372
  t("renewRunLock only succeeds for the current owner", async () => {
2318
2373
  await store.createRun(run({
2319
2374
  id: "r1"
@@ -4239,6 +4294,7 @@ __name(assertTransportConformance, "assertTransportConformance");
4239
4294
  export {
4240
4295
  DURABLE_CANONICAL_COLUMNS,
4241
4296
  MutableClock,
4297
+ RUN_HISTORY_FIXTURE_VERSION,
4242
4298
  StateStoreUnavailableError,
4243
4299
  aggregationFixture,
4244
4300
  assertDurableColumns,
@@ -4248,13 +4304,16 @@ export {
4248
4304
  assertStepAttempts,
4249
4305
  assertStepsRan,
4250
4306
  assertTransportConformance,
4307
+ captureHistory,
4251
4308
  createTestEngine,
4252
4309
  failOnce,
4253
4310
  failTimes,
4311
+ parseRunHistory,
4254
4312
  preserveColumnExpectation,
4255
4313
  recordedSteps,
4256
4314
  registerCheckpointAggregationCases,
4257
4315
  runAdmissionBackendContract,
4258
- runStateStoreContract
4316
+ runStateStoreContract,
4317
+ serializeRunHistory
4259
4318
  };
4260
4319
  //# sourceMappingURL=index.js.map