Skip to content

knpwrs/listenator

Repository files navigation

listenator

TypeScript Dependency Status devDependency Status Build Status Npm Version Deno License Badges

Turn any event stream into an async generator. Inspired by eventChannel from redux-saga. Includes TypeScript typings.

Usage

This package has one default export, listenator, which takes a function as an argument. That function should itself take one or two arguments, emit and optionally done. listenator returns an Asynchronous Generator which yields anything passed to emit. Calling done will flush any queued events and then complete the generator.

Note that this package is not transpiled to ES5. It targets ES2018. If you need to support older browsers or Node versions you will need to process it with Babel or TypeScript.

Examples

Simple

import listenator from 'listenator';

const numbers = listenator((emit, done) => {
  emit(1);
  emit(2);
  emit(3);
  done();
});

// In an async context this will log 1, 2, and then 3:
for await (const num of numbers) {
  console.log(num);
}

// Execution picks up here because `done` was called
console.log('Hello!');

DOM Events

import listenator from 'listenator';

const clicks = listenator((emit) => {
  const button = document.getElementById('my-btn');
  button.addEventListener('click', emit);
});

// In an async context this will log every click event from clicking on #my-btn
for await (const click of clicks) {
  console.log(num);
}

Node Events

import listenator from 'listenator';
import EventEmitter from 'events';

class MyEmitter extends EventEmitter {}

const myEmitter = new MyEmitter();

const events = listenator((emit) => {
  myEmitter.on('event', () => {
    console.log('an event occurred!');
  });
});

myEmitter.emit('event', 'foo');

// In an async context:
for await (const event of events) {
  console.log(event); // Logs 'foo', and then all future emits
}

Multiple Arguments

Just pass an array and destructure it on the way out:

import listenator from 'listenator';

const numbers = listenator((emit) => {
  emit([1, 2, 3]);
});

// In an async context:
for await (const [x, y, z] of numbers) {
  console.log(`(${x}, ${y}, ${z})`);
}

Deno

import listenator from 'https://deno.land/x/listenator/mod.ts';

const numbers = listenator((emit, done) => {
  emit(1);
  emit(2);
  emit(3);
  done();
});

// In an async context this will log 1, 2, and then 3:
for await (const num of numbers) {
  console.log(num);
}

// Execution picks up here because `done` was called
console.log('Hello!');

Contributing

Please run make init in the root directory before making any commits so the commit-msg hook can validate your commit messages.

Prior Art

Other Modules

License

MIT

About

Turn any event stream into an async iterator

Resources

License

Stars

Watchers

Forks

Packages

No packages published