@sonamu-kit/tasks 0.1.3 → 0.2.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/backend.d.ts +4 -0
- package/dist/backend.d.ts.map +1 -1
- package/dist/backend.js.map +1 -1
- package/dist/client.d.ts.map +1 -1
- package/dist/client.js +3 -1
- package/dist/client.js.map +1 -1
- package/dist/core/retry.d.ts +35 -19
- package/dist/core/retry.d.ts.map +1 -1
- package/dist/core/retry.js +50 -14
- package/dist/core/retry.js.map +1 -1
- package/dist/core/retry.test.js +172 -11
- package/dist/core/retry.test.js.map +1 -1
- package/dist/database/backend.d.ts.map +1 -1
- package/dist/database/backend.js +42 -10
- package/dist/database/backend.js.map +1 -1
- package/dist/database/backend.testsuite.d.ts.map +1 -1
- package/dist/database/backend.testsuite.js +106 -0
- package/dist/database/backend.testsuite.js.map +1 -1
- package/dist/execution.d.ts +2 -0
- package/dist/execution.d.ts.map +1 -1
- package/dist/execution.js +17 -3
- package/dist/execution.js.map +1 -1
- package/dist/execution.test.js +104 -0
- package/dist/execution.test.js.map +1 -1
- package/dist/internal.d.ts +2 -1
- package/dist/internal.d.ts.map +1 -1
- package/dist/internal.js +1 -1
- package/dist/internal.js.map +1 -1
- package/dist/worker.d.ts.map +1 -1
- package/dist/worker.js +2 -1
- package/dist/worker.js.map +1 -1
- package/dist/workflow.d.ts +3 -0
- package/dist/workflow.d.ts.map +1 -1
- package/dist/workflow.js.map +1 -1
- package/package.json +3 -3
- package/src/backend.ts +4 -0
- package/src/client.ts +2 -0
- package/src/core/retry.test.ts +180 -11
- package/src/core/retry.ts +95 -19
- package/src/database/backend.testsuite.ts +119 -0
- package/src/database/backend.ts +65 -11
- package/src/execution.test.ts +115 -0
- package/src/execution.ts +18 -2
- package/src/internal.ts +21 -1
- package/src/worker.ts +1 -0
- package/src/workflow.ts +3 -0
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/database/backend.testsuite.ts"],"sourcesContent":["import { randomUUID } from \"node:crypto\";\nimport { afterAll, beforeAll, describe, expect, test } from \"vitest\";\nimport type { Backend } from \"..//backend\";\nimport type { StepAttempt } from \"../core/step\";\nimport type { WorkflowRun } from \"../core/workflow\";\n\n/**\n * Options for the Backend test suite.\n */\nexport interface TestBackendOptions {\n /**\n * Creates a new isolated Backend instance.\n */\n setup: () => Promise<Backend>;\n /**\n * Cleans up a Backend instance.\n */\n teardown: (backend: Backend) => Promise<void>;\n}\n\n/**\n * Runs the Backend test suite.\n * @param options - Test suite options\n */\nexport function testBackend(options: TestBackendOptions): void {\n const { setup, teardown } = options;\n describe(\"Backend\", () => {\n let backend: Backend;\n\n beforeAll(async () => {\n backend = await setup();\n });\n\n afterAll(async () => {\n await teardown(backend);\n });\n\n describe(\"createWorkflowRun()\", () => {\n test(\"creates a workflow run\", async () => {\n const expected: WorkflowRun = {\n namespaceId: \"\", // -\n id: \"\", // -\n workflowName: randomUUID(),\n version: randomUUID(),\n status: \"pending\",\n idempotencyKey: randomUUID(),\n config: { key: \"val\" },\n context: { key: \"val\" },\n input: { key: \"val\" },\n output: null,\n error: null,\n attempts: 0,\n parentStepAttemptNamespaceId: null,\n parentStepAttemptId: null,\n workerId: null,\n availableAt: newDateInOneYear(), // -\n deadlineAt: newDateInOneYear(),\n startedAt: null,\n finishedAt: null,\n createdAt: new Date(), // -\n updatedAt: new Date(), // -\n };\n\n // Create with all fields\n const created = await backend.createWorkflowRun({\n workflowName: expected.workflowName,\n version: expected.version,\n idempotencyKey: expected.idempotencyKey,\n input: expected.input,\n config: expected.config,\n context: expected.context,\n availableAt: expected.availableAt,\n deadlineAt: expected.deadlineAt,\n });\n expect(created.namespaceId).toHaveLength(36);\n expect(created.id).toHaveLength(36);\n expect(deltaSeconds(created.availableAt)).toBeGreaterThan(1);\n expect(deltaSeconds(created.createdAt)).toBeLessThan(1);\n expect(deltaSeconds(created.updatedAt)).toBeLessThan(1);\n\n expected.namespaceId = created.namespaceId;\n expected.id = created.id;\n expected.availableAt = created.availableAt;\n expected.createdAt = created.createdAt;\n expected.updatedAt = created.updatedAt;\n expect(created).toEqual(expected);\n\n // Create with minimal fields\n const createdMin = await backend.createWorkflowRun({\n workflowName: expected.workflowName,\n version: null,\n idempotencyKey: null,\n input: null,\n config: {},\n context: null,\n availableAt: null,\n deadlineAt: null,\n });\n expect(createdMin.version).toBeNull();\n expect(createdMin.idempotencyKey).toBeNull();\n expect(createdMin.input).toBeNull();\n expect(createdMin.context).toBeNull();\n expect(deltaSeconds(createdMin.availableAt)).toBeLessThan(1); // defaults to NOW()\n expect(createdMin.deadlineAt).toBeNull();\n });\n });\n\n describe(\"listWorkflowRuns()\", () => {\n test(\"lists workflow runs ordered by creation time\", async () => {\n const backend = await setup();\n const first = await createPendingWorkflowRun(backend);\n await sleep(10); // ensure timestamp difference\n const second = await createPendingWorkflowRun(backend);\n\n const listed = await backend.listWorkflowRuns({});\n const listedIds = listed.data.map((run) => run.id);\n expect(listedIds).toEqual([first.id, second.id]);\n await teardown(backend);\n });\n\n test(\"paginates workflow runs\", async () => {\n const backend = await setup();\n const runs: WorkflowRun[] = [];\n for (let i = 0; i < 5; i++) {\n runs.push(await createPendingWorkflowRun(backend));\n await sleep(10);\n }\n\n // p1\n const page1 = await backend.listWorkflowRuns({ limit: 2 });\n expect(page1.data).toHaveLength(2);\n expect(page1.data[0]?.id).toBe(runs[0]?.id);\n expect(page1.data[1]?.id).toBe(runs[1]?.id);\n expect(page1.pagination.next).not.toBeNull();\n expect(page1.pagination.prev).toBeNull();\n\n // p2\n const page2 = await backend.listWorkflowRuns({\n limit: 2,\n // biome-ignore lint/style/noNonNullAssertion: for test\n after: page1.pagination.next!,\n });\n expect(page2.data).toHaveLength(2);\n expect(page2.data[0]?.id).toBe(runs[2]?.id);\n expect(page2.data[1]?.id).toBe(runs[3]?.id);\n expect(page2.pagination.next).not.toBeNull();\n expect(page2.pagination.prev).not.toBeNull();\n\n // p3\n const page3 = await backend.listWorkflowRuns({\n limit: 2,\n // biome-ignore lint/style/noNonNullAssertion: for test\n after: page2.pagination.next!,\n });\n expect(page3.data).toHaveLength(1);\n expect(page3.data[0]?.id).toBe(runs[4]?.id);\n expect(page3.pagination.next).toBeNull();\n expect(page3.pagination.prev).not.toBeNull();\n\n // p2 again\n const page2Back = await backend.listWorkflowRuns({\n limit: 2,\n // biome-ignore lint/style/noNonNullAssertion: for test\n before: page3.pagination.prev!,\n });\n expect(page2Back.data).toHaveLength(2);\n expect(page2Back.data[0]?.id).toBe(runs[2]?.id);\n expect(page2Back.data[1]?.id).toBe(runs[3]?.id);\n expect(page2Back.pagination.next).toEqual(page2.pagination.next);\n expect(page2Back.pagination.prev).toEqual(page2.pagination.prev);\n await teardown(backend);\n });\n\n test(\"handles empty results\", async () => {\n const backend = await setup();\n const listed = await backend.listWorkflowRuns({});\n expect(listed.data).toHaveLength(0);\n expect(listed.pagination.next).toBeNull();\n expect(listed.pagination.prev).toBeNull();\n await teardown(backend);\n });\n\n test(\"paginates correctly with id as tiebreaker when multiple items have the same created_at timestamp\", async () => {\n const backend = await setup();\n\n const runs: WorkflowRun[] = [];\n for (let i = 0; i < 5; i++) {\n runs.push(await createPendingWorkflowRun(backend));\n }\n\n runs.sort((a, b) => {\n const timeDiff = a.createdAt.getTime() - b.createdAt.getTime();\n if (timeDiff !== 0) return timeDiff;\n return a.id.localeCompare(b.id);\n });\n\n const page1 = await backend.listWorkflowRuns({ limit: 2 });\n expect(page1.data).toHaveLength(2);\n expect(page1.data[0]?.id).toBe(runs[0]?.id);\n expect(page1.data[1]?.id).toBe(runs[1]?.id);\n expect(page1.pagination.next).not.toBeNull();\n\n const page2 = await backend.listWorkflowRuns({\n limit: 2,\n // biome-ignore lint/style/noNonNullAssertion: for test\n after: page1.pagination.next!,\n });\n expect(page2.data).toHaveLength(2);\n expect(page2.data[0]?.id).toBe(runs[2]?.id);\n expect(page2.data[1]?.id).toBe(runs[3]?.id);\n expect(page2.pagination.next).not.toBeNull();\n\n const page3 = await backend.listWorkflowRuns({\n limit: 2,\n // biome-ignore lint/style/noNonNullAssertion: for test\n after: page2.pagination.next!,\n });\n expect(page3.data).toHaveLength(1);\n expect(page3.data[0]?.id).toBe(runs[4]?.id);\n expect(page3.pagination.next).toBeNull();\n\n const page2Back = await backend.listWorkflowRuns({\n limit: 2,\n // biome-ignore lint/style/noNonNullAssertion: for test\n before: page3.pagination.prev!,\n });\n expect(page2Back.data).toHaveLength(2);\n expect(page2Back.data[0]?.id).toBe(runs[2]?.id);\n expect(page2Back.data[1]?.id).toBe(runs[3]?.id);\n\n await teardown(backend);\n });\n });\n\n describe(\"claimWorkflowRun()\", () => {\n // because claims involve timing and leases, we create and teardown a new\n // namespaced backend instance for each test\n\n test(\"claims workflow runs and respects leases, reclaiming if lease expires\", async () => {\n const backend = await setup();\n\n await createPendingWorkflowRun(backend);\n\n const firstLeaseMs = 30;\n const firstWorker = randomUUID();\n const claimed = await backend.claimWorkflowRun({\n workerId: firstWorker,\n leaseDurationMs: firstLeaseMs,\n });\n expect(claimed?.status).toBe(\"running\");\n expect(claimed?.workerId).toBe(firstWorker);\n expect(claimed?.attempts).toBe(1);\n expect(claimed?.startedAt).not.toBeNull();\n\n const secondWorker = randomUUID();\n const blocked = await backend.claimWorkflowRun({\n workerId: secondWorker,\n leaseDurationMs: 10,\n });\n expect(blocked).toBeNull();\n\n await sleep(firstLeaseMs + 5); // small buffer for timing variability\n\n const reclaimed = await backend.claimWorkflowRun({\n workerId: secondWorker,\n leaseDurationMs: 10,\n });\n expect(reclaimed?.id).toBe(claimed?.id);\n expect(reclaimed?.attempts).toBe(2);\n expect(reclaimed?.workerId).toBe(secondWorker);\n expect(reclaimed?.startedAt?.getTime()).toBe(claimed?.startedAt?.getTime());\n\n await teardown(backend);\n });\n\n test(\"prioritizes pending workflow runs over expired running ones\", async () => {\n const backend = await setup();\n\n const running = await createPendingWorkflowRun(backend);\n const runningClaim = await backend.claimWorkflowRun({\n workerId: \"worker-running\",\n leaseDurationMs: 5,\n });\n if (!runningClaim) throw new Error(\"expected claim\");\n expect(runningClaim.id).toBe(running.id);\n\n await sleep(10); // wait for running's lease to expire\n\n // pending claimed first, even though running expired\n const pending = await createPendingWorkflowRun(backend);\n const claimedFirst = await backend.claimWorkflowRun({\n workerId: \"worker-second\",\n leaseDurationMs: 100,\n });\n expect(claimedFirst?.id).toBe(pending.id);\n\n // running claimed second\n const claimedSecond = await backend.claimWorkflowRun({\n workerId: \"worker-third\",\n leaseDurationMs: 100,\n });\n expect(claimedSecond?.id).toBe(running.id);\n\n await teardown(backend);\n });\n\n test(\"returns null when no workflow runs are available\", async () => {\n const backend = await setup();\n\n const claimed = await backend.claimWorkflowRun({\n workerId: randomUUID(),\n leaseDurationMs: 10,\n });\n expect(claimed).toBeNull();\n\n await teardown(backend);\n });\n });\n\n describe(\"extendWorkflowRunLease()\", () => {\n test(\"extends the lease for running workflow runs\", async () => {\n const workerId = randomUUID();\n await createPendingWorkflowRun(backend);\n\n const claimed = await backend.claimWorkflowRun({\n workerId,\n leaseDurationMs: 20,\n });\n if (!claimed) throw new Error(\"Expected workflow run to be claimed\"); // for type narrowing\n\n const previousExpiry = claimed.availableAt;\n const extended = await backend.extendWorkflowRunLease({\n workflowRunId: claimed.id,\n workerId,\n leaseDurationMs: 200,\n });\n\n expect(extended.availableAt?.getTime()).toBeGreaterThan(\n previousExpiry?.getTime() ?? Infinity,\n );\n });\n });\n\n describe(\"sleepWorkflowRun()\", () => {\n test(\"sets a running workflow to sleeping status until a future time\", async () => {\n const workerId = randomUUID();\n await createPendingWorkflowRun(backend);\n\n const claimed = await backend.claimWorkflowRun({\n workerId,\n leaseDurationMs: 100,\n });\n if (!claimed) throw new Error(\"Expected workflow run to be claimed\");\n\n const sleepUntil = new Date(Date.now() + 5000); // 5 seconds from now\n\n await backend.sleepWorkflowRun({\n workflowRunId: claimed.id,\n workerId,\n availableAt: sleepUntil,\n });\n\n const fetched = await backend.getWorkflowRun({\n workflowRunId: claimed.id,\n });\n\n expect(fetched).not.toBeNull();\n expect(fetched?.availableAt?.getTime()).toBe(sleepUntil.getTime());\n expect(fetched?.workerId).toBeNull();\n expect(fetched?.status).toBe(\"sleeping\");\n });\n\n test(\"fails when trying to sleep a canceled workflow\", async () => {\n const backend = await setup();\n\n // completed run\n let claimed = await createClaimedWorkflowRun(backend);\n await backend.completeWorkflowRun({\n workflowRunId: claimed.id,\n workerId: claimed.workerId ?? \"\",\n output: null,\n });\n await expect(\n backend.sleepWorkflowRun({\n workflowRunId: claimed.id,\n workerId: claimed.workerId ?? \"\",\n availableAt: new Date(Date.now() + 60_000),\n }),\n ).rejects.toThrow(\"Failed to sleep workflow run\");\n\n // failed run\n claimed = await createClaimedWorkflowRun(backend);\n await backend.failWorkflowRun({\n workflowRunId: claimed.id,\n workerId: claimed.workerId ?? \"\",\n error: { message: \"failed\" },\n });\n await expect(\n backend.sleepWorkflowRun({\n workflowRunId: claimed.id,\n workerId: claimed.workerId ?? \"\",\n availableAt: new Date(Date.now() + 60_000),\n }),\n ).rejects.toThrow(\"Failed to sleep workflow run\");\n\n // canceled run\n claimed = await createClaimedWorkflowRun(backend);\n await backend.cancelWorkflowRun({\n workflowRunId: claimed.id,\n });\n await expect(\n backend.sleepWorkflowRun({\n workflowRunId: claimed.id,\n workerId: claimed.workerId ?? \"\",\n availableAt: new Date(Date.now() + 60_000),\n }),\n ).rejects.toThrow(\"Failed to sleep workflow run\");\n\n await teardown(backend);\n });\n });\n\n describe(\"completeWorkflowRun()\", () => {\n test(\"marks running workflow runs as completed\", async () => {\n const workerId = randomUUID();\n await createPendingWorkflowRun(backend);\n\n const claimed = await backend.claimWorkflowRun({\n workerId,\n leaseDurationMs: 20,\n });\n if (!claimed) throw new Error(\"Expected workflow run to be claimed\"); // for type narrowing\n\n const output = { ok: true };\n const completed = await backend.completeWorkflowRun({\n workflowRunId: claimed.id,\n workerId,\n output,\n });\n\n expect(completed.status).toBe(\"completed\");\n expect(completed.output).toEqual(output);\n expect(completed.error).toBeNull();\n expect(completed.finishedAt).not.toBeNull();\n expect(completed.availableAt).toBeNull();\n });\n });\n\n describe(\"failWorkflowRun()\", () => {\n test(\"reschedules workflow runs with exponential backoff on first failure\", async () => {\n const workerId = randomUUID();\n await createPendingWorkflowRun(backend);\n\n const claimed = await backend.claimWorkflowRun({\n workerId,\n leaseDurationMs: 20,\n });\n if (!claimed) throw new Error(\"Expected workflow run to be claimed\");\n\n const beforeFailTime = Date.now();\n\n const error = { message: \"boom\" };\n const failed = await backend.failWorkflowRun({\n workflowRunId: claimed.id,\n workerId,\n error,\n });\n\n // rescheduled, not permanently failed\n expect(failed.status).toBe(\"pending\");\n expect(failed.error).toEqual(error);\n expect(failed.output).toBeNull();\n expect(failed.finishedAt).toBeNull();\n expect(failed.workerId).toBeNull();\n expect(failed.startedAt).toBeNull(); // cleared on failure for retry\n\n expect(failed.availableAt).not.toBeNull();\n if (!failed.availableAt) throw new Error(\"Expected availableAt\");\n const delayMs = failed.availableAt.getTime() - beforeFailTime;\n expect(delayMs).toBeGreaterThanOrEqual(900); // ~1s with some tolerance\n expect(delayMs).toBeLessThan(1500);\n });\n\n test(\"reschedules with increasing backoff on multiple failures (known slow test)\", async () => {\n // this test needs isolated namespace\n const backend = await setup();\n\n await createPendingWorkflowRun(backend);\n\n // fail first attempt\n let workerId = randomUUID();\n let claimed = await backend.claimWorkflowRun({\n workerId,\n leaseDurationMs: 20,\n });\n if (!claimed) throw new Error(\"Expected workflow run to be claimed\");\n expect(claimed.attempts).toBe(1);\n\n const firstFailed = await backend.failWorkflowRun({\n workflowRunId: claimed.id,\n workerId,\n error: { message: \"first failure\" },\n });\n\n expect(firstFailed.status).toBe(\"pending\");\n\n await sleep(1100); // wait for first backoff (~1s)\n\n // fail second attempt\n workerId = randomUUID();\n claimed = await backend.claimWorkflowRun({\n workerId,\n leaseDurationMs: 20,\n });\n if (!claimed) throw new Error(\"Expected workflow run to be claimed\");\n expect(claimed.attempts).toBe(2);\n\n const beforeSecondFail = Date.now();\n const secondFailed = await backend.failWorkflowRun({\n workflowRunId: claimed.id,\n workerId,\n error: { message: \"second failure\" },\n });\n\n expect(secondFailed.status).toBe(\"pending\");\n\n // second attempt should have ~2s backoff (1s * 2^1)\n if (!secondFailed.availableAt) throw new Error(\"Expected availableAt\");\n const delayMs = secondFailed.availableAt.getTime() - beforeSecondFail;\n expect(delayMs).toBeGreaterThanOrEqual(1900); // ~2s with some tolerance\n expect(delayMs).toBeLessThan(2500);\n\n await teardown(backend);\n });\n });\n\n describe(\"createStepAttempt()\", () => {\n test(\"creates a step attempt\", async () => {\n const workflowRun = await createClaimedWorkflowRun(backend);\n\n const expected: StepAttempt = {\n namespaceId: workflowRun.namespaceId,\n id: \"\", // -\n workflowRunId: workflowRun.id,\n stepName: randomUUID(),\n kind: \"function\",\n status: \"running\",\n config: { key: \"val\" },\n context: null,\n output: null,\n error: null,\n childWorkflowRunNamespaceId: null,\n childWorkflowRunId: null,\n startedAt: null,\n finishedAt: null,\n createdAt: new Date(), // -\n updatedAt: new Date(), // -\n };\n\n const created = await backend.createStepAttempt({\n workflowRunId: expected.workflowRunId,\n // biome-ignore lint/style/noNonNullAssertion: for test\n workerId: workflowRun.workerId!,\n stepName: expected.stepName,\n kind: expected.kind,\n config: expected.config,\n context: expected.context,\n });\n expect(created.id).toHaveLength(36);\n expect(deltaSeconds(created.startedAt)).toBeLessThan(1);\n expect(deltaSeconds(created.createdAt)).toBeLessThan(1);\n expect(deltaSeconds(created.updatedAt)).toBeLessThan(1);\n\n expected.id = created.id;\n expected.startedAt = created.startedAt;\n expected.createdAt = created.createdAt;\n expected.updatedAt = created.updatedAt;\n expect(created).toEqual(expected);\n });\n });\n\n describe(\"getStepAttempt()\", () => {\n test(\"returns a persisted step attempt\", async () => {\n const claimed = await createClaimedWorkflowRun(backend);\n\n const created = await backend.createStepAttempt({\n workflowRunId: claimed.id,\n // biome-ignore lint/style/noNonNullAssertion: for test\n workerId: claimed.workerId!,\n stepName: randomUUID(),\n kind: \"function\",\n config: {},\n context: null,\n });\n\n const got = await backend.getStepAttempt({\n stepAttemptId: created.id,\n });\n expect(got).toEqual(created);\n });\n });\n\n describe(\"listStepAttempts()\", () => {\n beforeAll(async () => {\n backend = await setup();\n });\n\n afterAll(async () => {\n await teardown(backend);\n });\n\n test(\"lists step attempts ordered by creation time\", async () => {\n const claimed = await createClaimedWorkflowRun(backend);\n\n const first = await backend.createStepAttempt({\n workflowRunId: claimed.id,\n // biome-ignore lint/style/noNonNullAssertion: for test\n workerId: claimed.workerId!,\n stepName: randomUUID(),\n kind: \"function\",\n config: {},\n context: null,\n });\n await backend.completeStepAttempt({\n workflowRunId: claimed.id,\n stepAttemptId: first.id,\n // biome-ignore lint/style/noNonNullAssertion: for test\n workerId: claimed.workerId!,\n output: { ok: true },\n });\n\n await sleep(10); // ensure timestamp difference\n\n const second = await backend.createStepAttempt({\n workflowRunId: claimed.id,\n // biome-ignore lint/style/noNonNullAssertion: for test\n workerId: claimed.workerId!,\n stepName: randomUUID(),\n kind: \"function\",\n config: {},\n context: null,\n });\n\n const listed = await backend.listStepAttempts({\n workflowRunId: claimed.id,\n });\n const listedStepNames = listed.data.map((step) => step.stepName);\n expect(listedStepNames).toEqual([first.stepName, second.stepName]);\n });\n\n test(\"paginates step attempts\", async () => {\n const claimed = await createClaimedWorkflowRun(backend);\n\n for (let i = 0; i < 5; i++) {\n await backend.createStepAttempt({\n workflowRunId: claimed.id,\n // biome-ignore lint/style/noNonNullAssertion: for test\n workerId: claimed.workerId!,\n stepName: `step-${String(i)}`,\n kind: \"function\",\n config: {},\n context: null,\n });\n\n await sleep(10); // ensure createdAt differs\n }\n\n // p1\n const page1 = await backend.listStepAttempts({\n workflowRunId: claimed.id,\n limit: 2,\n });\n expect(page1.data).toHaveLength(2);\n expect(page1.data[0]?.stepName).toBe(\"step-0\");\n expect(page1.data[1]?.stepName).toBe(\"step-1\");\n expect(page1.pagination.next).not.toBeNull();\n expect(page1.pagination.prev).toBeNull();\n\n // p2\n const page2 = await backend.listStepAttempts({\n workflowRunId: claimed.id,\n limit: 2,\n // biome-ignore lint/style/noNonNullAssertion: for test\n after: page1.pagination.next!,\n });\n expect(page2.data).toHaveLength(2);\n expect(page2.data[0]?.stepName).toBe(\"step-2\");\n expect(page2.data[1]?.stepName).toBe(\"step-3\");\n expect(page2.pagination.next).not.toBeNull();\n expect(page2.pagination.prev).not.toBeNull();\n\n // p3\n const page3 = await backend.listStepAttempts({\n workflowRunId: claimed.id,\n limit: 2,\n // biome-ignore lint/style/noNonNullAssertion: for test\n after: page2.pagination.next!,\n });\n expect(page3.data).toHaveLength(1);\n expect(page3.data[0]?.stepName).toBe(\"step-4\");\n expect(page3.pagination.next).toBeNull();\n expect(page3.pagination.prev).not.toBeNull();\n\n // p2 again\n const page2Back = await backend.listStepAttempts({\n workflowRunId: claimed.id,\n limit: 2,\n // biome-ignore lint/style/noNonNullAssertion: for test\n before: page3.pagination.prev!,\n });\n expect(page2Back.data).toHaveLength(2);\n expect(page2Back.data[0]?.stepName).toBe(\"step-2\");\n expect(page2Back.data[1]?.stepName).toBe(\"step-3\");\n expect(page2Back.pagination.next).toEqual(page2.pagination.next);\n expect(page2Back.pagination.prev).toEqual(page2.pagination.prev);\n });\n\n test(\"handles empty results\", async () => {\n const claimed = await createClaimedWorkflowRun(backend);\n const listed = await backend.listStepAttempts({\n workflowRunId: claimed.id,\n });\n expect(listed.data).toHaveLength(0);\n expect(listed.pagination.next).toBeNull();\n expect(listed.pagination.prev).toBeNull();\n });\n\n test(\"handles exact limit match\", async () => {\n const claimed = await createClaimedWorkflowRun(backend);\n await backend.createStepAttempt({\n workflowRunId: claimed.id,\n // biome-ignore lint/style/noNonNullAssertion: for test\n workerId: claimed.workerId!,\n stepName: \"step-1\",\n kind: \"function\",\n config: {},\n context: null,\n });\n\n const listed = await backend.listStepAttempts({\n workflowRunId: claimed.id,\n limit: 1,\n });\n expect(listed.data).toHaveLength(1);\n expect(listed.pagination.next).toBeNull();\n expect(listed.pagination.prev).toBeNull();\n });\n });\n\n describe(\"completeStepAttempt()\", () => {\n beforeAll(async () => {\n backend = await setup();\n });\n\n afterAll(async () => {\n await teardown(backend);\n });\n\n test(\"marks running step attempts as completed\", async () => {\n const claimed = await createClaimedWorkflowRun(backend);\n\n const created = await backend.createStepAttempt({\n workflowRunId: claimed.id,\n // biome-ignore lint/style/noNonNullAssertion: for test\n workerId: claimed.workerId!,\n stepName: randomUUID(),\n kind: \"function\",\n config: {},\n context: null,\n });\n const output = { foo: \"bar\" };\n\n const completed = await backend.completeStepAttempt({\n workflowRunId: claimed.id,\n stepAttemptId: created.id,\n // biome-ignore lint/style/noNonNullAssertion: for test\n workerId: claimed.workerId!,\n output,\n });\n\n expect(completed.status).toBe(\"completed\");\n expect(completed.output).toEqual(output);\n expect(completed.error).toBeNull();\n expect(completed.finishedAt).not.toBeNull();\n\n const fetched = await backend.getStepAttempt({\n stepAttemptId: created.id,\n });\n expect(fetched?.status).toBe(\"completed\");\n expect(fetched?.output).toEqual(output);\n expect(fetched?.error).toBeNull();\n expect(fetched?.finishedAt).not.toBeNull();\n });\n\n test(\"throws when workflow is not running\", async () => {\n const backend = await setup();\n await createPendingWorkflowRun(backend);\n\n // create a step attempt by first claiming the workflow\n const claimed = await backend.claimWorkflowRun({\n workerId: randomUUID(),\n leaseDurationMs: 100,\n });\n if (!claimed) throw new Error(\"Failed to claim workflow run\");\n\n const stepAttempt = await backend.createStepAttempt({\n workflowRunId: claimed.id,\n // biome-ignore lint/style/noNonNullAssertion: for test\n workerId: claimed.workerId!,\n stepName: randomUUID(),\n kind: \"function\",\n config: {},\n context: null,\n });\n\n // complete the workflow so it's no longer running\n await backend.completeWorkflowRun({\n workflowRunId: claimed.id,\n // biome-ignore lint/style/noNonNullAssertion: for test\n workerId: claimed.workerId!,\n output: null,\n });\n\n // try to complete the step attempt\n await expect(\n backend.completeStepAttempt({\n workflowRunId: claimed.id,\n stepAttemptId: stepAttempt.id,\n // biome-ignore lint/style/noNonNullAssertion: for test\n workerId: claimed.workerId!,\n output: { foo: \"bar\" },\n }),\n ).rejects.toThrow(\"Failed to mark step attempt completed\");\n\n await teardown(backend);\n });\n\n test(\"throws when step attempt does not exist\", async () => {\n const backend = await setup();\n const claimed = await createClaimedWorkflowRun(backend);\n\n await expect(\n backend.completeStepAttempt({\n workflowRunId: claimed.id,\n stepAttemptId: randomUUID(),\n // biome-ignore lint/style/noNonNullAssertion: for test\n workerId: claimed.workerId!,\n output: { foo: \"bar\" },\n }),\n ).rejects.toThrow(\"Failed to mark step attempt completed\");\n\n await teardown(backend);\n });\n });\n\n describe(\"failStepAttempt()\", () => {\n beforeAll(async () => {\n backend = await setup();\n });\n\n afterAll(async () => {\n await teardown(backend);\n });\n\n test(\"marks running step attempts as failed\", async () => {\n const claimed = await createClaimedWorkflowRun(backend);\n\n const created = await backend.createStepAttempt({\n workflowRunId: claimed.id,\n // biome-ignore lint/style/noNonNullAssertion: for test\n workerId: claimed.workerId!,\n stepName: randomUUID(),\n kind: \"function\",\n config: {},\n context: null,\n });\n const error = { message: \"nope\" };\n\n const failed = await backend.failStepAttempt({\n workflowRunId: claimed.id,\n stepAttemptId: created.id,\n // biome-ignore lint/style/noNonNullAssertion: for test\n workerId: claimed.workerId!,\n error,\n });\n\n expect(failed.status).toBe(\"failed\");\n expect(failed.error).toEqual(error);\n expect(failed.output).toBeNull();\n expect(failed.finishedAt).not.toBeNull();\n\n const fetched = await backend.getStepAttempt({\n stepAttemptId: created.id,\n });\n expect(fetched?.status).toBe(\"failed\");\n expect(fetched?.error).toEqual(error);\n expect(fetched?.output).toBeNull();\n expect(fetched?.finishedAt).not.toBeNull();\n });\n\n test(\"throws when workflow is not running\", async () => {\n const backend = await setup();\n await createPendingWorkflowRun(backend);\n\n // create a step attempt by first claiming the workflow\n const claimed = await backend.claimWorkflowRun({\n workerId: randomUUID(),\n leaseDurationMs: 100,\n });\n if (!claimed) throw new Error(\"Failed to claim workflow run\");\n\n const stepAttempt = await backend.createStepAttempt({\n workflowRunId: claimed.id,\n // biome-ignore lint/style/noNonNullAssertion: for test\n workerId: claimed.workerId!,\n stepName: randomUUID(),\n kind: \"function\",\n config: {},\n context: null,\n });\n\n // complete the workflow so it's no longer running\n await backend.completeWorkflowRun({\n workflowRunId: claimed.id,\n // biome-ignore lint/style/noNonNullAssertion: for test\n workerId: claimed.workerId!,\n output: null,\n });\n\n // try to fail the step attempt\n await expect(\n backend.failStepAttempt({\n workflowRunId: claimed.id,\n stepAttemptId: stepAttempt.id,\n // biome-ignore lint/style/noNonNullAssertion: for test\n workerId: claimed.workerId!,\n error: { message: \"nope\" },\n }),\n ).rejects.toThrow(\"Failed to mark step attempt failed\");\n\n await teardown(backend);\n });\n\n test(\"throws when step attempt does not exist\", async () => {\n const backend = await setup();\n const claimed = await createClaimedWorkflowRun(backend);\n\n await expect(\n backend.failStepAttempt({\n workflowRunId: claimed.id,\n stepAttemptId: randomUUID(),\n // biome-ignore lint/style/noNonNullAssertion: for test\n workerId: claimed.workerId!,\n error: { message: \"nope\" },\n }),\n ).rejects.toThrow(\"Failed to mark step attempt failed\");\n\n await teardown(backend);\n });\n });\n\n describe(\"deadline_at\", () => {\n beforeAll(async () => {\n backend = await setup();\n });\n\n afterAll(async () => {\n await teardown(backend);\n });\n\n test(\"creates a workflow run with a deadline\", async () => {\n const deadline = new Date(Date.now() + 60_000); // in 1 minute\n const created = await backend.createWorkflowRun({\n workflowName: randomUUID(),\n version: null,\n idempotencyKey: null,\n input: null,\n config: {},\n context: null,\n availableAt: null,\n deadlineAt: deadline,\n });\n\n expect(created.deadlineAt).not.toBeNull();\n expect(created.deadlineAt?.getTime()).toBe(deadline.getTime());\n });\n\n test(\"does not claim workflow runs past their deadline\", async () => {\n const backend = await setup();\n\n const pastDeadline = new Date(Date.now() - 1000);\n await backend.createWorkflowRun({\n workflowName: randomUUID(),\n version: null,\n idempotencyKey: null,\n input: null,\n config: {},\n context: null,\n availableAt: null,\n deadlineAt: pastDeadline,\n });\n\n const claimed = await backend.claimWorkflowRun({\n workerId: randomUUID(),\n leaseDurationMs: 1000,\n });\n\n expect(claimed).toBeNull();\n\n await teardown(backend);\n });\n\n test(\"marks deadline-expired workflow runs as failed when claiming\", async () => {\n const backend = await setup();\n\n const pastDeadline = new Date(Date.now() - 1000);\n const created = await backend.createWorkflowRun({\n workflowName: randomUUID(),\n version: null,\n idempotencyKey: null,\n input: null,\n config: {},\n context: null,\n availableAt: null,\n deadlineAt: pastDeadline,\n });\n\n // attempt to claim triggers deadline check\n const claimed = await backend.claimWorkflowRun({\n workerId: randomUUID(),\n leaseDurationMs: 1000,\n });\n expect(claimed).toBeNull();\n\n // verify it was marked as failed\n const failed = await backend.getWorkflowRun({\n workflowRunId: created.id,\n });\n expect(failed?.status).toBe(\"failed\");\n expect(failed?.error).toEqual({\n message: \"Workflow run deadline exceeded\",\n });\n expect(failed?.finishedAt).not.toBeNull();\n expect(failed?.availableAt).toBeNull();\n\n await teardown(backend);\n });\n\n test(\"does not reschedule failed workflow runs if next retry would exceed deadline\", async () => {\n const backend = await setup();\n\n const deadline = new Date(Date.now() + 500); // 500ms from now\n const created = await backend.createWorkflowRun({\n workflowName: randomUUID(),\n version: null,\n idempotencyKey: null,\n input: null,\n config: {},\n context: null,\n availableAt: null,\n deadlineAt: deadline,\n });\n\n const workerId = randomUUID();\n const claimed = await backend.claimWorkflowRun({\n workerId,\n leaseDurationMs: 100,\n });\n expect(claimed).not.toBeNull();\n\n // should mark as permanently failed since retry backoff (1s) would exceed deadline (500ms)\n const failed = await backend.failWorkflowRun({\n workflowRunId: created.id,\n workerId,\n error: { message: \"test error\" },\n });\n\n expect(failed.status).toBe(\"failed\");\n expect(failed.availableAt).toBeNull();\n expect(failed.finishedAt).not.toBeNull();\n expect(failed.startedAt).toBeNull(); // cleared on permanent failure\n\n await teardown(backend);\n });\n\n test(\"reschedules failed workflow runs if retry would complete before deadline\", async () => {\n const backend = await setup();\n\n const deadline = new Date(Date.now() + 5000); // in 5 seconds\n const created = await backend.createWorkflowRun({\n workflowName: randomUUID(),\n version: null,\n idempotencyKey: null,\n input: null,\n config: {},\n context: null,\n availableAt: null,\n deadlineAt: deadline,\n });\n\n const workerId = randomUUID();\n const claimed = await backend.claimWorkflowRun({\n workerId,\n leaseDurationMs: 100,\n });\n expect(claimed).not.toBeNull();\n\n // should reschedule since retry backoff (1s) is before deadline (5s\n const failed = await backend.failWorkflowRun({\n workflowRunId: created.id,\n workerId,\n error: { message: \"test error\" },\n });\n\n expect(failed.status).toBe(\"pending\");\n expect(failed.availableAt).not.toBeNull();\n expect(failed.finishedAt).toBeNull();\n\n await teardown(backend);\n });\n });\n\n describe(\"cancelWorkflowRun()\", () => {\n test(\"cancels a pending workflow run\", async () => {\n const backend = await setup();\n\n const created = await createPendingWorkflowRun(backend);\n expect(created.status).toBe(\"pending\");\n\n const canceled = await backend.cancelWorkflowRun({\n workflowRunId: created.id,\n });\n\n expect(canceled.status).toBe(\"canceled\");\n expect(canceled.workerId).toBeNull();\n expect(canceled.availableAt).toBeNull();\n expect(canceled.finishedAt).not.toBeNull();\n expect(deltaSeconds(canceled.finishedAt)).toBeLessThan(1);\n\n await teardown(backend);\n });\n\n test(\"cancels a running workflow run\", async () => {\n const backend = await setup();\n\n const created = await createClaimedWorkflowRun(backend);\n expect(created.status).toBe(\"running\");\n expect(created.workerId).not.toBeNull();\n\n const canceled = await backend.cancelWorkflowRun({\n workflowRunId: created.id,\n });\n\n expect(canceled.status).toBe(\"canceled\");\n expect(canceled.workerId).toBeNull();\n expect(canceled.availableAt).toBeNull();\n expect(canceled.finishedAt).not.toBeNull();\n\n await teardown(backend);\n });\n\n test(\"cancels a sleeping workflow run\", async () => {\n const backend = await setup();\n\n const claimed = await createClaimedWorkflowRun(backend);\n\n // put workflow to sleep\n const sleepUntil = new Date(Date.now() + 60_000); // 1 minute from now\n const sleeping = await backend.sleepWorkflowRun({\n workflowRunId: claimed.id,\n workerId: claimed.workerId ?? \"\",\n availableAt: sleepUntil,\n });\n expect(sleeping.status).toBe(\"sleeping\");\n\n const canceled = await backend.cancelWorkflowRun({\n workflowRunId: sleeping.id,\n });\n\n expect(canceled.status).toBe(\"canceled\");\n expect(canceled.workerId).toBeNull();\n expect(canceled.availableAt).toBeNull();\n expect(canceled.finishedAt).not.toBeNull();\n\n await teardown(backend);\n });\n\n test(\"throws error when canceling a completed workflow run\", async () => {\n const backend = await setup();\n\n const claimed = await createClaimedWorkflowRun(backend);\n\n // mark as completed\n await backend.completeWorkflowRun({\n workflowRunId: claimed.id,\n workerId: claimed.workerId ?? \"\",\n output: { result: \"success\" },\n });\n\n await expect(\n backend.cancelWorkflowRun({\n workflowRunId: claimed.id,\n }),\n ).rejects.toThrow(/Cannot cancel workflow run .* with status completed/);\n\n await teardown(backend);\n });\n\n test(\"throws error when canceling a failed workflow run\", async () => {\n const backend = await setup();\n\n // create with deadline that's already passed to make it fail\n const workflowWithDeadline = await backend.createWorkflowRun({\n workflowName: randomUUID(),\n version: null,\n idempotencyKey: null,\n input: null,\n config: {},\n context: null,\n availableAt: null,\n deadlineAt: new Date(Date.now() - 1000), // deadline in the past\n });\n\n // try to claim it, which should mark it as failed due to deadline\n const claimed = await backend.claimWorkflowRun({\n workerId: randomUUID(),\n leaseDurationMs: 100,\n });\n\n // if claim succeeds, manually fail it\n if (claimed?.workerId) {\n await backend.failWorkflowRun({\n workflowRunId: claimed.id,\n workerId: claimed.workerId,\n error: { message: \"test error\" },\n });\n }\n\n // get a workflow that's definitely failed\n const failedRun = await backend.getWorkflowRun({\n workflowRunId: workflowWithDeadline.id,\n });\n\n if (failedRun?.status === \"failed\") {\n await expect(\n backend.cancelWorkflowRun({\n workflowRunId: failedRun.id,\n }),\n ).rejects.toThrow(/Cannot cancel workflow run .* with status failed/);\n }\n\n await teardown(backend);\n });\n\n test(\"is idempotent when canceling an already canceled workflow run\", async () => {\n const backend = await setup();\n\n const created = await createPendingWorkflowRun(backend);\n\n const firstCancel = await backend.cancelWorkflowRun({\n workflowRunId: created.id,\n });\n expect(firstCancel.status).toBe(\"canceled\");\n\n const secondCancel = await backend.cancelWorkflowRun({\n workflowRunId: created.id,\n });\n expect(secondCancel.status).toBe(\"canceled\");\n expect(secondCancel.id).toBe(firstCancel.id);\n\n await teardown(backend);\n });\n\n test(\"throws error when canceling a non-existent workflow run\", async () => {\n const backend = await setup();\n\n const nonExistentId = randomUUID();\n\n await expect(\n backend.cancelWorkflowRun({\n workflowRunId: nonExistentId,\n }),\n ).rejects.toThrow(`Workflow run ${nonExistentId} does not exist`);\n\n await teardown(backend);\n });\n\n test(\"canceled workflow is not claimed by workers\", async () => {\n const backend = await setup();\n\n const created = await createPendingWorkflowRun(backend);\n\n // cancel the workflow\n await backend.cancelWorkflowRun({\n workflowRunId: created.id,\n });\n\n // try to claim work\n const claimed = await backend.claimWorkflowRun({\n workerId: randomUUID(),\n leaseDurationMs: 100,\n });\n\n // should not claim the canceled workflow\n expect(claimed).toBeNull();\n\n await teardown(backend);\n });\n });\n });\n}\n\n/**\n * Create a pending workflow run for tests.\n * @param b - Backend\n * @returns Created workflow run\n */\nasync function createPendingWorkflowRun(b: Backend) {\n return await b.createWorkflowRun({\n workflowName: randomUUID(),\n version: null,\n idempotencyKey: null,\n input: null,\n config: {},\n context: null,\n availableAt: null,\n deadlineAt: null,\n });\n}\n\n/**\n * Create and claim a workflow run for tests.\n * @param b - Backend\n * @returns Claimed workflow run\n */\nasync function createClaimedWorkflowRun(b: Backend) {\n await createPendingWorkflowRun(b);\n\n const claimed = await b.claimWorkflowRun({\n workerId: randomUUID(),\n leaseDurationMs: 100,\n });\n\n if (!claimed) throw new Error(\"Failed to claim workflow run\");\n\n return claimed;\n}\n\n/**\n * Get delta in seconds from now.\n * @param date - Date to compare\n * @returns Delta in seconds\n */\nfunction deltaSeconds(date: Date | null | undefined): number {\n if (!date) return Infinity;\n return Math.abs((Date.now() - date.getTime()) / 1000);\n}\n\n/**\n * Create a Date one year in the future.\n * @returns Future Date\n */\nfunction newDateInOneYear() {\n const d = new Date();\n d.setFullYear(d.getFullYear() + 1);\n return d;\n}\n\n/**\n * Sleep for a given duration.\n * @param ms - Milliseconds to sleep\n * @returns Promise resolved after sleeping\n */\nfunction sleep(ms: number) {\n return new Promise((resolve) => setTimeout(resolve, ms));\n}\n"],"names":["randomUUID","afterAll","beforeAll","describe","expect","test","testBackend","options","setup","teardown","backend","expected","namespaceId","id","workflowName","version","status","idempotencyKey","config","key","context","input","output","error","attempts","parentStepAttemptNamespaceId","parentStepAttemptId","workerId","availableAt","newDateInOneYear","deadlineAt","startedAt","finishedAt","createdAt","Date","updatedAt","created","createWorkflowRun","toHaveLength","deltaSeconds","toBeGreaterThan","toBeLessThan","toEqual","createdMin","toBeNull","first","createPendingWorkflowRun","sleep","second","listed","listWorkflowRuns","listedIds","data","map","run","runs","i","push","page1","limit","toBe","pagination","next","not","prev","page2","after","page3","page2Back","before","sort","a","b","timeDiff","getTime","localeCompare","firstLeaseMs","firstWorker","claimed","claimWorkflowRun","leaseDurationMs","secondWorker","blocked","reclaimed","running","runningClaim","Error","pending","claimedFirst","claimedSecond","previousExpiry","extended","extendWorkflowRunLease","workflowRunId","Infinity","sleepUntil","now","sleepWorkflowRun","fetched","getWorkflowRun","createClaimedWorkflowRun","completeWorkflowRun","rejects","toThrow","failWorkflowRun","message","cancelWorkflowRun","ok","completed","beforeFailTime","failed","delayMs","toBeGreaterThanOrEqual","firstFailed","beforeSecondFail","secondFailed","workflowRun","stepName","kind","childWorkflowRunNamespaceId","childWorkflowRunId","createStepAttempt","got","getStepAttempt","stepAttemptId","completeStepAttempt","listStepAttempts","listedStepNames","step","String","foo","stepAttempt","failStepAttempt","deadline","pastDeadline","canceled","sleeping","result","workflowWithDeadline","failedRun","firstCancel","secondCancel","nonExistentId","date","Math","abs","d","setFullYear","getFullYear","ms","Promise","resolve","setTimeout"],"mappings":"AAAA,SAASA,UAAU,QAAQ,cAAc;AACzC,SAASC,QAAQ,EAAEC,SAAS,EAAEC,QAAQ,EAAEC,MAAM,EAAEC,IAAI,QAAQ,SAAS;AAmBrE;;;CAGC,GACD,OAAO,SAASC,YAAYC,OAA2B;IACrD,MAAM,EAAEC,KAAK,EAAEC,QAAQ,EAAE,GAAGF;IAC5BJ,SAAS,WAAW;QAClB,IAAIO;QAEJR,UAAU;YACRQ,UAAU,MAAMF;QAClB;QAEAP,SAAS;YACP,MAAMQ,SAASC;QACjB;QAEAP,SAAS,uBAAuB;YAC9BE,KAAK,0BAA0B;gBAC7B,MAAMM,WAAwB;oBAC5BC,aAAa;oBACbC,IAAI;oBACJC,cAAcd;oBACde,SAASf;oBACTgB,QAAQ;oBACRC,gBAAgBjB;oBAChBkB,QAAQ;wBAAEC,KAAK;oBAAM;oBACrBC,SAAS;wBAAED,KAAK;oBAAM;oBACtBE,OAAO;wBAAEF,KAAK;oBAAM;oBACpBG,QAAQ;oBACRC,OAAO;oBACPC,UAAU;oBACVC,8BAA8B;oBAC9BC,qBAAqB;oBACrBC,UAAU;oBACVC,aAAaC;oBACbC,YAAYD;oBACZE,WAAW;oBACXC,YAAY;oBACZC,WAAW,IAAIC;oBACfC,WAAW,IAAID;gBACjB;gBAEA,yBAAyB;gBACzB,MAAME,UAAU,MAAM1B,QAAQ2B,iBAAiB,CAAC;oBAC9CvB,cAAcH,SAASG,YAAY;oBACnCC,SAASJ,SAASI,OAAO;oBACzBE,gBAAgBN,SAASM,cAAc;oBACvCI,OAAOV,SAASU,KAAK;oBACrBH,QAAQP,SAASO,MAAM;oBACvBE,SAAST,SAASS,OAAO;oBACzBQ,aAAajB,SAASiB,WAAW;oBACjCE,YAAYnB,SAASmB,UAAU;gBACjC;gBACA1B,OAAOgC,QAAQxB,WAAW,EAAE0B,YAAY,CAAC;gBACzClC,OAAOgC,QAAQvB,EAAE,EAAEyB,YAAY,CAAC;gBAChClC,OAAOmC,aAAaH,QAAQR,WAAW,GAAGY,eAAe,CAAC;gBAC1DpC,OAAOmC,aAAaH,QAAQH,SAAS,GAAGQ,YAAY,CAAC;gBACrDrC,OAAOmC,aAAaH,QAAQD,SAAS,GAAGM,YAAY,CAAC;gBAErD9B,SAASC,WAAW,GAAGwB,QAAQxB,WAAW;gBAC1CD,SAASE,EAAE,GAAGuB,QAAQvB,EAAE;gBACxBF,SAASiB,WAAW,GAAGQ,QAAQR,WAAW;gBAC1CjB,SAASsB,SAAS,GAAGG,QAAQH,SAAS;gBACtCtB,SAASwB,SAAS,GAAGC,QAAQD,SAAS;gBACtC/B,OAAOgC,SAASM,OAAO,CAAC/B;gBAExB,6BAA6B;gBAC7B,MAAMgC,aAAa,MAAMjC,QAAQ2B,iBAAiB,CAAC;oBACjDvB,cAAcH,SAASG,YAAY;oBACnCC,SAAS;oBACTE,gBAAgB;oBAChBI,OAAO;oBACPH,QAAQ,CAAC;oBACTE,SAAS;oBACTQ,aAAa;oBACbE,YAAY;gBACd;gBACA1B,OAAOuC,WAAW5B,OAAO,EAAE6B,QAAQ;gBACnCxC,OAAOuC,WAAW1B,cAAc,EAAE2B,QAAQ;gBAC1CxC,OAAOuC,WAAWtB,KAAK,EAAEuB,QAAQ;gBACjCxC,OAAOuC,WAAWvB,OAAO,EAAEwB,QAAQ;gBACnCxC,OAAOmC,aAAaI,WAAWf,WAAW,GAAGa,YAAY,CAAC,IAAI,oBAAoB;gBAClFrC,OAAOuC,WAAWb,UAAU,EAAEc,QAAQ;YACxC;QACF;QAEAzC,SAAS,sBAAsB;YAC7BE,KAAK,gDAAgD;gBACnD,MAAMK,UAAU,MAAMF;gBACtB,MAAMqC,QAAQ,MAAMC,yBAAyBpC;gBAC7C,MAAMqC,MAAM,KAAK,8BAA8B;gBAC/C,MAAMC,SAAS,MAAMF,yBAAyBpC;gBAE9C,MAAMuC,SAAS,MAAMvC,QAAQwC,gBAAgB,CAAC,CAAC;gBAC/C,MAAMC,YAAYF,OAAOG,IAAI,CAACC,GAAG,CAAC,CAACC,MAAQA,IAAIzC,EAAE;gBACjDT,OAAO+C,WAAWT,OAAO,CAAC;oBAACG,MAAMhC,EAAE;oBAAEmC,OAAOnC,EAAE;iBAAC;gBAC/C,MAAMJ,SAASC;YACjB;YAEAL,KAAK,2BAA2B;gBAC9B,MAAMK,UAAU,MAAMF;gBACtB,MAAM+C,OAAsB,EAAE;gBAC9B,IAAK,IAAIC,IAAI,GAAGA,IAAI,GAAGA,IAAK;oBAC1BD,KAAKE,IAAI,CAAC,MAAMX,yBAAyBpC;oBACzC,MAAMqC,MAAM;gBACd;gBAEA,KAAK;gBACL,MAAMW,QAAQ,MAAMhD,QAAQwC,gBAAgB,CAAC;oBAAES,OAAO;gBAAE;gBACxDvD,OAAOsD,MAAMN,IAAI,EAAEd,YAAY,CAAC;gBAChClC,OAAOsD,MAAMN,IAAI,CAAC,EAAE,EAAEvC,IAAI+C,IAAI,CAACL,IAAI,CAAC,EAAE,EAAE1C;gBACxCT,OAAOsD,MAAMN,IAAI,CAAC,EAAE,EAAEvC,IAAI+C,IAAI,CAACL,IAAI,CAAC,EAAE,EAAE1C;gBACxCT,OAAOsD,MAAMG,UAAU,CAACC,IAAI,EAAEC,GAAG,CAACnB,QAAQ;gBAC1CxC,OAAOsD,MAAMG,UAAU,CAACG,IAAI,EAAEpB,QAAQ;gBAEtC,KAAK;gBACL,MAAMqB,QAAQ,MAAMvD,QAAQwC,gBAAgB,CAAC;oBAC3CS,OAAO;oBACP,uDAAuD;oBACvDO,OAAOR,MAAMG,UAAU,CAACC,IAAI;gBAC9B;gBACA1D,OAAO6D,MAAMb,IAAI,EAAEd,YAAY,CAAC;gBAChClC,OAAO6D,MAAMb,IAAI,CAAC,EAAE,EAAEvC,IAAI+C,IAAI,CAACL,IAAI,CAAC,EAAE,EAAE1C;gBACxCT,OAAO6D,MAAMb,IAAI,CAAC,EAAE,EAAEvC,IAAI+C,IAAI,CAACL,IAAI,CAAC,EAAE,EAAE1C;gBACxCT,OAAO6D,MAAMJ,UAAU,CAACC,IAAI,EAAEC,GAAG,CAACnB,QAAQ;gBAC1CxC,OAAO6D,MAAMJ,UAAU,CAACG,IAAI,EAAED,GAAG,CAACnB,QAAQ;gBAE1C,KAAK;gBACL,MAAMuB,QAAQ,MAAMzD,QAAQwC,gBAAgB,CAAC;oBAC3CS,OAAO;oBACP,uDAAuD;oBACvDO,OAAOD,MAAMJ,UAAU,CAACC,IAAI;gBAC9B;gBACA1D,OAAO+D,MAAMf,IAAI,EAAEd,YAAY,CAAC;gBAChClC,OAAO+D,MAAMf,IAAI,CAAC,EAAE,EAAEvC,IAAI+C,IAAI,CAACL,IAAI,CAAC,EAAE,EAAE1C;gBACxCT,OAAO+D,MAAMN,UAAU,CAACC,IAAI,EAAElB,QAAQ;gBACtCxC,OAAO+D,MAAMN,UAAU,CAACG,IAAI,EAAED,GAAG,CAACnB,QAAQ;gBAE1C,WAAW;gBACX,MAAMwB,YAAY,MAAM1D,QAAQwC,gBAAgB,CAAC;oBAC/CS,OAAO;oBACP,uDAAuD;oBACvDU,QAAQF,MAAMN,UAAU,CAACG,IAAI;gBAC/B;gBACA5D,OAAOgE,UAAUhB,IAAI,EAAEd,YAAY,CAAC;gBACpClC,OAAOgE,UAAUhB,IAAI,CAAC,EAAE,EAAEvC,IAAI+C,IAAI,CAACL,IAAI,CAAC,EAAE,EAAE1C;gBAC5CT,OAAOgE,UAAUhB,IAAI,CAAC,EAAE,EAAEvC,IAAI+C,IAAI,CAACL,IAAI,CAAC,EAAE,EAAE1C;gBAC5CT,OAAOgE,UAAUP,UAAU,CAACC,IAAI,EAAEpB,OAAO,CAACuB,MAAMJ,UAAU,CAACC,IAAI;gBAC/D1D,OAAOgE,UAAUP,UAAU,CAACG,IAAI,EAAEtB,OAAO,CAACuB,MAAMJ,UAAU,CAACG,IAAI;gBAC/D,MAAMvD,SAASC;YACjB;YAEAL,KAAK,yBAAyB;gBAC5B,MAAMK,UAAU,MAAMF;gBACtB,MAAMyC,SAAS,MAAMvC,QAAQwC,gBAAgB,CAAC,CAAC;gBAC/C9C,OAAO6C,OAAOG,IAAI,EAAEd,YAAY,CAAC;gBACjClC,OAAO6C,OAAOY,UAAU,CAACC,IAAI,EAAElB,QAAQ;gBACvCxC,OAAO6C,OAAOY,UAAU,CAACG,IAAI,EAAEpB,QAAQ;gBACvC,MAAMnC,SAASC;YACjB;YAEAL,KAAK,oGAAoG;gBACvG,MAAMK,UAAU,MAAMF;gBAEtB,MAAM+C,OAAsB,EAAE;gBAC9B,IAAK,IAAIC,IAAI,GAAGA,IAAI,GAAGA,IAAK;oBAC1BD,KAAKE,IAAI,CAAC,MAAMX,yBAAyBpC;gBAC3C;gBAEA6C,KAAKe,IAAI,CAAC,CAACC,GAAGC;oBACZ,MAAMC,WAAWF,EAAEtC,SAAS,CAACyC,OAAO,KAAKF,EAAEvC,SAAS,CAACyC,OAAO;oBAC5D,IAAID,aAAa,GAAG,OAAOA;oBAC3B,OAAOF,EAAE1D,EAAE,CAAC8D,aAAa,CAACH,EAAE3D,EAAE;gBAChC;gBAEA,MAAM6C,QAAQ,MAAMhD,QAAQwC,gBAAgB,CAAC;oBAAES,OAAO;gBAAE;gBACxDvD,OAAOsD,MAAMN,IAAI,EAAEd,YAAY,CAAC;gBAChClC,OAAOsD,MAAMN,IAAI,CAAC,EAAE,EAAEvC,IAAI+C,IAAI,CAACL,IAAI,CAAC,EAAE,EAAE1C;gBACxCT,OAAOsD,MAAMN,IAAI,CAAC,EAAE,EAAEvC,IAAI+C,IAAI,CAACL,IAAI,CAAC,EAAE,EAAE1C;gBACxCT,OAAOsD,MAAMG,UAAU,CAACC,IAAI,EAAEC,GAAG,CAACnB,QAAQ;gBAE1C,MAAMqB,QAAQ,MAAMvD,QAAQwC,gBAAgB,CAAC;oBAC3CS,OAAO;oBACP,uDAAuD;oBACvDO,OAAOR,MAAMG,UAAU,CAACC,IAAI;gBAC9B;gBACA1D,OAAO6D,MAAMb,IAAI,EAAEd,YAAY,CAAC;gBAChClC,OAAO6D,MAAMb,IAAI,CAAC,EAAE,EAAEvC,IAAI+C,IAAI,CAACL,IAAI,CAAC,EAAE,EAAE1C;gBACxCT,OAAO6D,MAAMb,IAAI,CAAC,EAAE,EAAEvC,IAAI+C,IAAI,CAACL,IAAI,CAAC,EAAE,EAAE1C;gBACxCT,OAAO6D,MAAMJ,UAAU,CAACC,IAAI,EAAEC,GAAG,CAACnB,QAAQ;gBAE1C,MAAMuB,QAAQ,MAAMzD,QAAQwC,gBAAgB,CAAC;oBAC3CS,OAAO;oBACP,uDAAuD;oBACvDO,OAAOD,MAAMJ,UAAU,CAACC,IAAI;gBAC9B;gBACA1D,OAAO+D,MAAMf,IAAI,EAAEd,YAAY,CAAC;gBAChClC,OAAO+D,MAAMf,IAAI,CAAC,EAAE,EAAEvC,IAAI+C,IAAI,CAACL,IAAI,CAAC,EAAE,EAAE1C;gBACxCT,OAAO+D,MAAMN,UAAU,CAACC,IAAI,EAAElB,QAAQ;gBAEtC,MAAMwB,YAAY,MAAM1D,QAAQwC,gBAAgB,CAAC;oBAC/CS,OAAO;oBACP,uDAAuD;oBACvDU,QAAQF,MAAMN,UAAU,CAACG,IAAI;gBAC/B;gBACA5D,OAAOgE,UAAUhB,IAAI,EAAEd,YAAY,CAAC;gBACpClC,OAAOgE,UAAUhB,IAAI,CAAC,EAAE,EAAEvC,IAAI+C,IAAI,CAACL,IAAI,CAAC,EAAE,EAAE1C;gBAC5CT,OAAOgE,UAAUhB,IAAI,CAAC,EAAE,EAAEvC,IAAI+C,IAAI,CAACL,IAAI,CAAC,EAAE,EAAE1C;gBAE5C,MAAMJ,SAASC;YACjB;QACF;QAEAP,SAAS,sBAAsB;YAC7B,yEAAyE;YACzE,4CAA4C;YAE5CE,KAAK,yEAAyE;gBAC5E,MAAMK,UAAU,MAAMF;gBAEtB,MAAMsC,yBAAyBpC;gBAE/B,MAAMkE,eAAe;gBACrB,MAAMC,cAAc7E;gBACpB,MAAM8E,UAAU,MAAMpE,QAAQqE,gBAAgB,CAAC;oBAC7CpD,UAAUkD;oBACVG,iBAAiBJ;gBACnB;gBACAxE,OAAO0E,SAAS9D,QAAQ4C,IAAI,CAAC;gBAC7BxD,OAAO0E,SAASnD,UAAUiC,IAAI,CAACiB;gBAC/BzE,OAAO0E,SAAStD,UAAUoC,IAAI,CAAC;gBAC/BxD,OAAO0E,SAAS/C,WAAWgC,GAAG,CAACnB,QAAQ;gBAEvC,MAAMqC,eAAejF;gBACrB,MAAMkF,UAAU,MAAMxE,QAAQqE,gBAAgB,CAAC;oBAC7CpD,UAAUsD;oBACVD,iBAAiB;gBACnB;gBACA5E,OAAO8E,SAAStC,QAAQ;gBAExB,MAAMG,MAAM6B,eAAe,IAAI,sCAAsC;gBAErE,MAAMO,YAAY,MAAMzE,QAAQqE,gBAAgB,CAAC;oBAC/CpD,UAAUsD;oBACVD,iBAAiB;gBACnB;gBACA5E,OAAO+E,WAAWtE,IAAI+C,IAAI,CAACkB,SAASjE;gBACpCT,OAAO+E,WAAW3D,UAAUoC,IAAI,CAAC;gBACjCxD,OAAO+E,WAAWxD,UAAUiC,IAAI,CAACqB;gBACjC7E,OAAO+E,WAAWpD,WAAW2C,WAAWd,IAAI,CAACkB,SAAS/C,WAAW2C;gBAEjE,MAAMjE,SAASC;YACjB;YAEAL,KAAK,+DAA+D;gBAClE,MAAMK,UAAU,MAAMF;gBAEtB,MAAM4E,UAAU,MAAMtC,yBAAyBpC;gBAC/C,MAAM2E,eAAe,MAAM3E,QAAQqE,gBAAgB,CAAC;oBAClDpD,UAAU;oBACVqD,iBAAiB;gBACnB;gBACA,IAAI,CAACK,cAAc,MAAM,IAAIC,MAAM;gBACnClF,OAAOiF,aAAaxE,EAAE,EAAE+C,IAAI,CAACwB,QAAQvE,EAAE;gBAEvC,MAAMkC,MAAM,KAAK,qCAAqC;gBAEtD,qDAAqD;gBACrD,MAAMwC,UAAU,MAAMzC,yBAAyBpC;gBAC/C,MAAM8E,eAAe,MAAM9E,QAAQqE,gBAAgB,CAAC;oBAClDpD,UAAU;oBACVqD,iBAAiB;gBACnB;gBACA5E,OAAOoF,cAAc3E,IAAI+C,IAAI,CAAC2B,QAAQ1E,EAAE;gBAExC,yBAAyB;gBACzB,MAAM4E,gBAAgB,MAAM/E,QAAQqE,gBAAgB,CAAC;oBACnDpD,UAAU;oBACVqD,iBAAiB;gBACnB;gBACA5E,OAAOqF,eAAe5E,IAAI+C,IAAI,CAACwB,QAAQvE,EAAE;gBAEzC,MAAMJ,SAASC;YACjB;YAEAL,KAAK,oDAAoD;gBACvD,MAAMK,UAAU,MAAMF;gBAEtB,MAAMsE,UAAU,MAAMpE,QAAQqE,gBAAgB,CAAC;oBAC7CpD,UAAU3B;oBACVgF,iBAAiB;gBACnB;gBACA5E,OAAO0E,SAASlC,QAAQ;gBAExB,MAAMnC,SAASC;YACjB;QACF;QAEAP,SAAS,4BAA4B;YACnCE,KAAK,+CAA+C;gBAClD,MAAMsB,WAAW3B;gBACjB,MAAM8C,yBAAyBpC;gBAE/B,MAAMoE,UAAU,MAAMpE,QAAQqE,gBAAgB,CAAC;oBAC7CpD;oBACAqD,iBAAiB;gBACnB;gBACA,IAAI,CAACF,SAAS,MAAM,IAAIQ,MAAM,wCAAwC,qBAAqB;gBAE3F,MAAMI,iBAAiBZ,QAAQlD,WAAW;gBAC1C,MAAM+D,WAAW,MAAMjF,QAAQkF,sBAAsB,CAAC;oBACpDC,eAAef,QAAQjE,EAAE;oBACzBc;oBACAqD,iBAAiB;gBACnB;gBAEA5E,OAAOuF,SAAS/D,WAAW,EAAE8C,WAAWlC,eAAe,CACrDkD,gBAAgBhB,aAAaoB;YAEjC;QACF;QAEA3F,SAAS,sBAAsB;YAC7BE,KAAK,kEAAkE;gBACrE,MAAMsB,WAAW3B;gBACjB,MAAM8C,yBAAyBpC;gBAE/B,MAAMoE,UAAU,MAAMpE,QAAQqE,gBAAgB,CAAC;oBAC7CpD;oBACAqD,iBAAiB;gBACnB;gBACA,IAAI,CAACF,SAAS,MAAM,IAAIQ,MAAM;gBAE9B,MAAMS,aAAa,IAAI7D,KAAKA,KAAK8D,GAAG,KAAK,OAAO,qBAAqB;gBAErE,MAAMtF,QAAQuF,gBAAgB,CAAC;oBAC7BJ,eAAef,QAAQjE,EAAE;oBACzBc;oBACAC,aAAamE;gBACf;gBAEA,MAAMG,UAAU,MAAMxF,QAAQyF,cAAc,CAAC;oBAC3CN,eAAef,QAAQjE,EAAE;gBAC3B;gBAEAT,OAAO8F,SAASnC,GAAG,CAACnB,QAAQ;gBAC5BxC,OAAO8F,SAAStE,aAAa8C,WAAWd,IAAI,CAACmC,WAAWrB,OAAO;gBAC/DtE,OAAO8F,SAASvE,UAAUiB,QAAQ;gBAClCxC,OAAO8F,SAASlF,QAAQ4C,IAAI,CAAC;YAC/B;YAEAvD,KAAK,kDAAkD;gBACrD,MAAMK,UAAU,MAAMF;gBAEtB,gBAAgB;gBAChB,IAAIsE,UAAU,MAAMsB,yBAAyB1F;gBAC7C,MAAMA,QAAQ2F,mBAAmB,CAAC;oBAChCR,eAAef,QAAQjE,EAAE;oBACzBc,UAAUmD,QAAQnD,QAAQ,IAAI;oBAC9BL,QAAQ;gBACV;gBACA,MAAMlB,OACJM,QAAQuF,gBAAgB,CAAC;oBACvBJ,eAAef,QAAQjE,EAAE;oBACzBc,UAAUmD,QAAQnD,QAAQ,IAAI;oBAC9BC,aAAa,IAAIM,KAAKA,KAAK8D,GAAG,KAAK;gBACrC,IACAM,OAAO,CAACC,OAAO,CAAC;gBAElB,aAAa;gBACbzB,UAAU,MAAMsB,yBAAyB1F;gBACzC,MAAMA,QAAQ8F,eAAe,CAAC;oBAC5BX,eAAef,QAAQjE,EAAE;oBACzBc,UAAUmD,QAAQnD,QAAQ,IAAI;oBAC9BJ,OAAO;wBAAEkF,SAAS;oBAAS;gBAC7B;gBACA,MAAMrG,OACJM,QAAQuF,gBAAgB,CAAC;oBACvBJ,eAAef,QAAQjE,EAAE;oBACzBc,UAAUmD,QAAQnD,QAAQ,IAAI;oBAC9BC,aAAa,IAAIM,KAAKA,KAAK8D,GAAG,KAAK;gBACrC,IACAM,OAAO,CAACC,OAAO,CAAC;gBAElB,eAAe;gBACfzB,UAAU,MAAMsB,yBAAyB1F;gBACzC,MAAMA,QAAQgG,iBAAiB,CAAC;oBAC9Bb,eAAef,QAAQjE,EAAE;gBAC3B;gBACA,MAAMT,OACJM,QAAQuF,gBAAgB,CAAC;oBACvBJ,eAAef,QAAQjE,EAAE;oBACzBc,UAAUmD,QAAQnD,QAAQ,IAAI;oBAC9BC,aAAa,IAAIM,KAAKA,KAAK8D,GAAG,KAAK;gBACrC,IACAM,OAAO,CAACC,OAAO,CAAC;gBAElB,MAAM9F,SAASC;YACjB;QACF;QAEAP,SAAS,yBAAyB;YAChCE,KAAK,4CAA4C;gBAC/C,MAAMsB,WAAW3B;gBACjB,MAAM8C,yBAAyBpC;gBAE/B,MAAMoE,UAAU,MAAMpE,QAAQqE,gBAAgB,CAAC;oBAC7CpD;oBACAqD,iBAAiB;gBACnB;gBACA,IAAI,CAACF,SAAS,MAAM,IAAIQ,MAAM,wCAAwC,qBAAqB;gBAE3F,MAAMhE,SAAS;oBAAEqF,IAAI;gBAAK;gBAC1B,MAAMC,YAAY,MAAMlG,QAAQ2F,mBAAmB,CAAC;oBAClDR,eAAef,QAAQjE,EAAE;oBACzBc;oBACAL;gBACF;gBAEAlB,OAAOwG,UAAU5F,MAAM,EAAE4C,IAAI,CAAC;gBAC9BxD,OAAOwG,UAAUtF,MAAM,EAAEoB,OAAO,CAACpB;gBACjClB,OAAOwG,UAAUrF,KAAK,EAAEqB,QAAQ;gBAChCxC,OAAOwG,UAAU5E,UAAU,EAAE+B,GAAG,CAACnB,QAAQ;gBACzCxC,OAAOwG,UAAUhF,WAAW,EAAEgB,QAAQ;YACxC;QACF;QAEAzC,SAAS,qBAAqB;YAC5BE,KAAK,uEAAuE;gBAC1E,MAAMsB,WAAW3B;gBACjB,MAAM8C,yBAAyBpC;gBAE/B,MAAMoE,UAAU,MAAMpE,QAAQqE,gBAAgB,CAAC;oBAC7CpD;oBACAqD,iBAAiB;gBACnB;gBACA,IAAI,CAACF,SAAS,MAAM,IAAIQ,MAAM;gBAE9B,MAAMuB,iBAAiB3E,KAAK8D,GAAG;gBAE/B,MAAMzE,QAAQ;oBAAEkF,SAAS;gBAAO;gBAChC,MAAMK,SAAS,MAAMpG,QAAQ8F,eAAe,CAAC;oBAC3CX,eAAef,QAAQjE,EAAE;oBACzBc;oBACAJ;gBACF;gBAEA,sCAAsC;gBACtCnB,OAAO0G,OAAO9F,MAAM,EAAE4C,IAAI,CAAC;gBAC3BxD,OAAO0G,OAAOvF,KAAK,EAAEmB,OAAO,CAACnB;gBAC7BnB,OAAO0G,OAAOxF,MAAM,EAAEsB,QAAQ;gBAC9BxC,OAAO0G,OAAO9E,UAAU,EAAEY,QAAQ;gBAClCxC,OAAO0G,OAAOnF,QAAQ,EAAEiB,QAAQ;gBAChCxC,OAAO0G,OAAO/E,SAAS,EAAEa,QAAQ,IAAI,+BAA+B;gBAEpExC,OAAO0G,OAAOlF,WAAW,EAAEmC,GAAG,CAACnB,QAAQ;gBACvC,IAAI,CAACkE,OAAOlF,WAAW,EAAE,MAAM,IAAI0D,MAAM;gBACzC,MAAMyB,UAAUD,OAAOlF,WAAW,CAAC8C,OAAO,KAAKmC;gBAC/CzG,OAAO2G,SAASC,sBAAsB,CAAC,MAAM,0BAA0B;gBACvE5G,OAAO2G,SAAStE,YAAY,CAAC;YAC/B;YAEApC,KAAK,8EAA8E;gBACjF,qCAAqC;gBACrC,MAAMK,UAAU,MAAMF;gBAEtB,MAAMsC,yBAAyBpC;gBAE/B,qBAAqB;gBACrB,IAAIiB,WAAW3B;gBACf,IAAI8E,UAAU,MAAMpE,QAAQqE,gBAAgB,CAAC;oBAC3CpD;oBACAqD,iBAAiB;gBACnB;gBACA,IAAI,CAACF,SAAS,MAAM,IAAIQ,MAAM;gBAC9BlF,OAAO0E,QAAQtD,QAAQ,EAAEoC,IAAI,CAAC;gBAE9B,MAAMqD,cAAc,MAAMvG,QAAQ8F,eAAe,CAAC;oBAChDX,eAAef,QAAQjE,EAAE;oBACzBc;oBACAJ,OAAO;wBAAEkF,SAAS;oBAAgB;gBACpC;gBAEArG,OAAO6G,YAAYjG,MAAM,EAAE4C,IAAI,CAAC;gBAEhC,MAAMb,MAAM,OAAO,+BAA+B;gBAElD,sBAAsB;gBACtBpB,WAAW3B;gBACX8E,UAAU,MAAMpE,QAAQqE,gBAAgB,CAAC;oBACvCpD;oBACAqD,iBAAiB;gBACnB;gBACA,IAAI,CAACF,SAAS,MAAM,IAAIQ,MAAM;gBAC9BlF,OAAO0E,QAAQtD,QAAQ,EAAEoC,IAAI,CAAC;gBAE9B,MAAMsD,mBAAmBhF,KAAK8D,GAAG;gBACjC,MAAMmB,eAAe,MAAMzG,QAAQ8F,eAAe,CAAC;oBACjDX,eAAef,QAAQjE,EAAE;oBACzBc;oBACAJ,OAAO;wBAAEkF,SAAS;oBAAiB;gBACrC;gBAEArG,OAAO+G,aAAanG,MAAM,EAAE4C,IAAI,CAAC;gBAEjC,oDAAoD;gBACpD,IAAI,CAACuD,aAAavF,WAAW,EAAE,MAAM,IAAI0D,MAAM;gBAC/C,MAAMyB,UAAUI,aAAavF,WAAW,CAAC8C,OAAO,KAAKwC;gBACrD9G,OAAO2G,SAASC,sBAAsB,CAAC,OAAO,0BAA0B;gBACxE5G,OAAO2G,SAAStE,YAAY,CAAC;gBAE7B,MAAMhC,SAASC;YACjB;QACF;QAEAP,SAAS,uBAAuB;YAC9BE,KAAK,0BAA0B;gBAC7B,MAAM+G,cAAc,MAAMhB,yBAAyB1F;gBAEnD,MAAMC,WAAwB;oBAC5BC,aAAawG,YAAYxG,WAAW;oBACpCC,IAAI;oBACJgF,eAAeuB,YAAYvG,EAAE;oBAC7BwG,UAAUrH;oBACVsH,MAAM;oBACNtG,QAAQ;oBACRE,QAAQ;wBAAEC,KAAK;oBAAM;oBACrBC,SAAS;oBACTE,QAAQ;oBACRC,OAAO;oBACPgG,6BAA6B;oBAC7BC,oBAAoB;oBACpBzF,WAAW;oBACXC,YAAY;oBACZC,WAAW,IAAIC;oBACfC,WAAW,IAAID;gBACjB;gBAEA,MAAME,UAAU,MAAM1B,QAAQ+G,iBAAiB,CAAC;oBAC9C5B,eAAelF,SAASkF,aAAa;oBACrC,uDAAuD;oBACvDlE,UAAUyF,YAAYzF,QAAQ;oBAC9B0F,UAAU1G,SAAS0G,QAAQ;oBAC3BC,MAAM3G,SAAS2G,IAAI;oBACnBpG,QAAQP,SAASO,MAAM;oBACvBE,SAAST,SAASS,OAAO;gBAC3B;gBACAhB,OAAOgC,QAAQvB,EAAE,EAAEyB,YAAY,CAAC;gBAChClC,OAAOmC,aAAaH,QAAQL,SAAS,GAAGU,YAAY,CAAC;gBACrDrC,OAAOmC,aAAaH,QAAQH,SAAS,GAAGQ,YAAY,CAAC;gBACrDrC,OAAOmC,aAAaH,QAAQD,SAAS,GAAGM,YAAY,CAAC;gBAErD9B,SAASE,EAAE,GAAGuB,QAAQvB,EAAE;gBACxBF,SAASoB,SAAS,GAAGK,QAAQL,SAAS;gBACtCpB,SAASsB,SAAS,GAAGG,QAAQH,SAAS;gBACtCtB,SAASwB,SAAS,GAAGC,QAAQD,SAAS;gBACtC/B,OAAOgC,SAASM,OAAO,CAAC/B;YAC1B;QACF;QAEAR,SAAS,oBAAoB;YAC3BE,KAAK,oCAAoC;gBACvC,MAAMyE,UAAU,MAAMsB,yBAAyB1F;gBAE/C,MAAM0B,UAAU,MAAM1B,QAAQ+G,iBAAiB,CAAC;oBAC9C5B,eAAef,QAAQjE,EAAE;oBACzB,uDAAuD;oBACvDc,UAAUmD,QAAQnD,QAAQ;oBAC1B0F,UAAUrH;oBACVsH,MAAM;oBACNpG,QAAQ,CAAC;oBACTE,SAAS;gBACX;gBAEA,MAAMsG,MAAM,MAAMhH,QAAQiH,cAAc,CAAC;oBACvCC,eAAexF,QAAQvB,EAAE;gBAC3B;gBACAT,OAAOsH,KAAKhF,OAAO,CAACN;YACtB;QACF;QAEAjC,SAAS,sBAAsB;YAC7BD,UAAU;gBACRQ,UAAU,MAAMF;YAClB;YAEAP,SAAS;gBACP,MAAMQ,SAASC;YACjB;YAEAL,KAAK,gDAAgD;gBACnD,MAAMyE,UAAU,MAAMsB,yBAAyB1F;gBAE/C,MAAMmC,QAAQ,MAAMnC,QAAQ+G,iBAAiB,CAAC;oBAC5C5B,eAAef,QAAQjE,EAAE;oBACzB,uDAAuD;oBACvDc,UAAUmD,QAAQnD,QAAQ;oBAC1B0F,UAAUrH;oBACVsH,MAAM;oBACNpG,QAAQ,CAAC;oBACTE,SAAS;gBACX;gBACA,MAAMV,QAAQmH,mBAAmB,CAAC;oBAChChC,eAAef,QAAQjE,EAAE;oBACzB+G,eAAe/E,MAAMhC,EAAE;oBACvB,uDAAuD;oBACvDc,UAAUmD,QAAQnD,QAAQ;oBAC1BL,QAAQ;wBAAEqF,IAAI;oBAAK;gBACrB;gBAEA,MAAM5D,MAAM,KAAK,8BAA8B;gBAE/C,MAAMC,SAAS,MAAMtC,QAAQ+G,iBAAiB,CAAC;oBAC7C5B,eAAef,QAAQjE,EAAE;oBACzB,uDAAuD;oBACvDc,UAAUmD,QAAQnD,QAAQ;oBAC1B0F,UAAUrH;oBACVsH,MAAM;oBACNpG,QAAQ,CAAC;oBACTE,SAAS;gBACX;gBAEA,MAAM6B,SAAS,MAAMvC,QAAQoH,gBAAgB,CAAC;oBAC5CjC,eAAef,QAAQjE,EAAE;gBAC3B;gBACA,MAAMkH,kBAAkB9E,OAAOG,IAAI,CAACC,GAAG,CAAC,CAAC2E,OAASA,KAAKX,QAAQ;gBAC/DjH,OAAO2H,iBAAiBrF,OAAO,CAAC;oBAACG,MAAMwE,QAAQ;oBAAErE,OAAOqE,QAAQ;iBAAC;YACnE;YAEAhH,KAAK,2BAA2B;gBAC9B,MAAMyE,UAAU,MAAMsB,yBAAyB1F;gBAE/C,IAAK,IAAI8C,IAAI,GAAGA,IAAI,GAAGA,IAAK;oBAC1B,MAAM9C,QAAQ+G,iBAAiB,CAAC;wBAC9B5B,eAAef,QAAQjE,EAAE;wBACzB,uDAAuD;wBACvDc,UAAUmD,QAAQnD,QAAQ;wBAC1B0F,UAAU,CAAC,KAAK,EAAEY,OAAOzE,IAAI;wBAC7B8D,MAAM;wBACNpG,QAAQ,CAAC;wBACTE,SAAS;oBACX;oBAEA,MAAM2B,MAAM,KAAK,2BAA2B;gBAC9C;gBAEA,KAAK;gBACL,MAAMW,QAAQ,MAAMhD,QAAQoH,gBAAgB,CAAC;oBAC3CjC,eAAef,QAAQjE,EAAE;oBACzB8C,OAAO;gBACT;gBACAvD,OAAOsD,MAAMN,IAAI,EAAEd,YAAY,CAAC;gBAChClC,OAAOsD,MAAMN,IAAI,CAAC,EAAE,EAAEiE,UAAUzD,IAAI,CAAC;gBACrCxD,OAAOsD,MAAMN,IAAI,CAAC,EAAE,EAAEiE,UAAUzD,IAAI,CAAC;gBACrCxD,OAAOsD,MAAMG,UAAU,CAACC,IAAI,EAAEC,GAAG,CAACnB,QAAQ;gBAC1CxC,OAAOsD,MAAMG,UAAU,CAACG,IAAI,EAAEpB,QAAQ;gBAEtC,KAAK;gBACL,MAAMqB,QAAQ,MAAMvD,QAAQoH,gBAAgB,CAAC;oBAC3CjC,eAAef,QAAQjE,EAAE;oBACzB8C,OAAO;oBACP,uDAAuD;oBACvDO,OAAOR,MAAMG,UAAU,CAACC,IAAI;gBAC9B;gBACA1D,OAAO6D,MAAMb,IAAI,EAAEd,YAAY,CAAC;gBAChClC,OAAO6D,MAAMb,IAAI,CAAC,EAAE,EAAEiE,UAAUzD,IAAI,CAAC;gBACrCxD,OAAO6D,MAAMb,IAAI,CAAC,EAAE,EAAEiE,UAAUzD,IAAI,CAAC;gBACrCxD,OAAO6D,MAAMJ,UAAU,CAACC,IAAI,EAAEC,GAAG,CAACnB,QAAQ;gBAC1CxC,OAAO6D,MAAMJ,UAAU,CAACG,IAAI,EAAED,GAAG,CAACnB,QAAQ;gBAE1C,KAAK;gBACL,MAAMuB,QAAQ,MAAMzD,QAAQoH,gBAAgB,CAAC;oBAC3CjC,eAAef,QAAQjE,EAAE;oBACzB8C,OAAO;oBACP,uDAAuD;oBACvDO,OAAOD,MAAMJ,UAAU,CAACC,IAAI;gBAC9B;gBACA1D,OAAO+D,MAAMf,IAAI,EAAEd,YAAY,CAAC;gBAChClC,OAAO+D,MAAMf,IAAI,CAAC,EAAE,EAAEiE,UAAUzD,IAAI,CAAC;gBACrCxD,OAAO+D,MAAMN,UAAU,CAACC,IAAI,EAAElB,QAAQ;gBACtCxC,OAAO+D,MAAMN,UAAU,CAACG,IAAI,EAAED,GAAG,CAACnB,QAAQ;gBAE1C,WAAW;gBACX,MAAMwB,YAAY,MAAM1D,QAAQoH,gBAAgB,CAAC;oBAC/CjC,eAAef,QAAQjE,EAAE;oBACzB8C,OAAO;oBACP,uDAAuD;oBACvDU,QAAQF,MAAMN,UAAU,CAACG,IAAI;gBAC/B;gBACA5D,OAAOgE,UAAUhB,IAAI,EAAEd,YAAY,CAAC;gBACpClC,OAAOgE,UAAUhB,IAAI,CAAC,EAAE,EAAEiE,UAAUzD,IAAI,CAAC;gBACzCxD,OAAOgE,UAAUhB,IAAI,CAAC,EAAE,EAAEiE,UAAUzD,IAAI,CAAC;gBACzCxD,OAAOgE,UAAUP,UAAU,CAACC,IAAI,EAAEpB,OAAO,CAACuB,MAAMJ,UAAU,CAACC,IAAI;gBAC/D1D,OAAOgE,UAAUP,UAAU,CAACG,IAAI,EAAEtB,OAAO,CAACuB,MAAMJ,UAAU,CAACG,IAAI;YACjE;YAEA3D,KAAK,yBAAyB;gBAC5B,MAAMyE,UAAU,MAAMsB,yBAAyB1F;gBAC/C,MAAMuC,SAAS,MAAMvC,QAAQoH,gBAAgB,CAAC;oBAC5CjC,eAAef,QAAQjE,EAAE;gBAC3B;gBACAT,OAAO6C,OAAOG,IAAI,EAAEd,YAAY,CAAC;gBACjClC,OAAO6C,OAAOY,UAAU,CAACC,IAAI,EAAElB,QAAQ;gBACvCxC,OAAO6C,OAAOY,UAAU,CAACG,IAAI,EAAEpB,QAAQ;YACzC;YAEAvC,KAAK,6BAA6B;gBAChC,MAAMyE,UAAU,MAAMsB,yBAAyB1F;gBAC/C,MAAMA,QAAQ+G,iBAAiB,CAAC;oBAC9B5B,eAAef,QAAQjE,EAAE;oBACzB,uDAAuD;oBACvDc,UAAUmD,QAAQnD,QAAQ;oBAC1B0F,UAAU;oBACVC,MAAM;oBACNpG,QAAQ,CAAC;oBACTE,SAAS;gBACX;gBAEA,MAAM6B,SAAS,MAAMvC,QAAQoH,gBAAgB,CAAC;oBAC5CjC,eAAef,QAAQjE,EAAE;oBACzB8C,OAAO;gBACT;gBACAvD,OAAO6C,OAAOG,IAAI,EAAEd,YAAY,CAAC;gBACjClC,OAAO6C,OAAOY,UAAU,CAACC,IAAI,EAAElB,QAAQ;gBACvCxC,OAAO6C,OAAOY,UAAU,CAACG,IAAI,EAAEpB,QAAQ;YACzC;QACF;QAEAzC,SAAS,yBAAyB;YAChCD,UAAU;gBACRQ,UAAU,MAAMF;YAClB;YAEAP,SAAS;gBACP,MAAMQ,SAASC;YACjB;YAEAL,KAAK,4CAA4C;gBAC/C,MAAMyE,UAAU,MAAMsB,yBAAyB1F;gBAE/C,MAAM0B,UAAU,MAAM1B,QAAQ+G,iBAAiB,CAAC;oBAC9C5B,eAAef,QAAQjE,EAAE;oBACzB,uDAAuD;oBACvDc,UAAUmD,QAAQnD,QAAQ;oBAC1B0F,UAAUrH;oBACVsH,MAAM;oBACNpG,QAAQ,CAAC;oBACTE,SAAS;gBACX;gBACA,MAAME,SAAS;oBAAE4G,KAAK;gBAAM;gBAE5B,MAAMtB,YAAY,MAAMlG,QAAQmH,mBAAmB,CAAC;oBAClDhC,eAAef,QAAQjE,EAAE;oBACzB+G,eAAexF,QAAQvB,EAAE;oBACzB,uDAAuD;oBACvDc,UAAUmD,QAAQnD,QAAQ;oBAC1BL;gBACF;gBAEAlB,OAAOwG,UAAU5F,MAAM,EAAE4C,IAAI,CAAC;gBAC9BxD,OAAOwG,UAAUtF,MAAM,EAAEoB,OAAO,CAACpB;gBACjClB,OAAOwG,UAAUrF,KAAK,EAAEqB,QAAQ;gBAChCxC,OAAOwG,UAAU5E,UAAU,EAAE+B,GAAG,CAACnB,QAAQ;gBAEzC,MAAMsD,UAAU,MAAMxF,QAAQiH,cAAc,CAAC;oBAC3CC,eAAexF,QAAQvB,EAAE;gBAC3B;gBACAT,OAAO8F,SAASlF,QAAQ4C,IAAI,CAAC;gBAC7BxD,OAAO8F,SAAS5E,QAAQoB,OAAO,CAACpB;gBAChClB,OAAO8F,SAAS3E,OAAOqB,QAAQ;gBAC/BxC,OAAO8F,SAASlE,YAAY+B,GAAG,CAACnB,QAAQ;YAC1C;YAEAvC,KAAK,uCAAuC;gBAC1C,MAAMK,UAAU,MAAMF;gBACtB,MAAMsC,yBAAyBpC;gBAE/B,uDAAuD;gBACvD,MAAMoE,UAAU,MAAMpE,QAAQqE,gBAAgB,CAAC;oBAC7CpD,UAAU3B;oBACVgF,iBAAiB;gBACnB;gBACA,IAAI,CAACF,SAAS,MAAM,IAAIQ,MAAM;gBAE9B,MAAM6C,cAAc,MAAMzH,QAAQ+G,iBAAiB,CAAC;oBAClD5B,eAAef,QAAQjE,EAAE;oBACzB,uDAAuD;oBACvDc,UAAUmD,QAAQnD,QAAQ;oBAC1B0F,UAAUrH;oBACVsH,MAAM;oBACNpG,QAAQ,CAAC;oBACTE,SAAS;gBACX;gBAEA,kDAAkD;gBAClD,MAAMV,QAAQ2F,mBAAmB,CAAC;oBAChCR,eAAef,QAAQjE,EAAE;oBACzB,uDAAuD;oBACvDc,UAAUmD,QAAQnD,QAAQ;oBAC1BL,QAAQ;gBACV;gBAEA,mCAAmC;gBACnC,MAAMlB,OACJM,QAAQmH,mBAAmB,CAAC;oBAC1BhC,eAAef,QAAQjE,EAAE;oBACzB+G,eAAeO,YAAYtH,EAAE;oBAC7B,uDAAuD;oBACvDc,UAAUmD,QAAQnD,QAAQ;oBAC1BL,QAAQ;wBAAE4G,KAAK;oBAAM;gBACvB,IACA5B,OAAO,CAACC,OAAO,CAAC;gBAElB,MAAM9F,SAASC;YACjB;YAEAL,KAAK,2CAA2C;gBAC9C,MAAMK,UAAU,MAAMF;gBACtB,MAAMsE,UAAU,MAAMsB,yBAAyB1F;gBAE/C,MAAMN,OACJM,QAAQmH,mBAAmB,CAAC;oBAC1BhC,eAAef,QAAQjE,EAAE;oBACzB+G,eAAe5H;oBACf,uDAAuD;oBACvD2B,UAAUmD,QAAQnD,QAAQ;oBAC1BL,QAAQ;wBAAE4G,KAAK;oBAAM;gBACvB,IACA5B,OAAO,CAACC,OAAO,CAAC;gBAElB,MAAM9F,SAASC;YACjB;QACF;QAEAP,SAAS,qBAAqB;YAC5BD,UAAU;gBACRQ,UAAU,MAAMF;YAClB;YAEAP,SAAS;gBACP,MAAMQ,SAASC;YACjB;YAEAL,KAAK,yCAAyC;gBAC5C,MAAMyE,UAAU,MAAMsB,yBAAyB1F;gBAE/C,MAAM0B,UAAU,MAAM1B,QAAQ+G,iBAAiB,CAAC;oBAC9C5B,eAAef,QAAQjE,EAAE;oBACzB,uDAAuD;oBACvDc,UAAUmD,QAAQnD,QAAQ;oBAC1B0F,UAAUrH;oBACVsH,MAAM;oBACNpG,QAAQ,CAAC;oBACTE,SAAS;gBACX;gBACA,MAAMG,QAAQ;oBAAEkF,SAAS;gBAAO;gBAEhC,MAAMK,SAAS,MAAMpG,QAAQ0H,eAAe,CAAC;oBAC3CvC,eAAef,QAAQjE,EAAE;oBACzB+G,eAAexF,QAAQvB,EAAE;oBACzB,uDAAuD;oBACvDc,UAAUmD,QAAQnD,QAAQ;oBAC1BJ;gBACF;gBAEAnB,OAAO0G,OAAO9F,MAAM,EAAE4C,IAAI,CAAC;gBAC3BxD,OAAO0G,OAAOvF,KAAK,EAAEmB,OAAO,CAACnB;gBAC7BnB,OAAO0G,OAAOxF,MAAM,EAAEsB,QAAQ;gBAC9BxC,OAAO0G,OAAO9E,UAAU,EAAE+B,GAAG,CAACnB,QAAQ;gBAEtC,MAAMsD,UAAU,MAAMxF,QAAQiH,cAAc,CAAC;oBAC3CC,eAAexF,QAAQvB,EAAE;gBAC3B;gBACAT,OAAO8F,SAASlF,QAAQ4C,IAAI,CAAC;gBAC7BxD,OAAO8F,SAAS3E,OAAOmB,OAAO,CAACnB;gBAC/BnB,OAAO8F,SAAS5E,QAAQsB,QAAQ;gBAChCxC,OAAO8F,SAASlE,YAAY+B,GAAG,CAACnB,QAAQ;YAC1C;YAEAvC,KAAK,uCAAuC;gBAC1C,MAAMK,UAAU,MAAMF;gBACtB,MAAMsC,yBAAyBpC;gBAE/B,uDAAuD;gBACvD,MAAMoE,UAAU,MAAMpE,QAAQqE,gBAAgB,CAAC;oBAC7CpD,UAAU3B;oBACVgF,iBAAiB;gBACnB;gBACA,IAAI,CAACF,SAAS,MAAM,IAAIQ,MAAM;gBAE9B,MAAM6C,cAAc,MAAMzH,QAAQ+G,iBAAiB,CAAC;oBAClD5B,eAAef,QAAQjE,EAAE;oBACzB,uDAAuD;oBACvDc,UAAUmD,QAAQnD,QAAQ;oBAC1B0F,UAAUrH;oBACVsH,MAAM;oBACNpG,QAAQ,CAAC;oBACTE,SAAS;gBACX;gBAEA,kDAAkD;gBAClD,MAAMV,QAAQ2F,mBAAmB,CAAC;oBAChCR,eAAef,QAAQjE,EAAE;oBACzB,uDAAuD;oBACvDc,UAAUmD,QAAQnD,QAAQ;oBAC1BL,QAAQ;gBACV;gBAEA,+BAA+B;gBAC/B,MAAMlB,OACJM,QAAQ0H,eAAe,CAAC;oBACtBvC,eAAef,QAAQjE,EAAE;oBACzB+G,eAAeO,YAAYtH,EAAE;oBAC7B,uDAAuD;oBACvDc,UAAUmD,QAAQnD,QAAQ;oBAC1BJ,OAAO;wBAAEkF,SAAS;oBAAO;gBAC3B,IACAH,OAAO,CAACC,OAAO,CAAC;gBAElB,MAAM9F,SAASC;YACjB;YAEAL,KAAK,2CAA2C;gBAC9C,MAAMK,UAAU,MAAMF;gBACtB,MAAMsE,UAAU,MAAMsB,yBAAyB1F;gBAE/C,MAAMN,OACJM,QAAQ0H,eAAe,CAAC;oBACtBvC,eAAef,QAAQjE,EAAE;oBACzB+G,eAAe5H;oBACf,uDAAuD;oBACvD2B,UAAUmD,QAAQnD,QAAQ;oBAC1BJ,OAAO;wBAAEkF,SAAS;oBAAO;gBAC3B,IACAH,OAAO,CAACC,OAAO,CAAC;gBAElB,MAAM9F,SAASC;YACjB;QACF;QAEAP,SAAS,eAAe;YACtBD,UAAU;gBACRQ,UAAU,MAAMF;YAClB;YAEAP,SAAS;gBACP,MAAMQ,SAASC;YACjB;YAEAL,KAAK,0CAA0C;gBAC7C,MAAMgI,WAAW,IAAInG,KAAKA,KAAK8D,GAAG,KAAK,SAAS,cAAc;gBAC9D,MAAM5D,UAAU,MAAM1B,QAAQ2B,iBAAiB,CAAC;oBAC9CvB,cAAcd;oBACde,SAAS;oBACTE,gBAAgB;oBAChBI,OAAO;oBACPH,QAAQ,CAAC;oBACTE,SAAS;oBACTQ,aAAa;oBACbE,YAAYuG;gBACd;gBAEAjI,OAAOgC,QAAQN,UAAU,EAAEiC,GAAG,CAACnB,QAAQ;gBACvCxC,OAAOgC,QAAQN,UAAU,EAAE4C,WAAWd,IAAI,CAACyE,SAAS3D,OAAO;YAC7D;YAEArE,KAAK,oDAAoD;gBACvD,MAAMK,UAAU,MAAMF;gBAEtB,MAAM8H,eAAe,IAAIpG,KAAKA,KAAK8D,GAAG,KAAK;gBAC3C,MAAMtF,QAAQ2B,iBAAiB,CAAC;oBAC9BvB,cAAcd;oBACde,SAAS;oBACTE,gBAAgB;oBAChBI,OAAO;oBACPH,QAAQ,CAAC;oBACTE,SAAS;oBACTQ,aAAa;oBACbE,YAAYwG;gBACd;gBAEA,MAAMxD,UAAU,MAAMpE,QAAQqE,gBAAgB,CAAC;oBAC7CpD,UAAU3B;oBACVgF,iBAAiB;gBACnB;gBAEA5E,OAAO0E,SAASlC,QAAQ;gBAExB,MAAMnC,SAASC;YACjB;YAEAL,KAAK,gEAAgE;gBACnE,MAAMK,UAAU,MAAMF;gBAEtB,MAAM8H,eAAe,IAAIpG,KAAKA,KAAK8D,GAAG,KAAK;gBAC3C,MAAM5D,UAAU,MAAM1B,QAAQ2B,iBAAiB,CAAC;oBAC9CvB,cAAcd;oBACde,SAAS;oBACTE,gBAAgB;oBAChBI,OAAO;oBACPH,QAAQ,CAAC;oBACTE,SAAS;oBACTQ,aAAa;oBACbE,YAAYwG;gBACd;gBAEA,2CAA2C;gBAC3C,MAAMxD,UAAU,MAAMpE,QAAQqE,gBAAgB,CAAC;oBAC7CpD,UAAU3B;oBACVgF,iBAAiB;gBACnB;gBACA5E,OAAO0E,SAASlC,QAAQ;gBAExB,iCAAiC;gBACjC,MAAMkE,SAAS,MAAMpG,QAAQyF,cAAc,CAAC;oBAC1CN,eAAezD,QAAQvB,EAAE;gBAC3B;gBACAT,OAAO0G,QAAQ9F,QAAQ4C,IAAI,CAAC;gBAC5BxD,OAAO0G,QAAQvF,OAAOmB,OAAO,CAAC;oBAC5B+D,SAAS;gBACX;gBACArG,OAAO0G,QAAQ9E,YAAY+B,GAAG,CAACnB,QAAQ;gBACvCxC,OAAO0G,QAAQlF,aAAagB,QAAQ;gBAEpC,MAAMnC,SAASC;YACjB;YAEAL,KAAK,gFAAgF;gBACnF,MAAMK,UAAU,MAAMF;gBAEtB,MAAM6H,WAAW,IAAInG,KAAKA,KAAK8D,GAAG,KAAK,MAAM,iBAAiB;gBAC9D,MAAM5D,UAAU,MAAM1B,QAAQ2B,iBAAiB,CAAC;oBAC9CvB,cAAcd;oBACde,SAAS;oBACTE,gBAAgB;oBAChBI,OAAO;oBACPH,QAAQ,CAAC;oBACTE,SAAS;oBACTQ,aAAa;oBACbE,YAAYuG;gBACd;gBAEA,MAAM1G,WAAW3B;gBACjB,MAAM8E,UAAU,MAAMpE,QAAQqE,gBAAgB,CAAC;oBAC7CpD;oBACAqD,iBAAiB;gBACnB;gBACA5E,OAAO0E,SAASf,GAAG,CAACnB,QAAQ;gBAE5B,2FAA2F;gBAC3F,MAAMkE,SAAS,MAAMpG,QAAQ8F,eAAe,CAAC;oBAC3CX,eAAezD,QAAQvB,EAAE;oBACzBc;oBACAJ,OAAO;wBAAEkF,SAAS;oBAAa;gBACjC;gBAEArG,OAAO0G,OAAO9F,MAAM,EAAE4C,IAAI,CAAC;gBAC3BxD,OAAO0G,OAAOlF,WAAW,EAAEgB,QAAQ;gBACnCxC,OAAO0G,OAAO9E,UAAU,EAAE+B,GAAG,CAACnB,QAAQ;gBACtCxC,OAAO0G,OAAO/E,SAAS,EAAEa,QAAQ,IAAI,+BAA+B;gBAEpE,MAAMnC,SAASC;YACjB;YAEAL,KAAK,4EAA4E;gBAC/E,MAAMK,UAAU,MAAMF;gBAEtB,MAAM6H,WAAW,IAAInG,KAAKA,KAAK8D,GAAG,KAAK,OAAO,eAAe;gBAC7D,MAAM5D,UAAU,MAAM1B,QAAQ2B,iBAAiB,CAAC;oBAC9CvB,cAAcd;oBACde,SAAS;oBACTE,gBAAgB;oBAChBI,OAAO;oBACPH,QAAQ,CAAC;oBACTE,SAAS;oBACTQ,aAAa;oBACbE,YAAYuG;gBACd;gBAEA,MAAM1G,WAAW3B;gBACjB,MAAM8E,UAAU,MAAMpE,QAAQqE,gBAAgB,CAAC;oBAC7CpD;oBACAqD,iBAAiB;gBACnB;gBACA5E,OAAO0E,SAASf,GAAG,CAACnB,QAAQ;gBAE5B,oEAAoE;gBACpE,MAAMkE,SAAS,MAAMpG,QAAQ8F,eAAe,CAAC;oBAC3CX,eAAezD,QAAQvB,EAAE;oBACzBc;oBACAJ,OAAO;wBAAEkF,SAAS;oBAAa;gBACjC;gBAEArG,OAAO0G,OAAO9F,MAAM,EAAE4C,IAAI,CAAC;gBAC3BxD,OAAO0G,OAAOlF,WAAW,EAAEmC,GAAG,CAACnB,QAAQ;gBACvCxC,OAAO0G,OAAO9E,UAAU,EAAEY,QAAQ;gBAElC,MAAMnC,SAASC;YACjB;QACF;QAEAP,SAAS,uBAAuB;YAC9BE,KAAK,kCAAkC;gBACrC,MAAMK,UAAU,MAAMF;gBAEtB,MAAM4B,UAAU,MAAMU,yBAAyBpC;gBAC/CN,OAAOgC,QAAQpB,MAAM,EAAE4C,IAAI,CAAC;gBAE5B,MAAM2E,WAAW,MAAM7H,QAAQgG,iBAAiB,CAAC;oBAC/Cb,eAAezD,QAAQvB,EAAE;gBAC3B;gBAEAT,OAAOmI,SAASvH,MAAM,EAAE4C,IAAI,CAAC;gBAC7BxD,OAAOmI,SAAS5G,QAAQ,EAAEiB,QAAQ;gBAClCxC,OAAOmI,SAAS3G,WAAW,EAAEgB,QAAQ;gBACrCxC,OAAOmI,SAASvG,UAAU,EAAE+B,GAAG,CAACnB,QAAQ;gBACxCxC,OAAOmC,aAAagG,SAASvG,UAAU,GAAGS,YAAY,CAAC;gBAEvD,MAAMhC,SAASC;YACjB;YAEAL,KAAK,kCAAkC;gBACrC,MAAMK,UAAU,MAAMF;gBAEtB,MAAM4B,UAAU,MAAMgE,yBAAyB1F;gBAC/CN,OAAOgC,QAAQpB,MAAM,EAAE4C,IAAI,CAAC;gBAC5BxD,OAAOgC,QAAQT,QAAQ,EAAEoC,GAAG,CAACnB,QAAQ;gBAErC,MAAM2F,WAAW,MAAM7H,QAAQgG,iBAAiB,CAAC;oBAC/Cb,eAAezD,QAAQvB,EAAE;gBAC3B;gBAEAT,OAAOmI,SAASvH,MAAM,EAAE4C,IAAI,CAAC;gBAC7BxD,OAAOmI,SAAS5G,QAAQ,EAAEiB,QAAQ;gBAClCxC,OAAOmI,SAAS3G,WAAW,EAAEgB,QAAQ;gBACrCxC,OAAOmI,SAASvG,UAAU,EAAE+B,GAAG,CAACnB,QAAQ;gBAExC,MAAMnC,SAASC;YACjB;YAEAL,KAAK,mCAAmC;gBACtC,MAAMK,UAAU,MAAMF;gBAEtB,MAAMsE,UAAU,MAAMsB,yBAAyB1F;gBAE/C,wBAAwB;gBACxB,MAAMqF,aAAa,IAAI7D,KAAKA,KAAK8D,GAAG,KAAK,SAAS,oBAAoB;gBACtE,MAAMwC,WAAW,MAAM9H,QAAQuF,gBAAgB,CAAC;oBAC9CJ,eAAef,QAAQjE,EAAE;oBACzBc,UAAUmD,QAAQnD,QAAQ,IAAI;oBAC9BC,aAAamE;gBACf;gBACA3F,OAAOoI,SAASxH,MAAM,EAAE4C,IAAI,CAAC;gBAE7B,MAAM2E,WAAW,MAAM7H,QAAQgG,iBAAiB,CAAC;oBAC/Cb,eAAe2C,SAAS3H,EAAE;gBAC5B;gBAEAT,OAAOmI,SAASvH,MAAM,EAAE4C,IAAI,CAAC;gBAC7BxD,OAAOmI,SAAS5G,QAAQ,EAAEiB,QAAQ;gBAClCxC,OAAOmI,SAAS3G,WAAW,EAAEgB,QAAQ;gBACrCxC,OAAOmI,SAASvG,UAAU,EAAE+B,GAAG,CAACnB,QAAQ;gBAExC,MAAMnC,SAASC;YACjB;YAEAL,KAAK,wDAAwD;gBAC3D,MAAMK,UAAU,MAAMF;gBAEtB,MAAMsE,UAAU,MAAMsB,yBAAyB1F;gBAE/C,oBAAoB;gBACpB,MAAMA,QAAQ2F,mBAAmB,CAAC;oBAChCR,eAAef,QAAQjE,EAAE;oBACzBc,UAAUmD,QAAQnD,QAAQ,IAAI;oBAC9BL,QAAQ;wBAAEmH,QAAQ;oBAAU;gBAC9B;gBAEA,MAAMrI,OACJM,QAAQgG,iBAAiB,CAAC;oBACxBb,eAAef,QAAQjE,EAAE;gBAC3B,IACAyF,OAAO,CAACC,OAAO,CAAC;gBAElB,MAAM9F,SAASC;YACjB;YAEAL,KAAK,qDAAqD;gBACxD,MAAMK,UAAU,MAAMF;gBAEtB,6DAA6D;gBAC7D,MAAMkI,uBAAuB,MAAMhI,QAAQ2B,iBAAiB,CAAC;oBAC3DvB,cAAcd;oBACde,SAAS;oBACTE,gBAAgB;oBAChBI,OAAO;oBACPH,QAAQ,CAAC;oBACTE,SAAS;oBACTQ,aAAa;oBACbE,YAAY,IAAII,KAAKA,KAAK8D,GAAG,KAAK;gBACpC;gBAEA,kEAAkE;gBAClE,MAAMlB,UAAU,MAAMpE,QAAQqE,gBAAgB,CAAC;oBAC7CpD,UAAU3B;oBACVgF,iBAAiB;gBACnB;gBAEA,sCAAsC;gBACtC,IAAIF,SAASnD,UAAU;oBACrB,MAAMjB,QAAQ8F,eAAe,CAAC;wBAC5BX,eAAef,QAAQjE,EAAE;wBACzBc,UAAUmD,QAAQnD,QAAQ;wBAC1BJ,OAAO;4BAAEkF,SAAS;wBAAa;oBACjC;gBACF;gBAEA,0CAA0C;gBAC1C,MAAMkC,YAAY,MAAMjI,QAAQyF,cAAc,CAAC;oBAC7CN,eAAe6C,qBAAqB7H,EAAE;gBACxC;gBAEA,IAAI8H,WAAW3H,WAAW,UAAU;oBAClC,MAAMZ,OACJM,QAAQgG,iBAAiB,CAAC;wBACxBb,eAAe8C,UAAU9H,EAAE;oBAC7B,IACAyF,OAAO,CAACC,OAAO,CAAC;gBACpB;gBAEA,MAAM9F,SAASC;YACjB;YAEAL,KAAK,iEAAiE;gBACpE,MAAMK,UAAU,MAAMF;gBAEtB,MAAM4B,UAAU,MAAMU,yBAAyBpC;gBAE/C,MAAMkI,cAAc,MAAMlI,QAAQgG,iBAAiB,CAAC;oBAClDb,eAAezD,QAAQvB,EAAE;gBAC3B;gBACAT,OAAOwI,YAAY5H,MAAM,EAAE4C,IAAI,CAAC;gBAEhC,MAAMiF,eAAe,MAAMnI,QAAQgG,iBAAiB,CAAC;oBACnDb,eAAezD,QAAQvB,EAAE;gBAC3B;gBACAT,OAAOyI,aAAa7H,MAAM,EAAE4C,IAAI,CAAC;gBACjCxD,OAAOyI,aAAahI,EAAE,EAAE+C,IAAI,CAACgF,YAAY/H,EAAE;gBAE3C,MAAMJ,SAASC;YACjB;YAEAL,KAAK,2DAA2D;gBAC9D,MAAMK,UAAU,MAAMF;gBAEtB,MAAMsI,gBAAgB9I;gBAEtB,MAAMI,OACJM,QAAQgG,iBAAiB,CAAC;oBACxBb,eAAeiD;gBACjB,IACAxC,OAAO,CAACC,OAAO,CAAC,CAAC,aAAa,EAAEuC,cAAc,eAAe,CAAC;gBAEhE,MAAMrI,SAASC;YACjB;YAEAL,KAAK,+CAA+C;gBAClD,MAAMK,UAAU,MAAMF;gBAEtB,MAAM4B,UAAU,MAAMU,yBAAyBpC;gBAE/C,sBAAsB;gBACtB,MAAMA,QAAQgG,iBAAiB,CAAC;oBAC9Bb,eAAezD,QAAQvB,EAAE;gBAC3B;gBAEA,oBAAoB;gBACpB,MAAMiE,UAAU,MAAMpE,QAAQqE,gBAAgB,CAAC;oBAC7CpD,UAAU3B;oBACVgF,iBAAiB;gBACnB;gBAEA,yCAAyC;gBACzC5E,OAAO0E,SAASlC,QAAQ;gBAExB,MAAMnC,SAASC;YACjB;QACF;IACF;AACF;AAEA;;;;CAIC,GACD,eAAeoC,yBAAyB0B,CAAU;IAChD,OAAO,MAAMA,EAAEnC,iBAAiB,CAAC;QAC/BvB,cAAcd;QACde,SAAS;QACTE,gBAAgB;QAChBI,OAAO;QACPH,QAAQ,CAAC;QACTE,SAAS;QACTQ,aAAa;QACbE,YAAY;IACd;AACF;AAEA;;;;CAIC,GACD,eAAesE,yBAAyB5B,CAAU;IAChD,MAAM1B,yBAAyB0B;IAE/B,MAAMM,UAAU,MAAMN,EAAEO,gBAAgB,CAAC;QACvCpD,UAAU3B;QACVgF,iBAAiB;IACnB;IAEA,IAAI,CAACF,SAAS,MAAM,IAAIQ,MAAM;IAE9B,OAAOR;AACT;AAEA;;;;CAIC,GACD,SAASvC,aAAawG,IAA6B;IACjD,IAAI,CAACA,MAAM,OAAOjD;IAClB,OAAOkD,KAAKC,GAAG,CAAC,AAAC/G,CAAAA,KAAK8D,GAAG,KAAK+C,KAAKrE,OAAO,EAAC,IAAK;AAClD;AAEA;;;CAGC,GACD,SAAS7C;IACP,MAAMqH,IAAI,IAAIhH;IACdgH,EAAEC,WAAW,CAACD,EAAEE,WAAW,KAAK;IAChC,OAAOF;AACT;AAEA;;;;CAIC,GACD,SAASnG,MAAMsG,EAAU;IACvB,OAAO,IAAIC,QAAQ,CAACC,UAAYC,WAAWD,SAASF;AACtD"}
|
|
1
|
+
{"version":3,"sources":["../../src/database/backend.testsuite.ts"],"sourcesContent":["import { randomUUID } from \"node:crypto\";\nimport { afterAll, beforeAll, describe, expect, test } from \"vitest\";\nimport type { Backend } from \"..//backend\";\nimport type { SerializableRetryPolicy } from \"../core/retry\";\nimport type { StepAttempt } from \"../core/step\";\nimport type { WorkflowRun } from \"../core/workflow\";\n\n/**\n * Options for the Backend test suite.\n */\nexport interface TestBackendOptions {\n /**\n * Creates a new isolated Backend instance.\n */\n setup: () => Promise<Backend>;\n /**\n * Cleans up a Backend instance.\n */\n teardown: (backend: Backend) => Promise<void>;\n}\n\n/**\n * Runs the Backend test suite.\n * @param options - Test suite options\n */\nexport function testBackend(options: TestBackendOptions): void {\n const { setup, teardown } = options;\n describe(\"Backend\", () => {\n let backend: Backend;\n\n beforeAll(async () => {\n backend = await setup();\n });\n\n afterAll(async () => {\n await teardown(backend);\n });\n\n describe(\"createWorkflowRun()\", () => {\n test(\"creates a workflow run\", async () => {\n const expected: WorkflowRun = {\n namespaceId: \"\", // -\n id: \"\", // -\n workflowName: randomUUID(),\n version: randomUUID(),\n status: \"pending\",\n idempotencyKey: randomUUID(),\n config: { key: \"val\" },\n context: { key: \"val\" },\n input: { key: \"val\" },\n output: null,\n error: null,\n attempts: 0,\n parentStepAttemptNamespaceId: null,\n parentStepAttemptId: null,\n workerId: null,\n availableAt: newDateInOneYear(), // -\n deadlineAt: newDateInOneYear(),\n startedAt: null,\n finishedAt: null,\n createdAt: new Date(), // -\n updatedAt: new Date(), // -\n };\n\n // Create with all fields\n const created = await backend.createWorkflowRun({\n workflowName: expected.workflowName,\n version: expected.version,\n idempotencyKey: expected.idempotencyKey,\n input: expected.input,\n config: expected.config,\n context: expected.context,\n availableAt: expected.availableAt,\n deadlineAt: expected.deadlineAt,\n });\n expect(created.namespaceId).toHaveLength(36);\n expect(created.id).toHaveLength(36);\n expect(deltaSeconds(created.availableAt)).toBeGreaterThan(1);\n expect(deltaSeconds(created.createdAt)).toBeLessThan(1);\n expect(deltaSeconds(created.updatedAt)).toBeLessThan(1);\n\n expected.namespaceId = created.namespaceId;\n expected.id = created.id;\n expected.availableAt = created.availableAt;\n expected.createdAt = created.createdAt;\n expected.updatedAt = created.updatedAt;\n expect(created).toEqual(expected);\n\n // Create with minimal fields\n const createdMin = await backend.createWorkflowRun({\n workflowName: expected.workflowName,\n version: null,\n idempotencyKey: null,\n input: null,\n config: {},\n context: null,\n availableAt: null,\n deadlineAt: null,\n });\n expect(createdMin.version).toBeNull();\n expect(createdMin.idempotencyKey).toBeNull();\n expect(createdMin.input).toBeNull();\n expect(createdMin.context).toBeNull();\n expect(deltaSeconds(createdMin.availableAt)).toBeLessThan(1); // defaults to NOW()\n expect(createdMin.deadlineAt).toBeNull();\n });\n });\n\n describe(\"listWorkflowRuns()\", () => {\n test(\"lists workflow runs ordered by creation time\", async () => {\n const backend = await setup();\n const first = await createPendingWorkflowRun(backend);\n await sleep(10); // ensure timestamp difference\n const second = await createPendingWorkflowRun(backend);\n\n const listed = await backend.listWorkflowRuns({});\n const listedIds = listed.data.map((run) => run.id);\n expect(listedIds).toEqual([first.id, second.id]);\n await teardown(backend);\n });\n\n test(\"paginates workflow runs\", async () => {\n const backend = await setup();\n const runs: WorkflowRun[] = [];\n for (let i = 0; i < 5; i++) {\n runs.push(await createPendingWorkflowRun(backend));\n await sleep(10);\n }\n\n // p1\n const page1 = await backend.listWorkflowRuns({ limit: 2 });\n expect(page1.data).toHaveLength(2);\n expect(page1.data[0]?.id).toBe(runs[0]?.id);\n expect(page1.data[1]?.id).toBe(runs[1]?.id);\n expect(page1.pagination.next).not.toBeNull();\n expect(page1.pagination.prev).toBeNull();\n\n // p2\n const page2 = await backend.listWorkflowRuns({\n limit: 2,\n // biome-ignore lint/style/noNonNullAssertion: for test\n after: page1.pagination.next!,\n });\n expect(page2.data).toHaveLength(2);\n expect(page2.data[0]?.id).toBe(runs[2]?.id);\n expect(page2.data[1]?.id).toBe(runs[3]?.id);\n expect(page2.pagination.next).not.toBeNull();\n expect(page2.pagination.prev).not.toBeNull();\n\n // p3\n const page3 = await backend.listWorkflowRuns({\n limit: 2,\n // biome-ignore lint/style/noNonNullAssertion: for test\n after: page2.pagination.next!,\n });\n expect(page3.data).toHaveLength(1);\n expect(page3.data[0]?.id).toBe(runs[4]?.id);\n expect(page3.pagination.next).toBeNull();\n expect(page3.pagination.prev).not.toBeNull();\n\n // p2 again\n const page2Back = await backend.listWorkflowRuns({\n limit: 2,\n // biome-ignore lint/style/noNonNullAssertion: for test\n before: page3.pagination.prev!,\n });\n expect(page2Back.data).toHaveLength(2);\n expect(page2Back.data[0]?.id).toBe(runs[2]?.id);\n expect(page2Back.data[1]?.id).toBe(runs[3]?.id);\n expect(page2Back.pagination.next).toEqual(page2.pagination.next);\n expect(page2Back.pagination.prev).toEqual(page2.pagination.prev);\n await teardown(backend);\n });\n\n test(\"handles empty results\", async () => {\n const backend = await setup();\n const listed = await backend.listWorkflowRuns({});\n expect(listed.data).toHaveLength(0);\n expect(listed.pagination.next).toBeNull();\n expect(listed.pagination.prev).toBeNull();\n await teardown(backend);\n });\n\n test(\"paginates correctly with id as tiebreaker when multiple items have the same created_at timestamp\", async () => {\n const backend = await setup();\n\n const runs: WorkflowRun[] = [];\n for (let i = 0; i < 5; i++) {\n runs.push(await createPendingWorkflowRun(backend));\n }\n\n runs.sort((a, b) => {\n const timeDiff = a.createdAt.getTime() - b.createdAt.getTime();\n if (timeDiff !== 0) return timeDiff;\n return a.id.localeCompare(b.id);\n });\n\n const page1 = await backend.listWorkflowRuns({ limit: 2 });\n expect(page1.data).toHaveLength(2);\n expect(page1.data[0]?.id).toBe(runs[0]?.id);\n expect(page1.data[1]?.id).toBe(runs[1]?.id);\n expect(page1.pagination.next).not.toBeNull();\n\n const page2 = await backend.listWorkflowRuns({\n limit: 2,\n // biome-ignore lint/style/noNonNullAssertion: for test\n after: page1.pagination.next!,\n });\n expect(page2.data).toHaveLength(2);\n expect(page2.data[0]?.id).toBe(runs[2]?.id);\n expect(page2.data[1]?.id).toBe(runs[3]?.id);\n expect(page2.pagination.next).not.toBeNull();\n\n const page3 = await backend.listWorkflowRuns({\n limit: 2,\n // biome-ignore lint/style/noNonNullAssertion: for test\n after: page2.pagination.next!,\n });\n expect(page3.data).toHaveLength(1);\n expect(page3.data[0]?.id).toBe(runs[4]?.id);\n expect(page3.pagination.next).toBeNull();\n\n const page2Back = await backend.listWorkflowRuns({\n limit: 2,\n // biome-ignore lint/style/noNonNullAssertion: for test\n before: page3.pagination.prev!,\n });\n expect(page2Back.data).toHaveLength(2);\n expect(page2Back.data[0]?.id).toBe(runs[2]?.id);\n expect(page2Back.data[1]?.id).toBe(runs[3]?.id);\n\n await teardown(backend);\n });\n });\n\n describe(\"claimWorkflowRun()\", () => {\n // because claims involve timing and leases, we create and teardown a new\n // namespaced backend instance for each test\n\n test(\"claims workflow runs and respects leases, reclaiming if lease expires\", async () => {\n const backend = await setup();\n\n await createPendingWorkflowRun(backend);\n\n const firstLeaseMs = 30;\n const firstWorker = randomUUID();\n const claimed = await backend.claimWorkflowRun({\n workerId: firstWorker,\n leaseDurationMs: firstLeaseMs,\n });\n expect(claimed?.status).toBe(\"running\");\n expect(claimed?.workerId).toBe(firstWorker);\n expect(claimed?.attempts).toBe(1);\n expect(claimed?.startedAt).not.toBeNull();\n\n const secondWorker = randomUUID();\n const blocked = await backend.claimWorkflowRun({\n workerId: secondWorker,\n leaseDurationMs: 10,\n });\n expect(blocked).toBeNull();\n\n await sleep(firstLeaseMs + 5); // small buffer for timing variability\n\n const reclaimed = await backend.claimWorkflowRun({\n workerId: secondWorker,\n leaseDurationMs: 10,\n });\n expect(reclaimed?.id).toBe(claimed?.id);\n expect(reclaimed?.attempts).toBe(2);\n expect(reclaimed?.workerId).toBe(secondWorker);\n expect(reclaimed?.startedAt?.getTime()).toBe(claimed?.startedAt?.getTime());\n\n await teardown(backend);\n });\n\n test(\"prioritizes pending workflow runs over expired running ones\", async () => {\n const backend = await setup();\n\n const running = await createPendingWorkflowRun(backend);\n const runningClaim = await backend.claimWorkflowRun({\n workerId: \"worker-running\",\n leaseDurationMs: 5,\n });\n if (!runningClaim) throw new Error(\"expected claim\");\n expect(runningClaim.id).toBe(running.id);\n\n await sleep(10); // wait for running's lease to expire\n\n // pending claimed first, even though running expired\n const pending = await createPendingWorkflowRun(backend);\n const claimedFirst = await backend.claimWorkflowRun({\n workerId: \"worker-second\",\n leaseDurationMs: 100,\n });\n expect(claimedFirst?.id).toBe(pending.id);\n\n // running claimed second\n const claimedSecond = await backend.claimWorkflowRun({\n workerId: \"worker-third\",\n leaseDurationMs: 100,\n });\n expect(claimedSecond?.id).toBe(running.id);\n\n await teardown(backend);\n });\n\n test(\"returns null when no workflow runs are available\", async () => {\n const backend = await setup();\n\n const claimed = await backend.claimWorkflowRun({\n workerId: randomUUID(),\n leaseDurationMs: 10,\n });\n expect(claimed).toBeNull();\n\n await teardown(backend);\n });\n });\n\n describe(\"extendWorkflowRunLease()\", () => {\n test(\"extends the lease for running workflow runs\", async () => {\n const workerId = randomUUID();\n await createPendingWorkflowRun(backend);\n\n const claimed = await backend.claimWorkflowRun({\n workerId,\n leaseDurationMs: 20,\n });\n if (!claimed) throw new Error(\"Expected workflow run to be claimed\"); // for type narrowing\n\n const previousExpiry = claimed.availableAt;\n const extended = await backend.extendWorkflowRunLease({\n workflowRunId: claimed.id,\n workerId,\n leaseDurationMs: 200,\n });\n\n expect(extended.availableAt?.getTime()).toBeGreaterThan(\n previousExpiry?.getTime() ?? Infinity,\n );\n });\n });\n\n describe(\"sleepWorkflowRun()\", () => {\n test(\"sets a running workflow to sleeping status until a future time\", async () => {\n const workerId = randomUUID();\n await createPendingWorkflowRun(backend);\n\n const claimed = await backend.claimWorkflowRun({\n workerId,\n leaseDurationMs: 100,\n });\n if (!claimed) throw new Error(\"Expected workflow run to be claimed\");\n\n const sleepUntil = new Date(Date.now() + 5000); // 5 seconds from now\n\n await backend.sleepWorkflowRun({\n workflowRunId: claimed.id,\n workerId,\n availableAt: sleepUntil,\n });\n\n const fetched = await backend.getWorkflowRun({\n workflowRunId: claimed.id,\n });\n\n expect(fetched).not.toBeNull();\n expect(fetched?.availableAt?.getTime()).toBe(sleepUntil.getTime());\n expect(fetched?.workerId).toBeNull();\n expect(fetched?.status).toBe(\"sleeping\");\n });\n\n test(\"fails when trying to sleep a canceled workflow\", async () => {\n const backend = await setup();\n\n // completed run\n let claimed = await createClaimedWorkflowRun(backend);\n await backend.completeWorkflowRun({\n workflowRunId: claimed.id,\n workerId: claimed.workerId ?? \"\",\n output: null,\n });\n await expect(\n backend.sleepWorkflowRun({\n workflowRunId: claimed.id,\n workerId: claimed.workerId ?? \"\",\n availableAt: new Date(Date.now() + 60_000),\n }),\n ).rejects.toThrow(\"Failed to sleep workflow run\");\n\n // failed run\n claimed = await createClaimedWorkflowRun(backend);\n await backend.failWorkflowRun({\n workflowRunId: claimed.id,\n workerId: claimed.workerId ?? \"\",\n error: { message: \"failed\" },\n });\n await expect(\n backend.sleepWorkflowRun({\n workflowRunId: claimed.id,\n workerId: claimed.workerId ?? \"\",\n availableAt: new Date(Date.now() + 60_000),\n }),\n ).rejects.toThrow(\"Failed to sleep workflow run\");\n\n // canceled run\n claimed = await createClaimedWorkflowRun(backend);\n await backend.cancelWorkflowRun({\n workflowRunId: claimed.id,\n });\n await expect(\n backend.sleepWorkflowRun({\n workflowRunId: claimed.id,\n workerId: claimed.workerId ?? \"\",\n availableAt: new Date(Date.now() + 60_000),\n }),\n ).rejects.toThrow(\"Failed to sleep workflow run\");\n\n await teardown(backend);\n });\n });\n\n describe(\"completeWorkflowRun()\", () => {\n test(\"marks running workflow runs as completed\", async () => {\n const workerId = randomUUID();\n await createPendingWorkflowRun(backend);\n\n const claimed = await backend.claimWorkflowRun({\n workerId,\n leaseDurationMs: 20,\n });\n if (!claimed) throw new Error(\"Expected workflow run to be claimed\"); // for type narrowing\n\n const output = { ok: true };\n const completed = await backend.completeWorkflowRun({\n workflowRunId: claimed.id,\n workerId,\n output,\n });\n\n expect(completed.status).toBe(\"completed\");\n expect(completed.output).toEqual(output);\n expect(completed.error).toBeNull();\n expect(completed.finishedAt).not.toBeNull();\n expect(completed.availableAt).toBeNull();\n });\n });\n\n describe(\"failWorkflowRun()\", () => {\n test(\"reschedules workflow runs with exponential backoff on first failure\", async () => {\n const workerId = randomUUID();\n await createPendingWorkflowRun(backend);\n\n const claimed = await backend.claimWorkflowRun({\n workerId,\n leaseDurationMs: 20,\n });\n if (!claimed) throw new Error(\"Expected workflow run to be claimed\");\n\n const beforeFailTime = Date.now();\n\n const error = { message: \"boom\" };\n const failed = await backend.failWorkflowRun({\n workflowRunId: claimed.id,\n workerId,\n error,\n });\n\n // rescheduled, not permanently failed\n expect(failed.status).toBe(\"pending\");\n expect(failed.error).toEqual(error);\n expect(failed.output).toBeNull();\n expect(failed.finishedAt).toBeNull();\n expect(failed.workerId).toBeNull();\n expect(failed.startedAt).toBeNull(); // cleared on failure for retry\n\n expect(failed.availableAt).not.toBeNull();\n if (!failed.availableAt) throw new Error(\"Expected availableAt\");\n const delayMs = failed.availableAt.getTime() - beforeFailTime;\n expect(delayMs).toBeGreaterThanOrEqual(900); // ~1s with some tolerance\n expect(delayMs).toBeLessThan(1500);\n });\n\n test(\"reschedules with increasing backoff on multiple failures (known slow test)\", async () => {\n // this test needs isolated namespace\n const backend = await setup();\n\n await createPendingWorkflowRun(backend);\n\n // fail first attempt\n let workerId = randomUUID();\n let claimed = await backend.claimWorkflowRun({\n workerId,\n leaseDurationMs: 20,\n });\n if (!claimed) throw new Error(\"Expected workflow run to be claimed\");\n expect(claimed.attempts).toBe(1);\n\n const firstFailed = await backend.failWorkflowRun({\n workflowRunId: claimed.id,\n workerId,\n error: { message: \"first failure\" },\n });\n\n expect(firstFailed.status).toBe(\"pending\");\n\n await sleep(1100); // wait for first backoff (~1s)\n\n // fail second attempt\n workerId = randomUUID();\n claimed = await backend.claimWorkflowRun({\n workerId,\n leaseDurationMs: 20,\n });\n if (!claimed) throw new Error(\"Expected workflow run to be claimed\");\n expect(claimed.attempts).toBe(2);\n\n const beforeSecondFail = Date.now();\n const secondFailed = await backend.failWorkflowRun({\n workflowRunId: claimed.id,\n workerId,\n error: { message: \"second failure\" },\n });\n\n expect(secondFailed.status).toBe(\"pending\");\n\n // second attempt should have ~2s backoff (1s * 2^1)\n if (!secondFailed.availableAt) throw new Error(\"Expected availableAt\");\n const delayMs = secondFailed.availableAt.getTime() - beforeSecondFail;\n expect(delayMs).toBeGreaterThanOrEqual(1900); // ~2s with some tolerance\n expect(delayMs).toBeLessThan(2500);\n\n await teardown(backend);\n });\n\n test(\"marks workflow run as failed when maxAttempts is reached\", async () => {\n const backend = await setup();\n\n // retryPolicy에 maxAttempts: 2를 지정하여 생성\n const retryPolicy: SerializableRetryPolicy = {\n maxAttempts: 2,\n initialIntervalMs: 100,\n };\n await backend.createWorkflowRun({\n workflowName: randomUUID(),\n version: null,\n idempotencyKey: null,\n input: null,\n config: {},\n context: null,\n availableAt: null,\n deadlineAt: null,\n retryPolicy,\n });\n\n // 첫 번째 시도 - 실패하면 pending으로 스케줄링\n let workerId = randomUUID();\n let claimed = await backend.claimWorkflowRun({\n workerId,\n leaseDurationMs: 100,\n });\n if (!claimed) throw new Error(\"Expected workflow run to be claimed\");\n expect(claimed.attempts).toBe(1);\n\n const firstFailed = await backend.failWorkflowRun({\n workflowRunId: claimed.id,\n workerId,\n error: { message: \"first failure\" },\n });\n expect(firstFailed.status).toBe(\"pending\"); // 아직 maxAttempts(2) 미달\n\n await sleep(150); // 100ms backoff 대기\n\n // 두 번째 시도 - maxAttempts에 도달하면 failed로 종료\n workerId = randomUUID();\n claimed = await backend.claimWorkflowRun({\n workerId,\n leaseDurationMs: 100,\n });\n if (!claimed) throw new Error(\"Expected workflow run to be claimed\");\n expect(claimed.attempts).toBe(2);\n\n const secondFailed = await backend.failWorkflowRun({\n workflowRunId: claimed.id,\n workerId,\n error: { message: \"second failure\" },\n });\n\n // maxAttempts에 도달했으므로 failed로 종료\n expect(secondFailed.status).toBe(\"failed\");\n expect(secondFailed.availableAt).toBeNull();\n expect(secondFailed.finishedAt).not.toBeNull();\n\n await teardown(backend);\n });\n\n test(\"marks workflow run as failed immediately when forceComplete is true\", async () => {\n const backend = await setup();\n\n await createPendingWorkflowRun(backend);\n\n const workerId = randomUUID();\n const claimed = await backend.claimWorkflowRun({\n workerId,\n leaseDurationMs: 100,\n });\n if (!claimed) throw new Error(\"Expected workflow run to be claimed\");\n\n // forceComplete: true로 호출하면 재시도 없이 즉시 failed\n const failed = await backend.failWorkflowRun({\n workflowRunId: claimed.id,\n workerId,\n error: { message: \"forced failure\" },\n forceComplete: true,\n });\n\n expect(failed.status).toBe(\"failed\");\n expect(failed.availableAt).toBeNull();\n expect(failed.finishedAt).not.toBeNull();\n\n await teardown(backend);\n });\n\n test(\"stores retryPolicy in config when creating workflow run\", async () => {\n const backend = await setup();\n\n const retryPolicy: SerializableRetryPolicy = {\n maxAttempts: 10,\n initialIntervalMs: 500,\n backoffCoefficient: 1.5,\n maximumIntervalMs: 30000,\n };\n\n const created = await backend.createWorkflowRun({\n workflowName: randomUUID(),\n version: null,\n idempotencyKey: null,\n input: null,\n config: { existingKey: \"existingValue\" },\n context: null,\n availableAt: null,\n deadlineAt: null,\n retryPolicy,\n });\n\n // config에 retryPolicy가 저장되어 있는지 확인\n const config = created.config as Record<string, unknown>;\n expect(config.existingKey).toBe(\"existingValue\");\n expect(config.retryPolicy).toEqual(retryPolicy);\n\n await teardown(backend);\n });\n });\n\n describe(\"createStepAttempt()\", () => {\n test(\"creates a step attempt\", async () => {\n const workflowRun = await createClaimedWorkflowRun(backend);\n\n const expected: StepAttempt = {\n namespaceId: workflowRun.namespaceId,\n id: \"\", // -\n workflowRunId: workflowRun.id,\n stepName: randomUUID(),\n kind: \"function\",\n status: \"running\",\n config: { key: \"val\" },\n context: null,\n output: null,\n error: null,\n childWorkflowRunNamespaceId: null,\n childWorkflowRunId: null,\n startedAt: null,\n finishedAt: null,\n createdAt: new Date(), // -\n updatedAt: new Date(), // -\n };\n\n const created = await backend.createStepAttempt({\n workflowRunId: expected.workflowRunId,\n // biome-ignore lint/style/noNonNullAssertion: for test\n workerId: workflowRun.workerId!,\n stepName: expected.stepName,\n kind: expected.kind,\n config: expected.config,\n context: expected.context,\n });\n expect(created.id).toHaveLength(36);\n expect(deltaSeconds(created.startedAt)).toBeLessThan(1);\n expect(deltaSeconds(created.createdAt)).toBeLessThan(1);\n expect(deltaSeconds(created.updatedAt)).toBeLessThan(1);\n\n expected.id = created.id;\n expected.startedAt = created.startedAt;\n expected.createdAt = created.createdAt;\n expected.updatedAt = created.updatedAt;\n expect(created).toEqual(expected);\n });\n });\n\n describe(\"getStepAttempt()\", () => {\n test(\"returns a persisted step attempt\", async () => {\n const claimed = await createClaimedWorkflowRun(backend);\n\n const created = await backend.createStepAttempt({\n workflowRunId: claimed.id,\n // biome-ignore lint/style/noNonNullAssertion: for test\n workerId: claimed.workerId!,\n stepName: randomUUID(),\n kind: \"function\",\n config: {},\n context: null,\n });\n\n const got = await backend.getStepAttempt({\n stepAttemptId: created.id,\n });\n expect(got).toEqual(created);\n });\n });\n\n describe(\"listStepAttempts()\", () => {\n beforeAll(async () => {\n backend = await setup();\n });\n\n afterAll(async () => {\n await teardown(backend);\n });\n\n test(\"lists step attempts ordered by creation time\", async () => {\n const claimed = await createClaimedWorkflowRun(backend);\n\n const first = await backend.createStepAttempt({\n workflowRunId: claimed.id,\n // biome-ignore lint/style/noNonNullAssertion: for test\n workerId: claimed.workerId!,\n stepName: randomUUID(),\n kind: \"function\",\n config: {},\n context: null,\n });\n await backend.completeStepAttempt({\n workflowRunId: claimed.id,\n stepAttemptId: first.id,\n // biome-ignore lint/style/noNonNullAssertion: for test\n workerId: claimed.workerId!,\n output: { ok: true },\n });\n\n await sleep(10); // ensure timestamp difference\n\n const second = await backend.createStepAttempt({\n workflowRunId: claimed.id,\n // biome-ignore lint/style/noNonNullAssertion: for test\n workerId: claimed.workerId!,\n stepName: randomUUID(),\n kind: \"function\",\n config: {},\n context: null,\n });\n\n const listed = await backend.listStepAttempts({\n workflowRunId: claimed.id,\n });\n const listedStepNames = listed.data.map((step) => step.stepName);\n expect(listedStepNames).toEqual([first.stepName, second.stepName]);\n });\n\n test(\"paginates step attempts\", async () => {\n const claimed = await createClaimedWorkflowRun(backend);\n\n for (let i = 0; i < 5; i++) {\n await backend.createStepAttempt({\n workflowRunId: claimed.id,\n // biome-ignore lint/style/noNonNullAssertion: for test\n workerId: claimed.workerId!,\n stepName: `step-${String(i)}`,\n kind: \"function\",\n config: {},\n context: null,\n });\n\n await sleep(10); // ensure createdAt differs\n }\n\n // p1\n const page1 = await backend.listStepAttempts({\n workflowRunId: claimed.id,\n limit: 2,\n });\n expect(page1.data).toHaveLength(2);\n expect(page1.data[0]?.stepName).toBe(\"step-0\");\n expect(page1.data[1]?.stepName).toBe(\"step-1\");\n expect(page1.pagination.next).not.toBeNull();\n expect(page1.pagination.prev).toBeNull();\n\n // p2\n const page2 = await backend.listStepAttempts({\n workflowRunId: claimed.id,\n limit: 2,\n // biome-ignore lint/style/noNonNullAssertion: for test\n after: page1.pagination.next!,\n });\n expect(page2.data).toHaveLength(2);\n expect(page2.data[0]?.stepName).toBe(\"step-2\");\n expect(page2.data[1]?.stepName).toBe(\"step-3\");\n expect(page2.pagination.next).not.toBeNull();\n expect(page2.pagination.prev).not.toBeNull();\n\n // p3\n const page3 = await backend.listStepAttempts({\n workflowRunId: claimed.id,\n limit: 2,\n // biome-ignore lint/style/noNonNullAssertion: for test\n after: page2.pagination.next!,\n });\n expect(page3.data).toHaveLength(1);\n expect(page3.data[0]?.stepName).toBe(\"step-4\");\n expect(page3.pagination.next).toBeNull();\n expect(page3.pagination.prev).not.toBeNull();\n\n // p2 again\n const page2Back = await backend.listStepAttempts({\n workflowRunId: claimed.id,\n limit: 2,\n // biome-ignore lint/style/noNonNullAssertion: for test\n before: page3.pagination.prev!,\n });\n expect(page2Back.data).toHaveLength(2);\n expect(page2Back.data[0]?.stepName).toBe(\"step-2\");\n expect(page2Back.data[1]?.stepName).toBe(\"step-3\");\n expect(page2Back.pagination.next).toEqual(page2.pagination.next);\n expect(page2Back.pagination.prev).toEqual(page2.pagination.prev);\n });\n\n test(\"handles empty results\", async () => {\n const claimed = await createClaimedWorkflowRun(backend);\n const listed = await backend.listStepAttempts({\n workflowRunId: claimed.id,\n });\n expect(listed.data).toHaveLength(0);\n expect(listed.pagination.next).toBeNull();\n expect(listed.pagination.prev).toBeNull();\n });\n\n test(\"handles exact limit match\", async () => {\n const claimed = await createClaimedWorkflowRun(backend);\n await backend.createStepAttempt({\n workflowRunId: claimed.id,\n // biome-ignore lint/style/noNonNullAssertion: for test\n workerId: claimed.workerId!,\n stepName: \"step-1\",\n kind: \"function\",\n config: {},\n context: null,\n });\n\n const listed = await backend.listStepAttempts({\n workflowRunId: claimed.id,\n limit: 1,\n });\n expect(listed.data).toHaveLength(1);\n expect(listed.pagination.next).toBeNull();\n expect(listed.pagination.prev).toBeNull();\n });\n });\n\n describe(\"completeStepAttempt()\", () => {\n beforeAll(async () => {\n backend = await setup();\n });\n\n afterAll(async () => {\n await teardown(backend);\n });\n\n test(\"marks running step attempts as completed\", async () => {\n const claimed = await createClaimedWorkflowRun(backend);\n\n const created = await backend.createStepAttempt({\n workflowRunId: claimed.id,\n // biome-ignore lint/style/noNonNullAssertion: for test\n workerId: claimed.workerId!,\n stepName: randomUUID(),\n kind: \"function\",\n config: {},\n context: null,\n });\n const output = { foo: \"bar\" };\n\n const completed = await backend.completeStepAttempt({\n workflowRunId: claimed.id,\n stepAttemptId: created.id,\n // biome-ignore lint/style/noNonNullAssertion: for test\n workerId: claimed.workerId!,\n output,\n });\n\n expect(completed.status).toBe(\"completed\");\n expect(completed.output).toEqual(output);\n expect(completed.error).toBeNull();\n expect(completed.finishedAt).not.toBeNull();\n\n const fetched = await backend.getStepAttempt({\n stepAttemptId: created.id,\n });\n expect(fetched?.status).toBe(\"completed\");\n expect(fetched?.output).toEqual(output);\n expect(fetched?.error).toBeNull();\n expect(fetched?.finishedAt).not.toBeNull();\n });\n\n test(\"throws when workflow is not running\", async () => {\n const backend = await setup();\n await createPendingWorkflowRun(backend);\n\n // create a step attempt by first claiming the workflow\n const claimed = await backend.claimWorkflowRun({\n workerId: randomUUID(),\n leaseDurationMs: 100,\n });\n if (!claimed) throw new Error(\"Failed to claim workflow run\");\n\n const stepAttempt = await backend.createStepAttempt({\n workflowRunId: claimed.id,\n // biome-ignore lint/style/noNonNullAssertion: for test\n workerId: claimed.workerId!,\n stepName: randomUUID(),\n kind: \"function\",\n config: {},\n context: null,\n });\n\n // complete the workflow so it's no longer running\n await backend.completeWorkflowRun({\n workflowRunId: claimed.id,\n // biome-ignore lint/style/noNonNullAssertion: for test\n workerId: claimed.workerId!,\n output: null,\n });\n\n // try to complete the step attempt\n await expect(\n backend.completeStepAttempt({\n workflowRunId: claimed.id,\n stepAttemptId: stepAttempt.id,\n // biome-ignore lint/style/noNonNullAssertion: for test\n workerId: claimed.workerId!,\n output: { foo: \"bar\" },\n }),\n ).rejects.toThrow(\"Failed to mark step attempt completed\");\n\n await teardown(backend);\n });\n\n test(\"throws when step attempt does not exist\", async () => {\n const backend = await setup();\n const claimed = await createClaimedWorkflowRun(backend);\n\n await expect(\n backend.completeStepAttempt({\n workflowRunId: claimed.id,\n stepAttemptId: randomUUID(),\n // biome-ignore lint/style/noNonNullAssertion: for test\n workerId: claimed.workerId!,\n output: { foo: \"bar\" },\n }),\n ).rejects.toThrow(\"Failed to mark step attempt completed\");\n\n await teardown(backend);\n });\n });\n\n describe(\"failStepAttempt()\", () => {\n beforeAll(async () => {\n backend = await setup();\n });\n\n afterAll(async () => {\n await teardown(backend);\n });\n\n test(\"marks running step attempts as failed\", async () => {\n const claimed = await createClaimedWorkflowRun(backend);\n\n const created = await backend.createStepAttempt({\n workflowRunId: claimed.id,\n // biome-ignore lint/style/noNonNullAssertion: for test\n workerId: claimed.workerId!,\n stepName: randomUUID(),\n kind: \"function\",\n config: {},\n context: null,\n });\n const error = { message: \"nope\" };\n\n const failed = await backend.failStepAttempt({\n workflowRunId: claimed.id,\n stepAttemptId: created.id,\n // biome-ignore lint/style/noNonNullAssertion: for test\n workerId: claimed.workerId!,\n error,\n });\n\n expect(failed.status).toBe(\"failed\");\n expect(failed.error).toEqual(error);\n expect(failed.output).toBeNull();\n expect(failed.finishedAt).not.toBeNull();\n\n const fetched = await backend.getStepAttempt({\n stepAttemptId: created.id,\n });\n expect(fetched?.status).toBe(\"failed\");\n expect(fetched?.error).toEqual(error);\n expect(fetched?.output).toBeNull();\n expect(fetched?.finishedAt).not.toBeNull();\n });\n\n test(\"throws when workflow is not running\", async () => {\n const backend = await setup();\n await createPendingWorkflowRun(backend);\n\n // create a step attempt by first claiming the workflow\n const claimed = await backend.claimWorkflowRun({\n workerId: randomUUID(),\n leaseDurationMs: 100,\n });\n if (!claimed) throw new Error(\"Failed to claim workflow run\");\n\n const stepAttempt = await backend.createStepAttempt({\n workflowRunId: claimed.id,\n // biome-ignore lint/style/noNonNullAssertion: for test\n workerId: claimed.workerId!,\n stepName: randomUUID(),\n kind: \"function\",\n config: {},\n context: null,\n });\n\n // complete the workflow so it's no longer running\n await backend.completeWorkflowRun({\n workflowRunId: claimed.id,\n // biome-ignore lint/style/noNonNullAssertion: for test\n workerId: claimed.workerId!,\n output: null,\n });\n\n // try to fail the step attempt\n await expect(\n backend.failStepAttempt({\n workflowRunId: claimed.id,\n stepAttemptId: stepAttempt.id,\n // biome-ignore lint/style/noNonNullAssertion: for test\n workerId: claimed.workerId!,\n error: { message: \"nope\" },\n }),\n ).rejects.toThrow(\"Failed to mark step attempt failed\");\n\n await teardown(backend);\n });\n\n test(\"throws when step attempt does not exist\", async () => {\n const backend = await setup();\n const claimed = await createClaimedWorkflowRun(backend);\n\n await expect(\n backend.failStepAttempt({\n workflowRunId: claimed.id,\n stepAttemptId: randomUUID(),\n // biome-ignore lint/style/noNonNullAssertion: for test\n workerId: claimed.workerId!,\n error: { message: \"nope\" },\n }),\n ).rejects.toThrow(\"Failed to mark step attempt failed\");\n\n await teardown(backend);\n });\n });\n\n describe(\"deadline_at\", () => {\n beforeAll(async () => {\n backend = await setup();\n });\n\n afterAll(async () => {\n await teardown(backend);\n });\n\n test(\"creates a workflow run with a deadline\", async () => {\n const deadline = new Date(Date.now() + 60_000); // in 1 minute\n const created = await backend.createWorkflowRun({\n workflowName: randomUUID(),\n version: null,\n idempotencyKey: null,\n input: null,\n config: {},\n context: null,\n availableAt: null,\n deadlineAt: deadline,\n });\n\n expect(created.deadlineAt).not.toBeNull();\n expect(created.deadlineAt?.getTime()).toBe(deadline.getTime());\n });\n\n test(\"does not claim workflow runs past their deadline\", async () => {\n const backend = await setup();\n\n const pastDeadline = new Date(Date.now() - 1000);\n await backend.createWorkflowRun({\n workflowName: randomUUID(),\n version: null,\n idempotencyKey: null,\n input: null,\n config: {},\n context: null,\n availableAt: null,\n deadlineAt: pastDeadline,\n });\n\n const claimed = await backend.claimWorkflowRun({\n workerId: randomUUID(),\n leaseDurationMs: 1000,\n });\n\n expect(claimed).toBeNull();\n\n await teardown(backend);\n });\n\n test(\"marks deadline-expired workflow runs as failed when claiming\", async () => {\n const backend = await setup();\n\n const pastDeadline = new Date(Date.now() - 1000);\n const created = await backend.createWorkflowRun({\n workflowName: randomUUID(),\n version: null,\n idempotencyKey: null,\n input: null,\n config: {},\n context: null,\n availableAt: null,\n deadlineAt: pastDeadline,\n });\n\n // attempt to claim triggers deadline check\n const claimed = await backend.claimWorkflowRun({\n workerId: randomUUID(),\n leaseDurationMs: 1000,\n });\n expect(claimed).toBeNull();\n\n // verify it was marked as failed\n const failed = await backend.getWorkflowRun({\n workflowRunId: created.id,\n });\n expect(failed?.status).toBe(\"failed\");\n expect(failed?.error).toEqual({\n message: \"Workflow run deadline exceeded\",\n });\n expect(failed?.finishedAt).not.toBeNull();\n expect(failed?.availableAt).toBeNull();\n\n await teardown(backend);\n });\n\n test(\"does not reschedule failed workflow runs if next retry would exceed deadline\", async () => {\n const backend = await setup();\n\n const deadline = new Date(Date.now() + 500); // 500ms from now\n const created = await backend.createWorkflowRun({\n workflowName: randomUUID(),\n version: null,\n idempotencyKey: null,\n input: null,\n config: {},\n context: null,\n availableAt: null,\n deadlineAt: deadline,\n });\n\n const workerId = randomUUID();\n const claimed = await backend.claimWorkflowRun({\n workerId,\n leaseDurationMs: 100,\n });\n expect(claimed).not.toBeNull();\n\n // should mark as permanently failed since retry backoff (1s) would exceed deadline (500ms)\n const failed = await backend.failWorkflowRun({\n workflowRunId: created.id,\n workerId,\n error: { message: \"test error\" },\n });\n\n expect(failed.status).toBe(\"failed\");\n expect(failed.availableAt).toBeNull();\n expect(failed.finishedAt).not.toBeNull();\n expect(failed.startedAt).toBeNull(); // cleared on permanent failure\n\n await teardown(backend);\n });\n\n test(\"reschedules failed workflow runs if retry would complete before deadline\", async () => {\n const backend = await setup();\n\n const deadline = new Date(Date.now() + 5000); // in 5 seconds\n const created = await backend.createWorkflowRun({\n workflowName: randomUUID(),\n version: null,\n idempotencyKey: null,\n input: null,\n config: {},\n context: null,\n availableAt: null,\n deadlineAt: deadline,\n });\n\n const workerId = randomUUID();\n const claimed = await backend.claimWorkflowRun({\n workerId,\n leaseDurationMs: 100,\n });\n expect(claimed).not.toBeNull();\n\n // should reschedule since retry backoff (1s) is before deadline (5s\n const failed = await backend.failWorkflowRun({\n workflowRunId: created.id,\n workerId,\n error: { message: \"test error\" },\n });\n\n expect(failed.status).toBe(\"pending\");\n expect(failed.availableAt).not.toBeNull();\n expect(failed.finishedAt).toBeNull();\n\n await teardown(backend);\n });\n });\n\n describe(\"cancelWorkflowRun()\", () => {\n test(\"cancels a pending workflow run\", async () => {\n const backend = await setup();\n\n const created = await createPendingWorkflowRun(backend);\n expect(created.status).toBe(\"pending\");\n\n const canceled = await backend.cancelWorkflowRun({\n workflowRunId: created.id,\n });\n\n expect(canceled.status).toBe(\"canceled\");\n expect(canceled.workerId).toBeNull();\n expect(canceled.availableAt).toBeNull();\n expect(canceled.finishedAt).not.toBeNull();\n expect(deltaSeconds(canceled.finishedAt)).toBeLessThan(1);\n\n await teardown(backend);\n });\n\n test(\"cancels a running workflow run\", async () => {\n const backend = await setup();\n\n const created = await createClaimedWorkflowRun(backend);\n expect(created.status).toBe(\"running\");\n expect(created.workerId).not.toBeNull();\n\n const canceled = await backend.cancelWorkflowRun({\n workflowRunId: created.id,\n });\n\n expect(canceled.status).toBe(\"canceled\");\n expect(canceled.workerId).toBeNull();\n expect(canceled.availableAt).toBeNull();\n expect(canceled.finishedAt).not.toBeNull();\n\n await teardown(backend);\n });\n\n test(\"cancels a sleeping workflow run\", async () => {\n const backend = await setup();\n\n const claimed = await createClaimedWorkflowRun(backend);\n\n // put workflow to sleep\n const sleepUntil = new Date(Date.now() + 60_000); // 1 minute from now\n const sleeping = await backend.sleepWorkflowRun({\n workflowRunId: claimed.id,\n workerId: claimed.workerId ?? \"\",\n availableAt: sleepUntil,\n });\n expect(sleeping.status).toBe(\"sleeping\");\n\n const canceled = await backend.cancelWorkflowRun({\n workflowRunId: sleeping.id,\n });\n\n expect(canceled.status).toBe(\"canceled\");\n expect(canceled.workerId).toBeNull();\n expect(canceled.availableAt).toBeNull();\n expect(canceled.finishedAt).not.toBeNull();\n\n await teardown(backend);\n });\n\n test(\"throws error when canceling a completed workflow run\", async () => {\n const backend = await setup();\n\n const claimed = await createClaimedWorkflowRun(backend);\n\n // mark as completed\n await backend.completeWorkflowRun({\n workflowRunId: claimed.id,\n workerId: claimed.workerId ?? \"\",\n output: { result: \"success\" },\n });\n\n await expect(\n backend.cancelWorkflowRun({\n workflowRunId: claimed.id,\n }),\n ).rejects.toThrow(/Cannot cancel workflow run .* with status completed/);\n\n await teardown(backend);\n });\n\n test(\"throws error when canceling a failed workflow run\", async () => {\n const backend = await setup();\n\n // create with deadline that's already passed to make it fail\n const workflowWithDeadline = await backend.createWorkflowRun({\n workflowName: randomUUID(),\n version: null,\n idempotencyKey: null,\n input: null,\n config: {},\n context: null,\n availableAt: null,\n deadlineAt: new Date(Date.now() - 1000), // deadline in the past\n });\n\n // try to claim it, which should mark it as failed due to deadline\n const claimed = await backend.claimWorkflowRun({\n workerId: randomUUID(),\n leaseDurationMs: 100,\n });\n\n // if claim succeeds, manually fail it\n if (claimed?.workerId) {\n await backend.failWorkflowRun({\n workflowRunId: claimed.id,\n workerId: claimed.workerId,\n error: { message: \"test error\" },\n });\n }\n\n // get a workflow that's definitely failed\n const failedRun = await backend.getWorkflowRun({\n workflowRunId: workflowWithDeadline.id,\n });\n\n if (failedRun?.status === \"failed\") {\n await expect(\n backend.cancelWorkflowRun({\n workflowRunId: failedRun.id,\n }),\n ).rejects.toThrow(/Cannot cancel workflow run .* with status failed/);\n }\n\n await teardown(backend);\n });\n\n test(\"is idempotent when canceling an already canceled workflow run\", async () => {\n const backend = await setup();\n\n const created = await createPendingWorkflowRun(backend);\n\n const firstCancel = await backend.cancelWorkflowRun({\n workflowRunId: created.id,\n });\n expect(firstCancel.status).toBe(\"canceled\");\n\n const secondCancel = await backend.cancelWorkflowRun({\n workflowRunId: created.id,\n });\n expect(secondCancel.status).toBe(\"canceled\");\n expect(secondCancel.id).toBe(firstCancel.id);\n\n await teardown(backend);\n });\n\n test(\"throws error when canceling a non-existent workflow run\", async () => {\n const backend = await setup();\n\n const nonExistentId = randomUUID();\n\n await expect(\n backend.cancelWorkflowRun({\n workflowRunId: nonExistentId,\n }),\n ).rejects.toThrow(`Workflow run ${nonExistentId} does not exist`);\n\n await teardown(backend);\n });\n\n test(\"canceled workflow is not claimed by workers\", async () => {\n const backend = await setup();\n\n const created = await createPendingWorkflowRun(backend);\n\n // cancel the workflow\n await backend.cancelWorkflowRun({\n workflowRunId: created.id,\n });\n\n // try to claim work\n const claimed = await backend.claimWorkflowRun({\n workerId: randomUUID(),\n leaseDurationMs: 100,\n });\n\n // should not claim the canceled workflow\n expect(claimed).toBeNull();\n\n await teardown(backend);\n });\n });\n });\n}\n\n/**\n * Create a pending workflow run for tests.\n * @param b - Backend\n * @returns Created workflow run\n */\nasync function createPendingWorkflowRun(b: Backend) {\n return await b.createWorkflowRun({\n workflowName: randomUUID(),\n version: null,\n idempotencyKey: null,\n input: null,\n config: {},\n context: null,\n availableAt: null,\n deadlineAt: null,\n });\n}\n\n/**\n * Create and claim a workflow run for tests.\n * @param b - Backend\n * @returns Claimed workflow run\n */\nasync function createClaimedWorkflowRun(b: Backend) {\n await createPendingWorkflowRun(b);\n\n const claimed = await b.claimWorkflowRun({\n workerId: randomUUID(),\n leaseDurationMs: 100,\n });\n\n if (!claimed) throw new Error(\"Failed to claim workflow run\");\n\n return claimed;\n}\n\n/**\n * Get delta in seconds from now.\n * @param date - Date to compare\n * @returns Delta in seconds\n */\nfunction deltaSeconds(date: Date | null | undefined): number {\n if (!date) return Infinity;\n return Math.abs((Date.now() - date.getTime()) / 1000);\n}\n\n/**\n * Create a Date one year in the future.\n * @returns Future Date\n */\nfunction newDateInOneYear() {\n const d = new Date();\n d.setFullYear(d.getFullYear() + 1);\n return d;\n}\n\n/**\n * Sleep for a given duration.\n * @param ms - Milliseconds to sleep\n * @returns Promise resolved after sleeping\n */\nfunction sleep(ms: number) {\n return new Promise((resolve) => setTimeout(resolve, ms));\n}\n"],"names":["randomUUID","afterAll","beforeAll","describe","expect","test","testBackend","options","setup","teardown","backend","expected","namespaceId","id","workflowName","version","status","idempotencyKey","config","key","context","input","output","error","attempts","parentStepAttemptNamespaceId","parentStepAttemptId","workerId","availableAt","newDateInOneYear","deadlineAt","startedAt","finishedAt","createdAt","Date","updatedAt","created","createWorkflowRun","toHaveLength","deltaSeconds","toBeGreaterThan","toBeLessThan","toEqual","createdMin","toBeNull","first","createPendingWorkflowRun","sleep","second","listed","listWorkflowRuns","listedIds","data","map","run","runs","i","push","page1","limit","toBe","pagination","next","not","prev","page2","after","page3","page2Back","before","sort","a","b","timeDiff","getTime","localeCompare","firstLeaseMs","firstWorker","claimed","claimWorkflowRun","leaseDurationMs","secondWorker","blocked","reclaimed","running","runningClaim","Error","pending","claimedFirst","claimedSecond","previousExpiry","extended","extendWorkflowRunLease","workflowRunId","Infinity","sleepUntil","now","sleepWorkflowRun","fetched","getWorkflowRun","createClaimedWorkflowRun","completeWorkflowRun","rejects","toThrow","failWorkflowRun","message","cancelWorkflowRun","ok","completed","beforeFailTime","failed","delayMs","toBeGreaterThanOrEqual","firstFailed","beforeSecondFail","secondFailed","retryPolicy","maxAttempts","initialIntervalMs","forceComplete","backoffCoefficient","maximumIntervalMs","existingKey","workflowRun","stepName","kind","childWorkflowRunNamespaceId","childWorkflowRunId","createStepAttempt","got","getStepAttempt","stepAttemptId","completeStepAttempt","listStepAttempts","listedStepNames","step","String","foo","stepAttempt","failStepAttempt","deadline","pastDeadline","canceled","sleeping","result","workflowWithDeadline","failedRun","firstCancel","secondCancel","nonExistentId","date","Math","abs","d","setFullYear","getFullYear","ms","Promise","resolve","setTimeout"],"mappings":"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"}
|
package/dist/execution.d.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import type { Backend } from "./backend";
|
|
2
2
|
import type { DurationString } from "./core/duration";
|
|
3
|
+
import { type RetryPolicy } from "./core/retry";
|
|
3
4
|
import type { StepAttempt } from "./core/step";
|
|
4
5
|
import type { WorkflowRun } from "./core/workflow";
|
|
5
6
|
/**
|
|
@@ -68,6 +69,7 @@ export interface ExecuteWorkflowParams {
|
|
|
68
69
|
workflowFn: WorkflowFunction<unknown, unknown>;
|
|
69
70
|
workflowVersion: string | null;
|
|
70
71
|
workerId: string;
|
|
72
|
+
retryPolicy?: RetryPolicy;
|
|
71
73
|
}
|
|
72
74
|
/**
|
|
73
75
|
* Execute a workflow run. This is the core application use case that handles:
|
package/dist/execution.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"execution.d.ts","sourceRoot":"","sources":["../src/execution.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACzC,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AAGtD,OAAO,KAAK,EAAE,WAAW,EAAoB,MAAM,aAAa,CAAC;AASjE,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AAEnD;;GAEG;AACH,MAAM,WAAW,kBAAkB;IACjC;;OAEG;IACH,IAAI,EAAE,MAAM,CAAC;CACd;AAED;;;GAGG;AACH,MAAM,WAAW,OAAO;IACtB,GAAG,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,CAAC,kBAAkB,CAAC,EAAE,EAAE,EAAE,YAAY,CAAC,MAAM,CAAC,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;IAC7F,KAAK,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,cAAc,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CAC9D;AAED;;;GAGG;AACH,MAAM,MAAM,YAAY,CAAC,MAAM,IAAI,MAAM,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC,GAAG,MAAM,GAAG,SAAS,CAAC;AAE1F;;GAEG;AACH,MAAM,WAAW,sBAAsB,CAAC,KAAK;IAC3C,KAAK,EAAE,KAAK,CAAC;IACb,IAAI,EAAE,OAAO,CAAC;IACd,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;CACxB;AAED;;;GAGG;AACH,MAAM,MAAM,gBAAgB,CAAC,KAAK,EAAE,MAAM,IAAI,CAC5C,MAAM,EAAE,QAAQ,CAAC,sBAAsB,CAAC,KAAK,CAAC,CAAC,KAC5C,OAAO,CAAC,MAAM,CAAC,GAAG,MAAM,CAAC;AAgB9B;;GAEG;AACH,MAAM,WAAW,mBAAmB;IAClC,OAAO,EAAE,OAAO,CAAC;IACjB,aAAa,EAAE,MAAM,CAAC;IACtB,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,WAAW,EAAE,CAAC;CACzB;AAED;;;GAGG;AACH,qBAAa,YAAa,YAAW,OAAO;IAC1C,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAU;IAClC,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAS;IACvC,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAS;IAClC,OAAO,CAAC,KAAK,CAAmB;gBAEpB,OAAO,EAAE,QAAQ,CAAC,mBAAmB,CAAC;IAQ5C,GAAG,CAAC,MAAM,EACd,MAAM,EAAE,QAAQ,CAAC,kBAAkB,CAAC,EACpC,EAAE,EAAE,YAAY,CAAC,MAAM,CAAC,GACvB,OAAO,CAAC,MAAM,CAAC;IAgDZ,KAAK,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,cAAc,GAAG,OAAO,CAAC,IAAI,CAAC;CA2BnE;AAED;;GAEG;AACH,MAAM,WAAW,qBAAqB;IACpC,OAAO,EAAE,OAAO,CAAC;IACjB,WAAW,EAAE,WAAW,CAAC;IACzB,UAAU,EAAE,gBAAgB,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;IAC/C,eAAe,EAAE,MAAM,GAAG,IAAI,CAAC;IAC/B,QAAQ,EAAE,MAAM,CAAC;
|
|
1
|
+
{"version":3,"file":"execution.d.ts","sourceRoot":"","sources":["../src/execution.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACzC,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AAGtD,OAAO,EAAwB,KAAK,WAAW,EAAE,MAAM,cAAc,CAAC;AACtE,OAAO,KAAK,EAAE,WAAW,EAAoB,MAAM,aAAa,CAAC;AASjE,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AAEnD;;GAEG;AACH,MAAM,WAAW,kBAAkB;IACjC;;OAEG;IACH,IAAI,EAAE,MAAM,CAAC;CACd;AAED;;;GAGG;AACH,MAAM,WAAW,OAAO;IACtB,GAAG,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,CAAC,kBAAkB,CAAC,EAAE,EAAE,EAAE,YAAY,CAAC,MAAM,CAAC,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;IAC7F,KAAK,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,cAAc,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CAC9D;AAED;;;GAGG;AACH,MAAM,MAAM,YAAY,CAAC,MAAM,IAAI,MAAM,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC,GAAG,MAAM,GAAG,SAAS,CAAC;AAE1F;;GAEG;AACH,MAAM,WAAW,sBAAsB,CAAC,KAAK;IAC3C,KAAK,EAAE,KAAK,CAAC;IACb,IAAI,EAAE,OAAO,CAAC;IACd,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;CACxB;AAED;;;GAGG;AACH,MAAM,MAAM,gBAAgB,CAAC,KAAK,EAAE,MAAM,IAAI,CAC5C,MAAM,EAAE,QAAQ,CAAC,sBAAsB,CAAC,KAAK,CAAC,CAAC,KAC5C,OAAO,CAAC,MAAM,CAAC,GAAG,MAAM,CAAC;AAgB9B;;GAEG;AACH,MAAM,WAAW,mBAAmB;IAClC,OAAO,EAAE,OAAO,CAAC;IACjB,aAAa,EAAE,MAAM,CAAC;IACtB,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,WAAW,EAAE,CAAC;CACzB;AAED;;;GAGG;AACH,qBAAa,YAAa,YAAW,OAAO;IAC1C,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAU;IAClC,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAS;IACvC,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAS;IAClC,OAAO,CAAC,KAAK,CAAmB;gBAEpB,OAAO,EAAE,QAAQ,CAAC,mBAAmB,CAAC;IAQ5C,GAAG,CAAC,MAAM,EACd,MAAM,EAAE,QAAQ,CAAC,kBAAkB,CAAC,EACpC,EAAE,EAAE,YAAY,CAAC,MAAM,CAAC,GACvB,OAAO,CAAC,MAAM,CAAC;IAgDZ,KAAK,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,cAAc,GAAG,OAAO,CAAC,IAAI,CAAC;CA2BnE;AAED;;GAEG;AACH,MAAM,WAAW,qBAAqB;IACpC,OAAO,EAAE,OAAO,CAAC;IACjB,WAAW,EAAE,WAAW,CAAC;IACzB,UAAU,EAAE,gBAAgB,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;IAC/C,eAAe,EAAE,MAAM,GAAG,IAAI,CAAC;IAC/B,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,CAAC,EAAE,WAAW,CAAC;CAC3B;AAED;;;;;;;;GAQG;AACH,wBAAsB,eAAe,CAAC,MAAM,EAAE,QAAQ,CAAC,qBAAqB,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC,CAyG5F"}
|
package/dist/execution.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { serializeError } from "./core/error.js";
|
|
2
|
+
import { isDynamicRetryPolicy } from "./core/retry.js";
|
|
2
3
|
import { addToStepAttemptCache, calculateSleepResumeAt, createSleepContext, createStepAttemptCacheFromAttempts, getCachedStepAttempt, normalizeStepOutput } from "./core/step.js";
|
|
3
4
|
/**
|
|
4
5
|
* Signal thrown when a workflow needs to sleep. Contains the time when the
|
|
@@ -100,7 +101,7 @@ import { addToStepAttemptCache, calculateSleepResumeAt, createSleepContext, crea
|
|
|
100
101
|
* - Completing, failing, or sleeping the workflow run based on the outcome
|
|
101
102
|
* @param params - The execution parameters
|
|
102
103
|
*/ export async function executeWorkflow(params) {
|
|
103
|
-
const { backend, workflowRun, workflowFn, workflowVersion, workerId } = params;
|
|
104
|
+
const { backend, workflowRun, workflowFn, workflowVersion, workerId, retryPolicy } = params;
|
|
104
105
|
try {
|
|
105
106
|
// load all pages of step history
|
|
106
107
|
const attempts = [];
|
|
@@ -170,11 +171,24 @@ import { addToStepAttemptCache, calculateSleepResumeAt, createSleepContext, crea
|
|
|
170
171
|
});
|
|
171
172
|
return;
|
|
172
173
|
}
|
|
173
|
-
//
|
|
174
|
+
// claimWorkflowRun에서 이미 attempts가 증가된 상태입니다.
|
|
175
|
+
let forceComplete = false;
|
|
176
|
+
let customDelayMs;
|
|
177
|
+
if (retryPolicy && isDynamicRetryPolicy(retryPolicy)) {
|
|
178
|
+
const serializedError = serializeError(error);
|
|
179
|
+
const decision = retryPolicy.shouldRetry(serializedError, workflowRun.attempts ?? 1);
|
|
180
|
+
if (!decision.shouldRetry) {
|
|
181
|
+
forceComplete = true;
|
|
182
|
+
} else {
|
|
183
|
+
customDelayMs = decision.delayMs;
|
|
184
|
+
}
|
|
185
|
+
}
|
|
174
186
|
await backend.failWorkflowRun({
|
|
175
187
|
workflowRunId: workflowRun.id,
|
|
176
188
|
workerId,
|
|
177
|
-
error: serializeError(error)
|
|
189
|
+
error: serializeError(error),
|
|
190
|
+
forceComplete,
|
|
191
|
+
customDelayMs
|
|
178
192
|
});
|
|
179
193
|
}
|
|
180
194
|
}
|
package/dist/execution.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/execution.ts"],"sourcesContent":["import type { Backend } from \"./backend\";\nimport type { DurationString } from \"./core/duration\";\nimport { serializeError } from \"./core/error\";\nimport type { JsonValue } from \"./core/json\";\nimport type { StepAttempt, StepAttemptCache } from \"./core/step\";\nimport {\n addToStepAttemptCache,\n calculateSleepResumeAt,\n createSleepContext,\n createStepAttemptCacheFromAttempts,\n getCachedStepAttempt,\n normalizeStepOutput,\n} from \"./core/step\";\nimport type { WorkflowRun } from \"./core/workflow\";\n\n/**\n * Config for an individual step defined with `step.run()`.\n */\nexport interface StepFunctionConfig {\n /**\n * The name of the step.\n */\n name: string;\n}\n\n/**\n * Represents the API for defining steps within a workflow. Used within a\n * workflow handler to define steps by calling `step.run()`.\n */\nexport interface StepApi {\n run<Output>(config: Readonly<StepFunctionConfig>, fn: StepFunction<Output>): Promise<Output>;\n sleep(name: string, duration: DurationString): Promise<void>;\n}\n\n/**\n * The step definition (defined by the user) that executes user code. Can return\n * undefined (e.g., when using `return;`) which will be converted to null.\n */\nexport type StepFunction<Output> = () => Promise<Output | undefined> | Output | undefined;\n\n/**\n * Params passed to a workflow function for the user to use when defining steps.\n */\nexport interface WorkflowFunctionParams<Input> {\n input: Input;\n step: StepApi;\n version: string | null;\n}\n\n/**\n * The workflow definition's function (defined by the user) that the user uses\n * to define the workflow's steps.\n */\nexport type WorkflowFunction<Input, Output> = (\n params: Readonly<WorkflowFunctionParams<Input>>,\n) => Promise<Output> | Output;\n\n/**\n * Signal thrown when a workflow needs to sleep. Contains the time when the\n * workflow should resume.\n */\nclass SleepSignal extends Error {\n readonly resumeAt: Date;\n\n constructor(resumeAt: Readonly<Date>) {\n super(\"SleepSignal\");\n this.name = \"SleepSignal\";\n this.resumeAt = resumeAt;\n }\n}\n\n/**\n * Configures the options for a StepExecutor.\n */\nexport interface StepExecutorOptions {\n backend: Backend;\n workflowRunId: string;\n workerId: string;\n attempts: StepAttempt[];\n}\n\n/**\n * Replays prior step attempts and persists new ones while memoizing\n * deterministic step outputs.\n */\nexport class StepExecutor implements StepApi {\n private readonly backend: Backend;\n private readonly workflowRunId: string;\n private readonly workerId: string;\n private cache: StepAttemptCache;\n\n constructor(options: Readonly<StepExecutorOptions>) {\n this.backend = options.backend;\n this.workflowRunId = options.workflowRunId;\n this.workerId = options.workerId;\n\n this.cache = createStepAttemptCacheFromAttempts(options.attempts);\n }\n\n async run<Output>(\n config: Readonly<StepFunctionConfig>,\n fn: StepFunction<Output>,\n ): Promise<Output> {\n const { name } = config;\n\n // return cached result if available\n const existingAttempt = getCachedStepAttempt(this.cache, name);\n if (existingAttempt) {\n return existingAttempt.output as Output;\n }\n\n // not in cache, create new step attempt\n const attempt = await this.backend.createStepAttempt({\n workflowRunId: this.workflowRunId,\n workerId: this.workerId,\n stepName: name,\n kind: \"function\",\n config: {},\n context: null,\n });\n\n try {\n // execute step function\n const result = await fn();\n const output = normalizeStepOutput(result);\n\n // mark success\n const savedAttempt = await this.backend.completeStepAttempt({\n workflowRunId: this.workflowRunId,\n stepAttemptId: attempt.id,\n workerId: this.workerId,\n output,\n });\n\n // cache result\n this.cache = addToStepAttemptCache(this.cache, savedAttempt);\n\n return savedAttempt.output as Output;\n } catch (error) {\n // mark failure\n await this.backend.failStepAttempt({\n workflowRunId: this.workflowRunId,\n stepAttemptId: attempt.id,\n workerId: this.workerId,\n error: serializeError(error),\n });\n throw error;\n }\n }\n\n async sleep(name: string, duration: DurationString): Promise<void> {\n // return cached result if this sleep already completed\n const existingAttempt = getCachedStepAttempt(this.cache, name);\n if (existingAttempt) return;\n\n // create new step attempt for the sleep\n const result = calculateSleepResumeAt(duration);\n if (!result.ok) {\n throw result.error;\n }\n const resumeAt = result.value;\n const context = createSleepContext(resumeAt);\n\n await this.backend.createStepAttempt({\n workflowRunId: this.workflowRunId,\n workerId: this.workerId,\n stepName: name,\n kind: \"sleep\",\n config: {},\n context,\n });\n\n // throw sleep signal to trigger postponement\n // we do not mark the step as completed here; it will be updated\n // when the workflow resumes\n throw new SleepSignal(resumeAt);\n }\n}\n\n/**\n * Parameters for the workflow execution use case.\n */\nexport interface ExecuteWorkflowParams {\n backend: Backend;\n workflowRun: WorkflowRun;\n workflowFn: WorkflowFunction<unknown, unknown>;\n workflowVersion: string | null;\n workerId: string;\n}\n\n/**\n * Execute a workflow run. This is the core application use case that handles:\n * - Loading step history\n * - Handling sleeping steps\n * - Creating the step executor\n * - Executing the workflow function\n * - Completing, failing, or sleeping the workflow run based on the outcome\n * @param params - The execution parameters\n */\nexport async function executeWorkflow(params: Readonly<ExecuteWorkflowParams>): Promise<void> {\n const { backend, workflowRun, workflowFn, workflowVersion, workerId } = params;\n\n try {\n // load all pages of step history\n const attempts: StepAttempt[] = [];\n let cursor: string | undefined;\n do {\n const response = await backend.listStepAttempts({\n workflowRunId: workflowRun.id,\n ...(cursor ? { after: cursor } : {}),\n limit: 1000,\n });\n attempts.push(...response.data);\n cursor = response.pagination.next ?? undefined;\n } while (cursor);\n\n // mark any sleep steps as completed if their sleep duration has elapsed,\n // or rethrow SleepSignal if still sleeping\n for (let i = 0; i < attempts.length; i++) {\n const attempt = attempts[i];\n if (!attempt) continue;\n\n if (\n attempt.status === \"running\" &&\n attempt.kind === \"sleep\" &&\n attempt.context?.kind === \"sleep\"\n ) {\n const now = Date.now();\n const resumeAt = new Date(attempt.context.resumeAt);\n const resumeAtMs = resumeAt.getTime();\n\n if (now < resumeAtMs) {\n // sleep duration HAS NOT elapsed yet, throw signal to put workflow\n // back to sleep\n throw new SleepSignal(resumeAt);\n }\n\n // sleep duration HAS elapsed, mark the step as completed and continue\n const completed = await backend.completeStepAttempt({\n workflowRunId: workflowRun.id,\n stepAttemptId: attempt.id,\n workerId,\n output: null,\n });\n\n // update cache w/ completed attempt\n attempts[i] = completed;\n }\n }\n\n // create step executor\n const executor = new StepExecutor({\n backend,\n workflowRunId: workflowRun.id,\n workerId,\n attempts,\n });\n\n // execute workflow\n const output = await workflowFn({\n input: workflowRun.input as unknown,\n step: executor,\n version: workflowVersion,\n });\n\n // mark success\n await backend.completeWorkflowRun({\n workflowRunId: workflowRun.id,\n workerId,\n output: (output ?? null) as JsonValue,\n });\n } catch (error) {\n // handle sleep signal by setting workflow to sleeping status\n if (error instanceof SleepSignal) {\n await backend.sleepWorkflowRun({\n workflowRunId: workflowRun.id,\n workerId,\n availableAt: error.resumeAt,\n });\n\n return;\n }\n\n // mark failure\n await backend.failWorkflowRun({\n workflowRunId: workflowRun.id,\n workerId,\n error: serializeError(error),\n });\n }\n}\n"],"names":["serializeError","addToStepAttemptCache","calculateSleepResumeAt","createSleepContext","createStepAttemptCacheFromAttempts","getCachedStepAttempt","normalizeStepOutput","SleepSignal","Error","resumeAt","name","StepExecutor","backend","workflowRunId","workerId","cache","options","attempts","run","config","fn","existingAttempt","output","attempt","createStepAttempt","stepName","kind","context","result","savedAttempt","completeStepAttempt","stepAttemptId","id","error","failStepAttempt","sleep","duration","ok","value","executeWorkflow","params","workflowRun","workflowFn","workflowVersion","cursor","response","listStepAttempts","after","limit","push","data","pagination","next","undefined","i","length","status","now","Date","resumeAtMs","getTime","completed","executor","input","step","version","completeWorkflowRun","sleepWorkflowRun","availableAt","failWorkflowRun"],"mappings":"AAEA,SAASA,cAAc,QAAQ,kBAAe;AAG9C,SACEC,qBAAqB,EACrBC,sBAAsB,EACtBC,kBAAkB,EAClBC,kCAAkC,EAClCC,oBAAoB,EACpBC,mBAAmB,QACd,iBAAc;AA6CrB;;;CAGC,GACD,MAAMC,oBAAoBC;IACfC,SAAe;IAExB,YAAYA,QAAwB,CAAE;QACpC,KAAK,CAAC;QACN,IAAI,CAACC,IAAI,GAAG;QACZ,IAAI,CAACD,QAAQ,GAAGA;IAClB;AACF;AAYA;;;CAGC,GACD,OAAO,MAAME;IACMC,QAAiB;IACjBC,cAAsB;IACtBC,SAAiB;IAC1BC,MAAwB;IAEhC,YAAYC,OAAsC,CAAE;QAClD,IAAI,CAACJ,OAAO,GAAGI,QAAQJ,OAAO;QAC9B,IAAI,CAACC,aAAa,GAAGG,QAAQH,aAAa;QAC1C,IAAI,CAACC,QAAQ,GAAGE,QAAQF,QAAQ;QAEhC,IAAI,CAACC,KAAK,GAAGX,mCAAmCY,QAAQC,QAAQ;IAClE;IAEA,MAAMC,IACJC,MAAoC,EACpCC,EAAwB,EACP;QACjB,MAAM,EAAEV,IAAI,EAAE,GAAGS;QAEjB,oCAAoC;QACpC,MAAME,kBAAkBhB,qBAAqB,IAAI,CAACU,KAAK,EAAEL;QACzD,IAAIW,iBAAiB;YACnB,OAAOA,gBAAgBC,MAAM;QAC/B;QAEA,wCAAwC;QACxC,MAAMC,UAAU,MAAM,IAAI,CAACX,OAAO,CAACY,iBAAiB,CAAC;YACnDX,eAAe,IAAI,CAACA,aAAa;YACjCC,UAAU,IAAI,CAACA,QAAQ;YACvBW,UAAUf;YACVgB,MAAM;YACNP,QAAQ,CAAC;YACTQ,SAAS;QACX;QAEA,IAAI;YACF,wBAAwB;YACxB,MAAMC,SAAS,MAAMR;YACrB,MAAME,SAAShB,oBAAoBsB;YAEnC,eAAe;YACf,MAAMC,eAAe,MAAM,IAAI,CAACjB,OAAO,CAACkB,mBAAmB,CAAC;gBAC1DjB,eAAe,IAAI,CAACA,aAAa;gBACjCkB,eAAeR,QAAQS,EAAE;gBACzBlB,UAAU,IAAI,CAACA,QAAQ;gBACvBQ;YACF;YAEA,eAAe;YACf,IAAI,CAACP,KAAK,GAAGd,sBAAsB,IAAI,CAACc,KAAK,EAAEc;YAE/C,OAAOA,aAAaP,MAAM;QAC5B,EAAE,OAAOW,OAAO;YACd,eAAe;YACf,MAAM,IAAI,CAACrB,OAAO,CAACsB,eAAe,CAAC;gBACjCrB,eAAe,IAAI,CAACA,aAAa;gBACjCkB,eAAeR,QAAQS,EAAE;gBACzBlB,UAAU,IAAI,CAACA,QAAQ;gBACvBmB,OAAOjC,eAAeiC;YACxB;YACA,MAAMA;QACR;IACF;IAEA,MAAME,MAAMzB,IAAY,EAAE0B,QAAwB,EAAiB;QACjE,uDAAuD;QACvD,MAAMf,kBAAkBhB,qBAAqB,IAAI,CAACU,KAAK,EAAEL;QACzD,IAAIW,iBAAiB;QAErB,wCAAwC;QACxC,MAAMO,SAAS1B,uBAAuBkC;QACtC,IAAI,CAACR,OAAOS,EAAE,EAAE;YACd,MAAMT,OAAOK,KAAK;QACpB;QACA,MAAMxB,WAAWmB,OAAOU,KAAK;QAC7B,MAAMX,UAAUxB,mBAAmBM;QAEnC,MAAM,IAAI,CAACG,OAAO,CAACY,iBAAiB,CAAC;YACnCX,eAAe,IAAI,CAACA,aAAa;YACjCC,UAAU,IAAI,CAACA,QAAQ;YACvBW,UAAUf;YACVgB,MAAM;YACNP,QAAQ,CAAC;YACTQ;QACF;QAEA,6CAA6C;QAC7C,gEAAgE;QAChE,4BAA4B;QAC5B,MAAM,IAAIpB,YAAYE;IACxB;AACF;AAaA;;;;;;;;CAQC,GACD,OAAO,eAAe8B,gBAAgBC,MAAuC;IAC3E,MAAM,EAAE5B,OAAO,EAAE6B,WAAW,EAAEC,UAAU,EAAEC,eAAe,EAAE7B,QAAQ,EAAE,GAAG0B;IAExE,IAAI;QACF,iCAAiC;QACjC,MAAMvB,WAA0B,EAAE;QAClC,IAAI2B;QACJ,GAAG;YACD,MAAMC,WAAW,MAAMjC,QAAQkC,gBAAgB,CAAC;gBAC9CjC,eAAe4B,YAAYT,EAAE;gBAC7B,GAAIY,SAAS;oBAAEG,OAAOH;gBAAO,IAAI,CAAC,CAAC;gBACnCI,OAAO;YACT;YACA/B,SAASgC,IAAI,IAAIJ,SAASK,IAAI;YAC9BN,SAASC,SAASM,UAAU,CAACC,IAAI,IAAIC;QACvC,QAAST,OAAQ;QAEjB,yEAAyE;QACzE,2CAA2C;QAC3C,IAAK,IAAIU,IAAI,GAAGA,IAAIrC,SAASsC,MAAM,EAAED,IAAK;YACxC,MAAM/B,UAAUN,QAAQ,CAACqC,EAAE;YAC3B,IAAI,CAAC/B,SAAS;YAEd,IACEA,QAAQiC,MAAM,KAAK,aACnBjC,QAAQG,IAAI,KAAK,WACjBH,QAAQI,OAAO,EAAED,SAAS,SAC1B;gBACA,MAAM+B,MAAMC,KAAKD,GAAG;gBACpB,MAAMhD,WAAW,IAAIiD,KAAKnC,QAAQI,OAAO,CAAClB,QAAQ;gBAClD,MAAMkD,aAAalD,SAASmD,OAAO;gBAEnC,IAAIH,MAAME,YAAY;oBACpB,mEAAmE;oBACnE,gBAAgB;oBAChB,MAAM,IAAIpD,YAAYE;gBACxB;gBAEA,sEAAsE;gBACtE,MAAMoD,YAAY,MAAMjD,QAAQkB,mBAAmB,CAAC;oBAClDjB,eAAe4B,YAAYT,EAAE;oBAC7BD,eAAeR,QAAQS,EAAE;oBACzBlB;oBACAQ,QAAQ;gBACV;gBAEA,oCAAoC;gBACpCL,QAAQ,CAACqC,EAAE,GAAGO;YAChB;QACF;QAEA,uBAAuB;QACvB,MAAMC,WAAW,IAAInD,aAAa;YAChCC;YACAC,eAAe4B,YAAYT,EAAE;YAC7BlB;YACAG;QACF;QAEA,mBAAmB;QACnB,MAAMK,SAAS,MAAMoB,WAAW;YAC9BqB,OAAOtB,YAAYsB,KAAK;YACxBC,MAAMF;YACNG,SAAStB;QACX;QAEA,eAAe;QACf,MAAM/B,QAAQsD,mBAAmB,CAAC;YAChCrD,eAAe4B,YAAYT,EAAE;YAC7BlB;YACAQ,QAASA,UAAU;QACrB;IACF,EAAE,OAAOW,OAAO;QACd,6DAA6D;QAC7D,IAAIA,iBAAiB1B,aAAa;YAChC,MAAMK,QAAQuD,gBAAgB,CAAC;gBAC7BtD,eAAe4B,YAAYT,EAAE;gBAC7BlB;gBACAsD,aAAanC,MAAMxB,QAAQ;YAC7B;YAEA;QACF;QAEA,eAAe;QACf,MAAMG,QAAQyD,eAAe,CAAC;YAC5BxD,eAAe4B,YAAYT,EAAE;YAC7BlB;YACAmB,OAAOjC,eAAeiC;QACxB;IACF;AACF"}
|
|
1
|
+
{"version":3,"sources":["../src/execution.ts"],"sourcesContent":["import type { Backend } from \"./backend\";\nimport type { DurationString } from \"./core/duration\";\nimport { serializeError } from \"./core/error\";\nimport type { JsonValue } from \"./core/json\";\nimport { isDynamicRetryPolicy, type RetryPolicy } from \"./core/retry\";\nimport type { StepAttempt, StepAttemptCache } from \"./core/step\";\nimport {\n addToStepAttemptCache,\n calculateSleepResumeAt,\n createSleepContext,\n createStepAttemptCacheFromAttempts,\n getCachedStepAttempt,\n normalizeStepOutput,\n} from \"./core/step\";\nimport type { WorkflowRun } from \"./core/workflow\";\n\n/**\n * Config for an individual step defined with `step.run()`.\n */\nexport interface StepFunctionConfig {\n /**\n * The name of the step.\n */\n name: string;\n}\n\n/**\n * Represents the API for defining steps within a workflow. Used within a\n * workflow handler to define steps by calling `step.run()`.\n */\nexport interface StepApi {\n run<Output>(config: Readonly<StepFunctionConfig>, fn: StepFunction<Output>): Promise<Output>;\n sleep(name: string, duration: DurationString): Promise<void>;\n}\n\n/**\n * The step definition (defined by the user) that executes user code. Can return\n * undefined (e.g., when using `return;`) which will be converted to null.\n */\nexport type StepFunction<Output> = () => Promise<Output | undefined> | Output | undefined;\n\n/**\n * Params passed to a workflow function for the user to use when defining steps.\n */\nexport interface WorkflowFunctionParams<Input> {\n input: Input;\n step: StepApi;\n version: string | null;\n}\n\n/**\n * The workflow definition's function (defined by the user) that the user uses\n * to define the workflow's steps.\n */\nexport type WorkflowFunction<Input, Output> = (\n params: Readonly<WorkflowFunctionParams<Input>>,\n) => Promise<Output> | Output;\n\n/**\n * Signal thrown when a workflow needs to sleep. Contains the time when the\n * workflow should resume.\n */\nclass SleepSignal extends Error {\n readonly resumeAt: Date;\n\n constructor(resumeAt: Readonly<Date>) {\n super(\"SleepSignal\");\n this.name = \"SleepSignal\";\n this.resumeAt = resumeAt;\n }\n}\n\n/**\n * Configures the options for a StepExecutor.\n */\nexport interface StepExecutorOptions {\n backend: Backend;\n workflowRunId: string;\n workerId: string;\n attempts: StepAttempt[];\n}\n\n/**\n * Replays prior step attempts and persists new ones while memoizing\n * deterministic step outputs.\n */\nexport class StepExecutor implements StepApi {\n private readonly backend: Backend;\n private readonly workflowRunId: string;\n private readonly workerId: string;\n private cache: StepAttemptCache;\n\n constructor(options: Readonly<StepExecutorOptions>) {\n this.backend = options.backend;\n this.workflowRunId = options.workflowRunId;\n this.workerId = options.workerId;\n\n this.cache = createStepAttemptCacheFromAttempts(options.attempts);\n }\n\n async run<Output>(\n config: Readonly<StepFunctionConfig>,\n fn: StepFunction<Output>,\n ): Promise<Output> {\n const { name } = config;\n\n // return cached result if available\n const existingAttempt = getCachedStepAttempt(this.cache, name);\n if (existingAttempt) {\n return existingAttempt.output as Output;\n }\n\n // not in cache, create new step attempt\n const attempt = await this.backend.createStepAttempt({\n workflowRunId: this.workflowRunId,\n workerId: this.workerId,\n stepName: name,\n kind: \"function\",\n config: {},\n context: null,\n });\n\n try {\n // execute step function\n const result = await fn();\n const output = normalizeStepOutput(result);\n\n // mark success\n const savedAttempt = await this.backend.completeStepAttempt({\n workflowRunId: this.workflowRunId,\n stepAttemptId: attempt.id,\n workerId: this.workerId,\n output,\n });\n\n // cache result\n this.cache = addToStepAttemptCache(this.cache, savedAttempt);\n\n return savedAttempt.output as Output;\n } catch (error) {\n // mark failure\n await this.backend.failStepAttempt({\n workflowRunId: this.workflowRunId,\n stepAttemptId: attempt.id,\n workerId: this.workerId,\n error: serializeError(error),\n });\n throw error;\n }\n }\n\n async sleep(name: string, duration: DurationString): Promise<void> {\n // return cached result if this sleep already completed\n const existingAttempt = getCachedStepAttempt(this.cache, name);\n if (existingAttempt) return;\n\n // create new step attempt for the sleep\n const result = calculateSleepResumeAt(duration);\n if (!result.ok) {\n throw result.error;\n }\n const resumeAt = result.value;\n const context = createSleepContext(resumeAt);\n\n await this.backend.createStepAttempt({\n workflowRunId: this.workflowRunId,\n workerId: this.workerId,\n stepName: name,\n kind: \"sleep\",\n config: {},\n context,\n });\n\n // throw sleep signal to trigger postponement\n // we do not mark the step as completed here; it will be updated\n // when the workflow resumes\n throw new SleepSignal(resumeAt);\n }\n}\n\n/**\n * Parameters for the workflow execution use case.\n */\nexport interface ExecuteWorkflowParams {\n backend: Backend;\n workflowRun: WorkflowRun;\n workflowFn: WorkflowFunction<unknown, unknown>;\n workflowVersion: string | null;\n workerId: string;\n retryPolicy?: RetryPolicy;\n}\n\n/**\n * Execute a workflow run. This is the core application use case that handles:\n * - Loading step history\n * - Handling sleeping steps\n * - Creating the step executor\n * - Executing the workflow function\n * - Completing, failing, or sleeping the workflow run based on the outcome\n * @param params - The execution parameters\n */\nexport async function executeWorkflow(params: Readonly<ExecuteWorkflowParams>): Promise<void> {\n const { backend, workflowRun, workflowFn, workflowVersion, workerId, retryPolicy } = params;\n\n try {\n // load all pages of step history\n const attempts: StepAttempt[] = [];\n let cursor: string | undefined;\n do {\n const response = await backend.listStepAttempts({\n workflowRunId: workflowRun.id,\n ...(cursor ? { after: cursor } : {}),\n limit: 1000,\n });\n attempts.push(...response.data);\n cursor = response.pagination.next ?? undefined;\n } while (cursor);\n\n // mark any sleep steps as completed if their sleep duration has elapsed,\n // or rethrow SleepSignal if still sleeping\n for (let i = 0; i < attempts.length; i++) {\n const attempt = attempts[i];\n if (!attempt) continue;\n\n if (\n attempt.status === \"running\" &&\n attempt.kind === \"sleep\" &&\n attempt.context?.kind === \"sleep\"\n ) {\n const now = Date.now();\n const resumeAt = new Date(attempt.context.resumeAt);\n const resumeAtMs = resumeAt.getTime();\n\n if (now < resumeAtMs) {\n // sleep duration HAS NOT elapsed yet, throw signal to put workflow\n // back to sleep\n throw new SleepSignal(resumeAt);\n }\n\n // sleep duration HAS elapsed, mark the step as completed and continue\n const completed = await backend.completeStepAttempt({\n workflowRunId: workflowRun.id,\n stepAttemptId: attempt.id,\n workerId,\n output: null,\n });\n\n // update cache w/ completed attempt\n attempts[i] = completed;\n }\n }\n\n // create step executor\n const executor = new StepExecutor({\n backend,\n workflowRunId: workflowRun.id,\n workerId,\n attempts,\n });\n\n // execute workflow\n const output = await workflowFn({\n input: workflowRun.input as unknown,\n step: executor,\n version: workflowVersion,\n });\n\n // mark success\n await backend.completeWorkflowRun({\n workflowRunId: workflowRun.id,\n workerId,\n output: (output ?? null) as JsonValue,\n });\n } catch (error) {\n // handle sleep signal by setting workflow to sleeping status\n if (error instanceof SleepSignal) {\n await backend.sleepWorkflowRun({\n workflowRunId: workflowRun.id,\n workerId,\n availableAt: error.resumeAt,\n });\n\n return;\n }\n\n // claimWorkflowRun에서 이미 attempts가 증가된 상태입니다.\n let forceComplete = false;\n let customDelayMs: number | undefined;\n if (retryPolicy && isDynamicRetryPolicy(retryPolicy)) {\n const serializedError = serializeError(error);\n const decision = retryPolicy.shouldRetry(serializedError, workflowRun.attempts ?? 1);\n if (!decision.shouldRetry) {\n forceComplete = true;\n } else {\n customDelayMs = decision.delayMs;\n }\n }\n\n await backend.failWorkflowRun({\n workflowRunId: workflowRun.id,\n workerId,\n error: serializeError(error),\n forceComplete,\n customDelayMs,\n });\n }\n}\n"],"names":["serializeError","isDynamicRetryPolicy","addToStepAttemptCache","calculateSleepResumeAt","createSleepContext","createStepAttemptCacheFromAttempts","getCachedStepAttempt","normalizeStepOutput","SleepSignal","Error","resumeAt","name","StepExecutor","backend","workflowRunId","workerId","cache","options","attempts","run","config","fn","existingAttempt","output","attempt","createStepAttempt","stepName","kind","context","result","savedAttempt","completeStepAttempt","stepAttemptId","id","error","failStepAttempt","sleep","duration","ok","value","executeWorkflow","params","workflowRun","workflowFn","workflowVersion","retryPolicy","cursor","response","listStepAttempts","after","limit","push","data","pagination","next","undefined","i","length","status","now","Date","resumeAtMs","getTime","completed","executor","input","step","version","completeWorkflowRun","sleepWorkflowRun","availableAt","forceComplete","customDelayMs","serializedError","decision","shouldRetry","delayMs","failWorkflowRun"],"mappings":"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"}
|