@deepwatch/dsh-contracts 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 +21 -0
- package/README.md +77 -0
- package/lib/approval.d.ts +114 -0
- package/lib/approval.js +108 -0
- package/lib/bindings.d.ts +248 -0
- package/lib/bindings.js +333 -0
- package/lib/digests.d.ts +77 -0
- package/lib/digests.js +103 -0
- package/lib/execution.d.ts +259 -0
- package/lib/execution.js +213 -0
- package/lib/failures.d.ts +145 -0
- package/lib/failures.js +204 -0
- package/lib/identity.d.ts +54 -0
- package/lib/identity.js +74 -0
- package/lib/index.d.ts +382 -0
- package/lib/index.js +79 -0
- package/lib/language.d.ts +158 -0
- package/lib/language.js +202 -0
- package/lib/paths.d.ts +194 -0
- package/lib/paths.js +286 -0
- package/lib/presentation.d.ts +90 -0
- package/lib/presentation.js +158 -0
- package/lib/query/validate.d.ts +74 -0
- package/lib/query/validate.js +243 -0
- package/lib/query/wire.d.ts +409 -0
- package/lib/query/wire.js +37 -0
- package/lib/query.d.ts +362 -0
- package/lib/query.js +431 -0
- package/lib/readiness.d.ts +198 -0
- package/lib/readiness.js +209 -0
- package/lib/workspace.d.ts +141 -0
- package/lib/workspace.js +158 -0
- package/package.json +60 -0
|
@@ -0,0 +1,409 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The read plane's wire DTOs, and nothing else.
|
|
3
|
+
*
|
|
4
|
+
* Typert builds a type graph over a Remote's signature and emits a strict
|
|
5
|
+
* codec from it. That graph is only as tractable as the types it reaches, so
|
|
6
|
+
* this module is deliberately the smallest thing that can describe the wire:
|
|
7
|
+
* concrete, JSON-representable, and free of the machinery that makes the
|
|
8
|
+
* runtime module useful to write against.
|
|
9
|
+
*
|
|
10
|
+
* What is banned here, and why each one matters to a generated schema:
|
|
11
|
+
*
|
|
12
|
+
* - `unknown` and `any` — nothing to describe, so the analyzer has nothing
|
|
13
|
+
* to emit and fails rather than reporting an empty model.
|
|
14
|
+
* - an open `Record<string, unknown>` — a schema that validates anything is
|
|
15
|
+
* a schema that validates nothing.
|
|
16
|
+
* - generics at the boundary — `QuerySnapshot<Item>` is pleasant to write
|
|
17
|
+
* and forces the analyzer to instantiate a type it cannot name.
|
|
18
|
+
* - parser functions — they take `unknown` by their nature.
|
|
19
|
+
* - Host classes, Node types, filesystem types — none of them cross a wire.
|
|
20
|
+
*
|
|
21
|
+
* There is exactly one result envelope, and it is not here. Typert wraps every
|
|
22
|
+
* invocation in `RemoteResult<T>`, which carries transport, Gateway,
|
|
23
|
+
* cancellation and codec failure. What this module defines is the *domain*
|
|
24
|
+
* outcome inside that envelope: the answers a surface has to render
|
|
25
|
+
* differently, like a cursor that has expired or an index that is still
|
|
26
|
+
* rebuilding. Nesting a second `WatchResult` inside `RemoteResult` would give
|
|
27
|
+
* two overlapping vocabularies for failure and no rule about which one owns a
|
|
28
|
+
* given case.
|
|
29
|
+
*
|
|
30
|
+
* Browser-safe: no Node imports, no runtime identity, nothing a client bundle
|
|
31
|
+
* would have to deduplicate.
|
|
32
|
+
*
|
|
33
|
+
* @module @deepwatch/dsh-contracts/query/wire
|
|
34
|
+
*/
|
|
35
|
+
/** The read-plane contract version a wire message declares. */
|
|
36
|
+
export declare const WATCH_QUERY_WIRE_VERSION = 1;
|
|
37
|
+
/** What a Library search asks for. */
|
|
38
|
+
export interface LibrarySearchRequest {
|
|
39
|
+
/** The contract version the caller speaks. */
|
|
40
|
+
readonly protocol: number;
|
|
41
|
+
/** Correlates the answer, and is what a cancellation names. */
|
|
42
|
+
readonly requestId: string;
|
|
43
|
+
/** Free text. Every term must match; the host decides how it tokenises. */
|
|
44
|
+
readonly query: string;
|
|
45
|
+
/** Restrict to these modalities. Empty means all of them. */
|
|
46
|
+
readonly modalities: readonly string[];
|
|
47
|
+
/** How many records to return. The host clamps it. */
|
|
48
|
+
readonly limit: number;
|
|
49
|
+
/** Continues an earlier snapshot, or null to start one. */
|
|
50
|
+
readonly cursor: string | null;
|
|
51
|
+
/** How long the caller will wait. The host clamps it. */
|
|
52
|
+
readonly deadlineMs: number;
|
|
53
|
+
}
|
|
54
|
+
/** One Library record, by id. */
|
|
55
|
+
export interface LibraryGetRequest {
|
|
56
|
+
readonly protocol: number;
|
|
57
|
+
readonly requestId: string;
|
|
58
|
+
/** An identifier, never a path: no separator, no colon, no dot-dot. */
|
|
59
|
+
readonly recordId: string;
|
|
60
|
+
readonly deadlineMs: number;
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* One record, as the surface renders it.
|
|
64
|
+
*
|
|
65
|
+
* The provenance fields are the persisted ones rather than anything derived.
|
|
66
|
+
* `observedAt` in particular is the record's own timestamp: an earlier version
|
|
67
|
+
* of this shape computed a `capturedAt` from a temporal range's `startMs`,
|
|
68
|
+
* which is a media-relative offset, so a clip beginning at zero was rendered
|
|
69
|
+
* as January 1970.
|
|
70
|
+
*/
|
|
71
|
+
export interface LibraryRecord {
|
|
72
|
+
readonly recordId: string;
|
|
73
|
+
readonly revisionId: string;
|
|
74
|
+
readonly title: string;
|
|
75
|
+
readonly modality: string;
|
|
76
|
+
/** When the source was observed. An ISO-8601 instant, or null if unknown. */
|
|
77
|
+
readonly observedAt: string | null;
|
|
78
|
+
/** Which source produced it. */
|
|
79
|
+
readonly source: string;
|
|
80
|
+
/** The run it belongs to, when it belongs to one. */
|
|
81
|
+
readonly runId: string | null;
|
|
82
|
+
/** Core's verdict, when Core minted one. Never invented here. */
|
|
83
|
+
readonly verdict: string | null;
|
|
84
|
+
readonly tags: readonly string[];
|
|
85
|
+
/** The evidence this record points at. Never a filesystem path. */
|
|
86
|
+
readonly evidenceIds: readonly string[];
|
|
87
|
+
/** False when a newer revision of the same source exists. */
|
|
88
|
+
readonly current: boolean;
|
|
89
|
+
}
|
|
90
|
+
/**
|
|
91
|
+
* Where a hit sits inside its source, on that source's own clock.
|
|
92
|
+
*
|
|
93
|
+
* Media-relative milliseconds, deliberately not an instant. A range and a
|
|
94
|
+
* timestamp are different measurements and converting one to the other is how
|
|
95
|
+
* a zero offset becomes 1970.
|
|
96
|
+
*/
|
|
97
|
+
export interface MediaRange {
|
|
98
|
+
readonly startMs: number;
|
|
99
|
+
readonly endMs: number;
|
|
100
|
+
}
|
|
101
|
+
/** How complete an answer is, said out loud rather than implied by emptiness. */
|
|
102
|
+
export type LibraryIndexState = 'ready' | 'rebuilding' | 'stale' | 'empty';
|
|
103
|
+
/** A successful Library search. */
|
|
104
|
+
export interface LibrarySearchPage {
|
|
105
|
+
readonly outcome: 'page';
|
|
106
|
+
readonly protocol: number;
|
|
107
|
+
readonly requestId: string;
|
|
108
|
+
/** The host revision this page was produced from. */
|
|
109
|
+
readonly revision: number;
|
|
110
|
+
/**
|
|
111
|
+
* Which index generation answered.
|
|
112
|
+
*
|
|
113
|
+
* Explicit rather than left implicit inside `revision`. A surface that has
|
|
114
|
+
* just asked for a refresh needs to know whether the page in front of it
|
|
115
|
+
* came from the new index or the old one, and recovering that by arithmetic
|
|
116
|
+
* on a packed number is the kind of thing a caller gets wrong once.
|
|
117
|
+
*/
|
|
118
|
+
readonly generation: number;
|
|
119
|
+
readonly records: readonly LibraryRecord[];
|
|
120
|
+
/** Non-null when more remains; pass it back as `cursor`. */
|
|
121
|
+
readonly nextCursor: string | null;
|
|
122
|
+
/** How many records match in total, not merely on this page. */
|
|
123
|
+
readonly total: number;
|
|
124
|
+
readonly indexState: LibraryIndexState;
|
|
125
|
+
}
|
|
126
|
+
/** A single record, found. */
|
|
127
|
+
export interface LibraryRecordFound {
|
|
128
|
+
readonly outcome: 'record';
|
|
129
|
+
readonly protocol: number;
|
|
130
|
+
readonly requestId: string;
|
|
131
|
+
readonly revision: number;
|
|
132
|
+
readonly record: LibraryRecord;
|
|
133
|
+
}
|
|
134
|
+
/** A single record, absent. Not a failure: the question had an answer. */
|
|
135
|
+
export interface LibraryRecordAbsent {
|
|
136
|
+
readonly outcome: 'absent';
|
|
137
|
+
readonly protocol: number;
|
|
138
|
+
readonly requestId: string;
|
|
139
|
+
readonly revision: number;
|
|
140
|
+
readonly recordId: string;
|
|
141
|
+
}
|
|
142
|
+
/**
|
|
143
|
+
* The cursor names a snapshot this host no longer holds.
|
|
144
|
+
*
|
|
145
|
+
* Bounded fields on purpose. The surface needs to say "your page is gone,
|
|
146
|
+
* search again" and nothing here helps it say anything more specific, so
|
|
147
|
+
* nothing here invites a caller to depend on more.
|
|
148
|
+
*/
|
|
149
|
+
export interface LibraryCursorExpired {
|
|
150
|
+
readonly outcome: 'cursor_expired';
|
|
151
|
+
readonly protocol: number;
|
|
152
|
+
readonly requestId: string;
|
|
153
|
+
/** The revision the host is on now, so a surface can say what changed. */
|
|
154
|
+
readonly revision: number;
|
|
155
|
+
}
|
|
156
|
+
/** The request did not satisfy the contract. Nothing was read. */
|
|
157
|
+
export interface LibraryRequestRejected {
|
|
158
|
+
readonly outcome: 'rejected';
|
|
159
|
+
readonly protocol: number;
|
|
160
|
+
readonly requestId: string;
|
|
161
|
+
/** Which rule the request broke. A closed set, not free text. */
|
|
162
|
+
readonly reason: 'protocol_mismatch' | 'malformed_request' | 'request_too_large' | 'identifier_invalid';
|
|
163
|
+
/** Which field, when one field is responsible. */
|
|
164
|
+
readonly field: string | null;
|
|
165
|
+
}
|
|
166
|
+
/** The host could not answer inside the deadline it was given. */
|
|
167
|
+
export interface LibraryDeadlineExceeded {
|
|
168
|
+
readonly outcome: 'deadline_exceeded';
|
|
169
|
+
readonly protocol: number;
|
|
170
|
+
readonly requestId: string;
|
|
171
|
+
/** The deadline that elapsed, so the surface can offer a longer one. */
|
|
172
|
+
readonly deadlineMs: number;
|
|
173
|
+
}
|
|
174
|
+
/**
|
|
175
|
+
* What `librarySearch` answers.
|
|
176
|
+
*
|
|
177
|
+
* A discriminated union on `outcome`, so a surface switches on one field and
|
|
178
|
+
* the compiler tells it when a case is unhandled.
|
|
179
|
+
*/
|
|
180
|
+
export type LibrarySearchResponse = LibrarySearchPage | LibraryCursorExpired | LibraryRequestRejected | LibraryDeadlineExceeded;
|
|
181
|
+
/** What `libraryGet` answers. */
|
|
182
|
+
export type LibraryGetResponse = LibraryRecordFound | LibraryRecordAbsent | LibraryRequestRejected | LibraryDeadlineExceeded;
|
|
183
|
+
/**
|
|
184
|
+
* Ask the host to read its roots again and build a new index generation.
|
|
185
|
+
*
|
|
186
|
+
* An explicit operation rather than a flag on a search, because rebuilding is
|
|
187
|
+
* a side effect and a search is not. Folding it into `librarySearch` would
|
|
188
|
+
* make every keystroke a potential re-read of the corpus, and would leave a
|
|
189
|
+
* caller with no way to say "answer from what you have" — which is what a
|
|
190
|
+
* search means.
|
|
191
|
+
*/
|
|
192
|
+
export interface LibraryRefreshRequest {
|
|
193
|
+
readonly protocol: number;
|
|
194
|
+
readonly requestId: string;
|
|
195
|
+
/**
|
|
196
|
+
* How long the caller will wait.
|
|
197
|
+
*
|
|
198
|
+
* A caller that stops waiting does not stop the rebuild on its own: the work
|
|
199
|
+
* belongs to the host and other callers may be waiting on the same one. What
|
|
200
|
+
* ends it early is every waiter withdrawing, which the host tracks.
|
|
201
|
+
*/
|
|
202
|
+
readonly deadlineMs: number;
|
|
203
|
+
}
|
|
204
|
+
/**
|
|
205
|
+
* One index generation, described.
|
|
206
|
+
*
|
|
207
|
+
* `generation` increments only when a rebuild produced a healthy index that
|
|
208
|
+
* was swapped into service, so a caller comparing it across two answers learns
|
|
209
|
+
* whether what it is reading changed underneath it.
|
|
210
|
+
*/
|
|
211
|
+
export interface LibraryIndexGeneration {
|
|
212
|
+
readonly generation: number;
|
|
213
|
+
/** ISO-8601. When the rebuild that produced this generation began. */
|
|
214
|
+
readonly startedAt: string;
|
|
215
|
+
/** ISO-8601, or null while a rebuild is still running. */
|
|
216
|
+
readonly completedAt: string | null;
|
|
217
|
+
/** Roots read. */
|
|
218
|
+
readonly sourceCount: number;
|
|
219
|
+
/** Records indexed. */
|
|
220
|
+
readonly recordCount: number;
|
|
221
|
+
readonly indexState: LibraryIndexState;
|
|
222
|
+
}
|
|
223
|
+
/** The rebuild finished and its result is now what searches answer from. */
|
|
224
|
+
export interface LibraryRefreshed {
|
|
225
|
+
readonly outcome: 'refreshed';
|
|
226
|
+
readonly protocol: number;
|
|
227
|
+
readonly requestId: string;
|
|
228
|
+
readonly index: LibraryIndexGeneration;
|
|
229
|
+
/** Files the host declined to read, by name. Never a path. */
|
|
230
|
+
readonly skipped: readonly string[];
|
|
231
|
+
}
|
|
232
|
+
/**
|
|
233
|
+
* Every waiter withdrew before the rebuild finished, so it was abandoned.
|
|
234
|
+
*
|
|
235
|
+
* The generation named here is the one still in service — a cancelled rebuild
|
|
236
|
+
* never replaces a healthy index.
|
|
237
|
+
*/
|
|
238
|
+
export interface LibraryRefreshCancelled {
|
|
239
|
+
readonly outcome: 'refresh_cancelled';
|
|
240
|
+
readonly protocol: number;
|
|
241
|
+
readonly requestId: string;
|
|
242
|
+
readonly index: LibraryIndexGeneration;
|
|
243
|
+
}
|
|
244
|
+
/**
|
|
245
|
+
* The rebuild failed, and the previous generation is still in service.
|
|
246
|
+
*
|
|
247
|
+
* Reported rather than thrown: a failed refresh leaves a working Library, and
|
|
248
|
+
* a surface has to be able to say both things at once.
|
|
249
|
+
*/
|
|
250
|
+
export interface LibraryRefreshFailed {
|
|
251
|
+
readonly outcome: 'refresh_failed';
|
|
252
|
+
readonly protocol: number;
|
|
253
|
+
readonly requestId: string;
|
|
254
|
+
/** What went wrong, in words. Never a path and never a stack. */
|
|
255
|
+
readonly reason: string;
|
|
256
|
+
readonly index: LibraryIndexGeneration;
|
|
257
|
+
}
|
|
258
|
+
/** What `libraryRefresh` answers. */
|
|
259
|
+
export type LibraryRefreshResponse = LibraryRefreshed | LibraryRefreshCancelled | LibraryRefreshFailed | LibraryRequestRejected | LibraryDeadlineExceeded;
|
|
260
|
+
/**
|
|
261
|
+
* Ask the Host what Watch Core is doing right now.
|
|
262
|
+
*
|
|
263
|
+
* This method exists because Diagnostics had no way to find out. The panel
|
|
264
|
+
* rendered "Watch Core — Connected over stdio" as a green chip and a version
|
|
265
|
+
* beside it, and both were literals typed into a component: the read plane
|
|
266
|
+
* carried Library reads and nothing else, so the one screen whose job is to
|
|
267
|
+
* report the state of the engine was the one screen with no channel to it.
|
|
268
|
+
*
|
|
269
|
+
* The interim fix was to say "not read from here", which was honest and is not
|
|
270
|
+
* a product. This is the channel.
|
|
271
|
+
*/
|
|
272
|
+
export interface CoreHealthRequest {
|
|
273
|
+
readonly protocol: number;
|
|
274
|
+
readonly requestId: string;
|
|
275
|
+
readonly deadlineMs: number;
|
|
276
|
+
}
|
|
277
|
+
/**
|
|
278
|
+
* Why the product is in the state it is in, in one word a screen can act on.
|
|
279
|
+
*
|
|
280
|
+
* Mirrors `BridgeBlocker`. Restated here rather than imported because this
|
|
281
|
+
* union crosses a generated codec, and a codec generated from an alias to
|
|
282
|
+
* another module's type is a codec that stops matching when that module moves.
|
|
283
|
+
*/
|
|
284
|
+
export type CoreBlocker = 'connected' | 'core_missing' | 'bridge_surface_missing' | 'handshake_failed' | 'protocol_mismatch' | 'contract_mismatch' | 'core_crashed' | 'core_timeout' | 'circuit_open' | 'test_only_mock';
|
|
285
|
+
/** How many capabilities are in each state, so a screen need not count. */
|
|
286
|
+
export interface CapabilityTally {
|
|
287
|
+
/** Usable now: the engine reported them implemented or machine-tested. */
|
|
288
|
+
readonly ready: number;
|
|
289
|
+
/** Known to be unusable here, with a reason the report carries. */
|
|
290
|
+
readonly unavailable: number;
|
|
291
|
+
/** Present but reduced — a dependency probed, or a contract family drifted. */
|
|
292
|
+
readonly degraded: number;
|
|
293
|
+
/** Never checked. Not the same as unavailable. */
|
|
294
|
+
readonly unknown: number;
|
|
295
|
+
}
|
|
296
|
+
/** One Core capability, including why it is or is not usable on this machine. */
|
|
297
|
+
export interface CapabilityHealthDetail {
|
|
298
|
+
readonly capabilityId: string;
|
|
299
|
+
/** Core's evidence level; kept separate from whether contract negotiation made it usable. */
|
|
300
|
+
readonly status: 'implemented' | 'machine_tested' | 'probed' | 'unavailable' | 'not_tested';
|
|
301
|
+
readonly usable: boolean;
|
|
302
|
+
readonly missing: readonly string[];
|
|
303
|
+
readonly fixes: readonly string[];
|
|
304
|
+
readonly lastCheckedAt: string | null;
|
|
305
|
+
}
|
|
306
|
+
/**
|
|
307
|
+
* What the Host observed about Watch Core, at the moment it was asked.
|
|
308
|
+
*
|
|
309
|
+
* Every field is read from the running Bridge. There is no field here a
|
|
310
|
+
* component may substitute a default for: a value that could not be read is
|
|
311
|
+
* `null`, and a screen renders that as "not reported" rather than as a
|
|
312
|
+
* plausible number.
|
|
313
|
+
*/
|
|
314
|
+
export interface CoreHealthReport {
|
|
315
|
+
readonly outcome: 'core_health';
|
|
316
|
+
readonly protocol: number;
|
|
317
|
+
readonly requestId: string;
|
|
318
|
+
/** `disconnected` | `connecting` | `ready` | `degraded` | `failed`. */
|
|
319
|
+
readonly phase: string;
|
|
320
|
+
readonly blocker: CoreBlocker;
|
|
321
|
+
/** The engine's own version string. Null until a handshake has completed. */
|
|
322
|
+
readonly coreVersion: string | null;
|
|
323
|
+
readonly coreBuild: string | null;
|
|
324
|
+
/** The negotiated protocol, and the range Core said it supports. */
|
|
325
|
+
readonly protocolVersion: number | null;
|
|
326
|
+
readonly protocolMin: number | null;
|
|
327
|
+
/** Which backend is actually in use. Null before the first attempt. */
|
|
328
|
+
readonly transport: string | null;
|
|
329
|
+
/**
|
|
330
|
+
* True only when the backend is the in-process fixture.
|
|
331
|
+
*
|
|
332
|
+
* Every surface that could present data as observed reads this first. It is
|
|
333
|
+
* carried separately from `transport` so that adding a second fake backend
|
|
334
|
+
* cannot quietly bypass the check.
|
|
335
|
+
*/
|
|
336
|
+
readonly isTestOnlyMock: boolean;
|
|
337
|
+
/** Whether Core's contract digests matched this build's. */
|
|
338
|
+
readonly contractsMatch: boolean;
|
|
339
|
+
/** Families that disagreed, empty when they match. */
|
|
340
|
+
readonly contractDrift: readonly string[];
|
|
341
|
+
/** ISO-8601 of the last handshake that completed, null if none ever has. */
|
|
342
|
+
readonly lastHandshakeAt: string | null;
|
|
343
|
+
/** Core processes started this session. A climbing number is a crash loop. */
|
|
344
|
+
readonly restartCount: number;
|
|
345
|
+
readonly capabilities: CapabilityTally;
|
|
346
|
+
/** Per-capability truth used by readiness surfaces; never reconstructed from the tally. */
|
|
347
|
+
readonly capabilityDetails: readonly CapabilityHealthDetail[];
|
|
348
|
+
/** What to do about `blocker`, in words. Empty only when connected. */
|
|
349
|
+
readonly fix: string;
|
|
350
|
+
}
|
|
351
|
+
/** What `coreHealth` answers. */
|
|
352
|
+
export type CoreHealthResponse = CoreHealthReport | LibraryRequestRejected | LibraryDeadlineExceeded;
|
|
353
|
+
/** A user-triggered, bounded one-token request against one exact binding. */
|
|
354
|
+
export interface ProviderTestRequest {
|
|
355
|
+
readonly protocol: number;
|
|
356
|
+
readonly requestId: string;
|
|
357
|
+
readonly deadlineMs: number;
|
|
358
|
+
readonly provider: string;
|
|
359
|
+
readonly model: string;
|
|
360
|
+
}
|
|
361
|
+
/**
|
|
362
|
+
* What a screen asks the Host about a route it has already been told about.
|
|
363
|
+
*
|
|
364
|
+
* A read, not a test: it spends no provider request and reaches no network. It
|
|
365
|
+
* exists because the browser half used to hold its own memory of a provider
|
|
366
|
+
* test, which is a claim about a Host it cannot see — the Host may have
|
|
367
|
+
* restarted, or the route's configuration may have been edited in another tab,
|
|
368
|
+
* and the badge would still say tested over a route the Host would refuse.
|
|
369
|
+
*/
|
|
370
|
+
export interface RouteReadinessRequest {
|
|
371
|
+
readonly protocol: number;
|
|
372
|
+
readonly requestId: string;
|
|
373
|
+
readonly deadlineMs: number;
|
|
374
|
+
readonly provider: string;
|
|
375
|
+
readonly model: string;
|
|
376
|
+
}
|
|
377
|
+
/**
|
|
378
|
+
* The Host's own verdict, and nothing that could identify a credential.
|
|
379
|
+
*
|
|
380
|
+
* `reason` is separate from `proved` because the two states that are not
|
|
381
|
+
* proved need opposite actions: a route nobody has tested needs the test, and
|
|
382
|
+
* a route whose configuration moved since the test needs somebody to look at
|
|
383
|
+
* what moved before spending another request on it.
|
|
384
|
+
*/
|
|
385
|
+
export interface RouteReadinessReport {
|
|
386
|
+
readonly outcome: 'route_readiness';
|
|
387
|
+
readonly protocol: number;
|
|
388
|
+
readonly requestId: string;
|
|
389
|
+
readonly provider: string;
|
|
390
|
+
readonly model: string;
|
|
391
|
+
/** Whether the Host would serve this route to a turn right now. */
|
|
392
|
+
readonly proved: boolean;
|
|
393
|
+
readonly reason: 'proved' | 'never_tested' | 'configuration_changed' | 'unreadable';
|
|
394
|
+
}
|
|
395
|
+
/** What `routeReadiness` answers. */
|
|
396
|
+
export type RouteReadinessResponse = RouteReadinessReport | LibraryRequestRejected | LibraryDeadlineExceeded;
|
|
397
|
+
/** Only provider-neutral facts cross back; provider output and credentials never do. */
|
|
398
|
+
export interface ProviderTestResponse {
|
|
399
|
+
readonly outcome: 'provider_test';
|
|
400
|
+
readonly protocol: number;
|
|
401
|
+
readonly requestId: string;
|
|
402
|
+
readonly provider: string;
|
|
403
|
+
readonly model: string;
|
|
404
|
+
readonly ok: boolean;
|
|
405
|
+
readonly credential: 'configured_unverified' | 'verified' | 'rejected';
|
|
406
|
+
readonly reachability: 'reachable' | 'unreachable' | 'rate_limited' | 'unauthorized';
|
|
407
|
+
readonly message: string;
|
|
408
|
+
}
|
|
409
|
+
//# sourceMappingURL=wire.d.ts.map
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The read plane's wire DTOs, and nothing else.
|
|
3
|
+
*
|
|
4
|
+
* Typert builds a type graph over a Remote's signature and emits a strict
|
|
5
|
+
* codec from it. That graph is only as tractable as the types it reaches, so
|
|
6
|
+
* this module is deliberately the smallest thing that can describe the wire:
|
|
7
|
+
* concrete, JSON-representable, and free of the machinery that makes the
|
|
8
|
+
* runtime module useful to write against.
|
|
9
|
+
*
|
|
10
|
+
* What is banned here, and why each one matters to a generated schema:
|
|
11
|
+
*
|
|
12
|
+
* - `unknown` and `any` — nothing to describe, so the analyzer has nothing
|
|
13
|
+
* to emit and fails rather than reporting an empty model.
|
|
14
|
+
* - an open `Record<string, unknown>` — a schema that validates anything is
|
|
15
|
+
* a schema that validates nothing.
|
|
16
|
+
* - generics at the boundary — `QuerySnapshot<Item>` is pleasant to write
|
|
17
|
+
* and forces the analyzer to instantiate a type it cannot name.
|
|
18
|
+
* - parser functions — they take `unknown` by their nature.
|
|
19
|
+
* - Host classes, Node types, filesystem types — none of them cross a wire.
|
|
20
|
+
*
|
|
21
|
+
* There is exactly one result envelope, and it is not here. Typert wraps every
|
|
22
|
+
* invocation in `RemoteResult<T>`, which carries transport, Gateway,
|
|
23
|
+
* cancellation and codec failure. What this module defines is the *domain*
|
|
24
|
+
* outcome inside that envelope: the answers a surface has to render
|
|
25
|
+
* differently, like a cursor that has expired or an index that is still
|
|
26
|
+
* rebuilding. Nesting a second `WatchResult` inside `RemoteResult` would give
|
|
27
|
+
* two overlapping vocabularies for failure and no rule about which one owns a
|
|
28
|
+
* given case.
|
|
29
|
+
*
|
|
30
|
+
* Browser-safe: no Node imports, no runtime identity, nothing a client bundle
|
|
31
|
+
* would have to deduplicate.
|
|
32
|
+
*
|
|
33
|
+
* @module @deepwatch/dsh-contracts/query/wire
|
|
34
|
+
*/
|
|
35
|
+
/** The read-plane contract version a wire message declares. */
|
|
36
|
+
export const WATCH_QUERY_WIRE_VERSION = 1;
|
|
37
|
+
//# sourceMappingURL=wire.js.map
|