@hotmeshio/hotmesh 0.21.1 → 0.22.1
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 +12 -129
- package/build/modules/utils.d.ts +2 -0
- package/build/modules/utils.js +9 -1
- package/build/package.json +8 -2
- package/build/services/activities/hook.d.ts +178 -58
- package/build/services/activities/hook.js +244 -58
- package/build/services/activities/trigger.js +5 -1
- package/build/services/durable/client.d.ts +273 -67
- package/build/services/durable/client.js +351 -126
- package/build/services/durable/index.d.ts +7 -3
- package/build/services/durable/index.js +6 -0
- package/build/services/durable/schemas/factory.js +40 -0
- package/build/services/durable/worker.js +5 -28
- package/build/services/durable/workflow/condition.d.ts +69 -37
- package/build/services/durable/workflow/condition.js +70 -39
- package/build/services/hotmesh/index.d.ts +31 -4
- package/build/services/hotmesh/index.js +31 -4
- package/build/services/store/index.d.ts +1 -1
- package/build/services/store/providers/postgres/kvsql.d.ts +1 -1
- package/build/services/store/providers/postgres/kvtables.js +83 -122
- package/build/services/store/providers/postgres/kvtypes/hash/basic.d.ts +1 -1
- package/build/services/store/providers/postgres/kvtypes/hash/basic.js +8 -8
- package/build/services/store/providers/postgres/kvtypes/hash/index.d.ts +1 -1
- package/build/services/store/providers/postgres/postgres.d.ts +51 -188
- package/build/services/store/providers/postgres/postgres.js +542 -285
- package/build/types/activity.d.ts +2 -0
- package/build/types/hmsh_escalations.d.ts +240 -0
- package/build/types/index.d.ts +1 -1
- package/build/types/provider.d.ts +2 -0
- package/package.json +9 -2
- package/build/types/signal.d.ts +0 -147
- /package/build/types/{signal.js → hmsh_escalations.js} +0 -0
|
@@ -14,6 +14,8 @@ interface BaseActivity {
|
|
|
14
14
|
settings?: Record<string, any>;
|
|
15
15
|
job?: Record<string, any>;
|
|
16
16
|
hook?: Record<string, any>;
|
|
17
|
+
/** When present on a hook activity, writes a row to public.hmsh_escalations at suspension time. Values may use `@pipe` expressions resolved against the current job context. */
|
|
18
|
+
escalation?: Record<string, any>;
|
|
17
19
|
telemetry?: Record<string, any>;
|
|
18
20
|
emit?: boolean;
|
|
19
21
|
sleep?: number;
|
|
@@ -0,0 +1,240 @@
|
|
|
1
|
+
export interface ConditionQueueConfig {
|
|
2
|
+
role?: string;
|
|
3
|
+
type?: string;
|
|
4
|
+
subtype?: string;
|
|
5
|
+
entity?: string;
|
|
6
|
+
priority?: number;
|
|
7
|
+
description?: string;
|
|
8
|
+
taskQueue?: string;
|
|
9
|
+
workflowType?: string;
|
|
10
|
+
originId?: string;
|
|
11
|
+
parentId?: string;
|
|
12
|
+
initiatedBy?: string;
|
|
13
|
+
traceId?: string;
|
|
14
|
+
spanId?: string;
|
|
15
|
+
/** GIN-indexed; put claim/filter keys here */
|
|
16
|
+
metadata?: Record<string, unknown>;
|
|
17
|
+
/** Unindexed display/form context for resolver UIs */
|
|
18
|
+
envelope?: Record<string, unknown>;
|
|
19
|
+
expiresAt?: Date;
|
|
20
|
+
}
|
|
21
|
+
export interface EscalationEntry {
|
|
22
|
+
id: string;
|
|
23
|
+
namespace: string;
|
|
24
|
+
app_id: string;
|
|
25
|
+
/** Job ID / Durable signalId; NULL for standalone (no-signal) escalations */
|
|
26
|
+
signal_key: string | null;
|
|
27
|
+
/** Hook topic for signal delivery */
|
|
28
|
+
topic: string | null;
|
|
29
|
+
workflow_id: string | null;
|
|
30
|
+
task_queue: string | null;
|
|
31
|
+
workflow_type: string | null;
|
|
32
|
+
type: string | null;
|
|
33
|
+
subtype: string | null;
|
|
34
|
+
entity: string | null;
|
|
35
|
+
description: string | null;
|
|
36
|
+
role: string | null;
|
|
37
|
+
status: 'pending' | 'claimed' | 'resolved' | 'cancelled' | 'expired';
|
|
38
|
+
priority: number;
|
|
39
|
+
assigned_to: string | null;
|
|
40
|
+
assigned_until: Date | null;
|
|
41
|
+
claimed_at: Date | null;
|
|
42
|
+
claim_expires_at: Date | null;
|
|
43
|
+
resolved_at: Date | null;
|
|
44
|
+
escalation_payload: Record<string, unknown> | null;
|
|
45
|
+
resolver_payload: Record<string, unknown> | null;
|
|
46
|
+
envelope: Record<string, unknown> | null;
|
|
47
|
+
metadata: Record<string, unknown> | null;
|
|
48
|
+
origin_id: string | null;
|
|
49
|
+
parent_id: string | null;
|
|
50
|
+
initiated_by: string | null;
|
|
51
|
+
created_by: string | null;
|
|
52
|
+
milestones: unknown[];
|
|
53
|
+
trace_id: string | null;
|
|
54
|
+
span_id: string | null;
|
|
55
|
+
expires_at: Date | null;
|
|
56
|
+
created_at: Date;
|
|
57
|
+
updated_at: Date;
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* Result of `claim()` — identifies whether failure was due to the row not
|
|
61
|
+
* existing (`not-found`) or existing but locked / in a non-claimable state
|
|
62
|
+
* (`conflict`). Distinguishing these lets callers decide whether to retry or
|
|
63
|
+
* surface an error to the user.
|
|
64
|
+
*/
|
|
65
|
+
export type ClaimEscalationResult = {
|
|
66
|
+
ok: true;
|
|
67
|
+
entry: EscalationEntry;
|
|
68
|
+
} | {
|
|
69
|
+
ok: false;
|
|
70
|
+
reason: 'not-found' | 'conflict';
|
|
71
|
+
};
|
|
72
|
+
/**
|
|
73
|
+
* Result of `claimByMetadata()`. Includes `candidatesExist` — the total
|
|
74
|
+
* count of rows matching the metadata filter regardless of claimability — so
|
|
75
|
+
* callers can distinguish "nothing matching at all" from "found candidates but
|
|
76
|
+
* all are locked or in-progress".
|
|
77
|
+
*/
|
|
78
|
+
export type ClaimByMetadataResult = {
|
|
79
|
+
ok: true;
|
|
80
|
+
entry: EscalationEntry;
|
|
81
|
+
candidatesExist: number;
|
|
82
|
+
} | {
|
|
83
|
+
ok: false;
|
|
84
|
+
reason: 'not-found' | 'conflict';
|
|
85
|
+
candidatesExist: number;
|
|
86
|
+
};
|
|
87
|
+
export type ResolveEscalationResult = {
|
|
88
|
+
ok: true;
|
|
89
|
+
} | {
|
|
90
|
+
ok: false;
|
|
91
|
+
reason: 'not-found' | 'already-resolved' | 'already-cancelled' | 'signal-failed';
|
|
92
|
+
};
|
|
93
|
+
export type ReleaseEscalationResult = {
|
|
94
|
+
ok: true;
|
|
95
|
+
} | {
|
|
96
|
+
ok: false;
|
|
97
|
+
reason: 'not-found' | 'wrong-assignee';
|
|
98
|
+
};
|
|
99
|
+
export type CancelEscalationResult = {
|
|
100
|
+
ok: true;
|
|
101
|
+
} | {
|
|
102
|
+
ok: false;
|
|
103
|
+
reason: 'not-found' | 'already-terminal';
|
|
104
|
+
};
|
|
105
|
+
export interface ListEscalationsParams {
|
|
106
|
+
namespace?: string;
|
|
107
|
+
role?: string;
|
|
108
|
+
type?: string;
|
|
109
|
+
subtype?: string;
|
|
110
|
+
entity?: string;
|
|
111
|
+
status?: string;
|
|
112
|
+
assignedTo?: string;
|
|
113
|
+
workflowId?: string;
|
|
114
|
+
originId?: string;
|
|
115
|
+
limit?: number;
|
|
116
|
+
offset?: number;
|
|
117
|
+
}
|
|
118
|
+
export interface CreateEscalationParams {
|
|
119
|
+
namespace?: string;
|
|
120
|
+
appId?: string;
|
|
121
|
+
signalKey?: string;
|
|
122
|
+
topic?: string;
|
|
123
|
+
workflowId?: string;
|
|
124
|
+
taskQueue?: string;
|
|
125
|
+
workflowType?: string;
|
|
126
|
+
type?: string;
|
|
127
|
+
subtype?: string;
|
|
128
|
+
entity?: string;
|
|
129
|
+
description?: string;
|
|
130
|
+
role?: string;
|
|
131
|
+
priority?: number;
|
|
132
|
+
originId?: string;
|
|
133
|
+
parentId?: string;
|
|
134
|
+
initiatedBy?: string;
|
|
135
|
+
createdBy?: string;
|
|
136
|
+
traceId?: string;
|
|
137
|
+
spanId?: string;
|
|
138
|
+
escalationPayload?: Record<string, unknown>;
|
|
139
|
+
metadata?: Record<string, unknown>;
|
|
140
|
+
envelope?: Record<string, unknown>;
|
|
141
|
+
expiresAt?: Date;
|
|
142
|
+
}
|
|
143
|
+
/**
|
|
144
|
+
* Fields that can be patched on an existing escalation. All fields are
|
|
145
|
+
* optional — only provided fields are written. Signal routing fields
|
|
146
|
+
* (`signalKey`, `topic`, `workflowId`, `taskQueue`, `workflowType`) support
|
|
147
|
+
* the legacy two-step pattern where routing context is enriched after creation.
|
|
148
|
+
*/
|
|
149
|
+
export interface UpdateEscalationParams {
|
|
150
|
+
id: string;
|
|
151
|
+
namespace?: string;
|
|
152
|
+
description?: string;
|
|
153
|
+
priority?: number;
|
|
154
|
+
role?: string;
|
|
155
|
+
/** Merged into existing metadata (keys overwritten, others preserved) */
|
|
156
|
+
metadata?: Record<string, unknown>;
|
|
157
|
+
/** Replaces existing envelope */
|
|
158
|
+
envelope?: Record<string, unknown>;
|
|
159
|
+
/** Signal routing enrichment — equivalent to long-tail's enrichEscalationRouting */
|
|
160
|
+
signalKey?: string;
|
|
161
|
+
topic?: string;
|
|
162
|
+
workflowId?: string;
|
|
163
|
+
taskQueue?: string;
|
|
164
|
+
workflowType?: string;
|
|
165
|
+
expiresAt?: Date;
|
|
166
|
+
}
|
|
167
|
+
export interface AppendMilestonesParams {
|
|
168
|
+
id: string;
|
|
169
|
+
namespace?: string;
|
|
170
|
+
milestones: Array<{
|
|
171
|
+
name: string;
|
|
172
|
+
value: unknown;
|
|
173
|
+
[key: string]: unknown;
|
|
174
|
+
}>;
|
|
175
|
+
}
|
|
176
|
+
export interface ClaimEscalationParams {
|
|
177
|
+
id: string;
|
|
178
|
+
namespace?: string;
|
|
179
|
+
assignee?: string;
|
|
180
|
+
durationMinutes?: number;
|
|
181
|
+
}
|
|
182
|
+
export interface ClaimByMetadataParams {
|
|
183
|
+
key: string;
|
|
184
|
+
value: unknown;
|
|
185
|
+
namespace?: string;
|
|
186
|
+
assignee?: string;
|
|
187
|
+
durationMinutes?: number;
|
|
188
|
+
roles?: string[];
|
|
189
|
+
}
|
|
190
|
+
export interface ReleaseEscalationParams {
|
|
191
|
+
id: string;
|
|
192
|
+
namespace?: string;
|
|
193
|
+
/** When provided, the release is rejected with `wrong-assignee` if the current assignee differs */
|
|
194
|
+
assignee?: string;
|
|
195
|
+
}
|
|
196
|
+
export interface ResolveEscalationParams {
|
|
197
|
+
id: string;
|
|
198
|
+
namespace?: string;
|
|
199
|
+
resolverPayload?: Record<string, unknown>;
|
|
200
|
+
}
|
|
201
|
+
export interface ResolveByMetadataParams {
|
|
202
|
+
key: string;
|
|
203
|
+
value: unknown;
|
|
204
|
+
namespace?: string;
|
|
205
|
+
resolverPayload?: Record<string, unknown>;
|
|
206
|
+
roles?: string[];
|
|
207
|
+
}
|
|
208
|
+
export interface EscalateToRoleParams {
|
|
209
|
+
id: string;
|
|
210
|
+
targetRole: string;
|
|
211
|
+
namespace?: string;
|
|
212
|
+
}
|
|
213
|
+
/**
|
|
214
|
+
* Full-fidelity migration params. Extends `CreateEscalationParams` with:
|
|
215
|
+
* - `id` (required) — preserves the original UUID; no auto-generation
|
|
216
|
+
* - lifecycle state fields (`status`, `assignedTo`, `claimExpiresAt`, …) — carry over
|
|
217
|
+
* the exact state of the migrated row so in-flight escalations land correctly
|
|
218
|
+
* - `createdAt` / `updatedAt` — preserve original timestamps
|
|
219
|
+
*
|
|
220
|
+
* The underlying INSERT uses `ON CONFLICT (id) DO NOTHING`, so calling
|
|
221
|
+
* `migrate()` multiple times with the same ID is safe — subsequent calls
|
|
222
|
+
* return `null` without touching the existing row.
|
|
223
|
+
*/
|
|
224
|
+
export interface MigrateEscalationParams extends CreateEscalationParams {
|
|
225
|
+
/** Required — preserve the original UUID from the source table. */
|
|
226
|
+
id: string;
|
|
227
|
+
status?: 'pending' | 'claimed' | 'resolved' | 'cancelled' | 'expired';
|
|
228
|
+
assignedTo?: string;
|
|
229
|
+
claimExpiresAt?: Date;
|
|
230
|
+
claimedAt?: Date;
|
|
231
|
+
resolvedAt?: Date;
|
|
232
|
+
resolverPayload?: Record<string, unknown>;
|
|
233
|
+
milestones?: Array<{
|
|
234
|
+
name: string;
|
|
235
|
+
value: unknown;
|
|
236
|
+
[key: string]: unknown;
|
|
237
|
+
}>;
|
|
238
|
+
createdAt?: Date;
|
|
239
|
+
updatedAt?: Date;
|
|
240
|
+
}
|
package/build/types/index.d.ts
CHANGED
|
@@ -25,4 +25,4 @@ export { ReclaimedMessageType, RetryPolicy, RouterConfig, StreamCode, StreamConf
|
|
|
25
25
|
export { context, Context, Counter, Meter, metrics, propagation, SpanContext, Span, SpanStatus, SpanStatusCode, SpanKind, trace, Tracer, ValueType, } from './telemetry';
|
|
26
26
|
export { WorkListTaskType } from './task';
|
|
27
27
|
export { TransitionMatch, TransitionRule, Transitions } from './transition';
|
|
28
|
-
export {
|
|
28
|
+
export { ConditionQueueConfig, EscalationEntry, ClaimEscalationResult, ClaimByMetadataResult, ReleaseEscalationResult, ResolveEscalationResult, CancelEscalationResult, ListEscalationsParams, CreateEscalationParams, UpdateEscalationParams, AppendMilestonesParams, ClaimEscalationParams, ClaimByMetadataParams, ReleaseEscalationParams, ResolveEscalationParams, ResolveByMetadataParams, EscalateToRoleParams, MigrateEscalationParams, } from './hmsh_escalations';
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@hotmeshio/hotmesh",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.22.1",
|
|
4
4
|
"description": "Durable Workflow",
|
|
5
5
|
"main": "./build/index.js",
|
|
6
6
|
"types": "./build/index.d.ts",
|
|
@@ -50,6 +50,7 @@
|
|
|
50
50
|
"test:durable:signal": "vitest run tests/durable/signal/postgres.test.ts",
|
|
51
51
|
"test:durable:readonly": "docker compose --profile readonly up -d --build && docker compose exec hotmesh-readonly npx vitest run --config tests/durable/readonly/vitest.config.mts",
|
|
52
52
|
"test:durable:unknown": "vitest run tests/durable/unknown/postgres.test.ts",
|
|
53
|
+
"test:durable:escalations": "HMSH_LOGLEVEL=info vitest run tests/durable/escalations",
|
|
53
54
|
"test:durable:exporter": "HMSH_LOGLEVEL=info vitest run tests/durable/exporter",
|
|
54
55
|
"test:durable:exporter:debug": "EXPORT_DEBUG=1 HMSH_LOGLEVEL=error vitest run tests/durable/basic/postgres.test.ts",
|
|
55
56
|
"test:durable:codec": "vitest run tests/durable/codec/postgres.test.ts",
|
|
@@ -84,7 +85,13 @@
|
|
|
84
85
|
"test:sub:nats": "vitest run tests/functional/sub/providers/nats/nats.test.ts",
|
|
85
86
|
"test:trigger": "vitest run tests/unit/services/activities/trigger.test.ts",
|
|
86
87
|
"test:virtual": "vitest run tests/virtual",
|
|
87
|
-
"test:unit": "vitest run tests/unit"
|
|
88
|
+
"test:unit": "vitest run tests/unit",
|
|
89
|
+
|
|
90
|
+
"prove": "docker compose exec hotmesh npx vitest run tests/durable 2>&1 | tee /tmp/hmsh-durable.txt && grep -E 'FAIL|Tests |Files ' /tmp/hmsh-durable.txt | tail -5",
|
|
91
|
+
"prove:escalations": "docker compose exec hotmesh npx vitest run tests/durable/escalations/postgres.test.ts 2>&1 | tee /tmp/hmsh-escalations.txt && grep -E 'FAIL|Tests |Files ' /tmp/hmsh-escalations.txt | tail -5",
|
|
92
|
+
"prove:functional": "docker compose exec hotmesh npx vitest run tests/functional 2>&1 | tee /tmp/hmsh-functional.txt && grep -E 'FAIL|Tests |Files ' /tmp/hmsh-functional.txt | tail -5",
|
|
93
|
+
"prove:all": "docker compose exec hotmesh npx vitest run tests/ 2>&1 | tee /tmp/hmsh-all.txt && grep -E 'FAIL|Tests |Files ' /tmp/hmsh-all.txt | tail -5",
|
|
94
|
+
"prove:file": "f() { docker compose exec hotmesh npx vitest run \"$@\" 2>&1 | tee /tmp/hmsh-file.txt && grep -E 'FAIL|Tests |Files ' /tmp/hmsh-file.txt | tail -5; }; f"
|
|
88
95
|
},
|
|
89
96
|
"keywords": [
|
|
90
97
|
"Invisible Infrastructure",
|
package/build/types/signal.d.ts
DELETED
|
@@ -1,147 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Represents a queued signal record in the hotmesh_signals table.
|
|
3
|
-
* Created atomically with workflow suspension when condition() is called
|
|
4
|
-
* with a queue configuration.
|
|
5
|
-
*/
|
|
6
|
-
export interface SignalQueueEntry {
|
|
7
|
-
id: string;
|
|
8
|
-
namespace: string;
|
|
9
|
-
appId: string;
|
|
10
|
-
signalKey: string;
|
|
11
|
-
workflowId: string;
|
|
12
|
-
jobId?: string;
|
|
13
|
-
topic?: string;
|
|
14
|
-
status: 'pending' | 'claimed' | 'resolved' | 'expired' | 'released';
|
|
15
|
-
role?: string;
|
|
16
|
-
type?: string;
|
|
17
|
-
subtype?: string;
|
|
18
|
-
priority: number;
|
|
19
|
-
description?: string;
|
|
20
|
-
taskQueue?: string;
|
|
21
|
-
workflowType?: string;
|
|
22
|
-
assignedTo?: string;
|
|
23
|
-
claimedAt?: Date;
|
|
24
|
-
claimExpiresAt?: Date;
|
|
25
|
-
resolvedAt?: Date;
|
|
26
|
-
resolverPayload?: Record<string, unknown>;
|
|
27
|
-
envelope?: Record<string, unknown>;
|
|
28
|
-
metadata?: Record<string, unknown>;
|
|
29
|
-
expiresAt?: Date;
|
|
30
|
-
createdAt: Date;
|
|
31
|
-
updatedAt: Date;
|
|
32
|
-
}
|
|
33
|
-
/**
|
|
34
|
-
* Optional queue configuration passed to condition() to create a
|
|
35
|
-
* richly-typed, indexed, claimable signal record alongside workflow suspension.
|
|
36
|
-
*
|
|
37
|
-
* metadata is GIN-indexed and used for claimByMetadata / resolveByMetadata queries.
|
|
38
|
-
* envelope is unindexed and intended for display context (form schemas, etc.).
|
|
39
|
-
*/
|
|
40
|
-
export interface ConditionQueueConfig {
|
|
41
|
-
role?: string;
|
|
42
|
-
type?: string;
|
|
43
|
-
subtype?: string;
|
|
44
|
-
priority?: number;
|
|
45
|
-
description?: string;
|
|
46
|
-
taskQueue?: string;
|
|
47
|
-
workflowType?: string;
|
|
48
|
-
assignedTo?: string;
|
|
49
|
-
metadata?: Record<string, unknown>;
|
|
50
|
-
envelope?: Record<string, unknown>;
|
|
51
|
-
durationMinutes?: number;
|
|
52
|
-
}
|
|
53
|
-
export interface EnqueueSignalParams {
|
|
54
|
-
namespace: string;
|
|
55
|
-
appId: string;
|
|
56
|
-
signalKey: string;
|
|
57
|
-
workflowId: string;
|
|
58
|
-
jobId?: string;
|
|
59
|
-
topic?: string;
|
|
60
|
-
role?: string;
|
|
61
|
-
type?: string;
|
|
62
|
-
subtype?: string;
|
|
63
|
-
priority?: number;
|
|
64
|
-
description?: string;
|
|
65
|
-
taskQueue?: string;
|
|
66
|
-
workflowType?: string;
|
|
67
|
-
assignedTo?: string;
|
|
68
|
-
metadata?: Record<string, unknown>;
|
|
69
|
-
envelope?: Record<string, unknown>;
|
|
70
|
-
expiresAt?: Date;
|
|
71
|
-
}
|
|
72
|
-
export interface ClaimSignalParams {
|
|
73
|
-
id: string;
|
|
74
|
-
assignee?: string;
|
|
75
|
-
durationMinutes?: number;
|
|
76
|
-
}
|
|
77
|
-
export interface ClaimSignalByMetadataParams {
|
|
78
|
-
key: string;
|
|
79
|
-
value: unknown;
|
|
80
|
-
assignee?: string;
|
|
81
|
-
durationMinutes?: number;
|
|
82
|
-
}
|
|
83
|
-
export interface ResolveSignalParams {
|
|
84
|
-
id: string;
|
|
85
|
-
resolverPayload?: Record<string, unknown>;
|
|
86
|
-
}
|
|
87
|
-
export interface ResolveSignalByMetadataParams {
|
|
88
|
-
key: string;
|
|
89
|
-
value: unknown;
|
|
90
|
-
resolverPayload?: Record<string, unknown>;
|
|
91
|
-
}
|
|
92
|
-
export interface ListSignalsParams {
|
|
93
|
-
status?: 'pending' | 'claimed' | 'resolved' | 'expired' | 'released';
|
|
94
|
-
role?: string;
|
|
95
|
-
taskQueue?: string;
|
|
96
|
-
limit?: number;
|
|
97
|
-
offset?: number;
|
|
98
|
-
}
|
|
99
|
-
/**
|
|
100
|
-
* Result of a claim operation (by ID or by metadata).
|
|
101
|
-
*
|
|
102
|
-
* - ok: true → signal was claimed; entry contains the full record
|
|
103
|
-
* - ok: false, reason: 'not-found' → no signal exists for the given id/metadata
|
|
104
|
-
* - ok: false, reason: 'conflict' → signal exists but was already claimed concurrently
|
|
105
|
-
*/
|
|
106
|
-
export type ClaimSignalResult = {
|
|
107
|
-
ok: true;
|
|
108
|
-
entry: SignalQueueEntry;
|
|
109
|
-
} | {
|
|
110
|
-
ok: false;
|
|
111
|
-
reason: 'not-found' | 'conflict';
|
|
112
|
-
};
|
|
113
|
-
/**
|
|
114
|
-
* Result of a resolve operation (by ID or by metadata).
|
|
115
|
-
*
|
|
116
|
-
* - ok: true → signal marked resolved and workflow signal delivered
|
|
117
|
-
* - ok: false, reason: 'not-found' → no pending/claimed signal found
|
|
118
|
-
* - ok: false, reason: 'already-resolved' → signal exists but was already resolved (id-based only)
|
|
119
|
-
* - ok: false, reason: 'signal-failed' → DB record updated but workflow signal delivery failed;
|
|
120
|
-
* signalKey is provided so callers can retry delivery
|
|
121
|
-
*/
|
|
122
|
-
export type ResolveSignalResult = {
|
|
123
|
-
ok: true;
|
|
124
|
-
} | {
|
|
125
|
-
ok: false;
|
|
126
|
-
reason: 'not-found';
|
|
127
|
-
} | {
|
|
128
|
-
ok: false;
|
|
129
|
-
reason: 'already-resolved';
|
|
130
|
-
} | {
|
|
131
|
-
ok: false;
|
|
132
|
-
reason: 'signal-failed';
|
|
133
|
-
signalKey: string;
|
|
134
|
-
};
|
|
135
|
-
/**
|
|
136
|
-
* Result of a release operation.
|
|
137
|
-
*
|
|
138
|
-
* - ok: true → signal returned to pending
|
|
139
|
-
* - ok: false, reason: 'not-found' → no signal exists for this id
|
|
140
|
-
* - ok: false, reason: 'wrong-status' → signal exists but is not in 'claimed' status
|
|
141
|
-
*/
|
|
142
|
-
export type ReleaseSignalResult = {
|
|
143
|
-
ok: true;
|
|
144
|
-
} | {
|
|
145
|
-
ok: false;
|
|
146
|
-
reason: 'not-found' | 'wrong-status';
|
|
147
|
-
};
|
|
File without changes
|