@durable-streams/client 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +799 -0
- package/dist/index.cjs +1172 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +627 -0
- package/dist/index.d.ts +1072 -0
- package/dist/index.js +1830 -0
- package/dist/index.js.map +1 -0
- package/package.json +46 -0
- package/src/asyncIterableReadableStream.ts +220 -0
- package/src/constants.ts +105 -0
- package/src/error.ts +189 -0
- package/src/fetch.ts +267 -0
- package/src/index.ts +103 -0
- package/src/response.ts +1053 -0
- package/src/sse.ts +130 -0
- package/src/stream-api.ts +284 -0
- package/src/stream.ts +867 -0
- package/src/types.ts +737 -0
- package/src/utils.ts +104 -0
package/dist/index.d.cts
ADDED
|
@@ -0,0 +1,627 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Durable Streams TypeScript Client Types
|
|
3
|
+
*
|
|
4
|
+
* Following the Electric Durable Stream Protocol specification.
|
|
5
|
+
*/
|
|
6
|
+
/**
|
|
7
|
+
* Offset string - opaque to the client.
|
|
8
|
+
* Format: "<read-seq>_<byte-offset>"
|
|
9
|
+
*
|
|
10
|
+
* Always use the returned `offset` field from reads/follows as the next `offset` you pass in.
|
|
11
|
+
*/
|
|
12
|
+
type Offset = string;
|
|
13
|
+
/**
|
|
14
|
+
* Type for values that can be provided immediately or resolved asynchronously.
|
|
15
|
+
*/
|
|
16
|
+
type MaybePromise<T> = T | Promise<T>;
|
|
17
|
+
/**
|
|
18
|
+
* Auth configuration for requests.
|
|
19
|
+
*
|
|
20
|
+
* Supports:
|
|
21
|
+
* - Fixed tokens with optional custom header name
|
|
22
|
+
* - Arbitrary static headers
|
|
23
|
+
* - Async header resolution (e.g., for short-lived tokens)
|
|
24
|
+
*/
|
|
25
|
+
type Auth = {
|
|
26
|
+
token: string;
|
|
27
|
+
headerName?: string;
|
|
28
|
+
} | {
|
|
29
|
+
headers: Record<string, string>;
|
|
30
|
+
} | {
|
|
31
|
+
getHeaders: () => Promise<Record<string, string>>;
|
|
32
|
+
};
|
|
33
|
+
/**
|
|
34
|
+
* Headers record where values can be static strings or async functions.
|
|
35
|
+
* Following the @electric-sql/client pattern for dynamic headers.
|
|
36
|
+
*/
|
|
37
|
+
type HeadersRecord = {
|
|
38
|
+
[key: string]: string | (() => MaybePromise<string>);
|
|
39
|
+
};
|
|
40
|
+
/**
|
|
41
|
+
* Params record where values can be static or async functions.
|
|
42
|
+
* Following the @electric-sql/client pattern for dynamic params.
|
|
43
|
+
*/
|
|
44
|
+
type ParamsRecord = {
|
|
45
|
+
[key: string]: string | (() => MaybePromise<string>) | undefined;
|
|
46
|
+
};
|
|
47
|
+
/**
|
|
48
|
+
* Base options for all stream operations.
|
|
49
|
+
*/
|
|
50
|
+
interface StreamOptions {
|
|
51
|
+
/**
|
|
52
|
+
* The full URL to the durable stream.
|
|
53
|
+
* E.g., "https://streams.example.com/my-account/chat/room-1"
|
|
54
|
+
*/
|
|
55
|
+
url: string;
|
|
56
|
+
/**
|
|
57
|
+
* Authentication configuration.
|
|
58
|
+
* If using auth, you can provide:
|
|
59
|
+
* - A token (sent as Bearer token in Authorization header by default)
|
|
60
|
+
* - Custom headers
|
|
61
|
+
* - An async function to get headers (for refreshing tokens)
|
|
62
|
+
*/
|
|
63
|
+
auth?: Auth;
|
|
64
|
+
/**
|
|
65
|
+
* Additional headers to include in requests.
|
|
66
|
+
* Values can be strings or functions (sync or async) that return strings.
|
|
67
|
+
* Function values are resolved when needed, making this useful
|
|
68
|
+
* for dynamic headers like authentication tokens.
|
|
69
|
+
*/
|
|
70
|
+
headers?: HeadersRecord;
|
|
71
|
+
/**
|
|
72
|
+
* Additional query parameters to include in requests.
|
|
73
|
+
* Values can be strings or functions (sync or async) that return strings.
|
|
74
|
+
*/
|
|
75
|
+
params?: ParamsRecord;
|
|
76
|
+
/**
|
|
77
|
+
* Custom fetch implementation.
|
|
78
|
+
* Defaults to globalThis.fetch.
|
|
79
|
+
*/
|
|
80
|
+
fetch?: typeof globalThis.fetch;
|
|
81
|
+
/**
|
|
82
|
+
* Default AbortSignal for operations.
|
|
83
|
+
* Individual operations can override this.
|
|
84
|
+
*/
|
|
85
|
+
signal?: AbortSignal;
|
|
86
|
+
}
|
|
87
|
+
/**
|
|
88
|
+
* Options for creating a new stream.
|
|
89
|
+
*/
|
|
90
|
+
interface CreateOptions extends StreamOptions {
|
|
91
|
+
/**
|
|
92
|
+
* The content type for the stream.
|
|
93
|
+
* This is set once on creation and cannot be changed.
|
|
94
|
+
*/
|
|
95
|
+
contentType?: string;
|
|
96
|
+
/**
|
|
97
|
+
* Time-to-live in seconds (relative TTL).
|
|
98
|
+
*/
|
|
99
|
+
ttlSeconds?: number;
|
|
100
|
+
/**
|
|
101
|
+
* Absolute expiry time (RFC3339 format).
|
|
102
|
+
*/
|
|
103
|
+
expiresAt?: string;
|
|
104
|
+
/**
|
|
105
|
+
* Initial body to append on creation.
|
|
106
|
+
*/
|
|
107
|
+
body?: BodyInit | Uint8Array | string;
|
|
108
|
+
}
|
|
109
|
+
/**
|
|
110
|
+
* Options for appending data to a stream.
|
|
111
|
+
*/
|
|
112
|
+
interface AppendOptions {
|
|
113
|
+
/**
|
|
114
|
+
* Writer coordination sequence (stream-seq header).
|
|
115
|
+
* Monotonic, lexicographic sequence for coordinating multiple writers.
|
|
116
|
+
* If lower than last appended seq, server returns 409 Conflict.
|
|
117
|
+
* Not related to read offsets.
|
|
118
|
+
*/
|
|
119
|
+
seq?: string;
|
|
120
|
+
/**
|
|
121
|
+
* Content type for this append.
|
|
122
|
+
* Must match the stream's content type.
|
|
123
|
+
*/
|
|
124
|
+
contentType?: string;
|
|
125
|
+
/**
|
|
126
|
+
* AbortSignal for this operation.
|
|
127
|
+
*/
|
|
128
|
+
signal?: AbortSignal;
|
|
129
|
+
}
|
|
130
|
+
/**
|
|
131
|
+
* Live mode for reading from a stream.
|
|
132
|
+
*/
|
|
133
|
+
type LiveMode = `catchup` | `long-poll` | `sse`;
|
|
134
|
+
/**
|
|
135
|
+
* Options for reading from a stream.
|
|
136
|
+
*/
|
|
137
|
+
interface ReadOptions {
|
|
138
|
+
/**
|
|
139
|
+
* Starting offset, passed as ?offset=...
|
|
140
|
+
* If omitted, reads from the start of the stream.
|
|
141
|
+
*/
|
|
142
|
+
offset?: Offset;
|
|
143
|
+
/**
|
|
144
|
+
* Live mode behavior:
|
|
145
|
+
* - undefined (default for follow()): Start catch-up, then auto-select SSE or long-poll
|
|
146
|
+
* - "catchup": Only catch-up, stop after up-to-date
|
|
147
|
+
* - "long-poll": Skip catch-up, start long-polling immediately
|
|
148
|
+
* - "sse": Skip catch-up, start SSE immediately (throws if unsupported)
|
|
149
|
+
*/
|
|
150
|
+
live?: LiveMode;
|
|
151
|
+
/**
|
|
152
|
+
* Override cursor for the request.
|
|
153
|
+
* By default, the client echoes the last stream-cursor value.
|
|
154
|
+
*/
|
|
155
|
+
cursor?: string;
|
|
156
|
+
/**
|
|
157
|
+
* AbortSignal for this operation.
|
|
158
|
+
*/
|
|
159
|
+
signal?: AbortSignal;
|
|
160
|
+
}
|
|
161
|
+
/**
|
|
162
|
+
* Result from a HEAD request on a stream.
|
|
163
|
+
*/
|
|
164
|
+
interface HeadResult {
|
|
165
|
+
/**
|
|
166
|
+
* Whether the stream exists.
|
|
167
|
+
*/
|
|
168
|
+
exists: true;
|
|
169
|
+
/**
|
|
170
|
+
* The stream's content type.
|
|
171
|
+
*/
|
|
172
|
+
contentType?: string;
|
|
173
|
+
/**
|
|
174
|
+
* The tail offset (next offset after current end of stream).
|
|
175
|
+
* Provided by server as stream-offset header on HEAD.
|
|
176
|
+
*/
|
|
177
|
+
offset?: Offset;
|
|
178
|
+
/**
|
|
179
|
+
* ETag for the stream (format: {internal_stream_id}:{end_offset}).
|
|
180
|
+
*/
|
|
181
|
+
etag?: string;
|
|
182
|
+
/**
|
|
183
|
+
* Cache-Control header value.
|
|
184
|
+
*/
|
|
185
|
+
cacheControl?: string;
|
|
186
|
+
}
|
|
187
|
+
/**
|
|
188
|
+
* Result from a read operation.
|
|
189
|
+
*/
|
|
190
|
+
interface ReadResult {
|
|
191
|
+
/**
|
|
192
|
+
* The data read from the stream.
|
|
193
|
+
*/
|
|
194
|
+
data: Uint8Array;
|
|
195
|
+
/**
|
|
196
|
+
* Next offset to read from.
|
|
197
|
+
* This is the HTTP stream-offset header value.
|
|
198
|
+
*/
|
|
199
|
+
offset: Offset;
|
|
200
|
+
/**
|
|
201
|
+
* Cursor for CDN collapsing (stream-cursor header).
|
|
202
|
+
*/
|
|
203
|
+
cursor?: string;
|
|
204
|
+
/**
|
|
205
|
+
* True if stream-up-to-date header was present.
|
|
206
|
+
* Indicates the response ends at the current end of the stream.
|
|
207
|
+
*/
|
|
208
|
+
upToDate: boolean;
|
|
209
|
+
/**
|
|
210
|
+
* ETag for caching.
|
|
211
|
+
*/
|
|
212
|
+
etag?: string;
|
|
213
|
+
/**
|
|
214
|
+
* Content type of the data.
|
|
215
|
+
*/
|
|
216
|
+
contentType?: string;
|
|
217
|
+
}
|
|
218
|
+
/**
|
|
219
|
+
* A chunk returned from follow() or toReadableStream().
|
|
220
|
+
* Same structure as ReadResult.
|
|
221
|
+
*/
|
|
222
|
+
interface StreamChunk extends ReadResult {
|
|
223
|
+
}
|
|
224
|
+
/**
|
|
225
|
+
* Error codes for DurableStreamError.
|
|
226
|
+
*/
|
|
227
|
+
type DurableStreamErrorCode = `NOT_FOUND` | `CONFLICT_SEQ` | `CONFLICT_EXISTS` | `BAD_REQUEST` | `BUSY` | `SSE_NOT_SUPPORTED` | `UNAUTHORIZED` | `FORBIDDEN` | `RATE_LIMITED` | `UNKNOWN`;
|
|
228
|
+
/**
|
|
229
|
+
* Options returned from onError handler to retry with modified params/headers.
|
|
230
|
+
* Following the Electric client pattern.
|
|
231
|
+
*/
|
|
232
|
+
type RetryOpts = {
|
|
233
|
+
params?: ParamsRecord;
|
|
234
|
+
headers?: HeadersRecord;
|
|
235
|
+
};
|
|
236
|
+
/**
|
|
237
|
+
* Error handler callback type.
|
|
238
|
+
*
|
|
239
|
+
* Called when a recoverable error occurs during streaming.
|
|
240
|
+
*
|
|
241
|
+
* **Return value behavior** (following Electric client pattern):
|
|
242
|
+
* - Return `{}` to retry with the same params/headers
|
|
243
|
+
* - Return `{ params }` to retry with merged params (existing params are preserved)
|
|
244
|
+
* - Return `{ headers }` to retry with merged headers (existing headers are preserved)
|
|
245
|
+
* - Return `void`/`undefined` to stop the stream and propagate the error
|
|
246
|
+
*
|
|
247
|
+
* Note: Automatic retries with exponential backoff are already applied
|
|
248
|
+
* for 5xx server errors, network errors, and 429 rate limits before
|
|
249
|
+
* this handler is called.
|
|
250
|
+
*
|
|
251
|
+
* @example
|
|
252
|
+
* ```typescript
|
|
253
|
+
* // Retry on any error
|
|
254
|
+
* onError: (error) => ({})
|
|
255
|
+
*
|
|
256
|
+
* // Refresh auth token on 401
|
|
257
|
+
* onError: async (error) => {
|
|
258
|
+
* if (error instanceof FetchError && error.status === 401) {
|
|
259
|
+
* const newToken = await refreshAuthToken()
|
|
260
|
+
* return { headers: { Authorization: `Bearer ${newToken}` } }
|
|
261
|
+
* }
|
|
262
|
+
* // Don't retry other errors
|
|
263
|
+
* }
|
|
264
|
+
* ```
|
|
265
|
+
*/
|
|
266
|
+
type StreamErrorHandler = (error: Error) => void | RetryOpts | Promise<void | RetryOpts>;
|
|
267
|
+
|
|
268
|
+
/**
|
|
269
|
+
* Fetch utilities with retry and backoff support.
|
|
270
|
+
* Based on @electric-sql/client patterns.
|
|
271
|
+
*/
|
|
272
|
+
/**
|
|
273
|
+
* Options for configuring exponential backoff retry behavior.
|
|
274
|
+
*/
|
|
275
|
+
interface BackoffOptions {
|
|
276
|
+
/**
|
|
277
|
+
* Initial delay before retrying in milliseconds.
|
|
278
|
+
*/
|
|
279
|
+
initialDelay: number;
|
|
280
|
+
/**
|
|
281
|
+
* Maximum retry delay in milliseconds.
|
|
282
|
+
* After reaching this, delay stays constant.
|
|
283
|
+
*/
|
|
284
|
+
maxDelay: number;
|
|
285
|
+
/**
|
|
286
|
+
* Multiplier for exponential backoff.
|
|
287
|
+
*/
|
|
288
|
+
multiplier: number;
|
|
289
|
+
/**
|
|
290
|
+
* Callback invoked on each failed attempt.
|
|
291
|
+
*/
|
|
292
|
+
onFailedAttempt?: () => void;
|
|
293
|
+
/**
|
|
294
|
+
* Enable debug logging.
|
|
295
|
+
*/
|
|
296
|
+
debug?: boolean;
|
|
297
|
+
/**
|
|
298
|
+
* Maximum number of retry attempts before giving up.
|
|
299
|
+
* Set to Infinity for indefinite retries (useful for offline scenarios).
|
|
300
|
+
*/
|
|
301
|
+
maxRetries?: number;
|
|
302
|
+
}
|
|
303
|
+
/**
|
|
304
|
+
* Default backoff options.
|
|
305
|
+
*/
|
|
306
|
+
declare const BackoffDefaults: BackoffOptions;
|
|
307
|
+
/**
|
|
308
|
+
* Creates a fetch client that retries failed requests with exponential backoff.
|
|
309
|
+
*
|
|
310
|
+
* @param fetchClient - The base fetch client to wrap
|
|
311
|
+
* @param backoffOptions - Options for retry behavior
|
|
312
|
+
* @returns A fetch function with automatic retry
|
|
313
|
+
*/
|
|
314
|
+
declare function createFetchWithBackoff(fetchClient: typeof fetch, backoffOptions?: BackoffOptions): typeof fetch;
|
|
315
|
+
/**
|
|
316
|
+
* Creates a fetch client that ensures the response body is fully consumed.
|
|
317
|
+
* This prevents issues with connection pooling when bodies aren't read.
|
|
318
|
+
*
|
|
319
|
+
* Uses arrayBuffer() instead of text() to preserve binary data integrity.
|
|
320
|
+
*
|
|
321
|
+
* @param fetchClient - The base fetch client to wrap
|
|
322
|
+
* @returns A fetch function that consumes response bodies
|
|
323
|
+
*/
|
|
324
|
+
declare function createFetchWithConsumedBody(fetchClient: typeof fetch): typeof fetch;
|
|
325
|
+
|
|
326
|
+
/**
|
|
327
|
+
* DurableStream - A handle to a remote durable stream.
|
|
328
|
+
*
|
|
329
|
+
* Following the Electric Durable Stream Protocol specification.
|
|
330
|
+
*/
|
|
331
|
+
|
|
332
|
+
/**
|
|
333
|
+
* Options for DurableStream constructor.
|
|
334
|
+
*/
|
|
335
|
+
interface DurableStreamOptions extends StreamOptions {
|
|
336
|
+
/**
|
|
337
|
+
* Backoff options for retry behavior.
|
|
338
|
+
*/
|
|
339
|
+
backoffOptions?: BackoffOptions;
|
|
340
|
+
/**
|
|
341
|
+
* Error handler for recoverable errors.
|
|
342
|
+
*
|
|
343
|
+
* **Automatic retries**: The client automatically retries 5xx server errors, network
|
|
344
|
+
* errors, and 429 rate limits with exponential backoff. The `onError` callback is
|
|
345
|
+
* only invoked after these automatic retries are exhausted, or for non-retryable errors.
|
|
346
|
+
*
|
|
347
|
+
* **Return value behavior** (following Electric client pattern):
|
|
348
|
+
* - Return `{}` to retry with the same params/headers
|
|
349
|
+
* - Return `{ params }` to retry with merged params
|
|
350
|
+
* - Return `{ headers }` to retry with merged headers
|
|
351
|
+
* - Return `void`/`undefined` to stop the stream and propagate the error
|
|
352
|
+
*
|
|
353
|
+
* @example
|
|
354
|
+
* ```typescript
|
|
355
|
+
* // Refresh auth token on 401
|
|
356
|
+
* onError: async (error) => {
|
|
357
|
+
* if (error instanceof FetchError && error.status === 401) {
|
|
358
|
+
* const newToken = await refreshAuthToken()
|
|
359
|
+
* return { headers: { Authorization: `Bearer ${newToken}` } }
|
|
360
|
+
* }
|
|
361
|
+
* }
|
|
362
|
+
* ```
|
|
363
|
+
*/
|
|
364
|
+
onError?: StreamErrorHandler;
|
|
365
|
+
}
|
|
366
|
+
/**
|
|
367
|
+
* A handle to a remote durable stream.
|
|
368
|
+
*
|
|
369
|
+
* This is a lightweight, reusable handle - not a persistent connection.
|
|
370
|
+
* It does not automatically start reading or listening.
|
|
371
|
+
* Create sessions as needed via read(), follow(), or toReadableStream().
|
|
372
|
+
*
|
|
373
|
+
* @example
|
|
374
|
+
* ```typescript
|
|
375
|
+
* // Create a handle without any network IO
|
|
376
|
+
* const stream = new DurableStream({
|
|
377
|
+
* url: "https://streams.example.com/my-stream",
|
|
378
|
+
* auth: { token: "my-token" }
|
|
379
|
+
* });
|
|
380
|
+
*
|
|
381
|
+
* // One-shot read
|
|
382
|
+
* const result = await stream.read({ offset: savedOffset });
|
|
383
|
+
*
|
|
384
|
+
* // Follow for live updates
|
|
385
|
+
* for await (const chunk of stream.follow()) {
|
|
386
|
+
* console.log(new TextDecoder().decode(chunk.data));
|
|
387
|
+
* }
|
|
388
|
+
* ```
|
|
389
|
+
*/
|
|
390
|
+
declare class DurableStream {
|
|
391
|
+
#private;
|
|
392
|
+
/**
|
|
393
|
+
* The URL of the durable stream.
|
|
394
|
+
*/
|
|
395
|
+
readonly url: string;
|
|
396
|
+
/**
|
|
397
|
+
* The content type of the stream (populated after connect/head/read).
|
|
398
|
+
*/
|
|
399
|
+
contentType?: string;
|
|
400
|
+
/**
|
|
401
|
+
* Create a cold handle to a stream.
|
|
402
|
+
* No network IO is performed by the constructor.
|
|
403
|
+
*/
|
|
404
|
+
constructor(opts: DurableStreamOptions);
|
|
405
|
+
/**
|
|
406
|
+
* Create a new stream (create-only PUT) and return a handle.
|
|
407
|
+
* Fails with DurableStreamError(code="CONFLICT_EXISTS") if it already exists.
|
|
408
|
+
*/
|
|
409
|
+
static create(opts: CreateOptions): Promise<DurableStream>;
|
|
410
|
+
/**
|
|
411
|
+
* Validate that a stream exists and fetch metadata via HEAD.
|
|
412
|
+
* Returns a handle with contentType populated (if sent by server).
|
|
413
|
+
*/
|
|
414
|
+
static connect(opts: StreamOptions): Promise<DurableStream>;
|
|
415
|
+
/**
|
|
416
|
+
* HEAD metadata for a stream without creating a handle.
|
|
417
|
+
*/
|
|
418
|
+
static head(opts: StreamOptions): Promise<HeadResult>;
|
|
419
|
+
/**
|
|
420
|
+
* Delete a stream without creating a handle.
|
|
421
|
+
*/
|
|
422
|
+
static delete(opts: StreamOptions): Promise<void>;
|
|
423
|
+
/**
|
|
424
|
+
* HEAD metadata for this stream.
|
|
425
|
+
*/
|
|
426
|
+
head(opts?: {
|
|
427
|
+
signal?: AbortSignal;
|
|
428
|
+
}): Promise<HeadResult>;
|
|
429
|
+
/**
|
|
430
|
+
* Create this stream (create-only PUT) using the URL/auth from the handle.
|
|
431
|
+
*/
|
|
432
|
+
create(opts?: Omit<CreateOptions, keyof StreamOptions>): Promise<this>;
|
|
433
|
+
/**
|
|
434
|
+
* Delete this stream.
|
|
435
|
+
*/
|
|
436
|
+
delete(opts?: {
|
|
437
|
+
signal?: AbortSignal;
|
|
438
|
+
}): Promise<void>;
|
|
439
|
+
/**
|
|
440
|
+
* Append a single payload to the stream.
|
|
441
|
+
*
|
|
442
|
+
* - `body` may be Uint8Array, string, or any Fetch BodyInit.
|
|
443
|
+
* - Strings are encoded as UTF-8.
|
|
444
|
+
* - `seq` (if provided) is sent as stream-seq (writer coordination).
|
|
445
|
+
*/
|
|
446
|
+
append(body: BodyInit | Uint8Array | string, opts?: AppendOptions): Promise<void>;
|
|
447
|
+
/**
|
|
448
|
+
* Append a streaming body to the stream.
|
|
449
|
+
*
|
|
450
|
+
* - `source` yields Uint8Array or string chunks.
|
|
451
|
+
* - Strings are encoded as UTF-8; no delimiters are added.
|
|
452
|
+
* - Internally uses chunked transfer or HTTP/2 streaming.
|
|
453
|
+
*/
|
|
454
|
+
appendStream(source: ReadableStream<Uint8Array | string> | AsyncIterable<Uint8Array | string>, opts?: AppendOptions): Promise<void>;
|
|
455
|
+
/**
|
|
456
|
+
* One-shot read.
|
|
457
|
+
*
|
|
458
|
+
* Performs a single GET from the specified offset/mode and returns a chunk.
|
|
459
|
+
* Caller is responsible for persisting the returned offset if they want to resume.
|
|
460
|
+
*/
|
|
461
|
+
read(opts?: ReadOptions): Promise<ReadResult>;
|
|
462
|
+
/**
|
|
463
|
+
* Follow the stream as an AsyncIterable of chunks.
|
|
464
|
+
*
|
|
465
|
+
* Default behaviour:
|
|
466
|
+
* - From `offset` (or start if omitted), repeatedly perform catch-up reads
|
|
467
|
+
* until a chunk with upToDate=true.
|
|
468
|
+
* - Then switch to live mode:
|
|
469
|
+
* - SSE if content-type is text/* or application/json;
|
|
470
|
+
* - otherwise long-poll.
|
|
471
|
+
*
|
|
472
|
+
* Explicit live override:
|
|
473
|
+
* - live="catchup": only catch-up, stop at upToDate.
|
|
474
|
+
* - live="long-poll": start long-polling immediately from offset.
|
|
475
|
+
* - live="sse": start SSE immediately (throws if SSE not supported).
|
|
476
|
+
*/
|
|
477
|
+
follow(opts?: ReadOptions): AsyncIterable<StreamChunk>;
|
|
478
|
+
/**
|
|
479
|
+
* Wrap follow() in a Web ReadableStream for piping.
|
|
480
|
+
*
|
|
481
|
+
* Backpressure:
|
|
482
|
+
* - One chunk is pulled from follow() per pull() call, so standard
|
|
483
|
+
* Web Streams backpressure semantics apply.
|
|
484
|
+
*
|
|
485
|
+
* Cancellation:
|
|
486
|
+
* - rs.cancel() will stop follow() and abort any in-flight request.
|
|
487
|
+
*/
|
|
488
|
+
toReadableStream(opts?: ReadOptions & {
|
|
489
|
+
signal?: AbortSignal;
|
|
490
|
+
}): ReadableStream<StreamChunk>;
|
|
491
|
+
/**
|
|
492
|
+
* Wrap follow() in a Web ReadableStream<Uint8Array> for piping raw bytes.
|
|
493
|
+
*
|
|
494
|
+
* This is the native format for many web stream APIs.
|
|
495
|
+
*/
|
|
496
|
+
toByteStream(opts?: ReadOptions & {
|
|
497
|
+
signal?: AbortSignal;
|
|
498
|
+
}): ReadableStream<Uint8Array>;
|
|
499
|
+
/**
|
|
500
|
+
* Convenience: interpret data as JSON messages.
|
|
501
|
+
* Parses each chunk's data as JSON and yields the parsed values.
|
|
502
|
+
*/
|
|
503
|
+
json<T = unknown>(opts?: ReadOptions): AsyncIterable<T>;
|
|
504
|
+
/**
|
|
505
|
+
* Convenience: interpret data as text (UTF-8).
|
|
506
|
+
*/
|
|
507
|
+
text(opts?: ReadOptions & {
|
|
508
|
+
decoder?: TextDecoder;
|
|
509
|
+
}): AsyncIterable<string>;
|
|
510
|
+
}
|
|
511
|
+
|
|
512
|
+
/**
|
|
513
|
+
* Error thrown for transport/network errors.
|
|
514
|
+
* Following the @electric-sql/client FetchError pattern.
|
|
515
|
+
*/
|
|
516
|
+
declare class FetchError extends Error {
|
|
517
|
+
url: string;
|
|
518
|
+
status: number;
|
|
519
|
+
text?: string;
|
|
520
|
+
json?: object;
|
|
521
|
+
headers: Record<string, string>;
|
|
522
|
+
constructor(status: number, text: string | undefined, json: object | undefined, headers: Record<string, string>, url: string, message?: string);
|
|
523
|
+
static fromResponse(response: Response, url: string): Promise<FetchError>;
|
|
524
|
+
}
|
|
525
|
+
/**
|
|
526
|
+
* Error thrown when a fetch operation is aborted during backoff.
|
|
527
|
+
*/
|
|
528
|
+
declare class FetchBackoffAbortError extends Error {
|
|
529
|
+
constructor();
|
|
530
|
+
}
|
|
531
|
+
/**
|
|
532
|
+
* Protocol-level error for Durable Streams operations.
|
|
533
|
+
* Provides structured error handling with error codes.
|
|
534
|
+
*/
|
|
535
|
+
declare class DurableStreamError extends Error {
|
|
536
|
+
/**
|
|
537
|
+
* HTTP status code, if applicable.
|
|
538
|
+
*/
|
|
539
|
+
status?: number;
|
|
540
|
+
/**
|
|
541
|
+
* Structured error code for programmatic handling.
|
|
542
|
+
*/
|
|
543
|
+
code: DurableStreamErrorCode;
|
|
544
|
+
/**
|
|
545
|
+
* Additional error details (e.g., raw response body).
|
|
546
|
+
*/
|
|
547
|
+
details?: unknown;
|
|
548
|
+
constructor(message: string, code: DurableStreamErrorCode, status?: number, details?: unknown);
|
|
549
|
+
/**
|
|
550
|
+
* Create a DurableStreamError from an HTTP response.
|
|
551
|
+
*/
|
|
552
|
+
static fromResponse(response: Response, url: string): Promise<DurableStreamError>;
|
|
553
|
+
/**
|
|
554
|
+
* Create a DurableStreamError from a FetchError.
|
|
555
|
+
*/
|
|
556
|
+
static fromFetchError(error: FetchError): DurableStreamError;
|
|
557
|
+
}
|
|
558
|
+
/**
|
|
559
|
+
* Error thrown when stream URL is missing.
|
|
560
|
+
*/
|
|
561
|
+
declare class MissingStreamUrlError extends Error {
|
|
562
|
+
constructor();
|
|
563
|
+
}
|
|
564
|
+
/**
|
|
565
|
+
* Error thrown when signal option is invalid.
|
|
566
|
+
*/
|
|
567
|
+
declare class InvalidSignalError extends Error {
|
|
568
|
+
constructor();
|
|
569
|
+
}
|
|
570
|
+
|
|
571
|
+
/**
|
|
572
|
+
* Durable Streams Protocol Constants
|
|
573
|
+
*
|
|
574
|
+
* Header and query parameter names following the Electric Durable Stream Protocol.
|
|
575
|
+
*/
|
|
576
|
+
/**
|
|
577
|
+
* Response header containing the next offset to read from.
|
|
578
|
+
* Format: "<read-seq>_<byte-offset>"
|
|
579
|
+
*/
|
|
580
|
+
declare const STREAM_OFFSET_HEADER = "stream-offset";
|
|
581
|
+
/**
|
|
582
|
+
* Response header for cursor (used for CDN collapsing).
|
|
583
|
+
* Echo this value in subsequent long-poll requests.
|
|
584
|
+
*/
|
|
585
|
+
declare const STREAM_CURSOR_HEADER = "stream-cursor";
|
|
586
|
+
/**
|
|
587
|
+
* Presence header indicating response ends at current end of stream.
|
|
588
|
+
* When present (any value), indicates up-to-date.
|
|
589
|
+
*/
|
|
590
|
+
declare const STREAM_UP_TO_DATE_HEADER = "stream-up-to-date";
|
|
591
|
+
/**
|
|
592
|
+
* Request header for writer coordination sequence.
|
|
593
|
+
* Monotonic, lexicographic. If lower than last appended seq -> 409 Conflict.
|
|
594
|
+
*/
|
|
595
|
+
declare const STREAM_SEQ_HEADER = "stream-seq";
|
|
596
|
+
/**
|
|
597
|
+
* Request header for stream TTL in seconds (on create).
|
|
598
|
+
*/
|
|
599
|
+
declare const STREAM_TTL_HEADER = "stream-ttl";
|
|
600
|
+
/**
|
|
601
|
+
* Request header for absolute stream expiry time (RFC3339, on create).
|
|
602
|
+
*/
|
|
603
|
+
declare const STREAM_EXPIRES_AT_HEADER = "stream-expires-at";
|
|
604
|
+
/**
|
|
605
|
+
* Query parameter for starting offset.
|
|
606
|
+
*/
|
|
607
|
+
declare const OFFSET_QUERY_PARAM = "offset";
|
|
608
|
+
/**
|
|
609
|
+
* Query parameter for live mode.
|
|
610
|
+
* Values: "long-poll", "sse"
|
|
611
|
+
*/
|
|
612
|
+
declare const LIVE_QUERY_PARAM = "live";
|
|
613
|
+
/**
|
|
614
|
+
* Query parameter for echoing cursor (CDN collapsing).
|
|
615
|
+
*/
|
|
616
|
+
declare const CURSOR_QUERY_PARAM = "cursor";
|
|
617
|
+
/**
|
|
618
|
+
* Content types that support SSE mode.
|
|
619
|
+
* SSE is only valid for text/* or application/json streams.
|
|
620
|
+
*/
|
|
621
|
+
declare const SSE_COMPATIBLE_CONTENT_TYPES: string[];
|
|
622
|
+
/**
|
|
623
|
+
* Protocol query parameters that should not be set by users.
|
|
624
|
+
*/
|
|
625
|
+
declare const DURABLE_STREAM_PROTOCOL_QUERY_PARAMS: Array<string>;
|
|
626
|
+
|
|
627
|
+
export { type AppendOptions, type Auth, BackoffDefaults, type BackoffOptions, CURSOR_QUERY_PARAM, type CreateOptions, DURABLE_STREAM_PROTOCOL_QUERY_PARAMS, DurableStream, DurableStreamError, type DurableStreamErrorCode, type DurableStreamOptions, FetchBackoffAbortError, FetchError, type HeadResult, type HeadersRecord, InvalidSignalError, LIVE_QUERY_PARAM, type LiveMode, type MaybePromise, MissingStreamUrlError, OFFSET_QUERY_PARAM, type Offset, type ParamsRecord, type ReadOptions, type ReadResult, type RetryOpts, SSE_COMPATIBLE_CONTENT_TYPES, STREAM_CURSOR_HEADER, STREAM_EXPIRES_AT_HEADER, STREAM_OFFSET_HEADER, STREAM_SEQ_HEADER, STREAM_TTL_HEADER, STREAM_UP_TO_DATE_HEADER, type StreamChunk, type StreamErrorHandler, type StreamOptions, createFetchWithBackoff, createFetchWithConsumedBody };
|