@demlik/tea 0.14.0 → 0.16.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 +30 -7
- package/dist/agent/index.d.ts +49 -36
- package/dist/agent/index.js +12 -8
- package/dist/chunk-4LPY67E4.js +18 -0
- package/dist/chunk-4LPY67E4.js.map +1 -0
- package/dist/chunk-5XU6ZJO2.js +533 -0
- package/dist/chunk-5XU6ZJO2.js.map +1 -0
- package/dist/{chunk-AQ6ZIMEA.js → chunk-6NG4V5SB.js} +89 -115
- package/dist/chunk-6NG4V5SB.js.map +1 -0
- package/dist/{chunk-HYDWG35Q.js → chunk-7MGXQZPW.js} +11 -9
- package/dist/chunk-7MGXQZPW.js.map +1 -0
- package/dist/{chunk-BLJ2JQSH.js → chunk-BCTEOVOU.js} +3 -3
- package/dist/{chunk-BLJ2JQSH.js.map → chunk-BCTEOVOU.js.map} +1 -1
- package/dist/chunk-CH5KTOEZ.js +710 -0
- package/dist/chunk-CH5KTOEZ.js.map +1 -0
- package/dist/chunk-CIHSHLQX.js +64 -0
- package/dist/chunk-CIHSHLQX.js.map +1 -0
- package/dist/{chunk-Z2L3LSNV.js → chunk-EHUDXAKC.js} +246 -210
- package/dist/chunk-EHUDXAKC.js.map +1 -0
- package/dist/chunk-GOX2CYIM.js +380 -0
- package/dist/chunk-GOX2CYIM.js.map +1 -0
- package/dist/chunk-IVJP3GKJ.js +104 -0
- package/dist/chunk-IVJP3GKJ.js.map +1 -0
- package/dist/{chunk-F7FMAWLA.js → chunk-MVZS5FDM.js} +13 -6
- package/dist/chunk-MVZS5FDM.js.map +1 -0
- package/dist/{chunk-LYLTKJWM.js → chunk-MYNLY3HP.js} +9 -8
- package/dist/chunk-MYNLY3HP.js.map +1 -0
- package/dist/{chunk-I5MQMJDW.js → chunk-NSIAORRY.js} +20 -30
- package/dist/chunk-NSIAORRY.js.map +1 -0
- package/dist/{chunk-MYXFNWAJ.js → chunk-QNGYQMZB.js} +4 -4
- package/dist/chunk-QNGYQMZB.js.map +1 -0
- package/dist/chunk-WT5PBPLB.js +98 -0
- package/dist/chunk-WT5PBPLB.js.map +1 -0
- package/dist/{core-CTzMJ82M.d.ts → core-BbgtiXdg.d.ts} +231 -139
- package/dist/do/index.d.ts +37 -32
- package/dist/do/index.js +21 -14
- package/dist/do/index.js.map +1 -1
- package/dist/{durable-effects-B0-qGQDy.d.ts → durable-effects-7MTK_jnj.d.ts} +1 -1
- package/dist/effect/index.d.ts +151 -0
- package/dist/effect/index.js +98 -0
- package/dist/effect/index.js.map +1 -0
- package/dist/extension/index.d.ts +6 -7
- package/dist/extension/index.js +3 -2
- package/dist/extension/index.js.map +1 -1
- package/dist/flow/index.d.ts +68 -70
- package/dist/flow/index.js +32 -27
- package/dist/flow/index.js.map +1 -1
- package/dist/idempotency/index.d.ts +6 -7
- package/dist/idempotency/index.js +4 -2
- package/dist/{index-DJWIER_3.d.ts → index-7vV8xmsD.d.ts} +1 -1
- package/dist/{index-NjrT3fL2.d.ts → index-Bz5Rh9Ga.d.ts} +19 -96
- package/dist/index-CjFDUBeq.d.ts +207 -0
- package/dist/{index-6A7dB8f6.d.ts → index-CkFYA9Y6.d.ts} +14 -16
- package/dist/{index-B5BZ-_cT.d.ts → index-Cou86-GX.d.ts} +189 -108
- package/dist/{index-TvRb1KVf.d.ts → index-DU6JpQ8G.d.ts} +1 -1
- package/dist/{index-q0hXFeZ0.d.ts → index-Xufl55W8.d.ts} +286 -215
- package/dist/{index-4vZzljCD.d.ts → index-_dOR3xqA.d.ts} +57 -45
- package/dist/index.d.ts +181 -385
- package/dist/index.js +2 -1
- package/dist/jev/index.d.ts +147 -99
- package/dist/jev/index.js +329 -233
- package/dist/jev/index.js.map +1 -1
- package/dist/{machine-CdIcN2Xm.d.ts → machine-BQzTV8On.d.ts} +171 -280
- package/dist/machine-viz/index.d.ts +5 -5
- package/dist/machine-viz/index.js +8 -4
- package/dist/machine-viz/index.js.map +1 -1
- package/dist/mem/index.d.ts +3 -4
- package/dist/mem/index.js +2 -1
- package/dist/mem/index.js.map +1 -1
- package/dist/node/index.d.ts +119 -78
- package/dist/node/index.js +52 -38
- package/dist/node/index.js.map +1 -1
- package/dist/paginate/index.d.ts +27 -33
- package/dist/paginate/index.js +6 -4
- package/dist/parity/index.d.ts +4 -5
- package/dist/parity/index.js +3 -2
- package/dist/parity/index.js.map +1 -1
- package/dist/pbt/index.d.ts +2 -2
- package/dist/pbt/index.js +2 -1
- package/dist/pbt/index.js.map +1 -1
- package/dist/persistence/index.d.ts +6 -7
- package/dist/persistence/index.js +5 -3
- package/dist/promise/index.d.ts +186 -0
- package/dist/promise/index.js +5 -0
- package/dist/promise/index.js.map +1 -0
- package/dist/protocol-ClRZBhHQ.d.ts +53 -0
- package/dist/react/index.d.ts +36 -17
- package/dist/react/index.js +27 -4
- package/dist/react/index.js.map +1 -1
- package/dist/resilience/index.d.ts +63 -455
- package/dist/resilience/index.js +37 -483
- package/dist/resilience/index.js.map +1 -1
- package/dist/{runtime-types-LWDoi943.d.ts → runtime-types-CiVpC0HN.d.ts} +131 -388
- package/dist/testing/index.d.ts +165 -15
- package/dist/testing/index.js +104 -3
- package/dist/testing/index.js.map +1 -1
- package/dist/timing/index.d.ts +25 -22
- package/dist/timing/index.js +4 -3
- package/dist/timing/index.js.map +1 -1
- package/dist/{types-DP3f5NIl.d.ts → types-LxZxGYda.d.ts} +2 -2
- package/dist/work-queue/index.d.ts +5 -6
- package/package.json +18 -5
- package/dist/chunk-AQ6ZIMEA.js.map +0 -1
- package/dist/chunk-F2US5BW6.js +0 -72
- package/dist/chunk-F2US5BW6.js.map +0 -1
- package/dist/chunk-F7FMAWLA.js.map +0 -1
- package/dist/chunk-HUKZQX6U.js +0 -97
- package/dist/chunk-HUKZQX6U.js.map +0 -1
- package/dist/chunk-HYDWG35Q.js.map +0 -1
- package/dist/chunk-I5MQMJDW.js.map +0 -1
- package/dist/chunk-LYLTKJWM.js.map +0 -1
- package/dist/chunk-MYXFNWAJ.js.map +0 -1
- package/dist/chunk-RQULHGYH.js +0 -1804
- package/dist/chunk-RQULHGYH.js.map +0 -1
- package/dist/chunk-Z2L3LSNV.js.map +0 -1
- package/dist/index-DMCeMPMJ.d.ts +0 -272
package/dist/index.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
-
export {
|
|
1
|
+
export { NO_ACK, ack, defineListener, defineManagedResource, fromBroadcastChannel, fromEventSource, fromEventTarget, fromInterval, fromPort, fromReconnectingWebSocket, fromTimeout, fromTransport, fromWebSocket, historyTracker, initAck, liftSlice, nextSeq, partitionByAck, readInOrder, reconcile, tagSeq } from './chunk-GOX2CYIM.js';
|
|
2
|
+
export { AsyncSchemaError, Cmd, DispatchDiscardedError, DisposeTimeoutNotice, DriveFailedError, DriveStalledError, IdentityDropNotice, NoCellError, Outcome, OutcomeContractError, PortNameCollisionError, QuiescenceTimeoutError, RuntimeDiscardNotice, RuntimeDiscardedError, StoreConflictError, UndeclaredFailureError, __resetPortRegistry, absurd, acceptedTypes, acceptsOf, applyCell, applyCellChecked, asReducer, defineMachine, definePort, describeMachine, detectUpdateForm, foldMsgs, foldUpdates, formOf, isFencedStore, msgKeysOf, noop, replay, schemaMigrate, structuralHash, subId, subIdOf, tryApplyCell, tryFoldMsgs, tryInterpret, wrapDetached } from './chunk-CH5KTOEZ.js';
|
|
2
3
|
//# sourceMappingURL=index.js.map
|
|
3
4
|
//# sourceMappingURL=index.js.map
|
package/dist/jev/index.d.ts
CHANGED
|
@@ -1,15 +1,13 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { R as RunCmd, F as FailMsg, S as SucceedMsg, a as ResilientState, b as ResilientTimerMsg } from '../index-Cou86-GX.js';
|
|
2
|
+
import { l as Outcome, b as CmdDef, T as TimerDeps, C as Cmd, o as DepKeyedSub, q as TimerSub } from '../core-BbgtiXdg.js';
|
|
2
3
|
import { RetryPolicy } from '../retry-backoff/index.js';
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
|
|
6
|
-
import {
|
|
7
|
-
import
|
|
8
|
-
import
|
|
9
|
-
import '
|
|
10
|
-
import '../index-DJWIER_3.js';
|
|
11
|
-
import '../runtime-types-LWDoi943.js';
|
|
12
|
-
import 'better-result';
|
|
4
|
+
import { D as DeadlineExceeded, a as DeadlineSub, T as TtlCache, C as CacheEvictionSub, f as CacheEvictMsg } from '../index-Xufl55W8.js';
|
|
5
|
+
import { S as SubscribeHandler } from '../types-LxZxGYda.js';
|
|
6
|
+
import { B as BatchWindow, a as BatchWindowSub, b as BatchWindowExpired } from '../index-_dOR3xqA.js';
|
|
7
|
+
import { F as FanOutState } from '../index-CkFYA9Y6.js';
|
|
8
|
+
import '@standard-schema/spec';
|
|
9
|
+
import '../index-7vV8xmsD.js';
|
|
10
|
+
import '../runtime-types-CiVpC0HN.js';
|
|
13
11
|
|
|
14
12
|
/**
|
|
15
13
|
* @packageDocumentation
|
|
@@ -59,12 +57,19 @@ import 'better-result';
|
|
|
59
57
|
* network actually produced. Every `unknown` reaches a `JevErr`; nothing
|
|
60
58
|
* reaches a `throw`.
|
|
61
59
|
*
|
|
62
|
-
*
|
|
63
|
-
*
|
|
64
|
-
*
|
|
65
|
-
*
|
|
66
|
-
*
|
|
67
|
-
*
|
|
60
|
+
* The check itself is a walk DERIVED from the questions map, one step per
|
|
61
|
+
* field, and the typed value is the fresh object it builds. Both halves of a
|
|
62
|
+
* choice question's claim are structural in that walk: `choice` must be one of
|
|
63
|
+
* the criteria keys, and `probabilities` must carry exactly those keys — so a
|
|
64
|
+
* distribution missing one or carrying an extra fails the check rather than a
|
|
65
|
+
* separate arm a later reader has to remember. A partial distribution typed `Record<K, number>` is
|
|
66
|
+
* the representable-invalid state this module exists to refuse, and it arrives
|
|
67
|
+
* through this gate or not at all. The envelope is checked by the same schema:
|
|
68
|
+
* `model` is a string and `usage` carries two finite numbers.
|
|
69
|
+
*
|
|
70
|
+
* The walk stops at the first field that fails, and that field's path is
|
|
71
|
+
* mapped onto the `JevErr` arm that names it. It is hand-written rather than a
|
|
72
|
+
* schema library's so the published package depends on none (ADR 0021 §5).
|
|
68
73
|
*
|
|
69
74
|
* ## Why status classification lives here and not in `ask`
|
|
70
75
|
*
|
|
@@ -280,12 +285,11 @@ type JevParse<Q extends JevQuestionMap> = {
|
|
|
280
285
|
* Turn an `unknown` response body into the typed answers for `questions`, or
|
|
281
286
|
* into one `JevErr`. Pure, total, and never throwing on any input.
|
|
282
287
|
*
|
|
283
|
-
* The
|
|
284
|
-
*
|
|
285
|
-
*
|
|
286
|
-
*
|
|
287
|
-
*
|
|
288
|
-
* questions are the contract, and a wider response still satisfies it.
|
|
288
|
+
* The schema is question-driven: every id the request asked about must be
|
|
289
|
+
* answered, each answer is checked against ITS question's type and — for a
|
|
290
|
+
* choice — against that question's own criteria keys, both as the `choice`
|
|
291
|
+
* picked and as the exact key set of `probabilities`. An answer under an id
|
|
292
|
+
* nobody asked about is dropped rather than refused.
|
|
289
293
|
*/
|
|
290
294
|
declare const parseAnswers: <Q extends JevQuestionMap>(questions: Q, body: unknown) => JevParse<Q>;
|
|
291
295
|
/**
|
|
@@ -309,39 +313,33 @@ type JevHttpStatus = "ok" | "retry" | "terminal";
|
|
|
309
313
|
declare const classifyStatus: (status: number) => JevHttpStatus;
|
|
310
314
|
|
|
311
315
|
/**
|
|
312
|
-
*
|
|
316
|
+
* What an HTTP call to Jev came back with: the status and the undecoded body.
|
|
313
317
|
*
|
|
314
|
-
*
|
|
318
|
+
* Your handler returns this to {@link decodeJevReply} rather than throwing on a
|
|
315
319
|
* non-2xx, because WHICH non-2xx it is decides whether the call backs off, and
|
|
316
|
-
* a thrown
|
|
317
|
-
* `fetch` adapter can be cancelled; resilient-call issues no signal today, and
|
|
318
|
-
* the slot exists so an adapter's own shape does not have to change when it
|
|
319
|
-
* does.
|
|
320
|
-
*
|
|
321
|
-
* A `fetch` adapter and a scripted test fake satisfy this identically, which is
|
|
322
|
-
* the whole reason the key lives in the adapter's closure and never in config.
|
|
320
|
+
* a thrown error has already lost that.
|
|
323
321
|
*/
|
|
324
|
-
|
|
322
|
+
interface JevHttpReply {
|
|
325
323
|
readonly status: number;
|
|
326
324
|
readonly body: unknown;
|
|
327
|
-
}
|
|
325
|
+
}
|
|
328
326
|
/**
|
|
329
327
|
* The pure decider that answers when the network cannot.
|
|
330
328
|
*
|
|
331
|
-
* Called on exactly two paths:
|
|
332
|
-
* resilient retry budget is spent. It must
|
|
333
|
-
* the exhaustion path runs it inside the
|
|
334
|
-
* a clock read or an I/O call here would
|
|
335
|
-
* Returning a {@link JevErr} is how a fallback
|
|
336
|
-
* this one"; the call then settles as that error.
|
|
329
|
+
* Called on exactly two paths: a handler with no key returns
|
|
330
|
+
* {@link offlineJevAnswer}, and the resilient retry budget is spent. It must
|
|
331
|
+
* be a pure function of the request — the exhaustion path runs it inside the
|
|
332
|
+
* `fail` VERB, which replay re-runs, so a clock read or an I/O call here would
|
|
333
|
+
* make the machine unreplayable. Returning a {@link JevErr} is how a fallback
|
|
334
|
+
* says "I have no answer for this one"; the call then settles as that error.
|
|
337
335
|
*/
|
|
338
336
|
type JevFallback<Q extends JevQuestionMap> = (request: JevRequest<Q>) => JevAnswers<Q> | JevErr;
|
|
339
337
|
/**
|
|
340
338
|
* Every way an ask can fail, as DATA.
|
|
341
339
|
*
|
|
342
340
|
* A superset of the protocol child's {@link JevErr}: a parse failure is
|
|
343
|
-
* reported with the protocol's own tag untouched, and the
|
|
344
|
-
*
|
|
341
|
+
* reported with the protocol's own tag untouched, and the tags below are the
|
|
342
|
+
* ones only a caller can observe. `{_tag}`-discriminated and
|
|
345
343
|
* JSON-round-trippable like the rest (ADR 0011), because it is carried on the
|
|
346
344
|
* settle Msg and stored in the slice's `failed` phase.
|
|
347
345
|
*
|
|
@@ -359,12 +357,12 @@ type JevAskErr = JevErr
|
|
|
359
357
|
readonly _tag: "http_terminal";
|
|
360
358
|
readonly status: number;
|
|
361
359
|
}
|
|
362
|
-
/** The
|
|
360
|
+
/** The call itself threw (a socket error, a DNS failure) — transient. */
|
|
363
361
|
| {
|
|
364
362
|
readonly _tag: "port_threw";
|
|
365
363
|
readonly reason: string;
|
|
366
364
|
}
|
|
367
|
-
/** No
|
|
365
|
+
/** No key and no `fallback`: the knob was configured with no way to answer. */
|
|
368
366
|
| {
|
|
369
367
|
readonly _tag: "no_answer_path";
|
|
370
368
|
};
|
|
@@ -378,19 +376,23 @@ type JevAskErr = JevErr
|
|
|
378
376
|
*/
|
|
379
377
|
declare function isTransientJevAskErr(error: JevAskErr): boolean;
|
|
380
378
|
/**
|
|
381
|
-
*
|
|
382
|
-
*
|
|
383
|
-
*
|
|
384
|
-
* resilient-call routes a rejected port to a failure Msg carrying the raw
|
|
385
|
-
* thrown value, so throwing is the only way the handler can say "this attempt
|
|
386
|
-
* failed" — and a bare `Error` would arrive with its classification already
|
|
387
|
-
* lost. The typed payload rides on `jev`; the slice never stores this object
|
|
388
|
-
* (the verbs store `jev` itself), so nothing un-serializable reaches Model.
|
|
379
|
+
* How a {@link JevAskErr} crosses the handler: the run Cmd's declared
|
|
380
|
+
* `port_rejected` tag, with the typed error on `jev`. The engine mints it into
|
|
381
|
+
* `resilient_run_err` untouched, and {@link jevAskErrOf} reads it back.
|
|
389
382
|
*/
|
|
390
|
-
|
|
383
|
+
type JevRejected = {
|
|
384
|
+
readonly _tag: "port_rejected";
|
|
391
385
|
readonly jev: JevAskErr;
|
|
392
|
-
|
|
393
|
-
|
|
386
|
+
};
|
|
387
|
+
/**
|
|
388
|
+
* Read a settled failure back as a {@link JevAskErr}. PURE.
|
|
389
|
+
*
|
|
390
|
+
* A {@link JevRejected} yields its `jev`. Anything else a handler returned —
|
|
391
|
+
* a bare `port_rejected`, a `deadline_exceeded` — is a failure this door did
|
|
392
|
+
* not classify, and it reads as the transient `port_threw`, exactly as a
|
|
393
|
+
* foreign throw always has.
|
|
394
|
+
*/
|
|
395
|
+
declare function jevAskErrOf(error: unknown): JevAskErr;
|
|
394
396
|
/** The model the door asks for when config names none. */
|
|
395
397
|
declare const DEFAULT_JEV_MODEL = "jev-latest";
|
|
396
398
|
/**
|
|
@@ -401,9 +403,7 @@ declare const DEFAULT_JEV_MODEL = "jev-latest";
|
|
|
401
403
|
interface JevAskConfig<Q extends JevQuestionMap> {
|
|
402
404
|
/** The question map every request carries; its keys type the answers. */
|
|
403
405
|
readonly questions: Q;
|
|
404
|
-
/**
|
|
405
|
-
readonly port?: JevPort<Q>;
|
|
406
|
-
/** The pure decider for the no-port and budget-spent paths. Absent → those settle as an error. */
|
|
406
|
+
/** The pure decider for the no-key and budget-spent paths. Absent → those settle as an error. */
|
|
407
407
|
readonly fallback?: JevFallback<Q>;
|
|
408
408
|
/** Backoff policy, composed into `../../resilience/resilient-call`. Omit → no backoff. */
|
|
409
409
|
readonly retry?: RetryPolicy;
|
|
@@ -411,7 +411,7 @@ interface JevAskConfig<Q extends JevQuestionMap> {
|
|
|
411
411
|
readonly model?: string;
|
|
412
412
|
}
|
|
413
413
|
/**
|
|
414
|
-
* The settled answer carried on `
|
|
414
|
+
* The settled answer carried on `resilient_run_ok`.
|
|
415
415
|
*
|
|
416
416
|
* `source` is not decoration: a fallback answer and a model answer are both
|
|
417
417
|
* valid answers with identical shape, and a host that routes on confidence — or
|
|
@@ -428,6 +428,27 @@ interface JevOk<Q extends JevQuestionMap> {
|
|
|
428
428
|
/** Which path produced this answer. */
|
|
429
429
|
readonly source: "port" | "fallback";
|
|
430
430
|
}
|
|
431
|
+
/**
|
|
432
|
+
* Turn an HTTP reply into the run Cmd's outcome. PURE: classify the status,
|
|
433
|
+
* then parse the body against the questions the request carried.
|
|
434
|
+
*
|
|
435
|
+
* `ok` → the typed {@link JevOk}; a 429 / 529 → the transient `http_retry`;
|
|
436
|
+
* any other non-2xx → the terminal `http_terminal`; a body that disagrees with
|
|
437
|
+
* the questions → the protocol's own {@link JevErr}. Every failure is a
|
|
438
|
+
* {@link JevRejected}.
|
|
439
|
+
*/
|
|
440
|
+
declare function decodeJevReply<Q extends JevQuestionMap>(request: JevRequest<Q>, reply: JevHttpReply): Outcome<JevOk<Q>, JevRejected>;
|
|
441
|
+
/**
|
|
442
|
+
* The outcome for a call that threw before Jev answered — a socket error, a
|
|
443
|
+
* DNS failure. PURE. It is the transient `port_threw`, so it backs off.
|
|
444
|
+
*/
|
|
445
|
+
declare function jevCallThrew(cause: unknown): Outcome<never, JevRejected>;
|
|
446
|
+
/**
|
|
447
|
+
* The outcome with no network at all: the fallback's answer, or its refusal,
|
|
448
|
+
* or `no_answer_path` when there is no fallback. PURE — what a handler with
|
|
449
|
+
* no key returns.
|
|
450
|
+
*/
|
|
451
|
+
declare function offlineJevAnswer<Q extends JevQuestionMap>(request: JevRequest<Q>, fallback: JevFallback<Q> | undefined): Outcome<JevOk<Q>, JevRejected>;
|
|
431
452
|
/**
|
|
432
453
|
* The one effect this knob emits: run the ask for `key` with the plain-data
|
|
433
454
|
* {@link JevRequest} (ADR 0014 — a Cmd is DECLARED, so its input, ok and err
|
|
@@ -445,15 +466,17 @@ declare function jevAskCmdDef<Q extends JevQuestionMap>(): CmdDef<"resilient_run
|
|
|
445
466
|
} | {
|
|
446
467
|
readonly [detail: string]: unknown;
|
|
447
468
|
readonly _tag: "port_rejected";
|
|
448
|
-
}
|
|
469
|
+
}>;
|
|
449
470
|
/** The Cmd the verbs emit — `resilient_run` carrying the request. */
|
|
450
|
-
type JevAskCmd<Q extends JevQuestionMap> = RunCmd<JevRequest<Q>>;
|
|
451
|
-
/** The success settle Msg — resilient-call's, with `
|
|
471
|
+
type JevAskCmd<Q extends JevQuestionMap> = RunCmd<JevRequest<Q>, "resilient", JevOk<Q>>;
|
|
472
|
+
/** The success settle Msg — resilient-call's, with `value` narrowed to {@link JevOk}. */
|
|
452
473
|
type JevSucceedMsg<Q extends JevQuestionMap> = SucceedMsg<JevOk<Q>>;
|
|
453
|
-
/**
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
}
|
|
474
|
+
/**
|
|
475
|
+
* The failure settle Msg the engine mints — resilient-call's. Its `error` is a
|
|
476
|
+
* {@link JevRejected} when your handler used this door's builders; `fail`
|
|
477
|
+
* reads it with {@link jevAskErrOf}.
|
|
478
|
+
*/
|
|
479
|
+
type JevFailMsg = FailMsg;
|
|
457
480
|
/** The retry / deadline timer Msg — `DeadlineExceeded`, inherited. */
|
|
458
481
|
type JevTimerMsg = DeadlineExceeded;
|
|
459
482
|
/**
|
|
@@ -461,44 +484,54 @@ type JevTimerMsg = DeadlineExceeded;
|
|
|
461
484
|
* jitter (pass a fixed `() => 0` in tests to pin backoff; defaults to
|
|
462
485
|
* `Math.random`, read only at resilient-call's verb boundary).
|
|
463
486
|
*
|
|
464
|
-
* The slice and
|
|
465
|
-
*
|
|
466
|
-
* routes on it (see its docblock); it reimplements no backoff. `
|
|
467
|
-
*
|
|
468
|
-
* enriched settle Msg.
|
|
487
|
+
* The slice and most verbs are resilient-call's, forwarded. `fail` is the one
|
|
488
|
+
* composed verb — it reads the {@link JevAskErr} back off the settled Msg and
|
|
489
|
+
* routes on it (see its docblock); it reimplements no backoff. `decode`,
|
|
490
|
+
* `rejected` and `offline` are the pure outcome builders your handler returns.
|
|
469
491
|
*/
|
|
470
492
|
declare function createJevAsk<Q extends JevQuestionMap>(config: JevAskConfig<Q>, rng?: () => number): {
|
|
493
|
+
name: "resilient";
|
|
494
|
+
/** The `Cmd.define`d run Cmd — list it in the machine's `cmds`. */
|
|
495
|
+
run: CmdDef<"resilient_run", {
|
|
496
|
+
readonly key: string;
|
|
497
|
+
readonly input: JevRequest<Q>;
|
|
498
|
+
}, JevOk<Q>, {
|
|
499
|
+
readonly [detail: string]: unknown;
|
|
500
|
+
readonly _tag: "deadline_exceeded";
|
|
501
|
+
} | {
|
|
502
|
+
readonly [detail: string]: unknown;
|
|
503
|
+
readonly _tag: "port_rejected";
|
|
504
|
+
}>;
|
|
471
505
|
init: () => ResilientState<JevRequest<Q>, JevOk<Q>>;
|
|
472
506
|
attempt: (s: ResilientState<JevRequest<Q>, JevOk<Q>>, key: string, content: JevState, at: number) => readonly [ResilientState<JevRequest<Q>, JevOk<Q>>, readonly JevAskCmd<Q>[]];
|
|
473
|
-
succeed: (s: ResilientState<JevRequest<Q>, JevOk<Q>>,
|
|
474
|
-
fail: (s: ResilientState<JevRequest<Q>, JevOk<Q>>,
|
|
507
|
+
succeed: (s: ResilientState<JevRequest<Q>, JevOk<Q>>, msg: JevSucceedMsg<Q>) => readonly [ResilientState<JevRequest<Q>, JevOk<Q>>, readonly JevAskCmd<Q>[]];
|
|
508
|
+
fail: (s: ResilientState<JevRequest<Q>, JevOk<Q>>, msg: JevFailMsg) => readonly [ResilientState<JevRequest<Q>, JevOk<Q>>, readonly JevAskCmd<Q>[]];
|
|
475
509
|
onTimer: (s: ResilientState<JevRequest<Q>, JevOk<Q>>, msg: JevTimerMsg) => readonly [ResilientState<JevRequest<Q>, JevOk<Q>>, readonly JevAskCmd<Q>[]];
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
}
|
|
480
|
-
|
|
510
|
+
deadlines: (s: ResilientState<JevRequest<Q>, JevOk<Q>>) => readonly DeadlineSub[];
|
|
511
|
+
/** The built-in `timer` Sub's deps — resilient-call's `timer`. */
|
|
512
|
+
timer: (s: ResilientState<JevRequest<Q>, JevOk<Q>>) => TimerDeps<ResilientTimerMsg<"resilient">> | null;
|
|
513
|
+
/** Your handler's outcome for an HTTP reply — {@link decodeJevReply}. */
|
|
514
|
+
decode: (request: JevRequest<Q>, reply: JevHttpReply) => Outcome<JevOk<Q>, JevRejected>;
|
|
515
|
+
/** Your handler's outcome when the call threw — {@link jevCallThrew}. */
|
|
516
|
+
rejected: typeof jevCallThrew;
|
|
517
|
+
/** Your handler's outcome with no network — {@link offlineJevAnswer}. */
|
|
518
|
+
offline: (request: JevRequest<Q>) => Outcome<JevOk<Q>, JevRejected>;
|
|
481
519
|
};
|
|
482
520
|
/**
|
|
483
521
|
* The Cmd type a host machine declares in `types.cmd` when it splices a
|
|
484
522
|
* {@link createJevAsk} knob in — {@link JevAskCmd} under the name a `types`
|
|
485
523
|
* block reads well with. It is stated here so a host writes `cmd: {} as
|
|
486
|
-
* JevCmd<Questions>` rather than deriving it from the knob's shape
|
|
487
|
-
* what `ReturnType<Ask["attempt"]>[1][number]` used to be doing at every call
|
|
488
|
-
* site: a spelling of the same type that breaks the moment `attempt`'s tuple
|
|
489
|
-
* changes, and that reads as machinery rather than as a name.
|
|
524
|
+
* JevCmd<Questions>` rather than deriving it from the knob's shape.
|
|
490
525
|
*/
|
|
491
526
|
type JevCmd<Q extends JevQuestionMap> = JevAskCmd<Q>;
|
|
492
|
-
/**
|
|
493
|
-
* The Sub type a host machine declares in `types.sub` — the deadline Sub
|
|
494
|
-
* `subs` emits, inherited from resilient-call. Named here for the same reason
|
|
495
|
-
* as {@link JevCmd}: a host names the type, it does not re-derive it.
|
|
496
|
-
*/
|
|
497
|
-
type JevSub = DeadlineSub;
|
|
498
527
|
/**
|
|
499
528
|
* Lift a knob result `[slice, cmds]` into a host `[State, cmds]` where the slice
|
|
500
529
|
* lives at `state.resilience` — resilient-call's convenience, re-typed for this
|
|
501
530
|
* door's slice so a consumer wires one import. Pure.
|
|
531
|
+
*
|
|
532
|
+
* The record rebuild is `liftSlice` from the root door (#231), the same helper
|
|
533
|
+
* `liftResilience` is expressed over — this stays as the named, pre-keyed
|
|
534
|
+
* convenience for this door, unchanged in name, signature and subpath.
|
|
502
535
|
*/
|
|
503
536
|
declare function liftJevAsk<S extends {
|
|
504
537
|
resilience: ResilientState<JevRequest<Q>, JevOk<Q>>;
|
|
@@ -565,9 +598,7 @@ interface ClassifyBatchConfig<I, C extends string> {
|
|
|
565
598
|
readonly evictEveryMs?: number;
|
|
566
599
|
/** The model asked for. Forwarded to `../ask`'s default when omitted. */
|
|
567
600
|
readonly model?: string;
|
|
568
|
-
/**
|
|
569
|
-
readonly port?: JevPort<ItemQuestions<C>>;
|
|
570
|
-
/** The pure decider for the no-port path. Forwarded to `../ask`. */
|
|
601
|
+
/** The pure decider `offline` answers with, for a handler with no key. */
|
|
571
602
|
readonly fallback?: JevFallback<ItemQuestions<C>>;
|
|
572
603
|
}
|
|
573
604
|
/**
|
|
@@ -581,7 +612,7 @@ interface ClassifyBatchState<I, C extends string> {
|
|
|
581
612
|
readonly fanOut: FanOutState<Batch<I>, JevOk<ItemQuestions<C>>>;
|
|
582
613
|
/** The answers, keyed by `keyOf` — `../../resilience/cache`'s slice. */
|
|
583
614
|
readonly cache: TtlCache<ItemAnswer<C>>;
|
|
584
|
-
/** Keys whose batch settled `
|
|
615
|
+
/** Keys whose batch settled `resilient_run_err`, with the error that settled it. */
|
|
585
616
|
readonly failed: Readonly<Record<string, JevAskErr>>;
|
|
586
617
|
}
|
|
587
618
|
/** What {@link ClassifyBatchKnob.answerFor} reports about one key. */
|
|
@@ -591,7 +622,7 @@ type KeyAnswer<C extends string> =
|
|
|
591
622
|
readonly status: "answered";
|
|
592
623
|
readonly answer: ItemAnswer<C>;
|
|
593
624
|
}
|
|
594
|
-
/** The batch carrying this key settled `
|
|
625
|
+
/** The batch carrying this key settled `resilient_run_err`. Nothing was cached. */
|
|
595
626
|
| {
|
|
596
627
|
readonly status: "failed";
|
|
597
628
|
readonly error: JevAskErr;
|
|
@@ -612,6 +643,17 @@ type KeyAnswer<C extends string> =
|
|
|
612
643
|
* that keeps one key out of two batches at once.
|
|
613
644
|
*/
|
|
614
645
|
declare function createClassifyBatch<I, C extends string>(config: ClassifyBatchConfig<I, C>): {
|
|
646
|
+
/** The ask Cmd def — list it in the machine's `cmds`. */
|
|
647
|
+
ask: CmdDef<"resilient_run", {
|
|
648
|
+
readonly key: string;
|
|
649
|
+
readonly input: JevRequest<Readonly<Record<string, ItemQuestion<C>>>>;
|
|
650
|
+
}, JevOk<Readonly<Record<string, ItemQuestion<C>>>>, {
|
|
651
|
+
readonly [detail: string]: unknown;
|
|
652
|
+
readonly _tag: "deadline_exceeded";
|
|
653
|
+
} | {
|
|
654
|
+
readonly [detail: string]: unknown;
|
|
655
|
+
readonly _tag: "port_rejected";
|
|
656
|
+
}>;
|
|
615
657
|
init: () => ClassifyBatchState<I, C>;
|
|
616
658
|
add: (state: ClassifyBatchState<I, C>, item: I, at: number) => readonly [ClassifyBatchState<I, C>, readonly ClassifyBatchCmd<C>[]];
|
|
617
659
|
onWindow: (state: ClassifyBatchState<I, C>, at: number) => readonly [ClassifyBatchState<I, C>, readonly ClassifyBatchCmd<C>[]];
|
|
@@ -619,16 +661,22 @@ declare function createClassifyBatch<I, C extends string>(config: ClassifyBatchC
|
|
|
619
661
|
onBatchErr: (state: ClassifyBatchState<I, C>, msg: ClassifyBatchErrMsg) => readonly [ClassifyBatchState<I, C>, readonly ClassifyBatchCmd<C>[]];
|
|
620
662
|
onEvict: (state: ClassifyBatchState<I, C>, at: number) => readonly [ClassifyBatchState<I, C>, readonly ClassifyBatchCmd<C>[]];
|
|
621
663
|
answerFor: (state: ClassifyBatchState<I, C>, key: string, at: number) => KeyAnswer<C>;
|
|
622
|
-
subs: (state: ClassifyBatchState<I, C>, id?: string) => readonly
|
|
664
|
+
subs: (state: ClassifyBatchState<I, C>, id?: string) => readonly BatchWindowSub[];
|
|
665
|
+
subEntries: <Model>(select: (model: Model) => ClassifyBatchState<I, C>, id?: string) => readonly DepKeyedSub<Model, TimerSub<BatchWindowExpired> | CacheEvictionSub>[];
|
|
623
666
|
subscribers: () => {
|
|
624
|
-
deadline: SubscribeHandler<DeadlineSub, DeadlineExceeded, unknown>;
|
|
625
667
|
cache: SubscribeHandler<CacheEvictionSub, CacheEvictMsg, unknown>;
|
|
626
668
|
};
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
669
|
+
/**
|
|
670
|
+
* Your handler's outcome for Jev's reply to one batch — `../ask`'s
|
|
671
|
+
* `decodeJevReply`, parsing against the questions the batch carried.
|
|
672
|
+
*/
|
|
673
|
+
decode: (request: JevRequest<ItemQuestions<C>>, reply: JevHttpReply) => Outcome<JevOk<Readonly<Record<string, ItemQuestion<C>>>>, JevRejected>;
|
|
674
|
+
/** Your handler's outcome when the call threw — `../ask`'s `jevCallThrew`. */
|
|
675
|
+
rejected: typeof jevCallThrew;
|
|
676
|
+
/** Your handler's outcome with no network — the configured `fallback`. */
|
|
677
|
+
offline: (request: JevRequest<ItemQuestions<C>>) => Outcome<JevOk<Readonly<Record<string, ItemQuestion<C>>>>, JevRejected>;
|
|
630
678
|
};
|
|
631
679
|
/** The bound knob {@link createClassifyBatch} returns. */
|
|
632
680
|
type ClassifyBatchKnob<I, C extends string> = ReturnType<typeof createClassifyBatch<I, C>>;
|
|
633
681
|
|
|
634
|
-
export { type Batch, type ClassifyBatchCmd, type ClassifyBatchConfig, type ClassifyBatchErrMsg, type ClassifyBatchKnob, type ClassifyBatchOkMsg, type ClassifyBatchState, type ClassifyCriteria, DEFAULT_CLASSIFY_MAX_ITEMS, DEFAULT_JEV_MODEL,
|
|
682
|
+
export { type Batch, type ClassifyBatchCmd, type ClassifyBatchConfig, type ClassifyBatchErrMsg, type ClassifyBatchKnob, type ClassifyBatchOkMsg, type ClassifyBatchState, type ClassifyCriteria, DEFAULT_CLASSIFY_MAX_ITEMS, DEFAULT_JEV_MODEL, type ItemAnswer, type ItemQuestion, type ItemQuestions, JEV_ENDPOINT, type JevAnswer, type JevAnswerFor, type JevAnswers, type JevAskCmd, type JevAskConfig, type JevAskErr, type JevChoiceAnswer, type JevChoiceCriteria, type JevChoiceQuestion, type JevCmd, type JevErr, type JevFailMsg, type JevFallback, type JevHttpReply, type JevHttpStatus, type JevNoulAnswer, type JevNoulQuestion, type JevOk, type JevParse, type JevQuestion, type JevQuestionMap, type JevQuestionType, type JevRejected, type JevRequest, type JevResponse, type JevScoreAnswer, type JevScoreCriteria, type JevScoreQuestion, type JevState, type JevSucceedMsg, type JevText, type JevTimerMsg, type JevUsage, type KeyAnswer, ResilientState, classifyStatus, createClassifyBatch, createJevAsk, decodeJevReply, isJevErr, isTransientJevAskErr, jevAskCmdDef, jevAskErrOf, jevCallThrew, jevQuestions, liftJevAsk, offlineJevAnswer, parseAnswers };
|