sussudio
Version:
An unofficial VS Code Internal API
45 lines (44 loc) • 2.48 kB
JavaScript
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import { ipcRenderer } from 'electron';
import { Event } from "../../../common/event.mjs";
import { IPCServer } from "../common/ipc.mjs";
import { Protocol as MessagePortProtocol } from "../common/ipc.mp.mjs";
/**
* An implementation of a `IPCServer` on top of MessagePort style IPC communication.
* The clients register themselves via Electron IPC transfer.
*/
export class Server extends IPCServer {
static getOnDidClientConnect() {
// Clients connect via `vscode:createMessageChannel` to get a
// `MessagePort` that is ready to be used. For every connection
// we create a pair of message ports and send it back.
//
// The `nonce` is included so that the main side has a chance to
// correlate the response back to the sender.
const onCreateMessageChannel = Event.fromNodeEventEmitter(ipcRenderer, 'vscode:createMessageChannel', (_, nonce) => nonce);
return Event.map(onCreateMessageChannel, nonce => {
// Create a new pair of ports and protocol for this connection
const { port1: incomingPort, port2: outgoingPort } = new MessageChannel();
const protocol = new MessagePortProtocol(incomingPort);
const result = {
protocol,
// Not part of the standard spec, but in Electron we get a `close` event
// when the other side closes. We can use this to detect disconnects
// (https://github.com/electron/electron/blob/11-x-y/docs/api/message-port-main.md#event-close)
onDidClientDisconnect: Event.fromDOMEventEmitter(incomingPort, 'close')
};
// Send one port back to the requestor
// Note: we intentionally use `electron` APIs here because
// transferables like the `MessagePort` cannot be transferred
// over preload scripts when `contextIsolation: true`
ipcRenderer.postMessage('vscode:createMessageChannelResult', nonce, [outgoingPort]);
return result;
});
}
constructor() {
super(Server.getOnDidClientConnect());
}
}