Skip to content

Commit 47a1a97

Browse files
chore(internal): codegen related update
1 parent 2b21718 commit 47a1a97

4 files changed

Lines changed: 79 additions & 10 deletions

File tree

src/client.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,8 @@ export interface ClientOptions {
8989
*
9090
* Note that request timeouts are retried by default, so in a worst-case scenario you may wait
9191
* much longer than this timeout before the promise succeeds or fails.
92+
*
93+
* @unit milliseconds
9294
*/
9395
timeout?: number | undefined;
9496
/**

src/core/streaming.ts

Lines changed: 22 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@ import { findDoubleNewlineIndex, LineDecoder } from '../internal/decoders/line';
55
import { ReadableStreamToAsyncIterable } from '../internal/shims';
66
import { isAbortError } from '../internal/errors';
77
import { encodeUTF8 } from '../internal/utils/bytes';
8+
import { loggerFor } from '../internal/utils/log';
9+
import type { Opencode } from '../client';
810

911
type Bytes = string | ArrayBuffer | Uint8Array | null | undefined;
1012

@@ -16,16 +18,24 @@ export type ServerSentEvent = {
1618

1719
export class Stream<Item> implements AsyncIterable<Item> {
1820
controller: AbortController;
21+
#client: Opencode | undefined;
1922

2023
constructor(
2124
private iterator: () => AsyncIterator<Item>,
2225
controller: AbortController,
26+
client?: Opencode,
2327
) {
2428
this.controller = controller;
29+
this.#client = client;
2530
}
2631

27-
static fromSSEResponse<Item>(response: Response, controller: AbortController): Stream<Item> {
32+
static fromSSEResponse<Item>(
33+
response: Response,
34+
controller: AbortController,
35+
client?: Opencode,
36+
): Stream<Item> {
2837
let consumed = false;
38+
const logger = client ? loggerFor(client) : console;
2939

3040
async function* iterator(): AsyncIterator<Item, any, undefined> {
3141
if (consumed) {
@@ -38,8 +48,8 @@ export class Stream<Item> implements AsyncIterable<Item> {
3848
try {
3949
yield JSON.parse(sse.data);
4050
} catch (e) {
41-
console.error(`Could not parse message into JSON:`, sse.data);
42-
console.error(`From chunk:`, sse.raw);
51+
logger.error(`Could not parse message into JSON:`, sse.data);
52+
logger.error(`From chunk:`, sse.raw);
4353
throw e;
4454
}
4555
}
@@ -54,14 +64,18 @@ export class Stream<Item> implements AsyncIterable<Item> {
5464
}
5565
}
5666

57-
return new Stream(iterator, controller);
67+
return new Stream(iterator, controller, client);
5868
}
5969

6070
/**
6171
* Generates a Stream from a newline-separated ReadableStream
6272
* where each item is a JSON value.
6373
*/
64-
static fromReadableStream<Item>(readableStream: ReadableStream, controller: AbortController): Stream<Item> {
74+
static fromReadableStream<Item>(
75+
readableStream: ReadableStream,
76+
controller: AbortController,
77+
client?: Opencode,
78+
): Stream<Item> {
6579
let consumed = false;
6680

6781
async function* iterLines(): AsyncGenerator<string, void, unknown> {
@@ -101,7 +115,7 @@ export class Stream<Item> implements AsyncIterable<Item> {
101115
}
102116
}
103117

104-
return new Stream(iterator, controller);
118+
return new Stream(iterator, controller, client);
105119
}
106120

107121
[Symbol.asyncIterator](): AsyncIterator<Item> {
@@ -131,8 +145,8 @@ export class Stream<Item> implements AsyncIterable<Item> {
131145
};
132146

133147
return [
134-
new Stream(() => teeIterator(left), this.controller),
135-
new Stream(() => teeIterator(right), this.controller),
148+
new Stream(() => teeIterator(left), this.controller, this.#client),
149+
new Stream(() => teeIterator(right), this.controller, this.#client),
136150
];
137151
}
138152

src/internal/parse.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,10 +24,10 @@ export async function defaultParseResponse<T>(client: Opencode, props: APIRespon
2424
// that if you set `stream: true` the response type must also be `Stream<T>`
2525

2626
if (props.options.__streamClass) {
27-
return props.options.__streamClass.fromSSEResponse(response, props.controller) as any;
27+
return props.options.__streamClass.fromSSEResponse(response, props.controller, client) as any;
2828
}
2929

30-
return Stream.fromSSEResponse(response, props.controller) as any;
30+
return Stream.fromSSEResponse(response, props.controller, client) as any;
3131
}
3232

3333
// fetch refuses to read the body when the status code is 204.

src/internal/request-options.ts

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,17 +10,70 @@ import { type HeadersLike } from './headers';
1010
export type FinalRequestOptions = RequestOptions & { method: HTTPMethod; path: string };
1111

1212
export type RequestOptions = {
13+
/**
14+
* The HTTP method for the request (e.g., 'get', 'post', 'put', 'delete').
15+
*/
1316
method?: HTTPMethod;
17+
18+
/**
19+
* The URL path for the request.
20+
*
21+
* @example "/v1/foo"
22+
*/
1423
path?: string;
24+
25+
/**
26+
* Query parameters to include in the request URL.
27+
*/
1528
query?: object | undefined | null;
29+
30+
/**
31+
* The request body. Can be a string, JSON object, FormData, or other supported types.
32+
*/
1633
body?: unknown;
34+
35+
/**
36+
* HTTP headers to include with the request. Can be a Headers object, plain object, or array of tuples.
37+
*/
1738
headers?: HeadersLike;
39+
40+
/**
41+
* The maximum number of times that the client will retry a request in case of a
42+
* temporary failure, like a network error or a 5XX error from the server.
43+
*
44+
* @default 2
45+
*/
1846
maxRetries?: number;
47+
1948
stream?: boolean | undefined;
49+
50+
/**
51+
* The maximum amount of time (in milliseconds) that the client should wait for a response
52+
* from the server before timing out a single request.
53+
*
54+
* @unit milliseconds
55+
*/
2056
timeout?: number;
57+
58+
/**
59+
* Additional `RequestInit` options to be passed to the underlying `fetch` call.
60+
* These options will be merged with the client's default fetch options.
61+
*/
2162
fetchOptions?: MergedRequestInit;
63+
64+
/**
65+
* An AbortSignal that can be used to cancel the request.
66+
*/
2267
signal?: AbortSignal | undefined | null;
68+
69+
/**
70+
* A unique key for this request to enable idempotency.
71+
*/
2372
idempotencyKey?: string;
73+
74+
/**
75+
* Override the default base URL for this specific request.
76+
*/
2477
defaultBaseURL?: string | undefined;
2578

2679
__binaryResponse?: boolean | undefined;

0 commit comments

Comments
 (0)