@shardlink/agent-sdk 0.1.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/LICENSE +202 -0
- package/README.md +129 -0
- package/dist/client-quick-join.d.ts +38 -0
- package/dist/client-quick-join.d.ts.map +1 -0
- package/dist/client-quick-join.js +141 -0
- package/dist/client-quick-join.js.map +1 -0
- package/dist/client.d.ts +134 -0
- package/dist/client.d.ts.map +1 -0
- package/dist/client.js +190 -0
- package/dist/client.js.map +1 -0
- package/dist/errors.d.ts +126 -0
- package/dist/errors.d.ts.map +1 -0
- package/dist/errors.js +330 -0
- package/dist/errors.js.map +1 -0
- package/dist/index.d.ts +47 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +47 -0
- package/dist/index.js.map +1 -0
- package/dist/modules/a2a.d.ts +42 -0
- package/dist/modules/a2a.d.ts.map +1 -0
- package/dist/modules/a2a.js +47 -0
- package/dist/modules/a2a.js.map +1 -0
- package/dist/modules/agents.d.ts +100 -0
- package/dist/modules/agents.d.ts.map +1 -0
- package/dist/modules/agents.js +85 -0
- package/dist/modules/agents.js.map +1 -0
- package/dist/modules/auth.d.ts +49 -0
- package/dist/modules/auth.d.ts.map +1 -0
- package/dist/modules/auth.js +69 -0
- package/dist/modules/auth.js.map +1 -0
- package/dist/modules/billing.d.ts +254 -0
- package/dist/modules/billing.d.ts.map +1 -0
- package/dist/modules/billing.js +203 -0
- package/dist/modules/billing.js.map +1 -0
- package/dist/modules/clans.d.ts +73 -0
- package/dist/modules/clans.d.ts.map +1 -0
- package/dist/modules/clans.js +94 -0
- package/dist/modules/clans.js.map +1 -0
- package/dist/modules/compliance.d.ts +97 -0
- package/dist/modules/compliance.d.ts.map +1 -0
- package/dist/modules/compliance.js +227 -0
- package/dist/modules/compliance.js.map +1 -0
- package/dist/modules/cross-plane.d.ts +164 -0
- package/dist/modules/cross-plane.d.ts.map +1 -0
- package/dist/modules/cross-plane.js +195 -0
- package/dist/modules/cross-plane.js.map +1 -0
- package/dist/modules/dashboard.d.ts +130 -0
- package/dist/modules/dashboard.d.ts.map +1 -0
- package/dist/modules/dashboard.js +120 -0
- package/dist/modules/dashboard.js.map +1 -0
- package/dist/modules/degradation.d.ts +120 -0
- package/dist/modules/degradation.d.ts.map +1 -0
- package/dist/modules/degradation.js +205 -0
- package/dist/modules/degradation.js.map +1 -0
- package/dist/modules/diagnostics-checks.d.ts +32 -0
- package/dist/modules/diagnostics-checks.d.ts.map +1 -0
- package/dist/modules/diagnostics-checks.js +231 -0
- package/dist/modules/diagnostics-checks.js.map +1 -0
- package/dist/modules/diagnostics-types.d.ts +118 -0
- package/dist/modules/diagnostics-types.d.ts.map +1 -0
- package/dist/modules/diagnostics-types.js +16 -0
- package/dist/modules/diagnostics-types.js.map +1 -0
- package/dist/modules/diagnostics.d.ts +64 -0
- package/dist/modules/diagnostics.d.ts.map +1 -0
- package/dist/modules/diagnostics.js +206 -0
- package/dist/modules/diagnostics.js.map +1 -0
- package/dist/modules/discovery.d.ts +152 -0
- package/dist/modules/discovery.d.ts.map +1 -0
- package/dist/modules/discovery.js +100 -0
- package/dist/modules/discovery.js.map +1 -0
- package/dist/modules/fleets.d.ts +82 -0
- package/dist/modules/fleets.d.ts.map +1 -0
- package/dist/modules/fleets.js +33 -0
- package/dist/modules/fleets.js.map +1 -0
- package/dist/modules/lease-manager.d.ts +119 -0
- package/dist/modules/lease-manager.d.ts.map +1 -0
- package/dist/modules/lease-manager.js +242 -0
- package/dist/modules/lease-manager.js.map +1 -0
- package/dist/modules/leases.d.ts +70 -0
- package/dist/modules/leases.d.ts.map +1 -0
- package/dist/modules/leases.js +51 -0
- package/dist/modules/leases.js.map +1 -0
- package/dist/modules/operators.d.ts +176 -0
- package/dist/modules/operators.d.ts.map +1 -0
- package/dist/modules/operators.js +133 -0
- package/dist/modules/operators.js.map +1 -0
- package/dist/modules/providers.d.ts +141 -0
- package/dist/modules/providers.d.ts.map +1 -0
- package/dist/modules/providers.js +118 -0
- package/dist/modules/providers.js.map +1 -0
- package/dist/modules/quota.d.ts +102 -0
- package/dist/modules/quota.d.ts.map +1 -0
- package/dist/modules/quota.js +135 -0
- package/dist/modules/quota.js.map +1 -0
- package/dist/modules/reactions.d.ts +141 -0
- package/dist/modules/reactions.d.ts.map +1 -0
- package/dist/modules/reactions.js +122 -0
- package/dist/modules/reactions.js.map +1 -0
- package/dist/modules/register.d.ts +159 -0
- package/dist/modules/register.d.ts.map +1 -0
- package/dist/modules/register.js +239 -0
- package/dist/modules/register.js.map +1 -0
- package/dist/modules/sandbox.d.ts +106 -0
- package/dist/modules/sandbox.d.ts.map +1 -0
- package/dist/modules/sandbox.js +224 -0
- package/dist/modules/sandbox.js.map +1 -0
- package/dist/modules/streams.d.ts +81 -0
- package/dist/modules/streams.d.ts.map +1 -0
- package/dist/modules/streams.js +292 -0
- package/dist/modules/streams.js.map +1 -0
- package/dist/modules/tasks.d.ts +145 -0
- package/dist/modules/tasks.d.ts.map +1 -0
- package/dist/modules/tasks.js +165 -0
- package/dist/modules/tasks.js.map +1 -0
- package/dist/modules/telemetry.d.ts +137 -0
- package/dist/modules/telemetry.d.ts.map +1 -0
- package/dist/modules/telemetry.js +203 -0
- package/dist/modules/telemetry.js.map +1 -0
- package/dist/modules/workspace.d.ts +180 -0
- package/dist/modules/workspace.d.ts.map +1 -0
- package/dist/modules/workspace.js +157 -0
- package/dist/modules/workspace.js.map +1 -0
- package/dist/quickstart-join.d.ts +56 -0
- package/dist/quickstart-join.d.ts.map +1 -0
- package/dist/quickstart-join.js +116 -0
- package/dist/quickstart-join.js.map +1 -0
- package/dist/quickstart.d.ts +137 -0
- package/dist/quickstart.d.ts.map +1 -0
- package/dist/quickstart.js +292 -0
- package/dist/quickstart.js.map +1 -0
- package/dist/retry.d.ts +88 -0
- package/dist/retry.d.ts.map +1 -0
- package/dist/retry.js +152 -0
- package/dist/retry.js.map +1 -0
- package/dist/types.d.ts +447 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +10 -0
- package/dist/types.js.map +1 -0
- package/dist/utils.d.ts +88 -0
- package/dist/utils.d.ts.map +1 -0
- package/dist/utils.js +199 -0
- package/dist/utils.js.map +1 -0
- package/package.json +215 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"quickstart.d.ts","sourceRoot":"","sources":["../src/quickstart.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAEH,OAAO,EAAE,cAAc,EAA8B,MAAM,aAAa,CAAC;AACzE,OAAO,EAAc,KAAK,YAAY,EAAE,MAAM,sBAAsB,CAAC;AAErE,OAAO,KAAK,EAAE,wBAAwB,EAAE,iBAAiB,EAAE,MAAM,uBAAuB,CAAC;AACzF,OAAO,KAAK,EAAE,cAAc,EAAE,eAAe,EAAE,WAAW,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAC;AACnG,OAAO,KAAK,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAEpE,6CAA6C;AAC7C,MAAM,WAAW,gBAAgB;IAC/B,8BAA8B;IAC9B,OAAO,EAAE,MAAM,CAAC;IAChB;;;;OAIG;IACH,QAAQ,CAAC,EAAE,MAAM,OAAO,CAAC,MAAM,CAAC,GAAG,MAAM,CAAC;IAC1C;;;OAGG;IACH,MAAM,CAAC,EAAE,IAAI,CAAC,iBAAiB,EAAE,SAAS,CAAC,GAAG;QAAE,OAAO,CAAC,EAAE,iBAAiB,CAAC,SAAS,CAAC,CAAA;KAAE,CAAC;IACzF,8CAA8C;IAC9C,SAAS,CAAC,EAAE,OAAO,KAAK,CAAC;IACzB,mFAAmF;IACnF,IAAI,CAAC,EAAE,cAAc,CAAC;IACtB;;;;OAIG;IACH,QAAQ,CAAC,EAAE,wBAAwB,CAAC;IACpC;;;;OAIG;IACH,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,2DAA2D;IAC3D,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,oDAAoD;IACpD,mBAAmB,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IAC9C;;;;;;;;;;;;;;;;OAgBG;IACH,WAAW,CAAC,EAAE;QACZ,UAAU,EAAE,MAAM,CAAC;QACnB,mFAAmF;QACnF,IAAI,CAAC,EAAE,CAAC,KAAK,EAAE;YACb,MAAM,EAAE,cAAc,CAAC;YACvB,aAAa,EAAE,MAAM,CAAC;YACtB,iBAAiB,EAAE,MAAM,CAAC;SAC3B,KAAK,OAAO,CAAC,KAAK,CAAC;YAAE,EAAE,EAAE,MAAM,CAAC;YAAC,CAAC,CAAC,EAAE,MAAM,GAAG,OAAO,CAAA;SAAE,CAAC,CAAC,CAAC;KAC5D,CAAC;CACH;AAED,2DAA2D;AAC3D,MAAM,WAAW,YAAY;IAC3B,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,iBAAiB,EAAE,MAAM,CAAC;IACnC,QAAQ,CAAC,IAAI,EAAE,eAAe,CAAC;IAC/B,QAAQ,CAAC,MAAM,EAAE,cAAc,CAAC;IAChC,QAAQ,CAAC,MAAM,EAAE,YAAY,CAAC;IAC9B,0EAA0E;IAC1E,KAAK,EAAE,aAAa,CAAC,aAAa,CAAC,CAAC;IACpC,oEAAoE;IACpE,KAAK,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,CAAC,CAAC;IAC5C,+BAA+B;IAC/B,QAAQ,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,YAAY,GAAG,OAAO,CAAC,kBAAkB,CAAC,CAAC;IAC9E,gDAAgD;IAChD,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CAC3B;AAED,wDAAwD;AACxD,MAAM,WAAW,aAAa;IAC5B,EAAE,EAAE,MAAM,CAAC;IACX,8DAA8D;IAC9D,KAAK,EAAE,WAAW,CAAC;CACpB;AAaD;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,wBAAsB,UAAU,CAAC,MAAM,EAAE,gBAAgB,GAAG,OAAO,CAAC,YAAY,CAAC,CAkOhF"}
|
|
@@ -0,0 +1,292 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `quickStart` — the zero-to-earning composer.
|
|
3
|
+
*
|
|
4
|
+
* Goal: if an agent meets the basic requirements (wallet OR service token,
|
|
5
|
+
* supported adapter), one call here should take it from "nothing" to
|
|
6
|
+
* "listening for claimable tasks" in under 60 seconds.
|
|
7
|
+
*
|
|
8
|
+
* Composition:
|
|
9
|
+
* 1. Ensure a session (reuse wallet or service token)
|
|
10
|
+
* 2. Quick-join a workspace (register runtime, bootstrap, fund, lease)
|
|
11
|
+
* 3. Open the workspace event stream
|
|
12
|
+
* 4. Return a {@link RunningAgent} handle that exposes the task stream and
|
|
13
|
+
* lifecycle helpers
|
|
14
|
+
*
|
|
15
|
+
* @packageDocumentation
|
|
16
|
+
*/
|
|
17
|
+
import { AgentSdkClient } from "./client.js";
|
|
18
|
+
import { openStream } from "./modules/streams.js";
|
|
19
|
+
import { resolveJoinInput, runQuickJoin } from "./quickstart-join.js";
|
|
20
|
+
function toClientOptions(config, tokenProvider) {
|
|
21
|
+
return {
|
|
22
|
+
baseUrl: config.baseUrl,
|
|
23
|
+
getToken: tokenProvider,
|
|
24
|
+
...(config.fetchImpl ? { fetchImpl: config.fetchImpl } : {})
|
|
25
|
+
};
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Take an agent from zero to listening for work.
|
|
29
|
+
*
|
|
30
|
+
* @example
|
|
31
|
+
* ```ts
|
|
32
|
+
* const agent = await quickStart({
|
|
33
|
+
* baseUrl: process.env.SHARDLINK_BASE_URL!,
|
|
34
|
+
* getToken: () => process.env.SHARDLINK_SERVICE_TOKEN!,
|
|
35
|
+
* join: {
|
|
36
|
+
* identity: "agent_1",
|
|
37
|
+
* runtime: { runtimeKey: "openclaw", runtimeVersion: "1.0.0",
|
|
38
|
+
* adapterKind: "openclaw",
|
|
39
|
+
* supportedActions: ["claim_task", "complete_task"] }
|
|
40
|
+
* }
|
|
41
|
+
* });
|
|
42
|
+
*
|
|
43
|
+
* for await (const task of agent.tasks) {
|
|
44
|
+
* const claimed = await agent.claim(task.id);
|
|
45
|
+
* if (claimed.winner) {
|
|
46
|
+
* await agent.complete(task.id, { kind: "text", content: "done" });
|
|
47
|
+
* }
|
|
48
|
+
* }
|
|
49
|
+
* ```
|
|
50
|
+
*/
|
|
51
|
+
export async function quickStart(config) {
|
|
52
|
+
if (!config.getToken && !config.wallet) {
|
|
53
|
+
throw new Error("[quickStart] must provide either `getToken` or `wallet` config to mint a session.");
|
|
54
|
+
}
|
|
55
|
+
// Resolve a session: either use the caller's token, or self-register with a wallet.
|
|
56
|
+
let tokenProvider;
|
|
57
|
+
let selfRegisterResult = null;
|
|
58
|
+
if (config.getToken) {
|
|
59
|
+
tokenProvider = config.getToken;
|
|
60
|
+
}
|
|
61
|
+
else {
|
|
62
|
+
const bootstrapClient = new AgentSdkClient({
|
|
63
|
+
baseUrl: config.baseUrl,
|
|
64
|
+
...(config.fetchImpl ? { fetchImpl: config.fetchImpl } : {})
|
|
65
|
+
});
|
|
66
|
+
const runtime = config.wallet?.runtime ??
|
|
67
|
+
config.join?.runtime ??
|
|
68
|
+
undefined;
|
|
69
|
+
if (!runtime) {
|
|
70
|
+
throw new Error("[quickStart] must provide `wallet.runtime` or `join.runtime` when self-registering.");
|
|
71
|
+
}
|
|
72
|
+
selfRegisterResult = await bootstrapClient.register.selfRegister({
|
|
73
|
+
...config.wallet,
|
|
74
|
+
runtime
|
|
75
|
+
});
|
|
76
|
+
const sessionToken = selfRegisterResult.session.token;
|
|
77
|
+
tokenProvider = () => sessionToken;
|
|
78
|
+
}
|
|
79
|
+
const client = new AgentSdkClient(toClientOptions(config, tokenProvider));
|
|
80
|
+
// Build the quickJoin input — filling in defaults from self-register + discover when needed.
|
|
81
|
+
const joinInput = await resolveJoinInput(client, config, selfRegisterResult);
|
|
82
|
+
const join = await runQuickJoin(client, joinInput);
|
|
83
|
+
const actorSessionToken = join.actorSessionToken;
|
|
84
|
+
const stream = openStream({
|
|
85
|
+
baseUrl: client.baseUrl,
|
|
86
|
+
workspace: join.workspace.slug,
|
|
87
|
+
role: "agent",
|
|
88
|
+
getToken: () => actorSessionToken,
|
|
89
|
+
...(config.onStreamStateChange ? { onStateChange: (s) => config.onStreamStateChange?.(s) } : {})
|
|
90
|
+
});
|
|
91
|
+
const identity = joinInput.identity ??
|
|
92
|
+
joinInput.runtime.identity ??
|
|
93
|
+
selfRegisterResult?.identity ??
|
|
94
|
+
extractIdentity(join.bootstrap) ??
|
|
95
|
+
"self";
|
|
96
|
+
const taskQueue = [];
|
|
97
|
+
const waiters = [];
|
|
98
|
+
const seenTaskIds = new Set();
|
|
99
|
+
let closed = false;
|
|
100
|
+
const offer = (id, event) => {
|
|
101
|
+
if (seenTaskIds.has(id) || closed)
|
|
102
|
+
return;
|
|
103
|
+
seenTaskIds.add(id);
|
|
104
|
+
const task = { id, event };
|
|
105
|
+
if (waiters.length > 0) {
|
|
106
|
+
const resolve = waiters.shift();
|
|
107
|
+
resolve?.({ value: task, done: false });
|
|
108
|
+
}
|
|
109
|
+
else {
|
|
110
|
+
taskQueue.push(task);
|
|
111
|
+
}
|
|
112
|
+
};
|
|
113
|
+
// Stream-driven task discovery. The control-plane SSE stream emits native
|
|
114
|
+
// task-lifecycle events — `task_ready_for_claim` (a task is open for
|
|
115
|
+
// claiming), `task_claimed`, and `task_completed` — alongside the reactions
|
|
116
|
+
// snapshot + `reaction_event` feed. `task_created` is also handled
|
|
117
|
+
// defensively: it is not currently emitted by the control plane, but the
|
|
118
|
+
// synthetic poll-fallback event below carries that type, and accepting it
|
|
119
|
+
// costs nothing if a future server revision starts emitting it.
|
|
120
|
+
const unsubStream = stream.onAny((event) => {
|
|
121
|
+
const payload = event.payload;
|
|
122
|
+
if (event.type === "task_created" ||
|
|
123
|
+
event.type === "task_ready_for_claim" ||
|
|
124
|
+
event.type === "task_claimed" ||
|
|
125
|
+
event.type === "task_completed") {
|
|
126
|
+
const id = extractId(payload);
|
|
127
|
+
if (id)
|
|
128
|
+
offer(id, event);
|
|
129
|
+
return;
|
|
130
|
+
}
|
|
131
|
+
if (event.type === "snapshot" && isRecord(payload) && Array.isArray(payload.items)) {
|
|
132
|
+
for (const item of payload.items) {
|
|
133
|
+
const id = extractId(item);
|
|
134
|
+
if (id)
|
|
135
|
+
offer(id, event);
|
|
136
|
+
}
|
|
137
|
+
return;
|
|
138
|
+
}
|
|
139
|
+
if (event.type === "reaction_event" && isRecord(payload)) {
|
|
140
|
+
// Reactions can target tasks — when they do, surface the task for eligible agents.
|
|
141
|
+
if (payload.targetType === "task") {
|
|
142
|
+
const id = typeof payload.targetId === "string" ? payload.targetId : undefined;
|
|
143
|
+
if (id)
|
|
144
|
+
offer(id, event);
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
});
|
|
148
|
+
// Polling fallback — ON by default as defense-in-depth. The stream above
|
|
149
|
+
// surfaces task-lifecycle events natively, but an SSE connection can drop
|
|
150
|
+
// and miss events while reconnecting; the 5s poll covers that gap.
|
|
151
|
+
const pollConfig = config.taskPolling ?? { intervalMs: 5_000 };
|
|
152
|
+
let pollTimer = null;
|
|
153
|
+
if (pollConfig.intervalMs > 0) {
|
|
154
|
+
const lister = pollConfig.list ??
|
|
155
|
+
(async ({ client: c, workspaceSlug, actorSessionToken: tok }) => {
|
|
156
|
+
const params = new URLSearchParams({ status: "pending" });
|
|
157
|
+
try {
|
|
158
|
+
const res = await c.http.rawRequest({
|
|
159
|
+
path: `/v1/workspaces/${encodeURIComponent(workspaceSlug)}/tasks`,
|
|
160
|
+
method: "GET",
|
|
161
|
+
operation: "task-list-poll",
|
|
162
|
+
headers: c.http.bearerHeaders(tok),
|
|
163
|
+
params
|
|
164
|
+
});
|
|
165
|
+
if (!res.ok)
|
|
166
|
+
return [];
|
|
167
|
+
const json = (await res.json());
|
|
168
|
+
return Array.isArray(json.tasks) ? json.tasks : [];
|
|
169
|
+
}
|
|
170
|
+
catch {
|
|
171
|
+
return [];
|
|
172
|
+
}
|
|
173
|
+
});
|
|
174
|
+
pollTimer = setInterval(() => {
|
|
175
|
+
if (closed)
|
|
176
|
+
return;
|
|
177
|
+
void lister({
|
|
178
|
+
client,
|
|
179
|
+
workspaceSlug: join.workspace.slug,
|
|
180
|
+
actorSessionToken
|
|
181
|
+
}).then((tasks) => {
|
|
182
|
+
// Synthetic envelope tagging polled tasks — distinguishes a
|
|
183
|
+
// poll-discovered task from a stream-discovered one on the
|
|
184
|
+
// `ClaimableTask.event` field surfaced to callers.
|
|
185
|
+
const syntheticEvent = { type: "task_created", payload: null };
|
|
186
|
+
for (const task of tasks) {
|
|
187
|
+
if (typeof task.id === "string")
|
|
188
|
+
offer(task.id, syntheticEvent);
|
|
189
|
+
}
|
|
190
|
+
});
|
|
191
|
+
}, pollConfig.intervalMs);
|
|
192
|
+
}
|
|
193
|
+
const tasks = {
|
|
194
|
+
[Symbol.asyncIterator]() {
|
|
195
|
+
return {
|
|
196
|
+
next() {
|
|
197
|
+
if (taskQueue.length > 0) {
|
|
198
|
+
const task = taskQueue.shift();
|
|
199
|
+
return Promise.resolve({ value: task, done: false });
|
|
200
|
+
}
|
|
201
|
+
if (closed) {
|
|
202
|
+
return Promise.resolve({ value: undefined, done: true });
|
|
203
|
+
}
|
|
204
|
+
return new Promise((resolve) => waiters.push(resolve));
|
|
205
|
+
},
|
|
206
|
+
return() {
|
|
207
|
+
closed = true;
|
|
208
|
+
if (pollTimer) {
|
|
209
|
+
clearInterval(pollTimer);
|
|
210
|
+
pollTimer = null;
|
|
211
|
+
}
|
|
212
|
+
try {
|
|
213
|
+
unsubStream();
|
|
214
|
+
}
|
|
215
|
+
catch {
|
|
216
|
+
// ignore
|
|
217
|
+
}
|
|
218
|
+
waiters.forEach((resolve) => resolve({ value: undefined, done: true }));
|
|
219
|
+
waiters.length = 0;
|
|
220
|
+
return Promise.resolve({ value: undefined, done: true });
|
|
221
|
+
}
|
|
222
|
+
};
|
|
223
|
+
}
|
|
224
|
+
};
|
|
225
|
+
return {
|
|
226
|
+
identity,
|
|
227
|
+
workspace: join.workspace.slug,
|
|
228
|
+
actorSessionToken,
|
|
229
|
+
join,
|
|
230
|
+
client,
|
|
231
|
+
stream,
|
|
232
|
+
tasks,
|
|
233
|
+
async claim(taskId) {
|
|
234
|
+
return client.tasks.claim({
|
|
235
|
+
workspaceSlug: join.workspace.slug,
|
|
236
|
+
actorSessionToken,
|
|
237
|
+
taskId
|
|
238
|
+
});
|
|
239
|
+
},
|
|
240
|
+
async complete(taskId, artifact) {
|
|
241
|
+
return client.tasks.complete({
|
|
242
|
+
workspaceSlug: join.workspace.slug,
|
|
243
|
+
actorSessionToken,
|
|
244
|
+
taskId,
|
|
245
|
+
artifact
|
|
246
|
+
});
|
|
247
|
+
},
|
|
248
|
+
async shutdown() {
|
|
249
|
+
closed = true;
|
|
250
|
+
if (pollTimer) {
|
|
251
|
+
clearInterval(pollTimer);
|
|
252
|
+
pollTimer = null;
|
|
253
|
+
}
|
|
254
|
+
try {
|
|
255
|
+
unsubStream();
|
|
256
|
+
}
|
|
257
|
+
catch {
|
|
258
|
+
// ignore
|
|
259
|
+
}
|
|
260
|
+
waiters.forEach((resolve) => resolve({ value: undefined, done: true }));
|
|
261
|
+
waiters.length = 0;
|
|
262
|
+
stream.disconnect();
|
|
263
|
+
}
|
|
264
|
+
};
|
|
265
|
+
}
|
|
266
|
+
function isRecord(value) {
|
|
267
|
+
return typeof value === "object" && value !== null;
|
|
268
|
+
}
|
|
269
|
+
function extractId(payload) {
|
|
270
|
+
if (!isRecord(payload))
|
|
271
|
+
return undefined;
|
|
272
|
+
if (typeof payload.taskId === "string")
|
|
273
|
+
return payload.taskId;
|
|
274
|
+
if (typeof payload.id === "string")
|
|
275
|
+
return payload.id;
|
|
276
|
+
if (isRecord(payload.task) && typeof payload.task.id === "string")
|
|
277
|
+
return payload.task.id;
|
|
278
|
+
return undefined;
|
|
279
|
+
}
|
|
280
|
+
function extractIdentity(payload) {
|
|
281
|
+
if (!isRecord(payload))
|
|
282
|
+
return undefined;
|
|
283
|
+
const envelope = isRecord(payload.envelope) ? payload.envelope : undefined;
|
|
284
|
+
if (envelope && typeof envelope.identity === "string") {
|
|
285
|
+
return envelope.identity;
|
|
286
|
+
}
|
|
287
|
+
if (typeof payload.identity === "string") {
|
|
288
|
+
return payload.identity;
|
|
289
|
+
}
|
|
290
|
+
return undefined;
|
|
291
|
+
}
|
|
292
|
+
//# sourceMappingURL=quickstart.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"quickstart.js","sourceRoot":"","sources":["../src/quickstart.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAEH,OAAO,EAAE,cAAc,EAA8B,MAAM,aAAa,CAAC;AACzE,OAAO,EAAE,UAAU,EAAqB,MAAM,sBAAsB,CAAC;AACrE,OAAO,EAAE,gBAAgB,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AA6FtE,SAAS,eAAe,CACtB,MAAwB,EACxB,aAA6C;IAE7C,OAAO;QACL,OAAO,EAAE,MAAM,CAAC,OAAO;QACvB,QAAQ,EAAE,aAAa;QACvB,GAAG,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,SAAS,EAAE,MAAM,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;KAC7D,CAAC;AACJ,CAAC;AAED;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,MAAM,CAAC,KAAK,UAAU,UAAU,CAAC,MAAwB;IACvD,IAAI,CAAC,MAAM,CAAC,QAAQ,IAAI,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC;QACvC,MAAM,IAAI,KAAK,CACb,mFAAmF,CACpF,CAAC;IACJ,CAAC;IACD,oFAAoF;IACpF,IAAI,aAA6C,CAAC;IAClD,IAAI,kBAAkB,GACpB,IAAI,CAAC;IACP,IAAI,MAAM,CAAC,QAAQ,EAAE,CAAC;QACpB,aAAa,GAAG,MAAM,CAAC,QAAQ,CAAC;IAClC,CAAC;SAAM,CAAC;QACN,MAAM,eAAe,GAAG,IAAI,cAAc,CAAC;YACzC,OAAO,EAAE,MAAM,CAAC,OAAO;YACvB,GAAG,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,SAAS,EAAE,MAAM,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;SAC7D,CAAC,CAAC;QACH,MAAM,OAAO,GACX,MAAM,CAAC,MAAM,EAAE,OAAO;YACtB,MAAM,CAAC,IAAI,EAAE,OAAO;YACnB,SAAqD,CAAC;QACzD,IAAI,CAAC,OAAO,EAAE,CAAC;YACb,MAAM,IAAI,KAAK,CACb,qFAAqF,CACtF,CAAC;QACJ,CAAC;QACD,kBAAkB,GAAG,MAAM,eAAe,CAAC,QAAQ,CAAC,YAAY,CAAC;YAC/D,GAAI,MAAM,CAAC,MAA4B;YACvC,OAAO;SACR,CAAC,CAAC;QACH,MAAM,YAAY,GAAG,kBAAkB,CAAC,OAAO,CAAC,KAAK,CAAC;QACtD,aAAa,GAAG,GAAG,EAAE,CAAC,YAAY,CAAC;IACrC,CAAC;IAED,MAAM,MAAM,GAAG,IAAI,cAAc,CAAC,eAAe,CAAC,MAAM,EAAE,aAAa,CAAC,CAAC,CAAC;IAE1E,6FAA6F;IAC7F,MAAM,SAAS,GAAG,MAAM,gBAAgB,CAAC,MAAM,EAAE,MAAM,EAAE,kBAAkB,CAAC,CAAC;IAC7E,MAAM,IAAI,GAAG,MAAM,YAAY,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC;IACnD,MAAM,iBAAiB,GAAG,IAAI,CAAC,iBAAiB,CAAC;IAEjD,MAAM,MAAM,GAAG,UAAU,CAAC;QACxB,OAAO,EAAE,MAAM,CAAC,OAAO;QACvB,SAAS,EAAE,IAAI,CAAC,SAAS,CAAC,IAAI;QAC9B,IAAI,EAAE,OAAO;QACb,QAAQ,EAAE,GAAG,EAAE,CAAC,iBAAiB;QACjC,GAAG,CAAC,MAAM,CAAC,mBAAmB,CAAC,CAAC,CAAC,EAAE,aAAa,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,MAAM,CAAC,mBAAmB,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;KACjG,CAAC,CAAC;IAEH,MAAM,QAAQ,GACZ,SAAS,CAAC,QAAQ;QAClB,SAAS,CAAC,OAAO,CAAC,QAAQ;QAC1B,kBAAkB,EAAE,QAAQ;QAC5B,eAAe,CAAC,IAAI,CAAC,SAAS,CAAC;QAC/B,MAAM,CAAC;IAET,MAAM,SAAS,GAAoB,EAAE,CAAC;IACtC,MAAM,OAAO,GAA0D,EAAE,CAAC;IAC1E,MAAM,WAAW,GAAG,IAAI,GAAG,EAAU,CAAC;IACtC,IAAI,MAAM,GAAG,KAAK,CAAC;IAEnB,MAAM,KAAK,GAAG,CAAC,EAAU,EAAE,KAAkB,EAAQ,EAAE;QACrD,IAAI,WAAW,CAAC,GAAG,CAAC,EAAE,CAAC,IAAI,MAAM;YAAE,OAAO;QAC1C,WAAW,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QACpB,MAAM,IAAI,GAAkB,EAAE,EAAE,EAAE,KAAK,EAAE,CAAC;QAC1C,IAAI,OAAO,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACvB,MAAM,OAAO,GAAG,OAAO,CAAC,KAAK,EAAE,CAAC;YAChC,OAAO,EAAE,CAAC,EAAE,KAAK,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC;QAC1C,CAAC;aAAM,CAAC;YACN,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACvB,CAAC;IACH,CAAC,CAAC;IAEF,0EAA0E;IAC1E,qEAAqE;IACrE,4EAA4E;IAC5E,mEAAmE;IACnE,yEAAyE;IACzE,0EAA0E;IAC1E,gEAAgE;IAChE,MAAM,WAAW,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC,KAAK,EAAE,EAAE;QACzC,MAAM,OAAO,GAAG,KAAK,CAAC,OAAO,CAAC;QAC9B,IACE,KAAK,CAAC,IAAI,KAAK,cAAc;YAC7B,KAAK,CAAC,IAAI,KAAK,sBAAsB;YACrC,KAAK,CAAC,IAAI,KAAK,cAAc;YAC7B,KAAK,CAAC,IAAI,KAAK,gBAAgB,EAC/B,CAAC;YACD,MAAM,EAAE,GAAG,SAAS,CAAC,OAAO,CAAC,CAAC;YAC9B,IAAI,EAAE;gBAAE,KAAK,CAAC,EAAE,EAAE,KAAK,CAAC,CAAC;YACzB,OAAO;QACT,CAAC;QACD,IAAI,KAAK,CAAC,IAAI,KAAK,UAAU,IAAI,QAAQ,CAAC,OAAO,CAAC,IAAI,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;YACnF,KAAK,MAAM,IAAI,IAAI,OAAO,CAAC,KAAK,EAAE,CAAC;gBACjC,MAAM,EAAE,GAAG,SAAS,CAAC,IAAI,CAAC,CAAC;gBAC3B,IAAI,EAAE;oBAAE,KAAK,CAAC,EAAE,EAAE,KAAK,CAAC,CAAC;YAC3B,CAAC;YACD,OAAO;QACT,CAAC;QACD,IAAI,KAAK,CAAC,IAAI,KAAK,gBAAgB,IAAI,QAAQ,CAAC,OAAO,CAAC,EAAE,CAAC;YACzD,mFAAmF;YACnF,IAAI,OAAO,CAAC,UAAU,KAAK,MAAM,EAAE,CAAC;gBAClC,MAAM,EAAE,GAAG,OAAO,OAAO,CAAC,QAAQ,KAAK,QAAQ,CAAC,CAAC,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC,SAAS,CAAC;gBAC/E,IAAI,EAAE;oBAAE,KAAK,CAAC,EAAE,EAAE,KAAK,CAAC,CAAC;YAC3B,CAAC;QACH,CAAC;IACH,CAAC,CAAC,CAAC;IAEH,yEAAyE;IACzE,0EAA0E;IAC1E,mEAAmE;IACnE,MAAM,UAAU,GAAG,MAAM,CAAC,WAAW,IAAI,EAAE,UAAU,EAAE,KAAK,EAAE,CAAC;IAC/D,IAAI,SAAS,GAA0C,IAAI,CAAC;IAC5D,IAAI,UAAU,CAAC,UAAU,GAAG,CAAC,EAAE,CAAC;QAC9B,MAAM,MAAM,GACV,UAAU,CAAC,IAAI;YACf,CAAC,KAAK,EAAE,EAAE,MAAM,EAAE,CAAC,EAAE,aAAa,EAAE,iBAAiB,EAAE,GAAG,EAAE,EAAE,EAAE;gBAC9D,MAAM,MAAM,GAAG,IAAI,eAAe,CAAC,EAAE,MAAM,EAAE,SAAS,EAAE,CAAC,CAAC;gBAC1D,IAAI,CAAC;oBACH,MAAM,GAAG,GAAG,MAAM,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC;wBAClC,IAAI,EAAE,kBAAkB,kBAAkB,CAAC,aAAa,CAAC,QAAQ;wBACjE,MAAM,EAAE,KAAK;wBACb,SAAS,EAAE,gBAAgB;wBAC3B,OAAO,EAAE,CAAC,CAAC,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC;wBAClC,MAAM;qBACP,CAAC,CAAC;oBACH,IAAI,CAAC,GAAG,CAAC,EAAE;wBAAE,OAAO,EAAE,CAAC;oBACvB,MAAM,IAAI,GAAG,CAAC,MAAM,GAAG,CAAC,IAAI,EAAE,CAAsC,CAAC;oBACrE,OAAO,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC;gBACrD,CAAC;gBAAC,MAAM,CAAC;oBACP,OAAO,EAAE,CAAC;gBACZ,CAAC;YACH,CAAC,CAAC,CAAC;QACL,SAAS,GAAG,WAAW,CAAC,GAAG,EAAE;YAC3B,IAAI,MAAM;gBAAE,OAAO;YACnB,KAAK,MAAM,CAAC;gBACV,MAAM;gBACN,aAAa,EAAE,IAAI,CAAC,SAAS,CAAC,IAAI;gBAClC,iBAAiB;aAClB,CAAC,CAAC,IAAI,CAAC,CAAC,KAAK,EAAE,EAAE;gBAChB,4DAA4D;gBAC5D,2DAA2D;gBAC3D,mDAAmD;gBACnD,MAAM,cAAc,GAAgB,EAAE,IAAI,EAAE,cAAc,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;gBAC5E,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;oBACzB,IAAI,OAAO,IAAI,CAAC,EAAE,KAAK,QAAQ;wBAAE,KAAK,CAAC,IAAI,CAAC,EAAE,EAAE,cAAc,CAAC,CAAC;gBAClE,CAAC;YACH,CAAC,CAAC,CAAC;QACL,CAAC,EAAE,UAAU,CAAC,UAAU,CAAC,CAAC;IAC5B,CAAC;IAED,MAAM,KAAK,GAAiC;QAC1C,CAAC,MAAM,CAAC,aAAa,CAAC;YACpB,OAAO;gBACL,IAAI;oBACF,IAAI,SAAS,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;wBACzB,MAAM,IAAI,GAAG,SAAS,CAAC,KAAK,EAAG,CAAC;wBAChC,OAAO,OAAO,CAAC,OAAO,CAAC,EAAE,KAAK,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC;oBACvD,CAAC;oBACD,IAAI,MAAM,EAAE,CAAC;wBACX,OAAO,OAAO,CAAC,OAAO,CAAC,EAAE,KAAK,EAAE,SAAqC,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC;oBACvF,CAAC;oBACD,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC;gBACzD,CAAC;gBACD,MAAM;oBACJ,MAAM,GAAG,IAAI,CAAC;oBACd,IAAI,SAAS,EAAE,CAAC;wBACd,aAAa,CAAC,SAAS,CAAC,CAAC;wBACzB,SAAS,GAAG,IAAI,CAAC;oBACnB,CAAC;oBACD,IAAI,CAAC;wBACH,WAAW,EAAE,CAAC;oBAChB,CAAC;oBAAC,MAAM,CAAC;wBACP,SAAS;oBACX,CAAC;oBACD,OAAO,CAAC,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE,CAC1B,OAAO,CAAC,EAAE,KAAK,EAAE,SAAqC,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,CACtE,CAAC;oBACF,OAAO,CAAC,MAAM,GAAG,CAAC,CAAC;oBACnB,OAAO,OAAO,CAAC,OAAO,CAAC,EAAE,KAAK,EAAE,SAAqC,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC;gBACvF,CAAC;aACF,CAAC;QACJ,CAAC;KACF,CAAC;IAEF,OAAO;QACL,QAAQ;QACR,SAAS,EAAE,IAAI,CAAC,SAAS,CAAC,IAAI;QAC9B,iBAAiB;QACjB,IAAI;QACJ,MAAM;QACN,MAAM;QACN,KAAK;QACL,KAAK,CAAC,KAAK,CAAC,MAAM;YAChB,OAAO,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC;gBACxB,aAAa,EAAE,IAAI,CAAC,SAAS,CAAC,IAAI;gBAClC,iBAAiB;gBACjB,MAAM;aACP,CAAC,CAAC;QACL,CAAC;QACD,KAAK,CAAC,QAAQ,CAAC,MAAM,EAAE,QAAQ;YAC7B,OAAO,MAAM,CAAC,KAAK,CAAC,QAAQ,CAAC;gBAC3B,aAAa,EAAE,IAAI,CAAC,SAAS,CAAC,IAAI;gBAClC,iBAAiB;gBACjB,MAAM;gBACN,QAAQ;aACT,CAAC,CAAC;QACL,CAAC;QACD,KAAK,CAAC,QAAQ;YACZ,MAAM,GAAG,IAAI,CAAC;YACd,IAAI,SAAS,EAAE,CAAC;gBACd,aAAa,CAAC,SAAS,CAAC,CAAC;gBACzB,SAAS,GAAG,IAAI,CAAC;YACnB,CAAC;YACD,IAAI,CAAC;gBACH,WAAW,EAAE,CAAC;YAChB,CAAC;YAAC,MAAM,CAAC;gBACP,SAAS;YACX,CAAC;YACD,OAAO,CAAC,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE,CAC1B,OAAO,CAAC,EAAE,KAAK,EAAE,SAAqC,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,CACtE,CAAC;YACF,OAAO,CAAC,MAAM,GAAG,CAAC,CAAC;YACnB,MAAM,CAAC,UAAU,EAAE,CAAC;QACtB,CAAC;KACF,CAAC;AACJ,CAAC;AAED,SAAS,QAAQ,CAAC,KAAc;IAC9B,OAAO,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,IAAI,CAAC;AACrD,CAAC;AAED,SAAS,SAAS,CAAC,OAAgB;IACjC,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC;QAAE,OAAO,SAAS,CAAC;IACzC,IAAI,OAAO,OAAO,CAAC,MAAM,KAAK,QAAQ;QAAE,OAAO,OAAO,CAAC,MAAM,CAAC;IAC9D,IAAI,OAAO,OAAO,CAAC,EAAE,KAAK,QAAQ;QAAE,OAAO,OAAO,CAAC,EAAE,CAAC;IACtD,IAAI,QAAQ,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,OAAO,OAAO,CAAC,IAAI,CAAC,EAAE,KAAK,QAAQ;QAAE,OAAO,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC;IAC1F,OAAO,SAAS,CAAC;AACnB,CAAC;AAED,SAAS,eAAe,CAAC,OAAgB;IACvC,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC;QAAE,OAAO,SAAS,CAAC;IACzC,MAAM,QAAQ,GAAG,QAAQ,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC,SAAS,CAAC;IAC3E,IAAI,QAAQ,IAAI,OAAO,QAAQ,CAAC,QAAQ,KAAK,QAAQ,EAAE,CAAC;QACtD,OAAO,QAAQ,CAAC,QAAQ,CAAC;IAC3B,CAAC;IACD,IAAI,OAAO,OAAO,CAAC,QAAQ,KAAK,QAAQ,EAAE,CAAC;QACzC,OAAO,OAAO,CAAC,QAAQ,CAAC;IAC1B,CAAC;IACD,OAAO,SAAS,CAAC;AACnB,CAAC"}
|
package/dist/retry.d.ts
ADDED
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Smart retry policies and idempotency-key helpers.
|
|
3
|
+
*
|
|
4
|
+
* The default policy only retries errors the control-plane marked as
|
|
5
|
+
* retryable, respects server-supplied `Retry-After`, and adds jitter so
|
|
6
|
+
* independent clients don't synchronise on a thundering herd.
|
|
7
|
+
*
|
|
8
|
+
* @packageDocumentation
|
|
9
|
+
*/
|
|
10
|
+
/** Callback invoked before every retry sleep. */
|
|
11
|
+
export type RetryAttemptHook = (info: {
|
|
12
|
+
/** 1-indexed attempt number that just failed. */
|
|
13
|
+
attempt: number;
|
|
14
|
+
/** The error that caused the retry. */
|
|
15
|
+
error: unknown;
|
|
16
|
+
/** Milliseconds the retry loop will sleep before the next attempt. */
|
|
17
|
+
delayMs: number;
|
|
18
|
+
/** Total attempts allowed by the policy (including the first). */
|
|
19
|
+
maxAttempts: number;
|
|
20
|
+
}) => void;
|
|
21
|
+
/** Configuration for {@link withRetry}. */
|
|
22
|
+
export interface RetryPolicy {
|
|
23
|
+
/** Max attempts including the first (so `3` = one try + two retries). */
|
|
24
|
+
maxAttempts: number;
|
|
25
|
+
/** Base delay in milliseconds before doubling. */
|
|
26
|
+
baseDelay: number;
|
|
27
|
+
/** Cap for the exponential backoff. */
|
|
28
|
+
maxDelay: number;
|
|
29
|
+
/** 0..1 jitter factor applied to each delay. */
|
|
30
|
+
jitter: number;
|
|
31
|
+
/** If present, only retry when `error.code` is in this list. */
|
|
32
|
+
retryOn?: string[];
|
|
33
|
+
/** Abort retrying early (e.g. on shutdown). */
|
|
34
|
+
signal?: AbortSignal;
|
|
35
|
+
/**
|
|
36
|
+
* Observability hook — fires once per retry *before* the backoff sleep.
|
|
37
|
+
* Useful for structured logging and TelemetryClient spans. Sink failures
|
|
38
|
+
* never propagate; a thrown hook is swallowed.
|
|
39
|
+
*/
|
|
40
|
+
onAttempt?: RetryAttemptHook;
|
|
41
|
+
}
|
|
42
|
+
/** Reasonable defaults — safe for any idempotent mutation. */
|
|
43
|
+
export declare const DEFAULT_RETRY: RetryPolicy;
|
|
44
|
+
/**
|
|
45
|
+
* Generate an idempotency key suitable for HTTP `Idempotency-Key` headers.
|
|
46
|
+
*
|
|
47
|
+
* @param prefix - A stable prefix identifying the logical operation.
|
|
48
|
+
*
|
|
49
|
+
* @example
|
|
50
|
+
* ```ts
|
|
51
|
+
* const key = idempotencyKey("task-claim:task_123");
|
|
52
|
+
* // → "task-claim:task_123:01J...Z"
|
|
53
|
+
* ```
|
|
54
|
+
*/
|
|
55
|
+
export declare function idempotencyKey(prefix: string): string;
|
|
56
|
+
/**
|
|
57
|
+
* Format an idempotency key into the HTTP header object the control-plane
|
|
58
|
+
* expects. Pairs with {@link idempotencyKey} to keep the header name in
|
|
59
|
+
* exactly one place.
|
|
60
|
+
*
|
|
61
|
+
* The header is emitted lowercase to match HTTP/2 on-wire form and the
|
|
62
|
+
* existing SDK convention used by the module-internal helpers.
|
|
63
|
+
*
|
|
64
|
+
* @example
|
|
65
|
+
* ```ts
|
|
66
|
+
* const key = idempotencyKey("task-claim:task_123");
|
|
67
|
+
* await fetch(url, { headers: { ...idempotencyHeader(key), ...auth } });
|
|
68
|
+
* ```
|
|
69
|
+
*/
|
|
70
|
+
export declare function idempotencyHeader(key: string): {
|
|
71
|
+
"idempotency-key": string;
|
|
72
|
+
};
|
|
73
|
+
/**
|
|
74
|
+
* Run `fn` with retry, exponential backoff, and jitter.
|
|
75
|
+
*
|
|
76
|
+
* Retries only when the raised error is a retryable {@link ShardLinkError}.
|
|
77
|
+
* Respects `error.retryAfter` (from `Retry-After` header) when present.
|
|
78
|
+
*
|
|
79
|
+
* @example
|
|
80
|
+
* ```ts
|
|
81
|
+
* const result = await withRetry(
|
|
82
|
+
* () => tasks.claim("task_123"),
|
|
83
|
+
* { maxAttempts: 5, baseDelay: 500 }
|
|
84
|
+
* );
|
|
85
|
+
* ```
|
|
86
|
+
*/
|
|
87
|
+
export declare function withRetry<T>(fn: () => Promise<T>, overrides?: Partial<RetryPolicy>): Promise<T>;
|
|
88
|
+
//# sourceMappingURL=retry.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"retry.d.ts","sourceRoot":"","sources":["../src/retry.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAIH,iDAAiD;AACjD,MAAM,MAAM,gBAAgB,GAAG,CAAC,IAAI,EAAE;IACpC,iDAAiD;IACjD,OAAO,EAAE,MAAM,CAAC;IAChB,uCAAuC;IACvC,KAAK,EAAE,OAAO,CAAC;IACf,sEAAsE;IACtE,OAAO,EAAE,MAAM,CAAC;IAChB,kEAAkE;IAClE,WAAW,EAAE,MAAM,CAAC;CACrB,KAAK,IAAI,CAAC;AAEX,2CAA2C;AAC3C,MAAM,WAAW,WAAW;IAC1B,yEAAyE;IACzE,WAAW,EAAE,MAAM,CAAC;IACpB,kDAAkD;IAClD,SAAS,EAAE,MAAM,CAAC;IAClB,uCAAuC;IACvC,QAAQ,EAAE,MAAM,CAAC;IACjB,gDAAgD;IAChD,MAAM,EAAE,MAAM,CAAC;IACf,gEAAgE;IAChE,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;IACnB,+CAA+C;IAC/C,MAAM,CAAC,EAAE,WAAW,CAAC;IACrB;;;;OAIG;IACH,SAAS,CAAC,EAAE,gBAAgB,CAAC;CAC9B;AAED,8DAA8D;AAC9D,eAAO,MAAM,aAAa,EAAE,WAK3B,CAAC;AAEF;;;;;;;;;;GAUG;AACH,wBAAgB,cAAc,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAOrD;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAgB,iBAAiB,CAAC,GAAG,EAAE,MAAM,GAAG;IAAE,iBAAiB,EAAE,MAAM,CAAA;CAAE,CAE5E;AAuDD;;;;;;;;;;;;;GAaG;AACH,wBAAsB,SAAS,CAAC,CAAC,EAC/B,EAAE,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,EACpB,SAAS,GAAE,OAAO,CAAC,WAAW,CAAM,GACnC,OAAO,CAAC,CAAC,CAAC,CAgCZ"}
|
package/dist/retry.js
ADDED
|
@@ -0,0 +1,152 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Smart retry policies and idempotency-key helpers.
|
|
3
|
+
*
|
|
4
|
+
* The default policy only retries errors the control-plane marked as
|
|
5
|
+
* retryable, respects server-supplied `Retry-After`, and adds jitter so
|
|
6
|
+
* independent clients don't synchronise on a thundering herd.
|
|
7
|
+
*
|
|
8
|
+
* @packageDocumentation
|
|
9
|
+
*/
|
|
10
|
+
import { RateLimitError, ServerError, NetworkError, ShardLinkError } from "./errors.js";
|
|
11
|
+
/** Reasonable defaults — safe for any idempotent mutation. */
|
|
12
|
+
export const DEFAULT_RETRY = {
|
|
13
|
+
maxAttempts: 3,
|
|
14
|
+
baseDelay: 1_000,
|
|
15
|
+
maxDelay: 30_000,
|
|
16
|
+
jitter: 0.2
|
|
17
|
+
};
|
|
18
|
+
/**
|
|
19
|
+
* Generate an idempotency key suitable for HTTP `Idempotency-Key` headers.
|
|
20
|
+
*
|
|
21
|
+
* @param prefix - A stable prefix identifying the logical operation.
|
|
22
|
+
*
|
|
23
|
+
* @example
|
|
24
|
+
* ```ts
|
|
25
|
+
* const key = idempotencyKey("task-claim:task_123");
|
|
26
|
+
* // → "task-claim:task_123:01J...Z"
|
|
27
|
+
* ```
|
|
28
|
+
*/
|
|
29
|
+
export function idempotencyKey(prefix) {
|
|
30
|
+
const trimmed = prefix.trim().replace(/[:\s]+$/u, "");
|
|
31
|
+
const uuid = typeof globalThis.crypto?.randomUUID === "function"
|
|
32
|
+
? globalThis.crypto.randomUUID()
|
|
33
|
+
: fallbackRandom();
|
|
34
|
+
return `${trimmed}:${uuid}`;
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Format an idempotency key into the HTTP header object the control-plane
|
|
38
|
+
* expects. Pairs with {@link idempotencyKey} to keep the header name in
|
|
39
|
+
* exactly one place.
|
|
40
|
+
*
|
|
41
|
+
* The header is emitted lowercase to match HTTP/2 on-wire form and the
|
|
42
|
+
* existing SDK convention used by the module-internal helpers.
|
|
43
|
+
*
|
|
44
|
+
* @example
|
|
45
|
+
* ```ts
|
|
46
|
+
* const key = idempotencyKey("task-claim:task_123");
|
|
47
|
+
* await fetch(url, { headers: { ...idempotencyHeader(key), ...auth } });
|
|
48
|
+
* ```
|
|
49
|
+
*/
|
|
50
|
+
export function idempotencyHeader(key) {
|
|
51
|
+
return { "idempotency-key": key };
|
|
52
|
+
}
|
|
53
|
+
function fallbackRandom() {
|
|
54
|
+
const bytes = new Array(16)
|
|
55
|
+
.fill(0)
|
|
56
|
+
.map(() => Math.floor(Math.random() * 256)
|
|
57
|
+
.toString(16)
|
|
58
|
+
.padStart(2, "0"))
|
|
59
|
+
.join("");
|
|
60
|
+
return `${bytes.slice(0, 8)}-${bytes.slice(8, 12)}-${bytes.slice(12, 16)}-${bytes.slice(16, 20)}-${bytes.slice(20)}`;
|
|
61
|
+
}
|
|
62
|
+
function sleep(ms, signal) {
|
|
63
|
+
return new Promise((resolve, reject) => {
|
|
64
|
+
if (signal?.aborted) {
|
|
65
|
+
reject(new Error("aborted"));
|
|
66
|
+
return;
|
|
67
|
+
}
|
|
68
|
+
const handle = setTimeout(() => {
|
|
69
|
+
signal?.removeEventListener("abort", onAbort);
|
|
70
|
+
resolve();
|
|
71
|
+
}, ms);
|
|
72
|
+
const onAbort = () => {
|
|
73
|
+
clearTimeout(handle);
|
|
74
|
+
reject(new Error("aborted"));
|
|
75
|
+
};
|
|
76
|
+
signal?.addEventListener("abort", onAbort, { once: true });
|
|
77
|
+
});
|
|
78
|
+
}
|
|
79
|
+
function computeDelay(attempt, policy, errorRetryAfter) {
|
|
80
|
+
const exponential = Math.min(policy.maxDelay, policy.baseDelay * 2 ** (attempt - 1));
|
|
81
|
+
const jitterAmount = exponential * policy.jitter * Math.random();
|
|
82
|
+
const backoff = Math.round(exponential + jitterAmount);
|
|
83
|
+
if (errorRetryAfter !== undefined) {
|
|
84
|
+
return Math.max(errorRetryAfter, backoff);
|
|
85
|
+
}
|
|
86
|
+
return backoff;
|
|
87
|
+
}
|
|
88
|
+
function shouldRetry(error, policy) {
|
|
89
|
+
if (!(error instanceof ShardLinkError)) {
|
|
90
|
+
return false;
|
|
91
|
+
}
|
|
92
|
+
if (policy.retryOn && policy.retryOn.length > 0) {
|
|
93
|
+
return policy.retryOn.includes(error.code);
|
|
94
|
+
}
|
|
95
|
+
if (error instanceof RateLimitError)
|
|
96
|
+
return true;
|
|
97
|
+
if (error instanceof ServerError)
|
|
98
|
+
return true;
|
|
99
|
+
if (error instanceof NetworkError)
|
|
100
|
+
return true;
|
|
101
|
+
return error.retryable;
|
|
102
|
+
}
|
|
103
|
+
/**
|
|
104
|
+
* Run `fn` with retry, exponential backoff, and jitter.
|
|
105
|
+
*
|
|
106
|
+
* Retries only when the raised error is a retryable {@link ShardLinkError}.
|
|
107
|
+
* Respects `error.retryAfter` (from `Retry-After` header) when present.
|
|
108
|
+
*
|
|
109
|
+
* @example
|
|
110
|
+
* ```ts
|
|
111
|
+
* const result = await withRetry(
|
|
112
|
+
* () => tasks.claim("task_123"),
|
|
113
|
+
* { maxAttempts: 5, baseDelay: 500 }
|
|
114
|
+
* );
|
|
115
|
+
* ```
|
|
116
|
+
*/
|
|
117
|
+
export async function withRetry(fn, overrides = {}) {
|
|
118
|
+
const policy = { ...DEFAULT_RETRY, ...overrides };
|
|
119
|
+
let lastError;
|
|
120
|
+
for (let attempt = 1; attempt <= policy.maxAttempts; attempt += 1) {
|
|
121
|
+
if (policy.signal?.aborted) {
|
|
122
|
+
throw new Error("aborted");
|
|
123
|
+
}
|
|
124
|
+
try {
|
|
125
|
+
return await fn();
|
|
126
|
+
}
|
|
127
|
+
catch (error) {
|
|
128
|
+
lastError = error;
|
|
129
|
+
if (attempt === policy.maxAttempts || !shouldRetry(error, policy)) {
|
|
130
|
+
throw error;
|
|
131
|
+
}
|
|
132
|
+
const retryAfter = error instanceof ShardLinkError ? error.retryAfter : undefined;
|
|
133
|
+
const delay = computeDelay(attempt, policy, retryAfter);
|
|
134
|
+
if (policy.onAttempt) {
|
|
135
|
+
try {
|
|
136
|
+
policy.onAttempt({
|
|
137
|
+
attempt,
|
|
138
|
+
error,
|
|
139
|
+
delayMs: delay,
|
|
140
|
+
maxAttempts: policy.maxAttempts
|
|
141
|
+
});
|
|
142
|
+
}
|
|
143
|
+
catch {
|
|
144
|
+
// Observability hook failures must never break the retry loop.
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
await sleep(delay, policy.signal);
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
throw lastError;
|
|
151
|
+
}
|
|
152
|
+
//# sourceMappingURL=retry.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"retry.js","sourceRoot":"","sources":["../src/retry.ts"],"names":[],"mappings":"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"}
|