@defjs/core 0.4.0 → 0.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (5) hide show
  1. package/README.md +25 -71
  2. package/index.d.ts +363 -516
  3. package/index.js +701 -963
  4. package/index.min.js +20 -20
  5. package/package.json +1 -1
package/index.d.ts CHANGED
@@ -37,8 +37,8 @@ interface HttpProgressEvent {
37
37
  * Callbacks may be async and are awaited before the next chunk is processed. A
38
38
  * callback that throws or rejects fails the call with `EXT_OBSERVER_FAILED`,
39
39
  * with the thrown value as `cause`, for downloads and uploads alike. Caller
40
- * cancellation and `timeout` still take precedence and report `NET_ABORTED` or
41
- * `NET_TIMEOUT`.
40
+ * cancellation still takes precedence and reports `NET_ABORTED`, or `NET_TIMEOUT`
41
+ * when the abort reason is a timeout.
42
42
  *
43
43
  * Upload progress for a `Blob`, `File`, `ArrayBuffer`, or `FormData` body is
44
44
  * reported only where the runtime can stream request bodies (Bun, Node). In
@@ -48,8 +48,8 @@ interface HttpProgressEvent {
48
48
  *
49
49
  * On server runtimes, FormData with `onUploadProgress` reads its serialized
50
50
  * stream directly, keeps its multipart boundary, and is sent without a
51
- * library-generated `Content-Length` (chunked over HTTP/1.1), so progress,
52
- * timeout, and abort work without buffering the whole body. It reports an
51
+ * library-generated `Content-Length` (chunked over HTTP/1.1), so progress
52
+ * and abort work without buffering the whole body. It reports an
53
53
  * unknown total unless a valid explicit `Content-Length` supplies it. For an
54
54
  * endpoint that requires `Content-Length`, such as some presigned upload
55
55
  * targets, omit `onUploadProgress`; platform Fetch then sends FormData with its
@@ -111,7 +111,6 @@ interface HttpRequest {
111
111
  * unread and does not fall back to `responseType`.
112
112
  */
113
113
  readonly errorResponseType?: HttpResponseType;
114
- timeout?: number;
115
114
  uploadProgress?: HttpProgressFn;
116
115
  withCredentials?: boolean;
117
116
  xsrf?: {
@@ -501,7 +500,7 @@ interface PreservedStruct<T, I, O, OO extends boolean> extends Struct<I, O, OO>,
501
500
  /**
502
501
  * Broad struct constraint that accepts any struct, for endpoint and client generics.
503
502
  *
504
- * Used by generics such as `defineRequest`, `Fault`, and `HttpCommand`. Prefer a concrete `Struct<…>` when you need precise input and output inference.
503
+ * Used by generics such as `defineRequest` and `Fault`. Prefer a concrete `Struct<…>` when you need precise input and output inference.
505
504
  *
506
505
  * @group struct
507
506
  */
@@ -655,7 +654,7 @@ interface IntersectionStruct<T extends readonly StructLike<unknown, unknown, boo
655
654
  * | Class | Meaning |
656
655
  * | ------ | -------------------------------------------------------------- |
657
656
  * | `HTTP` | The peer answered with a non-2xx status. |
658
- * | `REQ` | The request never left: input, execute options, or build. |
657
+ * | `REQ` | The request never left: input, request options, or build. |
659
658
  * | `NET` | No usable response: cancel, timeout, connect, truncated body. |
660
659
  * | `RES` | A response arrived but could not be read as declared. |
661
660
  * | `EXT` | Code you attached to the pipeline threw. |
@@ -762,7 +761,7 @@ export type PreflightFault = Error & {
762
761
  response?: HttpMeta;
763
762
  };
764
763
  /**
765
- * Any failure returned by `client.execute`, expressed by its decoded error-body type.
764
+ * Any failure returned by an operation, expressed by its decoded error-body type.
766
765
  *
767
766
  * `Fault<TErr>` is `FaultOf` applied to `Infer<TErr>`, and `HttpAwaitResult` uses
768
767
  * `FaultOf<TErrorData>`. Pass a decoded type, not a struct: write
@@ -773,7 +772,7 @@ export type PreflightFault = Error & {
773
772
  */
774
773
  export type FaultOf<TData = undefined> = DecodeFault | HttpStatusFaultOf<TData> | PreflightFault;
775
774
  /**
776
- * Union of every failure `client.execute` can return, discriminated by `code`.
775
+ * Union of every failure an operation can return, discriminated by `code`.
777
776
  *
778
777
  * `Fault<TErr>` is {@link FaultOf} applied to the decoded body type, so it is the
779
778
  * union of {@link DecodeFault}, {@link HttpStatusFault}<TErr>, and
@@ -1380,7 +1379,7 @@ interface EventStreamMessage {
1380
1379
  /**
1381
1380
  * Metadata available once an SSE response has opened.
1382
1381
  *
1383
- * `response` is the handshake response and `url` is the resolved request URL. It is the third element of a successful `client.execute` result and the value of `EventStreamHandle.open`.
1382
+ * `response` is the handshake response and `url` is the resolved request URL. It is the third element of a successful event-stream result and the value of `EventStreamHandle.open`.
1384
1383
  *
1385
1384
  * @group sse
1386
1385
  */
@@ -1420,7 +1419,7 @@ type EventStreamCloseInfo = (EventStreamCloseInfoBase & {
1420
1419
  /**
1421
1420
  * Open SSE stream: iterate events, read open metadata, and close early.
1422
1421
  *
1423
- * `EventStreamMessage` is the raw `{ id: string; event: string; data: string }` message. Handles returned by `client.execute` carry parsed {@link EventStreamData}.
1422
+ * `EventStreamMessage` is the raw `{ id: string; event: string; data: string }` message. Handles returned by an event-stream operation carry parsed {@link EventStreamData}.
1424
1423
  *
1425
1424
  * `open` is the startup snapshot ({@link EventStreamOpenInfo}); after a reconnect it can change, so read `stream.open` again. `closed` resolves with an {@link EventStreamCloseInfo} when the stream ends.
1426
1425
  *
@@ -1443,16 +1442,8 @@ interface EventStreamHandle<TEvent = EventStreamMessage> extends AsyncIterable<T
1443
1442
  close(reason?: unknown): void;
1444
1443
  [Symbol.asyncDispose](): PromiseLike<void>;
1445
1444
  }
1446
- type UseCancellationConfig = {
1447
- abort?: AbortSignal;
1448
- timeout?: never;
1449
- } | {
1450
- abort?: never;
1451
- timeout?: number;
1452
- };
1453
- type EndpointInput<TInput extends AnyStruct | undefined> = TInput extends AnyStruct ? StructInput<TInput> : unknown;
1454
- type IsEndpointInputOptional<TInput extends AnyStruct | undefined> = [TInput] extends [undefined] ? true : undefined extends EndpointInput<TInput> ? true : false;
1455
- type EndpointCallable<TInput extends AnyStruct | undefined, TCommand> = [TInput] extends [undefined] ? () => TCommand : IsEndpointInputOptional<TInput> extends true ? (input?: EndpointInput<TInput>) => TCommand : (input: EndpointInput<TInput>) => TCommand;
1445
+ /** Argument list after the client, decided by the input struct. */
1446
+ type EndpointArgs<S extends AnyStruct | undefined> = [S] extends [undefined] ? [] : undefined extends StructInput<S> ? [input?: StructInput<S>] : [input: StructInput<S>];
1456
1447
  /** Object produced by endpoint input parsing. The symbol points at the struct that produced the node. */
1457
1448
  type Typed = {
1458
1449
  readonly [STRUCT]: AnyStruct;
@@ -1570,359 +1561,14 @@ type BuilderInput<S> = S extends CarriedStruct<infer Inner> ? NullishBuilderInpu
1570
1561
  [key: string]: BuilderInput<Value>;
1571
1562
  } : 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>;
1572
1563
  type BuilderField<TInput, TShape> = [TInput] extends [undefined] ? {
1573
- /** Pure, synchronous request builder, evaluated when the command runs. Optional without input. */
1564
+ /** Pure, synchronous request builder, evaluated when the operation runs. Optional without input. */
1574
1565
  builder?: () => TShape;
1575
1566
  } : {
1576
- /** Pure, synchronous function that explicitly places parsed input on the request when the command runs. */
1567
+ /** Pure, synchronous function that explicitly places parsed input on the request when the operation runs. */
1577
1568
  builder: (input: BuilderInput<TInput>) => TShape;
1578
1569
  };
1579
1570
  /** Accepts any concrete builder. `never` keeps the parameter contravariant. */
1580
1571
  type OutboundBuilder = (input: never) => unknown;
1581
- /**
1582
- * Per-request options for HTTP execution: progress callbacks and cancellation.
1583
- *
1584
- * The HTTP-specific part of {@link HttpExecuteOptions}, which adds `signal`.
1585
- * `onDownloadProgress` and `onUploadProgress` are {@link HttpProgressFn}
1586
- * callbacks. They receive an {@link HttpProgressEvent} with `loaded`, `total`,
1587
- * and `lengthComputable`.
1588
- *
1589
- * Cancellation is either `abort` or `timeout`, never both. The type rejects
1590
- * both, and at runtime passing both fails with a `REQ_OPTIONS_INVALID` fault.
1591
- * `timeout` must be a positive safe integer no greater than `2_147_483_647`.
1592
- * It replaces the default set by {@link withTimeout} for that call. `abort`
1593
- * combines with that default instead.
1594
- *
1595
- * @group http
1596
- */
1597
- export type UseRequestConfig = {
1598
- onDownloadProgress?: HttpProgressFn;
1599
- onUploadProgress?: HttpProgressFn;
1600
- } & UseCancellationConfig;
1601
- /**
1602
- * Opaque executable HTTP command produced by a `defineRequest` endpoint.
1603
- *
1604
- * Created by calling a `RequestEndpoint` with input. It carries the request
1605
- * definition and optional typed input for `client.execute`. Treat it as opaque
1606
- * and pass it to `client.execute`.
1607
- *
1608
- * @group http
1609
- */
1610
- export interface HttpCommand<TInput extends AnyStruct | undefined, TOutput extends AnyStruct | undefined, TError extends AnyStruct | undefined = undefined> extends BaseCommand<typeof HTTP_COMMAND> {
1611
- readonly definition: RequestDefinition<TInput, TOutput, TError>;
1612
- readonly input: EndpointInput<TInput> | undefined;
1613
- }
1614
- /**
1615
- * Options passed to `client.execute` or `executeHttpCommand` for one HTTP call: progress, `abort` or `timeout`, and `signal`.
1616
- *
1617
- * Cancellation is `abort` or `timeout`, not both (`abort` XOR `timeout`).
1618
- * `signal` combines with either; it is not an alias for `abort`. Valid shapes:
1619
- * `{ timeout }`, `{ abort }`, `{ signal, timeout }`, `{ signal, abort }`.
1620
- * `{ abort, timeout }` is invalid and makes the call resolve with a
1621
- * `REQ_OPTIONS_INVALID` fault. `timeout` must be a positive safe integer in
1622
- * `1..2_147_483_647`.
1623
- *
1624
- * When `timeout` is omitted, the client's `withTimeout` default applies;
1625
- * `abort` combines with that default.
1626
- *
1627
- * @group http
1628
- */
1629
- export type HttpExecuteOptions = UseRequestConfig & {
1630
- signal?: AbortSignal;
1631
- };
1632
- /**
1633
- * Callable endpoint returned by `defineRequest`.
1634
- *
1635
- * Call it to get an `HttpCommand`: with no arguments when the endpoint declares
1636
- * no `input`, with an optional argument when the input struct accepts
1637
- * `undefined`, and otherwise with the struct's input value.
1638
- *
1639
- * @group http
1640
- */
1641
- export type RequestEndpoint<TInput extends AnyStruct | undefined, TOutput extends AnyStruct | undefined, TError extends AnyStruct | undefined = undefined> = EndpointCallable<TInput, HttpCommand<TInput, TOutput, TError>>;
1642
- type DeclaredBody<TStruct> = [TStruct] extends [undefined] ? undefined : Infer<TStruct>;
1643
- type DeclaredResponse<TStruct> = [TStruct] extends [undefined] ? HttpMeta : DecodedResponse<Infer<TStruct>>;
1644
- /**
1645
- * Decoded success body for the declared `output` struct, or `undefined` when none is declared.
1646
- *
1647
- * @group http
1648
- */
1649
- export type RequestSuccessData<TOutput extends AnyStruct | undefined> = DeclaredBody<TOutput>;
1650
- /**
1651
- * Decoded error body for the declared `error` struct, or `undefined` when none is declared.
1652
- *
1653
- * @group http
1654
- */
1655
- export type RequestErrorData<TError extends AnyStruct | undefined> = DeclaredBody<TError>;
1656
- type ResponseDeclaration<TOutput extends AnyStruct | undefined, TError extends AnyStruct | undefined> = ([TOutput] extends [undefined] ? {
1657
- output?: never;
1658
- } : {
1659
- output: TOutput;
1660
- }) & ([TError] extends [undefined] ? {
1661
- error?: never;
1662
- } : {
1663
- error: TError;
1664
- });
1665
- /**
1666
- * Contract for an HTTP endpoint: method, path, optional input, and the structs that decode its bodies.
1667
- *
1668
- * Declaring `input` requires an explicit `builder` to place the parsed value on
1669
- * the request. `input` only defines the parameters; the builder alone decides
1670
- * where each value goes. Only definitions without `input` may omit `builder`.
1671
- * `output` declares the body for a 2xx response, `error` the body for anything
1672
- * else. Only one of the two ever runs, and omitting one means that body is never
1673
- * read. `ResponseDeclaration` is an internal helper type: `output` and `error`
1674
- * are required only when the matching type parameter is a struct. There is no
1675
- * `responseType`: the struct kind selects how a declared body is read. Pass to
1676
- * `defineRequest` to get a typed endpoint.
1677
- *
1678
- * @group http
1679
- */
1680
- export type RequestDefinition<TInput extends AnyStruct | undefined = undefined, TOutput extends AnyStruct | undefined = undefined, TError extends AnyStruct | undefined = undefined> = ResponseDeclaration<TOutput, TError> & {
1681
- builder?: OutboundBuilder;
1682
- input?: TInput;
1683
- method: string;
1684
- operation?: string;
1685
- path: string;
1686
- };
1687
- /**
1688
- * Await-result tuple for an HTTP call: success is `[null, data, response]`, and failure is `[fault, undefined, undefined]`.
1689
- *
1690
- * `TData` and `TErrorData` are decoded body types. On success the third slot
1691
- * carries `body` only when `output` was declared. On failure it is `undefined`,
1692
- * because the fault already holds whatever response metadata existed.
1693
- *
1694
- * @group http
1695
- */
1696
- 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];
1697
- 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];
1698
- /**
1699
- * Declares a typed HTTP request endpoint.
1700
- *
1701
- * Pass method, path, an optional input struct, and the single `output` and
1702
- * `error` structs. Call the returned endpoint with input to get an `HttpCommand`
1703
- * for `client.execute`.
1704
- *
1705
- * The contract is `method`, `path`, an optional `input` struct, optional
1706
- * `output` and `error` structs, and an optional `operation`. A declared `input`
1707
- * always requires an explicit `builder`. `input` only defines the parameters;
1708
- * the builder alone decides where each value goes. Only definitions without
1709
- * `input` may omit `builder`. `ResponseDeclaration` and `BuilderField` are
1710
- * internal helper types: `output` and `error` are required only when the
1711
- * matching type parameter is a struct, and `builder` is
1712
- * `(input: BuilderInput<TInput>) => HttpRequestShape` when `input` is declared.
1713
- *
1714
- * `output` is one struct for the 2xx body; `error` is one struct for every
1715
- * non-2xx body. Neither is keyed by status. A declaration is an assertion:
1716
- * omitting one means that body is never read.
1717
- *
1718
- * @param definition - Request contract (method, path, input, builder, output).
1719
- * @returns An endpoint that creates `HttpCommand` values from input.
1720
- *
1721
- * The checked example file passes the whole input object as `path`. This snippet maps individual fields into `path` and `query` instead:
1722
- *
1723
- * @example
1724
- * ```ts
1725
- * const getUser = defineRequest({
1726
- * method: 'GET',
1727
- * path: '/users/:id',
1728
- * input: struct.object({ id: struct.number(), verbose: struct.boolean() }),
1729
- * builder: (input) => ({ path: { id: input.id }, query: { verbose: input.verbose } }),
1730
- * output: struct.object({ id: struct.number(), name: struct.string() }),
1731
- * })
1732
- * ```
1733
- * @group http
1734
- * @exampleFile examples/api/define-request.ts#example
1735
- */
1736
- 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> & {
1737
- input?: TInput;
1738
- method: M;
1739
- operation?: string;
1740
- path: P;
1741
- } & BuilderField<NoInfer<TInput>, HttpRequestShape<NoInfer<P>, NoInfer<M>>>): RequestEndpoint<TInput, TOutput, TError>;
1742
- /**
1743
- * Runs an `HttpCommand` against client config: validate input, send the request, and parse the response.
1744
- *
1745
- * Low-level entry used by `client.execute`. Prefer `client.execute(command, options)`
1746
- * in application code. `HttpClientConfig` is the HTTP part of `ClientConfig`, so
1747
- * a `ClientConfig` is accepted. `HttpExecuteAwaitResult` is the internal result
1748
- * tuple.
1749
- *
1750
- * The result is `[null, data, response]` or `[fault, undefined, undefined]`.
1751
- * `data` is the decoded `output` body, or `undefined` when none is declared.
1752
- * `response` is `DecodedResponse` when `output` is declared and `HttpMeta`
1753
- * otherwise. The fault is `Fault<TError>`. A non-2xx status is `HTTP_STATUS`
1754
- * when no `error` struct is declared (its `data` is `undefined`) or when the
1755
- * declared body decodes (its `data` is that body). When a declared `error` body
1756
- * cannot be read, the fault is a `RES_*` decode fault instead. On failure the
1757
- * tuple's third slot is `undefined`; the fault carries the response metadata.
1758
- * `options.timeout` falls back to the client's `withTimeout` default when omitted.
1759
- *
1760
- * @param clientConfig - Resolved HTTP client configuration (endpoint, interceptors, handler).
1761
- * @param command - Command from a `defineRequest` endpoint.
1762
- * @param options - Per-request progress and cancellation options.
1763
- * @returns An await-result tuple of success body or typed request error.
1764
- * @group http
1765
- */
1766
- 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>>;
1767
- /**
1768
- * Map from SSE event names to the structs that decode their data.
1769
- *
1770
- * An event with no `event:` field is named `message`. An event whose name has no own entry uses the `default` struct; with neither, the event is skipped and `onInvalidEvent` is called. Declare the event name `__proto__` with a computed own key.
1771
- *
1772
- * A `string` event struct keeps the raw `data` text. Every other kind is JSON text: `JSON.parse`, then the struct. A bare `struct.literal` therefore needs JSON text, not an unquoted token.
1773
- *
1774
- * Reconnect lives on the client (`withSSEReconnect`). SSE `jitter` is a **0-1 multiplicative factor**, same as WebSocket.
1775
- *
1776
- * @group sse
1777
- */
1778
- export type EventStructs = {
1779
- [key: string]: AnyStruct;
1780
- };
1781
- type EventName<TKey extends string | number> = `${TKey}`;
1782
- type KnownEventUnion<TEvents extends EventStructs> = { [K in keyof TEvents & (number | string)]: EventName<K> extends "default" ? never : {
1783
- data: Infer<TEvents[K]>;
1784
- event: EventName<K>;
1785
- id?: string;
1786
- }; }[keyof TEvents & (number | string)];
1787
- type DefaultEventUnion<TEvents extends EventStructs> = "default" extends keyof TEvents ? {
1788
- data: Infer<TEvents["default"]>;
1789
- event: string;
1790
- id?: string;
1791
- } : never;
1792
- /**
1793
- * Union of parsed SSE events inferred from an EventStructs map.
1794
- *
1795
- * For each declared event name except `default`, the union has `{ event: <name>; data: Infer<TEvents[name]>; id?: string }`. When a `default` struct is declared, it adds `{ event: string; data: Infer<TEvents['default']>; id?: string }` for every event name that has no struct of its own. `KnownEventUnion` and `DefaultEventUnion` are internal helper types.
1796
- *
1797
- * @group sse
1798
- */
1799
- export type EventStreamData<TEvents extends EventStructs> = TEvents extends EventStructs ? KnownEventUnion<TEvents> | DefaultEventUnion<TEvents> : never;
1800
- interface EventStreamDefinitionBase<TEvents extends EventStructs = EventStructs> {
1801
- events: TEvents;
1802
- maxBufferSize: number;
1803
- maxQueueSize: number;
1804
- method?: string;
1805
- operation?: string;
1806
- path: string;
1807
- }
1808
- /** Makes `error` required only when an error struct is declared, so omission stays `Fault<undefined>`. */
1809
- type EventStreamErrorField<TError extends AnyStruct | undefined> = [TError] extends [undefined] ? {
1810
- error?: never;
1811
- } : {
1812
- error: TError;
1813
- };
1814
- /**
1815
- * Contract that describes an SSE endpoint for defineEventStream.
1816
- *
1817
- * The composed members are:
1818
- *
1819
- * - `events`, `maxBufferSize`, and `maxQueueSize` (both limits are required positive safe integers), optional `method`, `operation`, and a required `path`.
1820
- *
1821
- * - `error`, required only when `TError` is a struct. It decodes the body of a failed handshake (a non-2xx response). The kind rule is the same as for HTTP: `string` is text, `blob` and `file` are blobs, `arrayBuffer` is bytes, and everything else is JSON.
1822
- *
1823
- * - `input` and `builder`. The request shape matches HTTP, including `body`; `GET` and `HEAD` cannot return a body. A declared `input` always requires an explicit `builder`. `input` only defines the parameters; the builder alone decides where each value goes. Only definitions without `input` may omit `builder`.
1824
- *
1825
- * `EventStreamDefinitionBase` and `EventStreamErrorField` are internal helper types.
1826
- *
1827
- * @group sse
1828
- */
1829
- export type EventStreamDefinition<TInput extends AnyStruct | undefined = undefined, TEvents extends EventStructs = EventStructs, TError extends AnyStruct | undefined = undefined> = EventStreamDefinitionBase<TEvents> & EventStreamErrorField<TError> & {
1830
- builder?: OutboundBuilder;
1831
- input?: TInput;
1832
- };
1833
- /**
1834
- * Await-result tuple from opening an SSE stream via `client.execute`.
1835
- *
1836
- * - On success: `[null, stream, open]`. `open` is the returned connection's first successful handshake snapshot for native Defjs handles or wrappers forwarding the same live `open` object; custom handles or wrappers overriding `open` use their current public `open` even after reconnect, while `stream.open` stays live.
1837
- *
1838
- * - On failure: `[fault, undefined, open]`. `open` carries the response snapshot when the failure happened after a response arrived, for example a non-2xx handshake, and is `undefined` otherwise.
1839
- *
1840
- * - `TError` is the declared `error` struct. It types the decoded error body on the fault.
1841
- *
1842
- * @group sse
1843
- */
1844
- export type StreamAwaitResult<TEvent, TError extends AnyStruct | undefined = undefined> = [error: null, stream: EventStreamHandle<TEvent>, open: EventStreamOpenInfo] | [error: Fault<TError>, stream: undefined, open: EventStreamOpenInfo | undefined];
1845
- /**
1846
- * Opaque executable SSE command produced by an `EventStreamEndpoint`.
1847
- *
1848
- * Created by calling an `EventStreamEndpoint` with input. It also has internal symbol-keyed members that identify and run the command. Treat it as opaque and pass it to `client.execute`. `endpoint` is the definition plus `method`, which is always a string (it defaults to `'GET'` when the definition omits it). `ResolvedEventStreamDefinition` names that shape and is not exported.
1849
- *
1850
- * @group sse
1851
- */
1852
- export interface EventStreamCommand<TInput extends AnyStruct | undefined, TEvents extends EventStructs, TError extends AnyStruct | undefined = undefined> extends BaseCommand<typeof EVENT_STREAM_COMMAND> {
1853
- readonly endpoint: ResolvedEventStreamDefinition<TInput, TEvents, TError>;
1854
- readonly input: EndpointInput<TInput> | undefined;
1855
- }
1856
- /**
1857
- * Per-call options for opening an SSE stream: abort or timeout, plus an optional signal.
1858
- *
1859
- * Cancellation is `abort` **or** `timeout`, not both; passing both makes the call resolve with a `REQ_OPTIONS_INVALID` fault. `signal` combines with either and is not an alias for `abort`. `timeout` must be a positive safe integer up to 2147483647.
1860
- *
1861
- * For SSE, `timeout` is a startup deadline. It covers input parsing, the builder, the interceptors, and opening the connection, and stops applying once the stream is open. The client-level `withTimeout` default does not apply to SSE.
1862
- *
1863
- * @group sse
1864
- */
1865
- export type EventStreamExecuteOptions = UseCancellationConfig & {
1866
- signal?: AbortSignal;
1867
- };
1868
- /**
1869
- * Callable endpoint returned by defineEventStream.
1870
- *
1871
- * Returned by `defineEventStream`. Call it to get an `EventStreamCommand`: with no arguments when the endpoint declares no `input`, with an optional argument when the input struct accepts `undefined`, and otherwise with the struct's input value.
1872
- *
1873
- * @group sse
1874
- */
1875
- export type EventStreamEndpoint<TInput extends AnyStruct | undefined, TEvents extends EventStructs, TError extends AnyStruct | undefined = undefined> = EndpointCallable<TInput, EventStreamCommand<TInput, TEvents, TError>>;
1876
- type ResolvedEventStreamDefinition<TInput extends AnyStruct | undefined = undefined, TEvents extends EventStructs = EventStructs, TError extends AnyStruct | undefined = undefined> = EventStreamDefinition<TInput, TEvents, TError> & {
1877
- readonly method: string;
1878
- };
1879
- /**
1880
- * Declare a typed Server-Sent Events endpoint.
1881
- *
1882
- * Pass path, event structs, and buffer/queue limits. Call the returned endpoint
1883
- * with input to get an `EventStreamCommand` for `client.execute`.
1884
- *
1885
- * - **definition** — `path`, an `events` map, and the required `maxBufferSize` and `maxQueueSize` limits (positive safe integers). Optional `method` (default `'GET'`), `operation`, `input`, and `error`. A declared `input` always requires an explicit `builder`. `input` only defines the parameters; the builder alone decides where each value goes. Only definitions without `input` may omit `builder`.
1886
- *
1887
- * `EventStreamDefinitionBase`, `EventStreamErrorField`, and `BuilderField` are internal helper types: `error` is required only when `TError` is a struct, and `builder` is `(input: BuilderInput<TInput>) => EventStreamRequestShape` when `input` is declared.
1888
- *
1889
- * @param definition - SSE contract (path, events, buffer limits, optional input).
1890
- * @returns An endpoint that creates `EventStreamCommand` values from input.
1891
- *
1892
- * @group sse
1893
- * @exampleFile examples/api/define-event-stream.ts#example
1894
- */
1895
- 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> & {
1896
- input?: TInput;
1897
- method?: M;
1898
- path: P;
1899
- } & BuilderField<NoInfer<TInput>, EventStreamRequestShape<NoInfer<P>, NoInfer<M>>>): EventStreamEndpoint<TInput, TEvents, TError>;
1900
- /**
1901
- * Open an SSE command against the given client config.
1902
- *
1903
- * Prefer `client.execute(command)` in application code; this is the low-level entry used by the client.
1904
- *
1905
- * The result is `[null, stream, open]` or `[fault, undefined, open | undefined]`. The fault is `Fault<TError>`: the decoded handshake body is on `data` when `error` is declared, and `Fault<undefined>` otherwise.
1906
- *
1907
- * @param clientConfig - Resolved client configuration.
1908
- * @param command - SSE command from an `EventStreamEndpoint`.
1909
- * @param options - Optional execute options (abort, timeout).
1910
- * @returns Await-result tuple of `[error, stream, open]`.
1911
- * @group sse
1912
- */
1913
- 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>>;
1914
- declare const COMMAND_TYPE: unique symbol;
1915
- declare const HTTP_COMMAND: unique symbol;
1916
- declare const EVENT_STREAM_COMMAND: unique symbol;
1917
- declare const WEB_SOCKET_COMMAND: unique symbol;
1918
- /** The command's own runner, so `client.execute` never imports a transport the app does not use. */
1919
- declare const COMMAND_EXECUTE: unique symbol;
1920
- type CommandExecutor = (config: ClientConfig, command: never, options?: never) => Promise<unknown>;
1921
- type CommandType = typeof HTTP_COMMAND | typeof EVENT_STREAM_COMMAND | typeof WEB_SOCKET_COMMAND;
1922
- interface BaseCommand<TCommandType extends CommandType> {
1923
- readonly [COMMAND_EXECUTE]: CommandExecutor;
1924
- readonly [COMMAND_TYPE]: TCommandType;
1925
- }
1926
1572
  interface WebSocketCloseSnapshot {
1927
1573
  cause?: unknown;
1928
1574
  code?: number;
@@ -1982,13 +1628,13 @@ interface WebSocketDefinitionBase<TIncoming extends AnyStruct = AnyStruct, TOutg
1982
1628
  *
1983
1629
  * - `maxIncomingQueueSize` is required and must be a positive safe integer. `maxOutgoingQueueSize` must be a non-negative safe integer; it defaults to `0`, which disables queueing of messages sent while the session is `reconnecting`.
1984
1630
  *
1985
- * - `protocols` is the static default subprotocol list. The `protocols` execute option and {@link withWebSocketProtocols} override it.
1631
+ * - `protocols` is the static default subprotocol list. `RequestOptions.protocols` and {@link withWebSocketProtocols} override it.
1986
1632
  *
1987
1633
  * - `operation` is a static, low-cardinality name for telemetry.
1988
1634
  *
1989
- * - `input` is the struct for the command input. A declared `input` always requires an explicit `builder`. `input` only defines the parameters; the builder alone decides where each value goes. Only definitions without `input` may omit `builder`. The builder may return `path` and `query` only; see {@link WebSocketRequestShape}.
1635
+ * - `input` is the struct for the operation input. A declared `input` always requires an explicit `builder`. `input` only defines the parameters; the builder alone decides where each value goes. Only definitions without `input` may omit `builder`. The builder may return `path` and `query` only; see {@link WebSocketRequestShape}.
1990
1636
  *
1991
- * Invalid queue limits are reported when the command executes, as a `REQ_OPTIONS_INVALID` fault.
1637
+ * Invalid queue limits are reported when the operation runs, as a `REQ_OPTIONS_INVALID` fault.
1992
1638
  *
1993
1639
  * @group web-socket
1994
1640
  */
@@ -2005,7 +1651,7 @@ export type WebSocketDefinition<TInput extends AnyStruct | undefined = undefined
2005
1651
  *
2006
1652
  * - `generation` counts the physical sockets that reached `open`: `1` after the first open, one more after each reconnect. A snapshot taken before any open has `0`.
2007
1653
  *
2008
- * `session.connection` exposes the session's current public connection info. The `connection` in the execute result preserves the first successful snapshot only for a native Defjs session or a wrapper forwarding the same live `connection` object. Custom sessions and wrappers that transform `connection` instead return their current public `connection`. Sharing `closed` cannot bypass URL sanitization or metadata filtering, and Defjs does not reconstruct first-connection metadata from arbitrary transformations.
1654
+ * `session.connection` exposes the session's current public connection info. The `connection` in the operation result preserves the first successful snapshot only for a native Defjs session or a wrapper forwarding the same live `connection` object. Custom sessions and wrappers that transform `connection` instead return their current public `connection`. Sharing `closed` cannot bypass URL sanitization or metadata filtering, and Defjs does not reconstruct first-connection metadata from arbitrary transformations.
2009
1655
  *
2010
1656
  * @group web-socket
2011
1657
  */
@@ -2093,7 +1739,7 @@ export interface WebSocketSession<TIncoming = unknown, TOutgoing = never> extend
2093
1739
  send(message: TOutgoing): void;
2094
1740
  }
2095
1741
  /**
2096
- * Await-result tuple from opening a WebSocket via `client.execute`.
1742
+ * Await-result tuple from opening a WebSocket.
2097
1743
  *
2098
1744
  * - On success: `[null, session, connection]`. `session.connection` moves forward on reconnect. The tuple's `connection` preserves the first successful snapshot only for a native Defjs session or a wrapper forwarding the same live `connection` object. Custom sessions and wrappers that transform `connection` instead return their current public `connection`. Sharing `closed` cannot bypass URL sanitization or metadata filtering, and Defjs does not reconstruct first-connection metadata from arbitrary transformations.
2099
1745
  *
@@ -2111,83 +1757,33 @@ interface UseWebSocketBaseConfig<TIncoming = unknown, TOutgoing = unknown> {
2111
1757
  reconnect?: ClientWebSocketOptions["reconnect"];
2112
1758
  }
2113
1759
  /**
2114
- * WebSocket execute options without signal.
2115
- *
2116
- * The WebSocket-specific part of {@link WebSocketExecuteOptions}, which adds `signal`.
2117
- *
2118
- * - `beforeConnect`, `heartbeat`, `protocols`, and `reconnect` override the client-level options for one call.
2119
- *
2120
- * - Cancellation is either `abort` or `timeout`, never both. The type rejects both, and at runtime passing both fails with a `REQ_OPTIONS_INVALID` fault.
2121
- *
2122
- * @group web-socket
2123
- */
2124
- export type UseWebSocketConfig<TIncoming = unknown, TOutgoing = unknown> = UseWebSocketBaseConfig<TIncoming, TOutgoing> & UseCancellationConfig;
2125
- /**
2126
- * Per-call options for executing a WebSocket command.
1760
+ * WebSocket fields of {@link RequestOptions}, plus `abort`.
2127
1761
  *
2128
- * {@link UseWebSocketConfig} plus `signal`. Expanded:
2129
- *
2130
- * ```ts
2131
- * type WebSocketExecuteOptions<TIncoming = unknown, TOutgoing = unknown> = {
2132
- * beforeConnect?: (context: {
2133
- * attempt: number;
2134
- * signal: AbortSignal;
2135
- * }) => void | Promise<void>;
2136
- * heartbeat?: WebSocketHeartbeatConfig<TIncoming, TOutgoing>;
2137
- * protocols?: readonly string[];
2138
- * reconnect?: ClientWebSocketOptions["reconnect"];
2139
- * signal?: AbortSignal;
2140
- * } & (
2141
- * { abort?: AbortSignal; timeout?: never } | { abort?: never; timeout?: number }
2142
- * );
2143
- * ```
2144
- *
2145
- * - `abort` and `timeout` are mutually exclusive. The type rejects both, and at runtime passing both fails with a `REQ_OPTIONS_INVALID` fault.
2146
- *
2147
- * - `signal` combines with either one; it is not an alias for `abort`.
2148
- *
2149
- * - `timeout` must be a positive safe integer no greater than `2_147_483_647`. It limits how long opening the session may take and is not applied again on reconnect.
2150
- *
2151
- * - `beforeConnect`, `heartbeat`, `protocols`, and `reconnect` override the client-level options for this call.
2152
- *
2153
- * - When `reconnect` is set, `attempts` defaults to `3` per outage; `0` disables. Successful `open` resets the budget and backoff exponent. Omitting `attempts` does not give unlimited retries within one outage. See {@link withWebSocketReconnect} for validation and final delay caps.
2154
- *
2155
- * See {@link WebSocketHeartbeatConfig}.
1762
+ * `beforeConnect`, `heartbeat`, `protocols`, and `reconnect` override the client-level options for one call. `abort` covers the whole session, including after it opens. There is no startup-only deadline and no `signal` field.
2156
1763
  *
2157
1764
  * @group web-socket
2158
1765
  */
2159
- export type WebSocketExecuteOptions<TIncoming = unknown, TOutgoing = unknown> = UseWebSocketConfig<TIncoming, TOutgoing> & {
2160
- signal?: AbortSignal;
1766
+ export type UseWebSocketConfig<TIncoming = unknown, TOutgoing = unknown> = UseWebSocketBaseConfig<TIncoming, TOutgoing> & {
1767
+ /** Aborts the session, including after it is open. */
1768
+ abort?: AbortSignal;
2161
1769
  };
2162
1770
  /**
2163
- * Executable command created by calling a WebSocketEndpoint.
1771
+ * WebSocket fields read from {@link RequestOptions} for one call.
2164
1772
  *
2165
- * Created by calling a {@link WebSocketEndpoint}. It holds the endpoint definition and the unparsed input. Pass it to `client.execute` to open a session; nothing connects until then.
2166
- *
2167
- * `BaseCommand` carries symbol-keyed members that route the command to the right transport. They are internal, so treat the command as opaque.
1773
+ * See {@link UseWebSocketConfig}. `heartbeat` callbacks are not inferred from the operation; narrow `unknown` messages yourself.
2168
1774
  *
2169
1775
  * @group web-socket
1776
+ * @see {@link WebSocketHeartbeatConfig}
2170
1777
  */
2171
- export interface WebSocketCommand<TInput extends AnyStruct | undefined, TIncoming extends AnyStruct, TOutgoing extends AnyStruct | undefined> extends BaseCommand<typeof WEB_SOCKET_COMMAND> {
2172
- readonly endpoint: WebSocketDefinition<TInput, TIncoming, TOutgoing>;
2173
- readonly input: EndpointInput<TInput> | undefined;
2174
- }
1778
+ export type WebSocketExecuteOptions<TIncoming = unknown, TOutgoing = unknown> = UseWebSocketConfig<TIncoming, TOutgoing>;
2175
1779
  /**
2176
- * Callable returned by defineWebSocket.
2177
- *
2178
- * Returned by {@link defineWebSocket}. Calling it creates a {@link WebSocketCommand} that you pass to `client.execute`. The call signature depends on `input`:
2179
- *
2180
- * - No `input` declared: `() => WebSocketCommand`.
2181
- *
2182
- * - `input` accepts `undefined`: `(input?: StructInput<TInput>) => WebSocketCommand`.
2183
- *
2184
- * - Otherwise: `(input: StructInput<TInput>) => WebSocketCommand`.
1780
+ * Operation returned by `defineWebSocket`.
2185
1781
  *
2186
- * Calling the endpoint does not connect. The input is parsed when the command is executed.
1782
+ * The first argument is a {@link Client}. Further arguments are the input only. Calling it opens the session and returns the existing error-first tuple.
2187
1783
  *
2188
1784
  * @group web-socket
2189
1785
  */
2190
- export type WebSocketEndpoint<TInput extends AnyStruct | undefined, TIncoming extends AnyStruct, TOutgoing extends AnyStruct | undefined> = EndpointCallable<TInput, WebSocketCommand<TInput, TIncoming, TOutgoing>>;
1786
+ export type WebSocketEndpoint<Args extends unknown[], Incoming, Outgoing = never> = (client: Client, ...args: Args) => Promise<SocketAwaitResult<Incoming, Outgoing>>;
2191
1787
  /**
2192
1788
  * Close code and reason recorded when a session is closed with session.close.
2193
1789
  *
@@ -2215,7 +1811,7 @@ export type ManualSocketCloseReason = {
2215
1811
  *
2216
1812
  * - `intervalMs` and `timeoutMs` must be positive, finite, and at most `2_147_483_647`.
2217
1813
  *
2218
- * Set it with {@link withWebSocketHeartbeat} or the `heartbeat` execute option.
1814
+ * Set it with {@link withWebSocketHeartbeat} or the `heartbeat` request option.
2219
1815
  *
2220
1816
  * @group web-socket
2221
1817
  */
@@ -2229,14 +1825,14 @@ export interface WebSocketHeartbeatConfig<TIncoming = unknown, TOutgoing = unkno
2229
1825
  * Declare a typed WebSocket endpoint.
2230
1826
  *
2231
1827
  * Pass path, incoming (and optional outgoing) message structs, and queue limits.
2232
- * Call the returned endpoint with input to get a `WebSocketCommand` for `client.execute`.
1828
+ * Call the returned operation with a client and, when declared, the input.
2233
1829
  *
2234
1830
  * - **definition** — `path`, one `incoming` struct, and the required `maxIncomingQueueSize` (a positive safe integer). Optional `outgoing` and `input` structs, static `protocols`, `maxOutgoingQueueSize` (a non-negative safe integer), and `operation`. A declared `input` always requires an explicit `builder`. `input` only defines the parameters; the builder alone decides where each value goes. Only definitions without `input` may omit `builder`.
2235
1831
  *
2236
1832
  * A WebSocket `builder` may return `path` and `query` only; `headers` and `body` are rejected. `WebSocketDefinitionBase` and `BuilderField` are internal helper types.
2237
1833
  *
2238
1834
  * @param definition - WebSocket contract (path, structs, queue limits, optional input).
2239
- * @returns An endpoint that creates `WebSocketCommand` values from input.
1835
+ * @returns An operation `(client, ...input) => Promise<error-first tuple>`.
2240
1836
  *
2241
1837
  * @group web-socket
2242
1838
  * @exampleFile examples/api/define-web-socket.ts#example
@@ -2244,23 +1840,7 @@ export interface WebSocketHeartbeatConfig<TIncoming = unknown, TOutgoing = unkno
2244
1840
  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"> & {
2245
1841
  input?: TInput;
2246
1842
  path: P;
2247
- } & BuilderField<NoInfer<TInput>, WebSocketRequestShape<NoInfer<P>>>): WebSocketEndpoint<TInput, TIncoming, TOutgoing>;
2248
- /**
2249
- * Open a WebSocket command against the given client config.
2250
- *
2251
- * Prefer `client.execute(command)` in application code; this is the low-level entry used by the client.
2252
- *
2253
- * The result is `[null, session, connection]` or `[fault, undefined, connection | undefined]`, where the fault is `Fault<undefined>`.
2254
- *
2255
- * WebSocket execute options can override the client's `beforeConnect`, `heartbeat`, `protocols`, and `reconnect`.
2256
- *
2257
- * @param clientConfig - Resolved client configuration.
2258
- * @param command - WebSocket command from a `WebSocketEndpoint`.
2259
- * @param options - Optional execute options (heartbeat, reconnect, abort).
2260
- * @returns Await-result tuple of `[error, socket, connection]`.
2261
- * @group web-socket
2262
- */
2263
- 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>>>;
1843
+ } & BuilderField<NoInfer<TInput>, WebSocketRequestShape<NoInfer<P>>>): WebSocketEndpoint<EndpointArgs<TInput>, WebSocketIncomingData<TIncoming>, WebSocketOutgoingData<TOutgoing>>;
2264
1844
  /**
2265
1845
  * The outcome of a **single connect attempt**, not the final result of the session.
2266
1846
  *
@@ -2288,8 +1868,8 @@ export type SocketLifecycleOutcome = {
2288
1868
  * Continuation that runs the rest of the HTTP interceptor chain, or the handler.
2289
1869
  *
2290
1870
  * `next(req)` only goes inward: the interceptors registered after this one, then
2291
- * the Fetch handler. It is not a re-dispatch of `client.execute` from the
2292
- * outside of the chain. Call `next` again for a safe
1871
+ * the Fetch handler. It is not a new operation call from outside the chain.
1872
+ * Call `next` again for a safe
2293
1873
  * replay (for example one 401 refresh) from the same interceptor; outer layers
2294
1874
  * do not run a second time. Once the chain has settled, calling `next` rejects
2295
1875
  * with `HTTP interceptor next() cannot be called after the chain has settled`.
@@ -2324,10 +1904,10 @@ interface HttpInterceptor {
2324
1904
  * Returns `{ kind: 'http', fn }`. Call `next(req)` (optionally with a modified
2325
1905
  * request) or short-circuit with `makeResponse`. `next` runs only the
2326
1906
  * interceptors registered after this one and then the fetch handler. HTTP
2327
- * interceptors do not run for SSE or WebSocket commands.
1907
+ * interceptors do not run for SSE or WebSocket operations.
2328
1908
  *
2329
1909
  * A deterministic URL error from `next(req)` rejects the returned promise, so
2330
- * `.then` or `.catch` recovery runs; if it is not recovered, `client.execute`
1910
+ * `.then` or `.catch` recovery runs; if it is not recovered, the operation
2331
1911
  * still reports `REQ_BUILD_FAILED`.
2332
1912
  *
2333
1913
  * @param fn - HTTP interceptor function.
@@ -2369,7 +1949,7 @@ type SSEInterceptorFn = (req: HttpRequest, next: SSEHandler) => Promise<EventStr
2369
1949
  *
2370
1950
  * Created by `createSSEInterceptor`. The `kind` tag lets `withInterceptors`
2371
1951
  * accept HTTP, SSE, and WebSocket interceptors in one list; only `kind: 'sse'`
2372
- * interceptors run for SSE commands.
1952
+ * interceptors run for SSE operations.
2373
1953
  *
2374
1954
  * @group interceptors
2375
1955
  */
@@ -2380,12 +1960,12 @@ interface SSEInterceptor {
2380
1960
  /**
2381
1961
  * Wraps an `SSEInterceptorFn` as a tagged `SSEInterceptor`.
2382
1962
  *
2383
- * Returns `{ kind: 'sse', fn }`. SSE interceptors run only for SSE commands, in
1963
+ * Returns `{ kind: 'sse', fn }`. SSE interceptors run only for SSE operations, in
2384
1964
  * registration order; `next(req)` opens the stream through the remaining
2385
1965
  * interceptors.
2386
1966
  *
2387
1967
  * A deterministic URL error from `next(req)` rejects the returned promise, so
2388
- * `.then` or `.catch` recovery runs; if it is not recovered, `client.execute`
1968
+ * `.then` or `.catch` recovery runs; if it is not recovered, the operation
2389
1969
  * still reports `REQ_BUILD_FAILED`.
2390
1970
  *
2391
1971
  * `EventStreamHandle` extends `AsyncDisposable`. A structural short-circuit
@@ -2448,7 +2028,7 @@ type WebSocketHandler = (req: HttpRequest) => Promise<WebSocketSessionLike>;
2448
2028
  * {@link WebSocketSessionLike} to short-circuit. Wrap it with
2449
2029
  * `createWebSocketInterceptor` to register it through `withInterceptors`.
2450
2030
  *
2451
- * The chain runs once per `execute`. Reconnects happen inside the session it
2031
+ * The chain runs once per operation. Reconnects happen inside the session it
2452
2032
  * returns and do not run it again.
2453
2033
  *
2454
2034
  * @group interceptors
@@ -2459,7 +2039,7 @@ type WebSocketInterceptorFn = (req: HttpRequest, next: WebSocketHandler) => Prom
2459
2039
  *
2460
2040
  * Created by `createWebSocketInterceptor`. The `kind` tag lets
2461
2041
  * `withInterceptors` accept HTTP, SSE, and WebSocket interceptors in one list;
2462
- * only `kind: 'web-socket'` interceptors run for WebSocket commands.
2042
+ * only `kind: 'web-socket'` interceptors run for WebSocket operations.
2463
2043
  *
2464
2044
  * @group interceptors
2465
2045
  */
@@ -2471,7 +2051,7 @@ interface WebSocketInterceptor {
2471
2051
  * Wraps a `WebSocketInterceptorFn` as a tagged `WebSocketInterceptor`.
2472
2052
  *
2473
2053
  * Returns `{ kind: 'web-socket', fn }`. WebSocket interceptors run only for
2474
- * WebSocket commands. `next` and the interceptor return a
2054
+ * WebSocket operations. `next` and the interceptor return a
2475
2055
  * {@link WebSocketSessionLike}, the interceptor-facing session. A wrapper or
2476
2056
  * short-circuit session must forward its `[Symbol.asyncDispose]()` teardown.
2477
2057
  *
@@ -2483,7 +2063,7 @@ export declare function createWebSocketInterceptor(fn: WebSocketInterceptorFn):
2483
2063
  /**
2484
2064
  * Any tagged interceptor accepted by client interceptor options.
2485
2065
  *
2486
- * `kind` (`'http'`, `'sse'`, or `'web-socket'`) selects which commands an
2066
+ * `kind` (`'http'`, `'sse'`, or `'web-socket'`) selects which operations an
2487
2067
  * interceptor runs for. `withInterceptors` accepts any mix; each transport runs
2488
2068
  * only its own kind, in registration order.
2489
2069
  *
@@ -2603,7 +2183,7 @@ interface ClientWebSocketOptions {
2603
2183
  * - **onInvalidEvent** — Called when an event has no matching struct and no `default` struct (`'missing-struct'`), or its data fails validation (`'validation-failed'`). The event is skipped. An error thrown by the hook does not close the stream.
2604
2184
  * - **reconnect** — Opt-in. Without it the stream never reconnects. `attempts` defaults to **3** per outage; `attempts: 0` disables retry. A successful handshake resets the budget, callback `attempt`, and backoff exponent. `delayMs` is the first base delay, 1000 by default, and a server-sent `retry:` value replaces it. `factor` defaults to 1. `jitter` is a 0–1 multiplicative factor and defaults to 0. `maxDelayMs` caps the final delay after jitter and rounding; without a configured cap, the platform limit of `2_147_483_647` ms still applies. A zero base stays zero; valid-number overflow saturates at the caps. Without `shouldReconnect` only `GET`, `HEAD`, `OPTIONS`, `PUT`, and `DELETE` reconnect; with it, its result decides for every method and its context carries `method`. A `ReadableStream` request body never reconnects. Reconnect sends the latest ID as UTF-8 bytes in `Last-Event-ID`; an empty ID clears it and an ID containing NUL is ignored.
2605
2185
  *
2606
- * Reconnect options are validated before interceptors or Fetch: `attempts` is a non-negative safe integer; `delayMs` must be finite and non-negative; `maxDelayMs` must be a non-negative finite number or positive `Infinity`, which removes the configured cap but not the platform limit of `2_147_483_647` ms; `factor` is finite and positive; `jitter` is finite and within 0–1. Invalid values return `REQ_OPTIONS_INVALID` at execute time.
2186
+ * Reconnect options are validated before interceptors or Fetch: `attempts` is a non-negative safe integer; `delayMs` must be finite and non-negative; `maxDelayMs` must be a non-negative finite number or positive `Infinity`, which removes the configured cap but not the platform limit of `2_147_483_647` ms; `factor` is finite and positive; `jitter` is finite and within 0–1. Invalid values return `REQ_OPTIONS_INVALID` when the operation runs.
2607
2187
  *
2608
2188
  * Set these with `withSSEHandle`, `withSSEOnInvalidEvent`, and `withSSEReconnect`. Omitting `withSSEReconnect` disables retry.
2609
2189
  *
@@ -2670,7 +2250,7 @@ interface ClientSSEConfig extends ClientSSEOptions {
2670
2250
  interface HttpClientOptions {
2671
2251
  /** Base URL prepended to relative request paths. */
2672
2252
  endpoint: string;
2673
- /** Static default headers merged under command headers for HTTP/SSE. */
2253
+ /** Static default headers merged under headers returned by the builder for HTTP/SSE. */
2674
2254
  headers?: Headers;
2675
2255
  /** HTTP transport overrides; the default resolves global `fetch` on each call. */
2676
2256
  http?: {
@@ -2680,8 +2260,6 @@ interface HttpClientOptions {
2680
2260
  interceptors?: Interceptor[];
2681
2261
  /** Serializes encoded query objects. Omit to use `URLSearchParams`. */
2682
2262
  querySerializer?: QuerySerializer;
2683
- /** Default HTTP execute timeout in milliseconds (SSE/WebSocket ignore this). */
2684
- timeout?: number;
2685
2263
  /** XSRF cookie/header mapping and optional token provider. */
2686
2264
  xsrf?: {
2687
2265
  /** Cookie name that stores the XSRF token. */
@@ -2699,7 +2277,7 @@ interface HttpClientOptions {
2699
2277
  /**
2700
2278
  * Input-shaped client options, including SSE and WebSocket, that mirror what the option helpers configure.
2701
2279
  *
2702
- * The user-facing shape of the settings before defaults are applied. `createClient` does not accept this object; configure a client with option helpers such as `withEndpoint` and `withTimeout`. {@link ClientConfig} is the resolved counterpart. The HTTP members come from the non-exported `HttpClientOptions` base and are shown inline.
2280
+ * The user-facing shape of the settings before defaults are applied. `createClient` does not accept this object; configure a client with option helpers such as `withEndpoint`. {@link ClientConfig} is the resolved counterpart. The HTTP members come from the non-exported `HttpClientOptions` base and are shown inline.
2703
2281
  *
2704
2282
  * @group client
2705
2283
  */
@@ -2713,7 +2291,7 @@ interface ClientOptions extends HttpClientOptions {
2713
2291
  interface HttpClientConfig {
2714
2292
  /** Base URL prepended to relative request paths. */
2715
2293
  endpoint: string;
2716
- /** Static default headers merged under command headers for HTTP/SSE. */
2294
+ /** Static default headers merged under headers returned by the builder for HTTP/SSE. */
2717
2295
  headers?: Headers;
2718
2296
  /** HTTP transport with a required fetch handle. */
2719
2297
  http: {
@@ -2723,8 +2301,6 @@ interface HttpClientConfig {
2723
2301
  interceptors: Interceptor[];
2724
2302
  /** Serializes encoded query objects. Omit to use `URLSearchParams`. */
2725
2303
  querySerializer?: QuerySerializer;
2726
- /** Default HTTP execute timeout in milliseconds (SSE/WebSocket ignore this). */
2727
- timeout?: number;
2728
2304
  /** Resolved XSRF settings when enabled. */
2729
2305
  xsrf?: {
2730
2306
  /** Cookie name that stores the XSRF token. */
@@ -2766,7 +2342,7 @@ type ClientOption = (config: ClientConfig) => void;
2766
2342
  /**
2767
2343
  * Sets the valid absolute base URL prepended to relative request paths.
2768
2344
  *
2769
- * The default is an empty string, so execution requires an explicit endpoint. Its pathname is kept as a directory; its query and hash are discarded. For WebSocket commands, an `http:` base becomes `ws:` and `https:` becomes `wss:`.
2345
+ * The default is an empty string, so execution requires an explicit endpoint. Its pathname is kept as a directory; its query and hash are discarded. For WebSocket operations, an `http:` base becomes `ws:` and `https:` becomes `wss:`.
2770
2346
  *
2771
2347
  * A missing, relative, or invalid endpoint, or an illegal request path, fails with `REQ_BUILD_FAILED` during building, before any interceptor or transport runs, even when an interceptor would short-circuit. HTTP, SSE, and WebSocket share this rule. The resolved request must keep the base origin and stay under its directory; C0 control characters (including tab, CR, and LF), backslashes, `?`, `#`, and directory escapes in a path are rejected. Scheme-like and protocol-relative forms are rejected even with leading spaces; a plain inner space is allowed and sent as `%20`. An interceptor's final `req.endpoint` is checked against its final `req.baseEndpoint` with the same rule, but it may deliberately replace the base with another valid absolute URL. Deterministic URL errors are never retried.
2772
2348
  *
@@ -2789,22 +2365,10 @@ export declare function withEndpoint(endpoint: string): ClientOption;
2789
2365
  * @group client
2790
2366
  */
2791
2367
  export declare function withHeaders(headers: HeadersInit): ClientOption;
2792
- /**
2793
- * Sets the default timeout, in milliseconds, for HTTP `execute` only.
2794
- *
2795
- * SSE and WebSocket ignore it. `ms` must be a positive safe integer no greater than `2_147_483_647`. Anything else throws `RangeError` immediately, when `withTimeout` is called, not when the client executes.
2796
- *
2797
- * The timer starts before the interceptor chain runs. When it fires, the call returns a `NET_TIMEOUT` fault. Execute `{ timeout }` replaces this default for that call. Execute `{ abort }` combines with the default: an abort gives `NET_ABORTED`, the timer gives `NET_TIMEOUT`. Passing both `abort` and `timeout` to the same `execute` call is still rejected.
2798
- *
2799
- * @param ms - Positive safe integer timeout in milliseconds.
2800
- * @returns An option that writes `config.timeout`.
2801
- * @group client
2802
- */
2803
- export declare function withTimeout(ms: number): ClientOption;
2804
2368
  /**
2805
2369
  * Appends interceptors to the client interceptor chain.
2806
2370
  *
2807
- * Calling it again appends more; it never replaces earlier ones. The first registered interceptor is the outermost layer. HTTP, SSE, and WebSocket interceptors can be mixed in one call. At execute time only the interceptors of the command's transport run, in their registration order.
2371
+ * Calling it again appends more; it never replaces earlier ones. The first registered interceptor is the outermost layer. HTTP, SSE, and WebSocket interceptors can be mixed in one call. When an operation runs, only the interceptors of that transport run, in their registration order.
2808
2372
  *
2809
2373
  * @param interceptors - Interceptors applied in registration order.
2810
2374
  * @returns An option that pushes onto `config.interceptors`.
@@ -2848,7 +2412,7 @@ export declare function withSSEHandle(fetchImpl: FetchHandle): ClientOption;
2848
2412
  /**
2849
2413
  * Replaces the WebSocket constructor used for socket connections.
2850
2414
  *
2851
- * The default is `globalThis.WebSocket`. `WebSocketImpl` is a {@link WebSocketHandleConstructor} that returns a {@link WebSocketHandle}. If no constructor is available, executing a WebSocket command fails with an `ENV_UNSUPPORTED` fault.
2415
+ * The default is `globalThis.WebSocket`. `WebSocketImpl` is a {@link WebSocketHandleConstructor} that returns a {@link WebSocketHandle}. If no constructor is available, a WebSocket operation fails with an `ENV_UNSUPPORTED` fault.
2852
2416
  *
2853
2417
  * @param WebSocketImpl - Constructor that returns a `WebSocketHandle`.
2854
2418
  * @returns An option that sets `config.webSocket.handle`.
@@ -2867,7 +2431,7 @@ export declare function withWebSocketHandle(WebSocketImpl: WebSocketHandleConstr
2867
2431
  * - `attempt` is `0` for the first connect and grows by one for each reconnect.
2868
2432
  * - Pass `signal` into token refreshes and other async work so cancelling the session stops them.
2869
2433
  * - If the hook throws, the attempt fails with an `EXT_HOOK_FAILED` fault.
2870
- * - A `beforeConnect` in the execute options replaces this one for that call.
2434
+ * - A `beforeConnect` in the request options replaces this one for that call.
2871
2435
  *
2872
2436
  * @param beforeConnect - Hook receiving attempt index and abort signal.
2873
2437
  * @returns An option that sets `config.webSocket.beforeConnect`.
@@ -2879,7 +2443,7 @@ export declare function withWebSocketBeforeConnect(beforeConnect: ClientWebSocke
2879
2443
  *
2880
2444
  * They are passed as the second argument to the `WebSocket` constructor only when the list is not empty, so the platform can run the RFC 6455 subprotocol negotiation. They matter only when the server requires a specific subprotocol, for example `['json']` or `['v1']`.
2881
2445
  *
2882
- * Precedence, highest first: the `protocols` execute option, this client option, then `protocols` on the endpoint definition.
2446
+ * Precedence, highest first: the `protocols` request option, this client option, then `protocols` on the endpoint definition.
2883
2447
  *
2884
2448
  * @param protocols - Subprotocol list for the WebSocket constructor.
2885
2449
  * @returns An option that sets `config.webSocket.protocols`.
@@ -2904,8 +2468,8 @@ export declare function withWebSocketProtocols(protocols: readonly string[]): Cl
2904
2468
  * - With `timeoutMs`, an acknowledgement is expected after each heartbeat. `isAck` receives the decoded incoming message; when it returns `true`, the timer is cleared and that message is **not** delivered to `receive`.
2905
2469
  * - If no ack arrives within `timeoutMs`, or a heartbeat cannot be sent, the session fails. This does not trigger a reconnect.
2906
2470
  * - Heartbeat uses the same JSON guard as `session.send`: a value JSON cannot represent after struct encoding causes `TypeError` and ends the logical session.
2907
- * - `intervalMs` and `timeoutMs` must be positive, finite, and at most `2_147_483_647`; otherwise execute fails with `REQ_OPTIONS_INVALID`.
2908
- * - A `heartbeat` in the execute options replaces this one for that call.
2471
+ * - `intervalMs` and `timeoutMs` must be positive, finite, and at most `2_147_483_647`; otherwise the operation fails with `REQ_OPTIONS_INVALID`.
2472
+ * - A `heartbeat` in the request options replaces this one for that call.
2909
2473
  *
2910
2474
  * @param options - Heartbeat interval, payload, timeout, and ACK predicate.
2911
2475
  * @returns An option that sets `config.webSocket.heartbeat`.
@@ -2931,8 +2495,8 @@ export declare function withWebSocketHeartbeat(options: ClientWebSocketOptions["
2931
2495
  * - `attempts` is the retry budget for each outage. It defaults to `3`, and `0` disables reconnection. Successful `open` resets the budget and backoff exponent; the next outage starts at retry 1. Omitting it does not give unlimited retries within one outage. A socket that successfully opens and is immediately closed again by the server can keep reconnecting at the base delay (subject to jitter and caps), because every open resets the budget; use `shouldReconnect` to stop it.
2932
2496
  * - `delayMs` defaults to `1000`, `factor` to `2`, `maxDelayMs` to `30000`, and `jitter` (0 to 1) to `0`. Retry _n_ starts with `delayMs * factor^(n-1)`, capped at `maxDelayMs`; jitter and rounding follow, then the final delay is capped again at `maxDelayMs` and `2_147_483_647` ms. A zero base stays zero; valid-number overflow saturates at those caps.
2933
2497
  * - `shouldReconnect` can return `false` to end the session instead. Without it every close is retried while the budget lasts. It is not called for a manual `session.close()`.
2934
- * - Reconnect options are validated before connecting: `attempts` must be a non-negative safe integer; `delayMs` must be finite and non-negative; `maxDelayMs` must be a non-negative finite number or positive `Infinity`, which removes the configured cap but not the platform limit of `2_147_483_647` ms; `factor` must be finite and positive; `jitter` must be finite and within 0–1. Invalid values make execute fail with `REQ_OPTIONS_INVALID` before connecting. `attempts: 0` disables subsequent retries, but all explicitly supplied reconnect fields are still validated before the initial connection.
2935
- * - A `reconnect` in the execute options replaces this one for that call.
2498
+ * - Reconnect options are validated before connecting: `attempts` must be a non-negative safe integer; `delayMs` must be finite and non-negative; `maxDelayMs` must be a non-negative finite number or positive `Infinity`, which removes the configured cap but not the platform limit of `2_147_483_647` ms; `factor` must be finite and positive; `jitter` must be finite and within 0–1. Invalid values make the operation fail with `REQ_OPTIONS_INVALID` before connecting. `attempts: 0` disables subsequent retries, but all explicitly supplied reconnect fields are still validated before the initial connection.
2499
+ * - A `reconnect` in the request options replaces this one for that call.
2936
2500
  *
2937
2501
  * @param options - Retry budget, backoff, and `shouldReconnect` gate.
2938
2502
  * @returns An option that sets `config.webSocket.reconnect`.
@@ -2993,7 +2557,7 @@ export declare function withSSEOnInvalidEvent(handler: ClientSSEOptions["onInval
2993
2557
  * - `delayMs`, `factor`, `jitter` (0 to 1), and `maxDelayMs` shape the backoff. `factor` defaults to `1` and `jitter` to `0`. `maxDelayMs` caps the final delay after jitter and rounding. Without a configured cap, the platform timer limit of `2_147_483_647` ms still applies. A zero base stays zero; valid-number overflow saturates at the caps.
2994
2558
  * - `delayMs` is only the starting base delay (`1000` by default). A server `retry:` field (digits only, in milliseconds) replaces it for later attempts.
2995
2559
  * - The last event id is sent again as UTF-8 bytes in `Last-Event-ID` on the next attempt. An empty `id:` clears it; an ID containing NUL is ignored.
2996
- * - Reconnect options are validated before interceptors or Fetch: `attempts` must be a non-negative safe integer; `delayMs` must be finite and non-negative; `maxDelayMs` must be a non-negative finite number or positive `Infinity`, which removes the configured cap but not the platform limit of `2_147_483_647` ms; `factor` must be finite and positive; `jitter` must be finite and within 0–1. Invalid values return `REQ_OPTIONS_INVALID` at execute time.
2560
+ * - Reconnect options are validated before interceptors or Fetch: `attempts` must be a non-negative safe integer; `delayMs` must be finite and non-negative; `maxDelayMs` must be a non-negative finite number or positive `Infinity`, which removes the configured cap but not the platform limit of `2_147_483_647` ms; `factor` must be finite and positive; `jitter` must be finite and within 0–1. Invalid values return `REQ_OPTIONS_INVALID` when the operation runs.
2997
2561
  *
2998
2562
  * @param options - Retry budget, backoff, and `shouldReconnect` gate.
2999
2563
  * @returns An option that sets `config.sse.reconnect`.
@@ -3024,41 +2588,206 @@ export declare function withXSRF(options?: HttpClientOptions["xsrf"]): ClientOpt
3024
2588
  * @group client
3025
2589
  */
3026
2590
  export declare function withCredentials(value: boolean): ClientOption;
2591
+ /**
2592
+ * Internal symbol key for a client's base configuration and derived request options.
2593
+ *
2594
+ * Application code calls the client and passes it to an operation. It does not read this property.
2595
+ *
2596
+ * @group client
2597
+ */
3027
2598
  declare const CLIENT: unique symbol;
3028
2599
  /**
3029
- * A client returned by `createClient` holds the resolved {@link ClientConfig} and executes HTTP, SSE, and WebSocket commands.
2600
+ * Flat per-call options. Each protocol reads the fields it understands and ignores the rest.
3030
2601
  *
3031
- * The command type selects the `execute` overload. Failures are returned as faults in the result tuple rather than thrown; the promise rejects only for a value that is not a Defjs command (`Error: Unsupported command`). `[CLIENT]` is an internal symbol key that holds the resolved {@link ClientConfig}; it is not part of the call surface.
2602
+ * SSE reads only `abort` from request options. SSE reconnect comes from client configuration (`withSSEReconnect`), so `client({ reconnect })` affects WebSocket only.
2603
+ *
2604
+ * `abort` cancels HTTP, SSE, and WebSocket calls. `onUploadProgress` and `onDownloadProgress` apply to HTTP. `beforeConnect`, `protocols`, `heartbeat`, and `reconnect` apply to WebSocket and replace the client setting for that call as a whole value. There is no `timeout` or `signal` field. Pass `AbortSignal.timeout(ms)` as `abort` when a call needs a deadline.
3032
2605
  *
3033
2606
  * @group client
3034
- * @see {@link HttpAwaitResult}
3035
- * @see {@link StreamAwaitResult}
3036
- * @see {@link SocketAwaitResult}
3037
- */
3038
- type Client = {
3039
- /** Internal symbol key for the resolved client configuration. */
3040
- readonly [CLIENT]: ClientConfig;
3041
- /** Open an SSE command and return stream open/await results. */
3042
- 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>>;
3043
- /** Open a WebSocket command and return session await results. */
3044
- 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>>>;
3045
- /** Run an HTTP command and return an await-result tuple. */
3046
- 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>>;
2607
+ */
2608
+ type RequestOptions = {
2609
+ /** Aborts the call. An already aborted signal fails the call before transport. */
2610
+ abort?: AbortSignal;
2611
+ /** Observes HTTP upload progress. */
2612
+ onUploadProgress?: HttpProgressFn;
2613
+ /** Observes HTTP download progress. */
2614
+ onDownloadProgress?: HttpProgressFn;
2615
+ /** Runs before each WebSocket connect attempt for this call. */
2616
+ beforeConnect?: ClientWebSocketOptions["beforeConnect"];
2617
+ /** WebSocket subprotocols for this call. Replaces the client list; it is not appended. */
2618
+ protocols?: readonly string[];
2619
+ /** WebSocket heartbeat for this call. Replaces the client heartbeat as a whole value. */
2620
+ heartbeat?: ClientWebSocketOptions["heartbeat"];
2621
+ /** WebSocket reconnect policy for this call. Replaces the client policy as a whole value. */
2622
+ reconnect?: ClientWebSocketOptions["reconnect"];
3047
2623
  };
2624
+ interface ClientState {
2625
+ readonly config: ClientConfig;
2626
+ readonly options: RequestOptions;
2627
+ }
2628
+ /**
2629
+ * Application client returned by `createClient`.
2630
+ *
2631
+ * Calling it returns a new client. The seven known fields are copied from the argument when `client(options)` is called, a top-level snapshot into a fresh options object overlaid on the current options. A later field wins. A field whose value is `undefined` is treated as not provided and keeps the parent's value. A derived client cannot drop a setting its parent has; to go back to no setting, derive again from the client that did not have it. Nested `heartbeat`, `protocols`, and `reconnect` values are kept by reference, not cloned. WebSocket reads them when the operation runs, copying heartbeat fields and the protocols list at that time, so mutating those objects after deriving can still affect a later call. Applications should treat them as immutable after passing them. The original client is not mutated. `client()`, `client(undefined)`, and `client({})` copy the current options. Deriving a client performs no I/O. A getter that throws does so from the call and is not returned as a fault.
2632
+ *
2633
+ * @group client
2634
+ * @see {@link createClient}
2635
+ * @see {@link RequestOptions}
2636
+ */
2637
+ interface Client {
2638
+ /** Returns a new client with `options` overlaid on this client's request options. */
2639
+ (options?: RequestOptions): Client;
2640
+ /** Internal state. Not part of the call surface. */
2641
+ readonly [CLIENT]: ClientState;
2642
+ }
3048
2643
  /**
3049
2644
  * Creates a Defjs client from option helpers.
3050
2645
  *
3051
- * Options apply in order: a later option overwrites an earlier one for the same setting, and interceptors accumulate. Prefer creating the client inside the request boundary when interceptors close over auth or tenants. Default HTTP/SSE fetch availability is checked when the interceptor chain invokes transport.
2646
+ * Options apply in order: a later option overwrites an earlier one for the same setting, and interceptors accumulate. Prefer creating the client inside the request boundary when interceptors close over auth or tenants. Default HTTP/SSE fetch availability is checked when an operation invokes transport.
2647
+ *
2648
+ * The returned client is a function. Call it with {@link RequestOptions} to derive a client for one operation. The seven known fields are copied from that argument into a fresh options object. Nested `heartbeat`, `protocols`, and `reconnect` values are kept by reference. The base configuration is shared by every derived client and is not frozen at runtime. It is fixed by convention: nothing in the library changes it, and applications should not either. A getter that throws escapes the call; it is not converted into a fault.
3052
2649
  *
3053
2650
  * @param options - Client option helpers such as `withEndpoint`.
3054
- * @returns A client that can `execute` HTTP, SSE, and WebSocket commands.
2651
+ * @returns A callable client that carries the resolved base configuration.
3055
2652
  *
3056
2653
  * @group client
3057
2654
  * @see {@link Client}
3058
2655
  * @see {@link ClientOption}
2656
+ * @see {@link RequestOptions}
3059
2657
  * @exampleFile examples/api/create-client.ts#example
3060
2658
  */
3061
2659
  export declare function createClient(...options: ClientOption[]): Client;
2660
+ /**
2661
+ * HTTP fields of {@link RequestOptions}: progress callbacks and `abort`.
2662
+ *
2663
+ * `onDownloadProgress` and `onUploadProgress` are {@link HttpProgressFn}
2664
+ * callbacks. They receive an {@link HttpProgressEvent} with `loaded`, `total`,
2665
+ * and `lengthComputable`. Other request fields are ignored by HTTP.
2666
+ *
2667
+ * @group http
2668
+ */
2669
+ export type UseRequestConfig = {
2670
+ /** Aborts the call. */
2671
+ abort?: AbortSignal;
2672
+ /** Observes download progress. */
2673
+ onDownloadProgress?: HttpProgressFn;
2674
+ /** Observes upload progress. */
2675
+ onUploadProgress?: HttpProgressFn;
2676
+ };
2677
+ /**
2678
+ * HTTP fields read from {@link RequestOptions} for one call.
2679
+ *
2680
+ * Progress callbacks and `abort`. There is no `timeout` or `signal`.
2681
+ *
2682
+ * @group http
2683
+ */
2684
+ export type HttpExecuteOptions = UseRequestConfig;
2685
+ /**
2686
+ * Operation returned by `defineRequest`.
2687
+ *
2688
+ * The first argument is a {@link Client}. Further arguments are the input, and only the input: none when the definition declares no `input`, optional when the input struct accepts `undefined`, and required otherwise. Calling it starts the request and returns the error-first tuple.
2689
+ *
2690
+ * @group http
2691
+ */
2692
+ export type RequestEndpoint<Args extends unknown[], Data, ErrorData, Response extends HttpMeta> = (client: Client, ...args: Args) => Promise<[error: null, result: Data, response: Response] | [error: FaultOf<ErrorData>, result: undefined, response: undefined]>;
2693
+ type DeclaredBody<TStruct> = [TStruct] extends [undefined] ? undefined : Infer<TStruct>;
2694
+ type DeclaredResponse<TStruct> = [TStruct] extends [undefined] ? HttpMeta : DecodedResponse<Infer<TStruct>>;
2695
+ /**
2696
+ * Decoded success body for the declared `output` struct, or `undefined` when none is declared.
2697
+ *
2698
+ * @group http
2699
+ */
2700
+ export type RequestSuccessData<TOutput extends AnyStruct | undefined> = DeclaredBody<TOutput>;
2701
+ /**
2702
+ * Decoded error body for the declared `error` struct, or `undefined` when none is declared.
2703
+ *
2704
+ * @group http
2705
+ */
2706
+ export type RequestErrorData<TError extends AnyStruct | undefined> = DeclaredBody<TError>;
2707
+ type ResponseDeclaration<TOutput extends AnyStruct | undefined, TError extends AnyStruct | undefined> = ([TOutput] extends [undefined] ? {
2708
+ output?: never;
2709
+ } : {
2710
+ output: TOutput;
2711
+ }) & ([TError] extends [undefined] ? {
2712
+ error?: never;
2713
+ } : {
2714
+ error: TError;
2715
+ });
2716
+ /**
2717
+ * Contract for an HTTP endpoint: method, path, optional input, and the structs that decode its bodies.
2718
+ *
2719
+ * Declaring `input` requires an explicit `builder` to place the parsed value on
2720
+ * the request. `input` only defines the parameters; the builder alone decides
2721
+ * where each value goes. Only definitions without `input` may omit `builder`.
2722
+ * `output` declares the body for a 2xx response, `error` the body for anything
2723
+ * else. Only one of the two ever runs, and omitting one means that body is never
2724
+ * read. `ResponseDeclaration` is an internal helper type: `output` and `error`
2725
+ * are required only when the matching type parameter is a struct. There is no
2726
+ * `responseType`: the struct kind selects how a declared body is read. Pass to
2727
+ * `defineRequest` to get a typed endpoint.
2728
+ *
2729
+ * @group http
2730
+ */
2731
+ export type RequestDefinition<TInput extends AnyStruct | undefined = undefined, TOutput extends AnyStruct | undefined = undefined, TError extends AnyStruct | undefined = undefined> = ResponseDeclaration<TOutput, TError> & {
2732
+ builder?: OutboundBuilder;
2733
+ input?: TInput;
2734
+ method: string;
2735
+ operation?: string;
2736
+ path: string;
2737
+ };
2738
+ /**
2739
+ * Await-result tuple for an HTTP call: success is `[null, data, response]`, and failure is `[fault, undefined, undefined]`.
2740
+ *
2741
+ * `TData` and `TErrorData` are decoded body types. On success the third slot
2742
+ * carries `body` only when `output` was declared. On failure it is `undefined`,
2743
+ * because the fault already holds whatever response metadata existed.
2744
+ *
2745
+ * @group http
2746
+ */
2747
+ 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];
2748
+ /**
2749
+ * Declares a typed HTTP request endpoint.
2750
+ *
2751
+ * Pass method, path, an optional input struct, and the single `output` and
2752
+ * `error` structs. Call the returned operation with a client and, when declared, the input.
2753
+ *
2754
+ * The contract is `method`, `path`, an optional `input` struct, optional
2755
+ * `output` and `error` structs, and an optional `operation`. A declared `input`
2756
+ * always requires an explicit `builder`. `input` only defines the parameters;
2757
+ * the builder alone decides where each value goes. Only definitions without
2758
+ * `input` may omit `builder`. `ResponseDeclaration` and `BuilderField` are
2759
+ * internal helper types: `output` and `error` are required only when the
2760
+ * matching type parameter is a struct, and `builder` is
2761
+ * `(input: BuilderInput<TInput>) => HttpRequestShape` when `input` is declared.
2762
+ *
2763
+ * `output` is one struct for the 2xx body; `error` is one struct for every
2764
+ * non-2xx body. Neither is keyed by status. A declaration is an assertion:
2765
+ * omitting one means that body is never read.
2766
+ *
2767
+ * @param definition - Request contract (method, path, input, builder, output).
2768
+ * @returns An operation `(client, ...input) => Promise<error-first tuple>`.
2769
+ *
2770
+ * The checked example file passes the whole input object as `path`. This snippet maps individual fields into `path` and `query` instead:
2771
+ *
2772
+ * @example
2773
+ * ```ts
2774
+ * const getUser = defineRequest({
2775
+ * method: 'GET',
2776
+ * path: '/users/:id',
2777
+ * input: struct.object({ id: struct.number(), verbose: struct.boolean() }),
2778
+ * builder: (input) => ({ path: { id: input.id }, query: { verbose: input.verbose } }),
2779
+ * output: struct.object({ id: struct.number(), name: struct.string() }),
2780
+ * })
2781
+ * ```
2782
+ * @group http
2783
+ * @exampleFile examples/api/define-request.ts#example
2784
+ */
2785
+ 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> & {
2786
+ input?: TInput;
2787
+ method: M;
2788
+ operation?: string;
2789
+ path: P;
2790
+ } & BuilderField<NoInfer<TInput>, HttpRequestShape<NoInfer<P>, NoInfer<M>>>): RequestEndpoint<EndpointArgs<TInput>, RequestSuccessData<TOutput>, RequestErrorData<TError>, DeclaredResponse<TOutput>>;
3062
2791
  /**
3063
2792
  * Default HTTP transport: perform `httpRequest` with `fetch` and return an `HttpResponse`.
3064
2793
  *
@@ -3079,7 +2808,7 @@ export declare function fetchHandler(httpRequest: HttpRequest, fetchImpl?: Fetch
3079
2808
  /**
3080
2809
  * Resolves a relative definition path under the base endpoint's origin and directory into a URL.
3081
2810
  *
3082
- * During `client.execute`, a missing, relative, or invalid base or an illegal
2811
+ * During an operation, a missing, relative, or invalid base or an illegal
3083
2812
  * path becomes `REQ_BUILD_FAILED` before any interceptor or transport runs,
3084
2813
  * including a short-circuiting interceptor, for HTTP, SSE, and WebSocket alike.
3085
2814
  * An interceptor's final `req.endpoint` is also validated against its final
@@ -3122,7 +2851,7 @@ type BasicAuthInterceptorOptions = {
3122
2851
  * `encode`, calling `basicAuthHttpInterceptor` throws
3123
2852
  * `Error: BasicAuthInterceptor is not supported in this environment` when `btoa`
3124
2853
  * is not available in the runtime. Use {@link basicAuthSSEInterceptor} for SSE
3125
- * commands.
2854
+ * operations.
3126
2855
  *
3127
2856
  * @param fn - Factory returning username/password for each request.
3128
2857
  * @param options - Optional custom encoder (defaults to `btoa`).
@@ -3144,4 +2873,122 @@ export declare function basicAuthHttpInterceptor(fn: () => BasicCredential, opti
3144
2873
  * @group interceptors
3145
2874
  */
3146
2875
  export declare function basicAuthSSEInterceptor(fn: () => BasicCredential, options?: BasicAuthInterceptorOptions): SSEInterceptor;
3147
- 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 };
2876
+ /**
2877
+ * Map from SSE event names to the structs that decode their data.
2878
+ *
2879
+ * An event with no `event:` field is named `message`. An event whose name has no own entry uses the `default` struct; with neither, the event is skipped and `onInvalidEvent` is called. Declare the event name `__proto__` with a computed own key.
2880
+ *
2881
+ * A `string` event struct keeps the raw `data` text. Every other kind is JSON text: `JSON.parse`, then the struct. A bare `struct.literal` therefore needs JSON text, not an unquoted token.
2882
+ *
2883
+ * Reconnect lives on the client (`withSSEReconnect`). SSE `jitter` is a **0-1 multiplicative factor**, same as WebSocket.
2884
+ *
2885
+ * @group sse
2886
+ */
2887
+ export type EventStructs = {
2888
+ [key: string]: AnyStruct;
2889
+ };
2890
+ type EventName<TKey extends string | number> = `${TKey}`;
2891
+ type KnownEventUnion<TEvents extends EventStructs> = { [K in keyof TEvents & (number | string)]: EventName<K> extends "default" ? never : {
2892
+ data: Infer<TEvents[K]>;
2893
+ event: EventName<K>;
2894
+ id?: string;
2895
+ }; }[keyof TEvents & (number | string)];
2896
+ type DefaultEventUnion<TEvents extends EventStructs> = "default" extends keyof TEvents ? {
2897
+ data: Infer<TEvents["default"]>;
2898
+ event: string;
2899
+ id?: string;
2900
+ } : never;
2901
+ /**
2902
+ * Union of parsed SSE events inferred from an EventStructs map.
2903
+ *
2904
+ * For each declared event name except `default`, the union has `{ event: <name>; data: Infer<TEvents[name]>; id?: string }`. When a `default` struct is declared, it adds `{ event: string; data: Infer<TEvents['default']>; id?: string }` for every event name that has no struct of its own. `KnownEventUnion` and `DefaultEventUnion` are internal helper types.
2905
+ *
2906
+ * @group sse
2907
+ */
2908
+ export type EventStreamData<TEvents extends EventStructs> = TEvents extends EventStructs ? KnownEventUnion<TEvents> | DefaultEventUnion<TEvents> : never;
2909
+ interface EventStreamDefinitionBase<TEvents extends EventStructs = EventStructs> {
2910
+ events: TEvents;
2911
+ maxBufferSize: number;
2912
+ maxQueueSize: number;
2913
+ method?: string;
2914
+ operation?: string;
2915
+ path: string;
2916
+ }
2917
+ /** Makes `error` required only when an error struct is declared, so omission stays `Fault<undefined>`. */
2918
+ type EventStreamErrorField<TError extends AnyStruct | undefined> = [TError] extends [undefined] ? {
2919
+ error?: never;
2920
+ } : {
2921
+ error: TError;
2922
+ };
2923
+ /**
2924
+ * Contract that describes an SSE endpoint for defineEventStream.
2925
+ *
2926
+ * The composed members are:
2927
+ *
2928
+ * - `events`, `maxBufferSize`, and `maxQueueSize` (both limits are required positive safe integers), optional `method`, `operation`, and a required `path`.
2929
+ *
2930
+ * - `error`, required only when `TError` is a struct. It decodes the body of a failed handshake (a non-2xx response). The kind rule is the same as for HTTP: `string` is text, `blob` and `file` are blobs, `arrayBuffer` is bytes, and everything else is JSON.
2931
+ *
2932
+ * - `input` and `builder`. The request shape matches HTTP, including `body`; `GET` and `HEAD` cannot return a body. A declared `input` always requires an explicit `builder`. `input` only defines the parameters; the builder alone decides where each value goes. Only definitions without `input` may omit `builder`.
2933
+ *
2934
+ * `EventStreamDefinitionBase` and `EventStreamErrorField` are internal helper types.
2935
+ *
2936
+ * @group sse
2937
+ */
2938
+ export type EventStreamDefinition<TInput extends AnyStruct | undefined = undefined, TEvents extends EventStructs = EventStructs, TError extends AnyStruct | undefined = undefined> = EventStreamDefinitionBase<TEvents> & EventStreamErrorField<TError> & {
2939
+ builder?: OutboundBuilder;
2940
+ input?: TInput;
2941
+ };
2942
+ /**
2943
+ * Await-result tuple from opening an SSE stream.
2944
+ *
2945
+ * - On success: `[null, stream, open]`. `open` is the returned connection's first successful handshake snapshot for native Defjs handles or wrappers forwarding the same live `open` object; custom handles or wrappers overriding `open` use their current public `open` even after reconnect, while `stream.open` stays live.
2946
+ *
2947
+ * - On failure: `[fault, undefined, open]`. `open` carries the response snapshot when the failure happened after a response arrived, for example a non-2xx handshake, and is `undefined` otherwise.
2948
+ *
2949
+ * - `TError` is the declared `error` struct. It types the decoded error body on the fault.
2950
+ *
2951
+ * @group sse
2952
+ */
2953
+ export type StreamAwaitResult<TEvent, TError extends AnyStruct | undefined = undefined> = [error: null, stream: EventStreamHandle<TEvent>, open: EventStreamOpenInfo] | [error: Fault<TError>, stream: undefined, open: EventStreamOpenInfo | undefined];
2954
+ /**
2955
+ * SSE field of {@link RequestOptions}. HTTP progress and WebSocket fields are ignored.
2956
+ *
2957
+ * `abort` covers the whole stream, including after it opens. There is no startup-only deadline.
2958
+ *
2959
+ * @group sse
2960
+ */
2961
+ export type EventStreamExecuteOptions = {
2962
+ /** Aborts the stream, including after it is open. */
2963
+ abort?: AbortSignal;
2964
+ };
2965
+ /**
2966
+ * Operation returned by `defineEventStream`.
2967
+ *
2968
+ * The first argument is a {@link Client}. Further arguments are the input only. Calling it opens the stream and returns the existing error-first tuple.
2969
+ *
2970
+ * @group sse
2971
+ */
2972
+ export type EventStreamEndpoint<Args extends unknown[], Event, TError extends AnyStruct | undefined = undefined> = (client: Client, ...args: Args) => Promise<StreamAwaitResult<Event, TError>>;
2973
+ /**
2974
+ * Declare a typed Server-Sent Events endpoint.
2975
+ *
2976
+ * Pass path, event structs, and buffer/queue limits. Call the returned operation
2977
+ * with a client and, when declared, the input.
2978
+ *
2979
+ * - **definition** — `path`, an `events` map, and the required `maxBufferSize` and `maxQueueSize` limits (positive safe integers). Optional `method` (default `'GET'`), `operation`, `input`, and `error`. A declared `input` always requires an explicit `builder`. `input` only defines the parameters; the builder alone decides where each value goes. Only definitions without `input` may omit `builder`.
2980
+ *
2981
+ * `EventStreamDefinitionBase`, `EventStreamErrorField`, and `BuilderField` are internal helper types: `error` is required only when `TError` is a struct, and `builder` is `(input: BuilderInput<TInput>) => EventStreamRequestShape` when `input` is declared.
2982
+ *
2983
+ * @param definition - SSE contract (path, events, buffer limits, optional input).
2984
+ * @returns An operation `(client, ...input) => Promise<error-first tuple>`.
2985
+ *
2986
+ * @group sse
2987
+ * @exampleFile examples/api/define-event-stream.ts#example
2988
+ */
2989
+ 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> & {
2990
+ input?: TInput;
2991
+ method?: M;
2992
+ path: P;
2993
+ } & BuilderField<NoInfer<TInput>, EventStreamRequestShape<NoInfer<P>, NoInfer<M>>>): EventStreamEndpoint<EndpointArgs<TInput>, EventStreamData<TEvents>, TError>;
2994
+ 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, RequestOptions, SSEHandler, SSEInterceptor, SSEInterceptorFn, STRUCT, Struct, StructInput, StructIssue, StructLike, StructMethods, WebSocketHandle, WebSocketHandleConstructor, WebSocketHandler, WebSocketInterceptor, WebSocketInterceptorFn, WebSocketRequestShape, WebSocketSessionLike };