@stryke/capnp
Version:
A package to assist in running the Cap'n Proto compiler and creating Cap'n Proto serialization protocol schemas.
115 lines (113 loc) • 3.44 kB
JavaScript
import { t as Message } from "./capnp-es.GpvEvMIK-CH8kq1KS.mjs";
import { T as Deferred, a as DeferredTransport, r as Conn } from "./dist-DQ7xmzRT.mjs";
import { MessageChannel } from "node:worker_threads";
//#region src/rpc-helpers.ts
/**
* A transport class for Cap'n Proto RPC that uses {@link MessageChannel} for communication.
*/
var CapnpRPCMessageChannelTransport = class extends DeferredTransport {
port;
constructor(port) {
super();
this.port = port;
this.port.on("message", this.resolve);
this.port.on("messageerror", this.reject);
this.port.on("close", this.close);
}
/**
* Closes the transport and removes all event listeners.
*/
close = () => {
this.port.off("message", this.resolve);
this.port.off("messageerror", this.reject);
this.port.off("close", this.close);
this.port.close();
super.close();
};
/**
* Sends a Cap'n Proto RPC message over the MessagePort.
*
* @param msg - The RPC message to send.
*/
sendMessage(msg) {
const m = new Message();
m.setRoot(msg);
const buf = m.toArrayBuffer();
this.port.postMessage(buf, [buf]);
}
};
/**
* A class that manages Cap'n Proto RPC connections.
*/
var CapnpRPC = class {
/**
* A queue for deferred connections that are waiting to be accepted.
*
* @remarks
* This is used to manage incoming connections when the accept method is called.
*/
acceptQueue = new Array();
/**
* A map of connections by their ID.
*
* @remarks
* This is used to manage multiple connections and allows for easy retrieval by ID.
*/
connections = {};
/**
* A queue for connections that are waiting to be accepted.
*
* @remarks
* This is used to manage incoming connections when the accept method is called.
*/
connectQueue = new Array();
/**
* Creates a new {@link Conn} instance.
*
* @remarks
* This class is used to manage connections and accept incoming connections using the {@link MessageChannel} API.
*/
connect(id = 0) {
if (this.connections[id] !== void 0) return this.connections[id];
const ch = new MessageChannel();
const conn = new Conn(new CapnpRPCMessageChannelTransport(ch.port1));
const accept = this.acceptQueue.pop();
this.connections[id] = conn;
if (accept === void 0) this.connectQueue.push(ch.port2);
else accept.resolve(new Conn(new CapnpRPCMessageChannelTransport(ch.port2)));
return conn;
}
/**
* Accepts a connection from the connect queue.
*
* @returns A promise that resolves to a Conn instance when a connection is accepted.
* @throws If no connections are available in the connect queue.
*/
async accept() {
const port2 = this.connectQueue.pop();
if (port2 !== void 0) return Promise.resolve(new Conn(new CapnpRPCMessageChannelTransport(port2)));
const deferred = new Deferred();
this.acceptQueue.push(deferred);
return deferred.promise;
}
/**
* Closes all connections and clears the queues.
*
* @remarks
* This method will reject all pending accept promises and close all
* connections in the connect queue.
*/
close() {
let i = this.acceptQueue.length;
while (--i >= 0) this.acceptQueue[i]?.reject();
i = this.connectQueue.length;
while (--i >= 0) this.connectQueue[i].close();
for (const id in this.connections) this.connections[id]?.shutdown();
this.acceptQueue.length = 0;
this.connectQueue.length = 0;
this.connections = {};
}
};
//#endregion
export { CapnpRPC, CapnpRPCMessageChannelTransport };
//# sourceMappingURL=rpc-helpers.mjs.map