@defjs/core 0.3.3 → 0.4.0-beta.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.
Files changed (6) hide show
  1. package/LICENSE +1 -1
  2. package/README.md +85 -2
  3. package/index.d.ts +1645 -189
  4. package/index.js +5638 -852
  5. package/index.min.js +44 -1
  6. package/package.json +14 -12
package/index.d.ts CHANGED
@@ -1,194 +1,1650 @@
1
- declare const HTTP_CONTEXT_TOKEN: unique symbol;
2
- export type HttpContextToken<T> = (() => T) & {
3
- readonly [HTTP_CONTEXT_TOKEN]: () => T;
4
- };
5
- export declare function makeHttpContextToken<T>(defaultValue: () => T): HttpContextToken<T>;
6
- export declare function isHttpContextToken(value: unknown): value is HttpContextToken<unknown>;
7
- declare const HTTP_CONTEXT: unique symbol;
8
- export type HttpContext = {
9
- set<T>(token: HttpContextToken<T>, value: T): HttpContext;
10
- get<T>(token: HttpContextToken<T>): T;
11
- del(token: HttpContextToken<unknown>): HttpContext;
12
- has(token: HttpContextToken<unknown>): boolean;
13
- keys(): IterableIterator<HttpContextToken<unknown>>;
14
- get length(): number;
15
- readonly [HTTP_CONTEXT]: Map<HttpContextToken<unknown>, unknown>;
16
- };
17
- export declare function makeHttpContext(): HttpContext;
18
- export declare function makeHttpContext(entries?: readonly (readonly [
19
- HttpContextToken<unknown>,
20
- unknown
21
- ])[]): HttpContext;
22
- export declare function makeHttpContext(context?: HttpContext): HttpContext;
23
- export type ValidatorFn<T = unknown> = (value: T) => void;
24
- export type AsyncValidatorFn<T = unknown> = (value: T) => Promise<void>;
25
- export declare const required: ValidatorFn;
26
- export declare const requiredTrue: ValidatorFn;
27
- export declare const minLength: (min: number) => ValidatorFn;
28
- export declare const maxLength: (max: number) => ValidatorFn;
29
- export declare const min: (min: number) => ValidatorFn;
30
- export declare const max: (max: number) => ValidatorFn;
31
- export declare const pattern: (pattern: RegExp) => ValidatorFn;
32
- declare const FIELD: unique symbol;
33
- declare enum FieldType {
34
- Json = 0,
35
- Query = 1,
36
- Param = 2,
37
- Header = 3,
38
- Form = 4,
39
- Body = 5,
40
- UrlForm = 6
41
- }
42
- export interface FieldMetadata<T = undefined> {
43
- required: boolean;
44
- alias: Map<FieldType, string | undefined>;
45
- validators: ValidatorFn<T>[];
46
- asyncValidator: AsyncValidatorFn<T>[];
47
- }
48
- export type Field<T = undefined> = (() => T) & {
49
- withJson(alias?: string): Field<T>;
50
- withForm(alias?: string): Field<T>;
51
- withQuery(alias?: string): Field<T>;
52
- withParam(alias?: string): Field<T>;
53
- withHeader(alias?: string): Field<T>;
54
- withUrlForm(alias?: string): Field<T>;
55
- withBody(): Field<T>;
56
- withValidators(...fn: ValidatorFn<T>[]): Field<T>;
57
- withAsyncValidators(...fn: AsyncValidatorFn<T>[]): Field<T>;
58
- readonly [FIELD]: FieldMetadata<T>;
59
- };
60
- export declare function field(): Field;
61
- export declare function field<T>(): Field<T | undefined>;
62
- export declare function field<T>(defaultValue: T): Field<T>;
63
- export declare function doValid<T>(validators: (ValidatorFn<T> | AsyncValidatorFn<T>)[], value: T): Promise<void>;
64
- export declare function isField(value: unknown): value is Field;
65
- export declare function isFieldGroup(value: unknown): value is Record<PropertyKey, Field>;
1
+ //#region src/internal/http_request.d.ts
2
+ /**
3
+ * How the HTTP response body should be parsed before struct validation.
4
+ * Chosen from the declared struct kind: string is text, blob and file are blobs,
5
+ * arrayBuffer is bytes, and every other kind is JSON.
6
+ */
7
+ type HttpResponseType = 'arraybuffer' | 'blob' | 'json' | 'text';
8
+ /**
9
+ * Progress snapshot for upload or download callbacks.
10
+ * Mirrors the familiar `ProgressEvent` shape (`loaded` / `total` / `lengthComputable`).
11
+ */
12
+ interface HttpProgressEvent {
13
+ readonly lengthComputable: boolean;
14
+ readonly loaded: number;
15
+ readonly total: number;
16
+ }
17
+ /**
18
+ * Callback invoked as request bytes are uploaded or response bytes are downloaded.
19
+ */
20
+ type HttpProgressFn = (event: HttpProgressEvent) => Promise<void> | void;
21
+ /**
22
+ * Normalized outgoing HTTP request used by handlers, interceptors, and `fetchHandler`.
23
+ *
24
+ * After the request builder runs, `body` is already the wire value — for JSON that means a
25
+ * **JSON text string**. Sign HMAC / digests against that string (or other final bytes), not the
26
+ * original struct input.
27
+ */
28
+ interface HttpRequest {
29
+ abort?: AbortSignal;
30
+ baseEndpoint?: string;
31
+ body?: Blob | ArrayBuffer | FormData | URLSearchParams | ReadableStream<Uint8Array> | object | string | number | boolean | null;
32
+ bodyContentType?: string | null;
33
+ /** @internal Tracks which body value produced bodyContentType so interceptors cannot leave stale metadata behind. */
34
+ bodyContentTypeSource?: unknown;
35
+ downloadProgress?: HttpProgressFn;
36
+ endpoint: string;
37
+ headers?: Headers;
38
+ method: string;
39
+ /** Static, low-cardinality endpoint identity for telemetry and diagnostics. */
40
+ operation?: string;
41
+ queryParams?: URLSearchParams;
42
+ queryString?: string;
43
+ /**
44
+ * Representation for a 2xx body, derived from the endpoint `output` struct kind.
45
+ * Set only when `output` is declared. Interceptors that short-circuit with `makeResponse`
46
+ * read this to match the transport. Must not be changed. `undefined` leaves the 2xx body unread.
47
+ */
48
+ readonly responseType?: HttpResponseType;
49
+ /**
50
+ * Representation for a non-2xx body, derived from the endpoint `error` struct kind.
51
+ * Set only when `error` is declared. Must not be changed. `undefined` leaves the non-2xx body
52
+ * unread and does not fall back to `responseType`.
53
+ */
54
+ readonly errorResponseType?: HttpResponseType;
55
+ timeout?: number;
56
+ uploadProgress?: HttpProgressFn;
57
+ withCredentials?: boolean;
58
+ xsrf?: {
59
+ cookieName: string;
60
+ headerName: string;
61
+ tokenProvider?: (context: {
62
+ request: HttpRequest;
63
+ }) => string | null | undefined;
64
+ };
65
+ }
66
+ //#endregion
67
+ //#region src/internal/http_response.d.ts
68
+ declare const HTTP_RESPONSE: unique symbol;
69
+ /**
70
+ * Wire-shape HTTP response returned by transports and accepted by interceptors.
71
+ * `ok` is true for status codes in the 2xx range. A transport failure is a fault, never a response.
72
+ */
73
+ type HttpResponse<R> = {
74
+ readonly [HTTP_RESPONSE]: true;
75
+ readonly url: string;
76
+ readonly status: number;
77
+ readonly statusText: string;
78
+ readonly headers: Headers;
79
+ /** Absent when no body was present. JSON `null` stays `null`. */
80
+ readonly body: R | null | undefined;
81
+ readonly ok: boolean;
82
+ };
83
+ /**
84
+ * Response metadata, available whenever a response reached the client.
85
+ *
86
+ * Carries no body: a body only exists once a declared struct decoded it.
87
+ */
88
+ type HttpMeta = {
89
+ readonly headers: Headers;
90
+ readonly ok: boolean;
91
+ readonly status: number;
92
+ readonly statusText: string;
93
+ readonly url: string;
94
+ };
95
+ /**
96
+ * Response whose body decoded successfully against a declared struct.
97
+ *
98
+ * Reaching this type is the proof that decoding happened; a failed decode is reported
99
+ * as a fault carrying `HttpMeta` alone.
100
+ */
101
+ type DecodedResponse<TBody> = HttpMeta & {
102
+ readonly body: TBody;
103
+ };
104
+ /**
105
+ * Fields accepted by `makeResponse` when building a synthetic `HttpResponse` (for example in interceptors).
106
+ */
107
+ type MakeResponseOptions<R> = {
108
+ status?: number;
109
+ statusText?: string;
110
+ url?: string;
111
+ headers?: Headers;
112
+ body?: R | null;
113
+ request?: HttpRequest;
114
+ };
115
+ /**
116
+ * Build an `HttpResponse` value without performing a network call.
117
+ * Useful in interceptors that short-circuit `next`, and in tests.
118
+ *
119
+ * @param options - Status, headers, body, and an optional request to copy headers/url from; defaults yield status `0`.
120
+ * @returns An `HttpResponse` with `ok` derived from the status code.
121
+ */
122
+ export declare function makeResponse<R>(options?: MakeResponseOptions<R>): HttpResponse<R>;
123
+ //#endregion
124
+ //#region src/error/cause.d.ts
125
+ /** Shared cause/message sentinel for aborted requests. */
66
126
  export declare const ERR_ABORTED: Error;
127
+ /** Shared cause/message sentinel for timed-out requests. */
67
128
  export declare const ERR_TIMEOUT: Error;
68
- export declare const ERR_NETWORK: Error;
69
- export declare const ERR_NOT_FOUND_HANDLER: Error;
70
- export declare const ERR_OBSERVE: Error;
71
- export declare const ERR_NOT_SET_ALIAS: Error;
72
- export declare const ERR_UNSUPPORTED_FIELD_TYPE: Error;
73
- export declare const ERR_INVALID_CLIENT: Error;
74
- export declare const ERR_NOT_FOUND_GLOBAL_CLIENT: Error;
75
- export declare const ERR_INVALID_HTTP_CONTEXT_TOKEN: Error;
76
- export declare const ERR_UNKNOWN: Error;
77
- export type HttpResponseBody = string | ArrayBuffer | Blob | object | null;
78
- export type HttpResponse<R> = {
79
- readonly url: string;
80
- readonly status: number;
81
- readonly statusText: string;
82
- readonly headers: Headers;
83
- readonly body: R | null;
84
- readonly error?: Error | string | unknown;
85
- };
86
- export type MakeResponseOptions<R> = {
87
- status?: number;
88
- statusText?: string;
89
- url?: string;
90
- headers?: Headers;
91
- body?: R | null;
92
- error?: Error | string | unknown;
93
- };
94
- export type InterceptorFn = (req: HttpRequest, next: HttpHandler) => Promise<HttpResponse<unknown>>;
95
- export type BasicCredential = {
96
- username: string;
97
- password: string;
98
- };
99
- export type BasicAuthInterceptorOptions = {
100
- encode?: (credential: BasicCredential) => string;
101
- };
102
- export declare function basicAuthInterceptor(fn: () => BasicCredential, options?: BasicAuthInterceptorOptions): InterceptorFn;
103
- export type HttpResponseType = "arraybuffer" | "blob" | "json" | "text";
104
- export interface HttpProgressEvent {
105
- /**
106
- * Indicates whether the resources associated with Progress have a computable length.
107
- * Otherwise, the Progress.total attribute will be a meaningless value.
108
- */
109
- readonly lengthComputable: boolean;
110
- /** Indicates the workload of the underlying process. */
111
- readonly loaded: number;
112
- /**
113
- * The total size of the data being processed or transmitted.
114
- * If the Progress.lengthComputable attribute is false, this value is meaningless and should be ignored.
115
- */
116
- readonly total: number;
117
- }
118
- export type HttpProgressFn = (event: HttpProgressEvent) => void;
119
- export type TransformResponseFn<Output = unknown> = (response: HttpResponse<unknown>) => Output;
120
- export interface HttpRequest {
121
- host?: string;
122
- method: string;
123
- endpoint: string;
124
- body?: Blob | ArrayBuffer | FormData | URLSearchParams | object | string | number | boolean | null;
125
- headers?: Headers;
126
- queryParams?: URLSearchParams;
127
- /** default:json */
128
- responseType?: HttpResponseType;
129
- context?: HttpContext;
130
- timeout?: number;
131
- withCredentials?: boolean;
132
- /** when use fetch handler, no upload progress */
133
- uploadProgress?: HttpProgressFn;
134
- downloadProgress?: HttpProgressFn;
135
- abort?: AbortSignal;
136
- }
137
- export type RequestInputValue<T> = T extends {
138
- [K in keyof T]: Field<any>;
139
- } ? {
140
- [K in keyof T]: T[K] extends Field<infer V> ? V : never;
129
+ //#endregion
130
+ //#region src/struct/errors.d.ts
131
+ /**
132
+ * Optional callback that rewrites a `StructIssue` message before it is stored.
133
+ *
134
+ * Return a string to replace the default message, or `undefined` to keep it.
135
+ *
136
+ * @param issue - Issue about to be recorded.
137
+ * @returns Replacement message, or `undefined` to keep the default.
138
+ */
139
+ type ErrorMap = (issue: StructIssue) => string | undefined;
140
+ /**
141
+ * Aggregate of one or more `StructIssue`s from a failed parse.
142
+ *
143
+ * Use `format()`, `flatten()`, or `prettify()` to present issues to callers.
144
+ */
145
+ export declare class StructError extends Error {
146
+ /** Issues collected for this failure, in encounter order. */
147
+ readonly issues: StructIssue[];
148
+ /**
149
+ * @param issues - Non-empty list of parse issues (empty lists still produce a generic message).
150
+ */
151
+ constructor(issues: StructIssue[]);
152
+ /**
153
+ * Build a nested error tree keyed by path segments.
154
+ *
155
+ * @returns A `FormattedStructError` with `_errors` arrays at each node.
156
+ */
157
+ format(): FormattedStructError;
158
+ /**
159
+ * Split issues into root `formErrors` and first-segment `fieldErrors`.
160
+ *
161
+ * @returns Flat bags suitable for form libraries.
162
+ */
163
+ flatten(): FlattenedStructError;
164
+ /**
165
+ * Render a multi-line, human-readable summary of all issues.
166
+ *
167
+ * @returns One `× path: message` line per issue.
168
+ */
169
+ prettify(): string;
170
+ }
171
+ //#endregion
172
+ //#region src/struct/symbols.d.ts
173
+ /**
174
+ * Enumerable tag on objects produced while parsing endpoint input.
175
+ * Response decoding and `struct.parse` leave it unset. Internal to the outbound encoder.
176
+ *
177
+ * @internal
178
+ */
179
+ declare const STRUCT: unique symbol;
180
+ //#endregion
181
+ //#region src/struct/types.d.ts
182
+ type Path = Array<number | string>;
183
+ /**
184
+ * Error-first parse tuple from `struct.parse`.
185
+ *
186
+ * On success the error is `null` and `value` is the parsed output. On failure
187
+ * the error is a `StructError` and `value` is always `undefined`.
188
+ */
189
+ type ParseResult<O> = [error: null, value: O] | [error: StructError, value: undefined];
190
+ type LiteralValue = boolean | null | number | string;
191
+ interface StructTypes<Input = unknown, Output = unknown, OptionalOut extends boolean = false> {
192
+ input: Input;
193
+ optionalOut: OptionalOut extends true ? true : undefined;
194
+ output: Output;
195
+ }
196
+ /**
197
+ * Minimal structural brand carried by every struct instance.
198
+ *
199
+ * `_struct` holds input/output phantom types used by `Infer` and `StructInput`.
200
+ */
201
+ interface StructLike<I = unknown, O = unknown, OO extends boolean = boolean> {
202
+ readonly _struct: StructTypes<I, O, OO>;
203
+ }
204
+ type OptionalOutputStruct = {
205
+ readonly _struct: {
206
+ readonly optionalOut: true;
207
+ };
208
+ };
209
+ /**
210
+ * A single validation failure produced while parsing a struct.
211
+ */
212
+ interface StructIssue {
213
+ /** Machine-readable failure category. */
214
+ code: 'custom' | 'invalid_enum' | 'invalid_intersection' | 'invalid_literal' | 'invalid_type' | 'invalid_union' | 'missing_key';
215
+ /** Human-readable description of the expected type or value. */
216
+ expected: string;
217
+ /** Final message after optional `ErrorMap` rewriting. */
218
+ message: string;
219
+ /** Path from the parse root to the failing location. */
220
+ path: Path;
221
+ /** Value that failed validation at `path`. */
222
+ received: unknown;
223
+ }
224
+ /**
225
+ * Nested error tree returned by `StructError.format()`.
226
+ *
227
+ * Leaf messages live under `_errors`; nested keys mirror the failing path.
228
+ */
229
+ interface FormattedStructError {
230
+ _errors: string[];
231
+ [key: string]: FormattedStructError | string[];
232
+ }
233
+ /**
234
+ * Flat field/form error bags returned by `StructError.flatten()`.
235
+ */
236
+ interface FlattenedStructError {
237
+ /** Messages whose path is empty (root-level issues). */
238
+ formErrors: string[];
239
+ /** Messages keyed by the first path segment. */
240
+ fieldErrors: {
241
+ [key: string]: string[];
242
+ };
243
+ }
244
+ /**
245
+ * Chainable modifiers available on every `Struct` instance.
246
+ */
247
+ interface StructMethods<I, O, OO extends boolean> {
248
+ /**
249
+ * Override the external wire name for this field without changing the TypeScript property name.
250
+ *
251
+ * @param name - Wire / protocol field name.
252
+ * @returns The same struct branded with the alias.
253
+ */
254
+ alias(name: string): this;
255
+ /**
256
+ * Allow `null` in addition to the current input and output types.
257
+ *
258
+ * @returns A struct that accepts and emits `null`.
259
+ */
260
+ null(): Struct<I | null, O | null, OO>;
261
+ /**
262
+ * Alias for {@link StructMethods.null}.
263
+ *
264
+ * @returns A struct that accepts and emits `null`.
265
+ */
266
+ nullable(): Struct<I | null, O | null, OO>;
267
+ /**
268
+ * Allow `null` or `undefined`, marking the field optional in object output.
269
+ *
270
+ * @returns A struct that accepts `null`/`undefined` and treats the field as optional.
271
+ */
272
+ nullish(): Struct<I | null | undefined, O | null | undefined, true>;
273
+ /**
274
+ * Allow `undefined`, marking the field optional in object shapes.
275
+ *
276
+ * @returns A struct that accepts `undefined` and treats the field as optional.
277
+ */
278
+ optional(): Struct<I | undefined, O | undefined, true>;
279
+ }
280
+ /**
281
+ * Public struct contract: modifiers plus the `_struct` type brand.
282
+ *
283
+ * Built via the `struct` facade (`struct.string()`, `struct.object()`, …).
284
+ */
285
+ type Struct<Input = unknown, Output = Input, OptionalOut extends boolean = false> = StructMethods<Input, Output, OptionalOut> & StructLike<Input, Output, OptionalOut>;
286
+ type PresentValue = NonNullable<unknown>;
287
+ declare const carriedStruct: unique symbol;
288
+ /** Keeps the struct that a nullish modifier wrapped, so builders still see its fields. */
289
+ type CarriedStruct<T> = {
290
+ readonly [carriedStruct]: T;
291
+ };
292
+ declare const unionStructOptions: unique symbol;
293
+ declare const intersectionStructOptions: unique symbol;
294
+ declare const discriminatedUnionOptions: unique symbol;
295
+ interface PreservedStruct<T, I, O, OO extends boolean> extends Struct<I, O, OO>, CarriedStruct<T> {
296
+ null(): PreservedStruct<T, I | null, O | null, OO>;
297
+ nullable(): PreservedStruct<T, I | null, O | null, OO>;
298
+ nullish(): PreservedStruct<T, I | null | undefined, O | null | undefined, true>;
299
+ optional(): PreservedStruct<T, I | undefined, O | undefined, true>;
300
+ }
301
+ /**
302
+ * Broad struct constraint for endpoint and client generics.
303
+ *
304
+ * Prefer a concrete `Struct<…>` when you need precise input/output inference.
305
+ */
306
+ type AnyStruct = Struct<any, any, boolean>;
307
+ /**
308
+ * Infer the accepted input type of a struct.
309
+ *
310
+ * @typeParam T - A struct-like value with a `_struct.input` brand.
311
+ */
312
+ type StructInput<T> = T extends {
313
+ readonly _struct: {
314
+ readonly input: unknown;
315
+ };
316
+ } ? T['_struct']['input'] : never;
317
+ type StructOutput<T> = T extends {
318
+ readonly _struct: {
319
+ readonly output: unknown;
320
+ };
321
+ } ? T['_struct']['output'] : never;
322
+ /**
323
+ * Infer the parsed output type of a struct (alias of the internal output brand).
324
+ *
325
+ * @typeParam T - A struct-like value with a `_struct.output` brand.
326
+ */
327
+ type Infer<T> = StructOutput<T>;
328
+ type FieldOutput<S> = S extends StructLike<unknown, unknown, boolean> ? S extends OptionalOutputStruct ? Exclude<S['_struct']['output'], undefined> : S['_struct']['output'] : never;
329
+ type Simplify<T> = { [K in keyof T]: T[K]; } & {};
330
+ type ObjectShape = {
331
+ [key: string]: any;
332
+ };
333
+ type ObjectInput<T extends ObjectShape> = Simplify<{ -readonly [K in keyof T as T[K] extends OptionalOutputStruct ? never : K]: T[K]['_struct']['input']; } & { -readonly [K in keyof T as T[K] extends OptionalOutputStruct ? K : never]?: Exclude<T[K]['_struct']['input'], undefined>; }>;
334
+ type ObjectOutput<T extends ObjectShape> = Simplify<{ -readonly [K in keyof T as T[K] extends OptionalOutputStruct ? never : K]: FieldOutput<T[K]>; } & { -readonly [K in keyof T as T[K] extends OptionalOutputStruct ? K : never]?: FieldOutput<T[K]>; }>;
335
+ type TupleInput<T extends readonly StructLike<unknown, unknown, boolean>[]> = { -readonly [K in keyof T]: StructInput<T[K]>; };
336
+ type TupleOutput<T extends readonly StructLike<unknown, unknown, boolean>[]> = { -readonly [K in keyof T]: StructOutput<T[K]>; };
337
+ type UnionOutput<T extends readonly StructLike<unknown, unknown, boolean>[]> = Exclude<StructOutput<T[number]>, undefined>;
338
+ type UnionInput<T extends readonly StructLike<unknown, unknown, boolean>[]> = Exclude<StructInput<T[number]>, undefined>;
339
+ type IntersectionInputValue<T extends readonly StructLike<unknown, unknown, boolean>[]> = T extends readonly [infer Head extends StructLike<unknown, unknown, boolean>, ...infer Tail extends StructLike<unknown, unknown, boolean>[]] ? StructInput<Head> & IntersectionInputValue<Tail> : unknown;
340
+ type IntersectionInput<T extends readonly StructLike<unknown, unknown, boolean>[]> = Exclude<IntersectionInputValue<T>, undefined>;
341
+ type IntersectionOutputValue<T extends readonly StructLike<unknown, unknown, boolean>[]> = T extends readonly [infer Head extends StructLike<unknown, unknown, boolean>, ...infer Tail extends StructLike<unknown, unknown, boolean>[]] ? StructOutput<Head> & IntersectionOutputValue<Tail> : unknown;
342
+ type IntersectionOutput<T extends readonly StructLike<unknown, unknown, boolean>[]> = Exclude<IntersectionOutputValue<T>, undefined>;
343
+ type StringStruct = Struct<string, string>;
344
+ type NumberStruct = Struct<number, number>;
345
+ type UnknownStruct = Struct<PresentValue, unknown>;
346
+ type ArrayInput<S extends StructLike<unknown, unknown, boolean>> = StructInput<S>[];
347
+ type ArrayOutput<S extends StructLike<unknown, unknown, boolean>> = StructOutput<S>[];
348
+ interface ArrayStructTypes<S extends StructLike<unknown, unknown, boolean>> extends StructTypes<ArrayInput<S>, ArrayOutput<S>, false> {
349
+ input: ArrayInput<S>;
350
+ optionalOut: undefined;
351
+ output: ArrayOutput<S>;
352
+ }
353
+ interface ArrayStruct<S extends StructLike<unknown, unknown, boolean>> extends StructMethods<ArrayInput<S>, ArrayOutput<S>, false>, StructLike<ArrayInput<S>, ArrayOutput<S>, false> {
354
+ readonly _struct: ArrayStructTypes<S>;
355
+ null(): PreservedStruct<ArrayStruct<S>, ArrayInput<S> | null, ArrayOutput<S> | null, false>;
356
+ nullable(): PreservedStruct<ArrayStruct<S>, ArrayInput<S> | null, ArrayOutput<S> | null, false>;
357
+ nullish(): PreservedStruct<ArrayStruct<S>, ArrayInput<S> | null | undefined, ArrayOutput<S> | null | undefined, true>;
358
+ optional(): PreservedStruct<ArrayStruct<S>, ArrayInput<S> | undefined, ArrayOutput<S> | undefined, true>;
359
+ }
360
+ interface ObjectStructTypes<T extends ObjectShape> extends StructTypes<ObjectInput<T>, ObjectOutput<T>, false> {
361
+ input: ObjectInput<T>;
362
+ optionalOut: undefined;
363
+ output: ObjectOutput<T>;
364
+ }
365
+ /**
366
+ * Object-shaped struct produced by `struct.object(shape)`.
367
+ *
368
+ * Field presence follows each field's optional/nullish modifiers; wire names
369
+ * can differ from TypeScript keys via `.alias()`.
370
+ */
371
+ interface ObjectStruct<T extends ObjectShape> extends StructMethods<ObjectInput<T>, ObjectOutput<T>, false>, StructLike<ObjectInput<T>, ObjectOutput<T>, false> {
372
+ readonly _struct: ObjectStructTypes<T>;
373
+ null(): PreservedStruct<ObjectStruct<T>, ObjectInput<T> | null, ObjectOutput<T> | null, false>;
374
+ nullable(): PreservedStruct<ObjectStruct<T>, ObjectInput<T> | null, ObjectOutput<T> | null, false>;
375
+ nullish(): PreservedStruct<ObjectStruct<T>, ObjectInput<T> | null | undefined, ObjectOutput<T> | null | undefined, true>;
376
+ optional(): PreservedStruct<ObjectStruct<T>, ObjectInput<T> | undefined, ObjectOutput<T> | undefined, true>;
377
+ }
378
+ declare const recordValueStruct: unique symbol;
379
+ declare const tupleItemStructs: unique symbol;
380
+ type RecordInput<S extends StructLike<unknown, unknown, boolean>> = {
381
+ [key: string]: StructInput<S>;
382
+ };
383
+ type RecordOutput<S extends StructLike<unknown, unknown, boolean>> = {
384
+ [key: string]: FieldOutput<S>;
385
+ };
386
+ /**
387
+ * Value struct carried by `struct.record`.
388
+ * Tagged parsing stores this struct on the record object itself. `null` and `undefined` are not tagged.
389
+ */
390
+ interface RecordStruct<S extends StructLike<unknown, unknown, boolean>> extends Struct<RecordInput<S>, RecordOutput<S>> {
391
+ readonly [recordValueStruct]: S;
392
+ null(): PreservedStruct<RecordStruct<S>, RecordInput<S> | null, RecordOutput<S> | null, false>;
393
+ nullable(): PreservedStruct<RecordStruct<S>, RecordInput<S> | null, RecordOutput<S> | null, false>;
394
+ nullish(): PreservedStruct<RecordStruct<S>, RecordInput<S> | null | undefined, RecordOutput<S> | null | undefined, true>;
395
+ optional(): PreservedStruct<RecordStruct<S>, RecordInput<S> | undefined, RecordOutput<S> | undefined, true>;
396
+ }
397
+ /** Item structs carried by `struct.tuple`, so builders tag each position. The tuple itself is not tagged. */
398
+ interface TupleStruct<T extends readonly StructLike<unknown, unknown, boolean>[]> extends Struct<TupleInput<T>, TupleOutput<T>> {
399
+ readonly [tupleItemStructs]: T;
400
+ null(): PreservedStruct<TupleStruct<T>, TupleInput<T> | null, TupleOutput<T> | null, false>;
401
+ nullable(): PreservedStruct<TupleStruct<T>, TupleInput<T> | null, TupleOutput<T> | null, false>;
402
+ nullish(): PreservedStruct<TupleStruct<T>, TupleInput<T> | null | undefined, TupleOutput<T> | null | undefined, true>;
403
+ optional(): PreservedStruct<TupleStruct<T>, TupleInput<T> | undefined, TupleOutput<T> | undefined, true>;
404
+ }
405
+ interface UnionStruct<T extends readonly StructLike<unknown, unknown, boolean>[]> extends Struct<UnionInput<T>, UnionOutput<T>> {
406
+ readonly [unionStructOptions]: T;
407
+ null(): PreservedStruct<UnionStruct<T>, UnionInput<T> | null, UnionOutput<T> | null, false>;
408
+ nullable(): PreservedStruct<UnionStruct<T>, UnionInput<T> | null, UnionOutput<T> | null, false>;
409
+ nullish(): PreservedStruct<UnionStruct<T>, UnionInput<T> | null | undefined, UnionOutput<T> | null | undefined, true>;
410
+ optional(): PreservedStruct<UnionStruct<T>, UnionInput<T> | undefined, UnionOutput<T> | undefined, true>;
411
+ }
412
+ interface DiscriminatedUnionStruct<TOptions extends readonly ObjectStruct<ObjectShape>[]> extends Struct<StructInput<TOptions[number]>, StructOutput<TOptions[number]>> {
413
+ readonly [discriminatedUnionOptions]: TOptions;
414
+ null(): PreservedStruct<DiscriminatedUnionStruct<TOptions>, StructInput<TOptions[number]> | null, StructOutput<TOptions[number]> | null, false>;
415
+ nullable(): PreservedStruct<DiscriminatedUnionStruct<TOptions>, StructInput<TOptions[number]> | null, StructOutput<TOptions[number]> | null, false>;
416
+ nullish(): PreservedStruct<DiscriminatedUnionStruct<TOptions>, StructInput<TOptions[number]> | null | undefined, StructOutput<TOptions[number]> | null | undefined, true>;
417
+ optional(): PreservedStruct<DiscriminatedUnionStruct<TOptions>, StructInput<TOptions[number]> | undefined, StructOutput<TOptions[number]> | undefined, true>;
418
+ }
419
+ interface IntersectionStruct<T extends readonly StructLike<unknown, unknown, boolean>[]> extends Struct<IntersectionInput<T>, IntersectionOutput<T>> {
420
+ readonly [intersectionStructOptions]: T;
421
+ null(): PreservedStruct<IntersectionStruct<T>, IntersectionInput<T> | null, IntersectionOutput<T> | null, false>;
422
+ nullable(): PreservedStruct<IntersectionStruct<T>, IntersectionInput<T> | null, IntersectionOutput<T> | null, false>;
423
+ nullish(): PreservedStruct<IntersectionStruct<T>, IntersectionInput<T> | null | undefined, IntersectionOutput<T> | null | undefined, true>;
424
+ optional(): PreservedStruct<IntersectionStruct<T>, IntersectionInput<T> | undefined, IntersectionOutput<T> | undefined, true>;
425
+ }
426
+ //#endregion
427
+ //#region src/error/types.d.ts
428
+ /**
429
+ * Every failure Defjs reports, as one closed set of codes.
430
+ *
431
+ * The prefix before the first `_` is the class; there is no separate `kind` field.
432
+ * Read the prefix for coarse triage and the whole code for an exact case:
433
+ *
434
+ * | Class | Meaning |
435
+ * | ------ | -------------------------------------------------------------- |
436
+ * | `HTTP` | The peer answered with a non-2xx status. |
437
+ * | `REQ` | The request never left: input, execute options, or build. |
438
+ * | `NET` | No usable response: cancel, timeout, connect, truncated body. |
439
+ * | `RES` | A response arrived but could not be read as declared. |
440
+ * | `EXT` | Code you attached to the pipeline threw. |
441
+ * | `CAP` | A declared buffer or queue limit was exceeded. |
442
+ * | `ENV` | The host runtime lacks a required capability. |
443
+ *
444
+ * The set is closed on purpose: it keeps `switch (fault.code)` exhaustive. Extensions
445
+ * report their own detail through `cause`, not through a new code.
446
+ */
447
+ export type FaultCode = 'CAP_BUFFER_EXCEEDED' | 'CAP_QUEUE_OVERFLOW' | 'ENV_UNSUPPORTED' | 'EXT_HOOK_FAILED' | 'EXT_INTERCEPTOR_FAILED' | 'EXT_OBSERVER_FAILED' | 'HTTP_STATUS' | 'NET_ABORTED' | 'NET_BODY_INCOMPLETE' | 'NET_TIMEOUT' | 'NET_UNREACHABLE' | 'REQ_BUILD_FAILED' | 'REQ_INPUT_INVALID' | 'REQ_OPTIONS_INVALID' | 'RES_DECODE_FAILED' | 'RES_MEDIA_TYPE_INVALID' | 'RES_STRUCT_MISMATCH';
448
+ /**
449
+ * The class of a fault code: the segment before its first `_`.
450
+ *
451
+ * @typeParam C - A `FaultCode`, or a union of them.
452
+ */
453
+ export type FaultClass<C extends string> = C extends `${infer TClass}_${string}` ? TClass : never;
454
+ /** Codes whose fault carries response metadata but no body. */
455
+ export type DecodeFaultCode = 'RES_DECODE_FAILED' | 'RES_MEDIA_TYPE_INVALID' | 'RES_STRUCT_MISMATCH';
456
+ /** Codes whose fault may never have reached a response. */
457
+ export type PreflightFaultCode = Exclude<FaultCode, DecodeFaultCode | 'HTTP_STATUS'>;
458
+ type ErrorBody<TErr> = [TErr] extends [undefined] ? undefined : Infer<TErr>;
459
+ /**
460
+ * `HttpStatusFault` expressed by its decoded body type instead of the struct that produced it.
461
+ *
462
+ * Factories work in decoded values, so they use this form; endpoint types use
463
+ * `HttpStatusFault` and let `Infer` bridge the two.
464
+ */
465
+ export type HttpStatusFaultOf<TData> = Error & {
466
+ code: 'HTTP_STATUS';
467
+ data: TData;
468
+ response: [TData] extends [undefined] ? HttpMeta : DecodedResponse<TData>;
469
+ status: number;
470
+ };
471
+ /**
472
+ * The peer answered with a non-2xx status and the declared `error` struct decoded its body.
473
+ *
474
+ * Omitting `error` skips decoding, which leaves `data` as `undefined` and `response`
475
+ * without a `body` field.
476
+ */
477
+ export type HttpStatusFault<TErr extends AnyStruct | undefined = undefined> = HttpStatusFaultOf<ErrorBody<TErr>>;
478
+ /**
479
+ * A response arrived but could not be read as declared.
480
+ *
481
+ * `response` is metadata only: a body is a decoded value, and decoding is what failed.
482
+ * The offending detail lives on `cause` (a `StructError` for a struct mismatch, the
483
+ * parser failure for an unreadable representation).
484
+ */
485
+ export type DecodeFault = Error & {
486
+ cause: unknown;
487
+ code: DecodeFaultCode;
488
+ response: HttpMeta;
489
+ status: number;
490
+ };
491
+ /**
492
+ * A failure that may have happened before any response existed.
493
+ *
494
+ * `response` is present only where the transport already had metadata to report,
495
+ * such as a body that truncated mid-download.
496
+ */
497
+ export type PreflightFault = Error & {
498
+ cause?: unknown;
499
+ code: PreflightFaultCode;
500
+ response?: HttpMeta;
501
+ };
502
+ /**
503
+ * Any failure returned by `client.execute`, expressed by its decoded error-body type.
504
+ *
505
+ * @typeParam TData - The decoded `error` body, or `undefined` when no error struct was declared.
506
+ */
507
+ export type FaultOf<TData = undefined> = DecodeFault | HttpStatusFaultOf<TData> | PreflightFault;
508
+ /**
509
+ * Any failure returned by `client.execute`, discriminated by `code`.
510
+ *
511
+ * @typeParam TErr - The endpoint's declared `error` struct, or `undefined` when it declares none.
512
+ */
513
+ export type Fault<TErr extends AnyStruct | undefined = undefined> = FaultOf<ErrorBody<TErr>>;
514
+ /**
515
+ * Any fault at all, whatever its decoded error-body type.
516
+ *
517
+ * Use it for handlers that classify faults without caring which endpoint produced them.
518
+ * Prefer `Fault<typeof yourErrorStruct>` where the body type matters.
519
+ */
520
+ export type AnyFault = DecodeFault | HttpStatusFaultOf<undefined> | HttpStatusFaultOf<unknown> | PreflightFault;
521
+ //#endregion
522
+ //#region src/error/factory.d.ts
523
+ /**
524
+ * Build the fault for a non-2xx response whose body decoded against the declared `error` struct.
525
+ *
526
+ * @param response - The response, carrying the decoded body.
527
+ * @returns An `HTTP_STATUS` fault whose `data` is that body.
528
+ */
529
+ export declare function createHttpStatusFault<TData>(response: DecodedResponse<TData>): HttpStatusFaultOf<TData>;
530
+ /**
531
+ * Build the fault for a non-2xx response that was never decoded, because the endpoint
532
+ * declared no `error` struct.
533
+ *
534
+ * @param response - Metadata of the response; no body was read.
535
+ * @returns An `HTTP_STATUS` fault whose `data` is `undefined`.
536
+ */
537
+ export declare function createUndecodedHttpStatusFault(response: HttpMeta): HttpStatusFaultOf<undefined>;
538
+ /**
539
+ * Build the fault for a response that arrived but could not be read as declared.
540
+ *
541
+ * Carries metadata only: a body is a decoded value, and decoding is what failed.
542
+ *
543
+ * @param code - Which read step failed.
544
+ * @param cause - Underlying parser or struct failure.
545
+ * @param response - Metadata of the response that could not be read.
546
+ * @returns A decode fault with no body.
547
+ */
548
+ export declare function createDecodeFault(code: DecodeFaultCode, cause: unknown, response: HttpMeta): DecodeFault;
549
+ /**
550
+ * Build a fault for a failure that may have happened before any response existed.
551
+ *
552
+ * @param code - The specific failure.
553
+ * @param cause - Underlying value, when there is one; the code becomes the message otherwise.
554
+ * @param response - Metadata, only where the transport already had some to report.
555
+ * @returns A preflight fault.
556
+ */
557
+ export declare function createPreflightFault(code: PreflightFaultCode, cause?: unknown, response?: HttpMeta): PreflightFault;
558
+ /**
559
+ * Build a `NET_*` fault, choosing the code from the shape of `cause`.
560
+ *
561
+ * Recognizes the shared abort/timeout sentinels and the platform's `AbortError`/`TimeoutError`;
562
+ * anything else is reported as unreachable.
563
+ *
564
+ * @param cause - Underlying cancellation, timeout, or transport failure.
565
+ * @param response - Metadata, only where the transport already had some to report.
566
+ * @returns A `NET_ABORTED`, `NET_TIMEOUT`, or `NET_UNREACHABLE` fault.
567
+ */
568
+ export declare function createNetworkFault(cause: unknown, response?: HttpMeta): PreflightFault;
569
+ //#endregion
570
+ //#region src/struct/constructors.d.ts
571
+ declare function createStringStruct(): StringStruct;
572
+ declare function createNumberStruct(): NumberStruct;
573
+ declare function createBooleanStruct(): Struct<boolean, boolean>;
574
+ declare function createNullStruct(): Struct<null, null>;
575
+ declare function createAnyStruct(): Struct<PresentValue, any>;
576
+ declare function createUnknownStruct(): UnknownStruct;
577
+ declare function createLiteralStruct<const T extends LiteralValue>(value: T): Struct<T, T>;
578
+ declare function createArrayStruct<S extends StructLike<unknown, unknown, boolean>>(item: S): ArrayStruct<S>;
579
+ declare function createObjectStruct<T extends ObjectShape>(shape: T): ObjectStruct<T>;
580
+ declare function createUrlencodedBodyStruct<T extends ObjectShape>(shape: T): ObjectStruct<T>;
581
+ declare function createFormDataBodyStruct<T extends ObjectShape>(shape: T): ObjectStruct<T>;
582
+ declare function createRecordStruct<S extends StructLike<unknown, unknown, boolean>>(value: S): RecordStruct<S>;
583
+ declare function createTupleStruct<const T extends readonly [StructLike<unknown, unknown, boolean>, ...StructLike<unknown, unknown, boolean>[]]>(items: T): TupleStruct<T>;
584
+ type RequiredDiscriminatorOption<TDiscriminator extends string, TOption extends ObjectStruct<ObjectShape>> = TOption extends ObjectStruct<infer TShape> ? TDiscriminator extends keyof TShape ? TShape[TDiscriminator] extends StructLike<infer TInput, unknown, false> ? undefined extends TInput ? never : null extends TInput ? [TInput] extends [null] ? TOption : never : TOption : never : never : never;
585
+ type RequiredDiscriminatorOptions<TDiscriminator extends string, TOptions extends readonly ObjectStruct<ObjectShape>[]> = { [K in keyof TOptions]: TOptions[K] extends ObjectStruct<ObjectShape> ? RequiredDiscriminatorOption<TDiscriminator, TOptions[K]> : never; };
586
+ declare function createDiscriminatedUnionStruct<const TDiscriminator extends string, const TOptions extends readonly [ObjectStruct<ObjectShape>, ...ObjectStruct<ObjectShape>[]]>(discriminator: TDiscriminator, options: TOptions & RequiredDiscriminatorOptions<TDiscriminator, TOptions>): DiscriminatedUnionStruct<TOptions>;
587
+ declare function createBlobStruct(): Struct<Blob, Blob>;
588
+ declare function createBigIntStruct(): Struct<bigint | string, bigint>;
589
+ declare function createDateStruct(): Struct<Date | number | string, Date>;
590
+ declare function createIntersectionStruct<const T extends readonly [StructLike<unknown, unknown, boolean>, ...StructLike<unknown, unknown, boolean>[]]>(...structs: T): IntersectionStruct<T>;
591
+ declare function createFileStruct(): Struct<File, File>;
592
+ declare function createArrayBufferStruct(): Struct<ArrayBuffer, ArrayBuffer>;
593
+ //#endregion
594
+ //#region src/struct/introspection.d.ts
595
+ declare function parseStructTuple<S extends StructLike<unknown, unknown, boolean>>(struct: S, value: unknown, options?: {
596
+ aliases?: boolean;
597
+ errorMap?: ErrorMap;
598
+ }): ParseResult<S['_struct']['output']>;
599
+ //#endregion
600
+ //#region src/struct/facade.d.ts
601
+ type EnumValue<T> = T extends readonly (infer U extends string)[] ? U : T extends {
602
+ [key: string]: infer U extends number | string;
603
+ } ? U : never;
604
+ declare function structEnum<const T extends readonly [string, ...string[]]>(value: T): Struct<EnumValue<T>, EnumValue<T>>;
605
+ declare function structEnum<const T extends {
606
+ [key: string]: number | string;
607
+ }>(value: T): Struct<EnumValue<T>, EnumValue<T>>;
608
+ declare function structOr<const T extends readonly [StructLike, ...StructLike[]]>(...options: T): UnionStruct<T>;
609
+ /**
610
+ * Facade for building protocol-boundary structs and parsing values.
611
+ *
612
+ * Prefer this entry point over internal constructors. Compose shapes with
613
+ * `struct.object`, then parse with `struct.parse` or let HTTP/SSE/WebSocket
614
+ * endpoints apply the same contracts at the wire boundary.
615
+ *
616
+ * @example
617
+ * ```ts
618
+ * const User = struct.object({
619
+ * id: struct.number(),
620
+ * displayName: struct.string().alias('display_name'),
621
+ * })
622
+ *
623
+ * const getUser = defineRequest({
624
+ * method: 'GET',
625
+ * path: '/users/:id',
626
+ * input: struct.object({ id: struct.number() }),
627
+ * builder: (input) => ({ path: input }),
628
+ * output: User,
629
+ * })
630
+ *
631
+ * const [error, user] = struct.parse(User, { id: 1, displayName: 'Ada' })
632
+ * ```
633
+ */
634
+ export declare const struct: {
635
+ readonly any: typeof createAnyStruct;
636
+ readonly array: typeof createArrayStruct;
637
+ readonly arrayBuffer: typeof createArrayBufferStruct;
638
+ readonly bigint: typeof createBigIntStruct;
639
+ readonly blob: typeof createBlobStruct;
640
+ readonly boolean: typeof createBooleanStruct;
641
+ readonly date: typeof createDateStruct;
642
+ readonly discriminatedUnion: typeof createDiscriminatedUnionStruct;
643
+ readonly enum: typeof structEnum;
644
+ readonly file: typeof createFileStruct;
645
+ readonly formData: typeof createFormDataBodyStruct;
646
+ readonly intersection: typeof createIntersectionStruct;
647
+ readonly literal: typeof createLiteralStruct;
648
+ readonly null: typeof createNullStruct;
649
+ readonly number: typeof createNumberStruct;
650
+ readonly object: typeof createObjectStruct;
651
+ readonly or: typeof structOr;
652
+ readonly parse: typeof parseStructTuple;
653
+ readonly record: typeof createRecordStruct;
654
+ readonly string: typeof createStringStruct;
655
+ readonly tuple: typeof createTupleStruct;
656
+ readonly unknown: typeof createUnknownStruct;
657
+ readonly urlencoded: typeof createUrlencodedBodyStruct;
658
+ };
659
+ //#endregion
660
+ //#region src/sse/transport/parser.d.ts
661
+ /**
662
+ * Portions of this file are adapted from Azure/fetch-event-source.
663
+ * See packages/core/THIRD_PARTY_NOTICES.md for the license text.
664
+ */
665
+ interface EventStreamMessage {
666
+ id: string;
667
+ event: string;
668
+ data: string;
669
+ }
670
+ //#endregion
671
+ //#region src/sse/transport/event_stream.d.ts
672
+ /** Metadata available after an SSE response opens successfully. */
673
+ interface EventStreamOpenInfo {
674
+ response: HttpResponse<unknown>;
675
+ url: string;
676
+ }
677
+ /**
678
+ * Fault codes an event stream can end with, drawn from the one shared `FaultCode` namespace.
679
+ *
680
+ * SSE used to carry a parallel set with no mapping to the request error model.
681
+ */
682
+ type EventStreamFaultCode = Extract<FaultCode, 'CAP_BUFFER_EXCEEDED' | 'CAP_QUEUE_OVERFLOW' | 'EXT_HOOK_FAILED' | 'EXT_OBSERVER_FAILED' | 'NET_TIMEOUT' | 'NET_UNREACHABLE' | 'RES_DECODE_FAILED' | 'RES_MEDIA_TYPE_INVALID'>;
683
+ interface EventStreamCloseInfoBase {
684
+ reason?: string;
685
+ cause?: unknown;
686
+ }
687
+ /**
688
+ * How an SSE stream ended: clean EOF, abort, or an error carrying its fault `code`.
689
+ *
690
+ * The discriminant is `kind` so that `code` can mean the same thing it means on a fault.
691
+ */
692
+ type EventStreamCloseInfo = (EventStreamCloseInfoBase & {
693
+ kind: 'eof';
694
+ }) | (EventStreamCloseInfoBase & {
695
+ kind: 'aborted';
696
+ }) | (EventStreamCloseInfoBase & {
697
+ code: EventStreamFaultCode;
698
+ kind: 'error';
699
+ });
700
+ /** Open SSE stream: iterate events, inspect open metadata, and close early. */
701
+ interface EventStreamHandle<TEvent = EventStreamMessage> extends AsyncIterable<TEvent>, AsyncDisposable {
702
+ readonly open: EventStreamOpenInfo;
703
+ readonly closed: Promise<EventStreamCloseInfo>;
704
+ close(reason?: unknown): void;
705
+ [Symbol.asyncDispose](): PromiseLike<void>;
706
+ }
707
+ //#endregion
708
+ //#region src/internal/abort.d.ts
709
+ type UseCancellationConfig = {
710
+ abort?: AbortSignal;
711
+ timeout?: never;
712
+ } | {
713
+ abort?: never;
714
+ timeout?: number;
715
+ };
716
+ //#endregion
717
+ //#region src/internal/endpoint_input.d.ts
718
+ type EndpointInput<TInput extends AnyStruct | undefined> = TInput extends AnyStruct ? StructInput<TInput> : unknown;
719
+ //#endregion
720
+ //#region src/internal/endpoint_command.d.ts
721
+ type IsEndpointInputOptional<TInput extends AnyStruct | undefined> = [TInput] extends [undefined] ? true : undefined extends EndpointInput<TInput> ? true : false;
722
+ type EndpointCallable<TInput extends AnyStruct | undefined, TCommand> = [TInput] extends [undefined] ? () => TCommand : IsEndpointInputOptional<TInput> extends true ? (input?: EndpointInput<TInput>) => TCommand : (input: EndpointInput<TInput>) => TCommand;
723
+ //#endregion
724
+ //#region src/internal/builder_types.d.ts
725
+ /** Object produced by endpoint input parsing. The symbol points at the struct that produced the node. */
726
+ type Typed = {
727
+ readonly [STRUCT]: AnyStruct;
728
+ };
729
+ type Scalar = string | number | bigint | boolean | Date;
730
+ type FlatValue = Scalar | readonly Scalar[] | undefined;
731
+ type FlatRecord = {
732
+ readonly [key: string]: FlatValue;
733
+ };
734
+ type QueryValue = Scalar | readonly QueryValue[] | {
735
+ readonly [key: string]: QueryValue;
736
+ } | undefined;
737
+ type QueryRecord = {
738
+ readonly [key: string]: QueryValue;
739
+ };
740
+ type PathParams<P extends string> = P extends `${string}:${infer Name}/${infer Rest}` ? Name | PathParams<`/${Rest}`> : P extends `${string}:${infer Name}` ? Name : never;
741
+ type PathValue<P extends string> = [PathParams<P>] extends [never] ? never : ({ readonly [K in PathParams<P>]: Scalar; } & {
742
+ readonly [STRUCT]?: never;
743
+ }) | (Typed & {
744
+ readonly [key: string]: Scalar;
745
+ });
746
+ type HttpRequestShape<P extends string, M extends string> = {
747
+ body?: Uppercase<M> extends 'GET' | 'HEAD' ? never : unknown;
748
+ headers?: HeadersInit | FlatRecord;
749
+ path?: PathValue<P>;
750
+ query?: URLSearchParams | QueryRecord;
751
+ };
752
+ type WebSocketRequestShape<P extends string> = {
753
+ body?: never;
754
+ headers?: never;
755
+ path?: PathValue<P>;
756
+ query?: URLSearchParams | QueryRecord;
757
+ };
758
+ type EventStreamRequestShape<P extends string, M extends string> = HttpRequestShape<P, M>;
759
+ type NullishBuilderInput<S, Inner> = null extends Infer<S> ? undefined extends Infer<S> ? BuilderInput<Inner> | null | undefined : BuilderInput<Inner> | null : undefined extends Infer<S> ? BuilderInput<Inner> | undefined : BuilderInput<Inner>;
760
+ type IntersectBuilderInputs<T extends readonly StructLike<unknown, unknown, boolean>[]> = T extends readonly [infer Head extends StructLike<unknown, unknown, boolean>, ...infer Tail extends readonly StructLike<unknown, unknown, boolean>[]] ? BuilderInput<Head> & (Tail['length'] extends 0 ? unknown : IntersectBuilderInputs<Tail>) : unknown;
761
+ /**
762
+ * Parsed endpoint input seen by a builder.
763
+ *
764
+ * Object nodes are intersected with {@link Typed}. Record entries and tuple items are too.
765
+ * At runtime a record container is also tagged when the parsed value is an object, whether or not it
766
+ * was merged. Array and tuple containers are not. `null` and `undefined` are never tagged.
767
+ * Modifiers recover the struct they wrapped. Union options are distributed; intersection options are combined.
768
+ */
769
+ type BuilderInput<S> = S extends CarriedStruct<infer Inner> ? NullishBuilderInput<S, Inner> : S extends UnionStruct<infer Options> ? BuilderInput<Options[number]> : S extends DiscriminatedUnionStruct<infer Options> ? BuilderInput<Options[number]> : S extends IntersectionStruct<infer Options> ? IntersectBuilderInputs<Options> : S extends RecordStruct<infer Value> ? {
770
+ [key: string]: BuilderInput<Value>;
771
+ } : S extends TupleStruct<infer Items> ? { [K in keyof Items]: Items[K] extends StructLike<unknown, unknown, boolean> ? BuilderInput<Items[K]> : Items[K]; } : S extends ArrayStruct<infer Item> ? BuilderInput<Item>[] : S extends ObjectStruct<infer Shape> ? { [K in keyof Shape]: BuilderInput<Shape[K]>; } & Typed : Infer<S>;
772
+ type BuilderField<TInput, TShape> = [TInput] extends [undefined] ? {
773
+ builder?: () => TShape;
774
+ } : BuilderInput<TInput> extends TShape ? {
775
+ builder?: (input: BuilderInput<TInput>) => TShape;
776
+ } : {
777
+ builder: (input: BuilderInput<TInput>) => TShape;
778
+ };
779
+ //#endregion
780
+ //#region src/internal/outbound_request.d.ts
781
+ /** Accepts any concrete builder. `never` keeps the parameter contravariant. */
782
+ type OutboundBuilder = (input: never) => unknown;
783
+ //#endregion
784
+ //#region src/http/http.d.ts
785
+ /**
786
+ * Per-request options for HTTP execution: progress callbacks and cancellation.
787
+ * Cancellation is either `abort` or `timeout` (not both).
788
+ */
789
+ export type UseRequestConfig = {
790
+ onDownloadProgress?: HttpProgressFn;
791
+ onUploadProgress?: HttpProgressFn;
792
+ } & UseCancellationConfig;
793
+ /**
794
+ * Executable HTTP command produced by a `defineRequest` endpoint.
795
+ * Carries the request definition and optional typed input for `client.execute`.
796
+ */
797
+ export interface HttpCommand<TInput extends AnyStruct | undefined, TOutput extends AnyStruct | undefined, TError extends AnyStruct | undefined = undefined> extends BaseCommand<typeof HTTP_COMMAND> {
798
+ readonly definition: RequestDefinition<TInput, TOutput, TError>;
799
+ readonly input: EndpointInput<TInput> | undefined;
800
+ }
801
+ /**
802
+ * Options passed to `client.execute` / `executeHttpCommand` for a single HTTP call.
803
+ * `signal` combines with `abort` or `timeout`; it is not an alias for `abort`.
804
+ * `abort` and `timeout` are mutually exclusive (`abort` XOR `timeout`).
805
+ */
806
+ export type HttpExecuteOptions = UseRequestConfig & {
807
+ signal?: AbortSignal;
808
+ };
809
+ /**
810
+ * Endpoint returned by `defineRequest`; call with input to create an `HttpCommand`.
811
+ */
812
+ export type RequestEndpoint<TInput extends AnyStruct | undefined, TOutput extends AnyStruct | undefined, TError extends AnyStruct | undefined = undefined> = EndpointCallable<TInput, HttpCommand<TInput, TOutput, TError>>;
813
+ type DeclaredBody<TStruct> = [TStruct] extends [undefined] ? undefined : Infer<TStruct>;
814
+ type DeclaredResponse<TStruct> = [TStruct] extends [undefined] ? HttpMeta : DecodedResponse<Infer<TStruct>>;
815
+ /** Inferred success body for the declared `output` struct, or `undefined` when none is declared. */
816
+ export type RequestSuccessData<TOutput extends AnyStruct | undefined> = DeclaredBody<TOutput>;
817
+ /** Inferred error body for the declared `error` struct, or `undefined` when none is declared. */
818
+ export type RequestErrorData<TError extends AnyStruct | undefined> = DeclaredBody<TError>;
819
+ type ResponseDeclaration<TOutput extends AnyStruct | undefined, TError extends AnyStruct | undefined> = ([TOutput] extends [undefined] ? {
820
+ output?: never;
821
+ } : {
822
+ output: TOutput;
823
+ }) & ([TError] extends [undefined] ? {
824
+ error?: never;
825
+ } : {
826
+ error: TError;
827
+ });
828
+ /**
829
+ * Contract for an HTTP endpoint: method, path, optional input struct, and the structs that
830
+ * decode its bodies.
831
+ *
832
+ * `output` declares the body for a 2xx response, `error` the body for anything else. Only one
833
+ * of the two ever runs, and omitting one means that body is never read. Pass to `defineRequest`
834
+ * to get a typed endpoint.
835
+ */
836
+ export type RequestDefinition<TInput extends AnyStruct | undefined = undefined, TOutput extends AnyStruct | undefined = undefined, TError extends AnyStruct | undefined = undefined> = ResponseDeclaration<TOutput, TError> & {
837
+ builder?: OutboundBuilder;
838
+ input?: TInput;
839
+ method: string;
840
+ operation?: string;
841
+ path: string;
842
+ };
843
+ /**
844
+ * Await-result tuple for an HTTP call.
845
+ *
846
+ * Success is `[null, data, response]`; failure is `[fault, undefined, undefined]` because the
847
+ * fault carries whatever response metadata existed.
848
+ */
849
+ export type HttpAwaitResult<TData = undefined, TErrorData = undefined> = [error: null, result: TData, response: [TData] extends [undefined] ? HttpMeta : DecodedResponse<TData>] | [error: FaultOf<TErrorData>, result: undefined, response: undefined];
850
+ type HttpExecuteAwaitResult<TOutput extends AnyStruct | undefined, TError extends AnyStruct | undefined> = [error: null, result: RequestSuccessData<TOutput>, response: DeclaredResponse<TOutput>] | [error: Fault<TError>, result: undefined, response: undefined];
851
+ /**
852
+ * Declare a typed HTTP request endpoint.
853
+ *
854
+ * Pass method, path, an optional input struct, and the single `output` and `error` structs.
855
+ * Call the returned endpoint with input to get an `HttpCommand` for `client.execute`.
856
+ *
857
+ * @param definition - Request contract (method, path, input, builder, output).
858
+ * @returns An endpoint that creates `HttpCommand` values from input.
859
+ *
860
+ * @example
861
+ * ```ts
862
+ * const getUser = defineRequest({
863
+ * method: 'GET',
864
+ * path: '/users/:id',
865
+ * input: struct.object({ id: struct.number() }),
866
+ * builder: (input) => ({ path: { id: input.id } }),
867
+ * output: struct.object({ id: struct.number(), name: struct.string() }),
868
+ * error: struct.object({ message: struct.string() }),
869
+ * })
870
+ * ```
871
+ */
872
+ export declare function defineRequest<const M extends string, const P extends string, TInput extends AnyStruct | undefined = undefined, TOutput extends AnyStruct | undefined = undefined, TError extends AnyStruct | undefined = undefined>(definition: ResponseDeclaration<TOutput, TError> & {
873
+ input?: TInput;
874
+ method: M;
875
+ operation?: string;
876
+ path: P;
877
+ } & BuilderField<NoInfer<TInput>, HttpRequestShape<NoInfer<P>, NoInfer<M>>>): RequestEndpoint<TInput, TOutput, TError>;
878
+ /**
879
+ * Run an `HttpCommand` against client config: validate input, send the request, parse the response.
880
+ * Prefer `client.execute(command)` in application code; this is the underlying implementation.
881
+ *
882
+ * @param clientConfig - Resolved HTTP client configuration (endpoint, interceptors, handler).
883
+ * @param command - Command from a `defineRequest` endpoint.
884
+ * @param options - Per-request progress and cancellation options.
885
+ * @returns An await-result tuple of success body or typed request error.
886
+ */
887
+ export declare function executeHttpCommand<TInput extends AnyStruct | undefined, TOutput extends AnyStruct | undefined, TError extends AnyStruct | undefined>(clientConfig: HttpClientConfig, command: HttpCommand<TInput, TOutput, TError>, options?: HttpExecuteOptions): Promise<HttpExecuteAwaitResult<TOutput, TError>>;
888
+ //#endregion
889
+ //#region src/sse/sse.d.ts
890
+ /** Map of SSE event names to payload structs. Declare `__proto__` with a computed own key. */
891
+ export type EventStructs = {
892
+ [key: string]: AnyStruct;
893
+ };
894
+ type EventName<TKey extends string | number> = `${TKey}`;
895
+ type KnownEventUnion<TEvents extends EventStructs> = { [K in keyof TEvents & (number | string)]: EventName<K> extends 'default' ? never : {
896
+ data: Infer<TEvents[K]>;
897
+ event: EventName<K>;
898
+ id?: string;
899
+ }; }[keyof TEvents & (number | string)];
900
+ type DefaultEventUnion<TEvents extends EventStructs> = 'default' extends keyof TEvents ? {
901
+ data: Infer<TEvents['default']>;
902
+ event: string;
903
+ id?: string;
141
904
  } : never;
142
- export type UseRequestOptions = {
143
- abort?: AbortSignal;
144
- handler?: HttpHandler;
145
- client?: Client;
146
- timeout?: number;
147
- };
148
- export type UseRequestFn<Input, Output> = {
149
- doRequest: undefined extends RequestInputValue<Input> ? (input?: RequestInputValue<Input>) => Promise<HttpResponse<Output>> : (input: RequestInputValue<Input>) => Promise<HttpResponse<Output>>;
150
- cancel: () => void;
151
- getInitValue: () => RequestInputValue<Input>;
152
- setUploadProgress: (fn: HttpProgressFn) => void;
153
- setDownloadProgress: (fn: HttpProgressFn) => void;
154
- };
155
- export interface DefineRequest<Input extends Record<PropertyKey, Field<any>> | undefined = undefined, Output = unknown> {
156
- (options?: UseRequestOptions): UseRequestFn<Input, Output>;
157
- withField<I extends Record<PropertyKey, Field<any>>>(value: I): DefineRequest<I, Output>;
158
- withInterceptors(value: InterceptorFn[]): DefineRequest<Input, Output>;
159
- withContext(value: HttpContext): DefineRequest<Input, Output>;
160
- withCredentials(value: boolean): DefineRequest<Input, Output>;
161
- withValidators(...fn: (ValidatorFn<RequestInputValue<Input>> | AsyncValidatorFn<RequestInputValue<Input>>)[]): DefineRequest<Input, Output>;
162
- withTransformResponse<O>(fn: TransformResponseFn<O>): DefineRequest<Input, O>;
163
- withResponseType(value: "json"): DefineRequest<Input, Output>;
164
- withResponseType(value: "text"): DefineRequest<Input, string>;
165
- withResponseType(value: "blob"): DefineRequest<Input, Blob>;
166
- withResponseType(value: "arraybuffer"): DefineRequest<Input, ArrayBuffer>;
167
- }
168
- export declare function defineRequest<Output>(endpoint: string): DefineRequest<undefined, Output>;
169
- export declare function defineRequest<Output>(method: string, endpoint: string): DefineRequest<undefined, Output>;
170
- export type HttpHandler = (req: HttpRequest) => Promise<HttpResponse<unknown>>;
171
- export declare function fetchHandler(httpRequest: HttpRequest): Promise<HttpResponse<unknown>>;
172
- export interface ClientOptions {
173
- host: string;
174
- interceptors?: InterceptorFn[];
175
- handler?: HttpHandler;
176
- }
177
- export type ClientConfig = {
178
- host: string;
179
- handler: HttpHandler;
180
- interceptors: InterceptorFn[];
905
+ /** Parsed SSE event payload inferred from an `EventStructs` map. */
906
+ export type EventStreamData<TEvents extends EventStructs> = TEvents extends EventStructs ? KnownEventUnion<TEvents> | DefaultEventUnion<TEvents> : never;
907
+ interface EventStreamDefinitionBase<TEvents extends EventStructs = EventStructs> {
908
+ events: TEvents;
909
+ maxBufferSize: number;
910
+ maxQueueSize: number;
911
+ method?: string;
912
+ operation?: string;
913
+ path: string;
914
+ }
915
+ /** Makes `error` required only when an error struct is declared, so omission stays `Fault<undefined>`. */
916
+ type EventStreamErrorField<TError extends AnyStruct | undefined> = [TError] extends [undefined] ? {
917
+ error?: never;
918
+ } : {
919
+ error: TError;
920
+ };
921
+ /** Contract describing an SSE endpoint: path, events, and buffer/queue limits. */
922
+ export type EventStreamDefinition<TInput extends AnyStruct | undefined = undefined, TEvents extends EventStructs = EventStructs, TError extends AnyStruct | undefined = undefined> = EventStreamDefinitionBase<TEvents> & EventStreamErrorField<TError> & {
923
+ builder?: OutboundBuilder;
924
+ input?: TInput;
925
+ };
926
+ /** Await-result tuple from opening an SSE stream via `client.execute`. */
927
+ export type StreamAwaitResult<TEvent, TError extends AnyStruct | undefined = undefined> = [error: null, stream: EventStreamHandle<TEvent>, open: EventStreamOpenInfo] | [error: Fault<TError>, stream: undefined, open: EventStreamOpenInfo | undefined];
928
+ /** Executable SSE command produced by an `EventStreamEndpoint`. */
929
+ export interface EventStreamCommand<TInput extends AnyStruct | undefined, TEvents extends EventStructs, TError extends AnyStruct | undefined = undefined> extends BaseCommand<typeof EVENT_STREAM_COMMAND> {
930
+ readonly endpoint: ResolvedEventStreamDefinition<TInput, TEvents, TError>;
931
+ readonly input: EndpointInput<TInput> | undefined;
932
+ }
933
+ /** Per-execute options for SSE commands (abort, timeout). */
934
+ export type EventStreamExecuteOptions = UseCancellationConfig & {
935
+ signal?: AbortSignal;
936
+ };
937
+ /** Endpoint returned by `defineEventStream`; call it to create an `EventStreamCommand`. */
938
+ export type EventStreamEndpoint<TInput extends AnyStruct | undefined, TEvents extends EventStructs, TError extends AnyStruct | undefined = undefined> = EndpointCallable<TInput, EventStreamCommand<TInput, TEvents, TError>>;
939
+ type ResolvedEventStreamDefinition<TInput extends AnyStruct | undefined = undefined, TEvents extends EventStructs = EventStructs, TError extends AnyStruct | undefined = undefined> = EventStreamDefinition<TInput, TEvents, TError> & {
940
+ readonly method: string;
941
+ };
942
+ /**
943
+ * Declare a typed Server-Sent Events endpoint.
944
+ *
945
+ * Pass path, event structs, and buffer/queue limits. Call the returned endpoint
946
+ * with input to get an `EventStreamCommand` for `client.execute`.
947
+ *
948
+ * @param definition - SSE contract (path, events, buffer limits, optional input).
949
+ * @returns An endpoint that creates `EventStreamCommand` values from input.
950
+ *
951
+ * @example
952
+ * ```ts
953
+ * const useEvents = defineEventStream({
954
+ * maxBufferSize: 1024,
955
+ * maxQueueSize: 16,
956
+ * path: '/events',
957
+ * events: { message: struct.object({ text: struct.string() }) },
958
+ * })
959
+ * ```
960
+ */
961
+ export declare function defineEventStream<const P extends string, const M extends string = 'GET', TInput extends AnyStruct | undefined = undefined, TEvents extends EventStructs = EventStructs, TError extends AnyStruct | undefined = undefined>(definition: Omit<EventStreamDefinitionBase<TEvents>, 'method' | 'path'> & EventStreamErrorField<TError> & {
962
+ input?: TInput;
963
+ method?: M;
964
+ path: P;
965
+ } & BuilderField<NoInfer<TInput>, EventStreamRequestShape<NoInfer<P>, NoInfer<M>>>): EventStreamEndpoint<TInput, TEvents, TError>;
966
+ /**
967
+ * Open an SSE command against the given client config.
968
+ *
969
+ * Prefer `client.execute(command)` in application code; this is the low-level entry used by the client.
970
+ *
971
+ * @param clientConfig - Resolved client configuration.
972
+ * @param command - SSE command from an `EventStreamEndpoint`.
973
+ * @param options - Optional execute options (abort, timeout).
974
+ * @returns Await-result tuple of `[error, stream, open]`.
975
+ */
976
+ export declare function executeEventStreamCommand<TInput extends AnyStruct | undefined, TEvents extends EventStructs, TError extends AnyStruct | undefined = undefined>(clientConfig: ClientConfig, command: EventStreamCommand<TInput, TEvents, TError>, options?: EventStreamExecuteOptions): Promise<StreamAwaitResult<EventStreamData<TEvents>, TError>>;
977
+ //#endregion
978
+ //#region src/client/command.d.ts
979
+ declare const COMMAND_TYPE: unique symbol;
980
+ declare const HTTP_COMMAND: unique symbol;
981
+ declare const EVENT_STREAM_COMMAND: unique symbol;
982
+ declare const WEB_SOCKET_COMMAND: unique symbol;
983
+ /** The command's own runner, so `client.execute` never imports a transport the app does not use. */
984
+ declare const COMMAND_EXECUTE: unique symbol;
985
+ type CommandExecutor = (config: ClientConfig, command: never, options?: never) => Promise<unknown>;
986
+ type CommandType = typeof HTTP_COMMAND | typeof EVENT_STREAM_COMMAND | typeof WEB_SOCKET_COMMAND;
987
+ interface BaseCommand<TCommandType extends CommandType> {
988
+ readonly [COMMAND_EXECUTE]: CommandExecutor;
989
+ readonly [COMMAND_TYPE]: TCommandType;
990
+ }
991
+ //#endregion
992
+ //#region src/web_socket/codec.d.ts
993
+ interface WebSocketCloseSnapshot {
994
+ cause?: unknown;
995
+ code?: number;
996
+ reason?: string;
997
+ wasClean?: boolean;
998
+ }
999
+ //#endregion
1000
+ //#region src/web_socket/web_socket.d.ts
1001
+ /** Lifecycle state of a managed WebSocket session. */
1002
+ export type WebSocketState = 'aborted' | 'closed' | 'closing' | 'connecting' | 'error' | 'idle' | 'open' | 'reconnecting';
1003
+ /** Decoded incoming frame. Alias fields use their logical names. */
1004
+ export type WebSocketIncomingData<TIncoming extends AnyStruct> = Infer<TIncoming>;
1005
+ /** Value accepted by `session.send`. `never` when the endpoint declares no outgoing struct. */
1006
+ export type WebSocketOutgoingData<TOutgoing extends AnyStruct | undefined> = TOutgoing extends AnyStruct ? StructInput<TOutgoing> : never;
1007
+ interface WebSocketDefinitionBase<TIncoming extends AnyStruct = AnyStruct, TOutgoing extends AnyStruct | undefined = undefined> {
1008
+ incoming: TIncoming;
1009
+ maxIncomingQueueSize: number;
1010
+ maxOutgoingQueueSize?: number;
1011
+ operation?: string;
1012
+ outgoing?: TOutgoing;
1013
+ path: string;
1014
+ protocols?: readonly string[];
1015
+ }
1016
+ /** Contract describing a WebSocket endpoint: path, message structs, and queue limits. */
1017
+ export type WebSocketDefinition<TInput extends AnyStruct | undefined = undefined, TIncoming extends AnyStruct = AnyStruct, TOutgoing extends AnyStruct | undefined = undefined> = WebSocketDefinitionBase<TIncoming, TOutgoing> & {
1018
+ builder?: OutboundBuilder;
1019
+ input?: TInput;
1020
+ };
1021
+ /** Connection metadata for the current WebSocket generation. */
1022
+ export interface WebSocketConnectionInfo {
1023
+ extensions?: string;
1024
+ generation: number;
1025
+ protocol?: string;
1026
+ url?: string;
1027
+ }
1028
+ /** How a WebSocket session ended: closed, aborted, or error. */
1029
+ export type WebSocketCloseInfo = {
1030
+ kind: 'closed';
1031
+ code?: number;
1032
+ reason?: string;
1033
+ wasClean?: boolean;
1034
+ } | {
1035
+ kind: 'aborted';
1036
+ cause?: unknown;
1037
+ code?: number;
1038
+ reason?: string;
1039
+ wasClean?: boolean;
1040
+ } | {
1041
+ kind: 'error';
1042
+ cause: unknown;
1043
+ code?: number;
1044
+ reason?: string;
1045
+ wasClean?: boolean;
1046
+ };
1047
+ /** Typed WebSocket session: send/receive messages, observe state, and close. */
1048
+ export interface WebSocketSession<TIncoming = unknown, TOutgoing = never> extends AsyncDisposable {
1049
+ readonly bufferedAmount: number;
1050
+ readonly connection: WebSocketConnectionInfo;
1051
+ readonly closed: Promise<WebSocketCloseInfo>;
1052
+ readonly receive: AsyncIterable<TIncoming>;
1053
+ readonly state: WebSocketState;
1054
+ close(code?: number, reason?: string): void;
1055
+ [Symbol.asyncDispose](): PromiseLike<void>;
1056
+ onRuntimeError(listener: (error: unknown) => void): () => void;
1057
+ onStateChange(listener: (state: WebSocketState) => void): () => void;
1058
+ send(message: TOutgoing): void;
1059
+ }
1060
+ /** Await-result tuple from opening a WebSocket via `client.execute`. */
1061
+ export type SocketAwaitResult<TIncoming, TOutgoing = never> = [error: null, socket: WebSocketSession<TIncoming, TOutgoing>, connection: WebSocketConnectionInfo] | [error: Fault<undefined>, socket: undefined, connection: WebSocketConnectionInfo | undefined];
1062
+ interface UseWebSocketBaseConfig<TIncoming = unknown, TOutgoing = unknown> {
1063
+ beforeConnect?: ClientWebSocketOptions['beforeConnect'];
1064
+ heartbeat?: WebSocketHeartbeatConfig<TIncoming, TOutgoing>;
1065
+ protocols?: readonly string[];
1066
+ reconnect?: ClientWebSocketOptions['reconnect'];
1067
+ }
1068
+ /** Client configuration for WebSocket execute (heartbeat, reconnect, abort). */
1069
+ export type UseWebSocketConfig<TIncoming = unknown, TOutgoing = unknown> = UseWebSocketBaseConfig<TIncoming, TOutgoing> & UseCancellationConfig;
1070
+ /** Per-execute options for WebSocket commands, including an optional `AbortSignal`. */
1071
+ export type WebSocketExecuteOptions<TIncoming = unknown, TOutgoing = unknown> = UseWebSocketConfig<TIncoming, TOutgoing> & {
1072
+ signal?: AbortSignal;
1073
+ };
1074
+ /** Executable WebSocket command produced by a `WebSocketEndpoint`. */
1075
+ export interface WebSocketCommand<TInput extends AnyStruct | undefined, TIncoming extends AnyStruct, TOutgoing extends AnyStruct | undefined> extends BaseCommand<typeof WEB_SOCKET_COMMAND> {
1076
+ readonly endpoint: WebSocketDefinition<TInput, TIncoming, TOutgoing>;
1077
+ readonly input: EndpointInput<TInput> | undefined;
1078
+ }
1079
+ /** Endpoint returned by `defineWebSocket`; call it to create a `WebSocketCommand`. */
1080
+ export type WebSocketEndpoint<TInput extends AnyStruct | undefined, TIncoming extends AnyStruct, TOutgoing extends AnyStruct | undefined> = EndpointCallable<TInput, WebSocketCommand<TInput, TIncoming, TOutgoing>>;
1081
+ /** Reason recorded when the session is closed via `session.close()`. */
1082
+ export type ManualSocketCloseReason = {
1083
+ code?: number;
1084
+ kind: 'manual-web-socket-close';
1085
+ reason?: string;
1086
+ };
1087
+ /** Heartbeat ping/ack configuration for a live WebSocket session. */
1088
+ export interface WebSocketHeartbeatConfig<TIncoming = unknown, TOutgoing = unknown> {
1089
+ intervalMs: number;
1090
+ isAck?: (message: TIncoming) => boolean;
1091
+ message?: () => TOutgoing;
1092
+ timeoutMs?: number;
1093
+ }
1094
+ /**
1095
+ * Declare a typed WebSocket endpoint.
1096
+ *
1097
+ * Pass path, incoming (and optional outgoing) message structs, and queue limits.
1098
+ * Call the returned endpoint with input to get a `WebSocketCommand` for `client.execute`.
1099
+ *
1100
+ * @param definition - WebSocket contract (path, structs, queue limits, optional input).
1101
+ * @returns An endpoint that creates `WebSocketCommand` values from input.
1102
+ *
1103
+ * @example
1104
+ * ```ts
1105
+ * const useChat = defineWebSocket({
1106
+ * maxIncomingQueueSize: 16,
1107
+ * path: '/ws/chat',
1108
+ * incoming: struct.object({ text: struct.string(), type: struct.literal('message') }),
1109
+ * outgoing: struct.object({ text: struct.string(), type: struct.literal('message') }),
1110
+ * })
1111
+ * ```
1112
+ */
1113
+ export declare function defineWebSocket<const P extends string, TInput extends AnyStruct | undefined = undefined, TIncoming extends AnyStruct = AnyStruct, TOutgoing extends AnyStruct | undefined = undefined>(definition: Omit<WebSocketDefinitionBase<TIncoming, TOutgoing>, 'path'> & {
1114
+ input?: TInput;
1115
+ path: P;
1116
+ } & BuilderField<NoInfer<TInput>, WebSocketRequestShape<NoInfer<P>>>): WebSocketEndpoint<TInput, TIncoming, TOutgoing>;
1117
+ /**
1118
+ * Open a WebSocket command against the given client config.
1119
+ *
1120
+ * Prefer `client.execute(command)` in application code; this is the low-level entry used by the client.
1121
+ *
1122
+ * @param clientConfig - Resolved client configuration.
1123
+ * @param command - WebSocket command from a `WebSocketEndpoint`.
1124
+ * @param options - Optional execute options (heartbeat, reconnect, abort).
1125
+ * @returns Await-result tuple of `[error, socket, connection]`.
1126
+ */
1127
+ export declare function executeWebSocketCommand<TInput extends AnyStruct | undefined, TIncoming extends AnyStruct, TOutgoing extends AnyStruct | undefined>(clientConfig: ClientConfig, command: WebSocketCommand<TInput, TIncoming, TOutgoing>, options?: WebSocketExecuteOptions<WebSocketIncomingData<TIncoming>, WebSocketOutgoingData<TOutgoing>>): Promise<SocketAwaitResult<WebSocketIncomingData<TIncoming>, WebSocketOutgoingData<TOutgoing>>>;
1128
+ /** Outcome of a single WebSocket connect attempt used by reconnect logic. */
1129
+ export type SocketLifecycleOutcome = {
1130
+ closeInfo: WebSocketCloseSnapshot;
1131
+ connection?: WebSocketConnectionInfo;
1132
+ cause?: unknown;
1133
+ opened: boolean;
1134
+ };
1135
+ //#endregion
1136
+ //#region src/interceptor/interceptor.d.ts
1137
+ /**
1138
+ * Continuation that runs the rest of the HTTP interceptor chain (or the handler).
1139
+ *
1140
+ * `next(req)` only goes **inward** — remaining interceptors registered after this one,
1141
+ * then the Fetch handler. It is not a re-dispatch of `client.execute` / `axios(config)`
1142
+ * from the outside of the onion. Call `next` again for a safe replay (for example one
1143
+ * 401 refresh) from the same interceptor; outer layers do not run a second time.
1144
+ */
1145
+ type HttpInterceptorNext = (req: HttpRequest) => Promise<HttpResponse<unknown>>;
1146
+ /**
1147
+ * HTTP interceptor function: may inspect/modify the request, then call `next`.
1148
+ */
1149
+ type InterceptorFn = (req: HttpRequest, next: HttpInterceptorNext) => Promise<HttpResponse<unknown>>;
1150
+ /**
1151
+ * Tagged HTTP interceptor for client option lists.
1152
+ */
1153
+ interface HttpInterceptor {
1154
+ kind: 'http';
1155
+ fn: InterceptorFn;
1156
+ }
1157
+ /**
1158
+ * Wrap an `InterceptorFn` as a tagged `HttpInterceptor`.
1159
+ *
1160
+ * @param fn - HTTP interceptor function.
1161
+ * @returns An `HttpInterceptor` with `kind: 'http'`.
1162
+ */
1163
+ export declare function createHttpInterceptor(fn: InterceptorFn): HttpInterceptor;
1164
+ /**
1165
+ * Terminal SSE handler that opens an event stream for the given request.
1166
+ */
1167
+ type SSEHandler = (req: HttpRequest) => Promise<EventStreamHandle<unknown>>;
1168
+ /**
1169
+ * SSE interceptor function: may inspect/modify the request, then call `next`.
1170
+ */
1171
+ type SSEInterceptorFn = (req: HttpRequest, next: SSEHandler) => Promise<EventStreamHandle<unknown>>;
1172
+ /**
1173
+ * Tagged SSE interceptor for client option lists.
1174
+ */
1175
+ interface SSEInterceptor {
1176
+ kind: 'sse';
1177
+ fn: SSEInterceptorFn;
1178
+ }
1179
+ /**
1180
+ * Wrap an `SSEInterceptorFn` as a tagged `SSEInterceptor`.
1181
+ *
1182
+ * @param fn - SSE interceptor function.
1183
+ * @returns An `SSEInterceptor` with `kind: 'sse'`.
1184
+ */
1185
+ export declare function createSSEInterceptor(fn: SSEInterceptorFn): SSEInterceptor;
1186
+ /**
1187
+ * Minimal WebSocket session surface used by interceptors.
1188
+ *
1189
+ * Structurally compatible with `WebSocketSession` without importing that type
1190
+ * (avoids a circular dependency between interceptors and WebSocket).
1191
+ */
1192
+ interface WebSocketSessionLike extends AsyncDisposable {
1193
+ readonly bufferedAmount: number;
1194
+ readonly connection: {
1195
+ extensions?: string;
1196
+ generation: number;
1197
+ protocol?: string;
1198
+ url?: string;
1199
+ };
1200
+ readonly closed: Promise<WebSocketCloseInfo>;
1201
+ readonly receive: AsyncIterable<unknown>;
1202
+ readonly state: WebSocketState;
1203
+ close(code?: number, reason?: string): void;
1204
+ [Symbol.asyncDispose](): PromiseLike<void>;
1205
+ onRuntimeError(listener: (error: unknown) => void): () => void;
1206
+ onStateChange(listener: (state: WebSocketState) => void): () => void;
1207
+ send(message: unknown): void;
1208
+ }
1209
+ /**
1210
+ * Terminal WebSocket handler that opens a session for the given request.
1211
+ */
1212
+ type WebSocketHandler = (req: HttpRequest) => Promise<WebSocketSessionLike>;
1213
+ /**
1214
+ * WebSocket interceptor function: may inspect/modify the request, then call `next`.
1215
+ */
1216
+ type WebSocketInterceptorFn = (req: HttpRequest, next: WebSocketHandler) => Promise<WebSocketSessionLike>;
1217
+ /**
1218
+ * Tagged WebSocket interceptor for client option lists.
1219
+ */
1220
+ interface WebSocketInterceptor {
1221
+ kind: 'web-socket';
1222
+ fn: WebSocketInterceptorFn;
1223
+ }
1224
+ /**
1225
+ * Wrap a `WebSocketInterceptorFn` as a tagged `WebSocketInterceptor`.
1226
+ *
1227
+ * @param fn - WebSocket interceptor function.
1228
+ * @returns A `WebSocketInterceptor` with `kind: 'web-socket'`.
1229
+ */
1230
+ export declare function createWebSocketInterceptor(fn: WebSocketInterceptorFn): WebSocketInterceptor;
1231
+ /**
1232
+ * Any tagged interceptor accepted by client interceptor options.
1233
+ */
1234
+ type Interceptor = HttpInterceptor | SSEInterceptor | WebSocketInterceptor;
1235
+ //#endregion
1236
+ //#region src/client/config.d.ts
1237
+ /**
1238
+ * Serializes an encoded query object into a query string.
1239
+ *
1240
+ * `query` is the wire object: aliases already applied, `Date` values already ISO
1241
+ * strings, `bigint` values already strings. Nested objects and arrays are preserved.
1242
+ * The returned string is used verbatim and is not passed through `URLSearchParams`.
1243
+ *
1244
+ * @param query - Encoded query object.
1245
+ * @returns The query string without a leading `?`.
1246
+ */
1247
+ type QuerySerializer = (query: {
1248
+ [key: string]: unknown;
1249
+ }) => string;
1250
+ /**
1251
+ * Fetch-compatible function used as an HTTP or SSE handle.
1252
+ *
1253
+ * This is the `(input, init?) => Promise<Response>` call signature Defjs invokes,
1254
+ * not `typeof fetch`, so mocks do not need host extras such as `preconnect`.
1255
+ */
1256
+ type FetchHandle = (input: RequestInfo | URL, init?: RequestInit) => Promise<Response>;
1257
+ /**
1258
+ * Minimal WebSocket-like handle used by the client transport.
1259
+ *
1260
+ * Omits browser event-handler properties so custom implementations only need
1261
+ * the send/close/state surface Defjs relies on.
1262
+ */
1263
+ type WebSocketHandle = Omit<WebSocket, 'binaryType' | 'CLOSED' | 'CLOSING' | 'CONNECTING' | 'dispatchEvent' | 'onclose' | 'onerror' | 'onmessage' | 'onopen' | 'OPEN' | 'readyState'> & {
1264
+ readonly readyState: number;
181
1265
  };
1266
+ /** Constructor for a `WebSocketHandle`, including the `OPEN` ready-state constant. */
1267
+ type WebSocketHandleConstructor = {
1268
+ readonly OPEN: number;
1269
+ } & (new (...args: never[]) => WebSocketHandle);
1270
+ /** Optional WebSocket settings applied when creating a client. */
1271
+ interface ClientWebSocketOptions {
1272
+ /** WebSocket constructor; defaults to `globalThis.WebSocket`. */
1273
+ handle?: WebSocketHandleConstructor;
1274
+ /** Hook before each connect/reconnect attempt. */
1275
+ beforeConnect?: (context: {
1276
+ attempt: number;
1277
+ signal: AbortSignal;
1278
+ }) => void | Promise<void>;
1279
+ /** Periodic heartbeat ping and optional ACK matching. */
1280
+ heartbeat?: {
1281
+ /** Delay between heartbeat messages. */
1282
+ intervalMs: number;
1283
+ /** Returns whether an incoming message acknowledges the heartbeat. */
1284
+ isAck?: (message: unknown) => boolean;
1285
+ /** Builds the outbound heartbeat payload. */
1286
+ message?: <T = unknown>() => T | unknown;
1287
+ /** Time to wait for an ACK before treating the connection as unhealthy. */
1288
+ timeoutMs?: number;
1289
+ };
1290
+ /** Subprotocols passed to the WebSocket constructor. */
1291
+ protocols?: readonly string[];
1292
+ /** Automatic reconnect policy after unexpected closes. */
1293
+ reconnect?: {
1294
+ /** Retry budget after the first connect. Defaults to 3 when `reconnect` is set. `0` disables. Omitting this field is not unlimited. */
1295
+ attempts?: number;
1296
+ /** Initial backoff delay in milliseconds. */
1297
+ delayMs?: number;
1298
+ /** Multiplier applied to the delay after each failed attempt. */
1299
+ factor?: number;
1300
+ /** Random jitter factor applied to the delay (0–1). */
1301
+ jitter?: number;
1302
+ /** Upper bound for computed backoff delay. */
1303
+ maxDelayMs?: number;
1304
+ /** Return `false` to skip reconnecting for this close. */
1305
+ shouldReconnect?: (context: {
1306
+ attempt: number;
1307
+ cause?: unknown;
1308
+ code?: number;
1309
+ reason?: string;
1310
+ wasClean?: boolean;
1311
+ }) => boolean;
1312
+ };
1313
+ }
1314
+ /** Optional SSE settings applied when creating a client. */
1315
+ interface ClientSSEOptions {
1316
+ /** Fetch implementation used to open the event stream. */
1317
+ handle?: FetchHandle;
1318
+ /** Called when an event has no matching struct or fails validation. */
1319
+ onInvalidEvent?: (context: {
1320
+ reason: 'missing-struct' | 'validation-failed';
1321
+ message: {
1322
+ id: string;
1323
+ event: string;
1324
+ data: string;
1325
+ };
1326
+ cause?: unknown;
1327
+ signal: AbortSignal;
1328
+ }) => unknown;
1329
+ /** Automatic reconnect policy after stream failures. */
1330
+ reconnect?: {
1331
+ /** Retry budget after the first attempt. Defaults to 3 when `reconnect` is set. `0` disables. Omitting this field is not unlimited. */
1332
+ attempts?: number;
1333
+ /** Initial backoff delay in milliseconds. */
1334
+ delayMs?: number;
1335
+ /** Multiplier applied to the delay after each failed attempt. */
1336
+ factor?: number;
1337
+ /** Random jitter factor applied to the delay (0–1). */
1338
+ jitter?: number;
1339
+ /** Upper bound for computed backoff delay. */
1340
+ maxDelayMs?: number;
1341
+ /** Return `false` to skip reconnecting for this failure. */
1342
+ shouldReconnect?: (context: {
1343
+ attempt: number;
1344
+ cause?: unknown;
1345
+ lastEventId: string;
1346
+ open?: {
1347
+ response: {
1348
+ status: number;
1349
+ statusText: string;
1350
+ url: string;
1351
+ };
1352
+ url: string;
1353
+ };
1354
+ }) => boolean | Promise<boolean>;
1355
+ };
1356
+ }
1357
+ /** Resolved SSE config with a required `handle`. */
1358
+ interface ClientSSEConfig extends ClientSSEOptions {
1359
+ /** Fetch implementation used to open the event stream. */
1360
+ handle: FetchHandle;
1361
+ }
1362
+ /** User-facing HTTP client options before defaults are applied. */
1363
+ interface HttpClientOptions {
1364
+ /** Base URL prepended to relative request paths. */
1365
+ endpoint: string;
1366
+ /** Static default headers merged under command headers for HTTP/SSE. */
1367
+ headers?: Headers;
1368
+ /** HTTP transport overrides. */
1369
+ http?: {
1370
+ handle?: FetchHandle;
1371
+ };
1372
+ /** Interceptors applied in registration order. */
1373
+ interceptors?: Interceptor[];
1374
+ /** Serializes encoded query objects. Omit to use `URLSearchParams`. */
1375
+ querySerializer?: QuerySerializer;
1376
+ /** Default HTTP execute timeout in milliseconds (SSE/WebSocket ignore this). */
1377
+ timeout?: number;
1378
+ /** XSRF cookie/header mapping and optional token provider. */
1379
+ xsrf?: {
1380
+ /** Cookie name that stores the XSRF token. */
1381
+ cookieName?: string;
1382
+ /** Request header name that receives the token. */
1383
+ headerName?: string;
1384
+ /** Supplies a token instead of reading the cookie. */
1385
+ tokenProvider?: (context: {
1386
+ request: HttpRequest;
1387
+ }) => string | null | undefined;
1388
+ };
1389
+ /** When `true`, credentials are included with requests. */
1390
+ withCredentials?: boolean;
1391
+ }
1392
+ /** User-facing options for `createClient`, including SSE and WebSocket. */
1393
+ interface ClientOptions extends HttpClientOptions {
1394
+ /** SSE transport and reconnect options. */
1395
+ sse?: ClientSSEOptions;
1396
+ /** WebSocket transport, heartbeat, and reconnect options. */
1397
+ webSocket?: ClientWebSocketOptions;
1398
+ }
1399
+ /** Resolved HTTP client config after defaults and options are applied. */
1400
+ interface HttpClientConfig {
1401
+ /** Base URL prepended to relative request paths. */
1402
+ endpoint: string;
1403
+ /** Static default headers merged under command headers for HTTP/SSE. */
1404
+ headers?: Headers;
1405
+ /** HTTP transport with a required fetch handle. */
1406
+ http: {
1407
+ handle: FetchHandle;
1408
+ };
1409
+ /** Interceptors applied in registration order. */
1410
+ interceptors: Interceptor[];
1411
+ /** Serializes encoded query objects. Omit to use `URLSearchParams`. */
1412
+ querySerializer?: QuerySerializer;
1413
+ /** Default HTTP execute timeout in milliseconds (SSE/WebSocket ignore this). */
1414
+ timeout?: number;
1415
+ /** Resolved XSRF settings when enabled. */
1416
+ xsrf?: {
1417
+ /** Cookie name that stores the XSRF token. */
1418
+ cookieName: string;
1419
+ /** Request header name that receives the token. */
1420
+ headerName: string;
1421
+ /** Supplies a token instead of reading the cookie. */
1422
+ tokenProvider?: (context: {
1423
+ request: HttpRequest;
1424
+ }) => string | null | undefined;
1425
+ };
1426
+ /** When `true`, credentials are included with requests. */
1427
+ withCredentials?: boolean;
1428
+ }
1429
+ /** Resolved client config held by instances from `createClient`. */
1430
+ interface ClientConfig extends HttpClientConfig {
1431
+ /** Resolved SSE configuration. */
1432
+ sse: ClientSSEConfig;
1433
+ /** Resolved WebSocket configuration. */
1434
+ webSocket: ClientWebSocketOptions;
1435
+ }
1436
+ //#endregion
1437
+ //#region src/client/option.d.ts
1438
+ /** Mutates `ClientConfig` when applied by `createClient`. */
1439
+ type ClientOption = (config: ClientConfig) => void;
1440
+ /**
1441
+ * Sets the base URL prepended to relative request paths.
1442
+ *
1443
+ * @param endpoint - Absolute or relative base endpoint.
1444
+ * @returns An option that writes `config.endpoint`.
1445
+ */
1446
+ export declare function withEndpoint(endpoint: string): ClientOption;
1447
+ /**
1448
+ * Sets static default headers for HTTP/SSE requests built by this client.
1449
+ *
1450
+ * Builder `headers` override the same names. HMAC and
1451
+ * dynamic Bearer tokens still belong in interceptors (they need the serialized body
1452
+ * or a refreshed credential).
1453
+ *
1454
+ * @param headers - `HeadersInit` bag cloned onto the client config.
1455
+ * @returns An option that writes `config.headers`.
1456
+ */
1457
+ export declare function withHeaders(headers: HeadersInit): ClientOption;
1458
+ /**
1459
+ * Sets the default timeout for HTTP `execute` only.
1460
+ *
1461
+ * Timeout is applied before the interceptor chain (`mergeAbortSignals`). Execute
1462
+ * `{ timeout }` overrides this default. Execute `{ abort }` combines with the
1463
+ * default (abort → `ABORTED`, timer → `TIMEOUT`). SSE and WebSocket ignore this
1464
+ * option. XOR still rejects execute options that pass both `abort` and `timeout`.
1465
+ *
1466
+ * @param ms - Positive safe integer timeout in milliseconds.
1467
+ * @returns An option that writes `config.timeout`.
1468
+ */
1469
+ export declare function withTimeout(ms: number): ClientOption;
1470
+ /**
1471
+ * Appends interceptors to the client interceptor chain.
1472
+ *
1473
+ * @param interceptors - Interceptors applied in registration order.
1474
+ * @returns An option that pushes onto `config.interceptors`.
1475
+ */
1476
+ export declare function withInterceptors(...interceptors: Interceptor[]): ClientOption;
1477
+ /**
1478
+ * Sets the query serializer for HTTP, SSE, and WebSocket requests.
1479
+ *
1480
+ * The function receives the encoded wire object and its string is used verbatim.
1481
+ * Without this option, queries use `URLSearchParams`: arrays repeat keys and a nested
1482
+ * object fails. A builder that returns `URLSearchParams` skips this serializer.
1483
+ *
1484
+ * @param serializer - Function that turns an encoded query object into a string.
1485
+ * @returns An option that sets `config.querySerializer`.
1486
+ */
1487
+ export declare function withQuerySerializer(serializer: QuerySerializer): ClientOption;
1488
+ /**
1489
+ * Overrides the Fetch-compatible function used for HTTP requests.
1490
+ *
1491
+ * @param fetchImpl - `(input, init?) => Promise<Response>`. Not `typeof fetch`, so
1492
+ * a mock does not need host extras such as `preconnect`.
1493
+ * @returns An option that sets `config.http.handle`.
1494
+ */
1495
+ export declare function withHTTPHandle(fetchImpl: FetchHandle): ClientOption;
1496
+ /**
1497
+ * Overrides the Fetch-compatible function used for SSE connections.
1498
+ *
1499
+ * @param fetchImpl - `(input, init?) => Promise<Response>`. Not `typeof fetch`, so
1500
+ * a mock does not need host extras such as `preconnect`.
1501
+ * @returns An option that sets `config.sse.handle`.
1502
+ */
1503
+ export declare function withSSEHandle(fetchImpl: FetchHandle): ClientOption;
1504
+ /**
1505
+ * Overrides the WebSocket constructor used for socket connections.
1506
+ *
1507
+ * @param WebSocketImpl - Constructor that returns a `WebSocketHandle`.
1508
+ * @returns An option that sets `config.webSocket.handle`.
1509
+ */
1510
+ export declare function withWebSocketHandle(WebSocketImpl: WebSocketHandleConstructor): ClientOption;
1511
+ /**
1512
+ * Runs logic before each WebSocket connect or reconnect attempt.
1513
+ *
1514
+ * @param beforeConnect - Hook receiving attempt index and abort signal.
1515
+ * @returns An option that sets `config.webSocket.beforeConnect`.
1516
+ */
1517
+ export declare function withWebSocketBeforeConnect(beforeConnect: ClientWebSocketOptions['beforeConnect']): ClientOption;
1518
+ /**
1519
+ * Configure WebSocket subprotocols for the connection handshake.
1520
+ *
1521
+ * `protocols` are passed as the second argument to the `WebSocket` constructor
1522
+ * and participate in the RFC 6455 subprotocol negotiation. They are only
1523
+ * meaningful when the server requires a specific protocol (for example,
1524
+ * `['json']` or `['v1']` to select a message encoding version).
1525
+ *
1526
+ * @param protocols - Subprotocol list for the WebSocket constructor.
1527
+ * @returns An option that sets `config.webSocket.protocols`.
1528
+ */
1529
+ export declare function withWebSocketProtocols(protocols: readonly string[]): ClientOption;
1530
+ /**
1531
+ * Enables WebSocket heartbeat pings and optional ACK detection.
1532
+ *
1533
+ * @param options - Heartbeat interval, payload, timeout, and ACK predicate.
1534
+ * @returns An option that sets `config.webSocket.heartbeat`.
1535
+ */
1536
+ export declare function withWebSocketHeartbeat(options: ClientWebSocketOptions['heartbeat']): ClientOption;
1537
+ /**
1538
+ * Configures automatic WebSocket reconnection after unexpected closes.
1539
+ *
1540
+ * @param options - Retry budget, backoff, and `shouldReconnect` gate.
1541
+ * @returns An option that sets `config.webSocket.reconnect`.
1542
+ */
1543
+ export declare function withWebSocketReconnect(options: ClientWebSocketOptions['reconnect']): ClientOption;
1544
+ /**
1545
+ * Handles SSE events that lack a matching struct or fail validation.
1546
+ *
1547
+ * @param handler - Callback for invalid events; may throw or return a value.
1548
+ * @returns An option that sets `config.sse.onInvalidEvent`.
1549
+ */
1550
+ export declare function withSSEOnInvalidEvent(handler: ClientSSEOptions['onInvalidEvent']): ClientOption;
1551
+ /**
1552
+ * Configures automatic SSE reconnection after stream failures.
1553
+ *
1554
+ * @param options - Retry budget, backoff, and `shouldReconnect` gate.
1555
+ * @returns An option that sets `config.sse.reconnect`.
1556
+ */
1557
+ export declare function withSSEReconnect(options: ClientSSEOptions['reconnect']): ClientOption;
1558
+ /**
1559
+ * Enables XSRF cookie-to-header token forwarding for HTTP requests.
1560
+ *
1561
+ * Defaults to cookie `XSRF-TOKEN` and header `X-XSRF-TOKEN` when names are omitted.
1562
+ *
1563
+ * @param options - Cookie/header names and optional token provider.
1564
+ * @returns An option that sets `config.xsrf`.
1565
+ */
1566
+ export declare function withXSRF(options?: HttpClientOptions['xsrf']): ClientOption;
1567
+ /**
1568
+ * Sets whether HTTP/SSE requests should include credentials (cookies).
1569
+ *
1570
+ * @param value - When `true`, credentials are sent with cross-origin requests.
1571
+ * @returns An option that sets `config.withCredentials`.
1572
+ */
1573
+ export declare function withCredentials(value: boolean): ClientOption;
1574
+ //#endregion
1575
+ //#region src/client/client.d.ts
182
1576
  declare const CLIENT: unique symbol;
183
- export type Client = {
184
- readonly [CLIENT]: ClientConfig;
185
- };
186
- export declare function isClient(value: unknown): value is Client;
187
- export declare function createClient(options: ClientOptions): Client;
188
- export declare function cloneClient(client: Client, options: Partial<ClientOptions>): Client;
189
- export declare function getGlobalClient(): Client;
190
- export declare function setGlobalClient(client: Client): void;
191
- export declare function restGlobalClient(): void;
192
- export declare function createGlobalClient(options: ClientOptions): void;
193
-
194
- export {};
1577
+ /**
1578
+ * Defjs client: holds config and `execute`s HTTP, SSE, and WebSocket commands.
1579
+ */
1580
+ type Client = {
1581
+ readonly [CLIENT]: ClientConfig;
1582
+ /** Open an SSE command and return stream open/await results. */
1583
+ execute<TInput extends AnyStruct | undefined, TEvents extends EventStructs, TError extends AnyStruct | undefined = undefined>(command: EventStreamCommand<TInput, TEvents, TError>, options?: EventStreamExecuteOptions): Promise<StreamAwaitResult<EventStreamData<TEvents>, TError>>;
1584
+ /** Open a WebSocket command and return session await results. */
1585
+ execute<TInput extends AnyStruct | undefined, TIncoming extends AnyStruct, TOutgoing extends AnyStruct | undefined>(command: WebSocketCommand<TInput, TIncoming, TOutgoing>, options?: WebSocketExecuteOptions<WebSocketIncomingData<TIncoming>, WebSocketOutgoingData<TOutgoing>>): Promise<SocketAwaitResult<WebSocketIncomingData<TIncoming>, WebSocketOutgoingData<TOutgoing>>>;
1586
+ /** Run an HTTP command and return an await-result tuple. */
1587
+ execute<TInput extends AnyStruct | undefined, TOutput extends AnyStruct | undefined, TError extends AnyStruct | undefined>(command: HttpCommand<TInput, TOutput, TError>, options?: HttpExecuteOptions): ReturnType<typeof executeHttpCommand<TInput, TOutput, TError>>;
1588
+ };
1589
+ /**
1590
+ * Create a Defjs client from option helpers.
1591
+ *
1592
+ * Options are applied in order. Prefer creating the client inside the
1593
+ * request boundary when interceptors close over auth or tenants.
1594
+ *
1595
+ * @param options - Client option helpers such as `withEndpoint`.
1596
+ * @returns A client that can `execute` HTTP, SSE, and WebSocket commands.
1597
+ *
1598
+ * @example
1599
+ * ```ts
1600
+ * const client = createClient(withEndpoint('https://api.example.com'))
1601
+ * ```
1602
+ */
1603
+ export declare function createClient(...options: ClientOption[]): Client;
1604
+ //#endregion
1605
+ //#region src/http/transport/fetch.d.ts
1606
+ /**
1607
+ * Default HTTP transport: perform `httpRequest` with `fetch` and return an `HttpResponse`.
1608
+ * Used by the client unless `withHTTPHandle` replaces it; also usable in tests and custom handlers.
1609
+ *
1610
+ * @param httpRequest - Normalized request (URL, headers, body, abort, progress hooks).
1611
+ * @param fetchImpl - Fetch implementation; defaults to global `fetch`. The library default handle is called as
1612
+ * `(url, init)` and its body is read in one piece unless download progress is observed. Any other handle receives a
1613
+ * `Request` and its body is read chunk by chunk.
1614
+ * @returns Parsed `HttpResponse`. Rejects when no response reached the client, or when reading the
1615
+ * body failed — a transport failure is a fault, never a response.
1616
+ */
1617
+ export declare function fetchHandler(httpRequest: HttpRequest, fetchImpl?: FetchHandle): Promise<HttpResponse<unknown>>;
1618
+ //#endregion
1619
+ //#region src/internal/url.d.ts
1620
+ export declare function createResolvedRequestUrl(baseEndpoint: string, path: string, queryString?: string): URL;
1621
+ //#endregion
1622
+ //#region src/interceptor/basic_auth.d.ts
1623
+ type BasicCredential = {
1624
+ username: string;
1625
+ password: string;
1626
+ };
1627
+ /**
1628
+ * Options for basic-auth interceptors, including a custom credential encoder.
1629
+ */
1630
+ type BasicAuthInterceptorOptions = {
1631
+ encode?: (credential: BasicCredential) => string;
1632
+ };
1633
+ /**
1634
+ * HTTP interceptor that sets an `Authorization: Basic …` header from credentials.
1635
+ *
1636
+ * @param fn - Factory returning username/password for each request.
1637
+ * @param options - Optional custom encoder (defaults to `btoa`).
1638
+ * @returns An `HttpInterceptor` that injects basic auth.
1639
+ */
1640
+ export declare function basicAuthHttpInterceptor(fn: () => BasicCredential, options?: BasicAuthInterceptorOptions): HttpInterceptor;
1641
+ /**
1642
+ * SSE interceptor that sets an `Authorization: Basic …` header from credentials.
1643
+ *
1644
+ * @param fn - Factory returning username/password for each request.
1645
+ * @param options - Optional custom encoder (defaults to `btoa`).
1646
+ * @returns An `SSEInterceptor` that injects basic auth.
1647
+ */
1648
+ export declare function basicAuthSSEInterceptor(fn: () => BasicCredential, options?: BasicAuthInterceptorOptions): SSEInterceptor;
1649
+ //#endregion
1650
+ export type { AnyStruct, BasicAuthInterceptorOptions, BuilderInput, Client, ClientConfig, ClientOption, ClientOptions, ClientSSEConfig, ClientSSEOptions, ClientWebSocketOptions, DecodedResponse, ErrorMap, EventStreamCloseInfo, EventStreamFaultCode, EventStreamHandle, EventStreamOpenInfo, EventStreamRequestShape, FetchHandle, FlattenedStructError, FormattedStructError, HttpInterceptor, HttpInterceptorNext, HttpMeta, HttpProgressEvent, HttpProgressFn, HttpRequest, HttpRequestShape, HttpResponse, HttpResponseType, Infer, Interceptor, InterceptorFn, MakeResponseOptions, ObjectStruct, ParseResult, QuerySerializer, SSEHandler, SSEInterceptor, SSEInterceptorFn, STRUCT, Struct, StructInput, StructIssue, StructLike, StructMethods, WebSocketHandle, WebSocketHandleConstructor, WebSocketHandler, WebSocketInterceptor, WebSocketInterceptorFn, WebSocketRequestShape, WebSocketSessionLike };