UNPKG

@oobleck/fluid-backend

Version:

Fluid Framework backend for nteract RTC

82 lines (73 loc) 2.82 kB
import { fromEventPattern, merge, Observable } from "rxjs"; import { filter, map } from "rxjs/operators"; import { IFluidDataStoreRuntime } from "@fluidframework/datastore-definitions"; import { IInboundSignalMessage } from "@fluidframework/runtime-definitions"; import { FrsMember, IFrsAudience } from "@fluid-experimental/frs-client"; import { IPeerConnectedEvent, IPeerDisconnectedEvent, IPeerLocationUpdatedEvent, PeerLocationDef, PresenceEvent } from "../schema"; // import { // FluidContainer, // IMember, // IServiceAudience, // SignalManager, // } from "@fluid-experimental/fluid-framework"; export class Presence { private readonly presenceKey: string; // private readonly presenceMap = new Map<string, PeerPresenceDef>(); readonly events$ = new Observable<PresenceEvent>(); constructor( audience: IFrsAudience, private readonly runtime: IFluidDataStoreRuntime ) { this.presenceKey = `presence-${runtime.id}`; const added$ = fromEventPattern<[string, FrsMember]>( handler => audience.on("memberAdded", handler), handler => audience.off("memberAdded", handler) ).pipe(map(([clientId, { userId, userName }]) => { return { __typename: "PeerConnectedEvent", id: clientId, userId, userName } as IPeerConnectedEvent; })); const removed$ = fromEventPattern<[string, FrsMember]>( handler => audience.on("memberRemoved", handler), handler => audience.off("memberRemoved", handler) ).pipe(map(([clientId]) => { return { __typename: "PeerDisconnectedEvent", id: clientId } as IPeerDisconnectedEvent; })); const updates$ = fromEventPattern<[IInboundSignalMessage, boolean]>( handler => this.runtime.on("signal", handler), handler => this.runtime.off("signal", handler) ).pipe( filter(([message, local]) => !local && runtime.connected && !!message.clientId && message.type === this.presenceKey), map(([{ clientId, content }]) => { return { __typename: "PeerLocationUpdatedEvent", id: clientId!, location: content as PeerLocationDef } as IPeerLocationUpdatedEvent; }) ); const current$ = new Observable<IPeerConnectedEvent>((observer) => { audience.getMembers().forEach(({ userId, userName }, id) => { observer.next({ __typename: "PeerConnectedEvent", id, userId, userName }); }); observer.complete(); }); this.events$ = merge(current$, added$, removed$, updates$); } update(input: PeerLocationDef) { if (this.runtime.connected) { this.runtime.submitSignal(this.presenceKey, input); } } }