All Projects → trutoo → event-bus

trutoo / event-bus

Licence: MIT License
Typesafe cross-platform pubsub event bus ensuring reliable communication between fragments and micro frontends.

Programming Languages

typescript
32286 projects
javascript
184084 projects - #8 most used programming language

Projects that are alternatives of or similar to event-bus

megaphone
Hear ye, hear ye 📣
Stars: ✭ 15 (+0%)
Mutual labels:  pubsub
php-pubsub
A PHP abstraction for the pub-sub pattern
Stars: ✭ 36 (+140%)
Mutual labels:  pubsub
httpubsub
Basic Pub/Sub over HTTP/S
Stars: ✭ 22 (+46.67%)
Mutual labels:  pubsub
pyroclastic
Functional dataflow through composable computations
Stars: ✭ 17 (+13.33%)
Mutual labels:  typesafe
safe-android-fragments
[DEPRECATED] The goal of this example is to show you a way to prevent the fragment state loss and consequently avoid potential crashes of your app using kotlin extensions and android support library (version up to 26.0.0).
Stars: ✭ 15 (+0%)
Mutual labels:  fragments
shamash
Autoscaling for Google Cloud Dataproc
Stars: ✭ 31 (+106.67%)
Mutual labels:  pubsub
js-libp2p-gossipsub
JavaScript implementation of Gossipsub
Stars: ✭ 76 (+406.67%)
Mutual labels:  pubsub
apollo-progressive-fragment-matcher
A smart alternative to the introspection fragment matcher.
Stars: ✭ 21 (+40%)
Mutual labels:  fragments
mini-project
An android eCommerce application for students through which they can buy and sell used goods .
Stars: ✭ 26 (+73.33%)
Mutual labels:  fragments
svelte-local-storage-store
Adds pub/sub to local storage.
Stars: ✭ 194 (+1193.33%)
Mutual labels:  pubsub
mros2
agent-less and lightweight communication library compatible with rclcpp for embedded devices
Stars: ✭ 72 (+380%)
Mutual labels:  pubsub
build-your-own-platform-with-knative
Knativeのコンポーネントを理解しながらFaaSプラットフォームをDIYするワークショップです
Stars: ✭ 43 (+186.67%)
Mutual labels:  pubsub
web-haskell-graphql-postgres-boilerplate
Modern webserver in Haskell: Graphql + Postgresql + Authentication + DB migration + Dotenv and more
Stars: ✭ 114 (+660%)
Mutual labels:  typesafe
sol
Lightweight MQTT broker, written from scratch. IO is handled by a super simple event loop based upon the most common IO multiplexing implementations.
Stars: ✭ 72 (+380%)
Mutual labels:  pubsub
poetimizely
Generate Kotlin type safe accessors for Optimizely experiments and features
Stars: ✭ 17 (+13.33%)
Mutual labels:  typesafe
SpockAdb
Spock Adb Plugin Helps you to have full control of your project
Stars: ✭ 102 (+580%)
Mutual labels:  fragments
typesql
TypeSQL - Generate Typescript API from raw MySQL queries. Compatible with Deno and Node.
Stars: ✭ 37 (+146.67%)
Mutual labels:  typesafe
react-bus
A global event emitter for react.
Stars: ✭ 34 (+126.67%)
Mutual labels:  pubsub
opal
Policy and data administration, distribution, and real-time updates on top of Open Policy Agent
Stars: ✭ 459 (+2960%)
Mutual labels:  pubsub
qiankun-simple-main-app-web
react微前端聚合系统(qiankun.js)
Stars: ✭ 19 (+26.67%)
Mutual labels:  micro-frontends

Event Bus

Continuous Delivery Coverage Status GitHub release (latest by date) [npm downloads] npm bundle size License

Simple typesafe cross-platform pubsub communication between different single page applications, web components, fragments, or services. Purposefully built for a micro frontend architecture with a distributed responsibility for deployment. Allowing for framework agnostic and safe communication between different implementations and version. Catch those pesky event errors early ❤️.


Table of Contents


Purpose

This project was created to improve upon some of the deficits CustomEvents has in relation to event communication between separate web components or fragments, which often is the preferred way of communication. Below points are some of the benefits of using this pub-sub solution over the native solution.

  1. Each fragment can register on a custom named event channel with an optional JSON schema draft-04 to ensure all future traffic on that channel follows the specification. This means incompatibilities are reported before any payload is sent and every payload will be typesafe.

  2. The individual event channels stores the last payload allowing new fragments or asynchronous subscriptions to ask for a replay of the last payloads data as a first callback.

  3. CustomEvents require a polyfill to work in older browsers, while this project works out of the box with Internet Explorer 11.

Installation

Either add the Trutoo GitHub Package registry to your .npmrc

@trutoo:registry=https://npm.pkg.github.com/trutoo

or install using the registry flag

npm install @trutoo/event-bus --registry=https://npm.pkg.github.com/trutoo

or install from the npm registry @trutoo/event-bus

npm install @trutoo/event-bus

Then either import the side effects only exposing a eventBus global instance.

import '@trutoo/event-bus';
// or
require('@trutoo/event-bus');

eventBus.register(/*...*/);

or import the EventBus class to create your own instance.

import { EventBus } from '@trutoo/event-bus';
// or
const { EventBus } = require('@trutoo/event-bus');

const myEventBus = new EventBus();
myEventBus.register(/*...*/);

or using the UMD module and instance.

<script src="https://unpkg.com/@trutoo/event-bus@latest/dist/index.umd.min.js"></script>
<script>
  eventBus.register(/*...*/);
  // or
  const myEventBus = new EventBus.EventBus();
  myEventBus.register(/*...*/);
</script>

Usage

Simple event bus registration with communication between a standard web component and a React component, as the event bus is framework agnostic. In addition a basic JSON schema draft-04 is used to restrict communication to a single boolean. Below outlines the basic usage, but can be can also be seen under /docs folder.

JSON Schema

{
  "type": "boolean"
}

Fragment One - Web Component

class PublisherElement extends HTMLElement {
  connectedCallback() {
    eventBus.register('namespace:eventName', { type: 'boolean' });
    this.render();
    this.firstChild && this.firstChild.addEventListener('click', this.send);
  }
  send() {
    eventBus.publish('namespace:eventName', true);
  }
  render() {
    this.innerHTML = `<button type="button">send</button>`;
  }
  disconnectedCallback() {
    this.firstChild && this.firstChild.removeEventListener('click', this.send);
  }
}

Fragment Two - React Component

import React, { useState, useEffect } from 'react';

function SubscriberComponent() {
  const [isFavorite, setFavorite] = useState(false);

  useEffect(() => {
    function handleSubscribe(favorite: boolean) {
      setFavorite(favorite);
    }
    eventBus.register('namespace:eventName', { type: 'boolean' });
    const sub = eventBus.subscribe<boolean>('namespace:eventName', handleSubscribe);
    return function cleanup() {
      sub.unsubscribe();
    };
  }, []);

  return isFavorite ? 'This is a favorite' : 'This is not interesting';
}

Advanced Schema

Following is an example of a more a more complex use-case with a larger JSON schema draft-04 and registration on multiple channels.

JSON Schema

{
  "type": "object",
  "required": [
    "name",
    "amount",
    "price"
  ],
  "properties": {
    "name": {
      "type": "string"
    },
    "amount": {
      "type": "string"
    },
    "price": {
      "type": "number"
    },
    "organic": {
      "type": "boolean"
    },
    "stores": {
      "type": "array",
      "items": {
        "type": "object",
        "required": [],
        "properties": {
          "name": {
            "type": "string"
          },
          "url": {
            "type": "string"
          }
        }
      }
    }
  }
}

Fragment - Angular Component

import { Component } from '@angular/core';
import eventSchema from './event-schema.json';

@Component({
  selector: 'app-store',
  template: '<button (onClick)="onSend()">Add to cart</button>',
})
export class StoreComponent implements OnInit, OnDestroy {
  private subs: { unsubscribe(): void }[] = [];

  ngOnInit() {
    // Register on add to cart channel
    eventBus.register('store:addToCart', eventSchema);

    // No need to register if no schema is required
    this.sub.push(eventBus.subscribe<boolean>('store:newDeals', this.onNewDeals));
  }

  onNewDeals() {
    /* handle new deals ... */
  }

  onSend() {
    eventBus.publish('store:addToCart', {
      name: 'Milk',
      amount: '1000 ml',
      price: 0.99,
      organic: true,
      stores: [
        {
          name: 'ACME Food AB',
          url: 'acme-food.com'
        }
      ]
    });
  }

  ngOnDestroy() {
    this.subs.forEach(sub => sub.unsubscribe());
  }
}

API

Register

Register a schema for the specified event type and equality checking on subsequent registers. Subsequent registers must use an equal schema or an error will be thrown.

register(channel: string, schema: object): boolean;

Parameters

Name Type Description
channel string name of event channel to register schema to
schema object all communication on channel must follow this schema

Returns - returns true if event channel already existed of false if a new one was created.


Unregister

Unregister the schema for the specified event type if channel exists.

unregister(channel: string): boolean;

Parameters

Name Type Description
channel string name of event channel to unregister schema from

Returns - returns true if event channel existed and an existing schema was removed.


Subscribe

Subscribe to an event channel triggering callback on received event matching type, with an optional replay of last event at initial subscription. The channel may be the wildcard '*' to subscribe to all channels.

subscribe<T>(channel: string, callback: Callback<T>): { unsubscribe(): void };

subscribe<T>(channel: string, replay: boolean, callback: Callback<T>): { unsubscribe(): void };

Callbacks will be fired when event is published on a subscribed channel with the argument:

{
  channel: string,
  payload: T,
}

Parameters

Name Type Description
channel string name of event channel to receive data from
replay boolean=false flag indicating if initial description should return last event
callback function function executed on when event channel receives new data

Returns - object containing an unsubscribe method


Publish

Publish to event channel with an optional payload triggering all subscription callbacks.

publish<T>(channel: string, payload?: T): void;

Parameters

Name Type Description
channel string name of event channel to send payload on
payload any payload to be sent

Returns - void


Get Latest

Get the latest published payload on the specified event channel.

getLatest<T>(channel: string): T | undefined;

Parameters

Name Type Description
channel string name of the event channel to fetch the latest payload from

Returns - the latest payload or undefined


Get Schema

Get the schema registered on the specified event channel.

getSchema<T>(channel: string): any | undefined;

Parameters

Name Type Description
channel string name of the event channel to fetch the schema from

Returns - the schema or undefined

Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].