@foursk/eh
TypeScript icon, indicating that this package has built-in type declarations

1.0.1 • Public • Published

eh - simple event manager

Eh provides simple and flexible event management.

For any questions, comments, feedback or hi-saying feel free to hit me up: orangilboa@gmail.com

v 1.0.0 added simple state management

v 0.1.5: updated packages

Installation

npm i -s @foursk/eh

Examples

Basic

// declare an event name
const MY_EVENT = 'myEvent';

// create a handler for your event
function myEventHandler(data, eventName) {
    console.log(`${eventName} ${data}`);
}

// register you handler with the relevant event name
eh.register(MY_EVENT, myEventHandler);

// fire/raise your event, with relevant data
eh.fire(MY_EVENT, 3);

// Output: myEvent 3

Event instances

Using EhEvent, you can create typed event instances using classes or object instances.

Using a class:

// declare a class you'd like to pass as an event
class Person {
    /**
     * JDoc used for intellisense
     * @param {string} name 
     * @param {number} age 
     */
    constructor(name, age) {
        this.name = name;
        this.age = age;
    }
}

// use the EhEvent.fromClass instantiator, and pass it your class
const PersonEvent = EhEvent.fromClass(Person);

// API is similar to global eh, but without event names
// register for event through instance
PersonEvent.register(np => console.log(`${np.name} is ${np.age} years old`));

// fire event through instance
PersonEvent.fire(new Person('Dan', 100));

// Output: Dan is 100 years old

Using an object instance:

// use the EhEvent.fromInstance instantiator, with a template instance. 
// use redundant data of desired type to "inform" intellisense
const imaginaryConcertEvent = EhEvent.fromInstance({ artist: '' });

imaginaryConcertEvent.register(({ artist }) => console.log(`${artist} is performing tonight!`));

imaginaryConcertEvent.fire(({ artist: 'Paul McCartney' }));

// Output: Paul McCartney is performing tonight!

EhEvent usage comes with pretty comfortable intellisense support

alt text

Promises

A fired eh event returns a promise, that resolves after all handlers have been called

const eCalculate = EhEvent.fromInstance({ someNumber: 0 });

// create a calculator using the "leisure function" createHandler
const powCalculator = eCalculate.createHandler(data => {
    data.someNumber *= data.someNumber;
});

// register your calculator
eCalculate.register(powCalculator);

// fire returns a promise containing the final object
eCalculate.fire({ someNumber: 5 })
    .then(console.log); //output: { someNumber: 25 }

// this syntax works with async/await as well
async function cannon() {
//  intellisense ↓
    const { someNumber } = await eCalculate.fire({ someNumber: 6 });
    console.log('someNumber', someNumber); //output: someNumber 36
}

We use this for object enrichments or mutations

// relevant for mutations or enrichments as well
const eEnrich = EhEvent.fromInstance({});

// enrichment 1
eEnrich.register(data => {
    data.now = new Date;
});

// enrichment 2
eEnrich.register(data => {
    data.weather = 'sunny';
});

// promise will resolved with enriched object
eEnrich.fire({}).then(console.log); //output: { now: 2020-02-22T18:59:45.693Z, weather: 'sunny' }

Simple State Mgmt

With EhState you simply manage states. EhState requires an initial state object to initialize, and functions very similarly to EhEvent, with 3 main differences:

  1. EhState maintains a state object
  2. All event handlers are immediately invoked upon registration with the current state
  3. Fire function updates or mutates state

Example:

// Initialize EhState with the initial desired state
const loadedState = EhState.fromInitialState({ isLoaded: false });

// handler will be fired as soon as it is registered, with the current state
loadedState.register(state => {
    console.count('state handler A');
    console.log('state', state);
    /**
     * First invocation with initial state
     * Further invocations due to fire function calls
     * Output:
     * state handler A: 1
     * state { isLoaded: false }
     * state handler A: 2
     * state { isLoaded: true }
     * state handler A: 3
     * state { isLoaded: true, count: 1 }
     */
});

// fire will merge the argument into the current stored state (using Object.assign), and then invoke all handlers (like EhEvent)
loadedState.fire({ isLoaded: true });

// handler will be fired as soon as it is registered, with the current state
loadedState.register(state => {
    console.count('state handler B');
    console.log('state', state);
    /**
     * First invocation with current state (after first fire)
     * Second invocation with second fire (mutation)
     * Output:     
     * state handler B: 1
     * state { isLoaded: true }
     * state handler B: 2
     * state { isLoaded: true, count: 1 }
     */
});

// Unnested mutations to state are allowed. Handlers will be invoked
// with the object results from Object.assign of current state and your argument
loadedState.fire({ count: 1 });

React

This shows how to use eh in React class components

// use the EhEvent.fromInstance instantiator to use a simple object as an event template
const eventChangeColor = EhEvent.fromInstance({ color: "" });

class Picker extends Component {
  constructor(props) {
    super(props);

    // create event-firing-functions ("cannons") for buttons
    this.cannonPickBlue = () => eventChangeColor.fire({ color: "blue" });
    this.cannonPickRed = () => eventChangeColor.fire({ color: "red" });
  }

  render() {
    return (
      <div className="picker">
        <button onClick={this.cannonPickBlue}>Blue</button>
        <button onClick={this.cannonPickRed}>Red</button>
      </div>
    );
  }
}

class ColorDisplay extends Component {
  constructor(props) {
    super(props);
    this.state = { color: "yellow" };

    // register a handler that updates state
    eventChangeColor.register(({ color }) => this.setState({ color }));
  }

  render() {
    return (
      <div className="display" style={{ backgroundColor: this.state.color }} />
    );
  }
}

Full example on CodeSandbox

Edit Eh React Basic Example

Readme

Keywords

Package Sidebar

Install

npm i @foursk/eh

Weekly Downloads

1

Version

1.0.1

License

ISC

Unpacked Size

26.1 kB

Total Files

10

Last publish

Collaborators

  • foursk