@dfinity/pic
Version:
An Internet Computer Protocol canister testing library for TypeScript and JavaScript.
137 lines • 5.98 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.Http2Client = exports.JSON_HEADER = void 0;
const error_1 = require("./error");
const util_1 = require("./util");
exports.JSON_HEADER = {
'Content-Type': 'application/json',
};
class Http2Client {
baseUrl;
processingTimeoutMs;
constructor(baseUrl, processingTimeoutMs) {
this.baseUrl = baseUrl;
this.processingTimeoutMs = processingTimeoutMs;
}
request(init) {
const timeoutAbortController = new AbortController();
const requestAbortController = new AbortController();
const cancelAfterTimeout = async () => {
return await new Promise((_, reject) => {
const timeoutId = setTimeout(() => {
requestAbortController.abort();
reject(new error_1.ServerRequestTimeoutError());
}, this.processingTimeoutMs);
timeoutAbortController.signal.addEventListener('abort', () => {
clearTimeout(timeoutId);
reject(new error_1.ServerRequestTimeoutError());
});
});
};
const makeRequest = async () => {
const url = `${this.baseUrl}${init.path}`;
const res = await fetch(url, {
method: init.method,
headers: init.headers,
body: init.body,
signal: requestAbortController.signal,
});
timeoutAbortController.abort();
return res;
};
return Promise.race([makeRequest(), cancelAfterTimeout()]);
}
async jsonGet(init) {
// poll the request until it is successful or times out
return await (0, util_1.poll)(async () => {
const res = await this.request({
method: 'GET',
path: init.path,
headers: { ...init.headers, ...exports.JSON_HEADER },
});
const resBody = (await res.json());
if (!resBody) {
return resBody;
}
// server encountered an error, throw and try again
if ('message' in resBody) {
console.error('PocketIC server encountered an error', resBody.message);
throw new Error(resBody.message);
}
// the server has started processing or is busy
if ('state_label' in resBody) {
// the server is too busy to process the request, throw and try again
if (res.status === 409) {
throw new Error('Server busy');
}
// the server has started processing the request
// this shouldn't happen for GET requests, throw and try again
if (res.status === 202) {
throw new Error('Server started processing');
}
// something weird happened, throw and try again
throw new Error('Unknown state');
}
// the request was successful, exit the loop
return resBody;
}, { intervalMs: POLLING_INTERVAL_MS, timeoutMs: this.processingTimeoutMs });
}
async jsonPost(init) {
const reqBody = init.body
? new TextEncoder().encode(JSON.stringify(init.body))
: undefined;
// poll the request until it is successful or times out
return await (0, util_1.poll)(async () => {
const res = await this.request({
method: 'POST',
path: init.path,
headers: { ...init.headers, ...exports.JSON_HEADER },
body: reqBody,
});
const resBody = (await res.json());
if ((0, util_1.isNil)(resBody)) {
return resBody;
}
// server encountered an error, throw and try again
if ('message' in resBody) {
console.error('PocketIC server encountered an error', resBody.message);
throw new Error(resBody.message);
}
// the server has started processing or is busy
if ('state_label' in resBody) {
// the server is too busy to process the request, throw and try again
if (res.status === 409) {
throw new Error('Server busy');
}
// the server has started processing the request, poll until it is done
if (res.status === 202) {
return await (0, util_1.poll)(async () => {
const stateRes = await this.request({
method: 'GET',
path: `/read_graph/${resBody.state_label}/${resBody.op_id}`,
});
const stateBody = (await stateRes.json());
// the server encountered an error, throw and try again
if ((0, util_1.isNil)(stateBody) ||
'message' in stateBody ||
'state_label' in stateBody) {
throw new Error('Polling has not succeeded yet');
}
// the request was successful, exit the loop
return stateBody;
}, {
intervalMs: POLLING_INTERVAL_MS,
timeoutMs: this.processingTimeoutMs,
});
}
// something weird happened, throw and try again
throw new Error('Unknown state');
}
// the request was successful, exit the loop
return resBody;
}, { intervalMs: POLLING_INTERVAL_MS, timeoutMs: this.processingTimeoutMs });
}
}
exports.Http2Client = Http2Client;
const POLLING_INTERVAL_MS = 10;
//# sourceMappingURL=http2-client.js.map