Skip to content

Instantly share code, notes, and snippets.

@harm-smits
Created August 3, 2021 09:21
Show Gist options
  • Save harm-smits/6c4aa3463903bfb3dafc5b9c828cf9fb to your computer and use it in GitHub Desktop.
Save harm-smits/6c4aa3463903bfb3dafc5b9c828cf9fb to your computer and use it in GitHub Desktop.
Very simple context based event system.
export interface EventClient {
subscribe: CallableFunction,
subscribeOnce: CallableFunction,
publish: CallableFunction,
unsubscribe: CallableFunction,
unsubscribeAll: CallableFunction
}
interface EventSubscription {
subject: Object,
event: string,
token: number,
clientId: number | undefined,
callback: Function
}
let eventToken: number = 0,
subscriptionList: EventSubscription[] = [],
autoClient: number = 0;
/**
* This holds all global subscriptions to events
*/
export let events: Object = {};
/**
* Subscribe to an event
* @param subject
* @param event
* @param callback
* @param clientId
* @returns {number}
*/
export function subscribe(subject: Object, event: string, callback: Function, clientId: number | undefined = undefined): number {
if ('function' != typeof callback)
return -1;
let newClientToken: number = ++eventToken;
subscriptionList.push({
subject: subject,
event: event,
token: eventToken,
clientId: clientId,
callback: callback
});
return newClientToken;
}
/**
* Subscribe only once, once the vent was fired, we disappear
* @param subject
* @param event
* @param callback
* @param clientId
*/
export function subscribeOnce(subject: Object, event: string, callback: CallableFunction, clientId: number | undefined = undefined): void {
let subscription = subscribe(subject, event, toPublish => {
callback(toPublish);
unsubscribe(subscription)
}, clientId);
}
/**
* Unsubscribe from a particular client
* @param clientId
*/
export function unsubscribe(clientId: number | undefined): void {
subscriptionList = subscriptionList.filter(subscription => subscription.token !== clientId);
}
/**
* Unsubscribe from all events
* @param clientId
*/
export function unsubscribeAll(clientId: number | undefined): void {
subscriptionList = subscriptionList.filter(subscription => subscription.clientId !== clientId);
}
/**
* Publish an event with a context
* @param subject
* @param event
* @param toPublish
*/
export function publish(subject: Object, event: string, toPublish: any = undefined) : void{
subscriptionList.forEach(item => {
item.subject === subject && item.event === event && item.callback(toPublish);
})
}
/**
* Clear all events
*/
export function clearAll() {
subscriptionList = []
}
/**
* Create a client object
* @param clientId
*/
function createClient(clientId: number | undefined = undefined): EventClient {
return {
subscribe: (subject, event, callback) => subscribe(subject, event, callback, clientId),
subscribeOnce: (subject, event, callback) => subscribeOnce(subject, event, callback, clientId),
publish: publish,
unsubscribe: unsubscribe,
unsubscribeAll: () => unsubscribeAll(clientId)
}
}
/**
* Get an event client
*/
export function getClient(): EventClient {
return createClient(++autoClient)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment