@phala/dstack-sdk
Version:
dstack SDK
139 lines • 5.42 kB
JavaScript
;
// SPDX-FileCopyrightText: © 2025 Phala Network <dstack@phala.network>
//
// SPDX-License-Identifier: Apache-2.0
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.__version__ = void 0;
exports.send_rpc_request = send_rpc_request;
const http_1 = __importDefault(require("http"));
const https_1 = __importDefault(require("https"));
const net_1 = __importDefault(require("net"));
exports.__version__ = "0.5.6";
function send_rpc_request(endpoint, path, payload, timeoutMs) {
return new Promise((resolve, reject) => {
const abortController = new AbortController();
let isCompleted = false;
const safeReject = (error) => {
if (!isCompleted) {
isCompleted = true;
reject(error);
}
};
const safeResolve = (result) => {
if (!isCompleted) {
isCompleted = true;
resolve(result);
}
};
const timeout = setTimeout(() => {
abortController.abort();
safeReject(new Error('request timed out'));
}, timeoutMs || 30000); // Default 30 seconds timeout
const cleanup = () => {
clearTimeout(timeout);
abortController.signal.removeEventListener('abort', onAbort);
};
const onAbort = () => {
cleanup();
safeReject(new Error('request aborted'));
};
abortController.signal.addEventListener('abort', onAbort);
const isHttp = endpoint.startsWith('http://') || endpoint.startsWith('https://');
if (isHttp) {
const url = new URL(path, endpoint);
const options = {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Content-Length': Buffer.byteLength(payload),
'User-Agent': `dstack-sdk-js/${exports.__version__}`,
},
};
const req = (url.protocol === 'https:' ? https_1.default : http_1.default).request(url, options, (res) => {
let data = '';
res.on('data', (chunk) => {
data += chunk;
});
res.on('end', () => {
cleanup();
try {
const result = JSON.parse(data);
safeResolve(result);
}
catch (error) {
safeReject(new Error('failed to parse response'));
}
});
});
req.on('error', (error) => {
cleanup();
safeReject(error);
});
abortController.signal.addEventListener('abort', () => {
req.destroy();
});
req.write(payload);
req.end();
}
else {
const client = net_1.default.createConnection({ path: endpoint }, () => {
client.write(`POST ${path} HTTP/1.1\r\n`);
client.write(`Host: localhost\r\n`);
client.write(`Content-Type: application/json\r\n`);
client.write(`Content-Length: ${payload.length}\r\n`);
client.write('\r\n');
client.write(payload);
});
let data = '';
let headers = {};
let headersParsed = false;
let contentLength = 0;
let bodyData = '';
client.on('data', (chunk) => {
data += chunk;
if (!headersParsed) {
const headerEndIndex = data.indexOf('\r\n\r\n');
if (headerEndIndex !== -1) {
const headerLines = data.slice(0, headerEndIndex).split('\r\n');
headerLines.forEach(line => {
const [key, value] = line.split(': ');
if (key && value) {
headers[key.toLowerCase()] = value;
}
});
headersParsed = true;
contentLength = parseInt(headers['content-length'] || '0', 10);
bodyData = data.slice(headerEndIndex + 4);
}
}
else {
bodyData += chunk;
}
if (headersParsed && bodyData.length >= contentLength) {
client.end();
}
});
client.on('end', () => {
cleanup();
try {
const result = JSON.parse(bodyData.slice(0, contentLength));
safeResolve(result);
}
catch (error) {
safeReject(new Error('failed to parse response'));
}
});
client.on('error', (error) => {
cleanup();
safeReject(error);
});
abortController.signal.addEventListener('abort', () => {
client.destroy();
});
}
});
}
//# sourceMappingURL=send-rpc-request.js.map