@nuanu-ai/agentify 0.5.0 → 0.5.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/dist/backoff.d.ts +17 -39
- package/dist/backoff.js +17 -39
- package/dist/check-card.d.ts +15 -24
- package/dist/check-card.js +15 -24
- package/dist/cli.d.ts +6 -16
- package/dist/cli.js +6 -16
- package/dist/client.d.ts +123 -251
- package/dist/client.js +113 -255
- package/dist/contract.d.ts +7 -10
- package/dist/contract.js +7 -10
- package/dist/index.d.ts +16 -28
- package/dist/index.js +16 -28
- package/dist/schema.d.ts +15 -37
- package/dist/schema.js +12 -30
- package/dist/transport.d.ts +43 -122
- package/dist/transport.js +53 -144
- package/dist/verify.d.ts +8 -17
- package/dist/verify.js +15 -58
- package/dist/worker.d.ts +93 -236
- package/dist/worker.js +111 -255
- package/package.json +2 -2
package/dist/worker.d.ts
CHANGED
|
@@ -1,76 +1,37 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* The one loop that carries everything the merchant's process receives
|
|
3
|
-
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
*
|
|
11
|
-
*
|
|
12
|
-
*
|
|
13
|
-
*
|
|
14
|
-
*
|
|
15
|
-
*
|
|
16
|
-
*
|
|
17
|
-
*
|
|
18
|
-
*
|
|
19
|
-
* merchant's answer; in the asynchronous one it is usually an acceptance, and
|
|
20
|
-
* the goods follow later through the explicit `deliver` call, which is the
|
|
21
|
-
* merchant's to make and not this loop's.
|
|
22
|
-
*
|
|
23
|
-
* A price question is given to the price handler and the answer goes to the
|
|
24
|
-
* quote route against the `price_id` the question carried.
|
|
25
|
-
*
|
|
26
|
-
* An event is handed over and nothing is sent back. An event notifies, it does
|
|
27
|
-
* not ask for work.
|
|
28
|
-
*
|
|
29
|
-
* What happens when a handler throws is the design decision the rest follows
|
|
30
|
-
* from: nothing is sent. An order nobody answered comes back on its own,
|
|
31
|
-
* because the gateway's own order machine is watching for that answer and
|
|
32
|
-
* decides there should be another attempt — that is the machine's meaning of
|
|
33
|
-
* "not delivered". A retry written on this side would be a second machine with
|
|
34
|
-
* a second opinion about how many times a merchant's handler may run, and the
|
|
35
|
-
* two would disagree the first time one of them restarted. The same holds for a
|
|
36
|
-
* handler that answers with something the contract refuses, and for an envelope
|
|
37
|
-
* that arrives with no handler registered for its kind: the merchant is told
|
|
38
|
-
* through the problem channel, and an order or a price question comes back on
|
|
39
|
-
* its own.
|
|
40
|
-
*
|
|
41
|
-
* An event is the exception and it is worth knowing about. It carries no
|
|
42
|
-
* acknowledgement, so nothing here can ask for one again and nothing on the
|
|
43
|
-
* other side is waiting for a reply to notice that it went unanswered. The
|
|
44
|
-
* contract makes no promise that one is ever sent a second time, and whether a
|
|
45
|
-
* particular gateway sends one anyway is that gateway's business. A handler
|
|
46
|
-
* that throws on an event has lost what it carried.
|
|
47
|
-
*
|
|
48
|
-
* The transport failures are the one thing this loop does retry, because there
|
|
49
|
-
* is nothing else to do with them: a poll that did not reach the gateway
|
|
50
|
-
* delivered no envelope to anybody. That retry is the backoff in
|
|
51
|
-
* `backoff.ts` and nothing more.
|
|
2
|
+
* The one loop that carries everything the merchant's process receives, over
|
|
3
|
+
* HTTP long polling: the worker asks for the next batch, and the gateway holds
|
|
4
|
+
* the request until something arrives or its own window closes. An empty batch
|
|
5
|
+
* is the ordinary answer to a quiet window.
|
|
6
|
+
*
|
|
7
|
+
* An order goes to the merchant's handler, and what the handler returns is
|
|
8
|
+
* posted to the order's answer route in every mode. A price question goes to
|
|
9
|
+
* the price handler, and its answer to the quote route against the question's
|
|
10
|
+
* `price_id`. An event is handed over and nothing is sent back.
|
|
11
|
+
*
|
|
12
|
+
* When a handler throws, nothing is sent and nothing is retried here: an
|
|
13
|
+
* unanswered order comes back because the gateway decides on another attempt,
|
|
14
|
+
* and a second retry policy on this side would disagree with it. The same
|
|
15
|
+
* holds for an answer the contract refuses and for a kind with no handler; the
|
|
16
|
+
* merchant is told through the problem reporter. An event is not sent again,
|
|
17
|
+
* so a handler that throws on one has lost what it carried. The only retry
|
|
18
|
+
* here is of a poll that failed, with the backoff in `backoff.ts`.
|
|
52
19
|
*/
|
|
53
20
|
import { type HandlerAnswer, type Order, type OrderEvent, type QuoteRequest, type QuoteResponse } from "@nuanu-ai/agentify-contracts";
|
|
54
21
|
import { type Gateway } from "./transport.js";
|
|
55
22
|
/**
|
|
56
|
-
* What this loop calls with one paid order off the stream.
|
|
57
|
-
*
|
|
58
|
-
*
|
|
59
|
-
* carries the calls that close it, and putting those on it is `client.ts`'s
|
|
60
|
-
* job: this loop reads the envelope and knows nothing about a gateway address
|
|
61
|
-
* or an API key beyond the one it polls with. So the client registers a
|
|
62
|
-
* function of this shape which wraps the merchant's own.
|
|
23
|
+
* What this loop calls with one paid order off the stream. `client.ts`
|
|
24
|
+
* registers a function of this shape that attaches the order's calls and then
|
|
25
|
+
* calls the merchant's own handler.
|
|
63
26
|
*/
|
|
64
27
|
export type OrderDispatch = (order: Order) => HandlerAnswer | Promise<HandlerAnswer>;
|
|
65
28
|
/** The same, for "how much is this and is it there". */
|
|
66
29
|
export type QuoteDispatch = (question: QuoteRequest) => QuoteResponse | Promise<QuoteResponse>;
|
|
67
30
|
/**
|
|
68
|
-
*
|
|
69
|
-
*
|
|
70
|
-
*
|
|
71
|
-
*
|
|
72
|
-
* again builds a fresh envelope around it under a fresh `id`, and what holds
|
|
73
|
-
* still across such a repeat is the order's own identifier in the payload.
|
|
31
|
+
* The name of one delivery of a message: its envelope's `id` and when it was
|
|
32
|
+
* sent. It is no way to recognise a repeat; an order sent again comes in a
|
|
33
|
+
* fresh envelope with a fresh `id`, and what holds still is the order's own
|
|
34
|
+
* identifier.
|
|
74
35
|
*/
|
|
75
36
|
export interface Delivered {
|
|
76
37
|
readonly id: string;
|
|
@@ -79,26 +40,16 @@ export interface Delivered {
|
|
|
79
40
|
/**
|
|
80
41
|
* What the merchant's code does with something that happened to an order.
|
|
81
42
|
*
|
|
82
|
-
* The second argument
|
|
83
|
-
*
|
|
84
|
-
*
|
|
85
|
-
*
|
|
86
|
-
*
|
|
87
|
-
* question to us afterwards needs.
|
|
88
|
-
*
|
|
89
|
-
* It is not there to be deduplicated against. Nothing acknowledges an event, so
|
|
90
|
-
* nothing asks for one again, and the contract makes no promise that one is ever
|
|
91
|
-
* sent twice — which means the risk an event handler is written against is a
|
|
92
|
-
* message that never arrives rather than one that arrives twice.
|
|
43
|
+
* The second argument names this delivery of the message, for a log line or a
|
|
44
|
+
* question to Agentify afterwards, since an event is answered against nothing.
|
|
45
|
+
* An event is sent at most once, so the risk to write against is an event that
|
|
46
|
+
* never arrives, not one that arrives twice; reading open orders with
|
|
47
|
+
* `orders.list({ open: true })` finds a refund owed whose event went missing.
|
|
93
48
|
*/
|
|
94
49
|
export type EventHandler = (event: OrderEvent, delivered: Delivered) => void | Promise<void>;
|
|
95
50
|
/**
|
|
96
|
-
* The things the worker
|
|
97
|
-
*
|
|
98
|
-
*
|
|
99
|
-
* They are one vocabulary rather than several channels because every one of
|
|
100
|
-
* them has the same shape of consequence — something did not get through — and
|
|
101
|
-
* a merchant who wants to count them wants to count them together.
|
|
51
|
+
* The things the worker tells the merchant about, under names their code can
|
|
52
|
+
* branch on, through the reporter registered with `on('problem')`.
|
|
102
53
|
*/
|
|
103
54
|
export declare const WORKER_PROBLEM_KINDS: Readonly<{
|
|
104
55
|
/** The gateway speaks another dialect of the contract. The loop stops. */
|
|
@@ -123,8 +74,11 @@ export declare const WORKER_PROBLEM_KINDS: Readonly<{
|
|
|
123
74
|
readonly WORKER_FAILED: "worker_failed";
|
|
124
75
|
/** A delivery carried the one field name this contract removes in silence. */
|
|
125
76
|
readonly DELIVERY_FIELD_DROPPED: "delivery_field_dropped";
|
|
77
|
+
/** An acceptance was given an argument, which it does not carry. The order is taken on. */
|
|
78
|
+
readonly ACCEPTANCE_ARGUMENT_IGNORED: "acceptance_argument_ignored";
|
|
126
79
|
}>;
|
|
127
80
|
export type WorkerProblemKind = (typeof WORKER_PROBLEM_KINDS)[keyof typeof WORKER_PROBLEM_KINDS];
|
|
81
|
+
/** One thing the worker has to tell the merchant about. */
|
|
128
82
|
export interface WorkerProblem {
|
|
129
83
|
readonly kind: WorkerProblemKind;
|
|
130
84
|
/** What happened, in one sentence a person can act on. */
|
|
@@ -136,64 +90,42 @@ export interface WorkerProblem {
|
|
|
136
90
|
/** The order or the price question it is about, where it is about one. */
|
|
137
91
|
readonly subject?: string;
|
|
138
92
|
}
|
|
93
|
+
/**
|
|
94
|
+
* Where the worker reports problems, registered with `on('problem')`. It is
|
|
95
|
+
* called synchronously; whatever it throws or rejects with is swallowed, so a
|
|
96
|
+
* failing reporter cannot stop the worker. Without one, problems go to
|
|
97
|
+
* `console.error`.
|
|
98
|
+
*/
|
|
139
99
|
export type ProblemReporter = (problem: WorkerProblem) => void;
|
|
140
100
|
/**
|
|
141
|
-
* Calls a merchant's reporter and lets nothing it does escape.
|
|
142
|
-
*
|
|
143
|
-
*
|
|
144
|
-
*
|
|
145
|
-
*
|
|
146
|
-
* otherwise unwind the worker and, from the worker's own last-resort handler,
|
|
147
|
-
* escape as an unhandled rejection and take the host process down with it.
|
|
148
|
-
* There is nowhere left to report a reporter that throws, so it is swallowed.
|
|
149
|
-
*
|
|
150
|
-
* Both ways of throwing, and the second is the one that hid. A reporter
|
|
151
|
-
* declared `void` may still be an `async` function — TypeScript allows it, and
|
|
152
|
-
* a merchant shipping problems to an HTTP logger will write one — and such a
|
|
153
|
-
* reporter does not throw, it returns a promise that rejects a turn later, past
|
|
154
|
-
* this `catch`, with nothing holding it. That is the unhandled rejection this
|
|
155
|
-
* comment claims not to allow, arriving by the door the `try` does not cover.
|
|
156
|
-
* So what comes back is settled too, and its failure dropped in the same
|
|
157
|
-
* silence and for the same reason.
|
|
158
|
-
*
|
|
159
|
-
* It is at the top of the file rather than inside the loop because the loop is
|
|
160
|
-
* not the only thing that reports: a merchant calling `deliver` on an order
|
|
161
|
-
* directly has a reporter too, and the same reasoning covers it exactly.
|
|
101
|
+
* Calls a merchant's reporter and lets nothing it does escape. A reporter that
|
|
102
|
+
* throws, or that is `async` and rejects a turn later, would otherwise end the
|
|
103
|
+
* loop or surface as an unhandled rejection and take the host process down;
|
|
104
|
+
* there is nowhere left to report it, so it is swallowed. A merchant calling
|
|
105
|
+
* `deliver` directly reports through this too.
|
|
162
106
|
*/
|
|
163
107
|
export declare const reportSafely: (reporter: ProblemReporter, problem: WorkerProblem) => void;
|
|
164
108
|
/**
|
|
165
|
-
* The
|
|
166
|
-
*
|
|
167
|
-
*
|
|
168
|
-
*
|
|
169
|
-
*
|
|
170
|
-
* has no way to know that what it returned is not what went out. The contracts
|
|
171
|
-
* package names the delivery as the place the loss lands in what the agent is
|
|
172
|
-
* handed — `DeliverySchema` in its `handler.ts` — and a delivery is written
|
|
173
|
-
* here, so this file says it too.
|
|
174
|
-
*
|
|
175
|
-
* No card can declare such a field, so nothing legitimate reaches here; a
|
|
176
|
-
* merchant only meets it by delivering a name nobody asked for.
|
|
177
|
-
*
|
|
178
|
-
* It is one function because there are two roads to the same gateway and the
|
|
179
|
-
* loss is the same on both: the worker answering with what a handler returned,
|
|
180
|
-
* and a merchant calling `deliver` on an order himself. Written twice, one of
|
|
181
|
-
* them would drift or, as it did, never be written at all.
|
|
109
|
+
* The warning for a delivery carrying a field named `__proto__`, which is
|
|
110
|
+
* removed while the delivery is parsed: the agent never receives it, and
|
|
111
|
+
* without this the merchant would not know. No card can declare such a field.
|
|
112
|
+
* Both roads to the gateway use it, the worker answering for a handler and a
|
|
113
|
+
* merchant calling `deliver` directly.
|
|
182
114
|
*/
|
|
183
115
|
export declare const droppedFieldWarning: (orderId: string, delivered: Readonly<Record<string, unknown>> | undefined) => WorkerProblem | null;
|
|
184
116
|
/**
|
|
185
|
-
*
|
|
186
|
-
*
|
|
187
|
-
*
|
|
188
|
-
*
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
*
|
|
193
|
-
*
|
|
194
|
-
* this
|
|
195
|
-
*
|
|
196
|
-
*
|
|
117
|
+
* The warning reported when `accepted` or `accept` is given an argument.
|
|
118
|
+
* TypeScript refuses one, but JavaScript code can pass it, and nothing passed
|
|
119
|
+
* reaches the gateway. The order is accepted all the same, because refusing
|
|
120
|
+
* would strand an order its buyer has paid for.
|
|
121
|
+
*/
|
|
122
|
+
export declare const acceptanceArgumentWarning: (orderId: string) => WorkerProblem;
|
|
123
|
+
/**
|
|
124
|
+
* Which registration answers each kind on the stream, by the word a merchant
|
|
125
|
+
* passes to `on`. Everything that has to know the stream's kinds derives from
|
|
126
|
+
* this table, and the `satisfies` clause stops the file compiling when the
|
|
127
|
+
* contract gains a kind this table lacks; the `switch` in `dispatch` demands
|
|
128
|
+
* the behaviour for it.
|
|
197
129
|
*/
|
|
198
130
|
export declare const REGISTERED_AS: Readonly<{
|
|
199
131
|
readonly order: "order";
|
|
@@ -201,35 +133,22 @@ export declare const REGISTERED_AS: Readonly<{
|
|
|
201
133
|
readonly order_event: "event";
|
|
202
134
|
}>;
|
|
203
135
|
/**
|
|
204
|
-
* The words a merchant registers something on the stream under.
|
|
205
|
-
*
|
|
206
|
-
*
|
|
207
|
-
*
|
|
208
|
-
* added. Indexing by a key the table does not have yet collapses this type, and
|
|
209
|
-
* with it `Handlers[Kind]` and the contextual type of every `agentify.on(...)`
|
|
210
|
-
* call — so the first compile after the contract grows reports sixty errors, of
|
|
211
|
-
* which fifty-five are implicit-any at call sites that are not the problem, and
|
|
212
|
-
* the three places that do need a hand are buried among them. Indexed this way
|
|
213
|
-
* that same compile names two places, both real.
|
|
214
|
-
*
|
|
215
|
-
* Completeness is not what was lost: the `satisfies` clause on the table above
|
|
216
|
-
* is what demands a word per contract kind, and it still fires.
|
|
136
|
+
* The words a merchant registers something on the stream under. Indexed by
|
|
137
|
+
* the table's own keys rather than the contract's kinds, so that when the
|
|
138
|
+
* contract grows a kind, the compile errors name the two places that need
|
|
139
|
+
* work instead of collapsing every `on(...)` call site into implicit `any`.
|
|
217
140
|
*/
|
|
218
141
|
export type StreamHandlerKind = (typeof REGISTERED_AS)[keyof typeof REGISTERED_AS];
|
|
219
|
-
/** What answers each
|
|
142
|
+
/** What answers each kind, in the shape this loop calls. */
|
|
220
143
|
export interface StreamDispatch {
|
|
221
144
|
order: OrderDispatch;
|
|
222
145
|
quote: QuoteDispatch;
|
|
223
146
|
event: EventHandler;
|
|
224
147
|
}
|
|
225
148
|
/**
|
|
226
|
-
* The handlers the loop dispatches to, read
|
|
227
|
-
*
|
|
228
|
-
*
|
|
229
|
-
* The registry belongs to the client and outlives any one loop. A merchant
|
|
230
|
-
* registers what their process answers, starts, stops, and starts again on the
|
|
231
|
-
* same handlers — and a handler registered while a loop is already running is
|
|
232
|
-
* in place for the next envelope rather than for the next loop.
|
|
149
|
+
* The handlers the loop dispatches to, read when an envelope is handled rather
|
|
150
|
+
* than when the loop starts, so a handler registered while the loop runs is in
|
|
151
|
+
* place for the next envelope. It belongs to the client and outlives any loop.
|
|
233
152
|
*/
|
|
234
153
|
export type HandlerRegistry = {
|
|
235
154
|
[Kind in StreamHandlerKind]?: StreamDispatch[Kind] | undefined;
|
|
@@ -237,12 +156,8 @@ export type HandlerRegistry = {
|
|
|
237
156
|
problem: ProblemReporter;
|
|
238
157
|
};
|
|
239
158
|
/**
|
|
240
|
-
* Time, as the loop sees it
|
|
241
|
-
*
|
|
242
|
-
* A seam rather than a call to `setTimeout` in the middle of the loop, so that
|
|
243
|
-
* a test can assert which delays were asked for without waiting through them.
|
|
244
|
-
* It is not part of the published surface: a merchant has no business
|
|
245
|
-
* replacing the clock their worker runs on.
|
|
159
|
+
* Time, as the loop sees it: a seam so a test can check which delays were
|
|
160
|
+
* asked for without waiting. Not part of the published surface.
|
|
246
161
|
*/
|
|
247
162
|
export interface WorkerClock {
|
|
248
163
|
now(): number;
|
|
@@ -251,100 +166,42 @@ export interface WorkerClock {
|
|
|
251
166
|
}
|
|
252
167
|
export declare const systemClock: WorkerClock;
|
|
253
168
|
/**
|
|
254
|
-
* The shortest a quiet poll may take before the next one.
|
|
255
|
-
*
|
|
256
|
-
*
|
|
257
|
-
*
|
|
258
|
-
* passed and the next poll goes out at once — which is what keeps a waiting
|
|
259
|
-
* agent's price question free of any polling lag (ADR-0004 §4). It exists for
|
|
260
|
-
* the gateway that is not holding requests at all, misconfigured or half
|
|
261
|
-
* broken, where a loop with no floor turns into as many requests a second as
|
|
262
|
-
* the network allows. One second is the whole of the claim: slow enough that
|
|
263
|
-
* nothing is hammered, fast enough that it is invisible against a window
|
|
264
|
-
* measured in tens of seconds.
|
|
169
|
+
* The shortest a quiet poll may take before the next one. Against a gateway
|
|
170
|
+
* that holds polls open it costs nothing, since the window is far longer; it
|
|
171
|
+
* exists so a gateway that answers at once does not get as many requests a
|
|
172
|
+
* second as the network allows.
|
|
265
173
|
*/
|
|
266
174
|
export declare const QUIET_POLL_FLOOR_MS = 1000;
|
|
267
175
|
/**
|
|
268
|
-
* How long the worker asks the gateway to hold a poll open
|
|
269
|
-
*
|
|
270
|
-
* It is a request and not an expectation. The gateway holds it for its own
|
|
271
|
-
* window at most, and the contract says as much, so a shorter answer is
|
|
272
|
-
* ordinary rather than a fault. Asking is what makes the number visible on the
|
|
273
|
-
* wire, where a gateway that wanted to answer sooner can see it.
|
|
176
|
+
* How long the worker asks the gateway to hold a poll open. The gateway holds
|
|
177
|
+
* it for its own window at most, so a shorter answer is ordinary.
|
|
274
178
|
*/
|
|
275
179
|
export declare const POLL_WAIT_SECONDS = 25;
|
|
276
180
|
/**
|
|
277
|
-
* How long the worker
|
|
278
|
-
*
|
|
279
|
-
*
|
|
280
|
-
*
|
|
281
|
-
*
|
|
282
|
-
*
|
|
283
|
-
*
|
|
284
|
-
*
|
|
285
|
-
*
|
|
286
|
-
*
|
|
287
|
-
*
|
|
288
|
-
* never cut off, and a connection that has gone quiet costs one window of
|
|
289
|
-
* silence rather than several minutes of it.
|
|
290
|
-
*
|
|
291
|
-
* This worker never comes near it against the gateway in this repository, and
|
|
292
|
-
* that is not luck: every poll names the window it wants, and that gateway
|
|
293
|
-
* holds a poll for the smaller of the window asked for and its own, so the wait
|
|
294
|
-
* is bounded by the twenty-five seconds above however the gateway is
|
|
295
|
-
* configured. Naming the window is this side's guarantee. The deadline is for
|
|
296
|
-
* the other case — a connection that died without saying so.
|
|
297
|
-
*
|
|
298
|
-
* A second belt exists on the gateway's side, and it is not for this worker.
|
|
299
|
-
* The window is optional on the wire, and a poll that names none is held for
|
|
300
|
-
* the gateway's whole configured window instead; that window is refused above a
|
|
301
|
-
* ceiling set under this number (`WORKER_POLL_WAIT_CEILING_MS` in
|
|
302
|
-
* `apps/gateway/src/config.ts`), which is where this figure is copied. The
|
|
303
|
-
* gateway depends on the contracts and the core machine rather than on the SDK,
|
|
304
|
-
* so it cannot read it, and nothing checks that the copy still matches:
|
|
305
|
-
* changing what is written here means changing it there in the same breath.
|
|
306
|
-
*
|
|
307
|
-
* It is also the reason two poll failures can be a minute and a half apart,
|
|
308
|
-
* which matters to anybody counting them from outside. A gateway that refuses
|
|
309
|
-
* connections fails a poll at once and the backoff is the whole gap; one that
|
|
310
|
-
* accepts and never answers fails only when this deadline runs out, so the gap
|
|
311
|
-
* is this plus the backoff. `DOUBT_MS` in packages/slice/src/subscription.ts is
|
|
312
|
-
* that sum, and it is named here because raising this number silently narrows
|
|
313
|
-
* it — and a window too narrow reads the quiet between two failures as a
|
|
314
|
-
* recovery.
|
|
181
|
+
* How long the worker waits for a poll before giving up on it: twice the
|
|
182
|
+
* window asked for, so a gateway that answers late is never cut off, while a
|
|
183
|
+
* connection dropped silently by something in the middle costs one window
|
|
184
|
+
* rather than the runtime's default of minutes.
|
|
185
|
+
*
|
|
186
|
+
* Two copies elsewhere must move with it. `WORKER_POLL_WAIT_CEILING_MS` in
|
|
187
|
+
* `apps/gateway/src/config.ts` is set under this number, and nothing checks
|
|
188
|
+
* that it still is. `DOUBT_MS` in packages/slice/src/subscription.ts is this
|
|
189
|
+
* plus the backoff ceiling, since a gateway that accepts and never answers
|
|
190
|
+
* fails a poll only when this runs out; raise this alone and a healthcheck
|
|
191
|
+
* reads the quiet between two failures as a recovery.
|
|
315
192
|
*/
|
|
316
193
|
export declare const POLL_DEADLINE_MS: number;
|
|
317
194
|
/** What `startWorker` hands its caller, which is the client and never a merchant. */
|
|
318
195
|
export interface RunningWorker {
|
|
319
196
|
/**
|
|
320
|
-
* Stops the loop and waits for it to finish. Safe to call twice.
|
|
321
|
-
*
|
|
322
|
-
*
|
|
323
|
-
* on the same terms. A poll parked at the gateway is dropped, and the
|
|
324
|
-
* gateway stops it and keeps whatever arrives for the next poll; only
|
|
325
|
-
* something taken in the instant before the drop is lost, and that is an
|
|
326
|
-
* order, which comes again, or an event, which is sent once — the list of
|
|
327
|
-
* open orders is what finds a refund owed whose event went missing.
|
|
328
|
-
* An answer already on its way — a delivery the handler produced a moment
|
|
329
|
-
* ago — is dropped too, and there the honest thing to say is that nobody on
|
|
330
|
-
* this side knows whether it arrived first: the order may already be closed
|
|
331
|
-
* by it, or may come back. The merchant is told which of their orders that
|
|
332
|
-
* happened to, because on their side the work happened.
|
|
333
|
-
*
|
|
334
|
-
* Stopping does not drain. The contract has a word for a poll that asks for
|
|
335
|
-
* whatever is queued right now and comes straight back, and it is not what a
|
|
336
|
-
* worker shutting down wants: draining pulls more work into a process that
|
|
337
|
-
* is going away.
|
|
197
|
+
* Stops the loop and waits for it to finish. Safe to call twice. A parked
|
|
198
|
+
* poll is dropped, and so is an answer already on its way, which the
|
|
199
|
+
* merchant is told about by order; the queue is not drained.
|
|
338
200
|
*/
|
|
339
201
|
stop(): Promise<void>;
|
|
340
202
|
/** Whether the loop is still going. False once it has stopped for any reason. */
|
|
341
203
|
running(): boolean;
|
|
342
204
|
}
|
|
343
205
|
export declare const startWorker: (gateway: Gateway, handlers: HandlerRegistry, clock?: WorkerClock,
|
|
344
|
-
/**
|
|
345
|
-
* The deadline is a parameter for the same reason the clock is: a test
|
|
346
|
-
* cannot wait out fifty seconds to find out whether the worker gives up on a
|
|
347
|
-
* poll, and a deadline nothing exercises is a deadline nobody has seen work.
|
|
348
|
-
* It is not part of anything a merchant passes.
|
|
349
|
-
*/
|
|
206
|
+
/** A parameter so a test can see the deadline work without waiting it out. */
|
|
350
207
|
deadlineMs?: number) => RunningWorker;
|