Skip to content

Commit fac9b3b

Browse files
committed
fix after rebasing
1 parent 36d5c2c commit fac9b3b

File tree

4 files changed

+41
-22
lines changed

4 files changed

+41
-22
lines changed

packages/cubejs-client-core/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@
3838
],
3939
"license": "MIT",
4040
"devDependencies": {
41-
"@cubejs-backend/linter": "1.3.13",
41+
"@cubejs-backend/linter": "1.3.15",
4242
"@types/jest": "^29",
4343
"@types/moment-range": "^4.0.0",
4444
"@types/ramda": "^0.27.34",

packages/cubejs-client-core/src/HttpTransport.ts

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,10 @@ export type TransportOptions = {
2424
* Fetch timeout in milliseconds. Would be passed as AbortSignal.timeout()
2525
*/
2626
fetchTimeout?: number;
27+
/**
28+
* AbortSignal to cancel requests
29+
*/
30+
signal?: AbortSignal;
2731
};
2832

2933
export interface ITransportResponse<R> {
@@ -52,8 +56,8 @@ export class HttpTransport implements ITransport<Response> {
5256
protected credentials: TransportOptions['credentials'];
5357

5458
protected fetchTimeout: number | undefined;
55-
56-
private signal: any;
59+
60+
private readonly signal: AbortSignal | undefined;
5761

5862
public constructor({ authorization, apiUrl, method, headers = {}, credentials, fetchTimeout, signal }: Omit<TransportOptions, 'headers'> & { headers?: TransportOptions['headers'] }) {
5963
this.authorization = authorization;

packages/cubejs-client-core/src/index.ts

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,10 @@ export type LoadMethodOptions = {
4545
* Function that receives `ProgressResult` on each `Continue wait` message.
4646
*/
4747
progressCallback?(result: ProgressResult): void;
48+
/**
49+
* AbortSignal to cancel requests
50+
*/
51+
signal?: AbortSignal;
4852
};
4953

5054
export type DeeplyReadonly<T> = {
@@ -139,6 +143,14 @@ export type CubeApiOptions = {
139143
* How many network errors would be retried before returning to users. Default to 0.
140144
*/
141145
networkErrorRetries?: number;
146+
/**
147+
* AbortSignal to cancel requests
148+
*/
149+
signal?: AbortSignal;
150+
/**
151+
* Fetch timeout in milliseconds. Would be passed as AbortSignal.timeout()
152+
*/
153+
fetchTimeout?: number;
142154
};
143155

144156
/**
@@ -528,7 +540,7 @@ class CubeApi {
528540
() => this.request('load', {
529541
query,
530542
queryType: 'multi',
531-
signal: options.signal
543+
signal: options?.signal
532544
}),
533545
(response: any) => this.loadResponseInternal(response, options),
534546
options,
@@ -594,7 +606,7 @@ class CubeApi {
594606
() => this.request('subscribe', {
595607
query,
596608
queryType: 'multi',
597-
signal: options.signal
609+
signal: options?.signal
598610
}),
599611
(response: any) => this.loadResponseInternal(response, options),
600612
{ ...options, subscribe: true },

packages/cubejs-client-core/test/HttpTransport.test.ts

Lines changed: 20 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -120,13 +120,16 @@ describe('HttpTransport', () => {
120120
// Signal tests from src/tests/HttpTransport.test.js
121121
describe('Signal functionality', () => {
122122
beforeEach(() => {
123-
fetch.mockClear();
124123
// Default mock implementation for signal tests
125-
fetch.mockImplementation(() => Promise.resolve({
124+
mockedFetch.mockImplementation(() => Promise.resolve({
126125
json: () => Promise.resolve({ data: 'test data' }),
127126
ok: true,
128127
status: 200
129-
}));
128+
}) as any);
129+
});
130+
131+
afterEach(() => {
132+
mockedFetch.mockClear();
130133
});
131134

132135
test('should pass the signal to fetch when provided in constructor', async () => {
@@ -148,8 +151,8 @@ describe('HttpTransport', () => {
148151
await Promise.resolve();
149152

150153
// Ensure fetch was called with the signal
151-
expect(fetch).toHaveBeenCalledTimes(1);
152-
expect(fetch.mock.calls[0][1].signal).toBe(signal);
154+
expect(mockedFetch).toHaveBeenCalledTimes(1);
155+
expect(mockedFetch.mock.calls[0]?.[1]?.signal).toBe(signal);
153156

154157
await promise;
155158
});
@@ -175,8 +178,8 @@ describe('HttpTransport', () => {
175178
await Promise.resolve();
176179

177180
// Ensure fetch was called with the signal
178-
expect(fetch).toHaveBeenCalledTimes(1);
179-
expect(fetch.mock.calls[0][1].signal).toBe(signal);
181+
expect(mockedFetch).toHaveBeenCalledTimes(1);
182+
expect(mockedFetch.mock.calls[0]?.[1]?.signal).toBe(signal);
180183

181184
await promise;
182185
});
@@ -203,9 +206,9 @@ describe('HttpTransport', () => {
203206
await Promise.resolve();
204207

205208
// Ensure fetch was called with the request signal, not the constructor signal
206-
expect(fetch).toHaveBeenCalledTimes(1);
207-
expect(fetch.mock.calls[0][1].signal).toBe(controller2.signal);
208-
expect(fetch.mock.calls[0][1].signal).not.toBe(controller1.signal);
209+
expect(mockedFetch).toHaveBeenCalledTimes(1);
210+
expect(mockedFetch.mock.calls[0]?.[1]?.signal).toBe(controller2.signal);
211+
expect(mockedFetch.mock.calls[0]?.[1]?.signal).not.toBe(controller1.signal);
209212

210213
await promise;
211214
});
@@ -233,8 +236,8 @@ describe('HttpTransport', () => {
233236
await Promise.resolve();
234237

235238
// Ensure fetch was called with the timeout signal
236-
expect(fetch).toHaveBeenCalledTimes(1);
237-
expect(fetch.mock.calls[0][1].signal).toBe(mockTimeoutSignal);
239+
expect(mockedFetch).toHaveBeenCalledTimes(1);
240+
expect(mockedFetch.mock.calls[0]?.[1]?.signal).toBe(mockTimeoutSignal);
238241
expect(AbortSignal.timeout).toHaveBeenCalledWith(5000);
239242

240243
// Restore original implementation
@@ -246,12 +249,12 @@ describe('HttpTransport', () => {
246249
test('should handle request abortion', async () => {
247250
// Create a mock Promise and resolver function to control Promise completion
248251
let resolveFetch;
249-
const fetchPromise = new Promise(resolve => {
252+
const fetchPromise = new Promise<Response>(resolve => {
250253
resolveFetch = resolve;
251254
});
252255

253256
// Mock fetch to return our controlled Promise
254-
fetch.mockImplementationOnce(() => fetchPromise);
257+
mockedFetch.mockImplementationOnce(() => fetchPromise);
255258

256259
const controller = new AbortController();
257260
const { signal } = controller;
@@ -273,14 +276,14 @@ describe('HttpTransport', () => {
273276
await Promise.resolve();
274277

275278
// Ensure fetch was called with the signal
276-
expect(fetch).toHaveBeenCalledTimes(1);
277-
expect(fetch.mock.calls[0][1].signal).toBe(signal);
279+
expect(mockedFetch).toHaveBeenCalledTimes(1);
280+
expect(mockedFetch.mock.calls[0]?.[1]?.signal).toBe(signal);
278281

279282
// Abort the request
280283
controller.abort();
281284

282285
// Resolve the fetch Promise, simulating request completion
283-
resolveFetch({
286+
resolveFetch!({
284287
json: () => Promise.resolve({ data: 'aborted data' }),
285288
ok: true,
286289
status: 200

0 commit comments

Comments
 (0)