diff --git a/src/vs/base/common/event.ts b/src/vs/base/common/event.ts index be145a31743..87fd773a532 100644 --- a/src/vs/base/common/event.ts +++ b/src/vs/base/common/event.ts @@ -546,3 +546,17 @@ export class Relay implements IDisposable { this.emitter.dispose(); } } + +export interface NodeEventEmitter { + on(event: string | symbol, listener: Function): this; + removeListener(event: string | symbol, listener: Function): this; +} + +export function fromNodeEventEmitter(emitter: NodeEventEmitter, eventName: string, map: (...args: any[]) => T = id => id): Event { + const fn = (...args: any[]) => result.fire(map(...args)); + const onFirstListenerAdd = () => emitter.on(eventName, fn); + const onLastListenerRemove = () => emitter.removeListener(eventName, fn); + const result = new Emitter({ onFirstListenerAdd, onLastListenerRemove }); + + return result.event; +} diff --git a/src/vs/base/node/event.ts b/src/vs/base/node/event.ts deleted file mode 100644 index 037701d2431..00000000000 --- a/src/vs/base/node/event.ts +++ /dev/null @@ -1,18 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the MIT License. See License.txt in the project root for license information. - *--------------------------------------------------------------------------------------------*/ - -'use strict'; - -import Event, { Emitter } from 'vs/base/common/event'; -import { EventEmitter } from 'events'; - -export function fromEventEmitter(emitter: EventEmitter, eventName: string, map: (...args: any[]) => T = id => id): Event { - const fn = (...args: any[]) => result.fire(map(...args)); - const onFirstListenerAdd = () => emitter.on(eventName, fn); - const onLastListenerRemove = () => emitter.removeListener(eventName, fn); - const result = new Emitter({ onFirstListenerAdd, onLastListenerRemove }); - - return result.event; -} diff --git a/src/vs/base/parts/ipc/electron-browser/ipc.electron-browser.ts b/src/vs/base/parts/ipc/electron-browser/ipc.electron-browser.ts index 599cf277211..7e3ce8ddd1e 100644 --- a/src/vs/base/parts/ipc/electron-browser/ipc.electron-browser.ts +++ b/src/vs/base/parts/ipc/electron-browser/ipc.electron-browser.ts @@ -3,7 +3,7 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -import { fromEventEmitter } from 'vs/base/node/event'; +import { fromNodeEventEmitter } from 'vs/base/common/event'; import { IPCClient } from 'vs/base/parts/ipc/common/ipc'; import { Protocol } from 'vs/base/parts/ipc/common/ipc.electron'; import { ipcRenderer } from 'electron'; @@ -11,7 +11,7 @@ import { ipcRenderer } from 'electron'; export class Client extends IPCClient { private static createProtocol(): Protocol { - const onMessage = fromEventEmitter(ipcRenderer, 'ipc:message', (_, message) => message); + const onMessage = fromNodeEventEmitter(ipcRenderer, 'ipc:message', (_, message) => message); ipcRenderer.send('ipc:hello'); return new Protocol(ipcRenderer, onMessage); } diff --git a/src/vs/base/parts/ipc/electron-main/ipc.electron-main.ts b/src/vs/base/parts/ipc/electron-main/ipc.electron-main.ts index d0295a4937b..c6e556c6c0a 100644 --- a/src/vs/base/parts/ipc/electron-main/ipc.electron-main.ts +++ b/src/vs/base/parts/ipc/electron-main/ipc.electron-main.ts @@ -3,8 +3,7 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -import Event, { filterEvent, mapEvent } from 'vs/base/common/event'; -import { fromEventEmitter } from 'vs/base/node/event'; +import Event, { filterEvent, mapEvent, fromNodeEventEmitter } from 'vs/base/common/event'; import { IPCServer, ClientConnectionEvent } from 'vs/base/parts/ipc/common/ipc'; import { Protocol } from 'vs/base/parts/ipc/common/ipc.electron'; import { ipcMain } from 'electron'; @@ -19,7 +18,7 @@ interface IIPCEvent { } function createScopedOnMessageEvent(senderId: number): Event { - const onMessage = fromEventEmitter(ipcMain, 'ipc:message', (event, message) => ({ event, message })); + const onMessage = fromNodeEventEmitter(ipcMain, 'ipc:message', (event, message) => ({ event, message })); const onMessageFromSender = filterEvent(onMessage, ({ event }) => event.sender.getId() === senderId); return mapEvent(onMessageFromSender, ({ message }) => message); } @@ -27,12 +26,12 @@ function createScopedOnMessageEvent(senderId: number): Event { export class Server extends IPCServer { private static getOnDidClientConnect(): Event { - const onHello = fromEventEmitter(ipcMain, 'ipc:hello', ({ sender }) => sender); + const onHello = fromNodeEventEmitter(ipcMain, 'ipc:hello', ({ sender }) => sender); return mapEvent(onHello, webContents => { const onMessage = createScopedOnMessageEvent(webContents.getId()); const protocol = new Protocol(webContents, onMessage); - const onDidClientDisconnect = fromEventEmitter(webContents, 'destroyed'); + const onDidClientDisconnect = fromNodeEventEmitter(webContents, 'destroyed'); return { protocol, onDidClientDisconnect }; }); diff --git a/src/vs/base/parts/ipc/node/ipc.cp.ts b/src/vs/base/parts/ipc/node/ipc.cp.ts index cb73fe6f937..d7c610160f1 100644 --- a/src/vs/base/parts/ipc/node/ipc.cp.ts +++ b/src/vs/base/parts/ipc/node/ipc.cp.ts @@ -8,8 +8,7 @@ import { IDisposable } from 'vs/base/common/lifecycle'; import { TPromise } from 'vs/base/common/winjs.base'; import { Delayer } from 'vs/base/common/async'; import { clone, assign } from 'vs/base/common/objects'; -import { Emitter } from 'vs/base/common/event'; -import { fromEventEmitter } from 'vs/base/node/event'; +import { Emitter, fromNodeEventEmitter } from 'vs/base/common/event'; import { createQueuedSender } from 'vs/base/node/processes'; import { ChannelServer as IPCServer, ChannelClient as IPCClient, IChannelClient, IChannel } from 'vs/base/parts/ipc/common/ipc'; import { isRemoteConsoleLog, log } from 'vs/base/node/console'; @@ -18,7 +17,7 @@ export class Server extends IPCServer { constructor() { super({ send: r => { try { process.send(r); } catch (e) { /* not much to do */ } }, - onMessage: fromEventEmitter(process, 'message', msg => msg) + onMessage: fromNodeEventEmitter(process, 'message', msg => msg) }); process.once('disconnect', () => this.dispose()); @@ -149,7 +148,7 @@ export class Client implements IChannelClient, IDisposable { this.child = fork(this.modulePath, args, forkOpts); const onMessageEmitter = new Emitter(); - const onRawMessage = fromEventEmitter(this.child, 'message', msg => msg); + const onRawMessage = fromNodeEventEmitter(this.child, 'message', msg => msg); onRawMessage(msg => { diff --git a/src/vs/base/parts/ipc/node/ipc.net.ts b/src/vs/base/parts/ipc/node/ipc.net.ts index e4194ca6693..a080e193cb7 100644 --- a/src/vs/base/parts/ipc/node/ipc.net.ts +++ b/src/vs/base/parts/ipc/node/ipc.net.ts @@ -7,8 +7,7 @@ import { Socket, Server as NetServer, createConnection, createServer } from 'net'; import { TPromise } from 'vs/base/common/winjs.base'; -import Event, { Emitter, once, mapEvent } from 'vs/base/common/event'; -import { fromEventEmitter } from 'vs/base/node/event'; +import Event, { Emitter, once, mapEvent, fromNodeEventEmitter } from 'vs/base/common/event'; import { IMessagePassingProtocol, ClientConnectionEvent, IPCServer, IPCClient } from 'vs/base/parts/ipc/common/ipc'; import { join } from 'path'; import { tmpdir } from 'os'; @@ -156,11 +155,11 @@ export class Protocol implements IMessagePassingProtocol { export class Server extends IPCServer { private static toClientConnectionEvent(server: NetServer): Event { - const onConnection = fromEventEmitter(server, 'connection'); + const onConnection = fromNodeEventEmitter(server, 'connection'); return mapEvent(onConnection, socket => ({ protocol: new Protocol(socket), - onDidClientDisconnect: once(fromEventEmitter(socket, 'close')) + onDidClientDisconnect: once(fromNodeEventEmitter(socket, 'close')) })); } diff --git a/src/vs/code/electron-main/auth.ts b/src/vs/code/electron-main/auth.ts index dcafa6360b5..6434cfd557c 100644 --- a/src/vs/code/electron-main/auth.ts +++ b/src/vs/code/electron-main/auth.ts @@ -8,7 +8,7 @@ import { localize } from 'vs/nls'; import { IDisposable, dispose } from 'vs/base/common/lifecycle'; import { IWindowsMainService } from 'vs/platform/windows/electron-main/windows'; -import { fromEventEmitter } from 'vs/base/node/event'; +import { fromNodeEventEmitter } from 'vs/base/common/event'; import { BrowserWindow, app } from 'electron'; type LoginEvent = { @@ -34,7 +34,7 @@ export class ProxyAuthHandler { constructor( @IWindowsMainService private windowsService: IWindowsMainService ) { - const onLogin = fromEventEmitter(app, 'login', (event, webContents, req, authInfo, cb) => ({ event, webContents, req, authInfo, cb })); + const onLogin = fromNodeEventEmitter(app, 'login', (event, webContents, req, authInfo, cb) => ({ event, webContents, req, authInfo, cb })); onLogin(this.onLogin, this, this.disposables); } diff --git a/src/vs/platform/update/common/update.ts b/src/vs/platform/update/common/update.ts index 2c680aabced..13928e33f17 100644 --- a/src/vs/platform/update/common/update.ts +++ b/src/vs/platform/update/common/update.ts @@ -5,7 +5,7 @@ 'use strict'; -import Event from 'vs/base/common/event'; +import Event, { NodeEventEmitter } from 'vs/base/common/event'; import { createDecorator } from 'vs/platform/instantiation/common/instantiation'; import { TPromise } from 'vs/base/common/winjs.base'; @@ -35,7 +35,7 @@ export interface IUpdate { url?: string; } -export interface IAutoUpdater extends NodeJS.EventEmitter { +export interface IAutoUpdater extends NodeEventEmitter { setFeedURL(url: string): void; checkForUpdates(): void; quitAndInstall(): void; diff --git a/src/vs/platform/update/electron-main/updateService.ts b/src/vs/platform/update/electron-main/updateService.ts index 2dbdbbf6d1c..bb4b2da6262 100644 --- a/src/vs/platform/update/electron-main/updateService.ts +++ b/src/vs/platform/update/electron-main/updateService.ts @@ -9,10 +9,9 @@ import * as fs from 'original-fs'; import * as path from 'path'; import * as electron from 'electron'; import { IDisposable, dispose } from 'vs/base/common/lifecycle'; -import Event, { Emitter, once, filterEvent } from 'vs/base/common/event'; +import Event, { Emitter, once, filterEvent, fromNodeEventEmitter } from 'vs/base/common/event'; import { always, Throttler } from 'vs/base/common/async'; import { memoize } from 'vs/base/common/decorators'; -import { fromEventEmitter } from 'vs/base/node/event'; import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; import { Win32AutoUpdaterImpl } from './auto-updater.win32'; import { LinuxAutoUpdaterImpl } from './auto-updater.linux'; @@ -53,22 +52,22 @@ export class UpdateService implements IUpdateService { @memoize private get onRawError(): Event { - return fromEventEmitter(this.raw, 'error', (_, message) => message); + return fromNodeEventEmitter(this.raw, 'error', (_, message) => message); } @memoize private get onRawUpdateNotAvailable(): Event { - return fromEventEmitter(this.raw, 'update-not-available'); + return fromNodeEventEmitter(this.raw, 'update-not-available'); } @memoize private get onRawUpdateAvailable(): Event<{ url: string; version: string; }> { - return filterEvent(fromEventEmitter(this.raw, 'update-available', (_, url, version) => ({ url, version })), ({ url }) => !!url); + return filterEvent(fromNodeEventEmitter(this.raw, 'update-available', (_, url, version) => ({ url, version })), ({ url }) => !!url); } @memoize private get onRawUpdateDownloaded(): Event { - return fromEventEmitter(this.raw, 'update-downloaded', (_, releaseNotes, version, date, url) => ({ releaseNotes, version, date })); + return fromNodeEventEmitter(this.raw, 'update-downloaded', (_, releaseNotes, version, date, url) => ({ releaseNotes, version, date })); } get state(): State { diff --git a/src/vs/platform/url/electron-main/urlService.ts b/src/vs/platform/url/electron-main/urlService.ts index 2a7f2904df8..5469274fb20 100644 --- a/src/vs/platform/url/electron-main/urlService.ts +++ b/src/vs/platform/url/electron-main/urlService.ts @@ -5,8 +5,7 @@ 'use strict'; -import Event, { mapEvent, chain, echo, Emitter, anyEvent } from 'vs/base/common/event'; -import { fromEventEmitter } from 'vs/base/node/event'; +import Event, { mapEvent, chain, echo, Emitter, anyEvent, fromNodeEventEmitter } from 'vs/base/common/event'; import { IURLService } from 'vs/platform/url/common/url'; import product from 'vs/platform/node/product'; import { app } from 'electron'; @@ -28,7 +27,7 @@ export class URLService implements IURLService { app.setAsDefaultProtocolClient(product.urlProtocol, process.execPath, ['--open-url']); - const rawOnOpenUrl = fromEventEmitter(app, 'open-url', (event: Electron.Event, url: string) => ({ event, url })); + const rawOnOpenUrl = fromNodeEventEmitter(app, 'open-url', (event: Electron.Event, url: string) => ({ event, url })); // always prevent default and return the url as string const preventedOnOpenUrl = mapEvent(rawOnOpenUrl, ({ event, url }) => { diff --git a/src/vs/platform/windows/electron-main/windowsService.ts b/src/vs/platform/windows/electron-main/windowsService.ts index 4aa23f2a4c9..56fe2279713 100644 --- a/src/vs/platform/windows/electron-main/windowsService.ts +++ b/src/vs/platform/windows/electron-main/windowsService.ts @@ -12,8 +12,7 @@ import URI from 'vs/base/common/uri'; import { IWindowsService, OpenContext, INativeOpenDialogOptions, IEnterWorkspaceResult } from 'vs/platform/windows/common/windows'; import { IEnvironmentService } from 'vs/platform/environment/common/environment'; import { shell, crashReporter, app, Menu } from 'electron'; -import Event, { chain } from 'vs/base/common/event'; -import { fromEventEmitter } from 'vs/base/node/event'; +import Event, { chain, fromNodeEventEmitter } from 'vs/base/common/event'; import { IURLService } from 'vs/platform/url/common/url'; import { ILifecycleService } from 'vs/platform/lifecycle/electron-main/lifecycleMain'; import { IWindowsMainService, ISharedProcess } from 'vs/platform/windows/electron-main/windows'; @@ -27,9 +26,9 @@ export class WindowsService implements IWindowsService, IDisposable { private disposables: IDisposable[] = []; - readonly onWindowOpen: Event = fromEventEmitter(app, 'browser-window-created', (_, w: Electron.BrowserWindow) => w.id); - readonly onWindowFocus: Event = fromEventEmitter(app, 'browser-window-focus', (_, w: Electron.BrowserWindow) => w.id); - readonly onWindowBlur: Event = fromEventEmitter(app, 'browser-window-blur', (_, w: Electron.BrowserWindow) => w.id); + readonly onWindowOpen: Event = fromNodeEventEmitter(app, 'browser-window-created', (_, w: Electron.BrowserWindow) => w.id); + readonly onWindowFocus: Event = fromNodeEventEmitter(app, 'browser-window-focus', (_, w: Electron.BrowserWindow) => w.id); + readonly onWindowBlur: Event = fromNodeEventEmitter(app, 'browser-window-blur', (_, w: Electron.BrowserWindow) => w.id); constructor( private sharedProcess: ISharedProcess, diff --git a/src/vs/workbench/services/extensions/electron-browser/extensionHost.ts b/src/vs/workbench/services/extensions/electron-browser/extensionHost.ts index 24af572033f..8e82c3e4347 100644 --- a/src/vs/workbench/services/extensions/electron-browser/extensionHost.ts +++ b/src/vs/workbench/services/extensions/electron-browser/extensionHost.ts @@ -25,8 +25,7 @@ import { IEnvironmentService } from 'vs/platform/environment/common/environment' import { IMessagePassingProtocol } from 'vs/base/parts/ipc/common/ipc'; import { generateRandomPipeName, Protocol } from 'vs/base/parts/ipc/node/ipc.net'; import { createServer, Server, Socket } from 'net'; -import Event, { Emitter, debounceEvent, mapEvent, anyEvent } from 'vs/base/common/event'; -import { fromEventEmitter } from 'vs/base/node/event'; +import Event, { Emitter, debounceEvent, mapEvent, anyEvent, fromNodeEventEmitter } from 'vs/base/common/event'; import { IInitData, IWorkspaceData, IConfigurationInitData } from 'vs/workbench/api/node/extHost.protocol'; import { IExtensionService } from 'vs/platform/extensions/common/extensions'; import { IWorkspaceConfigurationService } from 'vs/workbench/services/configuration/common/configuration'; @@ -170,8 +169,8 @@ export class ExtensionHostProcessWorker { type Output = { data: string, format: string[] }; this._extensionHostProcess.stdout.setEncoding('utf8'); this._extensionHostProcess.stderr.setEncoding('utf8'); - const onStdout = fromEventEmitter(this._extensionHostProcess.stdout, 'data'); - const onStderr = fromEventEmitter(this._extensionHostProcess.stderr, 'data'); + const onStdout = fromNodeEventEmitter(this._extensionHostProcess.stdout, 'data'); + const onStderr = fromNodeEventEmitter(this._extensionHostProcess.stderr, 'data'); const onOutput = anyEvent( mapEvent(onStdout, o => ({ data: `%c${o}`, format: [''] })), mapEvent(onStderr, o => ({ data: `%c${o}`, format: ['color: red'] }))