(function (global, factory) {
  if (typeof define === "function" && define.amd) {
    define(["exports", "rxjs", "rxjs/operators"], factory);
  } else if (typeof exports !== "undefined") {
    factory(exports, require("rxjs"), require("rxjs/operators"));
  } else {
    var mod = {
      exports: {}
    };
    factory(mod.exports, global.rxjs, global.operators);
    global.send = mod.exports;
  }
})(typeof globalThis !== "undefined" ? globalThis : typeof self !== "undefined" ? self : this, function (_exports, _rxjs, _operators) {
  "use strict";

  Object.defineProperty(_exports, "__esModule", {
    value: true
  });
  _exports.default = _exports.testExports = _exports.MESSAGE_TO_SEND = void 0;
  const MESSAGE_TO_SEND = 'send/MESSAGE_TO_SEND';
  _exports.MESSAGE_TO_SEND = MESSAGE_TO_SEND;
  const errors = {
    wsParam: () => new Error('send() operator takes an Observable as its first parameter.')
  };

  const sendMessage = (serializer = JSON.stringify) => {
    return ([message, [socket]]) => socket.send(serializer(message));
  };

  const cacheMessagesUntilSocketEmits = ([buffer, socket], next) => {
    if (socket && next[0]) return [[next[0]], socket];
    if (socket && next[1]) return [[], next[1]];
    return next[1] ? [[...buffer, ...(next[0] ? [next[0]] : [])], next[1]] : [[...buffer, ...(next[0] ? [next[0]] : [])], null];
  };

  const bufferMessages = () => allEvent$ => {
    return allEvent$.pipe((0, _operators.map)(event => event.type === MESSAGE_TO_SEND ? [event.message, null] : [null, event]), (0, _operators.scan)(cacheMessagesUntilSocketEmits, [[], null]), (0, _operators.filter)(([messages, wsEvent]) => !!wsEvent && messages && messages.length), (0, _operators.mergeMap)(([messages, wsEvent]) => (0, _rxjs.of)(...messages.map(m => [m, wsEvent]))));
  };

  const send = function send(ws$, serializer = JSON.stringify, _sendMessage = sendMessage) {
    if (!ws$.subscribe || !ws$.pipe) return () => (0, _rxjs.throwError)(errors.wsParam());
    return messageIn$ => {
      const wsSub$ = ws$.pipe((0, _operators.share)());
      const messageEvent$ = messageIn$.pipe((0, _operators.map)(message => ({
        message,
        type: MESSAGE_TO_SEND
      })));
      const readyMessage$ = (0, _rxjs.merge)(messageEvent$, wsSub$).pipe(bufferMessages());
      const sendStream$ = readyMessage$.pipe((0, _operators.map)(_sendMessage(serializer)), (0, _operators.filter)(() => false));
      return (0, _rxjs.merge)(wsSub$, sendStream$);
    };
  };

  const testExports = {
    bufferMessages
  };
  _exports.testExports = testExports;
  var _default = send;
  _exports.default = _default;
});
//# sourceMappingURL=send.js.map