Module: util/one-event-source

Helper function that creates an object that can serve as an event source that is used in an API-object property.

Events are all over the place in Javascript, with several major themes:

We only need a very limited subset of those features. Nether things like event bubbling nor lots of different API functions to subscribe and control events are necessary. The specialized (exactly one per event type) "on-" event handlers, without event names (i.e. they are implicitly named by the property they are made available under) comes closest, but is too limited, since 1) it allows only one handler, 2) accidentally overwriting an existing handler is possible, making some kinds of code errors harder to find.

Instead, we use an event source that allows more than one event handler, but which does not use a special Event class and has only a limited set of API functions. In addition, each event source (object) will be responsible for exactly one kind of event only, just like the specialized DOM "on-" event types.

The goal is to expose an appropriately named event source object with methods to subscribe and unsubscribe to events for that event. The method to emit events should not be available on the event source object exposed as part of an API, but remain visible only to the code hidden behind that API.



function createSomethingAsynchronous () {
    // The two OneEventSource objects REMAIN PRIVATE
    const onDataEventSource = createEventSource();
    const onErrorEventSource = createEventSource();

    // If this functionality is needed
    onDataEventSource.onListenerChange = (oldSize, newSize) => {
        // Start a process as soon as there is at least one listener
        // Stop a process if there is no listener

    function receiveAsynchronousResults(data, err) {
        if (err) {
            return onErrorEventSource.dispatch(err);


    // Do something that periodically calls receiveAsynchronousResults()

    // The two OneEventSourceConsumer objects ARE EXPORTED
    return {
        onData: onDataEventSource.consumer,
        onError: onErrorEventSource.consumer

const someObj = createSomethingAsynchronous();

someObj.onData.addListener(data => processData(data));
someObj.onError.addListener(error => console.log(error));


(static) createEventSource() → {OneEventSource}

Creates an OneEventSource with an OneEventSourceConsumer object with public methods for consumers of the event, and non-public methods for the code that is the source of the events and is publishing the interface.


Returns an OneEventSource object

Type: OneEventSource