ryardley / ts-bus

A lightweight JavaScript/TypeScript event bus to help manage your application architecture.
MIT License
135 stars 8 forks source link

Possible interceptor / middleware #4

Closed evangelion1204 closed 5 years ago

evangelion1204 commented 5 years ago

Hi,

I can also do it myself but before investing time I wondered it would make sense to add support to listen to all events (not via wildcards - which actually not documented but saw it in your code) but through onAny of EventEmitter2. Typing here could be tricky because it could be any event but in case of just wanting to log the event it might be ok. For later an interceptor with the possibility to drop events or do similar functionality could be helpful too.

Reason is I want to build a bridge between client and server - I will give it a try with wildcards but in any case it might be more straight forward with the above mentioned approach.

ryardley commented 5 years ago

I have an example of a bridge over socket.io. I will try and publish it tonight if not it will have to be next week.

Basically you can get away with something like this on the client:

import React, { useEffect } from "react";

import socketIOClient from "socket.io-client";
import { EventBus } from "ts-bus";
import { useBus } from "ts-bus/react";
import { BusEvent } from "ts-bus/types";

function setupSocket(bus: EventBus) {
  const socket = socketIOClient("localhost:4000");

  bus.subscribe("**", event => {
    if (event.meta && event.meta.remote) return;
    socket.emit("event-sync", event);
  });

  socket.on("event-sync", (event: BusEvent) => {
    bus.publish(event, { remote: true });
  });
}

function EventSync({ children }: { children: React.ReactNode }) {
  const bus = useBus();
  useEffect(() => {
    setupSocket(bus);
  }, [bus]);
  return <>{children}</>;
}

export default EventSync;

Thats an example sharing everything but you probably want to use wildcards to only share a subset.

eg. shared.**


As far as typing what has been working for me has been to merge events together for strict event types. Eg.

export type BoardEvent =
  | ReturnType<typeof taskMoved>
  | ReturnType<typeof taskCreated>
  | ReturnType<typeof taskUpdated>
  | ReturnType<typeof taskDeleted>
  | ReturnType<typeof listTitleChanged>
  | ReturnType<typeof listDeleted>
  | ReturnType<typeof listCreated>;

Where each one of those is a eventCreator function.

It's a little manual but I am not really sure if there is a better way without resorting to BusEvent<any>

evangelion1204 commented 5 years ago

Yeah, built something similar using wildcards but struggling a bit differentiating what to bridge and what not - good idea using meta 😄 Will give it a try and close

ryardley commented 5 years ago

Just updated the source with an example here

evangelion1204 commented 5 years ago

Cool, will have a look tomorrow