First adaptation pass

This commit is contained in:
2025-11-06 00:01:59 +01:00
parent 5b1fd847c2
commit 6b883f8126
112 changed files with 44142 additions and 953 deletions
+1 -1
View File
@@ -8,7 +8,7 @@ npm install bare-events
## Usage
``` js
```js
const EventEmitter = require('bare-events')
const e = new EventEmitter()
+95 -72
View File
@@ -1,24 +1,24 @@
const errors = require('./lib/errors')
class EventListener {
constructor () {
constructor() {
this.list = []
this.count = 0
}
append (ctx, name, fn, once) {
append(ctx, name, fn, once) {
this.count++
ctx.emit('newListener', name, fn) // Emit BEFORE adding
this.list.push([fn, once])
}
prepend (ctx, name, fn, once) {
prepend(ctx, name, fn, once) {
this.count++
ctx.emit('newListener', name, fn) // Emit BEFORE adding
this.list.unshift([fn, once])
}
remove (ctx, name, fn) {
remove(ctx, name, fn) {
for (let i = 0, n = this.list.length; i < n; i++) {
const l = this.list[i]
@@ -35,7 +35,7 @@ class EventListener {
}
}
removeAll (ctx, name) {
removeAll(ctx, name) {
const list = [...this.list]
this.list = []
@@ -48,7 +48,7 @@ class EventListener {
this.count -= list.length
}
emit (ctx, name, ...args) {
emit(ctx, name, ...args) {
const list = [...this.list]
for (let i = 0, n = list.length; i < n; i++) {
@@ -56,32 +56,35 @@ class EventListener {
if (l[1] === true) this.remove(ctx, name, l[0])
l[0].call(ctx, ...args)
Reflect.apply(l[0], ctx, args)
}
return list.length > 0
}
}
function appendListener (ctx, name, fn, once) {
function appendListener(ctx, name, fn, once) {
if (ctx._events === undefined) ctx._events = Object.create(null)
const e = ctx._events[name] || (ctx._events[name] = new EventListener())
e.append(ctx, name, fn, once)
return ctx
}
function prependListener (ctx, name, fn, once) {
function prependListener(ctx, name, fn, once) {
if (ctx._events === undefined) ctx._events = Object.create(null)
const e = ctx._events[name] || (ctx._events[name] = new EventListener())
e.prepend(ctx, name, fn, once)
return ctx
}
function removeListener (ctx, name, fn) {
function removeListener(ctx, name, fn) {
if (ctx._events === undefined) return ctx
const e = ctx._events[name]
if (e !== undefined) e.remove(ctx, name, fn)
return ctx
}
function throwUnhandledError (...args) {
function throwUnhandledError(...args) {
let err
if (args.length > 0) err = args[0]
@@ -92,69 +95,77 @@ function throwUnhandledError (...args) {
Error.captureStackTrace(err, exports.prototype.emit)
}
queueMicrotask(() => { throw err })
queueMicrotask(() => {
throw err
})
}
module.exports = exports = class EventEmitter {
constructor () {
constructor() {
this._events = Object.create(null)
}
addListener (name, fn) {
addListener(name, fn) {
return appendListener(this, name, fn, false)
}
addOnceListener (name, fn) {
addOnceListener(name, fn) {
return appendListener(this, name, fn, true)
}
prependListener (name, fn) {
prependListener(name, fn) {
return prependListener(this, name, fn, false)
}
prependOnceListener (name, fn) {
prependOnceListener(name, fn) {
return prependListener(this, name, fn, true)
}
removeListener (name, fn) {
removeListener(name, fn) {
return removeListener(this, name, fn)
}
on (name, fn) {
on(name, fn) {
return appendListener(this, name, fn, false)
}
once (name, fn) {
once(name, fn) {
return appendListener(this, name, fn, true)
}
off (name, fn) {
off(name, fn) {
return removeListener(this, name, fn)
}
emit (name, ...args) {
if (name === 'error' && this._events.error === undefined) throwUnhandledError(...args)
emit(name, ...args) {
if (name === 'error' && this._events !== undefined && this._events.error === undefined) {
throwUnhandledError(...args)
}
if (this._events === undefined) return false
const e = this._events[name]
return e === undefined ? false : e.emit(this, name, ...args)
}
listeners (name) {
listeners(name) {
if (this._events === undefined) return []
const e = this._events[name]
return e === undefined ? [] : [...e.list]
}
listenerCount (name) {
listenerCount(name) {
if (this._events === undefined) return 0
const e = this._events[name]
return e === undefined ? 0 : e.list.length
}
getMaxListeners () {
getMaxListeners() {
return EventEmitter.defaultMaxListeners
}
setMaxListeners (n) {}
setMaxListeners(n) {}
removeAllListeners (name) {
removeAllListeners(name) {
if (arguments.length === 0) {
for (const key of Reflect.ownKeys(this._events)) {
if (key === 'removeListener') continue
@@ -175,10 +186,8 @@ exports.errors = errors
exports.defaultMaxListeners = 10
exports.on = function on (emitter, name, opts = {}) {
const {
signal
} = opts
exports.on = function on(emitter, name, opts = {}) {
const { signal } = opts
if (signal && signal.aborted) {
throw errors.OPERATION_ABORTED(signal.reason)
@@ -197,7 +206,7 @@ exports.on = function on (emitter, name, opts = {}) {
if (signal) signal.addEventListener('abort', onabort)
return {
next () {
next() {
if (events.length) {
return Promise.resolve({ value: events.shift(), done: false })
}
@@ -212,25 +221,23 @@ exports.on = function on (emitter, name, opts = {}) {
if (done) return onclose()
return new Promise((resolve, reject) =>
promises.push({ resolve, reject })
)
return new Promise((resolve, reject) => promises.push({ resolve, reject }))
},
return () {
return() {
return onclose()
},
throw (err) {
throw(err) {
return onerror(err)
},
[Symbol.asyncIterator] () {
[Symbol.asyncIterator]() {
return this
}
}
function onevent (...args) {
function onevent(...args) {
if (promises.length) {
promises.shift().resolve({ value: args, done: false })
} else {
@@ -238,7 +245,7 @@ exports.on = function on (emitter, name, opts = {}) {
}
}
function onerror (err) {
function onerror(err) {
if (promises.length) {
promises.shift().reject(err)
} else {
@@ -248,11 +255,11 @@ exports.on = function on (emitter, name, opts = {}) {
return Promise.resolve({ done: true })
}
function onabort () {
function onabort() {
onerror(errors.OPERATION_ABORTED(signal.reason))
}
function onclose () {
function onclose() {
emitter.off(name, onevent)
if (name !== 'error') emitter.off('error', onerror)
@@ -267,10 +274,8 @@ exports.on = function on (emitter, name, opts = {}) {
}
}
exports.once = function once (emitter, name, opts = {}) {
const {
signal
} = opts
exports.once = function once(emitter, name, opts = {}) {
const { signal } = opts
if (signal && signal.aborted) {
throw errors.OPERATION_ABORTED(signal.reason)
@@ -289,13 +294,13 @@ exports.once = function once (emitter, name, opts = {}) {
resolve(args)
})
function onerror (err) {
function onerror(err) {
emitter.off('error', onerror)
reject(err)
}
function onabort () {
function onabort() {
signal.removeEventListener('abort', onabort)
onerror(errors.OPERATION_ABORTED(signal.reason))
@@ -303,34 +308,52 @@ exports.once = function once (emitter, name, opts = {}) {
})
}
exports.forward = function forward (from, to, names, opts = {}) {
exports.forward = function forward(from, to, names, opts = {}) {
if (typeof names === 'string') names = [names]
const {
emit = to.emit.bind(to)
} = opts
const { emit = to.emit.bind(to) } = opts
const listeners = names.map((name) => function onevent (...args) {
emit(name, ...args)
const listeners = names.map(
(name) =>
function onevent(...args) {
emit(name, ...args)
}
)
to.on('newListener', (name) => {
const i = names.indexOf(name)
if (i !== -1 && to.listenerCount(name) === 0) {
from.on(name, listeners[i])
}
}).on('removeListener', (name) => {
const i = names.indexOf(name)
if (i !== -1 && to.listenerCount(name) === 0) {
from.off(name, listeners[i])
}
})
to
.on('newListener', (name) => {
const i = names.indexOf(name)
if (i !== -1 && to.listenerCount(name) === 0) {
from.on(name, listeners[i])
}
})
.on('removeListener', (name) => {
const i = names.indexOf(name)
if (i !== -1 && to.listenerCount(name) === 0) {
from.off(name, listeners[i])
}
})
}
exports.listenerCount = function listenerCount (emitter, name) {
exports.listenerCount = function listenerCount(emitter, name) {
return emitter.listenerCount(name)
}
exports.getMaxListeners = function getMaxListeners(emitter) {
if (typeof emitter.getMaxListeners === 'function') {
return emitter.getMaxListeners()
}
return exports.defaultMaxListeners
}
exports.setMaxListeners = function setMaxListeners(n, ...emitters) {
if (emitters.length === 0) exports.defaultMaxListeners = n
else {
for (const emitter of emitters) {
if (typeof emitter.setMaxListeners === 'function') {
emitter.setMaxListeners(n)
}
}
}
}
+10 -6
View File
@@ -1,5 +1,5 @@
module.exports = class EventEmitterError extends Error {
constructor (msg, code, fn = EventEmitterError, opts) {
constructor(msg, code, fn = EventEmitterError, opts) {
super(`${code}: ${msg}`, opts)
this.code = code
@@ -8,15 +8,19 @@ module.exports = class EventEmitterError extends Error {
}
}
get name () {
get name() {
return 'EventEmitterError'
}
static OPERATION_ABORTED (cause, msg = 'Operation aborted') {
return new EventEmitterError(msg, 'OPERATION_ABORTED', EventEmitterError.OPERATION_ABORTED, { cause })
static OPERATION_ABORTED(cause, msg = 'Operation aborted') {
return new EventEmitterError(msg, 'OPERATION_ABORTED', EventEmitterError.OPERATION_ABORTED, {
cause
})
}
static UNHANDLED_ERROR (cause, msg = 'Unhandled error') {
return new EventEmitterError(msg, 'UNHANDLED_ERROR', EventEmitterError.UNHANDLED_ERROR, { cause })
static UNHANDLED_ERROR(cause, msg = 'Unhandled error') {
return new EventEmitterError(msg, 'UNHANDLED_ERROR', EventEmitterError.UNHANDLED_ERROR, {
cause
})
}
}
+31 -4
View File
@@ -1,21 +1,37 @@
{
"name": "bare-events",
"version": "2.5.0",
"version": "2.8.1",
"description": "Event emitters for JavaScript",
"exports": {
".": "./index.js",
"./package": "./package.json",
".": {
"types": "./index.d.ts",
"default": "./index.js"
},
"./global": {
"types": "./global.d.ts",
"default": "./global.js"
},
"./web": {
"types": "./web.d.ts",
"default": "./web.js"
},
"./errors": "./lib/errors.js"
},
"files": [
"index.js",
"index.d.ts",
"global.js",
"global.d.ts",
"web.js",
"web.d.ts",
"lib"
],
"scripts": {
"test": "npm run lint && npm run test:bare && npm run test:node",
"test:bare": "bare test.js",
"test:node": "node test.js",
"lint": "standard"
"lint": "prettier . --check"
},
"repository": {
"type": "git",
@@ -28,7 +44,18 @@
},
"homepage": "https://github.com/holepunchto/bare-events#readme",
"devDependencies": {
"bare-abort-controller": "^1.0.0",
"brittle": "^3.3.2",
"standard": "^17.0.0"
"prettier": "^3.4.2",
"prettier-config-holepunch": "^2.0.0",
"uncaughts": "^1.1.1"
},
"peerDependencies": {
"bare-abort-controller": "*"
},
"peerDependenciesMeta": {
"bare-abort-controller": {
"optional": true
}
}
}