fix(core): Improve streaming support and timeout handling; add browser streaming & timeout tests and README clarifications

This commit is contained in:
2025-08-19 01:36:44 +00:00
parent 35867d9148
commit 361d97f440
8 changed files with 181 additions and 11 deletions

View File

@@ -9,6 +9,9 @@ export class CoreRequest extends AbstractCoreRequest<
types.ICoreRequestOptions,
CoreResponse
> {
private timeoutId: ReturnType<typeof setTimeout> | null = null;
private abortController: AbortController | null = null;
constructor(url: string, options: types.ICoreRequestOptions = {}) {
super(url, options);
@@ -61,11 +64,19 @@ export class CoreRequest extends AbstractCoreRequest<
if (
typeof this.options.requestBody === 'string' ||
this.options.requestBody instanceof ArrayBuffer ||
this.options.requestBody instanceof Uint8Array ||
this.options.requestBody instanceof FormData ||
this.options.requestBody instanceof URLSearchParams ||
this.options.requestBody instanceof ReadableStream
this.options.requestBody instanceof ReadableStream ||
// Check for Buffer (Node.js polyfills in browser may provide this)
(typeof Buffer !== 'undefined' && this.options.requestBody instanceof Buffer)
) {
fetchOptions.body = this.options.requestBody;
// If streaming, we need to set duplex mode
if (this.options.requestBody instanceof ReadableStream) {
(fetchOptions as any).duplex = 'half';
}
} else {
// Convert objects to JSON
fetchOptions.body = JSON.stringify(this.options.requestBody);
@@ -92,9 +103,13 @@ export class CoreRequest extends AbstractCoreRequest<
if (this.options.timeout || this.options.hardDataCuttingTimeout) {
const timeout =
this.options.hardDataCuttingTimeout || this.options.timeout;
const controller = new AbortController();
setTimeout(() => controller.abort(), timeout);
fetchOptions.signal = controller.signal;
this.abortController = new AbortController();
this.timeoutId = setTimeout(() => {
if (this.abortController) {
this.abortController.abort();
}
}, timeout);
fetchOptions.signal = this.abortController.signal;
}
return fetchOptions;
@@ -117,8 +132,12 @@ export class CoreRequest extends AbstractCoreRequest<
try {
const response = await fetch(url, options);
// Clear timeout on successful response
this.clearTimeout();
return response;
} catch (error) {
// Clear timeout on error
this.clearTimeout();
if (error.name === 'AbortError') {
throw new Error('Request timed out');
}
@@ -126,6 +145,19 @@ export class CoreRequest extends AbstractCoreRequest<
}
}
/**
* Clear the timeout and abort controller
*/
private clearTimeout(): void {
if (this.timeoutId) {
clearTimeout(this.timeoutId);
this.timeoutId = null;
}
if (this.abortController) {
this.abortController = null;
}
}
/**
* Static factory method to create and fire a request
*/