UNPKG

rx-postmessenger

Version:

Minimal RxJS adapter for the window.postMessage API for request-response streams and notification streams across frame windows.

67 lines (66 loc) 3.58 kB
import { fromEvent, share } from 'rxjs'; import { filter, map, pluck, take } from 'rxjs/operators'; import { RxPostmessengerRequest } from './RxPostmessengerRequest'; var Messenger = /** @class */ (function () { /** * @param {IMessageFactory} messageFactory - Factory instance for scalar message objects. * @param {IMessageValidator} messageValidator - Validator instance for incoming messages. * @param {IPostmessageAdapter} adapter - Adapter for interacting with the postMessage API */ function Messenger(messageFactory, messageValidator, adapter) { var _this = this; this.messageFactory = messageFactory; this.messageValidator = messageValidator; this.adapter = adapter; this.inboundMessages$ = fromEvent(window, 'message').pipe(filter(function (message) { return _this.messageValidator.validate(message); }), pluck('data'), share()); this.requests$ = this.messagesOfType('request'); this.responses$ = this.messagesOfType('response'); this.notifications$ = this.messagesOfType('notification'); this.inboundMessages$.subscribe(function (_a) { var id = _a.id; return _this.messageFactory.invalidateID(id); }); } Messenger.prototype.request = function (channel, payload) { var request = this.messageFactory.makeRequest(channel, payload); var responseObservable = this.createResponseObservable(request.id); this.adapter.postMessage(request); return responseObservable; }; Messenger.prototype.notify = function (channel, payload) { this.adapter.postMessage(this.messageFactory.makeNotification(channel, payload)); }; Messenger.prototype.requests = function (channel) { var _this = this; return this.requests$.pipe(filter(function (request) { return request.channel === channel; }), map(function (request) { return new RxPostmessengerRequest(request.id, request.channel, request.payload, function (payload) { return _this.respond(request.id, channel, payload); }); })); }; Messenger.prototype.notifications = function (channel) { return this.notifications$.pipe(filter(function (notification) { return notification.channel === channel; }), pluck('payload')); }; /** * Sends a response through given channel to the remote window, carrying given payload. */ Messenger.prototype.respond = function (requestId, channel, payload) { this.adapter.postMessage(this.messageFactory.makeResponse(requestId, channel, payload)); return this; }; /** * Creates an Observable that completes after a single emission of the MessageEvent * response for request of given requestId. If no matching response is ever received, * the Observable never completes. */ Messenger.prototype.createResponseObservable = function (requestId) { return this.responses$.pipe(filter(function (response) { return response.requestId === requestId; }), pluck('payload'), take(1)); }; /** * Returns an Observable emitting all inbound messages` of given type. * Returns an Observable emitting a subset of MessageEvent objects emitted * by this.inboundMessages$, passing through all MessageEvent objects whose * data.type property matches given type. */ Messenger.prototype.messagesOfType = function (type) { return this.inboundMessages$.pipe(filter(function (message) { return message.type === type; })); }; return Messenger; }()); export { Messenger };