@yaklabs-ai/plugin-sdk 0.13.10 → 0.14.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/signals.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  /**
2
- * The `signals` a host with no Jev lane or no signals store binds: `observe` never touches the
2
+ * The `signals` a host with no System One or no signals store binds: `observe` never touches the
3
3
  * network, answers `invalid` for an input that breaks the recorded-name grammar exactly as a
4
4
  * real host would, and otherwise `unavailable` with `stored: false`; both reads answer
5
5
  * `unavailable` with reason `no-store`. So a caller's result handling does not change with host
@@ -10,35 +10,25 @@ export declare function createFallbackOnlySignals(): KayAppSignals;
10
10
  /** The engine over one plugin's `observe` (normally `app.signals.observe`). */
11
11
  export declare function createSignalEngine(observe: KayAppSignals["observe"]): SignalEngine;
12
12
 
13
- /**
14
- * The `invalid` observation `observe` answers when a name in `input` breaks the recorded-name
15
- * grammar, or `undefined` when every name can be recorded. A reader later types these names into
16
- * an address or a `where` filter, so a row that broke the grammar would be unaddressable or
17
- * unfilterable forever: the grammars are on {@link KayAppSignalsDetectorInput},
18
- * {@link KayAppSignalSource}, and {@link KayAppSignalsObserveInput}. Checked first, before any
19
- * digest, grant, store, or Jev call, by the host and by {@link createFallbackOnlySignals} alike.
20
- */
21
- export declare function invalidObservation(input: KayAppSignalsObserveInput): KayAppSignalObservation | undefined;
13
+ declare type DecideAnswer = DecideBoolAnswer | DecideChoiceAnswer | DecideScoreAnswer;
22
14
 
23
- declare type JevAnswer = JevBoolAnswer | JevChoiceAnswer | JevScoreAnswer;
24
-
25
- declare interface JevBoolAnswer {
15
+ declare interface DecideBoolAnswer {
26
16
  readonly type: "bool";
27
17
  /** P(yes), from 0 to 1. */
28
18
  readonly probability: number;
29
19
  }
30
20
 
31
21
  /** A yes/no question. `criteria` says what yes and what no mean; omit it to leave both open. */
32
- declare interface JevBoolQuestion {
22
+ declare interface DecideBoolQuestion {
33
23
  readonly type: "bool";
34
- readonly instructions: string;
24
+ readonly instructions: DecideInstructions;
35
25
  readonly criteria?: {
36
26
  readonly true: string;
37
27
  readonly false: string;
38
28
  };
39
29
  }
40
30
 
41
- declare interface JevChoiceAnswer<L extends string = string> {
31
+ declare interface DecideChoiceAnswer<L extends string = string> {
42
32
  readonly type: "choice";
43
33
  readonly choice: L;
44
34
  readonly confidence: number;
@@ -47,59 +37,43 @@ declare interface JevChoiceAnswer<L extends string = string> {
47
37
  }
48
38
 
49
39
  /** A choice among labels. Each label maps to what it means; an empty string leaves it open. */
50
- declare interface JevChoiceQuestion<L extends string = string> {
40
+ declare interface DecideChoiceQuestion<L extends string = string> {
51
41
  readonly type: "choice";
52
- readonly instructions: string;
42
+ readonly instructions: DecideInstructions;
53
43
  readonly criteria: Readonly<Record<L, string>>;
54
44
  }
55
45
 
56
- declare type JevQuestion = JevBoolQuestion | JevChoiceQuestion | JevScoreQuestion;
46
+ /** What a question asks: text, or a JSON object the client sends as its JSON text. */
47
+ declare type DecideInstructions = string | object;
48
+
49
+ declare type DecideQuestion = DecideBoolQuestion | DecideChoiceQuestion | DecideScoreQuestion;
57
50
 
58
- /** A rubric: questions keyed by the name each answer comes back under. */
59
- declare type JevQuestions = Readonly<Record<string, JevQuestion>>;
51
+ /** Questions keyed by the name each answer comes back under. */
52
+ declare type DecideQuestions = Readonly<Record<string, DecideQuestion>>;
60
53
 
61
- declare interface JevScoreAnswer {
54
+ declare interface DecideScoreAnswer {
62
55
  readonly type: "score";
63
- /** The expected score, from 0 to the number of rungs minus one. */
56
+ /** The expected level, from 0 to the number of levels minus one. */
64
57
  readonly score: number;
65
58
  readonly confidence: number;
66
59
  }
67
60
 
68
- /** A score over ordered rungs: the first criterion scores 0, the next 1, and so on. */
69
- declare interface JevScoreQuestion {
61
+ /** A score over ordered levels: the first criterion scores 0, the next 1, and so on. */
62
+ declare interface DecideScoreQuestion {
70
63
  readonly type: "score";
71
- readonly instructions: string;
64
+ readonly instructions: DecideInstructions;
72
65
  readonly criteria: readonly string[];
73
66
  }
74
67
 
75
68
  /**
76
- * ---
77
- * responsibility: The plugin-facing CONTRACT for Jev typed-decision inference — the shape of
78
- * `api.withJev` on both plugin SDK targets, the {@link JevClient} a `use` body receives, the
79
- * question and answer vocabulary it speaks, and the fallback-only implementation a host
80
- * without a Jev lane binds.
81
- * owns:
82
- * - {@link WithJev}, {@link WithJevOptions}, {@link createFallbackOnlyWithJev}.
83
- * - {@link JevClient}, the {@link JevQuestion} and {@link JevAnswer} vocabulary, and
84
- * {@link JevCallError}.
85
- * does_not_own:
86
- * - The wire. The host serves `classify` over whichever route the user's Jev provider order
87
- * picks; a plugin never sees a vendor client, a vendor type, or a route.
88
- * - Credential resolution, the `jev.use` decision, the Jev-branch budget, or usage accounting.
89
- * Those are host-side (`@bonsai/agent-runtime`'s `kay/jev/`).
90
- * ---
91
- *
92
- * The vocabulary is Bonsai's own (SDK 0.12.0). Before it, `use` received TypeSafe's `TypeSafeClient`
93
- * and plugins coded against a vendor's types. It follows pi's classifier contract, which the host
94
- * runs Jev through: a yes/no question is `bool` and answers a `probability`, every instruction and
95
- * criterion is text, and the state is a JSON object.
96
- */
97
- /**
98
- * The state a rubric reads: a JSON object, never text or an array. Every value must survive
99
- * `JSON.stringify` unchanged (no functions or class instances), because it is sent as JSON.
100
- * Typed as `object` so a state declared as an interface fits without an index signature.
69
+ * The `invalid` observation `observe` answers when a name in `input` breaks the recorded-name
70
+ * grammar, or `undefined` when every name can be recorded. A reader later types these names into
71
+ * an address or a `where` filter, so a row that broke the grammar would be unaddressable or
72
+ * unfilterable forever: the grammars are on {@link KayAppSignalsDetectorInput},
73
+ * {@link KayAppSignalSource}, and {@link KayAppSignalsObserveInput}. Checked first, before any
74
+ * digest, grant, store, or Jev call, by the host and by {@link createFallbackOnlySignals} alike.
101
75
  */
102
- declare type JevState = object;
76
+ export declare function invalidObservation(input: KayAppSignalsObserveInput): KayAppSignalObservation | undefined;
103
77
 
104
78
  /** One stored signal: the answers exactly as Jev gave them, and where the observed turn is. */
105
79
  export declare interface KayAppSignal {
@@ -127,8 +101,8 @@ export declare interface KayAppSignal {
127
101
  readonly inputDigest: string;
128
102
  }
129
103
 
130
- /** One stored answer: a {@link JevAnswer}, or a yes/no answer recorded before SDK 0.12.0. */
131
- export declare type KayAppSignalAnswer = JevAnswer | KayAppSignalNoulAnswer;
104
+ /** One stored answer: a {@link DecideAnswer}, or a yes/no answer recorded before SDK 0.12.0. */
105
+ export declare type KayAppSignalAnswer = DecideAnswer | KayAppSignalNoulAnswer;
132
106
 
133
107
  /** One version of one detector, under one rubric, as the catalog lists it. */
134
108
  export declare interface KayAppSignalDetector {
@@ -157,7 +131,7 @@ export declare interface KayAppSignalNoulAnswer {
157
131
  /**
158
132
  * The result of one observe call. `status` is the only field a caller must switch on:
159
133
  *
160
- * - `classified`: Jev answered; `answers` (one {@link JevAnswer} per question), `model`, and
134
+ * - `classified`: Jev answered; `answers` (one {@link DecideAnswer} per question), `model`, and
161
135
  * `usage` are what the Jev call returned, and `stored` says whether the row landed in the
162
136
  * durable store.
163
137
  * - `unavailable`: Jev could not answer (no key, refused grant, timeout, vendor error, or a
@@ -206,6 +180,25 @@ export declare interface KayAppSignalObservation {
206
180
  readonly recordedAtMs: number;
207
181
  }
208
182
 
183
+ /** Per-call knobs for {@link KayAppSignals.observe}. Every field is optional; the host applies its
184
+ * own default budget when none is given, so the Jev branch is never unbounded. */
185
+ export declare interface KayAppSignalObserveOptions {
186
+ /**
187
+ * Explicit cancellation. Always propagates as a rejection, because an aborted call means
188
+ * "stop", not "record nothing and carry on".
189
+ */
190
+ readonly signal?: AbortSignal;
191
+ /** Bounds the Jev branch alone, measured from the call. */
192
+ readonly timeoutMs?: number;
193
+ /**
194
+ * Absolute epoch-ms hard deadline for the whole call. A deadline already passed rejects (like
195
+ * `signal`); one still ahead derives the Jev branch's budget from it.
196
+ */
197
+ readonly deadlineAt?: number;
198
+ /** Attribution slug for host usage accounting. Never sent to Jev. */
199
+ readonly purpose?: string;
200
+ }
201
+
209
202
  /** One page of signals, oldest recorded first. */
210
203
  export declare interface KayAppSignalPage {
211
204
  readonly signals: readonly KayAppSignal[];
@@ -370,7 +363,7 @@ export declare interface KayAppSignalsObserveInput {
370
363
  * transcript the source points at. So the projection must be a pure function of the
371
364
  * transcript and the detector version, or the row's evidence cannot be reproduced.
372
365
  */
373
- readonly state: JevState;
366
+ readonly state: KayAppSignalState;
374
367
  /**
375
368
  * The typed questions to answer. Stored once per digest. A
376
369
  * rubric asks 1 to 64 questions. Each name is an identifier (letters, digits, and `_`, not
@@ -379,8 +372,8 @@ export declare interface KayAppSignalsObserveInput {
379
372
  * characters with no `,`, `@`, or control or invisible character (`\p{C}`), and no whitespace
380
373
  * but single spaces between words, so a reader can copy it back exactly from rendered text.
381
374
  */
382
- readonly questions: JevQuestions;
383
- readonly options?: WithJevOptions;
375
+ readonly questions: DecideQuestions;
376
+ readonly options?: KayAppSignalObserveOptions;
384
377
  }
385
378
 
386
379
  /**
@@ -461,6 +454,9 @@ export declare interface KayAppSignalsSessionQuery {
461
454
  readonly limit?: number;
462
455
  }
463
456
 
457
+ /** The state a signal's questions are asked over: any object, projected from the transcript. */
458
+ export declare type KayAppSignalState = object;
459
+
464
460
  /**
465
461
  * What a signal is about, named by the recording plugin. The host stores both values and never
466
462
  * interprets them. A signal recorded without a subject has none; every reader treats it as before.
@@ -517,13 +513,13 @@ export declare interface SignalDefinition<I> {
517
513
  readonly version: string;
518
514
  /** What this signal is about, e.g. `turn`: a lowercase slug, stored on the row. */
519
515
  readonly subjectKind: string;
520
- readonly questions: JevQuestions;
516
+ readonly questions: DecideQuestions;
521
517
  /**
522
518
  * The state Jev reads for this subject, or `undefined` when the subject carries nothing this
523
519
  * signal can judge (no row is recorded). Must be a pure function of the subject: the row keeps
524
520
  * only its digest.
525
521
  */
526
- readonly project: (input: I) => JevState | undefined;
522
+ readonly project: (input: I) => KayAppSignalState | undefined;
527
523
  /**
528
524
  * The subject's identity across sessions. Required with `maxAgeMs`; without it a row is tied
529
525
  * to its own anchor only.
@@ -561,7 +557,7 @@ export declare interface SignalEngine {
561
557
  * `source` anchors every row to the transcript; `options` is passed to every observe, with
562
558
  * `purpose` set to `signals/<id>`.
563
559
  */
564
- evaluate<I>(definitions: readonly SignalDefinition<I>[], input: I, source: KayAppSignalSource, options?: WithJevOptions): Promise<readonly SignalEvaluation[]>;
560
+ evaluate<I>(definitions: readonly SignalDefinition<I>[], input: I, source: KayAppSignalSource, options?: KayAppSignalObserveOptions): Promise<readonly SignalEvaluation[]>;
565
561
  }
566
562
 
567
563
  /**
@@ -611,24 +607,4 @@ export declare interface SignalUpstream<I> {
611
607
  readonly pass: readonly KayAppSignalsAnswerFilter[];
612
608
  }
613
609
 
614
- /** Per-call knobs for {@link WithJev}. Every field is optional; the host applies its own default
615
- * budget when none is given, so the Jev branch is never unbounded. */
616
- declare interface WithJevOptions {
617
- /**
618
- * Explicit cancellation. Always propagates as a rejection; never substituted with `fallback`,
619
- * because an aborted call means "stop", not "use the cheaper path".
620
- */
621
- readonly signal?: AbortSignal;
622
- /** Bounds the Jev branch alone, measured from the call. */
623
- readonly timeoutMs?: number;
624
- /**
625
- * Absolute epoch-ms hard deadline for the WHOLE call, `fallback` included. A deadline already
626
- * passed rejects (like `signal`); one still ahead derives the Jev branch's budget from it and
627
- * keeps a small reserve so `fallback` has a window to run.
628
- */
629
- readonly deadlineAt?: number;
630
- /** Attribution slug for host usage accounting. Never sent to Jev. */
631
- readonly purpose?: string;
632
- }
633
-
634
610
  export { }
package/dist/signals.js CHANGED
@@ -120,7 +120,7 @@ function createFallbackOnlySignals() {
120
120
  return {
121
121
  observe: (input) => Promise.resolve(invalidObservation(input) ?? {
122
122
  status: "unavailable",
123
- reason: "no-jev-lane",
123
+ reason: "no-system-one",
124
124
  detector: { ...input.detector, rubricDigest: "" },
125
125
  source: input.source,
126
126
  stored: false,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@yaklabs-ai/plugin-sdk",
3
- "version": "0.13.10",
3
+ "version": "0.14.1",
4
4
  "description": "The Kay plugin SDK — types and helpers for authoring a Kay directory plugin.",
5
5
  "author": "YakLabs",
6
6
  "type": "module",
@@ -17,6 +17,10 @@
17
17
  "types": "./dist/kay-app.d.ts",
18
18
  "default": "./dist/kay-app.js"
19
19
  },
20
+ "./kay-app/session-summary": {
21
+ "types": "./dist/kay-app-session-summary.d.ts",
22
+ "default": "./dist/kay-app-session-summary.js"
23
+ },
20
24
  "./fs": {
21
25
  "types": "./dist/fs.d.ts",
22
26
  "default": "./dist/fs.js"
@@ -29,10 +33,6 @@
29
33
  "types": "./dist/disclosure.d.ts",
30
34
  "default": "./dist/disclosure.js"
31
35
  },
32
- "./jev": {
33
- "types": "./dist/jev.d.ts",
34
- "default": "./dist/jev.js"
35
- },
36
36
  "./signals": {
37
37
  "types": "./dist/signals.d.ts",
38
38
  "default": "./dist/signals.js"
@@ -101,7 +101,7 @@ a plugin you install yourself.
101
101
  ## The SDK resolution contract
102
102
 
103
103
  - Plugin source imports `@bonsai/plugin-sdk/<subpath>` as a **bare specifier**
104
- (`@bonsai/plugin-sdk/kay-agent`, `/kay-agent/testing`, `/kay-app`, `/disclosure`, `/fs`, `/jev`,
104
+ (`@bonsai/plugin-sdk/kay-agent`, `/kay-agent/testing`, `/kay-app`, `/disclosure`, `/fs`,
105
105
  `/signals`, `/phase-shift`, `/time`, `/transcript`, `/transcript-review`, `/agent-conversation`,
106
106
  `/app-data`, `/vendored-mcp`, `/system-one`, `/zod` — only declared exports exist). Take `z`
107
107
  from the SDK (`/kay-agent`, or `/zod` in code a page also loads), never from `zod` itself.
package/dist/jev.d.ts DELETED
@@ -1,203 +0,0 @@
1
- /**
2
- * The `withJev` a host with no Jev lane binds: `use` is never called, no client is ever built,
3
- * and no network is ever touched. It keeps the cancellation contract identical to the real
4
- * wrapper's so a caller's `signal`/`deadlineAt` handling does not change with host composition.
5
- *
6
- * Deliberately here rather than in the runtime: this is the DEFAULT for the SDK's own host
7
- * factory, which cannot import the runtime uphill. The runtime also delegates fallback execution
8
- * here, so both paths share cancellation, deadline enforcement, and cleanup.
9
- */
10
- export declare function createFallbackOnlyWithJev(): WithJev;
11
-
12
- export declare type JevAnswer = JevBoolAnswer | JevChoiceAnswer | JevScoreAnswer;
13
-
14
- /** The answer shape one question gets back. */
15
- export declare type JevAnswerFor<Q> = Q extends JevBoolQuestion ? JevBoolAnswer : Q extends JevChoiceQuestion<infer L> ? JevChoiceAnswer<L> : Q extends JevScoreQuestion ? JevScoreAnswer : never;
16
-
17
- export declare interface JevBoolAnswer {
18
- readonly type: "bool";
19
- /** P(yes), from 0 to 1. */
20
- readonly probability: number;
21
- }
22
-
23
- /** A yes/no question. `criteria` says what yes and what no mean; omit it to leave both open. */
24
- export declare interface JevBoolQuestion {
25
- readonly type: "bool";
26
- readonly instructions: string;
27
- readonly criteria?: {
28
- readonly true: string;
29
- readonly false: string;
30
- };
31
- }
32
-
33
- /**
34
- * The one error `classify` rejects with. It carries a classification, never the provider's own
35
- * message or body: those can echo the request state, and this error reaches logs.
36
- */
37
- export declare class JevCallError extends Error {
38
- readonly transport: JevTransport;
39
- readonly kind: JevCallErrorKind;
40
- /** The final attempt's HTTP status, when a response arrived. */
41
- readonly status: number | undefined;
42
- constructor(init: {
43
- readonly transport: JevTransport;
44
- readonly kind: JevCallErrorKind;
45
- readonly status?: number | undefined;
46
- });
47
- }
48
-
49
- /**
50
- * Why a Jev call failed, as a closed set:
51
- *
52
- * - `http`: the route answered with an error status (`status` says which).
53
- * - `too-large`: the route refused the request's size (413, or a 400 naming the token limit).
54
- * - `network`: no response arrived.
55
- * - `aborted`: the call was cancelled.
56
- * - `invalid-answer`: the route answered, but not with an answer for every asked question.
57
- */
58
- export declare type JevCallErrorKind = "http" | "too-large" | "network" | "aborted" | "invalid-answer";
59
-
60
- export declare interface JevChoiceAnswer<L extends string = string> {
61
- readonly type: "choice";
62
- readonly choice: L;
63
- readonly confidence: number;
64
- /** P(label) for every offered label. */
65
- readonly probabilities: Readonly<Record<L, number>>;
66
- }
67
-
68
- /** A choice among labels. Each label maps to what it means; an empty string leaves it open. */
69
- export declare interface JevChoiceQuestion<L extends string = string> {
70
- readonly type: "choice";
71
- readonly instructions: string;
72
- readonly criteria: Readonly<Record<L, string>>;
73
- }
74
-
75
- /** One answered request: every asked question has an answer of its own kind. */
76
- export declare interface JevClassification<Q extends JevQuestions = JevQuestions> {
77
- /** The Jev model the host asked. */
78
- readonly model: string;
79
- readonly answers: {
80
- readonly [K in keyof Q]: JevAnswerFor<Q[K]>;
81
- };
82
- /** Token counts, when the route reported them. */
83
- readonly usage?: {
84
- readonly inputTokens: number;
85
- readonly outputTokens: number;
86
- };
87
- }
88
-
89
- export declare interface JevClassifyRequest<Q extends JevQuestions = JevQuestions> {
90
- readonly state: JevState;
91
- readonly questions: Q;
92
- }
93
-
94
- /**
95
- * The Jev client a `use` body receives. `classify` either resolves with an answer for every
96
- * asked question, each of its question's kind, or rejects with a {@link JevCallError}; it never
97
- * resolves with a partial or substituted answer.
98
- */
99
- export declare interface JevClient {
100
- classify<const Q extends JevQuestions>(request: JevClassifyRequest<Q>, options?: {
101
- readonly signal?: AbortSignal;
102
- }): Promise<JevClassification<Q>>;
103
- }
104
-
105
- export declare type JevQuestion = JevBoolQuestion | JevChoiceQuestion | JevScoreQuestion;
106
-
107
- /** A rubric: questions keyed by the name each answer comes back under. */
108
- export declare type JevQuestions = Readonly<Record<string, JevQuestion>>;
109
-
110
- export declare interface JevScoreAnswer {
111
- readonly type: "score";
112
- /** The expected score, from 0 to the number of rungs minus one. */
113
- readonly score: number;
114
- readonly confidence: number;
115
- }
116
-
117
- /** A score over ordered rungs: the first criterion scores 0, the next 1, and so on. */
118
- export declare interface JevScoreQuestion {
119
- readonly type: "score";
120
- readonly instructions: string;
121
- readonly criteria: readonly string[];
122
- }
123
-
124
- /**
125
- * ---
126
- * responsibility: The plugin-facing CONTRACT for Jev typed-decision inference — the shape of
127
- * `api.withJev` on both plugin SDK targets, the {@link JevClient} a `use` body receives, the
128
- * question and answer vocabulary it speaks, and the fallback-only implementation a host
129
- * without a Jev lane binds.
130
- * owns:
131
- * - {@link WithJev}, {@link WithJevOptions}, {@link createFallbackOnlyWithJev}.
132
- * - {@link JevClient}, the {@link JevQuestion} and {@link JevAnswer} vocabulary, and
133
- * {@link JevCallError}.
134
- * does_not_own:
135
- * - The wire. The host serves `classify` over whichever route the user's Jev provider order
136
- * picks; a plugin never sees a vendor client, a vendor type, or a route.
137
- * - Credential resolution, the `jev.use` decision, the Jev-branch budget, or usage accounting.
138
- * Those are host-side (`@bonsai/agent-runtime`'s `kay/jev/`).
139
- * ---
140
- *
141
- * The vocabulary is Bonsai's own (SDK 0.12.0). Before it, `use` received TypeSafe's `TypeSafeClient`
142
- * and plugins coded against a vendor's types. It follows pi's classifier contract, which the host
143
- * runs Jev through: a yes/no question is `bool` and answers a `probability`, every instruction and
144
- * criterion is text, and the state is a JSON object.
145
- */
146
- /**
147
- * The state a rubric reads: a JSON object, never text or an array. Every value must survive
148
- * `JSON.stringify` unchanged (no functions or class instances), because it is sent as JSON.
149
- * Typed as `object` so a state declared as an interface fits without an index signature.
150
- */
151
- export declare type JevState = object;
152
-
153
- /** The route a Jev call took: the user's own TypeSafe key, or Bonsai's hosted gateway. */
154
- export declare type JevTransport = "direct" | "hosted";
155
-
156
- /**
157
- * Run `use` against a live Jev client, falling back to `fallback` whenever Jev cannot serve the
158
- * call. The wrapper exists so a feature can ASK for a typed decision without ever depending on
159
- * one: `fallback` is required, and it runs whenever no provider in the user's Jev provider
160
- * order holds a usable credential, the user has not granted `jev.use`, the branch exceeds its budget, `use` throws, or
161
- * `use` declines by returning `undefined`. With valid options, this rejects on an explicit
162
- * `signal` abort, reaching `deadlineAt`, or `fallback` itself throwing.
163
- *
164
- * ALWAYS PRESENT on the plugin API, on every host. A host that composed no Jev lane binds
165
- * {@link createFallbackOnlyWithJev}, so a caller never branches on availability — branching is
166
- * exactly how a fallback gets skipped.
167
- *
168
- * `jev` is a {@link JevClient} on the host's Jev model. It is valid only for the duration of
169
- * the callback: a reference retained past `use`'s scope is refused at the transport, and an
170
- * in-flight request is aborted when the call stops waiting.
171
- * The callback itself is ABANDONED, not interrupted — a host cannot stop arbitrary JavaScript
172
- * that is already running, so `use` must not perform side effects it would mind completing
173
- * unobserved. The same applies to a running fallback: abort/deadline stops waiting for it but
174
- * cannot interrupt its JavaScript.
175
- */
176
- export declare type WithJev = <T>(
177
- /** Return `undefined` to decline (the fallback runs). A feature whose real result can itself be
178
- * `undefined` should return `null` or its own wrapper type instead. */
179
- use: (jev: JevClient) => T | undefined | PromiseLike<T | undefined>,
180
- /** Required. The behaviour the feature has without Jev. */
181
- fallback: () => T | PromiseLike<T>, options?: WithJevOptions) => Promise<T>;
182
-
183
- /** Per-call knobs for {@link WithJev}. Every field is optional; the host applies its own default
184
- * budget when none is given, so the Jev branch is never unbounded. */
185
- export declare interface WithJevOptions {
186
- /**
187
- * Explicit cancellation. Always propagates as a rejection; never substituted with `fallback`,
188
- * because an aborted call means "stop", not "use the cheaper path".
189
- */
190
- readonly signal?: AbortSignal;
191
- /** Bounds the Jev branch alone, measured from the call. */
192
- readonly timeoutMs?: number;
193
- /**
194
- * Absolute epoch-ms hard deadline for the WHOLE call, `fallback` included. A deadline already
195
- * passed rejects (like `signal`); one still ahead derives the Jev branch's budget from it and
196
- * keeps a small reserve so `fallback` has a window to run.
197
- */
198
- readonly deadlineAt?: number;
199
- /** Attribution slug for host usage accounting. Never sent to Jev. */
200
- readonly purpose?: string;
201
- }
202
-
203
- export { }
package/dist/jev.js DELETED
@@ -1,77 +0,0 @@
1
- // packages/plugin-sdk/dist/jev.js
2
- var JevCallError = class extends Error {
3
- transport;
4
- kind;
5
- /** The final attempt's HTTP status, when a response arrived. */
6
- status;
7
- constructor(init) {
8
- super(`Jev call failed on the ${init.transport} route: ${init.kind}${init.status === void 0 ? "" : ` (HTTP ${init.status})`}.`);
9
- this.name = "JevCallError";
10
- this.transport = init.transport;
11
- this.kind = init.kind;
12
- this.status = init.status;
13
- }
14
- };
15
- function createFallbackOnlyWithJev() {
16
- return async (_use, fallback, options = {}) => {
17
- if (typeof fallback !== "function") {
18
- throw new TypeError("withJev requires a `fallback` function as its second argument.");
19
- }
20
- const { signal, deadlineAt } = options;
21
- if (deadlineAt !== void 0 && !Number.isFinite(deadlineAt)) {
22
- throw new TypeError("withJev's `deadlineAt` must be a finite epoch-ms timestamp.");
23
- }
24
- const assertWithinBoundaries = () => {
25
- if (signal?.aborted === true) {
26
- throw signal.reason ?? new DOMException("Aborted", "AbortError");
27
- }
28
- if (deadlineAt !== void 0 && Date.now() >= deadlineAt) {
29
- throw new Error("withJev's deadline has passed.");
30
- }
31
- };
32
- assertWithinBoundaries();
33
- let timer;
34
- let onAbort;
35
- const stopped = new Promise((_resolve, reject) => {
36
- if (signal !== void 0) {
37
- onAbort = () => reject(signal.reason ?? new DOMException("Aborted", "AbortError"));
38
- signal.addEventListener("abort", onAbort, { once: true });
39
- }
40
- if (deadlineAt !== void 0) {
41
- const checkDeadline = () => {
42
- const remaining = deadlineAt - Date.now();
43
- if (remaining <= 0) {
44
- reject(new Error("withJev's deadline has passed."));
45
- } else {
46
- timer = setTimeout(checkDeadline, Math.min(remaining, 2147483647));
47
- }
48
- };
49
- checkDeadline();
50
- }
51
- });
52
- try {
53
- const result = await Promise.race([
54
- Promise.resolve().then(() => {
55
- assertWithinBoundaries();
56
- return fallback();
57
- }),
58
- stopped
59
- ]);
60
- assertWithinBoundaries();
61
- return result;
62
- } catch (error) {
63
- assertWithinBoundaries();
64
- throw error;
65
- } finally {
66
- if (timer !== void 0)
67
- clearTimeout(timer);
68
- if (signal !== void 0 && onAbort !== void 0) {
69
- signal.removeEventListener("abort", onAbort);
70
- }
71
- }
72
- };
73
- }
74
- export {
75
- JevCallError,
76
- createFallbackOnlyWithJev
77
- };