Skip to content

Commit

Permalink
feat: cancellation support
Browse files Browse the repository at this point in the history
  • Loading branch information
RAORelewise committed Oct 20, 2023
1 parent 2653f96 commit fd68866
Showing 1 changed file with 35 additions and 3 deletions.
38 changes: 35 additions & 3 deletions lib/src/relewise.client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import version from './version';

export interface RelewiseClientOptions {
serverUrl?: string;
useCancellation?: boolean;
}

export class ProblemDetailsError extends Error {
Expand All @@ -28,8 +29,29 @@ export interface HttpProblemDetails {
}

export abstract class RelewiseClient {
private requestDictionary: { [requestUrl: string]: AbortController | null } = {};

private ensureAbortSignal(requestUrl: string): AbortSignal {
let abortController = this.requestDictionary[requestUrl];
if (abortController) {
abortController.abort();
}

abortController = new AbortController();
this.requestDictionary[requestUrl] = abortController;

return abortController.signal;
}

private clearAbortSignal(requestUrl: string) {
this.requestDictionary[requestUrl] = null;
delete this.requestDictionary[requestUrl];
}

private readonly _serverUrl: string = 'https://api.relewise.com';
private readonly _urlPath: string = 'v1';
private readonly apiKeyHeader = `APIKey ${this.apiKey}`;
private readonly useCancellation: boolean = false;

constructor(protected readonly datasetId: string, protected readonly apiKey: string, options?: RelewiseClientOptions) {
if (!datasetId) throw new Error('Dataset id cannot be null or empty. Please contact Relewise if you don\'t have an account already or would like a free demo license');
Expand All @@ -38,29 +60,39 @@ export abstract class RelewiseClient {
if (options?.serverUrl) {
this._serverUrl = options.serverUrl;
}

this.useCancellation = options?.useCancellation ?? false;
}

public get serverUrl(): string {
return this._serverUrl;
}

protected async request<TRequest, TResponse>(name: string, data: TRequest): Promise<TResponse | undefined> {
const apiKeyHeader = `APIKey ${this.apiKey}`;
const requestUrl = this.createRequestUrl(this._serverUrl, this.datasetId, this._urlPath, name);

const response = await fetch(requestUrl, {
method: 'POST',
headers: {
Authorization: apiKeyHeader,
Authorization: this.apiKeyHeader,
'Content-Type': 'application/json',
'X-Relewise-Version': version.tag,
},
body: JSON.stringify(data),
...(this.useCancellation && { signal: this.ensureAbortSignal(requestUrl) }),
});

if (!response.ok) {
let responseMessage = null;
try { responseMessage = await response.json(); } catch (_) { console.log(responseMessage)}
try {
responseMessage = await response.json();
} catch (_) {
console.log(responseMessage)
} finally {
if (this.useCancellation) {
this.clearAbortSignal(requestUrl);
}
}

throw new ProblemDetailsError('Error when calling the Relewise API. Read more in the details property if there is error response or look in the network tab.', responseMessage);
}
Expand Down

0 comments on commit fd68866

Please sign in to comment.