Socket
Socket
Sign inDemoInstall

@roomservice/browser

Package Overview
Dependencies
2
Maintainers
2
Versions
126
Alerts
File Explorer

Advanced tools

Install Socket

Detect and block malicious and high-risk dependencies

Install

Comparing version 3.0.0 to 3.0.1-0

69

dist/browser.cjs.development.js

@@ -764,3 +764,3 @@ 'use strict';

var _ListInterpreter$newL = core.ListInterpreter.newList(props.docID, props.listID, props.actor),
var _ListInterpreter$newL = core.ListInterpreter.newList(props.docID, props.listID),
meta = _ListInterpreter$newL.meta,

@@ -798,5 +798,5 @@ store = _ListInterpreter$newL.store;

_proto.dangerouslyUpdateClientDirectly = function dangerouslyUpdateClientDirectly(cmd) {
_proto.dangerouslyUpdateClientDirectly = function dangerouslyUpdateClientDirectly(cmd, versionstamp, ack) {
core.ListInterpreter.validateCommand(this.meta, cmd);
core.ListInterpreter.applyCommand(this.store, cmd);
core.ListInterpreter.applyCommand(this.store, cmd, versionstamp, ack);
return this.clone();

@@ -860,2 +860,7 @@ };

return core.ListInterpreter.toArray(this.store);
} // exposed for testing
;
_proto.session = function session() {
return this.store.rt.session;
};

@@ -905,5 +910,5 @@

_proto.dangerouslyUpdateClientDirectly = function dangerouslyUpdateClientDirectly(cmd) {
_proto.dangerouslyUpdateClientDirectly = function dangerouslyUpdateClientDirectly(cmd, versionstamp, ack) {
core.MapInterpreter.validateCommand(this.meta, cmd);
core.MapInterpreter.applyCommand(this.store, cmd);
core.MapInterpreter.applyCommand(this.store, cmd, versionstamp, ack);
return this.clone();

@@ -913,3 +918,5 @@ };

_proto.get = function get(key) {
return this.store[key];
var _this$store$kv$get;
return (_this$store$kv$get = this.store.kv.get(key)) === null || _this$store$kv$get === void 0 ? void 0 : _this$store$kv$get.value;
};

@@ -950,3 +957,3 @@

get: function get() {
return Object.keys(this.store);
return Array.from(this.store.kv.keys());
}

@@ -1083,5 +1090,22 @@ }]);

_proto.set = function set(value, exp) {
var _this2 = this;
var addition = exp ? exp : 60; // Convert to unix + add seconds
var expAt = Math.round(new Date().getTime() / 1000) + addition;
if (this.myExpirationHandle) {
clearTimeout(this.myExpirationHandle);
this.myExpirationHandle = undefined;
}
this.myExpirationHandle = setTimeout(function () {
// TODO: this should be revisited when presence ACKs are added
delete _this2.cache[_this2.actor];
_this2.bus.publish({
key: _this2.key,
valuesByUser: _this2.withoutExpired()
});
}, addition * 1000);
this.sendPres(this.key, {

@@ -1115,5 +1139,6 @@ room: this.roomID,

if (body.room !== this.roomID) return false;
if (body.from === this.actor) return false; // ignore validation msgs
if (body.room !== this.roomID) return false; // ignore validation msgs
// TODO: use same ack logic as doc cmds
if (body.from === this.actor) return false;
var obj = {

@@ -1215,3 +1240,3 @@ expAt: new Date(body.expAt * 1000),

this.mapClients = {};
this.expires = {};
this.expiresByActorByKey = {};
this.queueIncomingCmds = true;

@@ -1326,9 +1351,4 @@ this.cmdQueue = [];

if (core.vsReader(atob).isOlderVS(body.vs, this.bootstrapState.document.vs)) {
if (core.isOlderVS(body.vs, this.bootstrapState.document.vs)) {
return;
} // Ignore validated commands
if (body.from === this.actor) {
return;
}

@@ -1374,3 +1394,3 @@

var client = this.mapClients[objID];
var updatedClient = client.dangerouslyUpdateClientDirectly(body.args);
var updatedClient = client.dangerouslyUpdateClientDirectly(body.args, body.vs, body.ack);

@@ -1389,3 +1409,3 @@ for (var _iterator3 = _createForOfIteratorHelperLoose(this.mapCallbacksByObjID[objID] || []), _step3; !(_step3 = _iterator3()).done;) {

var client = this.listClients[objID];
var updatedClient = client.dangerouslyUpdateClientDirectly(body.args);
var updatedClient = client.dangerouslyUpdateClientDirectly(body.args, body.vs, body.ack);

@@ -1401,3 +1421,4 @@ for (var _iterator4 = _createForOfIteratorHelperLoose(this.listCallbacksByObjID[objID] || []), _step4; !(_step4 = _iterator4()).done;) {

if (body.room !== this.roomID) return;
if (body.room !== this.roomID) return; // TODO: use same ack logic as doc cmds
if (body.from === this.actor) return;

@@ -1416,4 +1437,7 @@ var key = body.key;

if (secondsTillTimeout < 60 * 60 * 12) {
if (this.expires[key]) {
clearTimeout(this.expires[key]);
var expiresByActor = this.expiresByActorByKey[key] || {};
var actor = body.from;
if (expiresByActor[actor]) {
clearTimeout(expiresByActor[actor]);
}

@@ -1434,3 +1458,4 @@

}, secondsTillTimeout * 1000);
this.expires[key] = timeout;
expiresByActor[actor] = timeout;
this.expiresByActorByKey[key] = expiresByActor;
}

@@ -1437,0 +1462,0 @@

@@ -1,2 +0,2 @@

"use strict";Object.defineProperty(exports,"__esModule",{value:!0});var e,t=(e=require("tiny-invariant"))&&"object"==typeof e&&"default"in e?e.default:e,r=require("@roomservice/core"),n="https://super.roomservice.dev/docs",o="https://super.roomservice.dev/presence";function s(e,t){for(var r=0;r<t.length;r++){var n=t[r];n.enumerable=n.enumerable||!1,n.configurable=!0,"value"in n&&(n.writable=!0),Object.defineProperty(e,n.key,n)}}function i(e,t,r){return t&&s(e.prototype,t),r&&s(e,r),e}function c(){return(c=Object.assign||function(e){for(var t=1;t<arguments.length;t++){var r=arguments[t];for(var n in r)Object.prototype.hasOwnProperty.call(r,n)&&(e[n]=r[n])}return e}).apply(this,arguments)}function u(e,t){(null==t||t>e.length)&&(t=e.length);for(var r=0,n=new Array(t);r<t;r++)n[r]=e[r];return n}function a(e,t){var r;if("undefined"==typeof Symbol||null==e[Symbol.iterator]){if(Array.isArray(e)||(r=function(e,t){if(e){if("string"==typeof e)return u(e,void 0);var r=Object.prototype.toString.call(e).slice(8,-1);return"Object"===r&&e.constructor&&(r=e.constructor.name),"Map"===r||"Set"===r?Array.from(e):"Arguments"===r||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(r)?u(e,void 0):void 0}}(e))||t&&e&&"number"==typeof e.length){r&&(e=r);var n=0;return function(){return n>=e.length?{done:!0}:{done:!1,value:e[n++]}}}throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}return(r=e[Symbol.iterator]()).next.bind(r)}const h=function(){function e(){}return e.prototype.then=function(t,r){const n=new e,o=this.s;if(o){const e=1&o?t:r;if(e){try{l(n,1,e(this.v))}catch(e){l(n,2,e)}return n}return this}return this.o=function(e){try{const o=e.v;1&e.s?l(n,1,t?t(o):o):r?l(n,1,r(o)):l(n,2,o)}catch(e){l(n,2,e)}},n},e}();function l(e,t,r){if(!e.s){if(r instanceof h){if(!r.s)return void(r.o=l.bind(null,e,t));1&t&&(t=r.s),r=r.v}if(r&&r.then)return void r.then(l.bind(null,e,t),l.bind(null,e,2));e.s=t,e.v=r;const n=e.o;n&&n(e)}}function d(e){return e instanceof h&&1&e.s}function m(e,t,r){for(var n;;){var o=e();if(d(o)&&(o=o.v),!o)return s;if(o.then){n=0;break}var s=r();if(s&&s.then){if(!d(s)){n=1;break}s=s.s}if(t){var i=t();if(i&&i.then&&!d(i)){n=2;break}}}var c=new h,u=l.bind(null,c,2);return(0===n?o.then(m):1===n?s.then(a):i.then(f)).then(void 0,u),c;function a(n){s=n;do{if(t&&(i=t())&&i.then&&!d(i))return void i.then(f).then(void 0,u);if(!(o=e())||d(o)&&!o.v)return void l(c,1,s);if(o.then)return void o.then(m).then(void 0,u);d(s=r())&&(s=s.v)}while(!s||!s.then);s.then(a).then(void 0,u)}function m(e){e?(s=r())&&s.then?s.then(a).then(void 0,u):a(s):l(c,1,s)}function f(){(o=e())?o.then?o.then(m).then(void 0,u):m(o):l(c,1,s)}}"undefined"!=typeof Symbol&&(Symbol.iterator||(Symbol.iterator=Symbol("Symbol.iterator"))),"undefined"!=typeof Symbol&&(Symbol.asyncIterator||(Symbol.asyncIterator=Symbol("Symbol.asyncIterator")));var f=function(e){try{var t=function(e){return r?e:Promise.resolve(fetch(o,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({resources:[{object:"document",reference:c,permission:"read_write",room:i},{object:"room",reference:i,permission:"join"}]})})).then((function(e){if(401===e.status)throw new Error("The Auth Webhook returned unauthorized.");if(200!==e.status)throw new Error("The Auth Webhook returned a status code other than 200.");return Promise.resolve(e.json()).then((function(e){var t=e.resources,r=e.token,n=e.user;if(!t||!r||!n){if("Unauthorized"===e.body)throw new Error("The Auth Webhook unexpectedly return unauthorized. You may be using an invalid API key.");throw new Error("The Auth Webhook has an incorrectly formatted JSON response.")}return{token:r,guestReference:n,docID:t.find((function(e){return"document"===e.object})).id,roomID:t.find((function(e){return"room"===e.object})).id}}))}))},r=!1,n=e.authBundle,o=n.strategy,s=n.ctx,i=e.room,c=e.document,u=function(){if("function"==typeof o)return Promise.resolve(o({room:i,ctx:s})).then((function(e){if(!e.user)throw new Error("The auth function must return a 'user' key.");var t=e.resources.find((function(e){return"document"===e.object})).id,n=e.resources.find((function(e){return"room"===e.object})).id;return r=!0,{token:e.token,guestReference:e.user,docID:t,roomID:n}}))}();return Promise.resolve(u&&u.then?u.then(t):t(u))}catch(e){return Promise.reject(e)}},p=function(e,t,r){try{return Promise.resolve(fetch(e+"/"+r,{headers:{Authorization:"Bearer: "+t}})).then((function(e){return Promise.resolve(e.json()).then((function(e){return e.body}))}))}catch(e){return Promise.reject(e)}},v=function(e,t,r){try{return Promise.resolve(fetch(e+"/"+r,{headers:{Authorization:"Bearer: "+t}})).then((function(e){return Promise.resolve(e.json()).then((function(e){for(var t=0,r=Object.keys(e);t<r.length;t++)for(var n=r[t],o=0,s=Object.keys(e[n]);o<s.length;o++){var i=s[o];if("string"==typeof e[n][i].value){var c=void 0;try{c=JSON.parse(e[n][i].value)}catch(e){}c&&(e[n][i].value=c)}}return e}))}))}catch(e){return Promise.reject(e)}},b=function(e){try{return Promise.resolve(Promise.all([v(e.presenceURL,e.token,e.roomID),p(e.docsURL,e.token,e.docID)])).then((function(e){return{presence:e[0],document:e[1]}}))}catch(e){return Promise.reject(e)}};function y(e){return new Promise((function(t){return setTimeout(t,e)}))}var C=function(e){try{return Promise.resolve(new Promise((function(t,r){var n=new WebSocket(e);n.onopen=function(){t(n)},n.onerror=function(e){r(e)}})))}catch(e){return Promise.reject(e)}},I=["doc:fwd","presence:fwd","room:rm_guest"],g=function(){function e(e){this.callbacks={},this.lastTime=0,this.msgsThisMilisecond=0,this.docCmdSendQueue=[],this.presenceCmdSendQueue=new Map,this.dispatcher=e.dispatcher,this.wsURL=e.wsURL,this.docsURL=e.docsURL,this.presenceURL=e.presenceURL,this.room=e.room,this.document=e.document,this.authBundle=e.authBundle,this.wsFactory=e.wsFactory||C,this.bootstrapFetch=e.bootstrapFetch||b,this.sessionFetch=e.sessionFetch||f,this.wsLoop()}var t=e.prototype;return t.close=function(){this.currentConn&&(this.currentConn.onmessage=null,this.currentConn.onclose=null,this.currentConn.close(),this.currentConn=void 0),this.pendingConn&&(this.pendingConn=void 0),this.dispatcher.startQueueingCmds()},t.connectAndAuth=function(){try{var e=function(){var e=t.session;return Promise.resolve(t.wsFactory(t.wsURL)).then((function(r){return r.onmessage=function(e){var r=JSON.parse(e.data);t.dispatch(r.type,r.body)},r.onclose=function(){return t.close()},Promise.resolve(r).then((function(r){try{return r.send(t.serializeMsg("guest:authenticate",e.token)),Promise.resolve(t.once("guest:authenticated")).then((function(){return r.send(t.serializeMsg("room:join",e.roomID)),Promise.resolve(t.once("room:joined")).then((function(){return Promise.resolve(t.bootstrapFetch({docID:e.docID,roomID:e.roomID,docsURL:t.docsURL,presenceURL:t.presenceURL,token:e.token})).then((function(n){return t.dispatcher.bootstrap(e.guestReference,n),r}))}))}))}catch(e){return Promise.reject(e)}}))}))},t=this,r=function(){if(!t.session)return Promise.resolve(t.sessionFetch({authBundle:t.authBundle,room:t.room,document:t.document})).then((function(e){t.session=e}))}();return Promise.resolve(r&&r.then?r.then(e):e())}catch(e){return Promise.reject(e)}},t.conn=function(){try{var e=this;return e.currentConn?Promise.resolve(e.currentConn):(e.pendingConn||(e.close(),e.pendingConn=function(){try{var t=!1,r=0;return Promise.resolve(m((function(){return!t}),void 0,(function(){var n=r*(Math.random()+1)/2;return Promise.resolve(y(n)).then((function(){return r=Math.min(2*r+100,6e4),function(r,n){try{var o=Promise.resolve(e.connectAndAuth()).then((function(r){return e.currentConn=r,e.pendingConn=void 0,t=!0,r}))}catch(e){return n(e)}return o&&o.then?o.then(void 0,n):o}(0,(function(e){console.error("Connection to RoomService failed with",e,"\nRetrying...")}))}))})))}catch(e){return Promise.reject(e)}}()),Promise.resolve(e.pendingConn))}catch(e){return Promise.reject(e)}},t.wsLoop=function(){try{var e=this,t=m((function(){return!0}),void 0,(function(){return Promise.resolve(e.conn()).then((function(){return e.processSendQueue(),Promise.resolve(y(1e3)).then((function(){}))}))}));return Promise.resolve(t&&t.then?t.then((function(){})):void 0)}catch(e){return Promise.reject(e)}},t.timestamp=function(){var e=Date.now();return e===this.lastTime?this.msgsThisMilisecond++:(this.lastTime=e,this.msgsThisMilisecond=0),e+":"+this.msgsThisMilisecond},t.serializeMsg=function(e,t){var r=this.timestamp();return JSON.stringify({type:e,ts:r,ver:0,body:t})},t.send=function(e,t){if("doc:cmd"==e){if(this.docCmdSendQueue.length>=1e4)throw"RoomService send queue full";this.docCmdSendQueue.push(t)}"presence:cmd"==e&&this.presenceCmdSendQueue.set(t.key,t),this.processSendQueue()},t.processSendQueue=function(){if(this.currentConn&&this.session)try{for(;this.presenceCmdSendQueue.size>0;){var e=this.presenceCmdSendQueue.entries().next();if(e){var t=e.value,r=t[0],n=this.serializeMsg("presence:cmd",t[1]);this.currentConn.send(n),this.presenceCmdSendQueue.delete(r)}}for(;this.docCmdSendQueue.length>0;){var o=this.serializeMsg("doc:cmd",this.docCmdSendQueue[0]);this.currentConn.send(o),this.docCmdSendQueue.splice(0,1)}}catch(e){console.error(e)}},t.bind=function(e,t){return this.callbacks[e]=this.callbacks[e]||[],this.callbacks[e].push(t),t},t.unbind=function(e,t){this.callbacks[e]=this.callbacks[e].filter((function(e){return e!==t}))},t.dispatch=function(e,t){"error"==e&&console.error(t);var r=this.callbacks[e];if(r)for(var n=0;n<r.length;n++)r[n](t);I.includes(e)&&this.dispatcher.forwardCmd(e,t)},t.once=function(e){try{var t,r=this;return Promise.race([new Promise((function(e,t){return setTimeout((function(){return t("timeout")}),2e3)})),new Promise((function(n){t=r.bind(e,(function(e){n(e)}))}))]).then((function(){t&&r.unbind(e,t)}))}catch(e){return Promise.reject(e)}},e}(),D=function(){function e(e){this.roomID=e.roomID,this.ws=e.ws,this.bus=e.bus,this.actor=e.actor,this.id=e.listID;var n=r.ListInterpreter.newList(e.docID,e.listID,e.actor),o=n.store;this.meta=n.meta,this.store=o,e.checkpoint.lists[e.listID]||t(!1),r.ListInterpreter.importFromRawCheckpoint(this.store,this.actor,e.checkpoint,this.meta.listID)}var n=e.prototype;return n.bootstrap=function(e,t){this.actor=e,r.ListInterpreter.importFromRawCheckpoint(this.store,this.actor,t.document,this.meta.listID)},n.sendCmd=function(e){this.ws.send("doc:cmd",{room:this.roomID,args:e}),this.bus.publish({args:e,from:this.actor})},n.clone=function(){return Object.assign(Object.create(Object.getPrototypeOf(this)),this)},n.dangerouslyUpdateClientDirectly=function(e){return r.ListInterpreter.validateCommand(this.meta,e),r.ListInterpreter.applyCommand(this.store,e),this.clone()},n.get=function(e){return r.ListInterpreter.get(this.store,e)},n.set=function(e,t){var n=r.ListInterpreter.runSet(this.store,this.meta,e,t);return this.sendCmd(n),this.clone()},n.delete=function(e){var t=r.ListInterpreter.runDelete(this.store,this.meta,e);return t?(this.sendCmd(t),this.clone()):this.clone()},n.insertAfter=function(e,t){return this.insertAt(e+1,t)},n.insertAt=function(e,t){var n=r.ListInterpreter.runInsertAt(this.store,this.meta,e,t);return this.sendCmd(n),this.clone()},n.push=function(){for(var e=arguments.length,t=new Array(e),n=0;n<e;n++)t[n]=arguments[n];for(var o,s=r.ListInterpreter.runPush.apply(r.ListInterpreter,[this.store,this.meta].concat(t)),i=a(s);!(o=i()).done;){var c=o.value;this.sendCmd(c)}return this},n.map=function(e){return r.ListInterpreter.map(this.store,e)},n.toArray=function(){return r.ListInterpreter.toArray(this.store)},e}(),w=function(){function e(e){this.roomID=e.roomID,this.ws=e.ws,this.bus=e.bus,this.actor=e.actor;var t=r.MapInterpreter.newMap(e.docID,e.mapID),n=t.meta;this.store=t.store,this.meta=n,r.MapInterpreter.importFromRawCheckpoint(this.store,e.checkpoint,this.meta.mapID)}var t=e.prototype;return t.bootstrap=function(e,t){this.actor=e,r.MapInterpreter.importFromRawCheckpoint(this.store,t.document,this.meta.mapID)},t.sendCmd=function(e){this.ws.send("doc:cmd",{room:this.roomID,args:e}),this.bus.publish({from:this.actor,args:e})},t.clone=function(){return Object.assign(Object.create(Object.getPrototypeOf(this)),this)},t.dangerouslyUpdateClientDirectly=function(e){return r.MapInterpreter.validateCommand(this.meta,e),r.MapInterpreter.applyCommand(this.store,e),this.clone()},t.get=function(e){return this.store[e]},t.set=function(e,t){var n=r.MapInterpreter.runSet(this.store,this.meta,e,t);return this.sendCmd(n),this.clone()},t.toObject=function(){for(var e,t={},r=a(this.keys);!(e=r()).done;){var n=e.value;t[n]=this.get(n)}return t},t.delete=function(e){var t=r.MapInterpreter.runDelete(this.store,this.meta,e);return this.sendCmd(t),this.clone()},i(e,[{key:"id",get:function(){return this.meta.mapID}},{key:"keys",get:function(){return Object.keys(this.store)}}]),e}(),k=function(){function e(e){var t=this;this.roomID=e.roomID,this.ws=e.ws,this.actor=e.actor,this.key=e.key,this.cache={},this.bus=e.bus,this.sendPres=function(e,t,r){void 0===r&&(r=!1);var n={},o=!0;return function(){var t=arguments,s=this,i=r&&o,c=function(){e.apply(s,t),n[t[0]]=null};i&&(o=!1,c()),n[arguments[0]]||(n[arguments[0]]=setTimeout(c,40))}}((function(e,r){t.ws.send("presence:cmd",r)})),this.bootstrap(this.actor,e.checkpoint)}var t=e.prototype;return t.bootstrap=function(e,t){this.actor=e,this.cache=c({},this.cache,t.presence[this.key]||{})},t.getAll=function(){return this.withoutExpired()},t.getMine=function(){var e;return null===(e=(this.cache||{})[this.actor])||void 0===e?void 0:e.value},t.withoutExpired=function(){var e={};for(var t in this.cache){var r=this.cache[t];new Date>r.expAt?delete this.cache[t]:e[t]=r.value}return e},t.withoutActorOrExpired=function(e){var t={};for(var r in this.cache){var n=this.cache[r];n&&(r===e&&this.cache[r]||new Date>n.expAt?delete this.cache[r]:t[r]=n.value)}return t},t.set=function(e,t){var r=t||60,n=Math.round((new Date).getTime()/1e3)+r;this.sendPres(this.key,{room:this.roomID,key:this.key,value:JSON.stringify(e),expAt:n}),this.cache[this.actor]={value:e,expAt:new Date(1e3*n)};var o=this.withoutExpired();return this.bus.publish({key:this.key,valuesByUser:o}),o},t.dangerouslyUpdateClientDirectly=function(e,t){if("room:rm_guest"===e)return this.withoutActorOrExpired(t.guest);if("presence:expire"===e)return this.withoutExpired();if(t.room!==this.roomID)return!1;if(t.from===this.actor)return!1;var r={expAt:new Date(1e3*t.expAt),value:JSON.parse(t.value)};return this.cache[t.from]=r,this.withoutExpired()},e}(),j=function(){function e(){this.isPublishing=!1,this.subs=new Set}var t=e.prototype;return t.unsubscribe=function(e){this.subs.delete(e)},t.subscribe=function(e){return this.subs.add(e),e},t.publish=function(e){if(this.isPublishing)throw new Error("Infinite loop detected, see more: See more: https://err.sh/getroomservice/browser/infinite-loop");this.isPublishing=!0,this.subs.forEach((function(t){t(e)})),this.isPublishing=!1},e}(),P=["mcreate","mput","mputref","mdel"],S=["lcreate","lins","linsref","lput","lputref","ldel"],L=function(){function e(e){this.presenceClients={},this.listClients={},this.mapClients={},this.expires={},this.queueIncomingCmds=!0,this.cmdQueue=[],this.mapCallbacksByObjID={},this.listCallbacksByObjID={},this.presenceCallbacksByKey={},this.ws=new g({dispatcher:this,wsURL:e.wsURL,docsURL:e.docsURL,presenceURL:e.presenceURL,room:e.room,document:e.document,authBundle:{strategy:e.auth,ctx:e.authCtx},sessionFetch:function(t){return Promise.resolve(e.session)}}),this.roomID=e.session.roomID,this.docID=e.bootstrapState.document.id,this.actor=e.actor,this.bootstrapState=e.bootstrapState}var n=e.prototype;return n.forwardCmd=function(e,t){this.queueIncomingCmds?this.cmdQueue.push([e,t]):this.processCmd(e,t)},n.processCmd=function(e,t){"doc:fwd"==e&&"args"in t&&this.dispatchDocCmd(t),"presence:fwd"==e&&"expAt"in t&&this.dispatchPresenceCmd(t),"room:rm_guest"==e&&"guest"in t&&this.dispatchRmGuest(t)},n.bootstrap=function(e,t){this.actor=e,this.bootstrapState=t;for(var r=0,n=Object.entries(this.listClients);r<n.length;r++)n[r][1].bootstrap(e,t);for(var o=0,s=Object.entries(this.mapClients);o<s.length;o++)s[o][1].bootstrap(e,t);for(var i=0,c=Object.entries(this.presenceClients);i<c.length;i++)c[i][1].bootstrap(e,t);this.queueIncomingCmds=!1;for(var u,h=a(this.cmdQueue);!(u=h()).done;){var l=u.value;this.processCmd(l[0],l[1])}this.cmdQueue.length=0},n.startQueueingCmds=function(){this.queueIncomingCmds=!0},n.dispatchDocCmd=function(e){if(e.room===this.roomID)if(!e.args||e.args.length<3)console.error("Unexpected command: ",e.args);else if(!r.vsReader(atob).isOlderVS(e.vs,this.bootstrapState.document.vs)&&e.from!==this.actor){var t=[e.args[0],e.args[1],e.args[2]],n=t[0],o=t[2];t[1]===this.docID&&(P.includes(n)?this.dispatchMapCmd(o,e):S.includes(n)?this.dispatchListCmd(o,e):console.warn("Unhandled Room Service doc:fwd command: "+n+". Consider updating the Room Service client."))}},n.dispatchRmGuest=function(e){if(e.room===this.roomID)for(var t=0,r=Object.entries(this.presenceClients);t<r.length;t++){var n=r[t],o=n[0],s=n[1].dangerouslyUpdateClientDirectly("room:rm_guest",e);if(!s)return;for(var i,c=a(this.presenceCallbacksByKey[o]||[]);!(i=c()).done;)(0,i.value)(s,e.guest)}},n.dispatchMapCmd=function(e,t){this.mapClients[e]||this.createMapLocally(e);for(var r,n=this.mapClients[e].dangerouslyUpdateClientDirectly(t.args),o=a(this.mapCallbacksByObjID[e]||[]);!(r=o()).done;)(0,r.value)(n.toObject(),t.from)},n.dispatchListCmd=function(e,t){this.listClients[e]||this.createListLocally(e);for(var r,n=this.listClients[e].dangerouslyUpdateClientDirectly(t.args),o=a(this.listCallbacksByObjID[e]||[]);!(r=o()).done;)(0,r.value)(n.toArray(),t.from)},n.dispatchPresenceCmd=function(e){var t=this;if(e.room===this.roomID&&e.from!==this.actor){var r=e.key,n=this.presence(r),o=(new Date).getTime()/1e3,s=e.expAt-o;if(!(s<0)){if(s<43200){this.expires[r]&&clearTimeout(this.expires[r]);var i=setTimeout((function(){var o=n.dangerouslyUpdateClientDirectly("presence:expire",{key:e.key});if(o)for(var s,i=a(null!==(c=t.presenceCallbacksByKey[r])&&void 0!==c?c:[]);!(s=i()).done;){var c;(0,s.value)(o,e.from)}}),1e3*s);this.expires[r]=i}var c=n.dangerouslyUpdateClientDirectly("presence:fwd",e);if(c)for(var u,h=a(null!==(l=this.presenceCallbacksByKey[r])&&void 0!==l?l:[]);!(u=h()).done;){var l;(0,u.value)(c,e.from)}}}},n.createListLocally=function(e){var t=this,r=new j;r.subscribe((function(r){for(var n,o=t.listClients[e],s=a(t.listCallbacksByObjID[e]||[]);!(n=s()).done;)(0,n.value)(o.toArray(),r.from)}));var n=new D({checkpoint:this.bootstrapState.document,roomID:this.roomID,docID:this.docID,listID:e,ws:this.ws,actor:this.actor,bus:r});return this.listClients[e]=n,n},n.list=function(e){return this.listClients[e]?this.listClients[e]:(this.bootstrapState.document.lists[e]||(this.ws.send("doc:cmd",{args:["lcreate",this.docID,e],room:this.roomID}),this.bootstrapState.document.lists[e]={afters:[],ids:[],values:[]}),this.createListLocally(e))},n.createMapLocally=function(e){var t=this,r=new j;r.subscribe((function(r){for(var n,o=t.mapClients[e],s=a(t.mapCallbacksByObjID[e]||[]);!(n=s()).done;)(0,n.value)(o.toObject(),r.from)}));var n=new w({checkpoint:this.bootstrapState.document,roomID:this.roomID,docID:this.docID,mapID:e,ws:this.ws,bus:r,actor:this.actor});return this.mapClients[e]=n,n},n.map=function(e){return this.mapClients[e]?this.mapClients[e]:(this.bootstrapState.document.maps[e]||this.ws.send("doc:cmd",{args:["mcreate",this.docID,e],room:this.roomID}),this.createMapLocally(e))},n.presence=function(e){var t=this;if(this.presenceClients[e])return this.presenceClients[e];var r=new j;r.subscribe((function(e){for(var r,n=a(t.presenceCallbacksByKey[e.key]||[]);!(r=n()).done;)(0,r.value)(e.valuesByUser,t.actor)}));var n=new k({checkpoint:this.bootstrapState,roomID:this.roomID,actor:this.actor,ws:this.ws,key:e,bus:r});try{this.presenceClients[e]=n}catch(e){throw new Error("Don't Freeze State. See more: https://err.sh/getroomservice/browser/dont-freeze")}return this.presenceClients[e]},n.subscribe=function(e,t){if(e instanceof k)return this.subscribePresence(e,t);var r,n=function(e,r){t(e,r)};return e instanceof w&&(this.mapCallbacksByObjID[r=e.id]=this.mapCallbacksByObjID[r]||[],this.mapCallbacksByObjID[r].push(n)),e instanceof D&&(this.listCallbacksByObjID[r=e.id]=this.listCallbacksByObjID[r]||[],this.listCallbacksByObjID[r].push(n)),[{objID:r,fn:n}]},n.subscribePresence=function(e,r){e||t(!1);var n=function(e,t){r&&r(e,t)},o=e.key;return this.presenceCallbacksByKey[o]=this.presenceCallbacksByKey[o]||[],this.presenceCallbacksByKey[o].push(n),[{objID:o,fn:n}]},n.unsubscribe=function(e){for(var t,r=a(e);!(t=r()).done;){var n=t.value;n.objID&&(this.mapCallbacksByObjID[n.objID]=O(this.mapCallbacksByObjID[n.objID],n.fn),this.listCallbacksByObjID[n.objID]=O(this.listCallbacksByObjID[n.objID],n.fn),this.presenceCallbacksByKey[n.objID]=O(this.presenceCallbacksByKey[n.objID],n.fn))}},i(e,[{key:"me",get:function(){return this.actor}}]),e}();function O(e,t){return e?e.filter((function(e){return e!==t})):[]}var R=function(){function e(e){this.roomClients={},this.auth=e.auth,this.ctx=e.ctx||{}}return e.prototype.room=function(e){try{var t=this;return t.roomClients[e]?Promise.resolve(t.roomClients[e]):Promise.resolve(function(e){try{return Promise.resolve(f({authBundle:{strategy:e.authStrategy,ctx:e.authCtx},room:e.room,document:e.document})).then((function(t){return Promise.resolve(b({docsURL:e.docsURL,presenceURL:e.presenceURL,token:t.token,docID:t.docID,roomID:t.roomID})).then((function(r){return new L({actor:t.guestReference,bootstrapState:r,token:t.token,room:e.room,document:e.document,auth:e.authStrategy,authCtx:e.authCtx,wsURL:"wss://super.roomservice.dev/ws",docsURL:n,presenceURL:o,session:t})}))}))}catch(e){return Promise.reject(e)}}({docsURL:n,presenceURL:o,authStrategy:t.auth,authCtx:t.ctx,room:e,document:"default"})).then((function(r){return t.roomClients[e]=r,r}))}catch(e){return Promise.reject(e)}},e}();exports.RoomClient=L,exports.RoomService=R,exports.default=R;
"use strict";Object.defineProperty(exports,"__esModule",{value:!0});var e,t=(e=require("tiny-invariant"))&&"object"==typeof e&&"default"in e?e.default:e,r=require("@roomservice/core"),n="https://super.roomservice.dev/docs",o="https://super.roomservice.dev/presence";function s(e,t){for(var r=0;r<t.length;r++){var n=t[r];n.enumerable=n.enumerable||!1,n.configurable=!0,"value"in n&&(n.writable=!0),Object.defineProperty(e,n.key,n)}}function i(e,t,r){return t&&s(e.prototype,t),r&&s(e,r),e}function c(){return(c=Object.assign||function(e){for(var t=1;t<arguments.length;t++){var r=arguments[t];for(var n in r)Object.prototype.hasOwnProperty.call(r,n)&&(e[n]=r[n])}return e}).apply(this,arguments)}function u(e,t){(null==t||t>e.length)&&(t=e.length);for(var r=0,n=new Array(t);r<t;r++)n[r]=e[r];return n}function a(e,t){var r;if("undefined"==typeof Symbol||null==e[Symbol.iterator]){if(Array.isArray(e)||(r=function(e,t){if(e){if("string"==typeof e)return u(e,void 0);var r=Object.prototype.toString.call(e).slice(8,-1);return"Object"===r&&e.constructor&&(r=e.constructor.name),"Map"===r||"Set"===r?Array.from(e):"Arguments"===r||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(r)?u(e,void 0):void 0}}(e))||t&&e&&"number"==typeof e.length){r&&(e=r);var n=0;return function(){return n>=e.length?{done:!0}:{done:!1,value:e[n++]}}}throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}return(r=e[Symbol.iterator]()).next.bind(r)}const h=function(){function e(){}return e.prototype.then=function(t,r){const n=new e,o=this.s;if(o){const e=1&o?t:r;if(e){try{l(n,1,e(this.v))}catch(e){l(n,2,e)}return n}return this}return this.o=function(e){try{const o=e.v;1&e.s?l(n,1,t?t(o):o):r?l(n,1,r(o)):l(n,2,o)}catch(e){l(n,2,e)}},n},e}();function l(e,t,r){if(!e.s){if(r instanceof h){if(!r.s)return void(r.o=l.bind(null,e,t));1&t&&(t=r.s),r=r.v}if(r&&r.then)return void r.then(l.bind(null,e,t),l.bind(null,e,2));e.s=t,e.v=r;const n=e.o;n&&n(e)}}function d(e){return e instanceof h&&1&e.s}function m(e,t,r){for(var n;;){var o=e();if(d(o)&&(o=o.v),!o)return s;if(o.then){n=0;break}var s=r();if(s&&s.then){if(!d(s)){n=1;break}s=s.s}if(t){var i=t();if(i&&i.then&&!d(i)){n=2;break}}}var c=new h,u=l.bind(null,c,2);return(0===n?o.then(m):1===n?s.then(a):i.then(f)).then(void 0,u),c;function a(n){s=n;do{if(t&&(i=t())&&i.then&&!d(i))return void i.then(f).then(void 0,u);if(!(o=e())||d(o)&&!o.v)return void l(c,1,s);if(o.then)return void o.then(m).then(void 0,u);d(s=r())&&(s=s.v)}while(!s||!s.then);s.then(a).then(void 0,u)}function m(e){e?(s=r())&&s.then?s.then(a).then(void 0,u):a(s):l(c,1,s)}function f(){(o=e())?o.then?o.then(m).then(void 0,u):m(o):l(c,1,s)}}"undefined"!=typeof Symbol&&(Symbol.iterator||(Symbol.iterator=Symbol("Symbol.iterator"))),"undefined"!=typeof Symbol&&(Symbol.asyncIterator||(Symbol.asyncIterator=Symbol("Symbol.asyncIterator")));var f=function(e){try{var t=function(e){return r?e:Promise.resolve(fetch(o,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({resources:[{object:"document",reference:c,permission:"read_write",room:i},{object:"room",reference:i,permission:"join"}]})})).then((function(e){if(401===e.status)throw new Error("The Auth Webhook returned unauthorized.");if(200!==e.status)throw new Error("The Auth Webhook returned a status code other than 200.");return Promise.resolve(e.json()).then((function(e){var t=e.resources,r=e.token,n=e.user;if(!t||!r||!n){if("Unauthorized"===e.body)throw new Error("The Auth Webhook unexpectedly return unauthorized. You may be using an invalid API key.");throw new Error("The Auth Webhook has an incorrectly formatted JSON response.")}return{token:r,guestReference:n,docID:t.find((function(e){return"document"===e.object})).id,roomID:t.find((function(e){return"room"===e.object})).id}}))}))},r=!1,n=e.authBundle,o=n.strategy,s=n.ctx,i=e.room,c=e.document,u=function(){if("function"==typeof o)return Promise.resolve(o({room:i,ctx:s})).then((function(e){if(!e.user)throw new Error("The auth function must return a 'user' key.");var t=e.resources.find((function(e){return"document"===e.object})).id,n=e.resources.find((function(e){return"room"===e.object})).id;return r=!0,{token:e.token,guestReference:e.user,docID:t,roomID:n}}))}();return Promise.resolve(u&&u.then?u.then(t):t(u))}catch(e){return Promise.reject(e)}},p=function(e,t,r){try{return Promise.resolve(fetch(e+"/"+r,{headers:{Authorization:"Bearer: "+t}})).then((function(e){return Promise.resolve(e.json()).then((function(e){return e.body}))}))}catch(e){return Promise.reject(e)}},v=function(e,t,r){try{return Promise.resolve(fetch(e+"/"+r,{headers:{Authorization:"Bearer: "+t}})).then((function(e){return Promise.resolve(e.json()).then((function(e){for(var t=0,r=Object.keys(e);t<r.length;t++)for(var n=r[t],o=0,s=Object.keys(e[n]);o<s.length;o++){var i=s[o];if("string"==typeof e[n][i].value){var c=void 0;try{c=JSON.parse(e[n][i].value)}catch(e){}c&&(e[n][i].value=c)}}return e}))}))}catch(e){return Promise.reject(e)}},y=function(e){try{return Promise.resolve(Promise.all([v(e.presenceURL,e.token,e.roomID),p(e.docsURL,e.token,e.docID)])).then((function(e){return{presence:e[0],document:e[1]}}))}catch(e){return Promise.reject(e)}};function b(e){return new Promise((function(t){return setTimeout(t,e)}))}var C=function(e){try{return Promise.resolve(new Promise((function(t,r){var n=new WebSocket(e);n.onopen=function(){t(n)},n.onerror=function(e){r(e)}})))}catch(e){return Promise.reject(e)}},g=["doc:fwd","presence:fwd","room:rm_guest"],I=function(){function e(e){this.callbacks={},this.lastTime=0,this.msgsThisMilisecond=0,this.docCmdSendQueue=[],this.presenceCmdSendQueue=new Map,this.dispatcher=e.dispatcher,this.wsURL=e.wsURL,this.docsURL=e.docsURL,this.presenceURL=e.presenceURL,this.room=e.room,this.document=e.document,this.authBundle=e.authBundle,this.wsFactory=e.wsFactory||C,this.bootstrapFetch=e.bootstrapFetch||y,this.sessionFetch=e.sessionFetch||f,this.wsLoop()}var t=e.prototype;return t.close=function(){this.currentConn&&(this.currentConn.onmessage=null,this.currentConn.onclose=null,this.currentConn.close(),this.currentConn=void 0),this.pendingConn&&(this.pendingConn=void 0),this.dispatcher.startQueueingCmds()},t.connectAndAuth=function(){try{var e=function(){var e=t.session;return Promise.resolve(t.wsFactory(t.wsURL)).then((function(r){return r.onmessage=function(e){var r=JSON.parse(e.data);t.dispatch(r.type,r.body)},r.onclose=function(){return t.close()},Promise.resolve(r).then((function(r){try{return r.send(t.serializeMsg("guest:authenticate",e.token)),Promise.resolve(t.once("guest:authenticated")).then((function(){return r.send(t.serializeMsg("room:join",e.roomID)),Promise.resolve(t.once("room:joined")).then((function(){return Promise.resolve(t.bootstrapFetch({docID:e.docID,roomID:e.roomID,docsURL:t.docsURL,presenceURL:t.presenceURL,token:e.token})).then((function(n){return t.dispatcher.bootstrap(e.guestReference,n),r}))}))}))}catch(e){return Promise.reject(e)}}))}))},t=this,r=function(){if(!t.session)return Promise.resolve(t.sessionFetch({authBundle:t.authBundle,room:t.room,document:t.document})).then((function(e){t.session=e}))}();return Promise.resolve(r&&r.then?r.then(e):e())}catch(e){return Promise.reject(e)}},t.conn=function(){try{var e=this;return e.currentConn?Promise.resolve(e.currentConn):(e.pendingConn||(e.close(),e.pendingConn=function(){try{var t=!1,r=0;return Promise.resolve(m((function(){return!t}),void 0,(function(){var n=r*(Math.random()+1)/2;return Promise.resolve(b(n)).then((function(){return r=Math.min(2*r+100,6e4),function(r,n){try{var o=Promise.resolve(e.connectAndAuth()).then((function(r){return e.currentConn=r,e.pendingConn=void 0,t=!0,r}))}catch(e){return n(e)}return o&&o.then?o.then(void 0,n):o}(0,(function(e){console.error("Connection to RoomService failed with",e,"\nRetrying...")}))}))})))}catch(e){return Promise.reject(e)}}()),Promise.resolve(e.pendingConn))}catch(e){return Promise.reject(e)}},t.wsLoop=function(){try{var e=this,t=m((function(){return!0}),void 0,(function(){return Promise.resolve(e.conn()).then((function(){return e.processSendQueue(),Promise.resolve(b(1e3)).then((function(){}))}))}));return Promise.resolve(t&&t.then?t.then((function(){})):void 0)}catch(e){return Promise.reject(e)}},t.timestamp=function(){var e=Date.now();return e===this.lastTime?this.msgsThisMilisecond++:(this.lastTime=e,this.msgsThisMilisecond=0),e+":"+this.msgsThisMilisecond},t.serializeMsg=function(e,t){var r=this.timestamp();return JSON.stringify({type:e,ts:r,ver:0,body:t})},t.send=function(e,t){if("doc:cmd"==e){if(this.docCmdSendQueue.length>=1e4)throw"RoomService send queue full";this.docCmdSendQueue.push(t)}"presence:cmd"==e&&this.presenceCmdSendQueue.set(t.key,t),this.processSendQueue()},t.processSendQueue=function(){if(this.currentConn&&this.session)try{for(;this.presenceCmdSendQueue.size>0;){var e=this.presenceCmdSendQueue.entries().next();if(e){var t=e.value,r=t[0],n=this.serializeMsg("presence:cmd",t[1]);this.currentConn.send(n),this.presenceCmdSendQueue.delete(r)}}for(;this.docCmdSendQueue.length>0;){var o=this.serializeMsg("doc:cmd",this.docCmdSendQueue[0]);this.currentConn.send(o),this.docCmdSendQueue.splice(0,1)}}catch(e){console.error(e)}},t.bind=function(e,t){return this.callbacks[e]=this.callbacks[e]||[],this.callbacks[e].push(t),t},t.unbind=function(e,t){this.callbacks[e]=this.callbacks[e].filter((function(e){return e!==t}))},t.dispatch=function(e,t){"error"==e&&console.error(t);var r=this.callbacks[e];if(r)for(var n=0;n<r.length;n++)r[n](t);g.includes(e)&&this.dispatcher.forwardCmd(e,t)},t.once=function(e){try{var t,r=this;return Promise.race([new Promise((function(e,t){return setTimeout((function(){return t("timeout")}),2e3)})),new Promise((function(n){t=r.bind(e,(function(e){n(e)}))}))]).then((function(){t&&r.unbind(e,t)}))}catch(e){return Promise.reject(e)}},e}(),w=function(){function e(e){this.roomID=e.roomID,this.ws=e.ws,this.bus=e.bus,this.actor=e.actor,this.id=e.listID;var n=r.ListInterpreter.newList(e.docID,e.listID),o=n.store;this.meta=n.meta,this.store=o,e.checkpoint.lists[e.listID]||t(!1),r.ListInterpreter.importFromRawCheckpoint(this.store,this.actor,e.checkpoint,this.meta.listID)}var n=e.prototype;return n.bootstrap=function(e,t){this.actor=e,r.ListInterpreter.importFromRawCheckpoint(this.store,this.actor,t.document,this.meta.listID)},n.sendCmd=function(e){this.ws.send("doc:cmd",{room:this.roomID,args:e}),this.bus.publish({args:e,from:this.actor})},n.clone=function(){return Object.assign(Object.create(Object.getPrototypeOf(this)),this)},n.dangerouslyUpdateClientDirectly=function(e,t,n){return r.ListInterpreter.validateCommand(this.meta,e),r.ListInterpreter.applyCommand(this.store,e,t,n),this.clone()},n.get=function(e){return r.ListInterpreter.get(this.store,e)},n.set=function(e,t){var n=r.ListInterpreter.runSet(this.store,this.meta,e,t);return this.sendCmd(n),this.clone()},n.delete=function(e){var t=r.ListInterpreter.runDelete(this.store,this.meta,e);return t?(this.sendCmd(t),this.clone()):this.clone()},n.insertAfter=function(e,t){return this.insertAt(e+1,t)},n.insertAt=function(e,t){var n=r.ListInterpreter.runInsertAt(this.store,this.meta,e,t);return this.sendCmd(n),this.clone()},n.push=function(){for(var e=arguments.length,t=new Array(e),n=0;n<e;n++)t[n]=arguments[n];for(var o,s=r.ListInterpreter.runPush.apply(r.ListInterpreter,[this.store,this.meta].concat(t)),i=a(s);!(o=i()).done;){var c=o.value;this.sendCmd(c)}return this},n.map=function(e){return r.ListInterpreter.map(this.store,e)},n.toArray=function(){return r.ListInterpreter.toArray(this.store)},n.session=function(){return this.store.rt.session},e}(),D=function(){function e(e){this.roomID=e.roomID,this.ws=e.ws,this.bus=e.bus,this.actor=e.actor;var t=r.MapInterpreter.newMap(e.docID,e.mapID),n=t.meta;this.store=t.store,this.meta=n,r.MapInterpreter.importFromRawCheckpoint(this.store,e.checkpoint,this.meta.mapID)}var t=e.prototype;return t.bootstrap=function(e,t){this.actor=e,r.MapInterpreter.importFromRawCheckpoint(this.store,t.document,this.meta.mapID)},t.sendCmd=function(e){this.ws.send("doc:cmd",{room:this.roomID,args:e}),this.bus.publish({from:this.actor,args:e})},t.clone=function(){return Object.assign(Object.create(Object.getPrototypeOf(this)),this)},t.dangerouslyUpdateClientDirectly=function(e,t,n){return r.MapInterpreter.validateCommand(this.meta,e),r.MapInterpreter.applyCommand(this.store,e,t,n),this.clone()},t.get=function(e){var t;return null===(t=this.store.kv.get(e))||void 0===t?void 0:t.value},t.set=function(e,t){var n=r.MapInterpreter.runSet(this.store,this.meta,e,t);return this.sendCmd(n),this.clone()},t.toObject=function(){for(var e,t={},r=a(this.keys);!(e=r()).done;){var n=e.value;t[n]=this.get(n)}return t},t.delete=function(e){var t=r.MapInterpreter.runDelete(this.store,this.meta,e);return this.sendCmd(t),this.clone()},i(e,[{key:"id",get:function(){return this.meta.mapID}},{key:"keys",get:function(){return Array.from(this.store.kv.keys())}}]),e}(),k=function(){function e(e){var t=this;this.roomID=e.roomID,this.ws=e.ws,this.actor=e.actor,this.key=e.key,this.cache={},this.bus=e.bus,this.sendPres=function(e,t,r){void 0===r&&(r=!1);var n={},o=!0;return function(){var t=arguments,s=this,i=r&&o,c=function(){e.apply(s,t),n[t[0]]=null};i&&(o=!1,c()),n[arguments[0]]||(n[arguments[0]]=setTimeout(c,40))}}((function(e,r){t.ws.send("presence:cmd",r)})),this.bootstrap(this.actor,e.checkpoint)}var t=e.prototype;return t.bootstrap=function(e,t){this.actor=e,this.cache=c({},this.cache,t.presence[this.key]||{})},t.getAll=function(){return this.withoutExpired()},t.getMine=function(){var e;return null===(e=(this.cache||{})[this.actor])||void 0===e?void 0:e.value},t.withoutExpired=function(){var e={};for(var t in this.cache){var r=this.cache[t];new Date>r.expAt?delete this.cache[t]:e[t]=r.value}return e},t.withoutActorOrExpired=function(e){var t={};for(var r in this.cache){var n=this.cache[r];n&&(r===e&&this.cache[r]||new Date>n.expAt?delete this.cache[r]:t[r]=n.value)}return t},t.set=function(e,t){var r=this,n=t||60,o=Math.round((new Date).getTime()/1e3)+n;this.myExpirationHandle&&(clearTimeout(this.myExpirationHandle),this.myExpirationHandle=void 0),this.myExpirationHandle=setTimeout((function(){delete r.cache[r.actor],r.bus.publish({key:r.key,valuesByUser:r.withoutExpired()})}),1e3*n),this.sendPres(this.key,{room:this.roomID,key:this.key,value:JSON.stringify(e),expAt:o}),this.cache[this.actor]={value:e,expAt:new Date(1e3*o)};var s=this.withoutExpired();return this.bus.publish({key:this.key,valuesByUser:s}),s},t.dangerouslyUpdateClientDirectly=function(e,t){if("room:rm_guest"===e)return this.withoutActorOrExpired(t.guest);if("presence:expire"===e)return this.withoutExpired();if(t.room!==this.roomID)return!1;if(t.from===this.actor)return!1;var r={expAt:new Date(1e3*t.expAt),value:JSON.parse(t.value)};return this.cache[t.from]=r,this.withoutExpired()},e}(),j=function(){function e(){this.isPublishing=!1,this.subs=new Set}var t=e.prototype;return t.unsubscribe=function(e){this.subs.delete(e)},t.subscribe=function(e){return this.subs.add(e),e},t.publish=function(e){if(this.isPublishing)throw new Error("Infinite loop detected, see more: See more: https://err.sh/getroomservice/browser/infinite-loop");this.isPublishing=!0,this.subs.forEach((function(t){t(e)})),this.isPublishing=!1},e}(),P=["mcreate","mput","mputref","mdel"],S=["lcreate","lins","linsref","lput","lputref","ldel"],L=function(){function e(e){this.presenceClients={},this.listClients={},this.mapClients={},this.expiresByActorByKey={},this.queueIncomingCmds=!0,this.cmdQueue=[],this.mapCallbacksByObjID={},this.listCallbacksByObjID={},this.presenceCallbacksByKey={},this.ws=new I({dispatcher:this,wsURL:e.wsURL,docsURL:e.docsURL,presenceURL:e.presenceURL,room:e.room,document:e.document,authBundle:{strategy:e.auth,ctx:e.authCtx},sessionFetch:function(t){return Promise.resolve(e.session)}}),this.roomID=e.session.roomID,this.docID=e.bootstrapState.document.id,this.actor=e.actor,this.bootstrapState=e.bootstrapState}var n=e.prototype;return n.forwardCmd=function(e,t){this.queueIncomingCmds?this.cmdQueue.push([e,t]):this.processCmd(e,t)},n.processCmd=function(e,t){"doc:fwd"==e&&"args"in t&&this.dispatchDocCmd(t),"presence:fwd"==e&&"expAt"in t&&this.dispatchPresenceCmd(t),"room:rm_guest"==e&&"guest"in t&&this.dispatchRmGuest(t)},n.bootstrap=function(e,t){this.actor=e,this.bootstrapState=t;for(var r=0,n=Object.entries(this.listClients);r<n.length;r++)n[r][1].bootstrap(e,t);for(var o=0,s=Object.entries(this.mapClients);o<s.length;o++)s[o][1].bootstrap(e,t);for(var i=0,c=Object.entries(this.presenceClients);i<c.length;i++)c[i][1].bootstrap(e,t);this.queueIncomingCmds=!1;for(var u,h=a(this.cmdQueue);!(u=h()).done;){var l=u.value;this.processCmd(l[0],l[1])}this.cmdQueue.length=0},n.startQueueingCmds=function(){this.queueIncomingCmds=!0},n.dispatchDocCmd=function(e){if(e.room===this.roomID)if(!e.args||e.args.length<3)console.error("Unexpected command: ",e.args);else if(!r.isOlderVS(e.vs,this.bootstrapState.document.vs)){var t=[e.args[0],e.args[1],e.args[2]],n=t[0],o=t[2];t[1]===this.docID&&(P.includes(n)?this.dispatchMapCmd(o,e):S.includes(n)?this.dispatchListCmd(o,e):console.warn("Unhandled Room Service doc:fwd command: "+n+". Consider updating the Room Service client."))}},n.dispatchRmGuest=function(e){if(e.room===this.roomID)for(var t=0,r=Object.entries(this.presenceClients);t<r.length;t++){var n=r[t],o=n[0],s=n[1].dangerouslyUpdateClientDirectly("room:rm_guest",e);if(!s)return;for(var i,c=a(this.presenceCallbacksByKey[o]||[]);!(i=c()).done;)(0,i.value)(s,e.guest)}},n.dispatchMapCmd=function(e,t){this.mapClients[e]||this.createMapLocally(e);for(var r,n=this.mapClients[e].dangerouslyUpdateClientDirectly(t.args,t.vs,t.ack),o=a(this.mapCallbacksByObjID[e]||[]);!(r=o()).done;)(0,r.value)(n.toObject(),t.from)},n.dispatchListCmd=function(e,t){this.listClients[e]||this.createListLocally(e);for(var r,n=this.listClients[e].dangerouslyUpdateClientDirectly(t.args,t.vs,t.ack),o=a(this.listCallbacksByObjID[e]||[]);!(r=o()).done;)(0,r.value)(n.toArray(),t.from)},n.dispatchPresenceCmd=function(e){var t=this;if(e.room===this.roomID&&e.from!==this.actor){var r=e.key,n=this.presence(r),o=(new Date).getTime()/1e3,s=e.expAt-o;if(!(s<0)){if(s<43200){var i=this.expiresByActorByKey[r]||{},c=e.from;i[c]&&clearTimeout(i[c]);var u=setTimeout((function(){var o=n.dangerouslyUpdateClientDirectly("presence:expire",{key:e.key});if(o)for(var s,i=a(null!==(c=t.presenceCallbacksByKey[r])&&void 0!==c?c:[]);!(s=i()).done;){var c;(0,s.value)(o,e.from)}}),1e3*s);i[c]=u,this.expiresByActorByKey[r]=i}var h=n.dangerouslyUpdateClientDirectly("presence:fwd",e);if(h)for(var l,d=a(null!==(m=this.presenceCallbacksByKey[r])&&void 0!==m?m:[]);!(l=d()).done;){var m;(0,l.value)(h,e.from)}}}},n.createListLocally=function(e){var t=this,r=new j;r.subscribe((function(r){for(var n,o=t.listClients[e],s=a(t.listCallbacksByObjID[e]||[]);!(n=s()).done;)(0,n.value)(o.toArray(),r.from)}));var n=new w({checkpoint:this.bootstrapState.document,roomID:this.roomID,docID:this.docID,listID:e,ws:this.ws,actor:this.actor,bus:r});return this.listClients[e]=n,n},n.list=function(e){return this.listClients[e]?this.listClients[e]:(this.bootstrapState.document.lists[e]||(this.ws.send("doc:cmd",{args:["lcreate",this.docID,e],room:this.roomID}),this.bootstrapState.document.lists[e]={afters:[],ids:[],values:[]}),this.createListLocally(e))},n.createMapLocally=function(e){var t=this,r=new j;r.subscribe((function(r){for(var n,o=t.mapClients[e],s=a(t.mapCallbacksByObjID[e]||[]);!(n=s()).done;)(0,n.value)(o.toObject(),r.from)}));var n=new D({checkpoint:this.bootstrapState.document,roomID:this.roomID,docID:this.docID,mapID:e,ws:this.ws,bus:r,actor:this.actor});return this.mapClients[e]=n,n},n.map=function(e){return this.mapClients[e]?this.mapClients[e]:(this.bootstrapState.document.maps[e]||this.ws.send("doc:cmd",{args:["mcreate",this.docID,e],room:this.roomID}),this.createMapLocally(e))},n.presence=function(e){var t=this;if(this.presenceClients[e])return this.presenceClients[e];var r=new j;r.subscribe((function(e){for(var r,n=a(t.presenceCallbacksByKey[e.key]||[]);!(r=n()).done;)(0,r.value)(e.valuesByUser,t.actor)}));var n=new k({checkpoint:this.bootstrapState,roomID:this.roomID,actor:this.actor,ws:this.ws,key:e,bus:r});try{this.presenceClients[e]=n}catch(e){throw new Error("Don't Freeze State. See more: https://err.sh/getroomservice/browser/dont-freeze")}return this.presenceClients[e]},n.subscribe=function(e,t){if(e instanceof k)return this.subscribePresence(e,t);var r,n=function(e,r){t(e,r)};return e instanceof D&&(this.mapCallbacksByObjID[r=e.id]=this.mapCallbacksByObjID[r]||[],this.mapCallbacksByObjID[r].push(n)),e instanceof w&&(this.listCallbacksByObjID[r=e.id]=this.listCallbacksByObjID[r]||[],this.listCallbacksByObjID[r].push(n)),[{objID:r,fn:n}]},n.subscribePresence=function(e,r){e||t(!1);var n=function(e,t){r&&r(e,t)},o=e.key;return this.presenceCallbacksByKey[o]=this.presenceCallbacksByKey[o]||[],this.presenceCallbacksByKey[o].push(n),[{objID:o,fn:n}]},n.unsubscribe=function(e){for(var t,r=a(e);!(t=r()).done;){var n=t.value;n.objID&&(this.mapCallbacksByObjID[n.objID]=O(this.mapCallbacksByObjID[n.objID],n.fn),this.listCallbacksByObjID[n.objID]=O(this.listCallbacksByObjID[n.objID],n.fn),this.presenceCallbacksByKey[n.objID]=O(this.presenceCallbacksByKey[n.objID],n.fn))}},i(e,[{key:"me",get:function(){return this.actor}}]),e}();function O(e,t){return e?e.filter((function(e){return e!==t})):[]}var x=function(){function e(e){this.roomClients={},this.auth=e.auth,this.ctx=e.ctx||{}}return e.prototype.room=function(e){try{var t=this;return t.roomClients[e]?Promise.resolve(t.roomClients[e]):Promise.resolve(function(e){try{return Promise.resolve(f({authBundle:{strategy:e.authStrategy,ctx:e.authCtx},room:e.room,document:e.document})).then((function(t){return Promise.resolve(y({docsURL:e.docsURL,presenceURL:e.presenceURL,token:t.token,docID:t.docID,roomID:t.roomID})).then((function(r){return new L({actor:t.guestReference,bootstrapState:r,token:t.token,room:e.room,document:e.document,auth:e.authStrategy,authCtx:e.authCtx,wsURL:"wss://super.roomservice.dev/ws",docsURL:n,presenceURL:o,session:t})}))}))}catch(e){return Promise.reject(e)}}({docsURL:n,presenceURL:o,authStrategy:t.auth,authCtx:t.ctx,room:e,document:"default"})).then((function(r){return t.roomClients[e]=r,r}))}catch(e){return Promise.reject(e)}},e}();exports.RoomClient=L,exports.RoomService=x,exports.default=x;
//# sourceMappingURL=browser.cjs.production.min.js.map
import invariant from 'tiny-invariant';
import { ListInterpreter, MapInterpreter, vsReader } from '@roomservice/core';
import { ListInterpreter, MapInterpreter, isOlderVS } from '@roomservice/core';

@@ -758,3 +758,3 @@ // export const WS_URL = 'ws://localhost:3452';

var _ListInterpreter$newL = ListInterpreter.newList(props.docID, props.listID, props.actor),
var _ListInterpreter$newL = ListInterpreter.newList(props.docID, props.listID),
meta = _ListInterpreter$newL.meta,

@@ -792,5 +792,5 @@ store = _ListInterpreter$newL.store;

_proto.dangerouslyUpdateClientDirectly = function dangerouslyUpdateClientDirectly(cmd) {
_proto.dangerouslyUpdateClientDirectly = function dangerouslyUpdateClientDirectly(cmd, versionstamp, ack) {
ListInterpreter.validateCommand(this.meta, cmd);
ListInterpreter.applyCommand(this.store, cmd);
ListInterpreter.applyCommand(this.store, cmd, versionstamp, ack);
return this.clone();

@@ -854,2 +854,7 @@ };

return ListInterpreter.toArray(this.store);
} // exposed for testing
;
_proto.session = function session() {
return this.store.rt.session;
};

@@ -899,5 +904,5 @@

_proto.dangerouslyUpdateClientDirectly = function dangerouslyUpdateClientDirectly(cmd) {
_proto.dangerouslyUpdateClientDirectly = function dangerouslyUpdateClientDirectly(cmd, versionstamp, ack) {
MapInterpreter.validateCommand(this.meta, cmd);
MapInterpreter.applyCommand(this.store, cmd);
MapInterpreter.applyCommand(this.store, cmd, versionstamp, ack);
return this.clone();

@@ -907,3 +912,5 @@ };

_proto.get = function get(key) {
return this.store[key];
var _this$store$kv$get;
return (_this$store$kv$get = this.store.kv.get(key)) === null || _this$store$kv$get === void 0 ? void 0 : _this$store$kv$get.value;
};

@@ -944,3 +951,3 @@

get: function get() {
return Object.keys(this.store);
return Array.from(this.store.kv.keys());
}

@@ -1077,5 +1084,22 @@ }]);

_proto.set = function set(value, exp) {
var _this2 = this;
var addition = exp ? exp : 60; // Convert to unix + add seconds
var expAt = Math.round(new Date().getTime() / 1000) + addition;
if (this.myExpirationHandle) {
clearTimeout(this.myExpirationHandle);
this.myExpirationHandle = undefined;
}
this.myExpirationHandle = setTimeout(function () {
// TODO: this should be revisited when presence ACKs are added
delete _this2.cache[_this2.actor];
_this2.bus.publish({
key: _this2.key,
valuesByUser: _this2.withoutExpired()
});
}, addition * 1000);
this.sendPres(this.key, {

@@ -1109,5 +1133,6 @@ room: this.roomID,

if (body.room !== this.roomID) return false;
if (body.from === this.actor) return false; // ignore validation msgs
if (body.room !== this.roomID) return false; // ignore validation msgs
// TODO: use same ack logic as doc cmds
if (body.from === this.actor) return false;
var obj = {

@@ -1209,3 +1234,3 @@ expAt: new Date(body.expAt * 1000),

this.mapClients = {};
this.expires = {};
this.expiresByActorByKey = {};
this.queueIncomingCmds = true;

@@ -1320,9 +1345,4 @@ this.cmdQueue = [];

if (vsReader(atob).isOlderVS(body.vs, this.bootstrapState.document.vs)) {
if (isOlderVS(body.vs, this.bootstrapState.document.vs)) {
return;
} // Ignore validated commands
if (body.from === this.actor) {
return;
}

@@ -1368,3 +1388,3 @@

var client = this.mapClients[objID];
var updatedClient = client.dangerouslyUpdateClientDirectly(body.args);
var updatedClient = client.dangerouslyUpdateClientDirectly(body.args, body.vs, body.ack);

@@ -1383,3 +1403,3 @@ for (var _iterator3 = _createForOfIteratorHelperLoose(this.mapCallbacksByObjID[objID] || []), _step3; !(_step3 = _iterator3()).done;) {

var client = this.listClients[objID];
var updatedClient = client.dangerouslyUpdateClientDirectly(body.args);
var updatedClient = client.dangerouslyUpdateClientDirectly(body.args, body.vs, body.ack);

@@ -1395,3 +1415,4 @@ for (var _iterator4 = _createForOfIteratorHelperLoose(this.listCallbacksByObjID[objID] || []), _step4; !(_step4 = _iterator4()).done;) {

if (body.room !== this.roomID) return;
if (body.room !== this.roomID) return; // TODO: use same ack logic as doc cmds
if (body.from === this.actor) return;

@@ -1410,4 +1431,7 @@ var key = body.key;

if (secondsTillTimeout < 60 * 60 * 12) {
if (this.expires[key]) {
clearTimeout(this.expires[key]);
var expiresByActor = this.expiresByActorByKey[key] || {};
var actor = body.from;
if (expiresByActor[actor]) {
clearTimeout(expiresByActor[actor]);
}

@@ -1428,3 +1452,4 @@

}, secondsTillTimeout * 1000);
this.expires[key] = timeout;
expiresByActor[actor] = timeout;
this.expiresByActorByKey[key] = expiresByActor;
}

@@ -1431,0 +1456,0 @@

@@ -29,3 +29,3 @@ import { SuperlumeSend } from './ws';

private clone;
dangerouslyUpdateClientDirectly(cmd: string[]): InnerListClient<T>;
dangerouslyUpdateClientDirectly(cmd: string[], versionstamp: string, ack: boolean): InnerListClient<T>;
get<K extends number>(index: K): T[K] | undefined;

@@ -39,2 +39,3 @@ set<K extends number>(index: K, val: T[K]): InnerListClient<T>;

toArray(): T[number][];
session(): string;
}

@@ -32,5 +32,5 @@ import { ObjectClient } from './types';

private clone;
dangerouslyUpdateClientDirectly(cmd: string[]): InnerMapClient<T>;
dangerouslyUpdateClientDirectly(cmd: string[], versionstamp: string, ack: boolean): InnerMapClient<T>;
get keys(): string[];
get<K extends keyof T>(key: K): T[K];
get<K extends keyof T>(key: K): T[K] | undefined;
set<K extends keyof T>(key: K, value: T[K]): InnerMapClient<T>;

@@ -37,0 +37,0 @@ toObject(): T;

@@ -43,2 +43,3 @@ import { SuperlumeSend } from './ws';

private withoutActorOrExpired;
private myExpirationHandle?;
/**

@@ -45,0 +46,0 @@ * @param value Any arbitrary object, string, boolean, or number.

@@ -25,3 +25,3 @@ import { ForwardedMessageBody, WebsocketDispatch } from './ws';

private mapClients;
private expires;
private expiresByActorByKey;
private ws;

@@ -28,0 +28,0 @@ constructor(params: {

@@ -93,3 +93,3 @@ import { ReverseTree } from '@roomservice/core/dist/ReverseTree';

id: string;
dangerouslyUpdateClientDirectly(msg: any): ObjectClient;
dangerouslyUpdateClientDirectly(msg: any, versionstamp: string, ack: boolean): ObjectClient;
}

@@ -96,0 +96,0 @@ export interface Resource {

@@ -40,2 +40,3 @@ export interface WebSocketAuthenticateMessage {

args: string[];
ack: boolean;
};

@@ -42,0 +43,0 @@ }

{
"version": "3.0.0",
"version": "3.0.1-0",
"license": "MIT",

@@ -43,5 +43,5 @@ "main": "dist/index.js",

"dependencies": {
"@roomservice/core": "0.3.1",
"@roomservice/core": "0.3.2",
"tiny-invariant": "^1.1.0"
}
}

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap

Packages

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc