
Security News
Attackers Are Hunting High-Impact Node.js Maintainers in a Coordinated Social Engineering Campaign
Multiple high-impact npm maintainers confirm they have been targeted in the same social engineering campaign that compromised Axios.
Zero-dependency universal connectors between Events, EventTargets and AsyncIterables with lightweight operators.
Debounce rapid events:
import { fromEventEmitter, debounceTime, pipe } from 'uniconnect';
const it = pipe(fromEventEmitter(emitter, 'data'), debounceTime(200));
for await (const v of it) console.log(v);
Throttle with trailing:
import { fromEventEmitter, throttleTime, pipe } from 'uniconnect';
const it = pipe(fromEventEmitter(emitter, 'data'), throttleTime(500, { leading: true, trailing: true }));
for await (const v of it) console.log(v);
Merge two streams:
import { merge, take } from 'uniconnect';
for await (const v of take(merge(streamA, streamB), 5)) console.log(v);
Zip two streams:
import { zip, take } from 'uniconnect';
for await (const pair of take(zip(streamA, streamB), 3)) console.log(pair);
Accumulate with scan:
import { scan, pipe } from 'uniconnect';
const sums = pipe(numbers, scan((acc, x) => acc + x, 0));
for await (const s of sums) console.log(s);
Zero-dependency universal connectors between Events, EventTargets and AsyncIterables with lightweight operators. Node 18+.
Universal, zero-dependency building blocks to connect Node/EventTarget event sources with modern AsyncIterables and compose them via tiny operators.
EventEmitter and EventTarget to AsyncIterablepipe() and tiny operators: map, filter, take, buffertoEventEmitter()AbortControllerimport { fromEventEmitter, pipe, take } from 'uniconnect';
import { EventEmitter } from 'node:events';
const ee = new EventEmitter();
const iterable = pipe(fromEventEmitter(ee, 'data'), take(3));
(async () => {
ee.emit('data', 'a');
ee.emit('data', 'b');
ee.emit('data', 'c');
})();
for await (const v of iterable) console.log(v);
npm install uniconnect
import { fromEventEmitter, take, pipe } from 'uniconnect';
import { EventEmitter } from 'node:events';
const emitter = new EventEmitter();
async function main() {
const it = pipe(
fromEventEmitter(emitter, 'data'),
take(3),
);
(async () => {
emitter.emit('data', 1);
emitter.emit('data', 2);
emitter.emit('data', 3);
emitter.emit('data', 4);
})();
for await (const v of it) {
console.log('got', v);
}
}
main();
import { fromEventTarget } from 'uniconnect';
const ac = new AbortController();
const { signal } = ac;
const target = new EventTarget();
const iterable = fromEventTarget(target, 'ping', { signal });
(async () => {
target.dispatchEvent(new Event('ping'));
ac.abort();
})();
for await (const ev of iterable) {
console.log('event', ev.type);
}
import { pipe, map, filter, buffer } from 'uniconnect';
const processed = pipe(
sourceIterable,
map(x => x * 2),
filter(x => x % 3 === 0),
buffer(5),
);
for await (const chunk of processed) {
// chunks of size 5
}
import { retryIterable } from 'uniconnect';
const src = () => someFlakyAsyncIterable();
for await (const v of retryIterable(src, { attempts: 5, delay: 200 })) {
// values...
}
fromEventTarget(target, eventName, { signal }) -> AsyncIterable
EventTarget (e.g. DOM/EventTarget polyfills) to an AsyncIterable.target: EventTarget, eventName: string, options?: { signal?: AbortSignal }AsyncIterable<Event>fromEventEmitter(emitter, eventName, { signal }) -> AsyncIterable
EventEmitter to an AsyncIterable.emitter: EventEmitter, eventName: string, options?: { signal?: AbortSignal }AsyncIterable<any>toEventEmitter(asyncIterable, emitter, eventName) -> Promise<void>
AsyncIterable and re-emits values as events on the target emitter.toAsyncIterable(source, eventName, options)
fromEventTarget or fromEventEmitter accordingly.pipe(iterable, ...ops) -> AsyncIterable
Operators
map(fn), filter(fn), take(n), buffer(n)scan(reducer, seed?), distinctUntilChanged(equals?)debounceTime(ms), throttleTime(ms, { leading, trailing })Utilities
retryIterable(factory, { attempts, delay }), timeout(ms, { error? })import { toEventEmitter } from 'uniconnect';
import { EventEmitter } from 'node:events';
async function* src() { yield 1; yield 2; }
const ee = new EventEmitter();
ee.on('data', v => console.log('data', v));
await toEventEmitter(src(), ee, 'data');
AbortController via options.signal.error event will propagate the error to the iterator.import { fromEventTarget } from 'uniconnect';
const ac = new AbortController();
const iterable = fromEventTarget(new EventTarget(), 'tick', { signal: ac.signal });
const it = iterable[Symbol.asyncIterator]();
ac.abort(); // iterator will close with AbortError
EventEmitter supported via standard methods: on/off or addListener/removeListener and emit.EventTarget requires addEventListener/removeEventListener.import() or configure transpilation.node:test) for any new functionality.npm test
Test files live under test/ and use the .test.mjs suffix.
MAJOR.MINOR.PATCH.npm version patchnpm version minornpm version majornpm publish --access public
git push origin main --follow-tags
MIT
See GitHub Releases for notable changes.
FAQs
Zero-dependency universal connectors between Events, EventTargets and AsyncIterables with lightweight operators.
We found that uniconnect demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Security News
Multiple high-impact npm maintainers confirm they have been targeted in the same social engineering campaign that compromised Axios.

Security News
Axios compromise traced to social engineering, showing how attacks on maintainers can bypass controls and expose the broader software supply chain.

Security News
Node.js has paused its bug bounty program after funding ended, removing payouts for vulnerability reports but keeping its security process unchanged.