Skip to content

Commit

Permalink
Add JSDoc comments, and rename type parameters
Browse files Browse the repository at this point in the history
JSDoc comments have been added for each method on the controller
messenger instance.

Additionally, the `event` parameter has been renamed to `eventType`,
and the `action` parameter has been renamed to `actionType`. This was
done while adding docs because it made the documentation easier to
understand.
  • Loading branch information
Gudahtt committed Mar 11, 2021
1 parent ed6488f commit cc8f81d
Showing 1 changed file with 92 additions and 20 deletions.
112 changes: 92 additions & 20 deletions src/ControllerMessenger.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,34 +23,76 @@ export class ControllerMessenger<Action extends ActionConstraint, Event extends

private events = new Map<Event['type'], Set<unknown>>();

registerActionHandler<T extends Action['type']>(action: T, handler: ActionHandler<Action, T>) {
if (this.actions.has(action)) {
throw new Error(`A handler for ${action} has already been registered`);
/**
* Register an action handler.
*
* This will make the registered function available to call via the `call` method.
*
* @param actionType - The action type. This is a unqiue identifier for this action.
* @param handler- The action handler. This function gets called when the `call` method is
* invoked with the given action type.
* @throws Will throw when a handler has been registered for this action type already.
*/
registerActionHandler<T extends Action['type']>(actionType: T, handler: ActionHandler<Action, T>) {
if (this.actions.has(actionType)) {
throw new Error(`A handler for ${actionType} has already been registered`);
}
this.actions.set(action, handler);
this.actions.set(actionType, handler);
}

unregisterActionHandler<T extends Action['type']>(action: T) {
this.actions.delete(action);
/**
* Unregister an action handler.
*
* This will prevent this action from being called.
*
* @param actionType - The action type. This is a unqiue identifier for this action.
*/
unregisterActionHandler<T extends Action['type']>(actionType: T) {
this.actions.delete(actionType);
}

/**
* Unregister all action handlers.
*
* This prevents all actions from being called.
*/
clearActions() {
this.actions.clear();
}

/**
* Call an action.
*
* This function will call the action handler corresponding to the given action type, passing
* along any parameters given.
*
* @param actionType - The action type. This is a unqiue identifier for this action.
* @param params - The action parameters. These must match the type of the parameters of the
* registered action handler.
* @throws Will throw when no handler has been registered for the given type.
*/
call<T extends Action['type']>(
action: T,
actionType: T,
...params: ExtractActionParameters<Action, T>
): ExtractActionResponse<Action, T> {
const handler = this.actions.get(action) as ActionHandler<Action, T>;
const handler = this.actions.get(actionType) as ActionHandler<Action, T>;
if (!handler) {
throw new Error(`A handler for ${action} has not been registered`);
throw new Error(`A handler for ${actionType} has not been registered`);
}
return handler(...params);
}

publish<E extends Event['type']>(event: E, ...payload: ExtractEventPayload<Event, E>) {
const subscribers = this.events.get(event) as Set<ExtractEvenHandler<Event, E>>;
/**
* Publish an event.
*
* Publishes the given payload to all subscribers of the given event type.
*
* @param eventType - The event type. This is a unique identifier for this event.
* @param payload - The event payload. The type of the parameters for each event handler must
* match the type of this payload.
*/
publish<E extends Event['type']>(eventType: E, ...payload: ExtractEventPayload<Event, E>) {
const subscribers = this.events.get(eventType) as Set<ExtractEvenHandler<Event, E>>;

if (subscribers) {
for (const eventHandler of subscribers) {
Expand All @@ -59,30 +101,60 @@ export class ControllerMessenger<Action extends ActionConstraint, Event extends
}
}

subscribe<E extends Event['type']>(event: E, handler: ExtractEvenHandler<Event, E>) {
let subscribers = this.events.get(event);
/**
* Subscribe to an event.
*
* Registers the given function as an event handler for the given event type.
*
* @param eventType - The event type. This is a unique identifier for this event.
* @param handler - The event handler. The type of the parameters for this event handler must
* match the type of the payload for this event type.
*/
subscribe<E extends Event['type']>(eventType: E, handler: ExtractEvenHandler<Event, E>) {
let subscribers = this.events.get(eventType);
if (!subscribers) {
subscribers = new Set();
}
subscribers.add(handler);
this.events.set(event, subscribers);
this.events.set(eventType, subscribers);
}

unsubscribe<E extends Event['type']>(event: E, handler: ExtractEvenHandler<Event, E>) {
const subscribers = this.events.get(event);
/**
* Unsubscribe from an event.
*
* Unregisters the given function as an event handler for the given event.
*
* @param eventType - The event type. This is a unique identifier for this event.
* @param handler - The event handler to unregister.
* @throws Will throw when the given event handler is not registered for this event.
*/
unsubscribe<E extends Event['type']>(eventType: E, handler: ExtractEvenHandler<Event, E>) {
const subscribers = this.events.get(eventType);

if (!subscribers || !subscribers.has(handler)) {
throw new Error(`Subscription not found for event: '${event}'`);
throw new Error(`Subscription not found for event: '${eventType}'`);
}

subscribers.delete(handler);
this.events.set(event, subscribers);
this.events.set(eventType, subscribers);
}

clearEventSubscriptions<E extends Event['type']>(event: E) {
this.events.delete(event);
/**
* Clear subscriptions for a specific event.
*
* This will remove all subscribed handlers for this event.
*
* @param eventType - The event type. This is a unique identifier for this event.
*/
clearEventSubscriptions<E extends Event['type']>(eventType: E) {
this.events.delete(eventType);
}

/**
* Clear all subscriptions.
*
* This will remove all subscribed handlers for all events.
*/
clearSubscriptions() {
this.events.clear();
}
Expand Down

0 comments on commit cc8f81d

Please sign in to comment.