@lostgradient/weft 0.23.0 → 0.24.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +72 -4
- package/dist/cli/codegen-emit-dedup.d.ts +81 -0
- package/dist/cli/codegen-emit-dedup.js +45 -0
- package/dist/cli/codegen-emit-registry.d.ts +90 -0
- package/dist/cli/codegen-emit-registry.js +50 -0
- package/dist/cli/codegen-emit.d.ts +26 -39
- package/dist/cli/codegen-emit.js +4 -27
- package/dist/cli/codegen-validate.d.ts +49 -0
- package/dist/cli/codegen-validate.js +186 -0
- package/dist/cli/codegen.js +6 -87
- package/dist/cli/generated/operation-catalog.snapshot.json +287 -3
- package/dist/cli/generated/operation-client.generated.d.ts +324 -10
- package/dist/cli/generated/operation-client.generated.js +12 -0
- package/dist/cli/output.js +1 -1
- package/dist/cli/storage-factory.js +2 -0
- package/dist/cli/workflow-commands.js +2 -0
- package/dist/cli-main.js +1 -1
- package/dist/core/application-payload-digest.d.ts +42 -0
- package/dist/core/application-payload-digest.js +76 -0
- package/dist/core/application-primitive-abort.d.ts +50 -0
- package/dist/core/application-primitive-abort.js +40 -0
- package/dist/core/application-primitive-attempt-registry.d.ts +74 -0
- package/dist/core/application-primitive-attempt-registry.js +73 -0
- package/dist/core/application-primitive-codec.d.ts +36 -0
- package/dist/core/application-primitive-codec.js +56 -0
- package/dist/core/application-primitive-commit.d.ts +67 -0
- package/dist/core/application-primitive-commit.js +66 -0
- package/dist/core/application-primitive-guards.d.ts +62 -0
- package/dist/core/application-primitive-guards.js +89 -0
- package/dist/core/application-primitive-payload.d.ts +29 -0
- package/dist/core/application-primitive-payload.js +65 -0
- package/dist/core/application-primitive-timing.d.ts +18 -0
- package/dist/core/application-primitive-timing.js +22 -0
- package/dist/core/atomic-state.js +2 -0
- package/dist/core/catalog/codec.d.ts +40 -0
- package/dist/core/catalog/codec.js +45 -0
- package/dist/core/catalog/errors.d.ts +104 -0
- package/dist/core/catalog/errors.js +41 -0
- package/dist/core/catalog/index.d.ts +25 -0
- package/dist/core/catalog/index.js +15 -0
- package/dist/core/catalog/reference-counts.d.ts +105 -0
- package/dist/core/catalog/reference-counts.js +28 -0
- package/dist/core/catalog/removal.d.ts +52 -0
- package/dist/core/catalog/removal.js +14 -0
- package/dist/core/catalog/storage-io.d.ts +78 -0
- package/dist/core/catalog/storage-io.js +106 -0
- package/dist/core/catalog/types.d.ts +108 -0
- package/dist/core/catalog/types.js +0 -0
- package/dist/core/catalog/workflow-catalog.d.ts +165 -0
- package/dist/core/catalog/workflow-catalog.js +198 -0
- package/dist/core/compare-codepoint.d.ts +13 -0
- package/dist/core/compare-codepoint.js +7 -0
- package/dist/core/compression.js +2 -0
- package/dist/core/context/attributes.d.ts +1 -1
- package/dist/core/context/durable-operations.d.ts +2 -2
- package/dist/core/context/index.js +5 -3
- package/dist/core/context/state-namespace.d.ts +1 -1
- package/dist/core/contract/build.d.ts +64 -0
- package/dist/core/contract/build.js +99 -0
- package/dist/core/contract/compatibility.d.ts +187 -0
- package/dist/core/contract/compatibility.js +37 -0
- package/dist/core/contract/failure.d.ts +64 -0
- package/dist/core/contract/failure.js +4 -0
- package/dist/core/contract/hash.d.ts +92 -0
- package/dist/core/contract/hash.js +34 -0
- package/dist/core/contract/index.d.ts +21 -0
- package/dist/core/contract/index.js +22 -0
- package/dist/core/contract/limits.d.ts +74 -0
- package/dist/core/contract/limits.js +1 -0
- package/dist/core/contract/manifest-parse-schema.d.ts +37 -0
- package/dist/core/contract/manifest-parse-schema.js +106 -0
- package/dist/core/contract/manifest-parse.d.ts +76 -0
- package/dist/core/contract/manifest-parse.js +189 -0
- package/dist/core/contract/manifest.d.ts +56 -0
- package/dist/core/contract/manifest.js +31 -0
- package/dist/core/contract/normalize.d.ts +97 -0
- package/dist/core/contract/normalize.js +127 -0
- package/dist/core/contract/revision.d.ts +29 -0
- package/dist/core/contract/revision.js +5 -0
- package/dist/core/contract/types.d.ts +274 -0
- package/dist/core/contract/types.js +1 -0
- package/dist/core/engine/catalog-activation.d.ts +40 -0
- package/dist/core/engine/catalog-activation.js +17 -0
- package/dist/core/engine/catalog-events.d.ts +36 -0
- package/dist/core/engine/catalog-events.js +15 -0
- package/dist/core/engine/catalog-readiness.d.ts +49 -0
- package/dist/core/engine/catalog-readiness.js +59 -0
- package/dist/core/engine/catalog-removal.d.ts +132 -0
- package/dist/core/engine/catalog-removal.js +70 -0
- package/dist/core/engine/construction.d.ts +1 -1
- package/dist/core/engine/construction.js +4 -2
- package/dist/core/engine/disposal.js +9 -0
- package/dist/core/engine/engine-workflows-namespace.d.ts +130 -0
- package/dist/core/engine/engine-workflows-namespace.js +49 -0
- package/dist/core/engine/finalizer-metadata.d.ts +22 -0
- package/dist/core/engine/finalizer-metadata.js +12 -0
- package/dist/core/engine/handle-result.js +2 -0
- package/dist/core/engine/index.d.ts +83 -0
- package/dist/core/engine/index.js +61 -0
- package/dist/core/engine/internals.d.ts +44 -1
- package/dist/core/engine/internals.js +6 -0
- package/dist/core/engine/lifecycle/start.js +3 -0
- package/dist/core/engine/registration.d.ts +76 -0
- package/dist/core/engine/registration.js +12 -6
- package/dist/core/engine/source-registration.d.ts +42 -0
- package/dist/core/engine/source-registration.js +36 -0
- package/dist/core/engine/source-resolution.d.ts +85 -0
- package/dist/core/engine/source-resolution.js +119 -0
- package/dist/core/engine/validation.js +2 -2
- package/dist/core/events/catalog-events.d.ts +117 -0
- package/dist/core/events/catalog-events.js +62 -0
- package/dist/core/events/event-map.d.ts +6 -0
- package/dist/core/events/index.d.ts +1 -0
- package/dist/core/events/index.js +1 -0
- package/dist/core/mailbox-admission.d.ts +26 -0
- package/dist/core/mailbox-admission.js +130 -0
- package/dist/core/mailbox-claims.d.ts +251 -0
- package/dist/core/mailbox-claims.js +0 -0
- package/dist/core/mailbox-codec.d.ts +32 -0
- package/dist/core/mailbox-codec.js +221 -0
- package/dist/core/mailbox-contract.d.ts +290 -0
- package/dist/core/mailbox-contract.js +0 -0
- package/dist/core/mailbox-delivery.d.ts +37 -0
- package/dist/core/mailbox-delivery.js +193 -0
- package/dist/core/mailbox-guards.d.ts +78 -0
- package/dist/core/mailbox-guards.js +58 -0
- package/dist/core/mailbox-index-codec.d.ts +41 -0
- package/dist/core/mailbox-index-codec.js +71 -0
- package/dist/core/mailbox-internals.d.ts +156 -0
- package/dist/core/mailbox-internals.js +154 -0
- package/dist/core/mailbox-maintenance.d.ts +29 -0
- package/dist/core/mailbox-maintenance.js +196 -0
- package/dist/core/mailbox-settlement.d.ts +69 -0
- package/dist/core/mailbox-settlement.js +206 -0
- package/dist/core/mailbox-storage.d.ts +117 -0
- package/dist/core/mailbox-storage.js +115 -0
- package/dist/core/mailbox-transition-helpers.d.ts +70 -0
- package/dist/core/mailbox-transition-helpers.js +43 -0
- package/dist/core/mailbox-transitions-recovery.d.ts +28 -0
- package/dist/core/mailbox-transitions-recovery.js +64 -0
- package/dist/core/mailbox-transitions.d.ts +138 -0
- package/dist/core/mailbox-transitions.js +180 -0
- package/dist/core/mailbox-types.d.ts +406 -0
- package/dist/core/mailbox-types.js +16 -0
- package/dist/core/mailbox-validation.d.ts +65 -0
- package/dist/core/mailbox-validation.js +73 -0
- package/dist/core/mailbox-waits.d.ts +50 -0
- package/dist/core/mailbox-waits.js +97 -0
- package/dist/core/mailbox.d.ts +163 -0
- package/dist/core/mailbox.js +211 -0
- package/dist/core/outbox-claims.d.ts +307 -0
- package/dist/core/outbox-claims.js +0 -0
- package/dist/core/outbox-codec.d.ts +24 -0
- package/dist/core/outbox-codec.js +257 -0
- package/dist/core/outbox-contract.d.ts +346 -0
- package/dist/core/outbox-contract.js +0 -0
- package/dist/core/outbox-delivery.d.ts +34 -0
- package/dist/core/outbox-delivery.js +149 -0
- package/dist/core/outbox-drain.d.ts +29 -0
- package/dist/core/outbox-drain.js +158 -0
- package/dist/core/outbox-enqueue.d.ts +24 -0
- package/dist/core/outbox-enqueue.js +115 -0
- package/dist/core/outbox-guards.d.ts +76 -0
- package/dist/core/outbox-guards.js +60 -0
- package/dist/core/outbox-index-codec.d.ts +33 -0
- package/dist/core/outbox-index-codec.js +71 -0
- package/dist/core/outbox-internals.d.ts +99 -0
- package/dist/core/outbox-internals.js +159 -0
- package/dist/core/outbox-listing.d.ts +12 -0
- package/dist/core/outbox-listing.js +38 -0
- package/dist/core/outbox-maintenance.d.ts +28 -0
- package/dist/core/outbox-maintenance.js +191 -0
- package/dist/core/outbox-operations.d.ts +18 -0
- package/dist/core/outbox-operations.js +46 -0
- package/dist/core/outbox-runner.d.ts +30 -0
- package/dist/core/outbox-runner.js +217 -0
- package/dist/core/outbox-settlement.d.ts +57 -0
- package/dist/core/outbox-settlement.js +183 -0
- package/dist/core/outbox-storage.d.ts +107 -0
- package/dist/core/outbox-storage.js +127 -0
- package/dist/core/outbox-transition-helpers.d.ts +83 -0
- package/dist/core/outbox-transition-helpers.js +63 -0
- package/dist/core/outbox-transitions-recovery.d.ts +30 -0
- package/dist/core/outbox-transitions-recovery.js +42 -0
- package/dist/core/outbox-transitions.d.ts +145 -0
- package/dist/core/outbox-transitions.js +236 -0
- package/dist/core/outbox-types.d.ts +400 -0
- package/dist/core/outbox-types.js +20 -0
- package/dist/core/outbox-validation.d.ts +101 -0
- package/dist/core/outbox-validation.js +127 -0
- package/dist/core/outbox-waits.d.ts +39 -0
- package/dist/core/outbox-waits.js +88 -0
- package/dist/core/outbox.d.ts +156 -0
- package/dist/core/outbox.js +234 -0
- package/dist/core/registry-limits.d.ts +49 -0
- package/dist/core/registry-limits.js +10 -0
- package/dist/core/registry-schema-conversion.d.ts +20 -0
- package/dist/core/registry-schema-conversion.js +22 -0
- package/dist/core/registry-snapshot.d.ts +91 -42
- package/dist/core/registry-snapshot.js +39 -77
- package/dist/core/registry-workflow-contract-draft.d.ts +32 -0
- package/dist/core/registry-workflow-contract-draft.js +28 -0
- package/dist/core/registry-workflow-manifest.d.ts +122 -0
- package/dist/core/registry-workflow-manifest.js +92 -0
- package/dist/core/source/errors.d.ts +55 -0
- package/dist/core/source/errors.js +13 -0
- package/dist/core/source/index.d.ts +19 -0
- package/dist/core/source/index.js +4 -0
- package/dist/core/source/resolvers.d.ts +45 -0
- package/dist/core/source/resolvers.js +9 -0
- package/dist/core/source/types.d.ts +211 -0
- package/dist/core/source/types.js +0 -0
- package/dist/core/source/validate.d.ts +91 -0
- package/dist/core/source/validate.js +62 -0
- package/dist/core/source/workflow-source.d.ts +43 -0
- package/dist/core/source/workflow-source.js +16 -0
- package/dist/core/types/workflow-registries.d.ts +7 -0
- package/dist/core/types/workflow-registry.d.ts +12 -0
- package/dist/core/versioning.js +2 -0
- package/dist/core/weft-error.d.ts +1 -1
- package/dist/core/weft-error.js +9 -1
- package/dist/http.js +2 -2
- package/dist/index.d.ts +23 -2
- package/dist/index.js +50 -0
- package/dist/indexeddb.js +1 -1
- package/dist/json-schema.js +3 -3
- package/dist/mcp/resources.js +2 -0
- package/dist/runtime/portable.d.ts +9 -1
- package/dist/server/fault-to-json-rpc.js +3 -1
- package/dist/server/handler/auth-context-principal.js +4 -0
- package/dist/server/json-rpc-http.js +2 -0
- package/dist/server/json-rpc-websocket.js +6 -4
- package/dist/server/operation-catalog/index.d.ts +1 -1
- package/dist/server/operation-catalog/pipeline-helpers.js +2 -0
- package/dist/server/operation-catalog/types.d.ts +17 -0
- package/dist/server/operation-fault.d.ts +3 -0
- package/dist/server/operation-fault.js +3 -1
- package/dist/server/operations/activate-workflow-revision.d.ts +30 -0
- package/dist/server/operations/activate-workflow-revision.js +69 -0
- package/dist/server/operations/fleet-events-subscription.js +1 -1
- package/dist/server/operations/fork-workflow.js +1 -1
- package/dist/server/operations/get-active-workflow-revision.d.ts +32 -0
- package/dist/server/operations/get-active-workflow-revision.js +46 -0
- package/dist/server/operations/get-catalog-diagnostics.d.ts +85 -0
- package/dist/server/operations/get-catalog-diagnostics.js +57 -0
- package/dist/server/operations/get-registry.js +17 -4
- package/dist/server/operations/get-workflow-revision.d.ts +25 -0
- package/dist/server/operations/get-workflow-revision.js +50 -0
- package/dist/server/operations/install-workflow-revision.d.ts +27 -0
- package/dist/server/operations/install-workflow-revision.js +46 -0
- package/dist/server/operations/list-workflow-revisions.d.ts +20 -0
- package/dist/server/operations/list-workflow-revisions.js +40 -0
- package/dist/server/operations/start-or-signal-workflow.js +1 -1
- package/dist/server/operations/start-workflow.js +1 -1
- package/dist/server/operations/static-registrations.js +36 -0
- package/dist/server/operations/storage.js +2 -2
- package/dist/server/operations/submit-review-decision.js +1 -1
- package/dist/server/operations/workflow-catalog-operation-helpers.d.ts +59 -0
- package/dist/server/operations/workflow-catalog-operation-helpers.js +135 -0
- package/dist/server/runtime/websocket-upgrade.js +2 -0
- package/dist/storage/bun-sql.js +49 -6
- package/dist/storage/catalog-keys.d.ts +45 -0
- package/dist/storage/catalog-keys.js +6 -0
- package/dist/storage/compressed-storage.js +1 -1
- package/dist/storage/derived-operations.js +1 -1
- package/dist/storage/index.d.ts +26 -1
- package/dist/storage/interface.d.ts +26 -1
- package/dist/storage/interface.js +1 -1
- package/dist/storage/key-encoding.d.ts +15 -0
- package/dist/storage/key-encoding.js +3 -0
- package/dist/storage/key-prefixes.d.ts +1 -1
- package/dist/storage/key-prefixes.js +15 -0
- package/dist/storage/lmdb.d.ts +26 -1
- package/dist/storage/lmdb.js +1 -1
- package/dist/storage/mailbox-keys.d.ts +80 -0
- package/dist/storage/mailbox-keys.js +14 -0
- package/dist/storage/memory.js +1 -1
- package/dist/storage/neon.js +2 -2
- package/dist/storage/node-sqlite-loader.d.ts +1 -1
- package/dist/storage/node-sqlite-loader.js +2 -2
- package/dist/storage/node-sqlite.js +51 -8
- package/dist/storage/outbox-keys.d.ts +77 -0
- package/dist/storage/outbox-keys.js +14 -0
- package/dist/storage/postgres.js +2 -2
- package/dist/storage/resolve.js +1 -1
- package/dist/storage/scoped-storage.js +1 -1
- package/dist/storage/storage-configuration.d.ts +6 -0
- package/dist/storage/testing.js +1 -1
- package/dist/storage/turso.js +2 -2
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/dist/web-extension.js +1 -1
- package/dist/worker/manifest/registry-contract-builder.d.ts +21 -3
- package/dist/worker/manifest/registry-contract-builder.js +40 -31
- package/package.json +1 -1
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
import { encodeStorageKeyComponent, KEYS } from "../storage/interface.js";
|
|
2
|
+
import {
|
|
3
|
+
commitApplicationTransition
|
|
4
|
+
} from "./application-primitive-commit.js";
|
|
5
|
+
import {
|
|
6
|
+
decodeApplicationDeliveryRecord,
|
|
7
|
+
encodeApplicationDeliveryRecord
|
|
8
|
+
} from "./outbox-codec.js";
|
|
9
|
+
import {
|
|
10
|
+
decodeApplicationDeliveryEntry,
|
|
11
|
+
decodeApplicationDeliveryIdempotencyRecord,
|
|
12
|
+
decodeOutboxRecord,
|
|
13
|
+
encodeApplicationDeliveryEntry,
|
|
14
|
+
encodeOutboxRecord
|
|
15
|
+
} from "./outbox-index-codec.js";
|
|
16
|
+
import {
|
|
17
|
+
isApplicationDeliveryTerminalState,
|
|
18
|
+
isApplicationDeliveryWaiting,
|
|
19
|
+
OUTBOX_RECORD_VERSION
|
|
20
|
+
} from "./outbox-types.js";
|
|
21
|
+
import { PersistedDataCorruptError } from "./persisted-data-incompatible-error.js";
|
|
22
|
+
export function createOutboxKeys(namespace, ownerId) {
|
|
23
|
+
return {
|
|
24
|
+
header: KEYS.applicationOutbox(namespace, ownerId),
|
|
25
|
+
sinkProbe: (nonce) => KEYS.applicationOutboxSinkProbe(namespace, ownerId, nonce),
|
|
26
|
+
deliveryPrefix: KEYS.applicationDeliveryPrefix(namespace, ownerId),
|
|
27
|
+
delivery: (deliveryId) => KEYS.applicationDelivery(namespace, ownerId, deliveryId),
|
|
28
|
+
duePrefix: KEYS.applicationDeliveryDuePrefix(namespace, ownerId),
|
|
29
|
+
due: (availableAt, deliveryId) => KEYS.applicationDeliveryDue(namespace, ownerId, availableAt, deliveryId),
|
|
30
|
+
bySequencePrefix: KEYS.applicationDeliveryBySequencePrefix(namespace, ownerId),
|
|
31
|
+
bySequence: (sequence) => KEYS.applicationDeliveryBySequence(namespace, ownerId, sequence),
|
|
32
|
+
idempotency: (key) => KEYS.applicationDeliveryIdempotency(namespace, ownerId, key),
|
|
33
|
+
terminalPrefix: KEYS.applicationDeliveryTerminalPrefix(namespace, ownerId),
|
|
34
|
+
terminal: (terminalAt, deliveryId) => KEYS.applicationDeliveryTerminal(namespace, ownerId, terminalAt, deliveryId)
|
|
35
|
+
};
|
|
36
|
+
}
|
|
37
|
+
export function emptyOutboxRecord(namespace, ownerId) {
|
|
38
|
+
return {
|
|
39
|
+
recordVersion: OUTBOX_RECORD_VERSION,
|
|
40
|
+
namespace,
|
|
41
|
+
ownerId,
|
|
42
|
+
nextSequence: 0,
|
|
43
|
+
openCount: 0,
|
|
44
|
+
enqueuedCount: 0
|
|
45
|
+
};
|
|
46
|
+
}
|
|
47
|
+
export async function loadOutboxHeader(storage, keys, namespace, ownerId) {
|
|
48
|
+
const bytes = await storage.get(keys.header);
|
|
49
|
+
if (bytes === null)
|
|
50
|
+
return { record: emptyOutboxRecord(namespace, ownerId), bytes: null };
|
|
51
|
+
return { record: decodeOutboxRecord(bytes, keys.header), bytes };
|
|
52
|
+
}
|
|
53
|
+
export async function loadDelivery(storage, keys, deliveryId) {
|
|
54
|
+
const key = keys.delivery(deliveryId), bytes = await storage.get(key);
|
|
55
|
+
if (bytes === null)
|
|
56
|
+
return null;
|
|
57
|
+
return { record: decodeApplicationDeliveryRecord(bytes, key), bytes };
|
|
58
|
+
}
|
|
59
|
+
export async function loadDeliveryIdempotencyBinding(storage, keys, idempotencyKey) {
|
|
60
|
+
const key = keys.idempotency(idempotencyKey), bytes = await storage.get(key);
|
|
61
|
+
if (bytes === null)
|
|
62
|
+
return null;
|
|
63
|
+
return { record: decodeApplicationDeliveryIdempotencyRecord(bytes, key), bytes };
|
|
64
|
+
}
|
|
65
|
+
export async function loadDueHead(storage, keys, limit) {
|
|
66
|
+
const entries = [];
|
|
67
|
+
for await (const [key, value] of storage.scan(keys.duePrefix, { limit })) {
|
|
68
|
+
const deliveryId = decodeApplicationDeliveryEntry(value, key);
|
|
69
|
+
if (!key.endsWith(`:${encodeStorageKeyComponent(deliveryId)}`))
|
|
70
|
+
throw new PersistedDataCorruptError(key);
|
|
71
|
+
entries.push({ key, bytes: value, deliveryId });
|
|
72
|
+
}
|
|
73
|
+
return entries;
|
|
74
|
+
}
|
|
75
|
+
export function indexOperationsFor(keys, previous, next) {
|
|
76
|
+
return [
|
|
77
|
+
...dueIndexOperations(keys, previous, next),
|
|
78
|
+
...terminalIndexOperations(keys, previous, next)
|
|
79
|
+
];
|
|
80
|
+
}
|
|
81
|
+
function moveIndexEntry(before, after, deliveryId) {
|
|
82
|
+
if (before === after)
|
|
83
|
+
return [];
|
|
84
|
+
const operations = [];
|
|
85
|
+
if (before !== null)
|
|
86
|
+
operations.push({ type: "delete", key: before });
|
|
87
|
+
if (after !== null)
|
|
88
|
+
operations.push({ type: "put", key: after, value: encodeApplicationDeliveryEntry(deliveryId) });
|
|
89
|
+
return operations;
|
|
90
|
+
}
|
|
91
|
+
function dueIndexOperations(keys, previous, next) {
|
|
92
|
+
const before = previous !== null && isApplicationDeliveryWaiting(previous) ? keys.due(previous.availableAt, previous.deliveryId) : null, after = isApplicationDeliveryWaiting(next) ? keys.due(next.availableAt, next.deliveryId) : null;
|
|
93
|
+
return moveIndexEntry(before, after, next.deliveryId);
|
|
94
|
+
}
|
|
95
|
+
function terminalIndexOperations(keys, previous, next) {
|
|
96
|
+
const before = previous !== null && isTerminalRecord(previous) ? keys.terminal(previous.terminalAt, previous.deliveryId) : null, after = isTerminalRecord(next) ? keys.terminal(next.terminalAt, next.deliveryId) : null;
|
|
97
|
+
return moveIndexEntry(before, after, next.deliveryId);
|
|
98
|
+
}
|
|
99
|
+
function isTerminalRecord(record) {
|
|
100
|
+
return isApplicationDeliveryTerminalState(record.state);
|
|
101
|
+
}
|
|
102
|
+
export function commitOutboxTransition(storage, events, plan) {
|
|
103
|
+
return commitApplicationTransition(storage, events, plan, "application outbox");
|
|
104
|
+
}
|
|
105
|
+
export function planDeliveryTransition(keys, options) {
|
|
106
|
+
return {
|
|
107
|
+
sinkProbeKey: keys.sinkProbe(crypto.randomUUID()),
|
|
108
|
+
conditions: [
|
|
109
|
+
{ key: keys.delivery(options.next.deliveryId), expectedValue: options.expectedBytes },
|
|
110
|
+
...options.extraConditions ?? []
|
|
111
|
+
],
|
|
112
|
+
operations: [
|
|
113
|
+
{
|
|
114
|
+
type: "put",
|
|
115
|
+
key: keys.delivery(options.next.deliveryId),
|
|
116
|
+
value: encodeApplicationDeliveryRecord(options.next)
|
|
117
|
+
},
|
|
118
|
+
...indexOperationsFor(keys, options.previous, options.next),
|
|
119
|
+
...options.extraOperations ?? []
|
|
120
|
+
],
|
|
121
|
+
event: options.event,
|
|
122
|
+
now: options.now
|
|
123
|
+
};
|
|
124
|
+
}
|
|
125
|
+
export function headerOperation(keys, record) {
|
|
126
|
+
return { type: "put", key: keys.header, value: encodeOutboxRecord(record) };
|
|
127
|
+
}
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The primitives every outbox transition shares (WFT-85): the
|
|
3
|
+
* rejection vocabulary, the transition result shape, non-terminal narrowing,
|
|
4
|
+
* identity-field carry-over, and retry scheduling.
|
|
5
|
+
*
|
|
6
|
+
* Extracted so `outbox-transitions.ts` and
|
|
7
|
+
* `outbox-transitions-recovery.ts` can both use them without
|
|
8
|
+
* importing each other.
|
|
9
|
+
*
|
|
10
|
+
* @module core/outbox-transition-helpers
|
|
11
|
+
*/
|
|
12
|
+
import { computeRetryBackoffMs } from './application-primitive-timing.ts';
|
|
13
|
+
import type { ApplicationDeliveryFailure, ApplicationDeliveryLeasedRecord, ApplicationDeliveryRecord, ApplicationDeliveryRetryScheduled, ApplicationDeliveryTerminalRecord, ApplicationDeliveryWaitingRecord } from './outbox-types.ts';
|
|
14
|
+
export { computeRetryBackoffMs };
|
|
15
|
+
/**
|
|
16
|
+
* Why a proposed transition is illegal. Stable and low-cardinality, so callers
|
|
17
|
+
* can map each reason onto a discriminated result without string matching.
|
|
18
|
+
*/
|
|
19
|
+
export type OutboxTransitionRejection = 'stale-attempt' | 'not-leased' | 'not-waiting' | 'not-due' | 'not-attempting' | 'deadline-exceeded' | 'already-terminal' | 'cancellation-requested' | 'not-applicable';
|
|
20
|
+
/** The outcome of a proposed transition: the record to persist, or why the edge is illegal. */
|
|
21
|
+
export type OutboxTransition<TNext> = {
|
|
22
|
+
readonly ok: true;
|
|
23
|
+
readonly next: TNext;
|
|
24
|
+
} | {
|
|
25
|
+
readonly ok: false;
|
|
26
|
+
readonly reason: OutboxTransitionRejection;
|
|
27
|
+
};
|
|
28
|
+
export declare function rejectedTransition<TNext>(reason: OutboxTransitionRejection): OutboxTransition<TNext>;
|
|
29
|
+
export declare function succeededTransition<TNext>(next: TNext): OutboxTransition<TNext>;
|
|
30
|
+
/** Narrow a record to a terminal disposition. */
|
|
31
|
+
export declare function isTerminalDeliveryRecord(record: ApplicationDeliveryRecord): record is ApplicationDeliveryTerminalRecord;
|
|
32
|
+
/** Narrow a record to the five non-terminal states, or `null`. */
|
|
33
|
+
export declare function nonTerminalDeliveryRecord(record: ApplicationDeliveryRecord): ApplicationDeliveryWaitingRecord | ApplicationDeliveryLeasedRecord | null;
|
|
34
|
+
/** Strip the state-specific fields so a transition rebuilds a record from identity alone. */
|
|
35
|
+
export declare function applicationDeliveryIdentityFields(record: ApplicationDeliveryRecord): {
|
|
36
|
+
readonly recordVersion: 1;
|
|
37
|
+
readonly namespace: string;
|
|
38
|
+
readonly ownerId: string;
|
|
39
|
+
readonly deliveryId: string;
|
|
40
|
+
readonly sequence: number;
|
|
41
|
+
readonly idempotencyKey: string | undefined;
|
|
42
|
+
readonly destinationRef: string;
|
|
43
|
+
readonly credentialRef: string | undefined;
|
|
44
|
+
readonly kind: string;
|
|
45
|
+
readonly payload: import("./mailbox-types.ts").ApplicationCommandPayload;
|
|
46
|
+
readonly payloadDigest: string;
|
|
47
|
+
readonly payloadMediaType: string | undefined;
|
|
48
|
+
readonly payloadSchema: string | undefined;
|
|
49
|
+
readonly causation: Readonly<{
|
|
50
|
+
correlationId?: string | undefined;
|
|
51
|
+
causationId?: string | undefined;
|
|
52
|
+
traceparent?: string | undefined;
|
|
53
|
+
}> | undefined;
|
|
54
|
+
readonly externalIdempotencyKey: string | undefined;
|
|
55
|
+
readonly unknownOutcomePolicy: import("./outbox-types.ts").ApplicationDeliveryUnknownOutcomePolicy;
|
|
56
|
+
readonly enqueuedAt: number;
|
|
57
|
+
readonly maxAttempts: number;
|
|
58
|
+
readonly visibilityTimeoutMs: number;
|
|
59
|
+
readonly attemptTimeoutMs: number;
|
|
60
|
+
readonly generation: number;
|
|
61
|
+
readonly attempt: number;
|
|
62
|
+
readonly retryCount: number;
|
|
63
|
+
readonly firstClaimedAt: number | undefined;
|
|
64
|
+
readonly availableAt: number;
|
|
65
|
+
};
|
|
66
|
+
/** Backoff policy shared by every reschedule. */
|
|
67
|
+
export type RetryPolicy = {
|
|
68
|
+
readonly retryBackoffMs: number;
|
|
69
|
+
readonly maxRetryBackoffMs: number;
|
|
70
|
+
};
|
|
71
|
+
/**
|
|
72
|
+
* Reschedule a leased delivery for another attempt, or dead-letter it when the
|
|
73
|
+
* attempt budget is spent.
|
|
74
|
+
*
|
|
75
|
+
* The delay is the outbox's own backoff or the transport's suggestion,
|
|
76
|
+
* whichever is longer: a transport asking for more time is honoured, one
|
|
77
|
+
* asking for less is not allowed to defeat the configured backoff.
|
|
78
|
+
*/
|
|
79
|
+
export declare function rescheduleOrDeadLetter(leased: ApplicationDeliveryLeasedRecord, options: {
|
|
80
|
+
readonly now: number;
|
|
81
|
+
readonly failure: ApplicationDeliveryFailure;
|
|
82
|
+
readonly retryAfterMs?: number | undefined;
|
|
83
|
+
} & RetryPolicy): ApplicationDeliveryRetryScheduled | ApplicationDeliveryTerminalRecord;
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import { computeRetryBackoffMs } from "./application-primitive-timing.js";
|
|
2
|
+
import { requireDerivedInstant } from "./outbox-guards.js";
|
|
3
|
+
import { OUTBOX_RECORD_VERSION, isApplicationDeliveryTerminalState } from "./outbox-types.js";
|
|
4
|
+
|
|
5
|
+
export { computeRetryBackoffMs };
|
|
6
|
+
export function rejectedTransition(reason) {
|
|
7
|
+
return { ok: !1, reason };
|
|
8
|
+
}
|
|
9
|
+
export function succeededTransition(next) {
|
|
10
|
+
return { ok: !0, next };
|
|
11
|
+
}
|
|
12
|
+
export function isTerminalDeliveryRecord(record) {
|
|
13
|
+
return isApplicationDeliveryTerminalState(record.state);
|
|
14
|
+
}
|
|
15
|
+
export function nonTerminalDeliveryRecord(record) {
|
|
16
|
+
return isTerminalDeliveryRecord(record) ? null : record;
|
|
17
|
+
}
|
|
18
|
+
export function applicationDeliveryIdentityFields(record) {
|
|
19
|
+
return {
|
|
20
|
+
recordVersion: OUTBOX_RECORD_VERSION,
|
|
21
|
+
namespace: record.namespace,
|
|
22
|
+
ownerId: record.ownerId,
|
|
23
|
+
deliveryId: record.deliveryId,
|
|
24
|
+
sequence: record.sequence,
|
|
25
|
+
idempotencyKey: record.idempotencyKey,
|
|
26
|
+
destinationRef: record.destinationRef,
|
|
27
|
+
credentialRef: record.credentialRef,
|
|
28
|
+
kind: record.kind,
|
|
29
|
+
payload: record.payload,
|
|
30
|
+
payloadDigest: record.payloadDigest,
|
|
31
|
+
payloadMediaType: record.payloadMediaType,
|
|
32
|
+
payloadSchema: record.payloadSchema,
|
|
33
|
+
causation: record.causation,
|
|
34
|
+
externalIdempotencyKey: record.externalIdempotencyKey,
|
|
35
|
+
unknownOutcomePolicy: record.unknownOutcomePolicy,
|
|
36
|
+
enqueuedAt: record.enqueuedAt,
|
|
37
|
+
maxAttempts: record.maxAttempts,
|
|
38
|
+
visibilityTimeoutMs: record.visibilityTimeoutMs,
|
|
39
|
+
attemptTimeoutMs: record.attemptTimeoutMs,
|
|
40
|
+
generation: record.generation + 1,
|
|
41
|
+
attempt: record.attempt,
|
|
42
|
+
retryCount: record.retryCount,
|
|
43
|
+
firstClaimedAt: record.firstClaimedAt,
|
|
44
|
+
availableAt: record.availableAt
|
|
45
|
+
};
|
|
46
|
+
}
|
|
47
|
+
export function rescheduleOrDeadLetter(leased, options) {
|
|
48
|
+
if (leased.attempt >= leased.maxAttempts)
|
|
49
|
+
return {
|
|
50
|
+
...applicationDeliveryIdentityFields(leased),
|
|
51
|
+
state: "dead-lettered",
|
|
52
|
+
terminalAt: options.now,
|
|
53
|
+
failure: { ...options.failure, reason: "attempts-exhausted" }
|
|
54
|
+
};
|
|
55
|
+
const backoff = computeRetryBackoffMs(leased.attempt, options.retryBackoffMs, options.maxRetryBackoffMs);
|
|
56
|
+
return {
|
|
57
|
+
...applicationDeliveryIdentityFields(leased),
|
|
58
|
+
state: "retry-scheduled",
|
|
59
|
+
retryCount: leased.retryCount + 1,
|
|
60
|
+
availableAt: requireDerivedInstant(options.now + Math.max(backoff, options.retryAfterMs ?? 0), "availableAt"),
|
|
61
|
+
lastFailure: options.failure
|
|
62
|
+
};
|
|
63
|
+
}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The time-driven recovery transition for the application delivery outbox
|
|
3
|
+
* (WFT-85): what happens to a lease nobody renewed.
|
|
4
|
+
*
|
|
5
|
+
* The state the lease expired in decides everything. A `claimed` lease never
|
|
6
|
+
* called the transport, so the delivery is safe to reschedule (or dead-letter
|
|
7
|
+
* when its attempt budget is spent). An `attempting` or cancellation-requested
|
|
8
|
+
* lease may have sent, so its outcome is unknown and the delivery's own
|
|
9
|
+
* unknown-outcome policy decides — never a blind retry.
|
|
10
|
+
*
|
|
11
|
+
* @module core/outbox-transitions-recovery
|
|
12
|
+
*/
|
|
13
|
+
import { type OutboxTransition, type RetryPolicy } from './outbox-transition-helpers.ts';
|
|
14
|
+
import type { ApplicationDeliveryRecord, ApplicationDeliveryRetryScheduled, ApplicationDeliveryTerminalRecord } from './outbox-types.ts';
|
|
15
|
+
/**
|
|
16
|
+
* Whether a leased record's lease has lapsed: its visibility expired or its
|
|
17
|
+
* attempt deadline passed, whichever came first.
|
|
18
|
+
*/
|
|
19
|
+
export declare function isDeliveryLeaseExpired(record: ApplicationDeliveryRecord, now: number): boolean;
|
|
20
|
+
/**
|
|
21
|
+
* Recover a delivery whose lease lapsed.
|
|
22
|
+
*
|
|
23
|
+
* `cleanupPending: true` and `abandonedAttemptToken` are written whenever the
|
|
24
|
+
* lease is abandoned rather than settled by its holder, in every disposition:
|
|
25
|
+
* the outbox stopped waiting for that attempt, which is not a claim that the
|
|
26
|
+
* attempt stopped.
|
|
27
|
+
*/
|
|
28
|
+
export declare function recoverExpiredDelivery(record: ApplicationDeliveryRecord, options: {
|
|
29
|
+
readonly now: number;
|
|
30
|
+
} & RetryPolicy): OutboxTransition<ApplicationDeliveryRetryScheduled | ApplicationDeliveryTerminalRecord>;
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import {
|
|
2
|
+
nonTerminalDeliveryRecord,
|
|
3
|
+
rejectedTransition,
|
|
4
|
+
rescheduleOrDeadLetter,
|
|
5
|
+
succeededTransition
|
|
6
|
+
} from "./outbox-transition-helpers.js";
|
|
7
|
+
import { applyUnknownOutcomePolicy } from "./outbox-transitions.js";
|
|
8
|
+
export function isDeliveryLeaseExpired(record, now) {
|
|
9
|
+
if (record.state !== "claimed" && record.state !== "attempting" && record.state !== "cancellation-requested")
|
|
10
|
+
return !1;
|
|
11
|
+
return now >= record.visibilityExpiresAt || now >= record.attemptDeadlineAt;
|
|
12
|
+
}
|
|
13
|
+
export function recoverExpiredDelivery(record, options) {
|
|
14
|
+
const live = nonTerminalDeliveryRecord(record);
|
|
15
|
+
if (live === null)
|
|
16
|
+
return rejectedTransition("already-terminal");
|
|
17
|
+
if (live.state === "queued" || live.state === "retry-scheduled")
|
|
18
|
+
return rejectedTransition("not-leased");
|
|
19
|
+
if (!isDeliveryLeaseExpired(live, options.now))
|
|
20
|
+
return rejectedTransition("not-due");
|
|
21
|
+
if (live.state === "claimed") {
|
|
22
|
+
const next = rescheduleOrDeadLetter(live, {
|
|
23
|
+
...options,
|
|
24
|
+
failure: { reason: "retryable", message: "The attempt lease expired before the send began." }
|
|
25
|
+
});
|
|
26
|
+
if (next.state === "retry-scheduled")
|
|
27
|
+
return succeededTransition(next);
|
|
28
|
+
return succeededTransition({
|
|
29
|
+
...next,
|
|
30
|
+
cleanupPending: !0,
|
|
31
|
+
abandonedAttemptToken: live.attemptToken
|
|
32
|
+
});
|
|
33
|
+
}
|
|
34
|
+
return succeededTransition(applyUnknownOutcomePolicy(live, {
|
|
35
|
+
...options,
|
|
36
|
+
failure: {
|
|
37
|
+
reason: "unknown-outcome",
|
|
38
|
+
message: "The attempt lease expired after the send began; the transport result is unknown."
|
|
39
|
+
},
|
|
40
|
+
abandonedAttemptToken: live.attemptToken
|
|
41
|
+
}));
|
|
42
|
+
}
|
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Pure conditional-transition functions for the durable application delivery
|
|
3
|
+
* outbox (WFT-85) — one function per legal edge of the outbox state machine.
|
|
4
|
+
*
|
|
5
|
+
* These functions are storage-agnostic. They take the currently decoded
|
|
6
|
+
* {@link ApplicationDeliveryRecord} and proposed inputs and return either the
|
|
7
|
+
* next record to persist or a stable rejection reason. They never read or write
|
|
8
|
+
* storage and never see encoded bytes; the caller that commits a transition
|
|
9
|
+
* keeps the raw bytes it read as the compare-and-swap `expectedValue`.
|
|
10
|
+
*
|
|
11
|
+
* The legal edges are:
|
|
12
|
+
*
|
|
13
|
+
* ```text
|
|
14
|
+
* (none) --enqueue--> queued
|
|
15
|
+
* queued | retry-scheduled --claim(due)--> claimed
|
|
16
|
+
* claimed --begin--> attempting
|
|
17
|
+
* claimed | attempting | cancel-req --heartbeat--> (same state, visibility extended)
|
|
18
|
+
* attempting --settle(acknowledged)--> acknowledged
|
|
19
|
+
* attempting --settle(rejected)--> rejected
|
|
20
|
+
* attempting --settle(retryable)--> retry-scheduled | dead-lettered
|
|
21
|
+
* attempting --settle(unknown)--> unknown-outcome | dead-lettered | retry-scheduled
|
|
22
|
+
* cancellation-requested --settle(ack)--> acknowledged (the effect happened)
|
|
23
|
+
* cancellation-requested --settle(other)--> cancelled | unknown-outcome | dead-lettered
|
|
24
|
+
* queued | retry-scheduled | claimed --cancel--> cancelled
|
|
25
|
+
* attempting --cancel--> cancellation-requested
|
|
26
|
+
* claimed --expire--> retry-scheduled | dead-lettered (recovery)
|
|
27
|
+
* attempting | cancel-req --expire--> unknown-outcome | dead-lettered | retry-scheduled
|
|
28
|
+
* unknown-outcome | dead-lettered | rejected --retry--> queued (operator)
|
|
29
|
+
* unknown-outcome --deadLetter--> dead-lettered (operator)
|
|
30
|
+
* ```
|
|
31
|
+
*
|
|
32
|
+
* @module core/outbox-transitions
|
|
33
|
+
*/
|
|
34
|
+
import type { JSONValue } from './json.ts';
|
|
35
|
+
import { type OutboxTransition, type RetryPolicy } from './outbox-transition-helpers.ts';
|
|
36
|
+
import type { ApplicationDeliveryAttempting, ApplicationDeliveryCancelling, ApplicationDeliveryClaimed, ApplicationDeliveryLeasedRecord, ApplicationDeliveryQueued, ApplicationDeliveryRecord, ApplicationDeliveryRetryScheduled, ApplicationDeliveryTerminalRecord } from './outbox-types.ts';
|
|
37
|
+
import type { ValidatedDeliveryInput, ValidatedOutcome } from './outbox-validation.ts';
|
|
38
|
+
export { isTerminalDeliveryRecord, nonTerminalDeliveryRecord, } from './outbox-transition-helpers.ts';
|
|
39
|
+
export type { OutboxTransition, OutboxTransitionRejection } from './outbox-transition-helpers.ts';
|
|
40
|
+
/** Build the record for a freshly enqueued delivery. */
|
|
41
|
+
export declare function createEnqueuedDeliveryRecord(input: ValidatedDeliveryInput, context: {
|
|
42
|
+
readonly namespace: string;
|
|
43
|
+
readonly ownerId: string;
|
|
44
|
+
readonly deliveryId: string;
|
|
45
|
+
readonly sequence: number;
|
|
46
|
+
readonly now: number;
|
|
47
|
+
}): ApplicationDeliveryQueued;
|
|
48
|
+
/**
|
|
49
|
+
* Lease a waiting delivery to one attempt.
|
|
50
|
+
*
|
|
51
|
+
* The attempt deadline is fixed here, at `now + attemptTimeoutMs`, and nothing
|
|
52
|
+
* later moves it. Visibility starts at the lesser of the renewal window and
|
|
53
|
+
* that deadline.
|
|
54
|
+
*/
|
|
55
|
+
export declare function claimWaitingDelivery(record: ApplicationDeliveryRecord, options: {
|
|
56
|
+
readonly now: number;
|
|
57
|
+
readonly attemptToken: string;
|
|
58
|
+
}): OutboxTransition<ApplicationDeliveryClaimed>;
|
|
59
|
+
/**
|
|
60
|
+
* Durably mark that the current attempt is about to call the transport.
|
|
61
|
+
*
|
|
62
|
+
* This is the edge that makes recovery honest: a lease that expires in
|
|
63
|
+
* `claimed` provably sent nothing and is safe to retry, while one that expires
|
|
64
|
+
* in `attempting` may have, and follows the unknown-outcome policy.
|
|
65
|
+
*/
|
|
66
|
+
export declare function beginDeliveryAttempt(record: ApplicationDeliveryRecord, options: {
|
|
67
|
+
readonly attemptToken: string;
|
|
68
|
+
readonly now: number;
|
|
69
|
+
}): OutboxTransition<ApplicationDeliveryAttempting>;
|
|
70
|
+
/**
|
|
71
|
+
* Record liveness for the current attempt and extend its visibility, clamped
|
|
72
|
+
* to the fixed attempt deadline. `transportActivity` is evidence of transport
|
|
73
|
+
* progress — bytes written, a request id — and is never fencing.
|
|
74
|
+
*/
|
|
75
|
+
export declare function heartbeatDeliveryAttempt(record: ApplicationDeliveryRecord, options: {
|
|
76
|
+
readonly attemptToken: string;
|
|
77
|
+
readonly now: number;
|
|
78
|
+
readonly transportActivity?: JSONValue | undefined;
|
|
79
|
+
}): OutboxTransition<ApplicationDeliveryLeasedRecord>;
|
|
80
|
+
/**
|
|
81
|
+
* Apply the unknown-outcome policy to a leased delivery whose transport result
|
|
82
|
+
* is lost. Shared by settlement (adapter reported `unknown`) and recovery (the
|
|
83
|
+
* lease expired in `attempting`).
|
|
84
|
+
*
|
|
85
|
+
* A delivery whose cancellation was requested is never retried: `park` and
|
|
86
|
+
* `retry-with-idempotency` both park it, because a retry would send work the
|
|
87
|
+
* caller asked to stop. `abandonedAttemptToken` is set by recovery only.
|
|
88
|
+
*/
|
|
89
|
+
export declare function applyUnknownOutcomePolicy(leased: ApplicationDeliveryLeasedRecord, options: {
|
|
90
|
+
readonly now: number;
|
|
91
|
+
readonly failure: {
|
|
92
|
+
readonly reason: 'unknown-outcome';
|
|
93
|
+
readonly message?: string | undefined;
|
|
94
|
+
};
|
|
95
|
+
readonly abandonedAttemptToken?: string | undefined;
|
|
96
|
+
} & RetryPolicy): ApplicationDeliveryRetryScheduled | ApplicationDeliveryTerminalRecord;
|
|
97
|
+
/**
|
|
98
|
+
* Settle the current attempt on what the transport reported.
|
|
99
|
+
*
|
|
100
|
+
* Only an `attempting` (or cancellation-requested) delivery can settle: a
|
|
101
|
+
* `claimed` one never called the transport, so it has no outcome to record.
|
|
102
|
+
* An acknowledgement always wins, even after cancellation was requested — the
|
|
103
|
+
* effect happened and the receipt must say so. Any other outcome on a
|
|
104
|
+
* cancelling delivery honours the cancellation: `cancelled` when nothing was
|
|
105
|
+
* confirmed, the unknown-outcome policy when the result was lost.
|
|
106
|
+
*/
|
|
107
|
+
export declare function settleDeliveryAttempt(record: ApplicationDeliveryRecord, options: {
|
|
108
|
+
readonly attemptToken: string;
|
|
109
|
+
readonly now: number;
|
|
110
|
+
readonly outcome: ValidatedOutcome;
|
|
111
|
+
} & RetryPolicy): OutboxTransition<ApplicationDeliveryRetryScheduled | ApplicationDeliveryTerminalRecord>;
|
|
112
|
+
/**
|
|
113
|
+
* Record a durable cancellation request.
|
|
114
|
+
*
|
|
115
|
+
* A waiting or merely claimed delivery cancels at once: nothing has been sent.
|
|
116
|
+
* (The claimant's `attempting` commit then loses its compare-and-swap and it
|
|
117
|
+
* re-reads a terminal record.) An attempting delivery keeps its lease and moves
|
|
118
|
+
* to `cancellation-requested`, so only the current attempt can settle it.
|
|
119
|
+
* Requesting cancellation twice rejects with `not-leased` against a record
|
|
120
|
+
* already in `cancellation-requested`, which the caller reports as the same
|
|
121
|
+
* outcome.
|
|
122
|
+
*/
|
|
123
|
+
export declare function requestDeliveryCancellation(record: ApplicationDeliveryRecord, options: {
|
|
124
|
+
readonly now: number;
|
|
125
|
+
readonly reason?: string | undefined;
|
|
126
|
+
}): OutboxTransition<ApplicationDeliveryCancelling | ApplicationDeliveryTerminalRecord>;
|
|
127
|
+
/**
|
|
128
|
+
* Operator retry: return a parked, dead-lettered, or rejected delivery to the
|
|
129
|
+
* due index with at least one more attempt to spend.
|
|
130
|
+
*
|
|
131
|
+
* A budget the delivery never used up — a permanent rejection on its first
|
|
132
|
+
* attempt of five, say — is kept, so the reopened delivery may retry on its
|
|
133
|
+
* own up to `maxAttempts`; a spent budget is raised to `attempt + 1`, so the
|
|
134
|
+
* delivery can be claimed exactly once more, and a second operator retry
|
|
135
|
+
* grants one more again. The record's provenance (`attempt`, `retryCount`) is
|
|
136
|
+
* preserved.
|
|
137
|
+
*/
|
|
138
|
+
export declare function retryDeliveryByOperator(record: ApplicationDeliveryRecord, options: {
|
|
139
|
+
readonly now: number;
|
|
140
|
+
}): OutboxTransition<ApplicationDeliveryQueued>;
|
|
141
|
+
/** Operator dead-letter: close a parked `unknown-outcome` delivery for good. */
|
|
142
|
+
export declare function deadLetterDeliveryByOperator(record: ApplicationDeliveryRecord, options: {
|
|
143
|
+
readonly now: number;
|
|
144
|
+
readonly reason?: string | undefined;
|
|
145
|
+
}): OutboxTransition<ApplicationDeliveryTerminalRecord>;
|