@algolia/client-common 5.52.1 → 5.54.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/dist/common.cjs +260 -27
- package/dist/common.cjs.map +1 -1
- package/dist/common.d.cts +69 -1
- package/dist/common.d.ts +69 -1
- package/dist/common.js +255 -26
- package/dist/common.js.map +1 -1
- package/package.json +6 -6
package/dist/common.d.cts
CHANGED
|
@@ -59,6 +59,67 @@ type FallbackableCacheOptions = {
|
|
|
59
59
|
caches: Cache[];
|
|
60
60
|
};
|
|
61
61
|
|
|
62
|
+
/**
|
|
63
|
+
* Shared configuration for chunked helpers that poll for task completion.
|
|
64
|
+
*/
|
|
65
|
+
type ChunkedHelperOptions = {
|
|
66
|
+
/**
|
|
67
|
+
* The maximum number of retries when polling for task completion. 100 by default.
|
|
68
|
+
*/
|
|
69
|
+
maxRetries?: number | undefined;
|
|
70
|
+
};
|
|
71
|
+
|
|
72
|
+
/**
|
|
73
|
+
* WHATWG-compliant Server-Sent Events parser.
|
|
74
|
+
*
|
|
75
|
+
* Three-layer architecture:
|
|
76
|
+
* 1. iterLines() — byte chunking → line decoding
|
|
77
|
+
* 2. SSEDecoder — line → SSE event decoding
|
|
78
|
+
* 3. iterSSEEvents — top-level composer (exported)
|
|
79
|
+
*
|
|
80
|
+
* @see https://html.spec.whatwg.org/multipage/server-sent-events.html#event-stream-interpretation
|
|
81
|
+
*/
|
|
82
|
+
type ServerSentEvent = {
|
|
83
|
+
/** Concatenated data: field values, joined by '\n'. */
|
|
84
|
+
data: string;
|
|
85
|
+
/** Event type from the event: field. Defaults to "" (empty string). */
|
|
86
|
+
event: string;
|
|
87
|
+
/** Last event ID. Persists across dispatches until changed. */
|
|
88
|
+
id: string | null;
|
|
89
|
+
/** Reconnection time in ms. Persists across dispatches until changed. */
|
|
90
|
+
retry: number | null;
|
|
91
|
+
};
|
|
92
|
+
/**
|
|
93
|
+
* Wrapper for a parsed SSE event, yielded by the typed `*Stream` methods.
|
|
94
|
+
*
|
|
95
|
+
* - `data` is the JSON-parsed payload when parsing succeeds, `null` otherwise.
|
|
96
|
+
* - `raw` is the original {@link ServerSentEvent} (always present).
|
|
97
|
+
* - `error` is set when JSON parsing of `event.data` failed.
|
|
98
|
+
*/
|
|
99
|
+
type StreamEvent<T = Record<string, unknown>> = {
|
|
100
|
+
/** Parsed data from the event, or `null` if parsing failed. */
|
|
101
|
+
data: T | null;
|
|
102
|
+
/** The original, unparsed SSE event. */
|
|
103
|
+
raw: ServerSentEvent;
|
|
104
|
+
/** The error that occurred while parsing `event.data`, if any. */
|
|
105
|
+
error?: Error;
|
|
106
|
+
};
|
|
107
|
+
/**
|
|
108
|
+
* Parses a byte stream as WHATWG Server-Sent Events.
|
|
109
|
+
*
|
|
110
|
+
* Accepts both ReadableStream<Uint8Array> (browser fetch) and
|
|
111
|
+
* AsyncIterable<Uint8Array> (Node.js streams / Buffer chunks).
|
|
112
|
+
*
|
|
113
|
+
* @example
|
|
114
|
+
* ```ts
|
|
115
|
+
* const response = await fetch(url);
|
|
116
|
+
* for await (const event of iterSSEEvents(response.body!)) {
|
|
117
|
+
* console.log(event.event, event.data);
|
|
118
|
+
* }
|
|
119
|
+
* ```
|
|
120
|
+
*/
|
|
121
|
+
declare function iterSSEEvents(stream: ReadableStream<Uint8Array> | AsyncIterable<Uint8Array>): AsyncGenerator<ServerSentEvent>;
|
|
122
|
+
|
|
62
123
|
type Host = {
|
|
63
124
|
/**
|
|
64
125
|
* The host URL.
|
|
@@ -173,6 +234,10 @@ type Requester = {
|
|
|
173
234
|
* Sends the given `request` to the server.
|
|
174
235
|
*/
|
|
175
236
|
send: (request: EndRequest) => Promise<Response>;
|
|
237
|
+
/**
|
|
238
|
+
* Sends the given `request` and returns a raw byte stream for streaming responses (e.g. SSE).
|
|
239
|
+
*/
|
|
240
|
+
sendStream?: (request: EndRequest) => Promise<ReadableStream<Uint8Array>>;
|
|
176
241
|
};
|
|
177
242
|
|
|
178
243
|
type RequestOptions = Pick<Request, 'cacheable'> & {
|
|
@@ -316,6 +381,7 @@ type Transporter = TransporterOptions & {
|
|
|
316
381
|
* The `baseRequest` and `baseRequestOptions` will be merged accordingly.
|
|
317
382
|
*/
|
|
318
383
|
request: <TResponse>(baseRequest: Request, baseRequestOptions?: RequestOptions) => Promise<TResponse>;
|
|
384
|
+
requestStream: (baseRequest: Request, baseRequestOptions?: RequestOptions) => AsyncGenerator<ServerSentEvent>;
|
|
319
385
|
};
|
|
320
386
|
|
|
321
387
|
type AuthMode = 'WithinHeaders' | 'WithinQueryParameters';
|
|
@@ -474,4 +540,6 @@ declare function isSuccess({ status }: Pick<Response, 'status'>): boolean;
|
|
|
474
540
|
declare function stackTraceWithoutCredentials(stackTrace: StackFrame[]): StackFrame[];
|
|
475
541
|
declare function stackFrameWithoutCredentials(stackFrame: StackFrame): StackFrame;
|
|
476
542
|
|
|
477
|
-
|
|
543
|
+
declare function validateRequired(field: string, method: string, value: unknown): void;
|
|
544
|
+
|
|
545
|
+
export { type AlgoliaAgent, type AlgoliaAgentOptions, AlgoliaError, ApiError, type AuthMode, type BrowserLocalStorageCacheItem, type BrowserLocalStorageOptions, COMPRESSION_THRESHOLD, type Cache, type CacheEvents, type ChunkedHelperOptions, type ClientOptions, type CreateClientOptions, type CreateIterablePromise, DEFAULT_CONNECT_TIMEOUT_BROWSER, DEFAULT_CONNECT_TIMEOUT_NODE, DEFAULT_READ_TIMEOUT_BROWSER, DEFAULT_READ_TIMEOUT_NODE, DEFAULT_WRITE_TIMEOUT_BROWSER, DEFAULT_WRITE_TIMEOUT_NODE, DeserializationError, DetailedApiError, type DetailedError, type DetailedErrorWithMessage, type DetailedErrorWithTypeID, type EndRequest, ErrorWithStackTrace, type FallbackableCacheOptions, type GetAlgoliaAgent, type Headers, type Host, IndexAlreadyExistsError, IndexNotFoundError, IndicesInSameAppError, type IterableOptions, LogLevelEnum, type LogLevelType, type Logger, type MemoryCacheOptions, type Method, type QueryParameters, type Request, type RequestOptions, type Requester, type Response, RetryError, type ServerSentEvent, type StackFrame, type StatefulHost, type StreamEvent, type Timeouts, type Transporter, type TransporterOptions, createAlgoliaAgent, createAuth, createBrowserLocalStorageCache, createFallbackableCache, createIterablePromise, createMemoryCache, createNullCache, createNullLogger, createStatefulHost, createTransporter, deserializeFailure, deserializeSuccess, getAlgoliaAgent, isNetworkError, isRetryable, isSuccess, iterSSEEvents, serializeData, serializeHeaders, serializeQueryParameters, serializeUrl, shuffle, stackFrameWithoutCredentials, stackTraceWithoutCredentials, validateRequired };
|
package/dist/common.d.ts
CHANGED
|
@@ -59,6 +59,67 @@ type FallbackableCacheOptions = {
|
|
|
59
59
|
caches: Cache[];
|
|
60
60
|
};
|
|
61
61
|
|
|
62
|
+
/**
|
|
63
|
+
* Shared configuration for chunked helpers that poll for task completion.
|
|
64
|
+
*/
|
|
65
|
+
type ChunkedHelperOptions = {
|
|
66
|
+
/**
|
|
67
|
+
* The maximum number of retries when polling for task completion. 100 by default.
|
|
68
|
+
*/
|
|
69
|
+
maxRetries?: number | undefined;
|
|
70
|
+
};
|
|
71
|
+
|
|
72
|
+
/**
|
|
73
|
+
* WHATWG-compliant Server-Sent Events parser.
|
|
74
|
+
*
|
|
75
|
+
* Three-layer architecture:
|
|
76
|
+
* 1. iterLines() — byte chunking → line decoding
|
|
77
|
+
* 2. SSEDecoder — line → SSE event decoding
|
|
78
|
+
* 3. iterSSEEvents — top-level composer (exported)
|
|
79
|
+
*
|
|
80
|
+
* @see https://html.spec.whatwg.org/multipage/server-sent-events.html#event-stream-interpretation
|
|
81
|
+
*/
|
|
82
|
+
type ServerSentEvent = {
|
|
83
|
+
/** Concatenated data: field values, joined by '\n'. */
|
|
84
|
+
data: string;
|
|
85
|
+
/** Event type from the event: field. Defaults to "" (empty string). */
|
|
86
|
+
event: string;
|
|
87
|
+
/** Last event ID. Persists across dispatches until changed. */
|
|
88
|
+
id: string | null;
|
|
89
|
+
/** Reconnection time in ms. Persists across dispatches until changed. */
|
|
90
|
+
retry: number | null;
|
|
91
|
+
};
|
|
92
|
+
/**
|
|
93
|
+
* Wrapper for a parsed SSE event, yielded by the typed `*Stream` methods.
|
|
94
|
+
*
|
|
95
|
+
* - `data` is the JSON-parsed payload when parsing succeeds, `null` otherwise.
|
|
96
|
+
* - `raw` is the original {@link ServerSentEvent} (always present).
|
|
97
|
+
* - `error` is set when JSON parsing of `event.data` failed.
|
|
98
|
+
*/
|
|
99
|
+
type StreamEvent<T = Record<string, unknown>> = {
|
|
100
|
+
/** Parsed data from the event, or `null` if parsing failed. */
|
|
101
|
+
data: T | null;
|
|
102
|
+
/** The original, unparsed SSE event. */
|
|
103
|
+
raw: ServerSentEvent;
|
|
104
|
+
/** The error that occurred while parsing `event.data`, if any. */
|
|
105
|
+
error?: Error;
|
|
106
|
+
};
|
|
107
|
+
/**
|
|
108
|
+
* Parses a byte stream as WHATWG Server-Sent Events.
|
|
109
|
+
*
|
|
110
|
+
* Accepts both ReadableStream<Uint8Array> (browser fetch) and
|
|
111
|
+
* AsyncIterable<Uint8Array> (Node.js streams / Buffer chunks).
|
|
112
|
+
*
|
|
113
|
+
* @example
|
|
114
|
+
* ```ts
|
|
115
|
+
* const response = await fetch(url);
|
|
116
|
+
* for await (const event of iterSSEEvents(response.body!)) {
|
|
117
|
+
* console.log(event.event, event.data);
|
|
118
|
+
* }
|
|
119
|
+
* ```
|
|
120
|
+
*/
|
|
121
|
+
declare function iterSSEEvents(stream: ReadableStream<Uint8Array> | AsyncIterable<Uint8Array>): AsyncGenerator<ServerSentEvent>;
|
|
122
|
+
|
|
62
123
|
type Host = {
|
|
63
124
|
/**
|
|
64
125
|
* The host URL.
|
|
@@ -173,6 +234,10 @@ type Requester = {
|
|
|
173
234
|
* Sends the given `request` to the server.
|
|
174
235
|
*/
|
|
175
236
|
send: (request: EndRequest) => Promise<Response>;
|
|
237
|
+
/**
|
|
238
|
+
* Sends the given `request` and returns a raw byte stream for streaming responses (e.g. SSE).
|
|
239
|
+
*/
|
|
240
|
+
sendStream?: (request: EndRequest) => Promise<ReadableStream<Uint8Array>>;
|
|
176
241
|
};
|
|
177
242
|
|
|
178
243
|
type RequestOptions = Pick<Request, 'cacheable'> & {
|
|
@@ -316,6 +381,7 @@ type Transporter = TransporterOptions & {
|
|
|
316
381
|
* The `baseRequest` and `baseRequestOptions` will be merged accordingly.
|
|
317
382
|
*/
|
|
318
383
|
request: <TResponse>(baseRequest: Request, baseRequestOptions?: RequestOptions) => Promise<TResponse>;
|
|
384
|
+
requestStream: (baseRequest: Request, baseRequestOptions?: RequestOptions) => AsyncGenerator<ServerSentEvent>;
|
|
319
385
|
};
|
|
320
386
|
|
|
321
387
|
type AuthMode = 'WithinHeaders' | 'WithinQueryParameters';
|
|
@@ -474,4 +540,6 @@ declare function isSuccess({ status }: Pick<Response, 'status'>): boolean;
|
|
|
474
540
|
declare function stackTraceWithoutCredentials(stackTrace: StackFrame[]): StackFrame[];
|
|
475
541
|
declare function stackFrameWithoutCredentials(stackFrame: StackFrame): StackFrame;
|
|
476
542
|
|
|
477
|
-
|
|
543
|
+
declare function validateRequired(field: string, method: string, value: unknown): void;
|
|
544
|
+
|
|
545
|
+
export { type AlgoliaAgent, type AlgoliaAgentOptions, AlgoliaError, ApiError, type AuthMode, type BrowserLocalStorageCacheItem, type BrowserLocalStorageOptions, COMPRESSION_THRESHOLD, type Cache, type CacheEvents, type ChunkedHelperOptions, type ClientOptions, type CreateClientOptions, type CreateIterablePromise, DEFAULT_CONNECT_TIMEOUT_BROWSER, DEFAULT_CONNECT_TIMEOUT_NODE, DEFAULT_READ_TIMEOUT_BROWSER, DEFAULT_READ_TIMEOUT_NODE, DEFAULT_WRITE_TIMEOUT_BROWSER, DEFAULT_WRITE_TIMEOUT_NODE, DeserializationError, DetailedApiError, type DetailedError, type DetailedErrorWithMessage, type DetailedErrorWithTypeID, type EndRequest, ErrorWithStackTrace, type FallbackableCacheOptions, type GetAlgoliaAgent, type Headers, type Host, IndexAlreadyExistsError, IndexNotFoundError, IndicesInSameAppError, type IterableOptions, LogLevelEnum, type LogLevelType, type Logger, type MemoryCacheOptions, type Method, type QueryParameters, type Request, type RequestOptions, type Requester, type Response, RetryError, type ServerSentEvent, type StackFrame, type StatefulHost, type StreamEvent, type Timeouts, type Transporter, type TransporterOptions, createAlgoliaAgent, createAuth, createBrowserLocalStorageCache, createFallbackableCache, createIterablePromise, createMemoryCache, createNullCache, createNullLogger, createStatefulHost, createTransporter, deserializeFailure, deserializeSuccess, getAlgoliaAgent, isNetworkError, isRetryable, isSuccess, iterSSEEvents, serializeData, serializeHeaders, serializeQueryParameters, serializeUrl, shuffle, stackFrameWithoutCredentials, stackTraceWithoutCredentials, validateRequired };
|
package/dist/common.js
CHANGED
|
@@ -14,42 +14,50 @@ function createBrowserLocalStorageCache(options) {
|
|
|
14
14
|
function setNamespace(namespace) {
|
|
15
15
|
getStorage().setItem(namespaceKey, JSON.stringify(namespace));
|
|
16
16
|
}
|
|
17
|
-
function
|
|
17
|
+
function yieldToMain() {
|
|
18
|
+
return new Promise((resolve) => setTimeout(resolve, 0));
|
|
19
|
+
}
|
|
20
|
+
function getFilteredNamespace() {
|
|
18
21
|
const timeToLive = options.timeToLive ? options.timeToLive * 1e3 : null;
|
|
19
22
|
const namespace = getNamespace();
|
|
20
|
-
const
|
|
23
|
+
const currentTime = (/* @__PURE__ */ new Date()).getTime();
|
|
24
|
+
let changed = false;
|
|
25
|
+
const filtered = Object.fromEntries(
|
|
21
26
|
Object.entries(namespace).filter(([, cacheItem]) => {
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
return
|
|
27
|
+
if (!cacheItem || cacheItem.timestamp === void 0) {
|
|
28
|
+
changed = true;
|
|
29
|
+
return false;
|
|
30
|
+
}
|
|
31
|
+
if (!timeToLive) {
|
|
32
|
+
return true;
|
|
33
|
+
}
|
|
34
|
+
if (cacheItem.timestamp + timeToLive < currentTime) {
|
|
35
|
+
changed = true;
|
|
36
|
+
return false;
|
|
37
|
+
}
|
|
38
|
+
return true;
|
|
34
39
|
})
|
|
35
40
|
);
|
|
36
|
-
|
|
41
|
+
return { namespace: filtered, changed };
|
|
37
42
|
}
|
|
38
43
|
return {
|
|
39
44
|
get(key, defaultValue, events = {
|
|
40
45
|
miss: () => Promise.resolve()
|
|
41
46
|
}) {
|
|
42
|
-
return
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
47
|
+
return yieldToMain().then(() => {
|
|
48
|
+
const { namespace, changed } = getFilteredNamespace();
|
|
49
|
+
const cachedItem = namespace[JSON.stringify(key)];
|
|
50
|
+
if (changed) {
|
|
51
|
+
setNamespace(namespace);
|
|
52
|
+
}
|
|
53
|
+
if (cachedItem) {
|
|
54
|
+
return cachedItem.value;
|
|
55
|
+
}
|
|
56
|
+
return defaultValue().then((value) => events.miss(value).then(() => value));
|
|
57
|
+
});
|
|
50
58
|
},
|
|
51
59
|
set(key, value) {
|
|
52
|
-
return
|
|
60
|
+
return yieldToMain().then(() => {
|
|
53
61
|
const namespace = getNamespace();
|
|
54
62
|
namespace[JSON.stringify(key)] = {
|
|
55
63
|
timestamp: (/* @__PURE__ */ new Date()).getTime(),
|
|
@@ -60,7 +68,7 @@ function createBrowserLocalStorageCache(options) {
|
|
|
60
68
|
});
|
|
61
69
|
},
|
|
62
70
|
delete(key) {
|
|
63
|
-
return
|
|
71
|
+
return yieldToMain().then(() => {
|
|
64
72
|
const namespace = getNamespace();
|
|
65
73
|
delete namespace[JSON.stringify(key)];
|
|
66
74
|
getStorage().setItem(namespaceKey, JSON.stringify(namespace));
|
|
@@ -255,6 +263,165 @@ function createNullLogger() {
|
|
|
255
263
|
};
|
|
256
264
|
}
|
|
257
265
|
|
|
266
|
+
// src/sse.ts
|
|
267
|
+
var MAX_LINE_BUFFER_SIZE = 10 * 1024 * 1024;
|
|
268
|
+
async function* readableStreamToAsyncIterable(stream) {
|
|
269
|
+
const reader = stream.getReader();
|
|
270
|
+
try {
|
|
271
|
+
while (true) {
|
|
272
|
+
const { done, value } = await reader.read();
|
|
273
|
+
if (done) return;
|
|
274
|
+
yield value;
|
|
275
|
+
}
|
|
276
|
+
} finally {
|
|
277
|
+
reader.releaseLock();
|
|
278
|
+
}
|
|
279
|
+
}
|
|
280
|
+
function toAsyncIterable(stream) {
|
|
281
|
+
if (Symbol.asyncIterator in stream) {
|
|
282
|
+
return stream;
|
|
283
|
+
}
|
|
284
|
+
return readableStreamToAsyncIterable(stream);
|
|
285
|
+
}
|
|
286
|
+
async function* iterLines(stream) {
|
|
287
|
+
const decoder = new TextDecoder("utf-8");
|
|
288
|
+
const buffer = [];
|
|
289
|
+
let bufferSize = 0;
|
|
290
|
+
let trailingCR = false;
|
|
291
|
+
let isFirstLine = true;
|
|
292
|
+
for await (const chunk of toAsyncIterable(stream)) {
|
|
293
|
+
const text = decoder.decode(chunk, { stream: true });
|
|
294
|
+
let offset = 0;
|
|
295
|
+
if (trailingCR) {
|
|
296
|
+
trailingCR = false;
|
|
297
|
+
if (text.length > 0 && text[0] === "\n") {
|
|
298
|
+
offset = 1;
|
|
299
|
+
}
|
|
300
|
+
}
|
|
301
|
+
while (offset < text.length) {
|
|
302
|
+
const crIdx = text.indexOf("\r", offset);
|
|
303
|
+
const lfIdx = text.indexOf("\n", offset);
|
|
304
|
+
if (crIdx === -1 && lfIdx === -1) {
|
|
305
|
+
const remaining2 = text.slice(offset);
|
|
306
|
+
buffer.push(remaining2);
|
|
307
|
+
bufferSize += remaining2.length;
|
|
308
|
+
if (bufferSize > MAX_LINE_BUFFER_SIZE) {
|
|
309
|
+
throw new Error("SSE line buffer exceeded 10MB");
|
|
310
|
+
}
|
|
311
|
+
break;
|
|
312
|
+
}
|
|
313
|
+
let endIdx;
|
|
314
|
+
let skipLen;
|
|
315
|
+
if (crIdx !== -1 && (lfIdx === -1 || crIdx < lfIdx)) {
|
|
316
|
+
endIdx = crIdx;
|
|
317
|
+
if (crIdx + 1 < text.length) {
|
|
318
|
+
skipLen = text[crIdx + 1] === "\n" ? 2 : 1;
|
|
319
|
+
} else {
|
|
320
|
+
trailingCR = true;
|
|
321
|
+
skipLen = 1;
|
|
322
|
+
}
|
|
323
|
+
} else {
|
|
324
|
+
endIdx = lfIdx;
|
|
325
|
+
skipLen = 1;
|
|
326
|
+
}
|
|
327
|
+
const segment = text.slice(offset, endIdx);
|
|
328
|
+
buffer.push(segment);
|
|
329
|
+
let line = buffer.length === 1 ? buffer[0] : buffer.join("");
|
|
330
|
+
buffer.length = 0;
|
|
331
|
+
bufferSize = 0;
|
|
332
|
+
if (isFirstLine) {
|
|
333
|
+
if (line.startsWith("\uFEFF")) {
|
|
334
|
+
line = line.slice(1);
|
|
335
|
+
}
|
|
336
|
+
isFirstLine = false;
|
|
337
|
+
}
|
|
338
|
+
yield line;
|
|
339
|
+
offset = endIdx + skipLen;
|
|
340
|
+
}
|
|
341
|
+
}
|
|
342
|
+
const remaining = decoder.decode();
|
|
343
|
+
if (remaining) {
|
|
344
|
+
buffer.push(remaining);
|
|
345
|
+
}
|
|
346
|
+
if (buffer.length > 0) {
|
|
347
|
+
let line = buffer.join("");
|
|
348
|
+
if (isFirstLine && line.startsWith("\uFEFF")) {
|
|
349
|
+
line = line.slice(1);
|
|
350
|
+
}
|
|
351
|
+
yield line;
|
|
352
|
+
}
|
|
353
|
+
}
|
|
354
|
+
var SSEDecoder = class {
|
|
355
|
+
data = [];
|
|
356
|
+
eventType = "";
|
|
357
|
+
lastEventId = null;
|
|
358
|
+
retry = null;
|
|
359
|
+
decode(line) {
|
|
360
|
+
if (line === "") {
|
|
361
|
+
return this.dispatch();
|
|
362
|
+
}
|
|
363
|
+
if (line[0] === ":") {
|
|
364
|
+
return null;
|
|
365
|
+
}
|
|
366
|
+
const colonIdx = line.indexOf(":");
|
|
367
|
+
let field;
|
|
368
|
+
let value;
|
|
369
|
+
if (colonIdx === -1) {
|
|
370
|
+
field = line;
|
|
371
|
+
value = "";
|
|
372
|
+
} else {
|
|
373
|
+
field = line.slice(0, colonIdx);
|
|
374
|
+
value = line.slice(colonIdx + 1);
|
|
375
|
+
if (value[0] === " ") {
|
|
376
|
+
value = value.slice(1);
|
|
377
|
+
}
|
|
378
|
+
}
|
|
379
|
+
switch (field) {
|
|
380
|
+
case "data":
|
|
381
|
+
this.data.push(value);
|
|
382
|
+
break;
|
|
383
|
+
case "event":
|
|
384
|
+
this.eventType = value;
|
|
385
|
+
break;
|
|
386
|
+
case "id":
|
|
387
|
+
if (!value.includes("\0")) {
|
|
388
|
+
this.lastEventId = value;
|
|
389
|
+
}
|
|
390
|
+
break;
|
|
391
|
+
case "retry":
|
|
392
|
+
if (/^[0-9]+$/.test(value)) {
|
|
393
|
+
this.retry = parseInt(value, 10);
|
|
394
|
+
}
|
|
395
|
+
break;
|
|
396
|
+
}
|
|
397
|
+
return null;
|
|
398
|
+
}
|
|
399
|
+
dispatch() {
|
|
400
|
+
const currentEventType = this.eventType;
|
|
401
|
+
this.eventType = "";
|
|
402
|
+
if (this.data.length === 0) {
|
|
403
|
+
return null;
|
|
404
|
+
}
|
|
405
|
+
const event = {
|
|
406
|
+
data: this.data.join("\n"),
|
|
407
|
+
event: currentEventType,
|
|
408
|
+
id: this.lastEventId,
|
|
409
|
+
retry: this.retry
|
|
410
|
+
};
|
|
411
|
+
this.data = [];
|
|
412
|
+
return event;
|
|
413
|
+
}
|
|
414
|
+
};
|
|
415
|
+
async function* iterSSEEvents(stream) {
|
|
416
|
+
const decoder = new SSEDecoder();
|
|
417
|
+
for await (const line of iterLines(stream)) {
|
|
418
|
+
const event = decoder.decode(line);
|
|
419
|
+
if (event !== null) {
|
|
420
|
+
yield event;
|
|
421
|
+
}
|
|
422
|
+
}
|
|
423
|
+
}
|
|
424
|
+
|
|
258
425
|
// src/transporter/compress.ts
|
|
259
426
|
var COMPRESSION_THRESHOLD = 750;
|
|
260
427
|
|
|
@@ -382,6 +549,9 @@ function serializeHeaders(baseHeaders, requestHeaders, requestOptionsHeaders) {
|
|
|
382
549
|
return serializedHeaders;
|
|
383
550
|
}
|
|
384
551
|
function deserializeSuccess(response) {
|
|
552
|
+
if (response.status === 204 || response.content.length === 0) {
|
|
553
|
+
return void 0;
|
|
554
|
+
}
|
|
385
555
|
try {
|
|
386
556
|
return JSON.parse(response.content);
|
|
387
557
|
} catch (e) {
|
|
@@ -590,6 +760,55 @@ function createTransporter({
|
|
|
590
760
|
}
|
|
591
761
|
);
|
|
592
762
|
}
|
|
763
|
+
async function* requestStream(request, requestOptions = {}) {
|
|
764
|
+
if (!requester.sendStream) {
|
|
765
|
+
throw new Error("This requester does not support streaming");
|
|
766
|
+
}
|
|
767
|
+
const data = serializeData(request, requestOptions);
|
|
768
|
+
const headers = serializeHeaders(baseHeaders, request.headers, requestOptions.headers);
|
|
769
|
+
headers["accept"] = "text/event-stream";
|
|
770
|
+
const dataQueryParameters = request.method === "GET" ? {
|
|
771
|
+
...request.data,
|
|
772
|
+
...requestOptions.data
|
|
773
|
+
} : {};
|
|
774
|
+
const queryParameters = {
|
|
775
|
+
...baseQueryParameters,
|
|
776
|
+
...request.queryParameters,
|
|
777
|
+
...dataQueryParameters
|
|
778
|
+
};
|
|
779
|
+
if (algoliaAgent.value) {
|
|
780
|
+
queryParameters["x-algolia-agent"] = algoliaAgent.value;
|
|
781
|
+
}
|
|
782
|
+
if (requestOptions && requestOptions.queryParameters) {
|
|
783
|
+
for (const key of Object.keys(requestOptions.queryParameters)) {
|
|
784
|
+
if (!requestOptions.queryParameters[key] || Object.prototype.toString.call(requestOptions.queryParameters[key]) === "[object Object]") {
|
|
785
|
+
queryParameters[key] = requestOptions.queryParameters[key];
|
|
786
|
+
} else {
|
|
787
|
+
queryParameters[key] = requestOptions.queryParameters[key].toString();
|
|
788
|
+
}
|
|
789
|
+
}
|
|
790
|
+
}
|
|
791
|
+
const isRead = request.useReadTransporter || request.method === "GET";
|
|
792
|
+
const compatibleHosts = hosts.filter(
|
|
793
|
+
(host2) => host2.accept === "readWrite" || (isRead ? host2.accept === "read" : host2.accept === "write")
|
|
794
|
+
);
|
|
795
|
+
const options = await createRetryableOptions(compatibleHosts);
|
|
796
|
+
const host = options.hosts[0];
|
|
797
|
+
if (!host) {
|
|
798
|
+
throw new RetryError([]);
|
|
799
|
+
}
|
|
800
|
+
const timeout = { ...timeouts, ...requestOptions.timeouts };
|
|
801
|
+
const payload = {
|
|
802
|
+
data,
|
|
803
|
+
headers,
|
|
804
|
+
method: request.method,
|
|
805
|
+
url: serializeUrl(host, request.path, queryParameters),
|
|
806
|
+
connectTimeout: timeout.connect,
|
|
807
|
+
responseTimeout: isRead ? timeout.read : timeout.write
|
|
808
|
+
};
|
|
809
|
+
const stream = await requester.sendStream(payload);
|
|
810
|
+
yield* iterSSEEvents(stream);
|
|
811
|
+
}
|
|
593
812
|
return {
|
|
594
813
|
hostsCache,
|
|
595
814
|
requester,
|
|
@@ -600,6 +819,7 @@ function createTransporter({
|
|
|
600
819
|
baseQueryParameters,
|
|
601
820
|
hosts,
|
|
602
821
|
request: createRequest,
|
|
822
|
+
requestStream,
|
|
603
823
|
requestsCache,
|
|
604
824
|
responsesCache
|
|
605
825
|
};
|
|
@@ -611,6 +831,13 @@ var LogLevelEnum = {
|
|
|
611
831
|
Info: 2,
|
|
612
832
|
Error: 3
|
|
613
833
|
};
|
|
834
|
+
|
|
835
|
+
// src/validateParam.ts
|
|
836
|
+
function validateRequired(field, method, value) {
|
|
837
|
+
if (value === null || value === void 0 || typeof value === "string" && value.length === 0) {
|
|
838
|
+
throw new Error(`Parameter \`${field}\` is required when calling \`${method}\`.`);
|
|
839
|
+
}
|
|
840
|
+
}
|
|
614
841
|
export {
|
|
615
842
|
AlgoliaError,
|
|
616
843
|
ApiError,
|
|
@@ -645,12 +872,14 @@ export {
|
|
|
645
872
|
isNetworkError,
|
|
646
873
|
isRetryable,
|
|
647
874
|
isSuccess,
|
|
875
|
+
iterSSEEvents,
|
|
648
876
|
serializeData,
|
|
649
877
|
serializeHeaders,
|
|
650
878
|
serializeQueryParameters,
|
|
651
879
|
serializeUrl,
|
|
652
880
|
shuffle,
|
|
653
881
|
stackFrameWithoutCredentials,
|
|
654
|
-
stackTraceWithoutCredentials
|
|
882
|
+
stackTraceWithoutCredentials,
|
|
883
|
+
validateRequired
|
|
655
884
|
};
|
|
656
885
|
//# sourceMappingURL=common.js.map
|