UNPKG

@dfinity/pic

Version:

An Internet Computer Protocol canister testing library for TypeScript and JavaScript.

126 lines 4.11 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.PocketIcServer = void 0; const node_child_process_1 = require("node:child_process"); const node_path_1 = require("node:path"); const node_fs_1 = require("node:fs"); const error_1 = require("./error"); const util_1 = require("./util"); const node_stream_1 = require("node:stream"); /** * This class represents the main PocketIC server. * It is responsible for maintaining the lifecycle of the server process. * See {@link PocketIc} for details on the client to use with this server. * * @category API * * @example * ```ts * import { PocketIc, PocketIcServer } from '@dfinity/pic'; * import { _SERVICE, idlFactory } from '../declarations'; * * const wasmPath = resolve('..', '..', 'canister.wasm'); * * const picServer = await PocketIcServer.create(); * const pic = await PocketIc.create(picServer.getUrl()); * * const fixture = await pic.setupCanister<_SERVICE>({ idlFactory, wasmPath }); * const { actor } = fixture; * * // perform tests... * * await pic.tearDown(); * await picServer.stop(); * ``` */ class PocketIcServer { serverProcess; url; constructor(serverProcess, portNumber) { this.serverProcess = serverProcess; this.url = `http://127.0.0.1:${portNumber}`; } /** * Start a new PocketIC server. * * @param options Options for starting the server. * @returns An instance of the PocketIC server. */ static async start(options = {}) { const binPath = this.getBinPath(); await this.assertBinExists(binPath); const pid = process.ppid; const picFilePrefix = `pocket_ic_${pid}`; const portFilePath = (0, util_1.tmpFile)(`${picFilePrefix}.port`); const serverProcess = (0, node_child_process_1.spawn)(binPath, ['--port-file', portFilePath]); if (options.showRuntimeLogs) { serverProcess.stdout.pipe(process.stdout); } else { serverProcess.stdout.pipe(new NullStream()); } if (options.showCanisterLogs) { serverProcess.stderr.pipe(process.stderr); } else { serverProcess.stderr.pipe(new NullStream()); } serverProcess.on('error', error => { if ((0, util_1.isArm)() && (0, util_1.isDarwin)()) { throw new error_1.BinStartMacOSArmError(error); } throw new error_1.BinStartError(error); }); return await (0, util_1.poll)(async () => { const portString = await (0, util_1.readFileAsString)(portFilePath); const port = parseInt(portString); if (isNaN(port)) { throw new error_1.BinTimeoutError(); } return new PocketIcServer(serverProcess, port); }, { intervalMs: POLL_INTERVAL_MS, timeoutMs: POLL_TIMEOUT_MS }); } /** * Get the URL of the server. * * @returns The URL of the server. */ getUrl() { return this.url; } /** * Stop the server. * * @returns A promise that resolves when the server has stopped. */ async stop() { return new Promise((resolve, reject) => { this.serverProcess.on('exit', () => { resolve(); }); this.serverProcess.on('error', error => { reject(error); }); this.serverProcess.kill(); }); } static getBinPath() { return (0, node_path_1.resolve)(__dirname, '..', 'pocket-ic'); } static async assertBinExists(binPath) { const binExists = await (0, util_1.exists)(binPath); if (!binExists) { throw new error_1.BinNotFoundError(binPath); } (0, node_fs_1.chmodSync)(binPath, 0o700); } } exports.PocketIcServer = PocketIcServer; const POLL_INTERVAL_MS = 20; const POLL_TIMEOUT_MS = 30_000; class NullStream extends node_stream_1.Writable { _write(_chunk, _encoding, callback) { callback(); } } //# sourceMappingURL=pocket-ic-server.js.map