Skip to content

Instantly share code, notes, and snippets.

@elcodabra
Created January 31, 2022 12:38
Show Gist options
  • Save elcodabra/9f84ce47211dad2ef8d11a9da680b40b to your computer and use it in GitHub Desktop.
Save elcodabra/9f84ce47211dad2ef8d11a9da680b40b to your computer and use it in GitHub Desktop.

Revisions

  1. elcodabra created this gist Jan 31, 2022.
    24 changes: 24 additions & 0 deletions events.spec.ts
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,24 @@
    import Reactor from './events'

    describe('Reactor: Events Management System', () => {
    const eventName = 'onError'
    const reactor = new (Reactor as any)()

    it(`registers window.${eventName} with callbacks`, () => {
    // reactor.registerEvent(eventName)
    const callback1 = jest.fn(() => console.log('callback 1'))
    const callback2 = jest.fn(() => console.log('callback 2'))

    reactor.addEventListener(eventName, callback1)
    reactor.addEventListener(eventName, callback2)

    // reactor.dispatchEvent(eventName)
    ;(window as any)[eventName]() // 2 results
    reactor.removeEventListener(eventName, callback2)
    // reactor.dispatchEvent(eventName)
    ;(window as any)[eventName]() // 1 result

    expect(callback1).toHaveBeenCalledTimes(2)
    expect(callback2).toHaveBeenCalledTimes(1)
    })
    })
    54 changes: 54 additions & 0 deletions events.ts
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,54 @@

    // https://gist.github.com/mohsen1/5123533
    import { common } from '@material-ui/core/colors'

    function Reactor() {
    // @ts-ignore
    this.events = {}
    }

    Reactor.prototype.registerEvent = function(eventName: string) {
    this.events[eventName] = new (Event as any)(eventName)
    }

    Reactor.prototype.dispatchEvent = function(eventName: string, eventArgs: any) {
    this.events[eventName].callbacks.forEach((callback: (e: any) => void) => {
    callback(eventArgs)
    })
    }

    Reactor.prototype.addEventListener = function(eventName: string, callback: (e: any) => void) {
    if (!this.events[eventName]) {
    this.registerEvent(eventName)
    }
    this.events[eventName].registerCallback(callback)
    }

    Reactor.prototype.removeEventListener = function(eventName: string, callback: (e: any) => void) {
    if (!this.events[eventName]) return
    this.events[eventName].unregisterCallback(callback)
    }

    export function Event(name: string) {
    // @ts-ignore
    this.name = name
    // @ts-ignore
    this.callbacks = []

    ;(window as any)[name] = (e: any) => {
    // @ts-ignore
    this.callbacks.forEach(callback => {
    callback(e)
    })
    }
    }

    Event.prototype.registerCallback = function(callback: (e: any) => void) {
    this.callbacks.push(callback)
    }

    Event.prototype.unregisterCallback = function(callback: (e: any) => void) {
    this.callbacks.pop(callback)
    }

    export default Reactor