All files / json-crdt-repo/src/pubsub index.ts

100% Statements 19/19
25% Branches 1/4
100% Functions 8/8
100% Lines 17/17

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 5114x         14x 138x     237x       138x       14x     138x 138x 138x 138x       237x 237x       138x 138x         14x               14x 138x      
import {Subject} from 'rxjs';
import type {PubSub} from './types';
 
export type * from './types';
 
export class PubSubM<Message> implements PubSub<Message> {
  public readonly bus$ = new Subject<Message>();
 
  public pub(msg: Message): void {
    this.bus$.next(msg);
  }
 
  public end(): void {
    this.bus$.complete();
  }
}
 
export class PubSubBC<Message> extends PubSubM<Message> {
  public readonly ch: BroadcastChannel;
 
  constructor(public readonly bus: string) {
    super();
    const ch = (this.ch = new BroadcastChannel(bus));
    ch.onmessage = (e) => this.bus$.next(e.data as Message);
  }
 
  public pub(msg: Message): void {
    this.ch.postMessage(msg);
    super.pub(msg);
  }
 
  public end(): void {
    this.ch.close();
    super.end();
  }
}
 
/** Cache of global in-memory pubsub instances. */
const memoryCache: Record<string, PubSubM<unknown>> = {};
 
/**
 * Creates new cross-tab pubsub broadcast channel. Own messages are also received.
 *
 * @param bus The name of the broadcast bus, where messages will be published.
 * @returns A PubSub instance that publishes messages to the specified bus.
 */
export const pubsub = <Events>(bus: string): PubSub<Events> =>
  typeof BroadcastChannel !== 'undefined'
    ? new PubSubBC<Events>(bus)
    : <any>memoryCache[bus] || ((<any>memoryCache[bus]) = new PubSubM<Events>());