jest-metadata
Version:
🦸♂️ Superhero power for your Jest reporters! 🦸♀️
106 lines • 3.9 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.IPCServer = void 0;
const tslib_1 = require("tslib");
const node_ipc_1 = tslib_1.__importDefault(require("node-ipc"));
const strip_ansi_1 = tslib_1.__importDefault(require("strip-ansi"));
const utils_1 = require("../utils");
const log = utils_1.diagnostics.child({
cat: ['ipc', 'ipc-server'],
tid: 'jest-metadata-ipc',
});
class IPCServer {
_startPromise;
_stopPromise;
_flushDeferred;
_ipc;
_globalMetadata;
_emitter;
_knownSockets = new Set();
constructor(config) {
this._ipc = new node_ipc_1.default.IPC();
this._ipc.config.id = config.serverId;
this._ipc.config.appspace = config.appspace;
this._ipc.config.logger = (0, utils_1.optimizeTracing)((msg) => log.trace((0, strip_ansi_1.default)(msg)));
this._globalMetadata = config.globalMetadata;
this._emitter = config.emitter;
}
get id() {
return this._ipc.config.id;
}
async start() {
if (!this._startPromise) {
this._startPromise = log.trace.complete('start', this._doStart());
}
return this._startPromise;
}
async stop() {
if (!this._stopPromise) {
this._stopPromise = log.trace.complete('stop', this._doStop());
}
return this._stopPromise;
}
flush() {
/* no-op, maybe we should delete this method */
}
async _doStart() {
await this._stopPromise;
this._stopPromise = undefined;
this._flushDeferred = (0, utils_1.makeDeferred)();
await new Promise((resolve, reject) => {
this._ipc.serve(() => resolve(void 0));
this._ipc.server.on('clientMessageBatch', this._onClientMessageBatch.bind(this));
// @ts-expect-error TS2339: Property 'once' does not exist on type 'Server'.
this._ipc.server.once('error', reject);
this._ipc.server.start();
});
}
async _doStop() {
await this._startPromise;
this._startPromise = undefined;
await new Promise((resolve, reject) => {
this._ipc.server.broadcast('beforeExit');
const handle = this._setEmergencyTimeout(1000);
this._checkIfAllClientsFlushed();
this._flushDeferred.promise.then(() => {
clearTimeout(handle);
// @ts-expect-error TS2339: Property 'server' does not exist on type 'Server'.
this._ipc.server.server.close((e) => (e ? reject(e) : resolve()));
this._ipc.server.stop();
});
});
}
_onClientMessageBatch({ batch, first, last }, socket) {
for (const rawEvent of batch) {
const event = JSON.parse(rawEvent);
if (event.type !== 'add_test_file') {
// Jest Metadata server adds new test files before we get
// the independent confirmation from the Jest worker via IPC.
// So, we don't want to emit the event twice.
this._emitter.emit(event);
}
}
const payload = first ? this._globalMetadata.get() : void 0;
this._ipc.server.emit(socket, 'clientMessageBatchDone', payload);
if (last) {
this._knownSockets.delete(socket);
this._checkIfAllClientsFlushed();
}
else {
this._knownSockets.add(socket);
}
}
_checkIfAllClientsFlushed() {
if (this._knownSockets.size === 0) {
this._flushDeferred.resolve();
}
}
_setEmergencyTimeout(ms) {
return setTimeout(() => {
log.warn('IPC clients did not flush all messages in time, forcing shutdown...');
this._flushDeferred.resolve();
}, ms);
}
}
exports.IPCServer = IPCServer;
//# sourceMappingURL=IPCServer.js.map