utils: switch to bevent.
This commit is contained in:
parent
4535cd1827
commit
73892701e8
@ -9,10 +9,10 @@
|
||||
|
||||
const assert = require('assert');
|
||||
const path = require('path');
|
||||
const AsyncEmitter = require('bevent');
|
||||
const Logger = require('blgr');
|
||||
const {Lock} = require('bmutex');
|
||||
const encoding = require('bbuf/lib/encoding');
|
||||
const AsyncEmitter = require('../utils/asyncemitter');
|
||||
const Network = require('../protocol/network');
|
||||
const ChainDB = require('./chaindb');
|
||||
const common = require('./common');
|
||||
|
||||
@ -1,440 +0,0 @@
|
||||
/*!
|
||||
* asyncemitter.js - event emitter which resolves promises.
|
||||
* Copyright (c) 2014-2017, Christopher Jeffrey (MIT License).
|
||||
* https://github.com/bcoin-org/bcoin
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
const assert = require('assert');
|
||||
|
||||
/**
|
||||
* Async Emitter
|
||||
* @alias module:utils.AsyncEmitter
|
||||
* @see EventEmitter
|
||||
*/
|
||||
|
||||
class AsyncEmitter {
|
||||
/**
|
||||
* Create an async emitter.
|
||||
* @constructor
|
||||
*/
|
||||
|
||||
constructor() {
|
||||
this._events = Object.create(null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a listener.
|
||||
* @param {String} type
|
||||
* @param {Function} handler
|
||||
*/
|
||||
|
||||
addListener(type, handler) {
|
||||
return this._push(type, handler, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a listener.
|
||||
* @param {String} type
|
||||
* @param {Function} handler
|
||||
*/
|
||||
|
||||
on(type, handler) {
|
||||
return this.addListener(type, handler);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a listener to execute once.
|
||||
* @param {String} type
|
||||
* @param {Function} handler
|
||||
*/
|
||||
|
||||
once(type, handler) {
|
||||
return this._push(type, handler, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Prepend a listener.
|
||||
* @param {String} type
|
||||
* @param {Function} handler
|
||||
*/
|
||||
|
||||
prependListener(type, handler) {
|
||||
return this._unshift(type, handler, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Prepend a listener to execute once.
|
||||
* @param {String} type
|
||||
* @param {Function} handler
|
||||
*/
|
||||
|
||||
prependOnceListener(type, handler) {
|
||||
return this._unshift(type, handler, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Push a listener.
|
||||
* @private
|
||||
* @param {String} type
|
||||
* @param {Function} handler
|
||||
* @param {Boolean} once
|
||||
*/
|
||||
|
||||
_push(type, handler, once) {
|
||||
assert(typeof type === 'string', '`type` must be a string.');
|
||||
|
||||
if (!this._events[type])
|
||||
this._events[type] = [];
|
||||
|
||||
this.emit('newListener', type, handler);
|
||||
|
||||
this._events[type].push(new Listener(handler, once));
|
||||
}
|
||||
|
||||
/**
|
||||
* Unshift a listener.
|
||||
* @param {String} type
|
||||
* @param {Function} handler
|
||||
* @param {Boolean} once
|
||||
*/
|
||||
|
||||
_unshift(type, handler, once) {
|
||||
assert(typeof type === 'string', '`type` must be a string.');
|
||||
|
||||
if (!this._events[type])
|
||||
this._events[type] = [];
|
||||
|
||||
this.emit('newListener', type, handler);
|
||||
|
||||
this._events[type].unshift(new Listener(handler, once));
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove a listener.
|
||||
* @param {String} type
|
||||
* @param {Function} handler
|
||||
*/
|
||||
|
||||
removeListener(type, handler) {
|
||||
assert(typeof type === 'string', '`type` must be a string.');
|
||||
|
||||
const listeners = this._events[type];
|
||||
|
||||
if (!listeners)
|
||||
return;
|
||||
|
||||
let index = -1;
|
||||
|
||||
for (let i = 0; i < listeners.length; i++) {
|
||||
const listener = listeners[i];
|
||||
if (listener.handler === handler) {
|
||||
index = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (index === -1)
|
||||
return;
|
||||
|
||||
splice(listeners, index);
|
||||
|
||||
if (listeners.length === 0)
|
||||
delete this._events[type];
|
||||
|
||||
this.emit('removeListener', type, handler);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set max listeners.
|
||||
* @param {Number} max
|
||||
*/
|
||||
|
||||
setMaxListeners(max) {
|
||||
assert(typeof max === 'number', '`max` must be a number.');
|
||||
assert(max >= 0, '`max` must be non-negative.');
|
||||
assert(Number.isSafeInteger(max), '`max` must be an integer.');
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove all listeners.
|
||||
* @param {String?} type
|
||||
*/
|
||||
|
||||
removeAllListeners(type) {
|
||||
if (arguments.length === 0) {
|
||||
this._events = Object.create(null);
|
||||
return;
|
||||
}
|
||||
|
||||
assert(typeof type === 'string', '`type` must be a string.');
|
||||
|
||||
delete this._events[type];
|
||||
}
|
||||
|
||||
/**
|
||||
* Get listeners array.
|
||||
* @param {String} type
|
||||
* @returns {Function[]}
|
||||
*/
|
||||
|
||||
listeners(type) {
|
||||
assert(typeof type === 'string', '`type` must be a string.');
|
||||
|
||||
const listeners = this._events[type];
|
||||
|
||||
if (!listeners)
|
||||
return [];
|
||||
|
||||
const result = [];
|
||||
|
||||
for (const {handler} of listeners)
|
||||
result.push(handler);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get listener count for an event.
|
||||
* @param {String} type
|
||||
*/
|
||||
|
||||
listenerCount(type) {
|
||||
assert(typeof type === 'string', '`type` must be a string.');
|
||||
|
||||
const listeners = this._events[type];
|
||||
|
||||
if (!listeners)
|
||||
return 0;
|
||||
|
||||
return listeners.length;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get event names.
|
||||
* @returns {String[]}
|
||||
*/
|
||||
|
||||
eventNames() {
|
||||
return Object.keys(this._events);
|
||||
}
|
||||
|
||||
/**
|
||||
* Emit an event synchronously.
|
||||
* @param {String} type
|
||||
* @param {...Object} args
|
||||
* @returns {Promise}
|
||||
*/
|
||||
|
||||
emit(type) {
|
||||
try {
|
||||
this._emit.apply(this, arguments);
|
||||
} catch (e) {
|
||||
if (type === 'error')
|
||||
throw e;
|
||||
|
||||
this._emit('error', e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Emit an event synchronously.
|
||||
* @private
|
||||
* @param {String} type
|
||||
* @param {...Object} args
|
||||
* @returns {Promise}
|
||||
*/
|
||||
|
||||
_emit(type) {
|
||||
assert(typeof type === 'string', '`type` must be a string.');
|
||||
|
||||
const listeners = this._events[type];
|
||||
|
||||
if (!listeners) {
|
||||
if (type === 'error') {
|
||||
const msg = arguments[1];
|
||||
|
||||
if (msg instanceof Error)
|
||||
throw msg;
|
||||
|
||||
const err = new Error(`Uncaught, unspecified "error" event. (${msg})`);
|
||||
err.context = msg;
|
||||
throw err;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
assert(listeners.length > 0);
|
||||
|
||||
let args = null;
|
||||
|
||||
for (let i = 0; i < listeners.length; i++) {
|
||||
const listener = listeners[i];
|
||||
const handler = listener.handler;
|
||||
|
||||
if (listener.once) {
|
||||
splice(listeners, i);
|
||||
if (listeners.length === 0)
|
||||
delete this._events[type];
|
||||
i -= 1;
|
||||
}
|
||||
|
||||
switch (arguments.length) {
|
||||
case 1:
|
||||
handler();
|
||||
break;
|
||||
case 2:
|
||||
handler(arguments[1]);
|
||||
break;
|
||||
case 3:
|
||||
handler(arguments[1], arguments[2]);
|
||||
break;
|
||||
case 4:
|
||||
handler(arguments[1], arguments[2], arguments[3]);
|
||||
break;
|
||||
default:
|
||||
if (!args) {
|
||||
args = new Array(arguments.length - 1);
|
||||
for (let j = 1; j < arguments.length; j++)
|
||||
args[j - 1] = arguments[j];
|
||||
}
|
||||
handler.apply(null, args);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Emit an event. Wait for promises to resolve.
|
||||
* @method
|
||||
* @param {String} type
|
||||
* @param {...Object} args
|
||||
* @returns {Promise}
|
||||
*/
|
||||
|
||||
async emitAsync(type) {
|
||||
try {
|
||||
await this._emitAsync.apply(this, arguments);
|
||||
} catch (e) {
|
||||
if (type === 'error')
|
||||
throw e;
|
||||
|
||||
await this._emitAsync('error', e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Emit an event. Wait for promises to resolve.
|
||||
* @private
|
||||
* @param {String} type
|
||||
* @param {...Object} args
|
||||
* @returns {Promise}
|
||||
*/
|
||||
|
||||
async _emitAsync(type) {
|
||||
assert(typeof type === 'string', '`type` must be a string.');
|
||||
|
||||
const listeners = this._events[type];
|
||||
|
||||
if (!listeners) {
|
||||
if (type === 'error') {
|
||||
const msg = arguments[1];
|
||||
|
||||
if (msg instanceof Error)
|
||||
throw msg;
|
||||
|
||||
const err = new Error(`Uncaught, unspecified "error" event. (${msg})`);
|
||||
err.context = msg;
|
||||
throw err;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
assert(listeners.length > 0);
|
||||
|
||||
let args = null;
|
||||
|
||||
for (let i = 0; i < listeners.length; i++) {
|
||||
const listener = listeners[i];
|
||||
const handler = listener.handler;
|
||||
|
||||
if (listener.once) {
|
||||
splice(listeners, i);
|
||||
if (listeners.length === 0)
|
||||
delete this._events[type];
|
||||
i -= 1;
|
||||
}
|
||||
|
||||
switch (arguments.length) {
|
||||
case 1:
|
||||
await handler();
|
||||
break;
|
||||
case 2:
|
||||
await handler(arguments[1]);
|
||||
break;
|
||||
case 3:
|
||||
await handler(arguments[1], arguments[2]);
|
||||
break;
|
||||
case 4:
|
||||
await handler(arguments[1], arguments[2], arguments[3]);
|
||||
break;
|
||||
default:
|
||||
if (!args) {
|
||||
args = new Array(arguments.length - 1);
|
||||
for (let j = 1; j < arguments.length; j++)
|
||||
args[j - 1] = arguments[j];
|
||||
}
|
||||
await handler.apply(null, args);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Event Listener
|
||||
* @ignore
|
||||
* @property {Function} handler
|
||||
* @property {Boolean} once
|
||||
*/
|
||||
|
||||
class Listener {
|
||||
/**
|
||||
* Create an event listener.
|
||||
* @constructor
|
||||
* @param {Function} handler
|
||||
* @param {Boolean} once
|
||||
*/
|
||||
|
||||
constructor(handler, once) {
|
||||
assert(typeof handler === 'function', '`handler` must be a function.');
|
||||
assert(typeof once === 'boolean', '`once` must be a function.');
|
||||
this.handler = handler;
|
||||
this.once = once;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Helpers
|
||||
*/
|
||||
|
||||
function splice(list, i) {
|
||||
if (i === 0) {
|
||||
list.shift();
|
||||
return;
|
||||
}
|
||||
|
||||
let k = i + 1;
|
||||
|
||||
while (k < list.length)
|
||||
list[i++] = list[k++];
|
||||
|
||||
list.pop();
|
||||
}
|
||||
|
||||
/*
|
||||
* Expose
|
||||
*/
|
||||
|
||||
module.exports = AsyncEmitter;
|
||||
@ -10,7 +10,6 @@
|
||||
* @module utils
|
||||
*/
|
||||
|
||||
exports.AsyncEmitter = require('./asyncemitter');
|
||||
exports.binary = require('./binary');
|
||||
exports.fixed = require('./fixed');
|
||||
exports.Heap = require('./heap');
|
||||
|
||||
@ -7,7 +7,7 @@
|
||||
'use strict';
|
||||
|
||||
const assert = require('assert');
|
||||
const AsyncEmitter = require('../utils/asyncemitter');
|
||||
const AsyncEmitter = require('bevent');
|
||||
|
||||
/**
|
||||
* Node Client
|
||||
|
||||
@ -27,6 +27,7 @@
|
||||
"bclient": "^0.0.1",
|
||||
"bcrypto": "^0.0.1",
|
||||
"bdb": "^0.0.1",
|
||||
"bevent": "^0.0.1",
|
||||
"bfile": "^0.0.1",
|
||||
"bfilter": "^0.0.1",
|
||||
"binet": "^0.0.1",
|
||||
|
||||
Loading…
Reference in New Issue
Block a user