kz logo mediator

kz is a collection of easy-to-use utility and feature libraries for creating anything you want with the Deno runtime.

@kz/mediator

The @kz/patterns/mediator module provides types and features for implementing the mediator pattern.

Overview | API Docs

## Examples ```ts import { AbstractDisposable } from '@kz/dispose'; import { TAbstractObserver } from '@kz/observe'; import { type PubSubTopicMessage, TAbstractSubscriber } from '@kz/pubsub'; import { type ParticipantTopicMessage, TAbstractParticipant, TBaseMediator, } from './mod.ts'; interface IUserResponse { name: string; birthYear: string; } type MediatorTopics = { 'get_users': undefined; 'get_user': number; 'user_response': IUserResponse; 'users_response': IUserResponse[]; }; class SwapiClient extends AbstractDisposable { protected cache = new Map(); constructor(protected baseUrl: string = 'https://swapi.dev/api') { super(); } public dispose(): void { this.cache.clear(); } protected async request(slug: string, id?: number): Promise { const { cache, baseUrl } = this; const uri = id ? `${baseUrl}/${slug}/${id}` : `${baseUrl}/${slug}`; const cached = cache.get(uri); if (cached) return cached; const response = await fetch(uri); const data = await response.text(); cache.set(uri, data); return data; } public async getPeople(id?: number): Promise { return await this.request('people', id); } } const client = new SwapiClient(); class DataBus extends TBaseMediator { } type DataBusRequest = Extract; class UserDataHandler extends TAbstractParticipant { public next( value: ParticipantTopicMessage, ): void { const [topic, message] = value; if (topic === 'get_users') { client.getPeople().then((data) => { const users = JSON.parse(data) as { results: any[] }; const userData = users.results.map((user) => { return { name: user.name, birthYear: user.birth_year }; }) as IUserResponse[]; this.publish(['users_response', userData]); }); } if (topic === 'get_user') { client.getPeople(message).then((data) => { const user = JSON.parse(data); const userData = { name: user.name, birthYear: user.birth_year, } as IUserResponse; this.publish(['user_response', userData]); }); } } public error(error: Error): void { console.error(error); } } // Will receive all messages from the mediator and be able to send requests back. class UserParticipant extends TAbstractParticipant { public next(value: ParticipantTopicMessage): void { const [topic] = value; console.log(`Participant(${topic}): Received a user update`); } public error(error: Error): void { console.error(error); } } // Yes! You can use pubsub subscriber to subscribe to a mediator. // Will receive updated user information, but not the request to do so. // Is unable to send requests back. class UserSubscriber extends TAbstractSubscriber< MediatorTopics, 'user_response' | 'users_response' > { public next( value: ParticipantTopicMessage< MediatorTopics, 'user_response' | 'users_response' >, ): void { const [topic, message] = value; if (topic === 'user_response') { console.log( `UserSub(${topic}): Updating user to ${ (message as IUserResponse).name }`, ); } else { console.log( `UserSub(${topic}): Updating users ${ (message as IUserResponse[]).length }`, ); } } public error(error: Error): void { console.error(error); } } // Yes! You can use regular observers to subscribe to a mediator. // Because they cannot specify a topic, they will receive all messages from the mediator. class UserObserver extends TAbstractObserver> { public next(value: ParticipantTopicMessage): void { const [topic] = value; console.log(`Observer(${topic}): Received a user update`); } public error(error: Error): void { console.error(error); } } const bus = new DataBus(); const handler = new UserDataHandler(['get_users', 'get_user']); const participant = new UserParticipant(['get_users', 'get_user']); const subscriber = new UserSubscriber(['user_response', 'users_response']); const observer = new UserObserver(); bus.subscribe(handler); bus.subscribe(participant); bus.subscribe(subscriber); bus.subscribe(observer); bus.publish(['get_users', undefined]); // go ahead and initialize data bus.publish(['get_user', 1]); // get a specific user participant.publish(['get_user', 2]); // get another specific user ``` ## Contributing Contributions are welcome! Take a look at our [contributing guidelines][contributing] to get started.

Contributor Covenant

## License The MIT License (MIT) 2020-2024 integereleven. Refer to [LICENSE][license] for details.

Built with ❤ by integereleven

@kz logo

GitHub commit activity GitHub issues

[deno]: https://deno.dom "Deno homepage" [jsr]: https://jsr.io "JSR homepage" [branches]: https://github.com/kz-io/mediator/branches "@kz/mediator branches on GitHub" [releases]: https://github.com/kz-io/mediator/releases "@kz/mediator releases on GitHub" [contributing]: https://github.com/kz-io/mediator/blob/main/CONTRIBUTING.md "@kz/mediator contributing guidelines" [license]: https://github.com/kz-io/mediator/blob/main/LICENSE "@kz/mediator license"