@liveblocks/client
Advanced tools
Comparing version 0.16.4 to 0.16.5
2311
index.js
@@ -1,1582 +0,857 @@ | ||
'use strict'; | ||
"use strict"; | ||
Object.defineProperty(exports, '__esModule', { value: true }); | ||
Object.defineProperty(exports, "__esModule", { | ||
value: !0 | ||
}); | ||
var LiveObject = require('./shared.js'); | ||
var LiveObject = require("./shared.js"), _excluded = [ "_hasReceivedInitialPresence" ], BACKOFF_RETRY_DELAYS = [ 250, 500, 1e3, 2e3, 4e3, 8e3, 1e4 ], BACKOFF_RETRY_DELAYS_SLOW = [ 2e3, 3e4, 6e4, 3e5 ]; | ||
var BACKOFF_RETRY_DELAYS = [250, 500, 1000, 2000, 4000, 8000, 10000]; | ||
var BACKOFF_RETRY_DELAYS_SLOW = [2000, 30000, 60000, 300000]; | ||
var HEARTBEAT_INTERVAL = 30000; | ||
var PONG_TIMEOUT = 2000; | ||
function isValidRoomEventType(value) { | ||
return value === "my-presence" || value === "others" || value === "event" || value === "error" || value === "connection"; | ||
return "my-presence" === value || "others" === value || "event" === value || "error" === value || "connection" === value; | ||
} | ||
function makeIdFactory(connectionId) { | ||
var count = 0; | ||
return function () { | ||
return connectionId + ":" + count++; | ||
}; | ||
} | ||
function makeOthers(userMap) { | ||
var _ref; | ||
var users = Object.values(userMap).map(function (user) { | ||
user._hasReceivedInitialPresence; | ||
var publicKeys = LiveObject._objectWithoutPropertiesLoose(user, ["_hasReceivedInitialPresence"]); | ||
return publicKeys; | ||
}); | ||
return _ref = { | ||
get count() { | ||
return users.length; | ||
} | ||
}, _ref[Symbol.iterator] = function () { | ||
return users[Symbol.iterator](); | ||
}, _ref.map = function map(callback) { | ||
return users.map(callback); | ||
}, _ref.toArray = function toArray() { | ||
return users; | ||
}, _ref; | ||
var _ref, users = Object.values(userMap).map((function(user) { | ||
return user._hasReceivedInitialPresence, LiveObject._objectWithoutPropertiesLoose(user, _excluded); | ||
})); | ||
return (_ref = { | ||
get count() { | ||
return users.length; | ||
} | ||
})[Symbol.iterator] = function() { | ||
return users[Symbol.iterator](); | ||
}, _ref.map = function(callback) { | ||
return users.map(callback); | ||
}, _ref.toArray = function() { | ||
return users; | ||
}, _ref; | ||
} | ||
function makeStateMachine(state, context, mockedEffects) { | ||
var effects = mockedEffects || { | ||
authenticate: function authenticate(auth, createWebSocket) { | ||
var token = state.token; | ||
if (token && LiveObject.isTokenValid(token)) { | ||
var parsedToken = parseToken(token); | ||
var socket = createWebSocket(token); | ||
authenticationSuccess(parsedToken, socket); | ||
} else { | ||
return auth(context.roomId).then(function (_ref2) { | ||
var token = _ref2.token; | ||
if (state.connection.state !== "authenticating") { | ||
return; | ||
} | ||
var parsedToken = parseToken(token); | ||
var socket = createWebSocket(token); | ||
authenticationSuccess(parsedToken, socket); | ||
state.token = token; | ||
}).catch(function (er) { | ||
return authenticationFailure(er); | ||
}); | ||
} | ||
}, | ||
send: function send(messageOrMessages) { | ||
if (state.socket == null) { | ||
throw new Error("Can't send message if socket is null"); | ||
} | ||
state.socket.send(JSON.stringify(messageOrMessages)); | ||
}, | ||
delayFlush: function delayFlush(delay) { | ||
return setTimeout(tryFlushing, delay); | ||
}, | ||
startHeartbeatInterval: function startHeartbeatInterval() { | ||
return setInterval(heartbeat, HEARTBEAT_INTERVAL); | ||
}, | ||
schedulePongTimeout: function schedulePongTimeout() { | ||
return setTimeout(pongTimeout, PONG_TIMEOUT); | ||
}, | ||
scheduleReconnect: function scheduleReconnect(delay) { | ||
return setTimeout(connect, delay); | ||
} | ||
var effects = mockedEffects || { | ||
authenticate: function(auth, createWebSocket) { | ||
var token = state.token; | ||
if (!token || !LiveObject.isTokenValid(token)) return auth(context.roomId).then((function(_ref2) { | ||
var token = _ref2.token; | ||
"authenticating" === state.connection.state && (authenticationSuccess(parseToken(token), createWebSocket(token)), | ||
state.token = token); | ||
})).catch((function(er) { | ||
return function(error) { | ||
"production" !== process.env.NODE_ENV && console.error("Call to authentication endpoint failed", error); | ||
state.token = null, updateConnection({ | ||
state: "unavailable" | ||
}), state.numberOfRetry++, state.timeoutHandles.reconnect = effects.scheduleReconnect(getRetryDelay()); | ||
}(er); | ||
})); | ||
authenticationSuccess(parseToken(token), createWebSocket(token)); | ||
}, | ||
send: function(messageOrMessages) { | ||
if (null == state.socket) throw new Error("Can't send message if socket is null"); | ||
state.socket.send(JSON.stringify(messageOrMessages)); | ||
}, | ||
delayFlush: function(delay) { | ||
return setTimeout(tryFlushing, delay); | ||
}, | ||
startHeartbeatInterval: function() { | ||
return setInterval(heartbeat, 3e4); | ||
}, | ||
schedulePongTimeout: function() { | ||
return setTimeout(pongTimeout, 2e3); | ||
}, | ||
scheduleReconnect: function(delay) { | ||
return setTimeout(connect, delay); | ||
} | ||
}; | ||
function genericSubscribe(callback) { | ||
return state.listeners.storage.push(callback), function() { | ||
return LiveObject.remove(state.listeners.storage, callback); | ||
}; | ||
function genericSubscribe(callback) { | ||
state.listeners.storage.push(callback); | ||
return function () { | ||
return LiveObject.remove(state.listeners.storage, callback); | ||
}; | ||
} | ||
function crdtSubscribe(crdt, innerCallback, options) { | ||
var cb = function cb(updates) { | ||
var relatedUpdates = []; | ||
for (var _iterator = LiveObject._createForOfIteratorHelperLoose(updates), _step; !(_step = _iterator()).done;) { | ||
var update = _step.value; | ||
if (options != null && options.isDeep && LiveObject.isSameNodeOrChildOf(update.node, crdt)) { | ||
relatedUpdates.push(update); | ||
} else if (update.node._id === crdt._id) { | ||
innerCallback(update.node); | ||
} | ||
} | ||
if (options != null && options.isDeep && relatedUpdates.length > 0) { | ||
innerCallback(relatedUpdates); | ||
} | ||
}; | ||
return genericSubscribe(cb); | ||
} | ||
function createOrUpdateRootFromMessage(message) { | ||
if (message.items.length === 0) { | ||
throw new Error("Internal error: cannot load storage without items"); | ||
} | ||
function createOrUpdateRootFromMessage(message) { | ||
if (0 === message.items.length) throw new Error("Internal error: cannot load storage without items"); | ||
var items, _buildRootAndParentTo, root, parentToChildren; | ||
for (var _key in state.root ? function(items) { | ||
if (!state.root) return; | ||
var currentItems = new Map; | ||
state.items.forEach((function(liveCrdt, id) { | ||
currentItems.set(id, liveCrdt._toSerializedCrdt()); | ||
})), notify(apply(LiveObject.getTreesDiffOperations(currentItems, new Map(items)), !1).updates); | ||
}(message.items) : state.root = (items = message.items, _buildRootAndParentTo = function(items) { | ||
for (var _step2, parentToChildren = new Map, root = null, _iterator2 = LiveObject._createForOfIteratorHelperLoose(items); !(_step2 = _iterator2()).done; ) { | ||
var tuple = _step2.value, parentId = tuple[1].parentId; | ||
if (null == parentId) root = tuple; else { | ||
var children = parentToChildren.get(parentId); | ||
null != children ? children.push(tuple) : parentToChildren.set(parentId, [ tuple ]); | ||
} | ||
if (state.root) { | ||
updateRoot(message.items); | ||
} else { | ||
state.root = load(message.items); | ||
} | ||
for (var _key in state.defaultStorageRoot) { | ||
if (state.root.get(_key) == null) { | ||
state.root.set(_key, state.defaultStorageRoot[_key]); | ||
} | ||
} | ||
} | ||
if (null == root) throw new Error("Root can't be null"); | ||
return [ root, parentToChildren ]; | ||
}(items), root = _buildRootAndParentTo[0], parentToChildren = _buildRootAndParentTo[1], | ||
LiveObject.LiveObject._deserialize(root, parentToChildren, { | ||
getItem: getItem, | ||
addItem: addItem, | ||
deleteItem: deleteItem, | ||
generateId: generateId, | ||
generateOpId: generateOpId, | ||
dispatch: storageDispatch, | ||
roomId: context.roomId | ||
})), state.defaultStorageRoot) null == state.root.get(_key) && state.root.set(_key, state.defaultStorageRoot[_key]); | ||
} | ||
function addItem(id, item) { | ||
state.items.set(id, item); | ||
} | ||
function deleteItem(id) { | ||
state.items.delete(id); | ||
} | ||
function getItem(id) { | ||
return state.items.get(id); | ||
} | ||
function addToUndoStack(historyItem) { | ||
var _state$pausedHistory; | ||
(state.undoStack.length >= 50 && state.undoStack.shift(), state.isHistoryPaused) ? (_state$pausedHistory = state.pausedHistory).unshift.apply(_state$pausedHistory, historyItem) : state.undoStack.push(historyItem); | ||
} | ||
function storageDispatch(ops, reverse, storageUpdates) { | ||
var _state$batch$ops, _state$batch$reverseO; | ||
state.isBatching ? ((_state$batch$ops = state.batch.ops).push.apply(_state$batch$ops, ops), | ||
storageUpdates.forEach((function(value, key) { | ||
state.batch.updates.storageUpdates.set(key, LiveObject.mergeStorageUpdates(state.batch.updates.storageUpdates.get(key), value)); | ||
})), (_state$batch$reverseO = state.batch.reverseOps).push.apply(_state$batch$reverseO, reverse)) : (addToUndoStack(reverse), | ||
state.redoStack = [], dispatch(ops), notify({ | ||
storageUpdates: storageUpdates | ||
})); | ||
} | ||
function notify(_ref3) { | ||
var _ref3$storageUpdates = _ref3.storageUpdates, storageUpdates = void 0 === _ref3$storageUpdates ? new Map : _ref3$storageUpdates, _ref3$presence = _ref3.presence, presence = void 0 !== _ref3$presence && _ref3$presence, _ref3$others = _ref3.others, otherEvents = void 0 === _ref3$others ? [] : _ref3$others; | ||
if (otherEvents.length > 0) { | ||
state.others = makeOthers(state.users); | ||
for (var _step3, _iterator3 = LiveObject._createForOfIteratorHelperLoose(otherEvents); !(_step3 = _iterator3()).done; ) for (var _step4, _event = _step3.value, _iterator4 = LiveObject._createForOfIteratorHelperLoose(state.listeners.others); !(_step4 = _iterator4()).done; ) { | ||
(0, _step4.value)(state.others, _event); | ||
} | ||
} | ||
function buildRootAndParentToChildren(items) { | ||
var parentToChildren = new Map(); | ||
var root = null; | ||
for (var _iterator2 = LiveObject._createForOfIteratorHelperLoose(items), _step2; !(_step2 = _iterator2()).done;) { | ||
var tuple = _step2.value; | ||
var parentId = tuple[1].parentId; | ||
if (parentId == null) { | ||
root = tuple; | ||
} else { | ||
var children = parentToChildren.get(parentId); | ||
if (children != null) { | ||
children.push(tuple); | ||
} else { | ||
parentToChildren.set(parentId, [tuple]); | ||
} | ||
} | ||
} | ||
if (root == null) { | ||
throw new Error("Root can't be null"); | ||
} | ||
return [root, parentToChildren]; | ||
if (presence) for (var _step5, _iterator5 = LiveObject._createForOfIteratorHelperLoose(state.listeners["my-presence"]); !(_step5 = _iterator5()).done; ) { | ||
(0, _step5.value)(state.me); | ||
} | ||
function updateRoot(items) { | ||
if (!state.root) { | ||
return; | ||
} | ||
var currentItems = new Map(); | ||
state.items.forEach(function (liveCrdt, id) { | ||
currentItems.set(id, liveCrdt._toSerializedCrdt()); | ||
}); | ||
var ops = LiveObject.getTreesDiffOperations(currentItems, new Map(items)); | ||
var result = apply(ops, false); | ||
notify(result.updates); | ||
if (storageUpdates.size > 0) for (var _step6, _iterator6 = LiveObject._createForOfIteratorHelperLoose(state.listeners.storage); !(_step6 = _iterator6()).done; ) { | ||
(0, _step6.value)(Array.from(storageUpdates.values())); | ||
} | ||
function load(items) { | ||
var _buildRootAndParentTo = buildRootAndParentToChildren(items), | ||
root = _buildRootAndParentTo[0], | ||
parentToChildren = _buildRootAndParentTo[1]; | ||
return LiveObject.LiveObject._deserialize(root, parentToChildren, { | ||
getItem: getItem, | ||
addItem: addItem, | ||
deleteItem: deleteItem, | ||
generateId: generateId, | ||
generateOpId: generateOpId, | ||
dispatch: storageDispatch, | ||
roomId: context.roomId | ||
}); | ||
} | ||
function addItem(id, item) { | ||
state.items.set(id, item); | ||
} | ||
function deleteItem(id) { | ||
state.items.delete(id); | ||
} | ||
function getItem(id) { | ||
return state.items.get(id); | ||
} | ||
function addToUndoStack(historyItem) { | ||
if (state.undoStack.length >= 50) { | ||
state.undoStack.shift(); | ||
} | ||
if (state.isHistoryPaused) { | ||
var _state$pausedHistory; | ||
(_state$pausedHistory = state.pausedHistory).unshift.apply(_state$pausedHistory, historyItem); | ||
} else { | ||
state.undoStack.push(historyItem); | ||
} | ||
} | ||
function storageDispatch(ops, reverse, storageUpdates) { | ||
if (state.isBatching) { | ||
var _state$batch$ops, _state$batch$reverseO; | ||
(_state$batch$ops = state.batch.ops).push.apply(_state$batch$ops, ops); | ||
storageUpdates.forEach(function (value, key) { | ||
state.batch.updates.storageUpdates.set(key, LiveObject.mergeStorageUpdates(state.batch.updates.storageUpdates.get(key), value)); | ||
}); | ||
(_state$batch$reverseO = state.batch.reverseOps).push.apply(_state$batch$reverseO, reverse); | ||
} else { | ||
addToUndoStack(reverse); | ||
state.redoStack = []; | ||
dispatch(ops); | ||
notify({ | ||
storageUpdates: storageUpdates | ||
}); | ||
} | ||
} | ||
function notify(_ref3) { | ||
var _ref3$storageUpdates = _ref3.storageUpdates, | ||
storageUpdates = _ref3$storageUpdates === void 0 ? new Map() : _ref3$storageUpdates, | ||
_ref3$presence = _ref3.presence, | ||
presence = _ref3$presence === void 0 ? false : _ref3$presence, | ||
_ref3$others = _ref3.others, | ||
otherEvents = _ref3$others === void 0 ? [] : _ref3$others; | ||
if (otherEvents.length > 0) { | ||
state.others = makeOthers(state.users); | ||
for (var _iterator3 = LiveObject._createForOfIteratorHelperLoose(otherEvents), _step3; !(_step3 = _iterator3()).done;) { | ||
var event = _step3.value; | ||
for (var _iterator4 = LiveObject._createForOfIteratorHelperLoose(state.listeners.others), _step4; !(_step4 = _iterator4()).done;) { | ||
var _listener = _step4.value; | ||
_listener(state.others, event); | ||
} | ||
} | ||
} | ||
if (presence) { | ||
for (var _iterator5 = LiveObject._createForOfIteratorHelperLoose(state.listeners["my-presence"]), _step5; !(_step5 = _iterator5()).done;) { | ||
var _listener2 = _step5.value; | ||
_listener2(state.me); | ||
} | ||
} | ||
if (storageUpdates.size > 0) { | ||
for (var _iterator6 = LiveObject._createForOfIteratorHelperLoose(state.listeners.storage), _step6; !(_step6 = _iterator6()).done;) { | ||
var subscriber = _step6.value; | ||
subscriber(Array.from(storageUpdates.values())); | ||
} | ||
} | ||
} | ||
function getConnectionId() { | ||
if (state.connection.state === "open" || state.connection.state === "connecting") { | ||
return state.connection.id; | ||
} else if (state.lastConnectionId !== null) { | ||
return state.lastConnectionId; | ||
} | ||
throw new Error("Internal. Tried to get connection id but connection was never open"); | ||
} | ||
function generateId() { | ||
return getConnectionId() + ":" + state.clock++; | ||
} | ||
function generateOpId() { | ||
return getConnectionId() + ":" + state.opClock++; | ||
} | ||
function apply(item, isLocal) { | ||
var result = { | ||
reverse: [], | ||
updates: { | ||
storageUpdates: new Map(), | ||
presence: false | ||
} | ||
} | ||
function getConnectionId() { | ||
if ("open" === state.connection.state || "connecting" === state.connection.state) return state.connection.id; | ||
if (null !== state.lastConnectionId) return state.lastConnectionId; | ||
throw new Error("Internal. Tried to get connection id but connection was never open"); | ||
} | ||
function generateId() { | ||
return getConnectionId() + ":" + state.clock++; | ||
} | ||
function generateOpId() { | ||
return getConnectionId() + ":" + state.opClock++; | ||
} | ||
function apply(item, isLocal) { | ||
for (var _step7, result = { | ||
reverse: [], | ||
updates: { | ||
storageUpdates: new Map, | ||
presence: !1 | ||
} | ||
}, createdNodeIds = new Set, _iterator7 = LiveObject._createForOfIteratorHelperLoose(item); !(_step7 = _iterator7()).done; ) { | ||
var op = _step7.value; | ||
if ("presence" === op.type) { | ||
var reverse = { | ||
type: "presence", | ||
data: {} | ||
}; | ||
var createdNodeIds = new Set(); | ||
for (var _iterator7 = LiveObject._createForOfIteratorHelperLoose(item), _step7; !(_step7 = _iterator7()).done;) { | ||
var op = _step7.value; | ||
if (op.type === "presence") { | ||
var reverse = { | ||
type: "presence", | ||
data: {} | ||
}; | ||
for (var _key2 in op.data) { | ||
reverse.data[_key2] = state.me[_key2]; | ||
} | ||
state.me = LiveObject._extends({}, state.me, op.data); | ||
if (state.buffer.presence == null) { | ||
state.buffer.presence = op.data; | ||
} else { | ||
for (var _key3 in op.data) { | ||
state.buffer.presence[_key3] = op.data[_key3]; | ||
} | ||
} | ||
result.reverse.unshift(reverse); | ||
result.updates.presence = true; | ||
} else { | ||
if (isLocal && !op.opId) { | ||
op.opId = generateOpId(); | ||
} | ||
var applyOpResult = applyOp(op, isLocal); | ||
if (applyOpResult.modified) { | ||
var _applyOpResult$modifi; | ||
var parentId = (_applyOpResult$modifi = applyOpResult.modified.node._parent) == null ? void 0 : _applyOpResult$modifi._id; | ||
if (!createdNodeIds.has(parentId)) { | ||
var _result$reverse; | ||
result.updates.storageUpdates.set(applyOpResult.modified.node._id, LiveObject.mergeStorageUpdates(result.updates.storageUpdates.get(applyOpResult.modified.node._id), applyOpResult.modified)); | ||
(_result$reverse = result.reverse).unshift.apply(_result$reverse, applyOpResult.reverse); | ||
} | ||
if (op.type === LiveObject.OpType.CreateList || op.type === LiveObject.OpType.CreateMap || op.type === LiveObject.OpType.CreateObject) { | ||
createdNodeIds.add(applyOpResult.modified.node._id); | ||
} | ||
} | ||
} | ||
for (var _key2 in op.data) reverse.data[_key2] = state.me[_key2]; | ||
if (state.me = LiveObject._extends({}, state.me, op.data), null == state.buffer.presence) state.buffer.presence = op.data; else for (var _key3 in op.data) state.buffer.presence[_key3] = op.data[_key3]; | ||
result.reverse.unshift(reverse), result.updates.presence = !0; | ||
} else { | ||
isLocal && !op.opId && (op.opId = generateOpId()); | ||
var applyOpResult = applyOp(op, isLocal); | ||
if (applyOpResult.modified) { | ||
var _applyOpResult$modifi, _result$reverse, parentId = null == (_applyOpResult$modifi = applyOpResult.modified.node._parent) ? void 0 : _applyOpResult$modifi._id; | ||
if (!createdNodeIds.has(parentId)) result.updates.storageUpdates.set(applyOpResult.modified.node._id, LiveObject.mergeStorageUpdates(result.updates.storageUpdates.get(applyOpResult.modified.node._id), applyOpResult.modified)), | ||
(_result$reverse = result.reverse).unshift.apply(_result$reverse, applyOpResult.reverse); | ||
op.type !== LiveObject.OpType.CreateList && op.type !== LiveObject.OpType.CreateMap && op.type !== LiveObject.OpType.CreateObject || createdNodeIds.add(applyOpResult.modified.node._id); | ||
} | ||
return result; | ||
} | ||
} | ||
return result; | ||
} | ||
function applyOp(op, isLocal) { | ||
switch (op.opId && state.offlineOperations.delete(op.opId), op.type) { | ||
case LiveObject.OpType.DeleteObjectKey: | ||
case LiveObject.OpType.UpdateObject: | ||
case LiveObject.OpType.DeleteCrdt: | ||
var item = state.items.get(op.id); | ||
return null == item ? { | ||
modified: !1 | ||
} : item._apply(op, isLocal); | ||
function applyOp(op, isLocal) { | ||
if (op.opId) { | ||
state.offlineOperations.delete(op.opId); | ||
} | ||
case LiveObject.OpType.SetParentKey: | ||
var _item = state.items.get(op.id); | ||
if (null == _item) return { | ||
modified: !1 | ||
}; | ||
if (_item._parent instanceof LiveObject.LiveList) { | ||
var previousKey = _item._parentKey; | ||
return previousKey === op.parentKey ? { | ||
modified: !1 | ||
} : _item._parent._setChildKey(op.parentKey, _item, previousKey); | ||
} | ||
return { | ||
modified: !1 | ||
}; | ||
switch (op.type) { | ||
case LiveObject.OpType.DeleteObjectKey: | ||
case LiveObject.OpType.UpdateObject: | ||
case LiveObject.OpType.DeleteCrdt: | ||
{ | ||
var item = state.items.get(op.id); | ||
if (item == null) { | ||
return { | ||
modified: false | ||
}; | ||
} | ||
return item._apply(op, isLocal); | ||
} | ||
case LiveObject.OpType.SetParentKey: | ||
{ | ||
var _item = state.items.get(op.id); | ||
if (_item == null) { | ||
return { | ||
modified: false | ||
}; | ||
} | ||
if (_item._parent instanceof LiveObject.LiveList) { | ||
var previousKey = _item._parentKey; | ||
if (previousKey === op.parentKey) { | ||
return { | ||
modified: false | ||
}; | ||
} else { | ||
return _item._parent._setChildKey(op.parentKey, _item, previousKey); | ||
} | ||
} | ||
return { | ||
modified: false | ||
}; | ||
} | ||
case LiveObject.OpType.CreateObject: | ||
case LiveObject.OpType.CreateList: | ||
case LiveObject.OpType.CreateMap: | ||
case LiveObject.OpType.CreateRegister: | ||
{ | ||
var parent = state.items.get(op.parentId); | ||
if (parent == null) { | ||
return { | ||
modified: false | ||
}; | ||
} | ||
return parent._attachChild(op, isLocal); | ||
} | ||
} | ||
case LiveObject.OpType.CreateObject: | ||
case LiveObject.OpType.CreateList: | ||
case LiveObject.OpType.CreateMap: | ||
case LiveObject.OpType.CreateRegister: | ||
var parent = state.items.get(op.parentId); | ||
return null == parent ? { | ||
modified: !1 | ||
} : parent._attachChild(op, isLocal); | ||
} | ||
function subscribe(firstParam, listener, options) { | ||
if (firstParam instanceof LiveObject.AbstractCrdt) { | ||
return crdtSubscribe(firstParam, listener, options); | ||
} else if (typeof firstParam === "function") { | ||
return genericSubscribe(firstParam); | ||
} else if (!isValidRoomEventType(firstParam)) { | ||
throw new Error("\"" + firstParam + "\" is not a valid event name"); | ||
} | ||
state.listeners[firstParam].push(listener); | ||
return function () { | ||
var callbacks = state.listeners[firstParam]; | ||
LiveObject.remove(callbacks, listener); | ||
} | ||
function connect() { | ||
if ("closed" !== state.connection.state && "unavailable" !== state.connection.state) return null; | ||
var auth = function(authentication, fetchPolyfill) { | ||
if ("public" === authentication.type) { | ||
if ("undefined" == typeof window && null == fetchPolyfill) throw new Error("To use Liveblocks client in a non-dom environment with a publicApiKey, you need to provide a fetch polyfill."); | ||
return function(room) { | ||
return fetchAuthEndpoint(fetchPolyfill || fetch, authentication.url, { | ||
room: room, | ||
publicApiKey: authentication.publicApiKey | ||
}); | ||
}; | ||
} | ||
function unsubscribe(event, callback) { | ||
console.warn("unsubscribe is depreacted and will be removed in a future version.\nuse the callback returned by subscribe instead.\nSee v0.13 release notes for more information.\n"); | ||
if (!isValidRoomEventType(event)) { | ||
throw new Error("\"" + event + "\" is not a valid event name"); | ||
} | ||
var callbacks = state.listeners[event]; | ||
LiveObject.remove(callbacks, callback); | ||
} | ||
function getConnectionState() { | ||
return state.connection.state; | ||
} | ||
function getSelf() { | ||
return state.connection.state === "open" || state.connection.state === "connecting" ? { | ||
connectionId: state.connection.id, | ||
id: state.connection.userId, | ||
info: state.connection.userInfo, | ||
presence: getPresence() | ||
} : null; | ||
} | ||
function connect() { | ||
if (state.connection.state !== "closed" && state.connection.state !== "unavailable") { | ||
return null; | ||
} | ||
var auth = prepareAuthEndpoint(context.authentication, context.fetchPolyfill); | ||
var createWebSocket = prepareCreateWebSocket(context.liveblocksServer, context.WebSocketPolyfill); | ||
updateConnection({ | ||
state: "authenticating" | ||
}); | ||
effects.authenticate(auth, createWebSocket); | ||
} | ||
function updatePresence(overrides, options) { | ||
var oldValues = {}; | ||
if (state.buffer.presence == null) { | ||
state.buffer.presence = {}; | ||
} | ||
for (var _key4 in overrides) { | ||
state.buffer.presence[_key4] = overrides[_key4]; | ||
oldValues[_key4] = state.me[_key4]; | ||
} | ||
state.me = LiveObject._extends({}, state.me, overrides); | ||
if (state.isBatching) { | ||
if (options != null && options.addToHistory) { | ||
state.batch.reverseOps.push({ | ||
type: "presence", | ||
data: oldValues | ||
}); | ||
} | ||
state.batch.updates.presence = true; | ||
} else { | ||
tryFlushing(); | ||
if (options != null && options.addToHistory) { | ||
addToUndoStack([{ | ||
type: "presence", | ||
data: oldValues | ||
}]); | ||
} | ||
notify({ | ||
presence: true | ||
}); | ||
} | ||
} | ||
function authenticationSuccess(token, socket) { | ||
socket.addEventListener("message", onMessage); | ||
socket.addEventListener("open", onOpen); | ||
socket.addEventListener("close", onClose); | ||
socket.addEventListener("error", onError); | ||
updateConnection({ | ||
state: "connecting", | ||
id: token.actor, | ||
userInfo: token.info, | ||
userId: token.id | ||
}); | ||
state.idFactory = makeIdFactory(token.actor); | ||
state.socket = socket; | ||
} | ||
function authenticationFailure(error) { | ||
if (process.env.NODE_ENV !== "production") { | ||
console.error("Call to authentication endpoint failed", error); | ||
} | ||
state.token = null; | ||
updateConnection({ | ||
state: "unavailable" | ||
}); | ||
state.numberOfRetry++; | ||
state.timeoutHandles.reconnect = effects.scheduleReconnect(getRetryDelay()); | ||
} | ||
function onVisibilityChange(visibilityState) { | ||
if (visibilityState === "visible" && state.connection.state === "open") { | ||
heartbeat(); | ||
} | ||
} | ||
function onUpdatePresenceMessage(message) { | ||
var user = state.users[message.actor]; | ||
if (message.targetActor === undefined && user != null && !user._hasReceivedInitialPresence) { | ||
return undefined; | ||
} | ||
if (user == null) { | ||
state.users[message.actor] = { | ||
connectionId: message.actor, | ||
presence: message.data, | ||
_hasReceivedInitialPresence: true | ||
}; | ||
} else { | ||
state.users[message.actor] = { | ||
id: user.id, | ||
info: user.info, | ||
connectionId: message.actor, | ||
presence: LiveObject._extends({}, user.presence, message.data), | ||
_hasReceivedInitialPresence: true | ||
}; | ||
} | ||
return { | ||
type: "update", | ||
updates: message.data, | ||
user: state.users[message.actor] | ||
} | ||
if ("private" === authentication.type) { | ||
if ("undefined" == typeof window && null == fetchPolyfill) throw new Error("To use Liveblocks client in a non-dom environment with a url as auth endpoint, you need to provide a fetch polyfill."); | ||
return function(room) { | ||
return fetchAuthEndpoint(fetchPolyfill || fetch, authentication.url, { | ||
room: room | ||
}); | ||
}; | ||
} | ||
if ("custom" === authentication.type) return authentication.callback; | ||
throw new Error("Internal error. Unexpected authentication type"); | ||
}(context.authentication, context.fetchPolyfill), createWebSocket = function(liveblocksServer, WebSocketPolyfill) { | ||
if ("undefined" == typeof window && null == WebSocketPolyfill) throw new Error("To use Liveblocks client in a non-dom environment, you need to provide a WebSocket polyfill."); | ||
var ws = WebSocketPolyfill || WebSocket; | ||
return function(token) { | ||
return new ws(liveblocksServer + "/?token=" + token); | ||
}; | ||
}(context.liveblocksServer, context.WebSocketPolyfill); | ||
updateConnection({ | ||
state: "authenticating" | ||
}), effects.authenticate(auth, createWebSocket); | ||
} | ||
function authenticationSuccess(token, socket) { | ||
var connectionId, count; | ||
socket.addEventListener("message", onMessage), socket.addEventListener("open", onOpen), | ||
socket.addEventListener("close", onClose), socket.addEventListener("error", onError), | ||
updateConnection({ | ||
state: "connecting", | ||
id: token.actor, | ||
userInfo: token.info, | ||
userId: token.id | ||
}), state.idFactory = (connectionId = token.actor, count = 0, function() { | ||
return connectionId + ":" + count++; | ||
}), state.socket = socket; | ||
} | ||
function onUpdatePresenceMessage(message) { | ||
var user = state.users[message.actor]; | ||
if (void 0 !== message.targetActor || null == user || user._hasReceivedInitialPresence) return state.users[message.actor] = null == user ? { | ||
connectionId: message.actor, | ||
presence: message.data, | ||
_hasReceivedInitialPresence: !0 | ||
} : { | ||
id: user.id, | ||
info: user.info, | ||
connectionId: message.actor, | ||
presence: LiveObject._extends({}, user.presence, message.data), | ||
_hasReceivedInitialPresence: !0 | ||
}, { | ||
type: "update", | ||
updates: message.data, | ||
user: state.users[message.actor] | ||
}; | ||
} | ||
function onUserLeftMessage(message) { | ||
var userLeftMessage = message, user = state.users[userLeftMessage.actor]; | ||
return user ? (delete state.users[userLeftMessage.actor], { | ||
type: "leave", | ||
user: user | ||
}) : null; | ||
} | ||
function onRoomStateMessage(message) { | ||
var newUsers = {}; | ||
for (var _key5 in message.users) { | ||
var _connectionId = Number.parseInt(_key5), user = message.users[_key5]; | ||
newUsers[_connectionId] = { | ||
connectionId: _connectionId, | ||
info: user.info, | ||
id: user.id | ||
}; | ||
} | ||
function onUserLeftMessage(message) { | ||
var userLeftMessage = message; | ||
var user = state.users[userLeftMessage.actor]; | ||
if (user) { | ||
delete state.users[userLeftMessage.actor]; | ||
return { | ||
type: "leave", | ||
user: user | ||
}; | ||
} | ||
return null; | ||
return state.users = newUsers, { | ||
type: "reset" | ||
}; | ||
} | ||
function onEvent(message) { | ||
for (var _step8, _iterator8 = LiveObject._createForOfIteratorHelperLoose(state.listeners.event); !(_step8 = _iterator8()).done; ) { | ||
(0, _step8.value)({ | ||
connectionId: message.actor, | ||
event: message.event | ||
}); | ||
} | ||
} | ||
function onUserJoinedMessage(message) { | ||
return state.users[message.actor] = { | ||
connectionId: message.actor, | ||
info: message.info, | ||
id: message.id, | ||
_hasReceivedInitialPresence: !0 | ||
}, state.me && (state.buffer.messages.push({ | ||
type: LiveObject.ClientMessageType.UpdatePresence, | ||
data: state.me, | ||
targetActor: message.actor | ||
}), tryFlushing()), { | ||
type: "enter", | ||
user: state.users[message.actor] | ||
}; | ||
} | ||
function parseServerMessage(data) { | ||
return LiveObject.isJsonObject(data) ? data : null; | ||
} | ||
function onMessage(event) { | ||
if ("pong" !== event.data) { | ||
var text, data, messages = (text = event.data, void 0 === (data = LiveObject.parseJson(text)) ? null : LiveObject.isJsonArray(data) ? LiveObject.compact(data.map((function(item) { | ||
return parseServerMessage(item); | ||
}))) : LiveObject.compact([ parseServerMessage(data) ])); | ||
if (null !== messages && 0 !== messages.length) { | ||
for (var _step9, updates = { | ||
storageUpdates: new Map, | ||
others: [] | ||
}, _iterator9 = LiveObject._createForOfIteratorHelperLoose(messages); !(_step9 = _iterator9()).done; ) { | ||
var message = _step9.value; | ||
switch (message.type) { | ||
case LiveObject.ServerMessageType.UserJoined: | ||
updates.others.push(onUserJoinedMessage(message)); | ||
break; | ||
function onRoomStateMessage(message) { | ||
var newUsers = {}; | ||
case LiveObject.ServerMessageType.UpdatePresence: | ||
var othersPresenceUpdate = onUpdatePresenceMessage(message); | ||
othersPresenceUpdate && updates.others.push(othersPresenceUpdate); | ||
break; | ||
for (var _key5 in message.users) { | ||
var _connectionId = Number.parseInt(_key5); | ||
case LiveObject.ServerMessageType.Event: | ||
onEvent(message); | ||
break; | ||
var user = message.users[_key5]; | ||
newUsers[_connectionId] = { | ||
connectionId: _connectionId, | ||
info: user.info, | ||
id: user.id | ||
}; | ||
} | ||
case LiveObject.ServerMessageType.UserLeft: | ||
var _event2 = onUserLeftMessage(message); | ||
_event2 && updates.others.push(_event2); | ||
break; | ||
state.users = newUsers; | ||
return { | ||
type: "reset" | ||
}; | ||
} | ||
case LiveObject.ServerMessageType.RoomState: | ||
updates.others.push(onRoomStateMessage(message)); | ||
break; | ||
function onNavigatorOnline() { | ||
if (state.connection.state === "unavailable") { | ||
reconnect(); | ||
} | ||
} | ||
case LiveObject.ServerMessageType.InitialStorageState: | ||
var offlineOps = new Map(state.offlineOperations); | ||
createOrUpdateRootFromMessage(message), applyAndSendOfflineOps(offlineOps), null == _getInitialStateResolver || _getInitialStateResolver(); | ||
break; | ||
function onEvent(message) { | ||
for (var _iterator8 = LiveObject._createForOfIteratorHelperLoose(state.listeners.event), _step8; !(_step8 = _iterator8()).done;) { | ||
var _listener3 = _step8.value; | ||
_listener3({ | ||
connectionId: message.actor, | ||
event: message.event | ||
}); | ||
} | ||
} | ||
function onUserJoinedMessage(message) { | ||
state.users[message.actor] = { | ||
connectionId: message.actor, | ||
info: message.info, | ||
id: message.id, | ||
_hasReceivedInitialPresence: true | ||
}; | ||
if (state.me) { | ||
state.buffer.messages.push({ | ||
type: LiveObject.ClientMessageType.UpdatePresence, | ||
data: state.me, | ||
targetActor: message.actor | ||
}); | ||
tryFlushing(); | ||
} | ||
return { | ||
type: "enter", | ||
user: state.users[message.actor] | ||
}; | ||
} | ||
function parseServerMessage(data) { | ||
if (!LiveObject.isJsonObject(data)) { | ||
return null; | ||
} | ||
return data; | ||
} | ||
function parseServerMessages(text) { | ||
var data = LiveObject.parseJson(text); | ||
if (data === undefined) { | ||
return null; | ||
} else if (LiveObject.isJsonArray(data)) { | ||
return LiveObject.compact(data.map(function (item) { | ||
return parseServerMessage(item); | ||
case LiveObject.ServerMessageType.UpdateStorage: | ||
apply(message.ops, !1).updates.storageUpdates.forEach((function(value, key) { | ||
updates.storageUpdates.set(key, LiveObject.mergeStorageUpdates(updates.storageUpdates.get(key), value)); | ||
})); | ||
} else { | ||
return LiveObject.compact([parseServerMessage(data)]); | ||
} | ||
} | ||
} | ||
function onMessage(event) { | ||
if (event.data === "pong") { | ||
clearTimeout(state.timeoutHandles.pongTimeout); | ||
return; | ||
} | ||
var messages = parseServerMessages(event.data); | ||
if (messages === null || messages.length === 0) { | ||
return; | ||
} | ||
var updates = { | ||
storageUpdates: new Map(), | ||
others: [] | ||
}; | ||
for (var _iterator9 = LiveObject._createForOfIteratorHelperLoose(messages), _step9; !(_step9 = _iterator9()).done;) { | ||
var message = _step9.value; | ||
switch (message.type) { | ||
case LiveObject.ServerMessageType.UserJoined: | ||
{ | ||
updates.others.push(onUserJoinedMessage(message)); | ||
break; | ||
} | ||
case LiveObject.ServerMessageType.UpdatePresence: | ||
{ | ||
var othersPresenceUpdate = onUpdatePresenceMessage(message); | ||
if (othersPresenceUpdate) { | ||
updates.others.push(othersPresenceUpdate); | ||
} | ||
break; | ||
} | ||
case LiveObject.ServerMessageType.Event: | ||
{ | ||
onEvent(message); | ||
break; | ||
} | ||
case LiveObject.ServerMessageType.UserLeft: | ||
{ | ||
var _event = onUserLeftMessage(message); | ||
if (_event) { | ||
updates.others.push(_event); | ||
} | ||
break; | ||
} | ||
case LiveObject.ServerMessageType.RoomState: | ||
{ | ||
updates.others.push(onRoomStateMessage(message)); | ||
break; | ||
} | ||
case LiveObject.ServerMessageType.InitialStorageState: | ||
{ | ||
var offlineOps = new Map(state.offlineOperations); | ||
createOrUpdateRootFromMessage(message); | ||
applyAndSendOfflineOps(offlineOps); | ||
_getInitialStateResolver == null ? void 0 : _getInitialStateResolver(); | ||
break; | ||
} | ||
case LiveObject.ServerMessageType.UpdateStorage: | ||
{ | ||
var applyResult = apply(message.ops, false); | ||
applyResult.updates.storageUpdates.forEach(function (value, key) { | ||
updates.storageUpdates.set(key, LiveObject.mergeStorageUpdates(updates.storageUpdates.get(key), value)); | ||
}); | ||
break; | ||
} | ||
} | ||
} | ||
notify(updates); | ||
} | ||
} else clearTimeout(state.timeoutHandles.pongTimeout); | ||
} | ||
function onClose(event) { | ||
if (state.socket = null, clearTimeout(state.timeoutHandles.pongTimeout), clearInterval(state.intervalHandles.heartbeat), | ||
state.timeoutHandles.flush && clearTimeout(state.timeoutHandles.flush), clearTimeout(state.timeoutHandles.reconnect), | ||
state.users = {}, notify({ | ||
others: [ { | ||
type: "reset" | ||
} ] | ||
}), event.code >= 4e3 && event.code <= 4100) { | ||
updateConnection({ | ||
state: "failed" | ||
}); | ||
for (var _step10, error = new LiveblocksError(event.reason, event.code), _iterator10 = LiveObject._createForOfIteratorHelperLoose(state.listeners.error); !(_step10 = _iterator10()).done; ) { | ||
(0, _step10.value)(error); | ||
} | ||
var _delay = getRetryDelay(!0); | ||
state.numberOfRetry++, "production" !== process.env.NODE_ENV && console.error("Connection to Liveblocks websocket server closed. Reason: " + error.message + " (code: " + error.code + "). Retrying in " + _delay + "ms."), | ||
updateConnection({ | ||
state: "unavailable" | ||
}), state.timeoutHandles.reconnect = effects.scheduleReconnect(_delay); | ||
} else if (event.code === LiveObject.WebsocketCloseCodes.CLOSE_WITHOUT_RETRY) updateConnection({ | ||
state: "closed" | ||
}); else { | ||
var _delay2 = getRetryDelay(); | ||
state.numberOfRetry++, "production" !== process.env.NODE_ENV && console.warn("Connection to Liveblocks websocket server closed (code: " + event.code + "). Retrying in " + _delay2 + "ms."), | ||
updateConnection({ | ||
state: "unavailable" | ||
}), state.timeoutHandles.reconnect = effects.scheduleReconnect(_delay2); | ||
} | ||
function onClose(event) { | ||
state.socket = null; | ||
clearTimeout(state.timeoutHandles.pongTimeout); | ||
clearInterval(state.intervalHandles.heartbeat); | ||
if (state.timeoutHandles.flush) { | ||
clearTimeout(state.timeoutHandles.flush); | ||
} | ||
clearTimeout(state.timeoutHandles.reconnect); | ||
state.users = {}; | ||
notify({ | ||
others: [{ | ||
type: "reset" | ||
}] | ||
}); | ||
if (event.code >= 4000 && event.code <= 4100) { | ||
updateConnection({ | ||
state: "failed" | ||
}); | ||
var error = new LiveblocksError(event.reason, event.code); | ||
for (var _iterator10 = LiveObject._createForOfIteratorHelperLoose(state.listeners.error), _step10; !(_step10 = _iterator10()).done;) { | ||
var _listener4 = _step10.value; | ||
_listener4(error); | ||
} | ||
var _delay = getRetryDelay(true); | ||
state.numberOfRetry++; | ||
if (process.env.NODE_ENV !== "production") { | ||
console.error("Connection to Liveblocks websocket server closed. Reason: " + error.message + " (code: " + error.code + "). Retrying in " + _delay + "ms."); | ||
} | ||
updateConnection({ | ||
state: "unavailable" | ||
}); | ||
state.timeoutHandles.reconnect = effects.scheduleReconnect(_delay); | ||
} else if (event.code === LiveObject.WebsocketCloseCodes.CLOSE_WITHOUT_RETRY) { | ||
updateConnection({ | ||
state: "closed" | ||
}); | ||
} else { | ||
var _delay2 = getRetryDelay(); | ||
state.numberOfRetry++; | ||
if (process.env.NODE_ENV !== "production") { | ||
console.warn("Connection to Liveblocks websocket server closed (code: " + event.code + "). Retrying in " + _delay2 + "ms."); | ||
} | ||
updateConnection({ | ||
state: "unavailable" | ||
}); | ||
state.timeoutHandles.reconnect = effects.scheduleReconnect(_delay2); | ||
} | ||
} | ||
function updateConnection(connection) { | ||
state.connection = connection; | ||
for (var _step11, _iterator11 = LiveObject._createForOfIteratorHelperLoose(state.listeners.connection); !(_step11 = _iterator11()).done; ) { | ||
(0, _step11.value)(connection.state); | ||
} | ||
function updateConnection(connection) { | ||
state.connection = connection; | ||
for (var _iterator11 = LiveObject._createForOfIteratorHelperLoose(state.listeners.connection), _step11; !(_step11 = _iterator11()).done;) { | ||
var _listener5 = _step11.value; | ||
_listener5(connection.state); | ||
} | ||
} | ||
function getRetryDelay(slow) { | ||
return void 0 === slow && (slow = !1), slow ? BACKOFF_RETRY_DELAYS_SLOW[state.numberOfRetry < BACKOFF_RETRY_DELAYS_SLOW.length ? state.numberOfRetry : BACKOFF_RETRY_DELAYS_SLOW.length - 1] : BACKOFF_RETRY_DELAYS[state.numberOfRetry < BACKOFF_RETRY_DELAYS.length ? state.numberOfRetry : BACKOFF_RETRY_DELAYS.length - 1]; | ||
} | ||
function onError() {} | ||
function onOpen() { | ||
clearInterval(state.intervalHandles.heartbeat), state.intervalHandles.heartbeat = effects.startHeartbeatInterval(), | ||
"connecting" === state.connection.state && (updateConnection(LiveObject._extends({}, state.connection, { | ||
state: "open" | ||
})), state.numberOfRetry = 0, void 0 !== state.lastConnectionId && (state.buffer.presence = state.me, | ||
tryFlushing()), state.lastConnectionId = state.connection.id, state.root && state.buffer.messages.push({ | ||
type: LiveObject.ClientMessageType.FetchStorage | ||
}), tryFlushing()); | ||
} | ||
function heartbeat() { | ||
null != state.socket && (clearTimeout(state.timeoutHandles.pongTimeout), state.timeoutHandles.pongTimeout = effects.schedulePongTimeout(), | ||
state.socket.readyState === state.socket.OPEN && state.socket.send("ping")); | ||
} | ||
function pongTimeout() { | ||
reconnect(); | ||
} | ||
function reconnect() { | ||
state.socket && (state.socket.removeEventListener("open", onOpen), state.socket.removeEventListener("message", onMessage), | ||
state.socket.removeEventListener("close", onClose), state.socket.removeEventListener("error", onError), | ||
state.socket.close(), state.socket = null), updateConnection({ | ||
state: "unavailable" | ||
}), clearTimeout(state.timeoutHandles.pongTimeout), state.timeoutHandles.flush && clearTimeout(state.timeoutHandles.flush), | ||
clearTimeout(state.timeoutHandles.reconnect), clearInterval(state.intervalHandles.heartbeat), | ||
connect(); | ||
} | ||
function applyAndSendOfflineOps(offlineOps) { | ||
if (0 !== offlineOps.size) { | ||
var messages = [], ops = Array.from(offlineOps.values()), result = apply(ops, !0); | ||
messages.push({ | ||
type: LiveObject.ClientMessageType.UpdateStorage, | ||
ops: ops | ||
}), notify(result.updates), effects.send(messages); | ||
} | ||
function getRetryDelay(slow) { | ||
if (slow === void 0) { | ||
slow = false; | ||
} | ||
if (slow) { | ||
return BACKOFF_RETRY_DELAYS_SLOW[state.numberOfRetry < BACKOFF_RETRY_DELAYS_SLOW.length ? state.numberOfRetry : BACKOFF_RETRY_DELAYS_SLOW.length - 1]; | ||
} | ||
return BACKOFF_RETRY_DELAYS[state.numberOfRetry < BACKOFF_RETRY_DELAYS.length ? state.numberOfRetry : BACKOFF_RETRY_DELAYS.length - 1]; | ||
} | ||
function onError() {} | ||
function onOpen() { | ||
clearInterval(state.intervalHandles.heartbeat); | ||
state.intervalHandles.heartbeat = effects.startHeartbeatInterval(); | ||
if (state.connection.state === "connecting") { | ||
updateConnection(LiveObject._extends({}, state.connection, { | ||
state: "open" | ||
})); | ||
state.numberOfRetry = 0; | ||
if (state.lastConnectionId !== undefined) { | ||
state.buffer.presence = state.me; | ||
tryFlushing(); | ||
} | ||
state.lastConnectionId = state.connection.id; | ||
if (state.root) { | ||
state.buffer.messages.push({ | ||
type: LiveObject.ClientMessageType.FetchStorage | ||
}); | ||
} | ||
tryFlushing(); | ||
} | ||
} | ||
function heartbeat() { | ||
if (state.socket == null) { | ||
return; | ||
} | ||
clearTimeout(state.timeoutHandles.pongTimeout); | ||
state.timeoutHandles.pongTimeout = effects.schedulePongTimeout(); | ||
if (state.socket.readyState === state.socket.OPEN) { | ||
state.socket.send("ping"); | ||
} | ||
} | ||
function pongTimeout() { | ||
reconnect(); | ||
} | ||
function reconnect() { | ||
if (state.socket) { | ||
state.socket.removeEventListener("open", onOpen); | ||
state.socket.removeEventListener("message", onMessage); | ||
state.socket.removeEventListener("close", onClose); | ||
state.socket.removeEventListener("error", onError); | ||
state.socket.close(); | ||
state.socket = null; | ||
} | ||
updateConnection({ | ||
state: "unavailable" | ||
}); | ||
clearTimeout(state.timeoutHandles.pongTimeout); | ||
if (state.timeoutHandles.flush) { | ||
clearTimeout(state.timeoutHandles.flush); | ||
} | ||
clearTimeout(state.timeoutHandles.reconnect); | ||
clearInterval(state.intervalHandles.heartbeat); | ||
connect(); | ||
} | ||
function applyAndSendOfflineOps(offlineOps) { | ||
if (offlineOps.size === 0) { | ||
return; | ||
} | ||
var messages = []; | ||
var ops = Array.from(offlineOps.values()); | ||
var result = apply(ops, true); | ||
messages.push({ | ||
} | ||
function tryFlushing() { | ||
var storageOps = state.buffer.storageOperations; | ||
if (storageOps.length > 0 && storageOps.forEach((function(op) { | ||
state.offlineOperations.set(op.opId, op); | ||
})), null != state.socket && state.socket.readyState === state.socket.OPEN) { | ||
var now = Date.now(); | ||
if (now - state.lastFlushTime > context.throttleDelay) { | ||
var _messages = function(state) { | ||
var messages = []; | ||
state.buffer.presence && messages.push({ | ||
type: LiveObject.ClientMessageType.UpdatePresence, | ||
data: state.buffer.presence | ||
}); | ||
for (var _step12, _iterator12 = LiveObject._createForOfIteratorHelperLoose(state.buffer.messages); !(_step12 = _iterator12()).done; ) { | ||
var _event3 = _step12.value; | ||
messages.push(_event3); | ||
} | ||
state.buffer.storageOperations.length > 0 && messages.push({ | ||
type: LiveObject.ClientMessageType.UpdateStorage, | ||
ops: ops | ||
}); | ||
notify(result.updates); | ||
effects.send(messages); | ||
} | ||
function tryFlushing() { | ||
var storageOps = state.buffer.storageOperations; | ||
if (storageOps.length > 0) { | ||
storageOps.forEach(function (op) { | ||
state.offlineOperations.set(op.opId, op); | ||
}); | ||
ops: state.buffer.storageOperations | ||
}); | ||
return messages; | ||
}(state); | ||
if (0 === _messages.length) return; | ||
effects.send(_messages), state.buffer = { | ||
messages: [], | ||
storageOperations: [], | ||
presence: null | ||
}, state.lastFlushTime = now; | ||
} else null != state.timeoutHandles.flush && clearTimeout(state.timeoutHandles.flush), | ||
state.timeoutHandles.flush = effects.delayFlush(context.throttleDelay - (now - state.lastFlushTime)); | ||
} else state.buffer.storageOperations = []; | ||
} | ||
function getPresence() { | ||
return state.me; | ||
} | ||
function dispatch(ops) { | ||
var _state$buffer$storage; | ||
(_state$buffer$storage = state.buffer.storageOperations).push.apply(_state$buffer$storage, ops), | ||
tryFlushing(); | ||
} | ||
var _getInitialStatePromise = null, _getInitialStateResolver = null; | ||
return { | ||
onClose: onClose, | ||
onMessage: onMessage, | ||
authenticationSuccess: authenticationSuccess, | ||
heartbeat: heartbeat, | ||
onNavigatorOnline: function() { | ||
"unavailable" === state.connection.state && reconnect(); | ||
}, | ||
simulateSocketClose: function() { | ||
state.socket && state.socket.close(); | ||
}, | ||
simulateSendCloseEvent: function(event) { | ||
state.socket && onClose(event); | ||
}, | ||
onVisibilityChange: function(visibilityState) { | ||
"visible" === visibilityState && "open" === state.connection.state && heartbeat(); | ||
}, | ||
getUndoStack: function() { | ||
return state.undoStack; | ||
}, | ||
getItemsCount: function() { | ||
return state.items.size; | ||
}, | ||
connect: connect, | ||
disconnect: function() { | ||
state.socket && (state.socket.removeEventListener("open", onOpen), state.socket.removeEventListener("message", onMessage), | ||
state.socket.removeEventListener("close", onClose), state.socket.removeEventListener("error", onError), | ||
state.socket.close(), state.socket = null), updateConnection({ | ||
state: "closed" | ||
}), state.timeoutHandles.flush && clearTimeout(state.timeoutHandles.flush), clearTimeout(state.timeoutHandles.reconnect), | ||
clearTimeout(state.timeoutHandles.pongTimeout), clearInterval(state.intervalHandles.heartbeat), | ||
state.users = {}, notify({ | ||
others: [ { | ||
type: "reset" | ||
} ] | ||
}), function() { | ||
for (var _key6 in state.listeners) state.listeners[_key6] = []; | ||
}(); | ||
}, | ||
subscribe: function(firstParam, listener, options) { | ||
if (firstParam instanceof LiveObject.AbstractCrdt) return function(crdt, innerCallback, options) { | ||
return genericSubscribe((function(updates) { | ||
for (var _step, relatedUpdates = [], _iterator = LiveObject._createForOfIteratorHelperLoose(updates); !(_step = _iterator()).done; ) { | ||
var update = _step.value; | ||
null != options && options.isDeep && LiveObject.isSameNodeOrChildOf(update.node, crdt) ? relatedUpdates.push(update) : update.node._id === crdt._id && innerCallback(update.node); | ||
} | ||
null != options && options.isDeep && relatedUpdates.length > 0 && innerCallback(relatedUpdates); | ||
})); | ||
}(firstParam, listener, options); | ||
if ("function" == typeof firstParam) return genericSubscribe(firstParam); | ||
if (!isValidRoomEventType(firstParam)) throw new Error('"' + firstParam + '" is not a valid event name'); | ||
return state.listeners[firstParam].push(listener), function() { | ||
var callbacks = state.listeners[firstParam]; | ||
LiveObject.remove(callbacks, listener); | ||
}; | ||
}, | ||
unsubscribe: function(event, callback) { | ||
if (console.warn("unsubscribe is depreacted and will be removed in a future version.\nuse the callback returned by subscribe instead.\nSee v0.13 release notes for more information.\n"), | ||
!isValidRoomEventType(event)) throw new Error('"' + event + '" is not a valid event name'); | ||
var callbacks = state.listeners[event]; | ||
LiveObject.remove(callbacks, callback); | ||
}, | ||
updatePresence: function(overrides, options) { | ||
var oldValues = {}; | ||
for (var _key4 in null == state.buffer.presence && (state.buffer.presence = {}), | ||
overrides) state.buffer.presence[_key4] = overrides[_key4], oldValues[_key4] = state.me[_key4]; | ||
state.me = LiveObject._extends({}, state.me, overrides), state.isBatching ? (null != options && options.addToHistory && state.batch.reverseOps.push({ | ||
type: "presence", | ||
data: oldValues | ||
}), state.batch.updates.presence = !0) : (tryFlushing(), null != options && options.addToHistory && addToUndoStack([ { | ||
type: "presence", | ||
data: oldValues | ||
} ]), notify({ | ||
presence: !0 | ||
})); | ||
}, | ||
broadcastEvent: function(event, options) { | ||
void 0 === options && (options = { | ||
shouldQueueEventIfNotReady: !1 | ||
}), null == state.socket && 0 == options.shouldQueueEventIfNotReady || (state.buffer.messages.push({ | ||
type: LiveObject.ClientMessageType.ClientEvent, | ||
event: event | ||
}), tryFlushing()); | ||
}, | ||
batch: function(callback) { | ||
if (state.isBatching) throw new Error("batch should not be called during a batch"); | ||
state.isBatching = !0; | ||
try { | ||
callback(); | ||
} finally { | ||
state.isBatching = !1, state.batch.reverseOps.length > 0 && addToUndoStack(state.batch.reverseOps), | ||
state.batch.ops.length > 0 && (state.redoStack = []), state.batch.ops.length > 0 && dispatch(state.batch.ops), | ||
notify(state.batch.updates), state.batch = { | ||
ops: [], | ||
reverseOps: [], | ||
updates: { | ||
others: [], | ||
storageUpdates: new Map, | ||
presence: !1 | ||
} | ||
}, tryFlushing(); | ||
} | ||
}, | ||
undo: function() { | ||
if (state.isBatching) throw new Error("undo is not allowed during a batch"); | ||
var historyItem = state.undoStack.pop(); | ||
if (null != historyItem) { | ||
state.isHistoryPaused = !1; | ||
var result = apply(historyItem, !0); | ||
notify(result.updates), state.redoStack.push(result.reverse); | ||
for (var _step13, _iterator13 = LiveObject._createForOfIteratorHelperLoose(historyItem); !(_step13 = _iterator13()).done; ) { | ||
var op = _step13.value; | ||
"presence" !== op.type && state.buffer.storageOperations.push(op); | ||
} | ||
if (state.socket == null || state.socket.readyState !== state.socket.OPEN) { | ||
state.buffer.storageOperations = []; | ||
return; | ||
tryFlushing(); | ||
} | ||
}, | ||
redo: function() { | ||
if (state.isBatching) throw new Error("redo is not allowed during a batch"); | ||
var historyItem = state.redoStack.pop(); | ||
if (null != historyItem) { | ||
state.isHistoryPaused = !1; | ||
var result = apply(historyItem, !0); | ||
notify(result.updates), state.undoStack.push(result.reverse); | ||
for (var _step14, _iterator14 = LiveObject._createForOfIteratorHelperLoose(historyItem); !(_step14 = _iterator14()).done; ) { | ||
var op = _step14.value; | ||
"presence" !== op.type && state.buffer.storageOperations.push(op); | ||
} | ||
var now = Date.now(); | ||
var elapsedTime = now - state.lastFlushTime; | ||
if (elapsedTime > context.throttleDelay) { | ||
var _messages = flushDataToMessages(state); | ||
if (_messages.length === 0) { | ||
return; | ||
} | ||
effects.send(_messages); | ||
state.buffer = { | ||
messages: [], | ||
storageOperations: [], | ||
presence: null | ||
}; | ||
state.lastFlushTime = now; | ||
} else { | ||
if (state.timeoutHandles.flush != null) { | ||
clearTimeout(state.timeoutHandles.flush); | ||
} | ||
state.timeoutHandles.flush = effects.delayFlush(context.throttleDelay - (now - state.lastFlushTime)); | ||
} | ||
} | ||
function flushDataToMessages(state) { | ||
var messages = []; | ||
if (state.buffer.presence) { | ||
messages.push({ | ||
type: LiveObject.ClientMessageType.UpdatePresence, | ||
data: state.buffer.presence | ||
}); | ||
} | ||
for (var _iterator12 = LiveObject._createForOfIteratorHelperLoose(state.buffer.messages), _step12; !(_step12 = _iterator12()).done;) { | ||
var event = _step12.value; | ||
messages.push(event); | ||
} | ||
if (state.buffer.storageOperations.length > 0) { | ||
messages.push({ | ||
type: LiveObject.ClientMessageType.UpdateStorage, | ||
ops: state.buffer.storageOperations | ||
}); | ||
} | ||
return messages; | ||
} | ||
function disconnect() { | ||
if (state.socket) { | ||
state.socket.removeEventListener("open", onOpen); | ||
state.socket.removeEventListener("message", onMessage); | ||
state.socket.removeEventListener("close", onClose); | ||
state.socket.removeEventListener("error", onError); | ||
state.socket.close(); | ||
state.socket = null; | ||
} | ||
updateConnection({ | ||
state: "closed" | ||
tryFlushing(); | ||
} | ||
}, | ||
pauseHistory: function() { | ||
state.pausedHistory = [], state.isHistoryPaused = !0; | ||
}, | ||
resumeHistory: function() { | ||
state.isHistoryPaused = !1, state.pausedHistory.length > 0 && addToUndoStack(state.pausedHistory), | ||
state.pausedHistory = []; | ||
}, | ||
getStorage: function() { | ||
return state.root ? new Promise((function(resolve) { | ||
return resolve({ | ||
root: state.root | ||
}); | ||
if (state.timeoutHandles.flush) { | ||
clearTimeout(state.timeoutHandles.flush); | ||
} | ||
clearTimeout(state.timeoutHandles.reconnect); | ||
clearTimeout(state.timeoutHandles.pongTimeout); | ||
clearInterval(state.intervalHandles.heartbeat); | ||
state.users = {}; | ||
notify({ | ||
others: [{ | ||
type: "reset" | ||
}] | ||
}); | ||
clearListeners(); | ||
} | ||
function clearListeners() { | ||
for (var _key6 in state.listeners) { | ||
state.listeners[_key6] = []; | ||
} | ||
} | ||
function getPresence() { | ||
return state.me; | ||
} | ||
function getOthers() { | ||
})) : (null == _getInitialStatePromise && (state.buffer.messages.push({ | ||
type: LiveObject.ClientMessageType.FetchStorage | ||
}), tryFlushing(), _getInitialStatePromise = new Promise((function(resolve) { | ||
return _getInitialStateResolver = resolve; | ||
}))), _getInitialStatePromise.then((function() { | ||
return { | ||
root: state.root | ||
}; | ||
}))); | ||
}, | ||
selectors: { | ||
getConnectionState: function() { | ||
return state.connection.state; | ||
}, | ||
getSelf: function() { | ||
return "open" === state.connection.state || "connecting" === state.connection.state ? { | ||
connectionId: state.connection.id, | ||
id: state.connection.userId, | ||
info: state.connection.userInfo, | ||
presence: getPresence() | ||
} : null; | ||
}, | ||
getPresence: getPresence, | ||
getOthers: function() { | ||
return state.others; | ||
} | ||
} | ||
}; | ||
} | ||
function broadcastEvent(event, options) { | ||
if (options === void 0) { | ||
options = { | ||
shouldQueueEventIfNotReady: false | ||
}; | ||
} | ||
if (state.socket == null && options.shouldQueueEventIfNotReady == false) { | ||
return; | ||
} | ||
state.buffer.messages.push({ | ||
type: LiveObject.ClientMessageType.ClientEvent, | ||
event: event | ||
}); | ||
tryFlushing(); | ||
} | ||
function dispatch(ops) { | ||
var _state$buffer$storage; | ||
(_state$buffer$storage = state.buffer.storageOperations).push.apply(_state$buffer$storage, ops); | ||
tryFlushing(); | ||
} | ||
var _getInitialStatePromise = null; | ||
var _getInitialStateResolver = null; | ||
function getStorage() { | ||
if (state.root) { | ||
return new Promise(function (resolve) { | ||
return resolve({ | ||
root: state.root | ||
}); | ||
}); | ||
} | ||
if (_getInitialStatePromise == null) { | ||
state.buffer.messages.push({ | ||
type: LiveObject.ClientMessageType.FetchStorage | ||
}); | ||
tryFlushing(); | ||
_getInitialStatePromise = new Promise(function (resolve) { | ||
return _getInitialStateResolver = resolve; | ||
}); | ||
} | ||
return _getInitialStatePromise.then(function () { | ||
return { | ||
root: state.root | ||
}; | ||
}); | ||
} | ||
function undo() { | ||
if (state.isBatching) { | ||
throw new Error("undo is not allowed during a batch"); | ||
} | ||
var historyItem = state.undoStack.pop(); | ||
if (historyItem == null) { | ||
return; | ||
} | ||
state.isHistoryPaused = false; | ||
var result = apply(historyItem, true); | ||
notify(result.updates); | ||
state.redoStack.push(result.reverse); | ||
for (var _iterator13 = LiveObject._createForOfIteratorHelperLoose(historyItem), _step13; !(_step13 = _iterator13()).done;) { | ||
var op = _step13.value; | ||
if (op.type !== "presence") { | ||
state.buffer.storageOperations.push(op); | ||
} | ||
} | ||
tryFlushing(); | ||
} | ||
function redo() { | ||
if (state.isBatching) { | ||
throw new Error("redo is not allowed during a batch"); | ||
} | ||
var historyItem = state.redoStack.pop(); | ||
if (historyItem == null) { | ||
return; | ||
} | ||
state.isHistoryPaused = false; | ||
var result = apply(historyItem, true); | ||
notify(result.updates); | ||
state.undoStack.push(result.reverse); | ||
for (var _iterator14 = LiveObject._createForOfIteratorHelperLoose(historyItem), _step14; !(_step14 = _iterator14()).done;) { | ||
var op = _step14.value; | ||
if (op.type !== "presence") { | ||
state.buffer.storageOperations.push(op); | ||
} | ||
} | ||
tryFlushing(); | ||
} | ||
function batch(callback) { | ||
if (state.isBatching) { | ||
throw new Error("batch should not be called during a batch"); | ||
} | ||
state.isBatching = true; | ||
try { | ||
callback(); | ||
} finally { | ||
state.isBatching = false; | ||
if (state.batch.reverseOps.length > 0) { | ||
addToUndoStack(state.batch.reverseOps); | ||
} | ||
if (state.batch.ops.length > 0) { | ||
state.redoStack = []; | ||
} | ||
if (state.batch.ops.length > 0) { | ||
dispatch(state.batch.ops); | ||
} | ||
notify(state.batch.updates); | ||
state.batch = { | ||
ops: [], | ||
reverseOps: [], | ||
updates: { | ||
others: [], | ||
storageUpdates: new Map(), | ||
presence: false | ||
} | ||
}; | ||
tryFlushing(); | ||
} | ||
} | ||
function pauseHistory() { | ||
state.pausedHistory = []; | ||
state.isHistoryPaused = true; | ||
} | ||
function resumeHistory() { | ||
state.isHistoryPaused = false; | ||
if (state.pausedHistory.length > 0) { | ||
addToUndoStack(state.pausedHistory); | ||
} | ||
state.pausedHistory = []; | ||
} | ||
function simulateSocketClose() { | ||
if (state.socket) { | ||
state.socket.close(); | ||
} | ||
} | ||
function simulateSendCloseEvent(event) { | ||
if (state.socket) { | ||
onClose(event); | ||
} | ||
} | ||
function createRoom(options, context) { | ||
var _options$initialPrese, _options$initialStora, initialPresence = null != (_options$initialPrese = options.initialPresence) ? _options$initialPrese : options.defaultPresence, initialStorage = null != (_options$initialStora = options.initialStorage) ? _options$initialStora : options.defaultStorageRoot, machine = makeStateMachine(function(initialPresence, initialStorage) { | ||
return { | ||
onClose: onClose, | ||
onMessage: onMessage, | ||
authenticationSuccess: authenticationSuccess, | ||
heartbeat: heartbeat, | ||
onNavigatorOnline: onNavigatorOnline, | ||
simulateSocketClose: simulateSocketClose, | ||
simulateSendCloseEvent: simulateSendCloseEvent, | ||
onVisibilityChange: onVisibilityChange, | ||
getUndoStack: function getUndoStack() { | ||
return state.undoStack; | ||
connection: { | ||
state: "closed" | ||
}, | ||
token: null, | ||
lastConnectionId: null, | ||
socket: null, | ||
listeners: { | ||
event: [], | ||
others: [], | ||
"my-presence": [], | ||
error: [], | ||
connection: [], | ||
storage: [] | ||
}, | ||
numberOfRetry: 0, | ||
lastFlushTime: 0, | ||
timeoutHandles: { | ||
flush: null, | ||
reconnect: 0, | ||
pongTimeout: 0 | ||
}, | ||
buffer: { | ||
presence: null == initialPresence ? {} : initialPresence, | ||
messages: [], | ||
storageOperations: [] | ||
}, | ||
intervalHandles: { | ||
heartbeat: 0 | ||
}, | ||
me: null == initialPresence ? {} : initialPresence, | ||
users: {}, | ||
others: makeOthers({}), | ||
defaultStorageRoot: initialStorage, | ||
idFactory: null, | ||
clock: 0, | ||
opClock: 0, | ||
items: new Map, | ||
root: void 0, | ||
undoStack: [], | ||
redoStack: [], | ||
isHistoryPaused: !1, | ||
pausedHistory: [], | ||
isBatching: !1, | ||
batch: { | ||
ops: [], | ||
updates: { | ||
storageUpdates: new Map, | ||
presence: !1, | ||
others: [] | ||
}, | ||
getItemsCount: function getItemsCount() { | ||
return state.items.size; | ||
}, | ||
connect: connect, | ||
disconnect: disconnect, | ||
subscribe: subscribe, | ||
unsubscribe: unsubscribe, | ||
updatePresence: updatePresence, | ||
broadcastEvent: broadcastEvent, | ||
batch: batch, | ||
undo: undo, | ||
redo: redo, | ||
pauseHistory: pauseHistory, | ||
resumeHistory: resumeHistory, | ||
getStorage: getStorage, | ||
selectors: { | ||
getConnectionState: getConnectionState, | ||
getSelf: getSelf, | ||
getPresence: getPresence, | ||
getOthers: getOthers | ||
} | ||
reverseOps: [] | ||
}, | ||
offlineOperations: new Map | ||
}; | ||
}("function" == typeof initialPresence ? initialPresence(context.roomId) : initialPresence, "function" == typeof initialStorage ? initialStorage(context.roomId) : initialStorage), context), room = { | ||
id: context.roomId, | ||
getConnectionState: machine.selectors.getConnectionState, | ||
getSelf: machine.selectors.getSelf, | ||
subscribe: machine.subscribe, | ||
unsubscribe: machine.unsubscribe, | ||
getPresence: machine.selectors.getPresence, | ||
updatePresence: machine.updatePresence, | ||
getOthers: machine.selectors.getOthers, | ||
broadcastEvent: machine.broadcastEvent, | ||
getStorage: machine.getStorage, | ||
batch: machine.batch, | ||
history: { | ||
undo: machine.undo, | ||
redo: machine.redo, | ||
pause: machine.pauseHistory, | ||
resume: machine.resumeHistory | ||
}, | ||
internalDevTools: { | ||
closeWebsocket: machine.simulateSocketClose, | ||
sendCloseEvent: machine.simulateSendCloseEvent | ||
} | ||
}; | ||
return { | ||
connect: machine.connect, | ||
disconnect: machine.disconnect, | ||
onNavigatorOnline: machine.onNavigatorOnline, | ||
onVisibilityChange: machine.onVisibilityChange, | ||
room: room | ||
}; | ||
} | ||
function defaultState(initialPresence, initialStorage) { | ||
return { | ||
connection: { | ||
state: "closed" | ||
}, | ||
token: null, | ||
lastConnectionId: null, | ||
socket: null, | ||
listeners: { | ||
event: [], | ||
others: [], | ||
"my-presence": [], | ||
error: [], | ||
connection: [], | ||
storage: [] | ||
}, | ||
numberOfRetry: 0, | ||
lastFlushTime: 0, | ||
timeoutHandles: { | ||
flush: null, | ||
reconnect: 0, | ||
pongTimeout: 0 | ||
}, | ||
buffer: { | ||
presence: initialPresence == null ? {} : initialPresence, | ||
messages: [], | ||
storageOperations: [] | ||
}, | ||
intervalHandles: { | ||
heartbeat: 0 | ||
}, | ||
me: initialPresence == null ? {} : initialPresence, | ||
users: {}, | ||
others: makeOthers({}), | ||
defaultStorageRoot: initialStorage, | ||
idFactory: null, | ||
clock: 0, | ||
opClock: 0, | ||
items: new Map(), | ||
root: undefined, | ||
undoStack: [], | ||
redoStack: [], | ||
isHistoryPaused: false, | ||
pausedHistory: [], | ||
isBatching: false, | ||
batch: { | ||
ops: [], | ||
updates: { | ||
storageUpdates: new Map(), | ||
presence: false, | ||
others: [] | ||
}, | ||
reverseOps: [] | ||
}, | ||
offlineOperations: new Map() | ||
}; | ||
} | ||
function createRoom(options, context) { | ||
var _options$initialPrese, _options$initialStora; | ||
var initialPresence = (_options$initialPrese = options.initialPresence) != null ? _options$initialPrese : options.defaultPresence; | ||
var initialStorage = (_options$initialStora = options.initialStorage) != null ? _options$initialStora : options.defaultStorageRoot; | ||
var state = defaultState(typeof initialPresence === "function" ? initialPresence(context.roomId) : initialPresence, typeof initialStorage === "function" ? initialStorage(context.roomId) : initialStorage); | ||
var machine = makeStateMachine(state, context); | ||
var room = { | ||
id: context.roomId, | ||
getConnectionState: machine.selectors.getConnectionState, | ||
getSelf: machine.selectors.getSelf, | ||
subscribe: machine.subscribe, | ||
unsubscribe: machine.unsubscribe, | ||
getPresence: machine.selectors.getPresence, | ||
updatePresence: machine.updatePresence, | ||
getOthers: machine.selectors.getOthers, | ||
broadcastEvent: machine.broadcastEvent, | ||
getStorage: machine.getStorage, | ||
batch: machine.batch, | ||
history: { | ||
undo: machine.undo, | ||
redo: machine.redo, | ||
pause: machine.pauseHistory, | ||
resume: machine.resumeHistory | ||
}, | ||
internalDevTools: { | ||
closeWebsocket: machine.simulateSocketClose, | ||
sendCloseEvent: machine.simulateSendCloseEvent | ||
} | ||
}; | ||
return { | ||
connect: machine.connect, | ||
disconnect: machine.disconnect, | ||
onNavigatorOnline: machine.onNavigatorOnline, | ||
onVisibilityChange: machine.onVisibilityChange, | ||
room: room | ||
}; | ||
} | ||
var LiveblocksError = function (_Error) { | ||
LiveObject._inheritsLoose(LiveblocksError, _Error); | ||
function LiveblocksError(message, code) { | ||
var _this; | ||
_this = _Error.call(this, message) || this; | ||
_this.code = code; | ||
return _this; | ||
} | ||
return LiveblocksError; | ||
var LiveblocksError = function(_Error) { | ||
function LiveblocksError(message, code) { | ||
return _Error.call(this, message) || this; | ||
} | ||
return LiveObject._inheritsLoose(LiveblocksError, _Error), LiveblocksError; | ||
}(LiveObject._wrapNativeSuper(Error)); | ||
function parseToken(token) { | ||
var tokenParts = token.split("."); | ||
if (tokenParts.length !== 3) { | ||
throw new Error("Authentication error. Liveblocks could not parse the response of your authentication endpoint"); | ||
} | ||
var data = LiveObject.parseJson(atob(tokenParts[1])); | ||
if (data !== undefined && LiveObject.isJsonObject(data) && typeof data.actor === "number" && (data.id === undefined || typeof data.id === "string")) { | ||
return { | ||
actor: data.actor, | ||
id: data.id, | ||
info: data.info | ||
}; | ||
} | ||
throw new Error("Authentication error. Liveblocks could not parse the response of your authentication endpoint"); | ||
var tokenParts = token.split("."); | ||
if (3 !== tokenParts.length) throw new Error("Authentication error. Liveblocks could not parse the response of your authentication endpoint"); | ||
var data = LiveObject.parseJson(atob(tokenParts[1])); | ||
if (void 0 !== data && LiveObject.isJsonObject(data) && "number" == typeof data.actor && (void 0 === data.id || "string" == typeof data.id)) return { | ||
actor: data.actor, | ||
id: data.id, | ||
info: data.info | ||
}; | ||
throw new Error("Authentication error. Liveblocks could not parse the response of your authentication endpoint"); | ||
} | ||
function prepareCreateWebSocket(liveblocksServer, WebSocketPolyfill) { | ||
if (typeof window === "undefined" && WebSocketPolyfill == null) { | ||
throw new Error("To use Liveblocks client in a non-dom environment, you need to provide a WebSocket polyfill."); | ||
} | ||
var ws = WebSocketPolyfill || WebSocket; | ||
return function (token) { | ||
return new ws(liveblocksServer + "/?token=" + token); | ||
}; | ||
} | ||
function prepareAuthEndpoint(authentication, fetchPolyfill) { | ||
if (authentication.type === "public") { | ||
if (typeof window === "undefined" && fetchPolyfill == null) { | ||
throw new Error("To use Liveblocks client in a non-dom environment with a publicApiKey, you need to provide a fetch polyfill."); | ||
} | ||
return function (room) { | ||
return fetchAuthEndpoint(fetchPolyfill || fetch, authentication.url, { | ||
room: room, | ||
publicApiKey: authentication.publicApiKey | ||
}); | ||
}; | ||
} | ||
if (authentication.type === "private") { | ||
if (typeof window === "undefined" && fetchPolyfill == null) { | ||
throw new Error("To use Liveblocks client in a non-dom environment with a url as auth endpoint, you need to provide a fetch polyfill."); | ||
} | ||
return function (room) { | ||
return fetchAuthEndpoint(fetchPolyfill || fetch, authentication.url, { | ||
room: room | ||
}); | ||
}; | ||
} | ||
if (authentication.type === "custom") { | ||
return authentication.callback; | ||
} | ||
throw new Error("Internal error. Unexpected authentication type"); | ||
} | ||
function fetchAuthEndpoint(fetch, endpoint, body) { | ||
return fetch(endpoint, { | ||
method: "POST", | ||
headers: { | ||
"Content-Type": "application/json" | ||
}, | ||
body: JSON.stringify(body) | ||
}).then(function (res) { | ||
if (!res.ok) { | ||
throw new AuthenticationError("Expected a status 200 but got " + res.status + " when doing a POST request on \"" + endpoint + "\""); | ||
} | ||
return res.json().catch(function (er) { | ||
throw new AuthenticationError("Expected a json when doing a POST request on \"" + endpoint + "\". " + er); | ||
}); | ||
}).then(function (authResponse) { | ||
if (typeof authResponse.token !== "string") { | ||
throw new AuthenticationError("Expected a json with a string token when doing a POST request on \"" + endpoint + "\", but got " + JSON.stringify(authResponse)); | ||
} | ||
return authResponse; | ||
}); | ||
return fetch(endpoint, { | ||
method: "POST", | ||
headers: { | ||
"Content-Type": "application/json" | ||
}, | ||
body: JSON.stringify(body) | ||
}).then((function(res) { | ||
if (!res.ok) throw new AuthenticationError("Expected a status 200 but got " + res.status + ' when doing a POST request on "' + endpoint + '"'); | ||
return res.json().catch((function(er) { | ||
throw new AuthenticationError('Expected a json when doing a POST request on "' + endpoint + '". ' + er); | ||
})); | ||
})).then((function(authResponse) { | ||
if ("string" != typeof authResponse.token) throw new AuthenticationError('Expected a json with a string token when doing a POST request on "' + endpoint + '", but got ' + JSON.stringify(authResponse)); | ||
return authResponse; | ||
})); | ||
} | ||
var AuthenticationError = function (_Error2) { | ||
LiveObject._inheritsLoose(AuthenticationError, _Error2); | ||
function AuthenticationError(message) { | ||
return _Error2.call(this, message) || this; | ||
} | ||
return AuthenticationError; | ||
var AuthenticationError = function(_Error2) { | ||
function AuthenticationError(message) { | ||
return _Error2.call(this, message) || this; | ||
} | ||
return LiveObject._inheritsLoose(AuthenticationError, _Error2), AuthenticationError; | ||
}(LiveObject._wrapNativeSuper(Error)); | ||
function createClient(options) { | ||
var clientOptions = options; | ||
var throttleDelay = getThrottleDelayFromOptions(options); | ||
var rooms = new Map(); | ||
function getRoom(roomId) { | ||
var internalRoom = rooms.get(roomId); | ||
return internalRoom ? internalRoom.room : null; | ||
} | ||
function enter(roomId, options) { | ||
if (options === void 0) { | ||
options = {}; | ||
} | ||
var internalRoom = rooms.get(roomId); | ||
if (internalRoom) { | ||
return internalRoom.room; | ||
} | ||
LiveObject.deprecateIf(options.defaultPresence, "Argument `defaultPresence` will be removed in @liveblocks/client 0.18. Please use `initialPresence` instead. For more info, see https://bit.ly/3Niy5aP", "defaultPresence"); | ||
LiveObject.deprecateIf(options.defaultStorageRoot, "Argument `defaultStorageRoot` will be removed in @liveblocks/client 0.18. Please use `initialStorage` instead. For more info, see https://bit.ly/3Niy5aP", "defaultStorageRoot"); | ||
internalRoom = createRoom({ | ||
initialPresence: options.initialPresence, | ||
initialStorage: options.initialStorage, | ||
defaultPresence: options.defaultPresence, | ||
defaultStorageRoot: options.defaultStorageRoot | ||
}, { | ||
roomId: roomId, | ||
throttleDelay: throttleDelay, | ||
WebSocketPolyfill: clientOptions.WebSocketPolyfill, | ||
fetchPolyfill: clientOptions.fetchPolyfill, | ||
liveblocksServer: clientOptions.liveblocksServer || "wss://liveblocks.net/v5", | ||
authentication: prepareAuthentication(clientOptions) | ||
}); | ||
rooms.set(roomId, internalRoom); | ||
if (!options.DO_NOT_USE_withoutConnecting) { | ||
internalRoom.connect(); | ||
} | ||
return internalRoom.room; | ||
} | ||
function leave(roomId) { | ||
var room = rooms.get(roomId); | ||
if (room) { | ||
room.disconnect(); | ||
rooms.delete(roomId); | ||
} | ||
} | ||
if (typeof window !== "undefined") { | ||
window.addEventListener("online", function () { | ||
for (var _iterator = LiveObject._createForOfIteratorHelperLoose(rooms), _step; !(_step = _iterator()).done;) { | ||
var _step$value = _step.value, | ||
room = _step$value[1]; | ||
room.onNavigatorOnline(); | ||
} | ||
}); | ||
} | ||
if (typeof document !== "undefined") { | ||
document.addEventListener("visibilitychange", function () { | ||
for (var _iterator2 = LiveObject._createForOfIteratorHelperLoose(rooms), _step2; !(_step2 = _iterator2()).done;) { | ||
var _step2$value = _step2.value, | ||
room = _step2$value[1]; | ||
room.onVisibilityChange(document.visibilityState); | ||
} | ||
}); | ||
} | ||
return { | ||
getRoom: getRoom, | ||
enter: enter, | ||
leave: leave | ||
}; | ||
function prepareAuthentication(clientOptions) { | ||
if ("string" == typeof clientOptions.publicApiKey) return { | ||
type: "public", | ||
publicApiKey: clientOptions.publicApiKey, | ||
url: clientOptions.publicAuthorizeEndpoint || "https://liveblocks.io/api/public/authorize" | ||
}; | ||
if ("string" == typeof clientOptions.authEndpoint) return { | ||
type: "private", | ||
url: clientOptions.authEndpoint | ||
}; | ||
if ("function" == typeof clientOptions.authEndpoint) return { | ||
type: "custom", | ||
callback: clientOptions.authEndpoint | ||
}; | ||
throw new Error("Invalid Liveblocks client options. For more information: https://liveblocks.io/docs/api-reference/liveblocks-client#createClient"); | ||
} | ||
function getThrottleDelayFromOptions(options) { | ||
if (options.throttle === undefined) { | ||
return 100; | ||
exports.LiveList = LiveObject.LiveList, exports.LiveMap = LiveObject.LiveMap, exports.LiveObject = LiveObject.LiveObject, | ||
exports.createClient = function(options) { | ||
var clientOptions = options, throttleDelay = function(options) { | ||
if (void 0 === options.throttle) return 100; | ||
if ("number" != typeof options.throttle || options.throttle < 80 || options.throttle > 1e3) throw new Error("throttle should be a number between 80 and 1000."); | ||
return options.throttle; | ||
}(options), rooms = new Map; | ||
return "undefined" != typeof window && window.addEventListener("online", (function() { | ||
for (var _step, _iterator = LiveObject._createForOfIteratorHelperLoose(rooms); !(_step = _iterator()).done; ) { | ||
_step.value[1].onNavigatorOnline(); | ||
} | ||
if (typeof options.throttle !== "number" || options.throttle < 80 || options.throttle > 1000) { | ||
throw new Error("throttle should be a number between 80 and 1000."); | ||
})), "undefined" != typeof document && document.addEventListener("visibilitychange", (function() { | ||
for (var _step2, _iterator2 = LiveObject._createForOfIteratorHelperLoose(rooms); !(_step2 = _iterator2()).done; ) { | ||
_step2.value[1].onVisibilityChange(document.visibilityState); | ||
} | ||
return options.throttle; | ||
} | ||
function prepareAuthentication(clientOptions) { | ||
if (typeof clientOptions.publicApiKey === "string") { | ||
return { | ||
type: "public", | ||
publicApiKey: clientOptions.publicApiKey, | ||
url: clientOptions.publicAuthorizeEndpoint || "https://liveblocks.io/api/public/authorize" | ||
}; | ||
} else if (typeof clientOptions.authEndpoint === "string") { | ||
return { | ||
type: "private", | ||
url: clientOptions.authEndpoint | ||
}; | ||
} else if (typeof clientOptions.authEndpoint === "function") { | ||
return { | ||
type: "custom", | ||
callback: clientOptions.authEndpoint | ||
}; | ||
})), { | ||
getRoom: function(roomId) { | ||
var internalRoom = rooms.get(roomId); | ||
return internalRoom ? internalRoom.room : null; | ||
}, | ||
enter: function(roomId, options) { | ||
void 0 === options && (options = {}); | ||
var internalRoom = rooms.get(roomId); | ||
return internalRoom || (LiveObject.deprecateIf(options.defaultPresence, "Argument `defaultPresence` will be removed in @liveblocks/client 0.18. Please use `initialPresence` instead. For more info, see https://bit.ly/3Niy5aP", "defaultPresence"), | ||
LiveObject.deprecateIf(options.defaultStorageRoot, "Argument `defaultStorageRoot` will be removed in @liveblocks/client 0.18. Please use `initialStorage` instead. For more info, see https://bit.ly/3Niy5aP", "defaultStorageRoot"), | ||
internalRoom = createRoom({ | ||
initialPresence: options.initialPresence, | ||
initialStorage: options.initialStorage, | ||
defaultPresence: options.defaultPresence, | ||
defaultStorageRoot: options.defaultStorageRoot | ||
}, { | ||
roomId: roomId, | ||
throttleDelay: throttleDelay, | ||
WebSocketPolyfill: clientOptions.WebSocketPolyfill, | ||
fetchPolyfill: clientOptions.fetchPolyfill, | ||
liveblocksServer: clientOptions.liveblocksServer || "wss://liveblocks.net/v5", | ||
authentication: prepareAuthentication(clientOptions) | ||
}), rooms.set(roomId, internalRoom), options.DO_NOT_USE_withoutConnecting || internalRoom.connect()), | ||
internalRoom.room; | ||
}, | ||
leave: function(roomId) { | ||
var room = rooms.get(roomId); | ||
room && (room.disconnect(), rooms.delete(roomId)); | ||
} | ||
throw new Error("Invalid Liveblocks client options. For more information: https://liveblocks.io/docs/api-reference/liveblocks-client#createClient"); | ||
} | ||
exports.LiveList = LiveObject.LiveList; | ||
exports.LiveMap = LiveObject.LiveMap; | ||
exports.LiveObject = LiveObject.LiveObject; | ||
exports.createClient = createClient; | ||
}; | ||
}; |
@@ -1,2 +0,2 @@ | ||
import { J as Json, P as Presence, d as JsonObject, e as Lson, A as AbstractCrdt, f as LsonObject, L as LiveObject, S as StorageUpdate } from './shared'; | ||
import { d as JsonObject, J as Json, e as Lson, A as AbstractCrdt, f as LsonObject, L as LiveObject, S as StorageUpdate } from './shared'; | ||
export { g as Resolve, h as RoomInitializers } from './shared'; | ||
@@ -7,3 +7,3 @@ | ||
*/ | ||
declare type ServerMessage = UpdatePresenceMessage | UserJoinMessage | UserLeftMessage | EventMessage | RoomStateMessage | InitialDocumentStateMessage | UpdateStorageMessage; | ||
declare type ServerMessage<TPresence extends JsonObject> = UpdatePresenceMessage<TPresence> | UserJoinMessage | UserLeftMessage | EventMessage | RoomStateMessage | InitialDocumentStateMessage | UpdateStorageMessage; | ||
declare enum ServerMessageType { | ||
@@ -43,3 +43,3 @@ UpdatePresence = 100, | ||
*/ | ||
declare type UpdatePresenceMessage = { | ||
declare type UpdatePresenceMessage<TPresence extends JsonObject> = { | ||
type: ServerMessageType.UpdatePresence; | ||
@@ -55,3 +55,3 @@ /** | ||
*/ | ||
data: Presence; | ||
data: TPresence; | ||
/** | ||
@@ -237,2 +237,7 @@ * If this message was sent in response to a newly joined user, this field | ||
/** | ||
* Tools to help with the controlled deprecation of public APIs. | ||
* | ||
* First warn, then error, then remove eventually. | ||
*/ | ||
/** | ||
* Displays a deprecation warning in the dev console. Only in dev mode, and | ||
@@ -248,2 +253,16 @@ * only once per message/key. In production, this is a no-op. | ||
declare function deprecateIf(condition: unknown, message: string, key?: string): void; | ||
/** | ||
* Throws a deprecation error in the dev console. | ||
* | ||
* Only triggers in dev mode. In production, this is a no-op. | ||
*/ | ||
declare function throwUsageError(message: string): void; | ||
/** | ||
* Conditionally throws a usage error in the dev console if the first argument | ||
* is truthy. Use this to "escalate" usage patterns that in previous versions | ||
* we already warned about with deprecation warnings. | ||
* | ||
* Only has effect in dev mode. In production, this is a no-op. | ||
*/ | ||
declare function errorIf(condition: unknown, message: string): void; | ||
@@ -254,2 +273,2 @@ declare function lsonToJson(value: Lson | AbstractCrdt): Json; | ||
export { ClientMessageType, CrdtType, OpType, SerializedCrdtWithId, ServerMessage, ServerMessageType, deprecate, deprecateIf, lsonToJson, patchImmutableObject, patchLiveObjectKey }; | ||
export { ClientMessageType, CrdtType, OpType, RoomStateMessage, SerializedCrdtWithId, ServerMessage, ServerMessageType, deprecate, deprecateIf, errorIf, lsonToJson, patchImmutableObject, patchLiveObjectKey, throwUsageError }; |
475
internal.js
@@ -1,367 +0,176 @@ | ||
'use strict'; | ||
"use strict"; | ||
Object.defineProperty(exports, '__esModule', { value: true }); | ||
Object.defineProperty(exports, "__esModule", { | ||
value: !0 | ||
}); | ||
var LiveObject = require('./shared.js'); | ||
var LiveObject = require("./shared.js"); | ||
function lsonObjectToJson(obj) { | ||
var result = {}; | ||
for (var _key in obj) { | ||
var val = obj[_key]; | ||
if (val !== undefined) { | ||
result[_key] = lsonToJson(val); | ||
} | ||
} | ||
return result; | ||
var result = {}; | ||
for (var _key in obj) { | ||
var val = obj[_key]; | ||
void 0 !== val && (result[_key] = lsonToJson(val)); | ||
} | ||
return result; | ||
} | ||
function liveObjectToJson(liveObject) { | ||
return lsonObjectToJson(liveObject.toObject()); | ||
} | ||
function liveMapToJson(map) { | ||
var result = {}; | ||
for (var _iterator = LiveObject._createForOfIteratorHelperLoose(map.entries()), _step; !(_step = _iterator()).done;) { | ||
var _step$value = _step.value, | ||
_key2 = _step$value[0], | ||
value = _step$value[1]; | ||
result[_key2] = lsonToJson(value); | ||
} | ||
return result; | ||
} | ||
function lsonListToJson(value) { | ||
return value.map(lsonToJson); | ||
return value.map(lsonToJson); | ||
} | ||
function liveListToJson(value) { | ||
function lsonToJson(value) { | ||
if (value instanceof LiveObject.LiveObject) return lsonObjectToJson(value.toObject()); | ||
if (value instanceof LiveObject.LiveList) return function(value) { | ||
return lsonListToJson(value.toArray()); | ||
} | ||
function lsonToJson(value) { | ||
if (value instanceof LiveObject.LiveObject) { | ||
return liveObjectToJson(value); | ||
} else if (value instanceof LiveObject.LiveList) { | ||
return liveListToJson(value); | ||
} else if (value instanceof LiveObject.LiveMap) { | ||
return liveMapToJson(value); | ||
} else if (value instanceof LiveObject.LiveRegister) { | ||
return value.data; | ||
} else if (value instanceof LiveObject.AbstractCrdt) { | ||
throw new Error("Unhandled subclass of AbstractCrdt encountered"); | ||
}(value); | ||
if (value instanceof LiveObject.LiveMap) return function(map) { | ||
for (var _step, result = {}, _iterator = LiveObject._createForOfIteratorHelperLoose(map.entries()); !(_step = _iterator()).done; ) { | ||
var _step$value = _step.value, _key2 = _step$value[0], value = _step$value[1]; | ||
result[_key2] = lsonToJson(value); | ||
} | ||
if (Array.isArray(value)) { | ||
return lsonListToJson(value); | ||
} else if (isPlainObject(value)) { | ||
return lsonObjectToJson(value); | ||
} | ||
return value; | ||
return result; | ||
}(value); | ||
if (value instanceof LiveObject.LiveRegister) return value.data; | ||
if (value instanceof LiveObject.AbstractCrdt) throw new Error("Unhandled subclass of AbstractCrdt encountered"); | ||
return Array.isArray(value) ? lsonListToJson(value) : isPlainObject(value) ? lsonObjectToJson(value) : value; | ||
} | ||
function isPlainObject(obj) { | ||
return obj !== null && Object.prototype.toString.call(obj) === "[object Object]"; | ||
return null !== obj && "[object Object]" === Object.prototype.toString.call(obj); | ||
} | ||
function anyToCrdt(obj) { | ||
if (obj == null) { | ||
return obj; | ||
} | ||
if (Array.isArray(obj)) { | ||
return new LiveObject.LiveList(obj.map(anyToCrdt)); | ||
} | ||
if (isPlainObject(obj)) { | ||
var init = {}; | ||
for (var _key3 in obj) { | ||
init[_key3] = anyToCrdt(obj[_key3]); | ||
} | ||
return new LiveObject.LiveObject(init); | ||
} | ||
return obj; | ||
if (null == obj) return obj; | ||
if (Array.isArray(obj)) return new LiveObject.LiveList(obj.map(anyToCrdt)); | ||
if (isPlainObject(obj)) { | ||
var init = {}; | ||
for (var _key3 in obj) init[_key3] = anyToCrdt(obj[_key3]); | ||
return new LiveObject.LiveObject(init); | ||
} | ||
return obj; | ||
} | ||
function patchLiveList(liveList, prev, next) { | ||
var i = 0; | ||
var prevEnd = prev.length - 1; | ||
var nextEnd = next.length - 1; | ||
var prevNode = prev[0]; | ||
var nextNode = next[0]; | ||
outer: { | ||
while (prevNode === nextNode) { | ||
++i; | ||
if (i > prevEnd || i > nextEnd) { | ||
break outer; | ||
} | ||
prevNode = prev[i]; | ||
nextNode = next[i]; | ||
function patchLiveObjectKey(liveObject, key, prev, next) { | ||
if ("production" !== process.env.NODE_ENV) { | ||
var nonSerializableValue = LiveObject.findNonSerializableValue(next); | ||
if (nonSerializableValue) return void console.error("New state path: '" + nonSerializableValue.path + "' value: '" + nonSerializableValue.value + "' is not serializable.\nOnly serializable value can be synced with Liveblocks."); | ||
} | ||
var value = liveObject.get(key); | ||
if (void 0 === next) liveObject.delete(key); else if (void 0 === value) liveObject.set(key, anyToCrdt(next)); else { | ||
if (prev === next) return; | ||
value instanceof LiveObject.LiveList && Array.isArray(prev) && Array.isArray(next) ? function(liveList, prev, next) { | ||
var i = 0, prevEnd = prev.length - 1, nextEnd = next.length - 1, prevNode = prev[0], nextNode = next[0]; | ||
outer: { | ||
for (;prevNode === nextNode; ) { | ||
if (++i > prevEnd || i > nextEnd) break outer; | ||
prevNode = prev[i], nextNode = next[i]; | ||
} | ||
prevNode = prev[prevEnd]; | ||
nextNode = next[nextEnd]; | ||
while (prevNode === nextNode) { | ||
prevEnd--; | ||
nextEnd--; | ||
if (i > prevEnd || i > nextEnd) { | ||
break outer; | ||
} | ||
prevNode = prev[prevEnd]; | ||
nextNode = next[nextEnd]; | ||
for (prevNode = prev[prevEnd], nextNode = next[nextEnd]; prevNode === nextNode; ) { | ||
if (nextEnd--, i > --prevEnd || i > nextEnd) break outer; | ||
prevNode = prev[prevEnd], nextNode = next[nextEnd]; | ||
} | ||
} | ||
if (i > prevEnd) { | ||
if (i <= nextEnd) { | ||
while (i <= nextEnd) { | ||
liveList.insert(anyToCrdt(next[i]), i); | ||
i++; | ||
} | ||
} | ||
if (i > prevEnd) { | ||
if (i <= nextEnd) for (;i <= nextEnd; ) liveList.insert(anyToCrdt(next[i]), i), | ||
i++; | ||
} else if (i > nextEnd) for (var localI = i; localI <= prevEnd; ) liveList.delete(i), | ||
localI++; else { | ||
for (;i <= prevEnd && i <= nextEnd; ) { | ||
prevNode = prev[i], nextNode = next[i]; | ||
var liveListNode = liveList.get(i); | ||
liveListNode instanceof LiveObject.LiveObject && isPlainObject(prevNode) && isPlainObject(nextNode) ? patchLiveObject(liveListNode, prevNode, nextNode) : liveList.set(i, anyToCrdt(nextNode)), | ||
i++; | ||
} | ||
} else if (i > nextEnd) { | ||
var localI = i; | ||
while (localI <= prevEnd) { | ||
liveList.delete(i); | ||
localI++; | ||
} | ||
} else { | ||
while (i <= prevEnd && i <= nextEnd) { | ||
prevNode = prev[i]; | ||
nextNode = next[i]; | ||
var liveListNode = liveList.get(i); | ||
if (liveListNode instanceof LiveObject.LiveObject && isPlainObject(prevNode) && isPlainObject(nextNode)) { | ||
patchLiveObject(liveListNode, prevNode, nextNode); | ||
} else { | ||
liveList.set(i, anyToCrdt(nextNode)); | ||
} | ||
i++; | ||
} | ||
while (i <= nextEnd) { | ||
liveList.insert(anyToCrdt(next[i]), i); | ||
i++; | ||
} | ||
var _localI = i; | ||
while (_localI <= prevEnd) { | ||
liveList.delete(i); | ||
_localI++; | ||
} | ||
} | ||
for (;i <= nextEnd; ) liveList.insert(anyToCrdt(next[i]), i), i++; | ||
for (var _localI = i; _localI <= prevEnd; ) liveList.delete(i), _localI++; | ||
} | ||
}(value, prev, next) : value instanceof LiveObject.LiveObject && isPlainObject(prev) && isPlainObject(next) ? patchLiveObject(value, prev, next) : liveObject.set(key, anyToCrdt(next)); | ||
} | ||
} | ||
function patchLiveObjectKey(liveObject, key, prev, next) { | ||
if (process.env.NODE_ENV !== "production") { | ||
var nonSerializableValue = LiveObject.findNonSerializableValue(next); | ||
if (nonSerializableValue) { | ||
console.error("New state path: '" + nonSerializableValue.path + "' value: '" + nonSerializableValue.value + "' is not serializable.\nOnly serializable value can be synced with Liveblocks."); | ||
return; | ||
} | ||
} | ||
var value = liveObject.get(key); | ||
if (next === undefined) { | ||
liveObject.delete(key); | ||
} else if (value === undefined) { | ||
liveObject.set(key, anyToCrdt(next)); | ||
} else if (prev === next) { | ||
return; | ||
} else if (value instanceof LiveObject.LiveList && Array.isArray(prev) && Array.isArray(next)) { | ||
patchLiveList(value, prev, next); | ||
} else if (value instanceof LiveObject.LiveObject && isPlainObject(prev) && isPlainObject(next)) { | ||
patchLiveObject(value, prev, next); | ||
} else { | ||
liveObject.set(key, anyToCrdt(next)); | ||
} | ||
} | ||
function patchLiveObject(root, prev, next) { | ||
var updates = {}; | ||
for (var _key4 in next) { | ||
patchLiveObjectKey(root, _key4, prev[_key4], next[_key4]); | ||
} | ||
for (var _key5 in prev) { | ||
if (next[_key5] === undefined) { | ||
root.delete(_key5); | ||
} | ||
} | ||
if (Object.keys(updates).length > 0) { | ||
root.update(updates); | ||
} | ||
var updates = {}; | ||
for (var _key4 in next) patchLiveObjectKey(root, _key4, prev[_key4], next[_key4]); | ||
for (var _key5 in prev) void 0 === next[_key5] && root.delete(_key5); | ||
Object.keys(updates).length > 0 && root.update(updates); | ||
} | ||
function getParentsPath(node) { | ||
var path = []; | ||
while (node._parentKey != null && node._parent != null) { | ||
if (node._parent instanceof LiveObject.LiveList) { | ||
path.push(node._parent._indexOfPosition(node._parentKey)); | ||
} else { | ||
path.push(node._parentKey); | ||
} | ||
node = node._parent; | ||
} | ||
return path; | ||
} | ||
function patchImmutableObject(state, updates) { | ||
return updates.reduce(function (state, update) { | ||
return patchImmutableObjectWithUpdate(state, update); | ||
}, state); | ||
} | ||
function patchImmutableObjectWithUpdate(state, update) { | ||
var path = getParentsPath(update.node); | ||
return patchImmutableNode(state, path, update); | ||
} | ||
function patchImmutableNode(state, path, update) { | ||
var pathItem = path.pop(); | ||
if (pathItem === undefined) { | ||
switch (update.type) { | ||
case "LiveObject": | ||
{ | ||
if (typeof state !== "object") { | ||
throw new Error("Internal: received update on LiveObject but state was not an object"); | ||
} | ||
var newState = Object.assign({}, state); | ||
for (var _key6 in update.updates) { | ||
var _update$updates$_key, _update$updates$_key2; | ||
if (((_update$updates$_key = update.updates[_key6]) == null ? void 0 : _update$updates$_key.type) === "update") { | ||
var val = update.node.get(_key6); | ||
if (val !== undefined) { | ||
newState[_key6] = lsonToJson(val); | ||
} | ||
} else if (((_update$updates$_key2 = update.updates[_key6]) == null ? void 0 : _update$updates$_key2.type) === "delete") { | ||
delete newState[_key6]; | ||
} | ||
} | ||
return newState; | ||
} | ||
case "LiveList": | ||
{ | ||
if (Array.isArray(state) === false) { | ||
throw new Error("Internal: received update on LiveList but state was not an array"); | ||
} | ||
var _newState = state.map(function (x) { | ||
return x; | ||
}); | ||
var _loop = function _loop() { | ||
var listUpdate = _step2.value; | ||
if (listUpdate.type === "set") { | ||
_newState = _newState.map(function (item, index) { | ||
return index === listUpdate.index ? listUpdate.item : item; | ||
}); | ||
} else if (listUpdate.type === "insert") { | ||
if (listUpdate.index === _newState.length) { | ||
_newState.push(lsonToJson(listUpdate.item)); | ||
} else { | ||
_newState = [].concat(_newState.slice(0, listUpdate.index), [lsonToJson(listUpdate.item)], _newState.slice(listUpdate.index)); | ||
} | ||
} else if (listUpdate.type === "delete") { | ||
_newState.splice(listUpdate.index, 1); | ||
} else if (listUpdate.type === "move") { | ||
if (listUpdate.previousIndex > listUpdate.index) { | ||
_newState = [].concat(_newState.slice(0, listUpdate.index), [lsonToJson(listUpdate.item)], _newState.slice(listUpdate.index, listUpdate.previousIndex), _newState.slice(listUpdate.previousIndex + 1)); | ||
} else { | ||
_newState = [].concat(_newState.slice(0, listUpdate.previousIndex), _newState.slice(listUpdate.previousIndex + 1, listUpdate.index + 1), [lsonToJson(listUpdate.item)], _newState.slice(listUpdate.index + 1)); | ||
} | ||
} | ||
}; | ||
for (var _iterator2 = LiveObject._createForOfIteratorHelperLoose(update.updates), _step2; !(_step2 = _iterator2()).done;) { | ||
_loop(); | ||
} | ||
return _newState; | ||
} | ||
case "LiveMap": | ||
{ | ||
if (typeof state !== "object") { | ||
throw new Error("Internal: received update on LiveMap but state was not an object"); | ||
} | ||
var _newState2 = Object.assign({}, state); | ||
for (var _key7 in update.updates) { | ||
var _update$updates$_key3, _update$updates$_key4; | ||
if (((_update$updates$_key3 = update.updates[_key7]) == null ? void 0 : _update$updates$_key3.type) === "update") { | ||
_newState2[_key7] = lsonToJson(update.node.get(_key7)); | ||
} else if (((_update$updates$_key4 = update.updates[_key7]) == null ? void 0 : _update$updates$_key4.type) === "delete") { | ||
delete _newState2[_key7]; | ||
} | ||
} | ||
return _newState2; | ||
} | ||
} | ||
var _extends2, pathItem = path.pop(); | ||
if (void 0 === pathItem) switch (update.type) { | ||
case "LiveObject": | ||
if ("object" != typeof state) throw new Error("Internal: received update on LiveObject but state was not an object"); | ||
var newState = Object.assign({}, state); | ||
for (var _key6 in update.updates) { | ||
var _update$updates$_key, _update$updates$_key2; | ||
if ("update" === (null == (_update$updates$_key = update.updates[_key6]) ? void 0 : _update$updates$_key.type)) { | ||
var val = update.node.get(_key6); | ||
void 0 !== val && (newState[_key6] = lsonToJson(val)); | ||
} else "delete" === (null == (_update$updates$_key2 = update.updates[_key6]) ? void 0 : _update$updates$_key2.type) && delete newState[_key6]; | ||
} | ||
return newState; | ||
if (Array.isArray(state)) { | ||
var newArray = [].concat(state); | ||
newArray[pathItem] = patchImmutableNode(state[pathItem], path, update); | ||
return newArray; | ||
} else { | ||
var _extends2; | ||
case "LiveList": | ||
if (!1 === Array.isArray(state)) throw new Error("Internal: received update on LiveList but state was not an array"); | ||
for (var _step2, _newState = state.map((function(x) { | ||
return x; | ||
})), _loop = function() { | ||
var listUpdate = _step2.value; | ||
"set" === listUpdate.type ? _newState = _newState.map((function(item, index) { | ||
return index === listUpdate.index ? listUpdate.item : item; | ||
})) : "insert" === listUpdate.type ? listUpdate.index === _newState.length ? _newState.push(lsonToJson(listUpdate.item)) : _newState = [].concat(_newState.slice(0, listUpdate.index), [ lsonToJson(listUpdate.item) ], _newState.slice(listUpdate.index)) : "delete" === listUpdate.type ? _newState.splice(listUpdate.index, 1) : "move" === listUpdate.type && (_newState = listUpdate.previousIndex > listUpdate.index ? [].concat(_newState.slice(0, listUpdate.index), [ lsonToJson(listUpdate.item) ], _newState.slice(listUpdate.index, listUpdate.previousIndex), _newState.slice(listUpdate.previousIndex + 1)) : [].concat(_newState.slice(0, listUpdate.previousIndex), _newState.slice(listUpdate.previousIndex + 1, listUpdate.index + 1), [ lsonToJson(listUpdate.item) ], _newState.slice(listUpdate.index + 1))); | ||
}, _iterator2 = LiveObject._createForOfIteratorHelperLoose(update.updates); !(_step2 = _iterator2()).done; ) _loop(); | ||
return _newState; | ||
return LiveObject._extends({}, state, (_extends2 = {}, _extends2[pathItem] = patchImmutableNode(state[pathItem], path, update), _extends2)); | ||
case "LiveMap": | ||
if ("object" != typeof state) throw new Error("Internal: received update on LiveMap but state was not an object"); | ||
var _newState2 = Object.assign({}, state); | ||
for (var _key7 in update.updates) { | ||
var _update$updates$_key3, _update$updates$_key4; | ||
"update" === (null == (_update$updates$_key3 = update.updates[_key7]) ? void 0 : _update$updates$_key3.type) ? _newState2[_key7] = lsonToJson(update.node.get(_key7)) : "delete" === (null == (_update$updates$_key4 = update.updates[_key7]) ? void 0 : _update$updates$_key4.type) && delete _newState2[_key7]; | ||
} | ||
return _newState2; | ||
} | ||
if (Array.isArray(state)) { | ||
var newArray = [].concat(state); | ||
return newArray[pathItem] = patchImmutableNode(state[pathItem], path, update), newArray; | ||
} | ||
return LiveObject._extends({}, state, ((_extends2 = {})[pathItem] = patchImmutableNode(state[pathItem], path, update), | ||
_extends2)); | ||
} | ||
Object.defineProperty(exports, 'ClientMessageType', { | ||
enumerable: true, | ||
get: function () { return LiveObject.ClientMessageType; } | ||
}); | ||
Object.defineProperty(exports, 'CrdtType', { | ||
enumerable: true, | ||
get: function () { return LiveObject.CrdtType; } | ||
}); | ||
Object.defineProperty(exports, 'OpType', { | ||
enumerable: true, | ||
get: function () { return LiveObject.OpType; } | ||
}); | ||
Object.defineProperty(exports, 'ServerMessageType', { | ||
enumerable: true, | ||
get: function () { return LiveObject.ServerMessageType; } | ||
}); | ||
exports.deprecate = LiveObject.deprecate; | ||
exports.deprecateIf = LiveObject.deprecateIf; | ||
exports.lsonToJson = lsonToJson; | ||
exports.patchImmutableObject = patchImmutableObject; | ||
exports.patchLiveObjectKey = patchLiveObjectKey; | ||
Object.defineProperty(exports, "ClientMessageType", { | ||
enumerable: !0, | ||
get: function() { | ||
return LiveObject.ClientMessageType; | ||
} | ||
}), Object.defineProperty(exports, "CrdtType", { | ||
enumerable: !0, | ||
get: function() { | ||
return LiveObject.CrdtType; | ||
} | ||
}), Object.defineProperty(exports, "OpType", { | ||
enumerable: !0, | ||
get: function() { | ||
return LiveObject.OpType; | ||
} | ||
}), Object.defineProperty(exports, "ServerMessageType", { | ||
enumerable: !0, | ||
get: function() { | ||
return LiveObject.ServerMessageType; | ||
} | ||
}), exports.deprecate = LiveObject.deprecate, exports.deprecateIf = LiveObject.deprecateIf, | ||
exports.errorIf = LiveObject.errorIf, exports.throwUsageError = LiveObject.throwUsageError, | ||
exports.lsonToJson = lsonToJson, exports.patchImmutableObject = function(state, updates) { | ||
return updates.reduce((function(state, update) { | ||
return function(state, update) { | ||
var path = function(node) { | ||
for (var path = []; null != node._parentKey && null != node._parent; ) node._parent instanceof LiveObject.LiveList ? path.push(node._parent._indexOfPosition(node._parentKey)) : path.push(node._parentKey), | ||
node = node._parent; | ||
return path; | ||
}(update.node); | ||
return patchImmutableNode(state, path, update); | ||
}(state, update); | ||
}), state); | ||
}, exports.patchLiveObjectKey = patchLiveObjectKey; |
{ | ||
"name": "@liveblocks/client", | ||
"version": "0.16.4", | ||
"version": "0.16.5", | ||
"description": "A client that lets you interact with Liveblocks servers.", | ||
@@ -34,2 +34,3 @@ "main": "./index.js", | ||
"build": "rollup -c && cp ./package.json ./README.md ./lib", | ||
"format": "eslint --fix src/ test/ && prettier --write src/ test/", | ||
"lint": "eslint src/ test/", | ||
@@ -41,7 +42,5 @@ "test": "jest --watch", | ||
"devDependencies": { | ||
"@babel/core": "^7.12.16", | ||
"@babel/plugin-proposal-class-properties": "^7.16.7", | ||
"@babel/plugin-proposal-private-methods": "^7.16.11", | ||
"@babel/preset-env": "^7.12.16", | ||
"@babel/preset-typescript": "^7.12.16", | ||
"@babel/core": "^7.17.10", | ||
"@babel/preset-env": "^7.17.10", | ||
"@babel/preset-typescript": "^7.16.7", | ||
"@rollup/plugin-babel": "^5.3.1", | ||
@@ -56,4 +55,5 @@ "@rollup/plugin-node-resolve": "^13.1.3", | ||
"@typescript-eslint/parser": "^5.17.0", | ||
"babel-jest": "^26.6.3", | ||
"eslint": "^8.12.0", | ||
"eslint-plugin-import": "^2.26.0", | ||
"eslint-plugin-simple-import-sort": "^7.0.0", | ||
"jest": "^26.6.3", | ||
@@ -66,2 +66,3 @@ "jest-each": "^27.5.1", | ||
"rollup-plugin-dts": "^4.1.0", | ||
"rollup-plugin-terser": "^7.0.2", | ||
"typescript": "^4.4.0", | ||
@@ -68,0 +69,0 @@ "whatwg-fetch": "^3.6.2", |
@@ -25,4 +25,8 @@ /** | ||
private _map; | ||
constructor(entries?: readonly (readonly [TKey, TValue])[] | null | undefined); | ||
constructor(entries?: readonly (readonly [TKey, TValue])[] | undefined); | ||
/** | ||
* @deprecated Please call as `new LiveMap()` or `new LiveMap([])` instead. | ||
*/ | ||
constructor(entries: null); | ||
/** | ||
* Returns a specified element from the LiveMap. | ||
@@ -398,3 +402,11 @@ * @param key The key of the element to return. | ||
}); | ||
declare type ConnectionState = "closed" | "authenticating" | "unavailable" | "failed" | "open" | "connecting"; | ||
declare type Connection = { | ||
state: "closed" | "authenticating" | "unavailable" | "failed"; | ||
} | { | ||
state: "open" | "connecting"; | ||
id: number; | ||
userId?: string; | ||
userInfo?: any; | ||
}; | ||
declare type ConnectionState = Connection["state"]; | ||
declare type OthersEvent<T extends Presence = Presence> = { | ||
@@ -743,3 +755,3 @@ type: "leave"; | ||
private _propToLastUpdate; | ||
constructor(object?: O); | ||
constructor(obj?: O); | ||
private _applyUpdate; | ||
@@ -746,0 +758,0 @@ private _applyDeleteObjectKey; |
3561
shared.js
@@ -1,2482 +0,1377 @@ | ||
'use strict'; | ||
"use strict"; | ||
function _defineProperties(target, props) { | ||
for (var i = 0; i < props.length; i++) { | ||
var descriptor = props[i]; | ||
descriptor.enumerable = descriptor.enumerable || false; | ||
descriptor.configurable = true; | ||
if ("value" in descriptor) descriptor.writable = true; | ||
Object.defineProperty(target, descriptor.key, descriptor); | ||
} | ||
for (var i = 0; i < props.length; i++) { | ||
var descriptor = props[i]; | ||
descriptor.enumerable = descriptor.enumerable || !1, descriptor.configurable = !0, | ||
"value" in descriptor && (descriptor.writable = !0), Object.defineProperty(target, descriptor.key, descriptor); | ||
} | ||
} | ||
function _createClass(Constructor, protoProps, staticProps) { | ||
if (protoProps) _defineProperties(Constructor.prototype, protoProps); | ||
if (staticProps) _defineProperties(Constructor, staticProps); | ||
return Constructor; | ||
return protoProps && _defineProperties(Constructor.prototype, protoProps), staticProps && _defineProperties(Constructor, staticProps), | ||
Object.defineProperty(Constructor, "prototype", { | ||
writable: !1 | ||
}), Constructor; | ||
} | ||
function _extends() { | ||
_extends = Object.assign || function (target) { | ||
for (var i = 1; i < arguments.length; i++) { | ||
var source = arguments[i]; | ||
for (var key in source) { | ||
if (Object.prototype.hasOwnProperty.call(source, key)) { | ||
target[key] = source[key]; | ||
} | ||
} | ||
} | ||
return target; | ||
}; | ||
return _extends.apply(this, arguments); | ||
return _extends = Object.assign || function(target) { | ||
for (var i = 1; i < arguments.length; i++) { | ||
var source = arguments[i]; | ||
for (var key in source) Object.prototype.hasOwnProperty.call(source, key) && (target[key] = source[key]); | ||
} | ||
return target; | ||
}, _extends.apply(this, arguments); | ||
} | ||
function _inheritsLoose(subClass, superClass) { | ||
subClass.prototype = Object.create(superClass.prototype); | ||
subClass.prototype.constructor = subClass; | ||
_setPrototypeOf(subClass, superClass); | ||
subClass.prototype = Object.create(superClass.prototype), subClass.prototype.constructor = subClass, | ||
_setPrototypeOf(subClass, superClass); | ||
} | ||
function _getPrototypeOf(o) { | ||
_getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf : function _getPrototypeOf(o) { | ||
return o.__proto__ || Object.getPrototypeOf(o); | ||
}; | ||
return _getPrototypeOf(o); | ||
return _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf : function(o) { | ||
return o.__proto__ || Object.getPrototypeOf(o); | ||
}, _getPrototypeOf(o); | ||
} | ||
function _setPrototypeOf(o, p) { | ||
_setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) { | ||
o.__proto__ = p; | ||
return o; | ||
}; | ||
return _setPrototypeOf(o, p); | ||
return _setPrototypeOf = Object.setPrototypeOf || function(o, p) { | ||
return o.__proto__ = p, o; | ||
}, _setPrototypeOf(o, p); | ||
} | ||
function _isNativeReflectConstruct() { | ||
if (typeof Reflect === "undefined" || !Reflect.construct) return false; | ||
if (Reflect.construct.sham) return false; | ||
if (typeof Proxy === "function") return true; | ||
try { | ||
Date.prototype.toString.call(Reflect.construct(Date, [], function () {})); | ||
return true; | ||
} catch (e) { | ||
return false; | ||
} | ||
if ("undefined" == typeof Reflect || !Reflect.construct) return !1; | ||
if (Reflect.construct.sham) return !1; | ||
if ("function" == typeof Proxy) return !0; | ||
try { | ||
return Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], (function() {}))), | ||
!0; | ||
} catch (e) { | ||
return !1; | ||
} | ||
} | ||
function _construct(Parent, args, Class) { | ||
if (_isNativeReflectConstruct()) { | ||
_construct = Reflect.construct; | ||
} else { | ||
_construct = function _construct(Parent, args, Class) { | ||
var a = [null]; | ||
a.push.apply(a, args); | ||
var Constructor = Function.bind.apply(Parent, a); | ||
var instance = new Constructor(); | ||
if (Class) _setPrototypeOf(instance, Class.prototype); | ||
return instance; | ||
}; | ||
} | ||
return _construct.apply(null, arguments); | ||
return _construct = _isNativeReflectConstruct() ? Reflect.construct : function(Parent, args, Class) { | ||
var a = [ null ]; | ||
a.push.apply(a, args); | ||
var instance = new (Function.bind.apply(Parent, a)); | ||
return Class && _setPrototypeOf(instance, Class.prototype), instance; | ||
}, _construct.apply(null, arguments); | ||
} | ||
function _isNativeFunction(fn) { | ||
return Function.toString.call(fn).indexOf("[native code]") !== -1; | ||
} | ||
function _wrapNativeSuper(Class) { | ||
var _cache = typeof Map === "function" ? new Map() : undefined; | ||
_wrapNativeSuper = function _wrapNativeSuper(Class) { | ||
if (Class === null || !_isNativeFunction(Class)) return Class; | ||
if (typeof Class !== "function") { | ||
throw new TypeError("Super expression must either be null or a function"); | ||
} | ||
if (typeof _cache !== "undefined") { | ||
if (_cache.has(Class)) return _cache.get(Class); | ||
_cache.set(Class, Wrapper); | ||
} | ||
function Wrapper() { | ||
return _construct(Class, arguments, _getPrototypeOf(this).constructor); | ||
} | ||
Wrapper.prototype = Object.create(Class.prototype, { | ||
constructor: { | ||
value: Wrapper, | ||
enumerable: false, | ||
writable: true, | ||
configurable: true | ||
} | ||
}); | ||
return _setPrototypeOf(Wrapper, Class); | ||
}; | ||
return _wrapNativeSuper(Class); | ||
} | ||
function _objectWithoutPropertiesLoose(source, excluded) { | ||
if (source == null) return {}; | ||
var target = {}; | ||
var sourceKeys = Object.keys(source); | ||
var key, i; | ||
for (i = 0; i < sourceKeys.length; i++) { | ||
key = sourceKeys[i]; | ||
if (excluded.indexOf(key) >= 0) continue; | ||
target[key] = source[key]; | ||
var _cache = "function" == typeof Map ? new Map : void 0; | ||
return _wrapNativeSuper = function(Class) { | ||
if (null === Class || (fn = Class, -1 === Function.toString.call(fn).indexOf("[native code]"))) return Class; | ||
var fn; | ||
if ("function" != typeof Class) throw new TypeError("Super expression must either be null or a function"); | ||
if (void 0 !== _cache) { | ||
if (_cache.has(Class)) return _cache.get(Class); | ||
_cache.set(Class, Wrapper); | ||
} | ||
return target; | ||
function Wrapper() { | ||
return _construct(Class, arguments, _getPrototypeOf(this).constructor); | ||
} | ||
return Wrapper.prototype = Object.create(Class.prototype, { | ||
constructor: { | ||
value: Wrapper, | ||
enumerable: !1, | ||
writable: !0, | ||
configurable: !0 | ||
} | ||
}), _setPrototypeOf(Wrapper, Class); | ||
}, _wrapNativeSuper(Class); | ||
} | ||
function _assertThisInitialized(self) { | ||
if (self === void 0) { | ||
throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); | ||
} | ||
return self; | ||
if (void 0 === self) throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); | ||
return self; | ||
} | ||
function _unsupportedIterableToArray(o, minLen) { | ||
if (!o) return; | ||
if (typeof o === "string") return _arrayLikeToArray(o, minLen); | ||
var n = Object.prototype.toString.call(o).slice(8, -1); | ||
if (n === "Object" && o.constructor) n = o.constructor.name; | ||
if (n === "Map" || n === "Set") return Array.from(o); | ||
if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); | ||
} | ||
function _arrayLikeToArray(arr, len) { | ||
if (len == null || len > arr.length) len = arr.length; | ||
for (var i = 0, arr2 = new Array(len); i < len; i++) arr2[i] = arr[i]; | ||
return arr2; | ||
(null == len || len > arr.length) && (len = arr.length); | ||
for (var i = 0, arr2 = new Array(len); i < len; i++) arr2[i] = arr[i]; | ||
return arr2; | ||
} | ||
function _createForOfIteratorHelperLoose(o, allowArrayLike) { | ||
var it; | ||
if (typeof Symbol === "undefined" || o[Symbol.iterator] == null) { | ||
if (Array.isArray(o) || (it = _unsupportedIterableToArray(o)) || allowArrayLike && o && typeof o.length === "number") { | ||
if (it) o = it; | ||
var i = 0; | ||
return function () { | ||
if (i >= o.length) return { | ||
done: true | ||
}; | ||
return { | ||
done: false, | ||
value: o[i++] | ||
}; | ||
}; | ||
} | ||
throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); | ||
var it = "undefined" != typeof Symbol && o[Symbol.iterator] || o["@@iterator"]; | ||
if (it) return (it = it.call(o)).next.bind(it); | ||
if (Array.isArray(o) || (it = function(o, minLen) { | ||
if (o) { | ||
if ("string" == typeof o) return _arrayLikeToArray(o, minLen); | ||
var n = Object.prototype.toString.call(o).slice(8, -1); | ||
return "Object" === n && o.constructor && (n = o.constructor.name), "Map" === n || "Set" === n ? Array.from(o) : "Arguments" === n || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n) ? _arrayLikeToArray(o, minLen) : void 0; | ||
} | ||
it = o[Symbol.iterator](); | ||
return it.next.bind(it); | ||
}(o)) || allowArrayLike && o && "number" == typeof o.length) { | ||
it && (o = it); | ||
var i = 0; | ||
return function() { | ||
return i >= o.length ? { | ||
done: !0 | ||
} : { | ||
done: !1, | ||
value: o[i++] | ||
}; | ||
}; | ||
} | ||
throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); | ||
} | ||
exports.ServerMessageType = void 0; | ||
var ServerMessageType, ClientMessageType, CrdtType, OpType, WebsocketCloseCodes; | ||
(function (ServerMessageType) { | ||
ServerMessageType[ServerMessageType["UpdatePresence"] = 100] = "UpdatePresence"; | ||
ServerMessageType[ServerMessageType["UserJoined"] = 101] = "UserJoined"; | ||
ServerMessageType[ServerMessageType["UserLeft"] = 102] = "UserLeft"; | ||
ServerMessageType[ServerMessageType["Event"] = 103] = "Event"; | ||
ServerMessageType[ServerMessageType["RoomState"] = 104] = "RoomState"; | ||
ServerMessageType[ServerMessageType["InitialStorageState"] = 200] = "InitialStorageState"; | ||
ServerMessageType[ServerMessageType["UpdateStorage"] = 201] = "UpdateStorage"; | ||
})(exports.ServerMessageType || (exports.ServerMessageType = {})); | ||
exports.ServerMessageType = void 0, (ServerMessageType = exports.ServerMessageType || (exports.ServerMessageType = {}))[ServerMessageType.UpdatePresence = 100] = "UpdatePresence", | ||
ServerMessageType[ServerMessageType.UserJoined = 101] = "UserJoined", ServerMessageType[ServerMessageType.UserLeft = 102] = "UserLeft", | ||
ServerMessageType[ServerMessageType.Event = 103] = "Event", ServerMessageType[ServerMessageType.RoomState = 104] = "RoomState", | ||
ServerMessageType[ServerMessageType.InitialStorageState = 200] = "InitialStorageState", | ||
ServerMessageType[ServerMessageType.UpdateStorage = 201] = "UpdateStorage", exports.ClientMessageType = void 0, | ||
(ClientMessageType = exports.ClientMessageType || (exports.ClientMessageType = {}))[ClientMessageType.UpdatePresence = 100] = "UpdatePresence", | ||
ClientMessageType[ClientMessageType.ClientEvent = 103] = "ClientEvent", ClientMessageType[ClientMessageType.FetchStorage = 200] = "FetchStorage", | ||
ClientMessageType[ClientMessageType.UpdateStorage = 201] = "UpdateStorage", exports.CrdtType = void 0, | ||
(CrdtType = exports.CrdtType || (exports.CrdtType = {}))[CrdtType.Object = 0] = "Object", | ||
CrdtType[CrdtType.List = 1] = "List", CrdtType[CrdtType.Map = 2] = "Map", CrdtType[CrdtType.Register = 3] = "Register", | ||
exports.OpType = void 0, (OpType = exports.OpType || (exports.OpType = {}))[OpType.Init = 0] = "Init", | ||
OpType[OpType.SetParentKey = 1] = "SetParentKey", OpType[OpType.CreateList = 2] = "CreateList", | ||
OpType[OpType.UpdateObject = 3] = "UpdateObject", OpType[OpType.CreateObject = 4] = "CreateObject", | ||
OpType[OpType.DeleteCrdt = 5] = "DeleteCrdt", OpType[OpType.DeleteObjectKey = 6] = "DeleteObjectKey", | ||
OpType[OpType.CreateMap = 7] = "CreateMap", OpType[OpType.CreateRegister = 8] = "CreateRegister", | ||
exports.WebsocketCloseCodes = void 0, (WebsocketCloseCodes = exports.WebsocketCloseCodes || (exports.WebsocketCloseCodes = {}))[WebsocketCloseCodes.CLOSE_ABNORMAL = 1006] = "CLOSE_ABNORMAL", | ||
WebsocketCloseCodes[WebsocketCloseCodes.INVALID_MESSAGE_FORMAT = 4e3] = "INVALID_MESSAGE_FORMAT", | ||
WebsocketCloseCodes[WebsocketCloseCodes.NOT_ALLOWED = 4001] = "NOT_ALLOWED", WebsocketCloseCodes[WebsocketCloseCodes.MAX_NUMBER_OF_MESSAGES_PER_SECONDS = 4002] = "MAX_NUMBER_OF_MESSAGES_PER_SECONDS", | ||
WebsocketCloseCodes[WebsocketCloseCodes.MAX_NUMBER_OF_CONCURRENT_CONNECTIONS = 4003] = "MAX_NUMBER_OF_CONCURRENT_CONNECTIONS", | ||
WebsocketCloseCodes[WebsocketCloseCodes.MAX_NUMBER_OF_MESSAGES_PER_DAY_PER_APP = 4004] = "MAX_NUMBER_OF_MESSAGES_PER_DAY_PER_APP", | ||
WebsocketCloseCodes[WebsocketCloseCodes.MAX_NUMBER_OF_CONCURRENT_CONNECTIONS_PER_ROOM = 4005] = "MAX_NUMBER_OF_CONCURRENT_CONNECTIONS_PER_ROOM", | ||
WebsocketCloseCodes[WebsocketCloseCodes.CLOSE_WITHOUT_RETRY = 4999] = "CLOSE_WITHOUT_RETRY"; | ||
exports.ClientMessageType = void 0; | ||
(function (ClientMessageType) { | ||
ClientMessageType[ClientMessageType["UpdatePresence"] = 100] = "UpdatePresence"; | ||
ClientMessageType[ClientMessageType["ClientEvent"] = 103] = "ClientEvent"; | ||
ClientMessageType[ClientMessageType["FetchStorage"] = 200] = "FetchStorage"; | ||
ClientMessageType[ClientMessageType["UpdateStorage"] = 201] = "UpdateStorage"; | ||
})(exports.ClientMessageType || (exports.ClientMessageType = {})); | ||
exports.CrdtType = void 0; | ||
(function (CrdtType) { | ||
CrdtType[CrdtType["Object"] = 0] = "Object"; | ||
CrdtType[CrdtType["List"] = 1] = "List"; | ||
CrdtType[CrdtType["Map"] = 2] = "Map"; | ||
CrdtType[CrdtType["Register"] = 3] = "Register"; | ||
})(exports.CrdtType || (exports.CrdtType = {})); | ||
exports.OpType = void 0; | ||
(function (OpType) { | ||
OpType[OpType["Init"] = 0] = "Init"; | ||
OpType[OpType["SetParentKey"] = 1] = "SetParentKey"; | ||
OpType[OpType["CreateList"] = 2] = "CreateList"; | ||
OpType[OpType["UpdateObject"] = 3] = "UpdateObject"; | ||
OpType[OpType["CreateObject"] = 4] = "CreateObject"; | ||
OpType[OpType["DeleteCrdt"] = 5] = "DeleteCrdt"; | ||
OpType[OpType["DeleteObjectKey"] = 6] = "DeleteObjectKey"; | ||
OpType[OpType["CreateMap"] = 7] = "CreateMap"; | ||
OpType[OpType["CreateRegister"] = 8] = "CreateRegister"; | ||
})(exports.OpType || (exports.OpType = {})); | ||
exports.WebsocketCloseCodes = void 0; | ||
(function (WebsocketCloseCodes) { | ||
WebsocketCloseCodes[WebsocketCloseCodes["CLOSE_ABNORMAL"] = 1006] = "CLOSE_ABNORMAL"; | ||
WebsocketCloseCodes[WebsocketCloseCodes["INVALID_MESSAGE_FORMAT"] = 4000] = "INVALID_MESSAGE_FORMAT"; | ||
WebsocketCloseCodes[WebsocketCloseCodes["NOT_ALLOWED"] = 4001] = "NOT_ALLOWED"; | ||
WebsocketCloseCodes[WebsocketCloseCodes["MAX_NUMBER_OF_MESSAGES_PER_SECONDS"] = 4002] = "MAX_NUMBER_OF_MESSAGES_PER_SECONDS"; | ||
WebsocketCloseCodes[WebsocketCloseCodes["MAX_NUMBER_OF_CONCURRENT_CONNECTIONS"] = 4003] = "MAX_NUMBER_OF_CONCURRENT_CONNECTIONS"; | ||
WebsocketCloseCodes[WebsocketCloseCodes["MAX_NUMBER_OF_MESSAGES_PER_DAY_PER_APP"] = 4004] = "MAX_NUMBER_OF_MESSAGES_PER_DAY_PER_APP"; | ||
WebsocketCloseCodes[WebsocketCloseCodes["MAX_NUMBER_OF_CONCURRENT_CONNECTIONS_PER_ROOM"] = 4005] = "MAX_NUMBER_OF_CONCURRENT_CONNECTIONS_PER_ROOM"; | ||
WebsocketCloseCodes[WebsocketCloseCodes["CLOSE_WITHOUT_RETRY"] = 4999] = "CLOSE_WITHOUT_RETRY"; | ||
})(exports.WebsocketCloseCodes || (exports.WebsocketCloseCodes = {})); | ||
var AbstractCrdt = function () { | ||
function AbstractCrdt() {} | ||
var _proto = AbstractCrdt.prototype; | ||
_proto._apply = function _apply(op, _isLocal) { | ||
switch (op.type) { | ||
case exports.OpType.DeleteCrdt: | ||
{ | ||
if (this._parent != null && this._parentKey != null) { | ||
return this._parent._detachChild(this); | ||
} | ||
return { | ||
modified: false | ||
}; | ||
} | ||
} | ||
return { | ||
modified: false | ||
}; | ||
var AbstractCrdt = function() { | ||
function AbstractCrdt() { | ||
this.__parent = void 0, this.__doc = void 0, this.__id = void 0, this.__parentKey = void 0; | ||
} | ||
var _proto = AbstractCrdt.prototype; | ||
return _proto._apply = function(op, _isLocal) { | ||
return op.type === exports.OpType.DeleteCrdt && null != this._parent && null != this._parentKey ? this._parent._detachChild(this) : { | ||
modified: !1 | ||
}; | ||
_proto._setParentLink = function _setParentLink(parent, key) { | ||
if (this.__parent != null && this.__parent !== parent) { | ||
throw new Error("Cannot attach parent if it already exist"); | ||
} | ||
this.__parentKey = key; | ||
this.__parent = parent; | ||
}; | ||
_proto._attach = function _attach(id, doc) { | ||
if (this.__id || this.__doc) { | ||
throw new Error("Cannot attach if CRDT is already attached"); | ||
} | ||
doc.addItem(id, this); | ||
this.__id = id; | ||
this.__doc = doc; | ||
}; | ||
_proto._detach = function _detach() { | ||
if (this.__doc && this.__id) { | ||
this.__doc.deleteItem(this.__id); | ||
} | ||
this.__parent = undefined; | ||
this.__doc = undefined; | ||
}; | ||
_createClass(AbstractCrdt, [{ | ||
key: "_doc", | ||
get: function get() { | ||
return this.__doc; | ||
} | ||
}, { | ||
key: "roomId", | ||
get: function get() { | ||
return this.__doc ? this.__doc.roomId : null; | ||
} | ||
}, { | ||
key: "_id", | ||
get: function get() { | ||
return this.__id; | ||
} | ||
}, { | ||
key: "_parent", | ||
get: function get() { | ||
return this.__parent; | ||
} | ||
}, { | ||
key: "_parentKey", | ||
get: function get() { | ||
return this.__parentKey; | ||
} | ||
}]); | ||
return AbstractCrdt; | ||
}(); | ||
var min = 32; | ||
var max = 126; | ||
function makePosition(before, after) { | ||
if (before == null && after == null) { | ||
return pos([min + 1]); | ||
}, _proto._setParentLink = function(parent, key) { | ||
if (null != this.__parent && this.__parent !== parent) throw new Error("Cannot attach parent if it already exist"); | ||
this.__parentKey = key, this.__parent = parent; | ||
}, _proto._attach = function(id, doc) { | ||
if (this.__id || this.__doc) throw new Error("Cannot attach if CRDT is already attached"); | ||
doc.addItem(id, this), this.__id = id, this.__doc = doc; | ||
}, _proto._detach = function() { | ||
this.__doc && this.__id && this.__doc.deleteItem(this.__id), this.__parent = void 0, | ||
this.__doc = void 0; | ||
}, _createClass(AbstractCrdt, [ { | ||
key: "_doc", | ||
get: function() { | ||
return this.__doc; | ||
} | ||
if (before != null && after == null) { | ||
return getNextPosition(before); | ||
}, { | ||
key: "roomId", | ||
get: function() { | ||
return this.__doc ? this.__doc.roomId : null; | ||
} | ||
if (before == null && after != null) { | ||
return getPreviousPosition(after); | ||
}, { | ||
key: "_id", | ||
get: function() { | ||
return this.__id; | ||
} | ||
}, { | ||
key: "_parent", | ||
get: function() { | ||
return this.__parent; | ||
} | ||
}, { | ||
key: "_parentKey", | ||
get: function() { | ||
return this.__parentKey; | ||
} | ||
} ]), AbstractCrdt; | ||
}(); | ||
return pos(makePositionFromCodes(posCodes(before), posCodes(after))); | ||
function parseJson(rawMessage) { | ||
try { | ||
return JSON.parse(rawMessage); | ||
} catch (e) { | ||
return; | ||
} | ||
} | ||
function getPreviousPosition(after) { | ||
var result = []; | ||
var afterCodes = posCodes(after); | ||
function isJsonArray(data) { | ||
return Array.isArray(data); | ||
} | ||
for (var i = 0; i < afterCodes.length; i++) { | ||
var code = afterCodes[i]; | ||
function isJsonObject(data) { | ||
return null !== data && "object" == typeof data && !isJsonArray(data); | ||
} | ||
if (code <= min + 1) { | ||
result.push(min); | ||
var _Symbol$iterator$1, _Symbol$iterator2, LiveRegister = function(_AbstractCrdt) { | ||
function LiveRegister(data) { | ||
var _this; | ||
return (_this = _AbstractCrdt.call(this) || this)._data = void 0, _this._data = data, | ||
_this; | ||
} | ||
_inheritsLoose(LiveRegister, _AbstractCrdt), LiveRegister._deserialize = function(_ref, _parentToChildren, doc) { | ||
var id = _ref[0], item = _ref[1]; | ||
if (item.type !== exports.CrdtType.Register) throw new Error('Tried to deserialize a map but item type is "' + item.type + '"'); | ||
var register = new LiveRegister(item.data); | ||
return register._attach(id, doc), register; | ||
}; | ||
var _proto = LiveRegister.prototype; | ||
return _proto._serialize = function(parentId, parentKey, doc, intent) { | ||
if (null == this._id || null == parentId || null == parentKey) throw new Error("Cannot serialize register if parentId or parentKey is undefined"); | ||
return [ { | ||
type: exports.OpType.CreateRegister, | ||
opId: null == doc ? void 0 : doc.generateOpId(), | ||
id: this._id, | ||
intent: intent, | ||
parentId: parentId, | ||
parentKey: parentKey, | ||
data: this.data | ||
} ]; | ||
}, _proto._toSerializedCrdt = function() { | ||
var _this$_parent; | ||
return { | ||
type: exports.CrdtType.Register, | ||
parentId: null == (_this$_parent = this._parent) ? void 0 : _this$_parent._id, | ||
parentKey: this._parentKey, | ||
data: this.data | ||
}; | ||
}, _proto._attachChild = function(_op, _isLocal) { | ||
throw new Error("Method not implemented."); | ||
}, _proto._detachChild = function(_crdt) { | ||
throw new Error("Method not implemented."); | ||
}, _proto._apply = function(op, isLocal) { | ||
return _AbstractCrdt.prototype._apply.call(this, op, isLocal); | ||
}, _createClass(LiveRegister, [ { | ||
key: "data", | ||
get: function() { | ||
return this._data; | ||
} | ||
} ]), LiveRegister; | ||
}(AbstractCrdt); | ||
if (afterCodes.length - 1 === i) { | ||
result.push(max); | ||
break; | ||
} | ||
} else { | ||
result.push(code - 1); | ||
break; | ||
} | ||
function makePosition(before, after) { | ||
return null == before && null == after ? pos([ 33 ]) : null != before && null == after ? function(before) { | ||
for (var result = [], beforeCodes = posCodes(before), i = 0; i < beforeCodes.length; i++) { | ||
var code = beforeCodes[i]; | ||
if (126 !== code) { | ||
result.push(code + 1); | ||
break; | ||
} | ||
if (result.push(code), beforeCodes.length - 1 === i) { | ||
result.push(33); | ||
break; | ||
} | ||
} | ||
return pos(result); | ||
} | ||
function getNextPosition(before) { | ||
var result = []; | ||
var beforeCodes = posCodes(before); | ||
for (var i = 0; i < beforeCodes.length; i++) { | ||
var code = beforeCodes[i]; | ||
if (code === max) { | ||
result.push(code); | ||
if (beforeCodes.length - 1 === i) { | ||
result.push(min + 1); | ||
break; | ||
} | ||
} else { | ||
result.push(code + 1); | ||
break; | ||
} | ||
}(before) : null == before && null != after ? function(after) { | ||
for (var result = [], afterCodes = posCodes(after), i = 0; i < afterCodes.length; i++) { | ||
var code = afterCodes[i]; | ||
if (!(code <= 33)) { | ||
result.push(code - 1); | ||
break; | ||
} | ||
if (result.push(32), afterCodes.length - 1 === i) { | ||
result.push(126); | ||
break; | ||
} | ||
} | ||
return pos(result); | ||
}(after) : pos(makePositionFromCodes(posCodes(before), posCodes(after))); | ||
} | ||
function makePositionFromCodes(before, after) { | ||
var index = 0; | ||
var result = []; | ||
while (true) { | ||
var beforeDigit = before[index] || min; | ||
var afterDigit = after[index] || max; | ||
if (beforeDigit > afterDigit) { | ||
throw new Error("Impossible to generate position between " + before + " and " + after); | ||
} | ||
if (beforeDigit === afterDigit) { | ||
result.push(beforeDigit); | ||
index++; | ||
continue; | ||
} | ||
if (afterDigit - beforeDigit === 1) { | ||
result.push(beforeDigit); | ||
result.push.apply(result, makePositionFromCodes(before.slice(index + 1), [])); | ||
break; | ||
} | ||
var mid = afterDigit + beforeDigit >> 1; | ||
result.push(mid); | ||
for (var index = 0, result = []; ;) { | ||
var beforeDigit = before[index] || 32, afterDigit = after[index] || 126; | ||
if (beforeDigit > afterDigit) throw new Error("Impossible to generate position between " + before + " and " + after); | ||
if (beforeDigit !== afterDigit) { | ||
if (afterDigit - beforeDigit == 1) { | ||
result.push(beforeDigit), result.push.apply(result, makePositionFromCodes(before.slice(index + 1), [])); | ||
break; | ||
} | ||
var mid = afterDigit + beforeDigit >> 1; | ||
result.push(mid); | ||
break; | ||
} | ||
return result; | ||
result.push(beforeDigit), index++; | ||
} | ||
return result; | ||
} | ||
function posCodes(str) { | ||
var codes = []; | ||
for (var codes = [], i = 0; i < str.length; i++) codes.push(str.charCodeAt(i)); | ||
return codes; | ||
} | ||
for (var i = 0; i < str.length; i++) { | ||
codes.push(str.charCodeAt(i)); | ||
} | ||
return codes; | ||
} | ||
function pos(codes) { | ||
return String.fromCharCode.apply(String, codes); | ||
return String.fromCharCode.apply(String, codes); | ||
} | ||
function compare(posA, posB) { | ||
var aCodes = posCodes(posA); | ||
var bCodes = posCodes(posB); | ||
var maxLength = Math.max(aCodes.length, bCodes.length); | ||
for (var i = 0; i < maxLength; i++) { | ||
var a = aCodes[i] == null ? min : aCodes[i]; | ||
var b = bCodes[i] == null ? min : bCodes[i]; | ||
if (a === b) { | ||
continue; | ||
} else { | ||
return a - b; | ||
} | ||
} | ||
throw new Error("Impossible to compare similar position \"" + posA + "\" and \"" + posB + "\""); | ||
for (var aCodes = posCodes(posA), bCodes = posCodes(posB), maxLength = Math.max(aCodes.length, bCodes.length), i = 0; i < maxLength; i++) { | ||
var a = null == aCodes[i] ? 32 : aCodes[i], b = null == bCodes[i] ? 32 : bCodes[i]; | ||
if (a !== b) return a - b; | ||
} | ||
throw new Error('Impossible to compare similar position "' + posA + '" and "' + posB + '"'); | ||
} | ||
var LiveRegister = function (_AbstractCrdt) { | ||
_inheritsLoose(LiveRegister, _AbstractCrdt); | ||
_Symbol$iterator$1 = Symbol.iterator; | ||
function LiveRegister(data) { | ||
var _this; | ||
_this = _AbstractCrdt.call(this) || this; | ||
_this._data = data; | ||
return _this; | ||
var LiveList = function(_AbstractCrdt) { | ||
function LiveList(items) { | ||
var _this; | ||
void 0 === items && (items = []), (_this = _AbstractCrdt.call(this) || this)._items = void 0, | ||
_this._items = []; | ||
for (var position = void 0, i = 0; i < items.length; i++) { | ||
var newPosition = makePosition(position), _item = selfOrRegister(items[i]); | ||
_this._items.push([ _item, newPosition ]), position = newPosition; | ||
} | ||
LiveRegister._deserialize = function _deserialize(_ref, _parentToChildren, doc) { | ||
var id = _ref[0], | ||
item = _ref[1]; | ||
if (item.type !== exports.CrdtType.Register) { | ||
throw new Error("Tried to deserialize a map but item type is \"" + item.type + "\""); | ||
} | ||
var register = new LiveRegister(item.data); | ||
register._attach(id, doc); | ||
return register; | ||
}; | ||
var _proto = LiveRegister.prototype; | ||
_proto._serialize = function _serialize(parentId, parentKey, doc, intent) { | ||
if (this._id == null || parentId == null || parentKey == null) { | ||
throw new Error("Cannot serialize register if parentId or parentKey is undefined"); | ||
} | ||
return [{ | ||
type: exports.OpType.CreateRegister, | ||
opId: doc == null ? void 0 : doc.generateOpId(), | ||
id: this._id, | ||
intent: intent, | ||
parentId: parentId, | ||
parentKey: parentKey, | ||
data: this.data | ||
}]; | ||
}; | ||
_proto._toSerializedCrdt = function _toSerializedCrdt() { | ||
var _this$_parent; | ||
return { | ||
type: exports.CrdtType.Register, | ||
parentId: (_this$_parent = this._parent) == null ? void 0 : _this$_parent._id, | ||
parentKey: this._parentKey, | ||
data: this.data | ||
}; | ||
}; | ||
_proto._attachChild = function _attachChild(_op, _isLocal) { | ||
throw new Error("Method not implemented."); | ||
}; | ||
_proto._detachChild = function _detachChild(_crdt) { | ||
throw new Error("Method not implemented."); | ||
}; | ||
_proto._apply = function _apply(op, isLocal) { | ||
return _AbstractCrdt.prototype._apply.call(this, op, isLocal); | ||
}; | ||
_createClass(LiveRegister, [{ | ||
key: "data", | ||
get: function get() { | ||
return this._data; | ||
} | ||
}]); | ||
return LiveRegister; | ||
}(AbstractCrdt); | ||
var LiveList = function (_AbstractCrdt) { | ||
_inheritsLoose(LiveList, _AbstractCrdt); | ||
function LiveList(items) { | ||
var _this; | ||
if (items === void 0) { | ||
items = []; | ||
} | ||
_this = _AbstractCrdt.call(this) || this; | ||
_this._items = []; | ||
var position = undefined; | ||
for (var i = 0; i < items.length; i++) { | ||
var newPosition = makePosition(position); | ||
var _item = selfOrRegister(items[i]); | ||
_this._items.push([_item, newPosition]); | ||
position = newPosition; | ||
} | ||
return _this; | ||
return _this; | ||
} | ||
_inheritsLoose(LiveList, _AbstractCrdt), LiveList._deserialize = function(_ref, parentToChildren, doc) { | ||
var id = _ref[0], list = new LiveList([]); | ||
list._attach(id, doc); | ||
var children = parentToChildren.get(id); | ||
if (null == children) return list; | ||
for (var _step, _iterator = _createForOfIteratorHelperLoose(children); !(_step = _iterator()).done; ) { | ||
var entry = _step.value, child = deserialize(entry, parentToChildren, doc); | ||
child._setParentLink(list, entry[1].parentKey), list._items.push([ child, entry[1].parentKey ]), | ||
list._items.sort((function(itemA, itemB) { | ||
return compare(itemA[1], itemB[1]); | ||
})); | ||
} | ||
LiveList._deserialize = function _deserialize(_ref, parentToChildren, doc) { | ||
var id = _ref[0]; | ||
var list = new LiveList([]); | ||
list._attach(id, doc); | ||
var children = parentToChildren.get(id); | ||
if (children == null) { | ||
return list; | ||
} | ||
for (var _iterator = _createForOfIteratorHelperLoose(children), _step; !(_step = _iterator()).done;) { | ||
var entry = _step.value; | ||
var child = deserialize(entry, parentToChildren, doc); | ||
child._setParentLink(list, entry[1].parentKey); | ||
list._items.push([child, entry[1].parentKey]); | ||
list._items.sort(function (itemA, itemB) { | ||
return compare(itemA[1], itemB[1]); | ||
}); | ||
} | ||
return list; | ||
return list; | ||
}; | ||
var _proto = LiveList.prototype; | ||
return _proto._serialize = function(parentId, parentKey, doc, intent) { | ||
if (null == this._id) throw new Error("Cannot serialize item is not attached"); | ||
if (null == parentId || null == parentKey) throw new Error("Cannot serialize list if parentId or parentKey is undefined"); | ||
var ops = [], op = { | ||
id: this._id, | ||
opId: null == doc ? void 0 : doc.generateOpId(), | ||
intent: intent, | ||
type: exports.OpType.CreateList, | ||
parentId: parentId, | ||
parentKey: parentKey | ||
}; | ||
var _proto = LiveList.prototype; | ||
_proto._serialize = function _serialize(parentId, parentKey, doc, intent) { | ||
if (this._id == null) { | ||
throw new Error("Cannot serialize item is not attached"); | ||
} | ||
if (parentId == null || parentKey == null) { | ||
throw new Error("Cannot serialize list if parentId or parentKey is undefined"); | ||
} | ||
var ops = []; | ||
var op = { | ||
id: this._id, | ||
opId: doc == null ? void 0 : doc.generateOpId(), | ||
intent: intent, | ||
type: exports.OpType.CreateList, | ||
parentId: parentId, | ||
parentKey: parentKey | ||
}; | ||
ops.push(op); | ||
for (var _iterator2 = _createForOfIteratorHelperLoose(this._items), _step2; !(_step2 = _iterator2()).done;) { | ||
var _step2$value = _step2.value, | ||
_value = _step2$value[0], | ||
key = _step2$value[1]; | ||
ops.push.apply(ops, _value._serialize(this._id, key, doc)); | ||
} | ||
return ops; | ||
}; | ||
_proto._indexOfPosition = function _indexOfPosition(position) { | ||
return this._items.findIndex(function (item) { | ||
return item[1] === position; | ||
}); | ||
}; | ||
_proto._attach = function _attach(id, doc) { | ||
_AbstractCrdt.prototype._attach.call(this, id, doc); | ||
for (var _iterator3 = _createForOfIteratorHelperLoose(this._items), _step3; !(_step3 = _iterator3()).done;) { | ||
var _step3$value = _step3.value, | ||
_item2 = _step3$value[0]; | ||
_item2._attach(doc.generateId(), doc); | ||
} | ||
}; | ||
_proto._detach = function _detach() { | ||
_AbstractCrdt.prototype._detach.call(this); | ||
for (var _iterator4 = _createForOfIteratorHelperLoose(this._items), _step4; !(_step4 = _iterator4()).done;) { | ||
var _step4$value = _step4.value, | ||
_value2 = _step4$value[0]; | ||
_value2._detach(); | ||
} | ||
}; | ||
_proto._attachChild = function _attachChild(op, isLocal) { | ||
if (this._doc == null) { | ||
throw new Error("Can't attach child if doc is not present"); | ||
} | ||
var id = op.id, | ||
parentKey = op.parentKey, | ||
intent = op.intent; | ||
var key = parentKey; | ||
var child = creationOpToLiveStructure(op); | ||
if (this._doc.getItem(id) !== undefined) { | ||
return { | ||
modified: false | ||
}; | ||
} | ||
child._attach(id, this._doc); | ||
child._setParentLink(this, key); | ||
var index = this._items.findIndex(function (entry) { | ||
return entry[1] === key; | ||
}); | ||
var newKey = key; | ||
if (index !== -1) { | ||
if (intent === "set") { | ||
var existingItem = this._items[index][0]; | ||
existingItem._detach(); | ||
var storageUpdate = { | ||
node: this, | ||
type: "LiveList", | ||
updates: [{ | ||
index: index, | ||
type: "set", | ||
item: child instanceof LiveRegister ? child.data : child | ||
}] | ||
}; | ||
this._items[index][0] = child; | ||
return { | ||
modified: storageUpdate, | ||
reverse: existingItem._serialize(this._id, key, this._doc, "set") | ||
}; | ||
} else if (isLocal) { | ||
var before = this._items[index] ? this._items[index][1] : undefined; | ||
var after = this._items[index + 1] ? this._items[index + 1][1] : undefined; | ||
newKey = makePosition(before, after); | ||
child._setParentLink(this, newKey); | ||
} else { | ||
var _this$_items; | ||
this._items[index][1] = makePosition(key, (_this$_items = this._items[index + 1]) == null ? void 0 : _this$_items[1]); | ||
} | ||
} | ||
this._items.push([child, newKey]); | ||
this._items.sort(function (itemA, itemB) { | ||
return compare(itemA[1], itemB[1]); | ||
}); | ||
var newIndex = this._items.findIndex(function (entry) { | ||
return entry[1] === newKey; | ||
}); | ||
return { | ||
reverse: [{ | ||
type: exports.OpType.DeleteCrdt, | ||
id: id | ||
}], | ||
modified: { | ||
node: this, | ||
type: "LiveList", | ||
updates: [{ | ||
index: newIndex, | ||
type: "insert", | ||
item: child instanceof LiveRegister ? child.data : child | ||
}] | ||
} | ||
}; | ||
}; | ||
_proto._detachChild = function _detachChild(child) { | ||
if (child) { | ||
var reverse = child._serialize(this._id, child._parentKey, this._doc); | ||
var indexToDelete = this._items.findIndex(function (item) { | ||
return item[0] === child; | ||
}); | ||
this._items.splice(indexToDelete, 1); | ||
child._detach(); | ||
var storageUpdate = { | ||
node: this, | ||
type: "LiveList", | ||
updates: [{ | ||
index: indexToDelete, | ||
type: "delete" | ||
}] | ||
}; | ||
return { | ||
modified: storageUpdate, | ||
reverse: reverse | ||
}; | ||
} | ||
return { | ||
modified: false | ||
}; | ||
}; | ||
_proto._setChildKey = function _setChildKey(key, child, previousKey) { | ||
child._setParentLink(this, key); | ||
var previousIndex = this._items.findIndex(function (entry) { | ||
return entry[0]._id === child._id; | ||
}); | ||
var index = this._items.findIndex(function (entry) { | ||
return entry[1] === key; | ||
}); | ||
if (index !== -1) { | ||
var _this$_items2; | ||
this._items[index][1] = makePosition(key, (_this$_items2 = this._items[index + 1]) == null ? void 0 : _this$_items2[1]); | ||
} | ||
var item = this._items.find(function (item) { | ||
return item[0] === child; | ||
}); | ||
if (item) { | ||
item[1] = key; | ||
} | ||
this._items.sort(function (itemA, itemB) { | ||
return compare(itemA[1], itemB[1]); | ||
}); | ||
var newIndex = this._items.findIndex(function (entry) { | ||
return entry[0]._id === child._id; | ||
}); | ||
var updatesDelta = newIndex === previousIndex ? [] : [{ | ||
index: newIndex, | ||
item: child instanceof LiveRegister ? child.data : child, | ||
previousIndex: previousIndex, | ||
type: "move" | ||
}]; | ||
return { | ||
modified: { | ||
node: this, | ||
type: "LiveList", | ||
updates: updatesDelta | ||
}, | ||
reverse: [{ | ||
type: exports.OpType.SetParentKey, | ||
id: item == null ? void 0 : item[0]._id, | ||
parentKey: previousKey | ||
}] | ||
}; | ||
}; | ||
_proto._apply = function _apply(op, isLocal) { | ||
return _AbstractCrdt.prototype._apply.call(this, op, isLocal); | ||
}; | ||
_proto._toSerializedCrdt = function _toSerializedCrdt() { | ||
var _this$_parent; | ||
return { | ||
type: exports.CrdtType.List, | ||
parentId: (_this$_parent = this._parent) == null ? void 0 : _this$_parent._id, | ||
parentKey: this._parentKey | ||
}; | ||
}; | ||
_proto.push = function push(element) { | ||
return this.insert(element, this.length); | ||
}; | ||
_proto.insert = function insert(element, index) { | ||
if (index < 0 || index > this._items.length) { | ||
throw new Error("Cannot insert list item at index \"\x1D" + index + "\". index should be between 0 and " + this._items.length); | ||
} | ||
var before = this._items[index - 1] ? this._items[index - 1][1] : undefined; | ||
var after = this._items[index] ? this._items[index][1] : undefined; | ||
var position = makePosition(before, after); | ||
var value = selfOrRegister(element); | ||
value._setParentLink(this, position); | ||
this._items.push([value, position]); | ||
this._items.sort(function (itemA, itemB) { | ||
return compare(itemA[1], itemB[1]); | ||
}); | ||
var newIndex = this._items.findIndex(function (entry) { | ||
return entry[1] === position; | ||
}); | ||
if (this._doc && this._id) { | ||
var _id = this._doc.generateId(); | ||
value._attach(_id, this._doc); | ||
var storageUpdates = new Map(); | ||
storageUpdates.set(this._id, { | ||
node: this, | ||
type: "LiveList", | ||
updates: [{ | ||
index: newIndex, | ||
item: value instanceof LiveRegister ? value.data : value, | ||
type: "insert" | ||
}] | ||
}); | ||
this._doc.dispatch(value._serialize(this._id, position, this._doc), [{ | ||
type: exports.OpType.DeleteCrdt, | ||
id: _id | ||
}], storageUpdates); | ||
} | ||
}; | ||
_proto.move = function move(index, targetIndex) { | ||
if (targetIndex < 0) { | ||
throw new Error("targetIndex cannot be less than 0"); | ||
} | ||
if (targetIndex >= this._items.length) { | ||
throw new Error("targetIndex cannot be greater or equal than the list length"); | ||
} | ||
if (index < 0) { | ||
throw new Error("index cannot be less than 0"); | ||
} | ||
if (index >= this._items.length) { | ||
throw new Error("index cannot be greater or equal than the list length"); | ||
} | ||
var beforePosition = null; | ||
var afterPosition = null; | ||
if (index < targetIndex) { | ||
afterPosition = targetIndex === this._items.length - 1 ? undefined : this._items[targetIndex + 1][1]; | ||
beforePosition = this._items[targetIndex][1]; | ||
} else { | ||
afterPosition = this._items[targetIndex][1]; | ||
beforePosition = targetIndex === 0 ? undefined : this._items[targetIndex - 1][1]; | ||
} | ||
var position = makePosition(beforePosition, afterPosition); | ||
var item = this._items[index]; | ||
var previousPosition = item[1]; | ||
item[1] = position; | ||
item[0]._setParentLink(this, position); | ||
this._items.sort(function (itemA, itemB) { | ||
return compare(itemA[1], itemB[1]); | ||
}); | ||
var newIndex = this._items.findIndex(function (entry) { | ||
return entry[1] === position; | ||
}); | ||
if (this._doc && this._id) { | ||
var storageUpdates = new Map(); | ||
storageUpdates.set(this._id, { | ||
node: this, | ||
type: "LiveList", | ||
updates: [{ | ||
index: newIndex, | ||
previousIndex: index, | ||
item: item[0], | ||
type: "move" | ||
}] | ||
}); | ||
this._doc.dispatch([{ | ||
type: exports.OpType.SetParentKey, | ||
id: item[0]._id, | ||
opId: this._doc.generateOpId(), | ||
parentKey: position | ||
}], [{ | ||
type: exports.OpType.SetParentKey, | ||
id: item[0]._id, | ||
parentKey: previousPosition | ||
}], storageUpdates); | ||
} | ||
}; | ||
_proto.delete = function _delete(index) { | ||
if (index < 0 || index >= this._items.length) { | ||
throw new Error("Cannot delete list item at index \"\x1D" + index + "\". index should be between 0 and " + (this._items.length - 1)); | ||
} | ||
var item = this._items[index]; | ||
item[0]._detach(); | ||
this._items.splice(index, 1); | ||
if (this._doc) { | ||
var childRecordId = item[0]._id; | ||
if (childRecordId) { | ||
var storageUpdates = new Map(); | ||
storageUpdates.set(this._id, { | ||
node: this, | ||
type: "LiveList", | ||
updates: [{ | ||
index: index, | ||
type: "delete" | ||
}] | ||
}); | ||
this._doc.dispatch([{ | ||
id: childRecordId, | ||
opId: this._doc.generateOpId(), | ||
type: exports.OpType.DeleteCrdt | ||
}], item[0]._serialize(this._id, item[1]), storageUpdates); | ||
} | ||
} | ||
}; | ||
_proto.clear = function clear() { | ||
if (this._doc) { | ||
var ops = []; | ||
var reverseOps = []; | ||
var updateDelta = []; | ||
var i = 0; | ||
for (var _iterator5 = _createForOfIteratorHelperLoose(this._items), _step5; !(_step5 = _iterator5()).done;) { | ||
var _item3 = _step5.value; | ||
_item3[0]._detach(); | ||
var childId = _item3[0]._id; | ||
if (childId) { | ||
ops.push({ | ||
id: childId, | ||
type: exports.OpType.DeleteCrdt | ||
}); | ||
reverseOps.push.apply(reverseOps, _item3[0]._serialize(this._id, _item3[1])); | ||
updateDelta.push({ | ||
index: i, | ||
type: "delete" | ||
}); | ||
} | ||
i++; | ||
} | ||
this._items = []; | ||
var storageUpdates = new Map(); | ||
storageUpdates.set(this._id, { | ||
node: this, | ||
type: "LiveList", | ||
updates: updateDelta | ||
}); | ||
this._doc.dispatch(ops, reverseOps, storageUpdates); | ||
} else { | ||
for (var _iterator6 = _createForOfIteratorHelperLoose(this._items), _step6; !(_step6 = _iterator6()).done;) { | ||
var _item4 = _step6.value; | ||
_item4[0]._detach(); | ||
} | ||
this._items = []; | ||
} | ||
}; | ||
_proto.set = function set(index, item) { | ||
if (index < 0 || index >= this._items.length) { | ||
throw new Error("Cannot set list item at index \"\x1D" + index + "\". index should be between 0 and " + (this._items.length - 1)); | ||
} | ||
var _this$_items$index = this._items[index], | ||
existingItem = _this$_items$index[0], | ||
position = _this$_items$index[1]; | ||
existingItem._detach(); | ||
var value = selfOrRegister(item); | ||
value._setParentLink(this, position); | ||
this._items[index][0] = value; | ||
if (this._doc && this._id) { | ||
var _id2 = this._doc.generateId(); | ||
value._attach(_id2, this._doc); | ||
var storageUpdates = new Map(); | ||
storageUpdates.set(this._id, { | ||
node: this, | ||
type: "LiveList", | ||
updates: [{ | ||
index: index, | ||
item: value instanceof LiveRegister ? value.data : value, | ||
type: "set" | ||
}] | ||
}); | ||
this._doc.dispatch(value._serialize(this._id, position, this._doc, "set"), existingItem._serialize(this._id, position, undefined, "set"), storageUpdates); | ||
} | ||
}; | ||
_proto.toArray = function toArray() { | ||
return this._items.map(function (entry) { | ||
return selfOrRegisterValue(entry[0]); | ||
}); | ||
}; | ||
_proto.every = function every(predicate) { | ||
return this.toArray().every(predicate); | ||
}; | ||
_proto.filter = function filter(predicate) { | ||
return this.toArray().filter(predicate); | ||
}; | ||
_proto.find = function find(predicate) { | ||
return this.toArray().find(predicate); | ||
}; | ||
_proto.findIndex = function findIndex(predicate) { | ||
return this.toArray().findIndex(predicate); | ||
}; | ||
_proto.forEach = function forEach(callbackfn) { | ||
return this.toArray().forEach(callbackfn); | ||
}; | ||
_proto.get = function get(index) { | ||
if (index < 0 || index >= this._items.length) { | ||
return undefined; | ||
} | ||
return selfOrRegisterValue(this._items[index][0]); | ||
}; | ||
_proto.indexOf = function indexOf(searchElement, fromIndex) { | ||
return this.toArray().indexOf(searchElement, fromIndex); | ||
}; | ||
_proto.lastIndexOf = function lastIndexOf(searchElement, fromIndex) { | ||
return this.toArray().lastIndexOf(searchElement, fromIndex); | ||
}; | ||
_proto.map = function map(callback) { | ||
return this._items.map(function (entry, i) { | ||
return callback(selfOrRegisterValue(entry[0]), i); | ||
}); | ||
}; | ||
_proto.some = function some(predicate) { | ||
return this.toArray().some(predicate); | ||
}; | ||
_proto[Symbol.iterator] = function () { | ||
return new LiveListIterator(this._items); | ||
}; | ||
_createClass(LiveList, [{ | ||
key: "length", | ||
get: function get() { | ||
return this._items.length; | ||
} | ||
}]); | ||
return LiveList; | ||
}(AbstractCrdt); | ||
var LiveListIterator = function () { | ||
function LiveListIterator(items) { | ||
this._innerIterator = items[Symbol.iterator](); | ||
ops.push(op); | ||
for (var _step2, _iterator2 = _createForOfIteratorHelperLoose(this._items); !(_step2 = _iterator2()).done; ) { | ||
var _step2$value = _step2.value, _value = _step2$value[0], key = _step2$value[1]; | ||
ops.push.apply(ops, _value._serialize(this._id, key, doc)); | ||
} | ||
var _proto2 = LiveListIterator.prototype; | ||
_proto2[Symbol.iterator] = function () { | ||
return this; | ||
}; | ||
_proto2.next = function next() { | ||
var result = this._innerIterator.next(); | ||
if (result.done) { | ||
return { | ||
done: true, | ||
value: undefined | ||
}; | ||
} | ||
return { | ||
value: selfOrRegisterValue(result.value[0]) | ||
}; | ||
}; | ||
return LiveListIterator; | ||
}(); | ||
var LiveMap = function (_AbstractCrdt) { | ||
_inheritsLoose(LiveMap, _AbstractCrdt); | ||
function LiveMap(entries) { | ||
var _this; | ||
_this = _AbstractCrdt.call(this) || this; | ||
if (entries) { | ||
var mappedEntries = []; | ||
for (var _iterator = _createForOfIteratorHelperLoose(entries), _step; !(_step = _iterator()).done;) { | ||
var entry = _step.value; | ||
var _value = selfOrRegister(entry[1]); | ||
_value._setParentLink(_assertThisInitialized(_this), entry[0]); | ||
mappedEntries.push([entry[0], _value]); | ||
} | ||
_this._map = new Map(mappedEntries); | ||
} else { | ||
_this._map = new Map(); | ||
} | ||
return _this; | ||
return ops; | ||
}, _proto._indexOfPosition = function(position) { | ||
return this._items.findIndex((function(item) { | ||
return item[1] === position; | ||
})); | ||
}, _proto._attach = function(id, doc) { | ||
_AbstractCrdt.prototype._attach.call(this, id, doc); | ||
for (var _step3, _iterator3 = _createForOfIteratorHelperLoose(this._items); !(_step3 = _iterator3()).done; ) { | ||
_step3.value[0]._attach(doc.generateId(), doc); | ||
} | ||
var _proto = LiveMap.prototype; | ||
_proto._serialize = function _serialize(parentId, parentKey, doc, intent) { | ||
if (this._id == null) { | ||
throw new Error("Cannot serialize item is not attached"); | ||
} | ||
if (parentId == null || parentKey == null) { | ||
throw new Error("Cannot serialize map if parentId or parentKey is undefined"); | ||
} | ||
var ops = []; | ||
var op = { | ||
id: this._id, | ||
opId: doc == null ? void 0 : doc.generateOpId(), | ||
type: exports.OpType.CreateMap, | ||
intent: intent, | ||
parentId: parentId, | ||
parentKey: parentKey | ||
}; | ||
ops.push(op); | ||
for (var _iterator2 = _createForOfIteratorHelperLoose(this._map), _step2; !(_step2 = _iterator2()).done;) { | ||
var _step2$value = _step2.value, | ||
_key2 = _step2$value[0], | ||
_value2 = _step2$value[1]; | ||
ops.push.apply(ops, _value2._serialize(this._id, _key2, doc)); | ||
} | ||
return ops; | ||
}, _proto._detach = function() { | ||
_AbstractCrdt.prototype._detach.call(this); | ||
for (var _step4, _iterator4 = _createForOfIteratorHelperLoose(this._items); !(_step4 = _iterator4()).done; ) { | ||
_step4.value[0]._detach(); | ||
} | ||
}, _proto._attachChild = function(op, isLocal) { | ||
if (null == this._doc) throw new Error("Can't attach child if doc is not present"); | ||
var id = op.id, parentKey = op.parentKey, intent = op.intent, key = parentKey, child = creationOpToLiveStructure(op); | ||
if (void 0 !== this._doc.getItem(id)) return { | ||
modified: !1 | ||
}; | ||
LiveMap._deserialize = function _deserialize(_ref, parentToChildren, doc) { | ||
var id = _ref[0], | ||
item = _ref[1]; | ||
if (item.type !== exports.CrdtType.Map) { | ||
throw new Error("Tried to deserialize a map but item type is \"" + item.type + "\""); | ||
} | ||
var map = new LiveMap(); | ||
map._attach(id, doc); | ||
var children = parentToChildren.get(id); | ||
if (children == null) { | ||
return map; | ||
} | ||
for (var _iterator3 = _createForOfIteratorHelperLoose(children), _step3; !(_step3 = _iterator3()).done;) { | ||
var entry = _step3.value; | ||
var crdt = entry[1]; | ||
if (crdt.parentKey == null) { | ||
throw new Error("Tried to deserialize a crdt but it does not have a parentKey and is not the root"); | ||
} | ||
var child = deserialize(entry, parentToChildren, doc); | ||
child._setParentLink(map, crdt.parentKey); | ||
map._map.set(crdt.parentKey, child); | ||
} | ||
return map; | ||
}; | ||
_proto._attach = function _attach(id, doc) { | ||
_AbstractCrdt.prototype._attach.call(this, id, doc); | ||
for (var _iterator4 = _createForOfIteratorHelperLoose(this._map), _step4; !(_step4 = _iterator4()).done;) { | ||
var _step4$value = _step4.value; | ||
_step4$value[0]; | ||
var _value3 = _step4$value[1]; | ||
if (isCrdt(_value3)) { | ||
_value3._attach(doc.generateId(), doc); | ||
} | ||
} | ||
}; | ||
_proto._attachChild = function _attachChild(op, _isLocal) { | ||
var _updates; | ||
if (this._doc == null) { | ||
throw new Error("Can't attach child if doc is not present"); | ||
} | ||
var id = op.id, | ||
parentKey = op.parentKey; | ||
var key = parentKey; | ||
var child = creationOpToLiveStructure(op); | ||
if (this._doc.getItem(id) !== undefined) { | ||
return { | ||
modified: false | ||
}; | ||
} | ||
var previousValue = this._map.get(key); | ||
var reverse; | ||
if (previousValue) { | ||
reverse = previousValue._serialize(this._id, key); | ||
previousValue._detach(); | ||
} else { | ||
reverse = [{ | ||
type: exports.OpType.DeleteCrdt, | ||
id: id | ||
}]; | ||
} | ||
child._setParentLink(this, key); | ||
child._attach(id, this._doc); | ||
this._map.set(key, child); | ||
return { | ||
modified: { | ||
node: this, | ||
type: "LiveMap", | ||
updates: (_updates = {}, _updates[key] = { | ||
type: "update" | ||
}, _updates) | ||
}, | ||
reverse: reverse | ||
}; | ||
}; | ||
_proto._detach = function _detach() { | ||
_AbstractCrdt.prototype._detach.call(this); | ||
for (var _iterator5 = _createForOfIteratorHelperLoose(this._map.values()), _step5; !(_step5 = _iterator5()).done;) { | ||
var item = _step5.value; | ||
item._detach(); | ||
} | ||
}; | ||
_proto._detachChild = function _detachChild(child) { | ||
var _updates2; | ||
var reverse = child._serialize(this._id, child._parentKey, this._doc); | ||
for (var _iterator6 = _createForOfIteratorHelperLoose(this._map), _step6; !(_step6 = _iterator6()).done;) { | ||
var _step6$value = _step6.value, | ||
_key3 = _step6$value[0], | ||
_value4 = _step6$value[1]; | ||
if (_value4 === child) { | ||
this._map.delete(_key3); | ||
} | ||
} | ||
child._detach(); | ||
child._attach(id, this._doc), child._setParentLink(this, key); | ||
var index = this._items.findIndex((function(entry) { | ||
return entry[1] === key; | ||
})), newKey = key; | ||
if (-1 !== index) { | ||
if ("set" === intent) { | ||
var existingItem = this._items[index][0]; | ||
existingItem._detach(); | ||
var storageUpdate = { | ||
node: this, | ||
type: "LiveMap", | ||
updates: (_updates2 = {}, _updates2[child._parentKey] = { | ||
type: "delete" | ||
}, _updates2) | ||
node: this, | ||
type: "LiveList", | ||
updates: [ { | ||
index: index, | ||
type: "set", | ||
item: child instanceof LiveRegister ? child.data : child | ||
} ] | ||
}; | ||
return { | ||
modified: storageUpdate, | ||
reverse: reverse | ||
return this._items[index][0] = child, { | ||
modified: storageUpdate, | ||
reverse: existingItem._serialize(this._id, key, this._doc, "set") | ||
}; | ||
} | ||
if (isLocal) { | ||
var before = this._items[index] ? this._items[index][1] : void 0, after = this._items[index + 1] ? this._items[index + 1][1] : void 0; | ||
newKey = makePosition(before, after), child._setParentLink(this, newKey); | ||
} else { | ||
var _this$_items; | ||
this._items[index][1] = makePosition(key, null == (_this$_items = this._items[index + 1]) ? void 0 : _this$_items[1]); | ||
} | ||
} | ||
this._items.push([ child, newKey ]), this._items.sort((function(itemA, itemB) { | ||
return compare(itemA[1], itemB[1]); | ||
})); | ||
var newIndex = this._items.findIndex((function(entry) { | ||
return entry[1] === newKey; | ||
})); | ||
return { | ||
reverse: [ { | ||
type: exports.OpType.DeleteCrdt, | ||
id: id | ||
} ], | ||
modified: { | ||
node: this, | ||
type: "LiveList", | ||
updates: [ { | ||
index: newIndex, | ||
type: "insert", | ||
item: child instanceof LiveRegister ? child.data : child | ||
} ] | ||
} | ||
}; | ||
_proto._toSerializedCrdt = function _toSerializedCrdt() { | ||
var _this$_parent; | ||
return { | ||
type: exports.CrdtType.Map, | ||
parentId: (_this$_parent = this._parent) == null ? void 0 : _this$_parent._id, | ||
parentKey: this._parentKey | ||
}; | ||
}, _proto._detachChild = function(child) { | ||
if (child) { | ||
var reverse = child._serialize(this._id, child._parentKey, this._doc), indexToDelete = this._items.findIndex((function(item) { | ||
return item[0] === child; | ||
})); | ||
return this._items.splice(indexToDelete, 1), child._detach(), { | ||
modified: { | ||
node: this, | ||
type: "LiveList", | ||
updates: [ { | ||
index: indexToDelete, | ||
type: "delete" | ||
} ] | ||
}, | ||
reverse: reverse | ||
}; | ||
} | ||
return { | ||
modified: !1 | ||
}; | ||
_proto.get = function get(key) { | ||
var value = this._map.get(key); | ||
if (value == undefined) { | ||
return undefined; | ||
} | ||
return selfOrRegisterValue(value); | ||
}, _proto._setChildKey = function(key, child, previousKey) { | ||
child._setParentLink(this, key); | ||
var _this$_items2, previousIndex = this._items.findIndex((function(entry) { | ||
return entry[0]._id === child._id; | ||
})), index = this._items.findIndex((function(entry) { | ||
return entry[1] === key; | ||
})); | ||
-1 !== index && (this._items[index][1] = makePosition(key, null == (_this$_items2 = this._items[index + 1]) ? void 0 : _this$_items2[1])); | ||
var item = this._items.find((function(item) { | ||
return item[0] === child; | ||
})); | ||
item && (item[1] = key), this._items.sort((function(itemA, itemB) { | ||
return compare(itemA[1], itemB[1]); | ||
})); | ||
var newIndex = this._items.findIndex((function(entry) { | ||
return entry[0]._id === child._id; | ||
})); | ||
return { | ||
modified: { | ||
node: this, | ||
type: "LiveList", | ||
updates: newIndex === previousIndex ? [] : [ { | ||
index: newIndex, | ||
item: child instanceof LiveRegister ? child.data : child, | ||
previousIndex: previousIndex, | ||
type: "move" | ||
} ] | ||
}, | ||
reverse: [ { | ||
type: exports.OpType.SetParentKey, | ||
id: null == item ? void 0 : item[0]._id, | ||
parentKey: previousKey | ||
} ] | ||
}; | ||
_proto.set = function set(key, value) { | ||
var oldValue = this._map.get(key); | ||
if (oldValue) { | ||
oldValue._detach(); | ||
} | ||
var item = selfOrRegister(value); | ||
item._setParentLink(this, key); | ||
this._map.set(key, item); | ||
if (this._doc && this._id) { | ||
var _updates3; | ||
var id = this._doc.generateId(); | ||
item._attach(id, this._doc); | ||
var storageUpdates = new Map(); | ||
storageUpdates.set(this._id, { | ||
node: this, | ||
type: "LiveMap", | ||
updates: (_updates3 = {}, _updates3[key] = { | ||
type: "update" | ||
}, _updates3) | ||
}); | ||
this._doc.dispatch(item._serialize(this._id, key, this._doc), oldValue ? oldValue._serialize(this._id, key) : [{ | ||
type: exports.OpType.DeleteCrdt, | ||
id: id | ||
}], storageUpdates); | ||
} | ||
}, _proto._apply = function(op, isLocal) { | ||
return _AbstractCrdt.prototype._apply.call(this, op, isLocal); | ||
}, _proto._toSerializedCrdt = function() { | ||
var _this$_parent; | ||
return { | ||
type: exports.CrdtType.List, | ||
parentId: null == (_this$_parent = this._parent) ? void 0 : _this$_parent._id, | ||
parentKey: this._parentKey | ||
}; | ||
}, _proto.push = function(element) { | ||
return this.insert(element, this.length); | ||
}, _proto.insert = function(element, index) { | ||
if (index < 0 || index > this._items.length) throw new Error('Cannot insert list item at index "' + index + '". index should be between 0 and ' + this._items.length); | ||
var position = makePosition(this._items[index - 1] ? this._items[index - 1][1] : void 0, this._items[index] ? this._items[index][1] : void 0), value = selfOrRegister(element); | ||
value._setParentLink(this, position), this._items.push([ value, position ]), this._items.sort((function(itemA, itemB) { | ||
return compare(itemA[1], itemB[1]); | ||
})); | ||
var newIndex = this._items.findIndex((function(entry) { | ||
return entry[1] === position; | ||
})); | ||
if (this._doc && this._id) { | ||
var _id = this._doc.generateId(); | ||
value._attach(_id, this._doc); | ||
var storageUpdates = new Map; | ||
storageUpdates.set(this._id, { | ||
node: this, | ||
type: "LiveList", | ||
updates: [ { | ||
index: newIndex, | ||
item: value instanceof LiveRegister ? value.data : value, | ||
type: "insert" | ||
} ] | ||
}), this._doc.dispatch(value._serialize(this._id, position, this._doc), [ { | ||
type: exports.OpType.DeleteCrdt, | ||
id: _id | ||
} ], storageUpdates); | ||
} | ||
}, _proto.move = function(index, targetIndex) { | ||
if (targetIndex < 0) throw new Error("targetIndex cannot be less than 0"); | ||
if (targetIndex >= this._items.length) throw new Error("targetIndex cannot be greater or equal than the list length"); | ||
if (index < 0) throw new Error("index cannot be less than 0"); | ||
if (index >= this._items.length) throw new Error("index cannot be greater or equal than the list length"); | ||
var beforePosition = null, afterPosition = null; | ||
index < targetIndex ? (afterPosition = targetIndex === this._items.length - 1 ? void 0 : this._items[targetIndex + 1][1], | ||
beforePosition = this._items[targetIndex][1]) : (afterPosition = this._items[targetIndex][1], | ||
beforePosition = 0 === targetIndex ? void 0 : this._items[targetIndex - 1][1]); | ||
var position = makePosition(beforePosition, afterPosition), item = this._items[index], previousPosition = item[1]; | ||
item[1] = position, item[0]._setParentLink(this, position), this._items.sort((function(itemA, itemB) { | ||
return compare(itemA[1], itemB[1]); | ||
})); | ||
var newIndex = this._items.findIndex((function(entry) { | ||
return entry[1] === position; | ||
})); | ||
if (this._doc && this._id) { | ||
var storageUpdates = new Map; | ||
storageUpdates.set(this._id, { | ||
node: this, | ||
type: "LiveList", | ||
updates: [ { | ||
index: newIndex, | ||
previousIndex: index, | ||
item: item[0], | ||
type: "move" | ||
} ] | ||
}), this._doc.dispatch([ { | ||
type: exports.OpType.SetParentKey, | ||
id: item[0]._id, | ||
opId: this._doc.generateOpId(), | ||
parentKey: position | ||
} ], [ { | ||
type: exports.OpType.SetParentKey, | ||
id: item[0]._id, | ||
parentKey: previousPosition | ||
} ], storageUpdates); | ||
} | ||
}, _proto.delete = function(index) { | ||
if (index < 0 || index >= this._items.length) throw new Error('Cannot delete list item at index "' + index + '". index should be between 0 and ' + (this._items.length - 1)); | ||
var item = this._items[index]; | ||
if (item[0]._detach(), this._items.splice(index, 1), this._doc) { | ||
var childRecordId = item[0]._id; | ||
if (childRecordId) { | ||
var storageUpdates = new Map; | ||
storageUpdates.set(this._id, { | ||
node: this, | ||
type: "LiveList", | ||
updates: [ { | ||
index: index, | ||
type: "delete" | ||
} ] | ||
}), this._doc.dispatch([ { | ||
id: childRecordId, | ||
opId: this._doc.generateOpId(), | ||
type: exports.OpType.DeleteCrdt | ||
} ], item[0]._serialize(this._id, item[1]), storageUpdates); | ||
} | ||
} | ||
}, _proto.clear = function() { | ||
if (this._doc) { | ||
for (var _step5, ops = [], reverseOps = [], updateDelta = [], i = 0, _iterator5 = _createForOfIteratorHelperLoose(this._items); !(_step5 = _iterator5()).done; ) { | ||
var _item3 = _step5.value; | ||
_item3[0]._detach(); | ||
var childId = _item3[0]._id; | ||
childId && (ops.push({ | ||
id: childId, | ||
type: exports.OpType.DeleteCrdt | ||
}), reverseOps.push.apply(reverseOps, _item3[0]._serialize(this._id, _item3[1])), | ||
updateDelta.push({ | ||
index: i, | ||
type: "delete" | ||
})), i++; | ||
} | ||
this._items = []; | ||
var storageUpdates = new Map; | ||
storageUpdates.set(this._id, { | ||
node: this, | ||
type: "LiveList", | ||
updates: updateDelta | ||
}), this._doc.dispatch(ops, reverseOps, storageUpdates); | ||
} else { | ||
for (var _step6, _iterator6 = _createForOfIteratorHelperLoose(this._items); !(_step6 = _iterator6()).done; ) { | ||
_step6.value[0]._detach(); | ||
} | ||
this._items = []; | ||
} | ||
}, _proto.set = function(index, item) { | ||
if (index < 0 || index >= this._items.length) throw new Error('Cannot set list item at index "' + index + '". index should be between 0 and ' + (this._items.length - 1)); | ||
var _this$_items$index = this._items[index], existingItem = _this$_items$index[0], position = _this$_items$index[1]; | ||
existingItem._detach(); | ||
var value = selfOrRegister(item); | ||
if (value._setParentLink(this, position), this._items[index][0] = value, this._doc && this._id) { | ||
var _id2 = this._doc.generateId(); | ||
value._attach(_id2, this._doc); | ||
var storageUpdates = new Map; | ||
storageUpdates.set(this._id, { | ||
node: this, | ||
type: "LiveList", | ||
updates: [ { | ||
index: index, | ||
item: value instanceof LiveRegister ? value.data : value, | ||
type: "set" | ||
} ] | ||
}), this._doc.dispatch(value._serialize(this._id, position, this._doc, "set"), existingItem._serialize(this._id, position, void 0, "set"), storageUpdates); | ||
} | ||
}, _proto.toArray = function() { | ||
return this._items.map((function(entry) { | ||
return selfOrRegisterValue(entry[0]); | ||
})); | ||
}, _proto.every = function(predicate) { | ||
return this.toArray().every(predicate); | ||
}, _proto.filter = function(predicate) { | ||
return this.toArray().filter(predicate); | ||
}, _proto.find = function(predicate) { | ||
return this.toArray().find(predicate); | ||
}, _proto.findIndex = function(predicate) { | ||
return this.toArray().findIndex(predicate); | ||
}, _proto.forEach = function(callbackfn) { | ||
return this.toArray().forEach(callbackfn); | ||
}, _proto.get = function(index) { | ||
if (!(index < 0 || index >= this._items.length)) return selfOrRegisterValue(this._items[index][0]); | ||
}, _proto.indexOf = function(searchElement, fromIndex) { | ||
return this.toArray().indexOf(searchElement, fromIndex); | ||
}, _proto.lastIndexOf = function(searchElement, fromIndex) { | ||
return this.toArray().lastIndexOf(searchElement, fromIndex); | ||
}, _proto.map = function(callback) { | ||
return this._items.map((function(entry, i) { | ||
return callback(selfOrRegisterValue(entry[0]), i); | ||
})); | ||
}, _proto.some = function(predicate) { | ||
return this.toArray().some(predicate); | ||
}, _proto[_Symbol$iterator$1] = function() { | ||
return new LiveListIterator(this._items); | ||
}, _createClass(LiveList, [ { | ||
key: "length", | ||
get: function() { | ||
return this._items.length; | ||
} | ||
} ]), LiveList; | ||
}(AbstractCrdt); | ||
_proto.has = function has(key) { | ||
return this._map.has(key); | ||
}; | ||
_Symbol$iterator2 = Symbol.iterator; | ||
_proto.delete = function _delete(key) { | ||
var item = this._map.get(key); | ||
if (item == null) { | ||
return false; | ||
} | ||
item._detach(); | ||
this._map.delete(key); | ||
if (this._doc && item._id) { | ||
var _updates4; | ||
var storageUpdates = new Map(); | ||
storageUpdates.set(this._id, { | ||
node: this, | ||
type: "LiveMap", | ||
updates: (_updates4 = {}, _updates4[key] = { | ||
type: "delete" | ||
}, _updates4) | ||
}); | ||
this._doc.dispatch([{ | ||
type: exports.OpType.DeleteCrdt, | ||
id: item._id, | ||
opId: this._doc.generateOpId() | ||
}], item._serialize(this._id, key), storageUpdates); | ||
} | ||
return true; | ||
var _Symbol$iterator, LiveListIterator = function() { | ||
function LiveListIterator(items) { | ||
this._innerIterator = void 0, this._innerIterator = items[Symbol.iterator](); | ||
} | ||
var _proto2 = LiveListIterator.prototype; | ||
return _proto2[_Symbol$iterator2] = function() { | ||
return this; | ||
}, _proto2.next = function() { | ||
var result = this._innerIterator.next(); | ||
return result.done ? { | ||
done: !0, | ||
value: void 0 | ||
} : { | ||
value: selfOrRegisterValue(result.value[0]) | ||
}; | ||
}, LiveListIterator; | ||
}(), _emittedDeprecationWarnings = new Set; | ||
_proto.entries = function entries() { | ||
var _ref2; | ||
function deprecate(message, key) { | ||
void 0 === key && (key = message), "production" !== process.env.NODE_ENV && (_emittedDeprecationWarnings.has(key) || (_emittedDeprecationWarnings.add(key), | ||
console.error("DEPRECATION WARNING: " + message))); | ||
} | ||
var innerIterator = this._map.entries(); | ||
function deprecateIf(condition, message, key) { | ||
void 0 === key && (key = message), "production" !== process.env.NODE_ENV && condition && deprecate(message, key); | ||
} | ||
return _ref2 = {}, _ref2[Symbol.iterator] = function () { | ||
return this; | ||
}, _ref2.next = function next() { | ||
var iteratorValue = innerIterator.next(); | ||
function throwUsageError(message) { | ||
if ("production" !== process.env.NODE_ENV) { | ||
var usageError = new Error(message); | ||
throw usageError.name = "Usage error", usageError; | ||
} | ||
} | ||
if (iteratorValue.done) { | ||
return { | ||
done: true, | ||
value: undefined | ||
}; | ||
} | ||
_Symbol$iterator = Symbol.iterator; | ||
var entry = iteratorValue.value; | ||
return { | ||
value: [entry[0], selfOrRegisterValue(iteratorValue.value[1])] | ||
}; | ||
}, _ref2; | ||
var LiveMap = function(_AbstractCrdt) { | ||
function LiveMap(entries) { | ||
var _this; | ||
if ((_this = _AbstractCrdt.call(this) || this)._map = void 0, deprecateIf(null === entries, "Support for calling `new LiveMap(null)` will be removed in @liveblocks/client 0.18. Please call as `new LiveMap()`, or `new LiveMap([])`."), | ||
entries) { | ||
for (var _step, mappedEntries = [], _iterator = _createForOfIteratorHelperLoose(entries); !(_step = _iterator()).done; ) { | ||
var entry = _step.value, _value = selfOrRegister(entry[1]); | ||
_value._setParentLink(_assertThisInitialized(_this), entry[0]), mappedEntries.push([ entry[0], _value ]); | ||
} | ||
_this._map = new Map(mappedEntries); | ||
} else _this._map = new Map; | ||
return _this; | ||
} | ||
_inheritsLoose(LiveMap, _AbstractCrdt); | ||
var _proto = LiveMap.prototype; | ||
return _proto._serialize = function(parentId, parentKey, doc, intent) { | ||
if (null == this._id) throw new Error("Cannot serialize item is not attached"); | ||
if (null == parentId || null == parentKey) throw new Error("Cannot serialize map if parentId or parentKey is undefined"); | ||
var ops = [], op = { | ||
id: this._id, | ||
opId: null == doc ? void 0 : doc.generateOpId(), | ||
type: exports.OpType.CreateMap, | ||
intent: intent, | ||
parentId: parentId, | ||
parentKey: parentKey | ||
}; | ||
_proto[Symbol.iterator] = function () { | ||
return this.entries(); | ||
ops.push(op); | ||
for (var _step2, _iterator2 = _createForOfIteratorHelperLoose(this._map); !(_step2 = _iterator2()).done; ) { | ||
var _step2$value = _step2.value, _key2 = _step2$value[0], _value2 = _step2$value[1]; | ||
ops.push.apply(ops, _value2._serialize(this._id, _key2, doc)); | ||
} | ||
return ops; | ||
}, LiveMap._deserialize = function(_ref, parentToChildren, doc) { | ||
var id = _ref[0], item = _ref[1]; | ||
if (item.type !== exports.CrdtType.Map) throw new Error('Tried to deserialize a map but item type is "' + item.type + '"'); | ||
var map = new LiveMap; | ||
map._attach(id, doc); | ||
var children = parentToChildren.get(id); | ||
if (null == children) return map; | ||
for (var _step3, _iterator3 = _createForOfIteratorHelperLoose(children); !(_step3 = _iterator3()).done; ) { | ||
var entry = _step3.value, crdt = entry[1]; | ||
if (null == crdt.parentKey) throw new Error("Tried to deserialize a crdt but it does not have a parentKey and is not the root"); | ||
var child = deserialize(entry, parentToChildren, doc); | ||
child._setParentLink(map, crdt.parentKey), map._map.set(crdt.parentKey, child); | ||
} | ||
return map; | ||
}, _proto._attach = function(id, doc) { | ||
_AbstractCrdt.prototype._attach.call(this, id, doc); | ||
for (var _step4, _iterator4 = _createForOfIteratorHelperLoose(this._map); !(_step4 = _iterator4()).done; ) { | ||
var _step4$value = _step4.value; | ||
_step4$value[0]; | ||
var _value3 = _step4$value[1]; | ||
isCrdt(_value3) && _value3._attach(doc.generateId(), doc); | ||
} | ||
}, _proto._attachChild = function(op, _isLocal) { | ||
var _updates; | ||
if (null == this._doc) throw new Error("Can't attach child if doc is not present"); | ||
var id = op.id, key = op.parentKey, child = creationOpToLiveStructure(op); | ||
if (void 0 !== this._doc.getItem(id)) return { | ||
modified: !1 | ||
}; | ||
_proto.keys = function keys() { | ||
return this._map.keys(); | ||
var reverse, previousValue = this._map.get(key); | ||
return previousValue ? (reverse = previousValue._serialize(this._id, key), previousValue._detach()) : reverse = [ { | ||
type: exports.OpType.DeleteCrdt, | ||
id: id | ||
} ], child._setParentLink(this, key), child._attach(id, this._doc), this._map.set(key, child), | ||
{ | ||
modified: { | ||
node: this, | ||
type: "LiveMap", | ||
updates: (_updates = {}, _updates[key] = { | ||
type: "update" | ||
}, _updates) | ||
}, | ||
reverse: reverse | ||
}; | ||
_proto.values = function values() { | ||
var _ref3; | ||
var innerIterator = this._map.values(); | ||
return _ref3 = {}, _ref3[Symbol.iterator] = function () { | ||
return this; | ||
}, _ref3.next = function next() { | ||
var iteratorValue = innerIterator.next(); | ||
if (iteratorValue.done) { | ||
return { | ||
done: true, | ||
value: undefined | ||
}; | ||
} | ||
return { | ||
value: selfOrRegisterValue(iteratorValue.value) | ||
}; | ||
}, _ref3; | ||
}, _proto._detach = function() { | ||
_AbstractCrdt.prototype._detach.call(this); | ||
for (var _step5, _iterator5 = _createForOfIteratorHelperLoose(this._map.values()); !(_step5 = _iterator5()).done; ) { | ||
_step5.value._detach(); | ||
} | ||
}, _proto._detachChild = function(child) { | ||
for (var _updates2, _step6, reverse = child._serialize(this._id, child._parentKey, this._doc), _iterator6 = _createForOfIteratorHelperLoose(this._map); !(_step6 = _iterator6()).done; ) { | ||
var _step6$value = _step6.value, _key3 = _step6$value[0]; | ||
_step6$value[1] === child && this._map.delete(_key3); | ||
} | ||
return child._detach(), { | ||
modified: { | ||
node: this, | ||
type: "LiveMap", | ||
updates: (_updates2 = {}, _updates2[child._parentKey] = { | ||
type: "delete" | ||
}, _updates2) | ||
}, | ||
reverse: reverse | ||
}; | ||
_proto.forEach = function forEach(callback) { | ||
for (var _iterator7 = _createForOfIteratorHelperLoose(this), _step7; !(_step7 = _iterator7()).done;) { | ||
var entry = _step7.value; | ||
callback(entry[1], entry[0], this); | ||
} | ||
}, _proto._toSerializedCrdt = function() { | ||
var _this$_parent; | ||
return { | ||
type: exports.CrdtType.Map, | ||
parentId: null == (_this$_parent = this._parent) ? void 0 : _this$_parent._id, | ||
parentKey: this._parentKey | ||
}; | ||
_createClass(LiveMap, [{ | ||
key: "size", | ||
get: function get() { | ||
return this._map.size; | ||
} | ||
}]); | ||
return LiveMap; | ||
}(AbstractCrdt); | ||
function parseJson(rawMessage) { | ||
try { | ||
return JSON.parse(rawMessage); | ||
} catch (e) { | ||
return undefined; | ||
}, _proto.get = function(key) { | ||
var value = this._map.get(key); | ||
if (null != value) return selfOrRegisterValue(value); | ||
}, _proto.set = function(key, value) { | ||
var oldValue = this._map.get(key); | ||
oldValue && oldValue._detach(); | ||
var item = selfOrRegister(value); | ||
if (item._setParentLink(this, key), this._map.set(key, item), this._doc && this._id) { | ||
var _updates3, id = this._doc.generateId(); | ||
item._attach(id, this._doc); | ||
var storageUpdates = new Map; | ||
storageUpdates.set(this._id, { | ||
node: this, | ||
type: "LiveMap", | ||
updates: (_updates3 = {}, _updates3[key] = { | ||
type: "update" | ||
}, _updates3) | ||
}), this._doc.dispatch(item._serialize(this._id, key, this._doc), oldValue ? oldValue._serialize(this._id, key) : [ { | ||
type: exports.OpType.DeleteCrdt, | ||
id: id | ||
} ], storageUpdates); | ||
} | ||
} | ||
function isJsonArray(data) { | ||
return Array.isArray(data); | ||
} | ||
function isJsonObject(data) { | ||
return data !== null && typeof data === "object" && !isJsonArray(data); | ||
} | ||
var _emittedDeprecationWarnings = new Set(); | ||
function deprecate(message, key) { | ||
if (key === void 0) { | ||
key = message; | ||
}, _proto.has = function(key) { | ||
return this._map.has(key); | ||
}, _proto.delete = function(key) { | ||
var item = this._map.get(key); | ||
if (null == item) return !1; | ||
if (item._detach(), this._map.delete(key), this._doc && item._id) { | ||
var _updates4, storageUpdates = new Map; | ||
storageUpdates.set(this._id, { | ||
node: this, | ||
type: "LiveMap", | ||
updates: (_updates4 = {}, _updates4[key] = { | ||
type: "delete" | ||
}, _updates4) | ||
}), this._doc.dispatch([ { | ||
type: exports.OpType.DeleteCrdt, | ||
id: item._id, | ||
opId: this._doc.generateOpId() | ||
} ], item._serialize(this._id, key), storageUpdates); | ||
} | ||
if (process.env.NODE_ENV !== "production") { | ||
if (!_emittedDeprecationWarnings.has(key)) { | ||
_emittedDeprecationWarnings.add(key); | ||
console.error("DEPRECATION WARNING: " + message); | ||
} | ||
return !0; | ||
}, _proto.entries = function() { | ||
var _ref2, innerIterator = this._map.entries(); | ||
return (_ref2 = {})[Symbol.iterator] = function() { | ||
return this; | ||
}, _ref2.next = function() { | ||
var iteratorValue = innerIterator.next(); | ||
return iteratorValue.done ? { | ||
done: !0, | ||
value: void 0 | ||
} : { | ||
value: [ iteratorValue.value[0], selfOrRegisterValue(iteratorValue.value[1]) ] | ||
}; | ||
}, _ref2; | ||
}, _proto[_Symbol$iterator] = function() { | ||
return this.entries(); | ||
}, _proto.keys = function() { | ||
return this._map.keys(); | ||
}, _proto.values = function() { | ||
var _ref3, innerIterator = this._map.values(); | ||
return (_ref3 = {})[Symbol.iterator] = function() { | ||
return this; | ||
}, _ref3.next = function() { | ||
var iteratorValue = innerIterator.next(); | ||
return iteratorValue.done ? { | ||
done: !0, | ||
value: void 0 | ||
} : { | ||
value: selfOrRegisterValue(iteratorValue.value) | ||
}; | ||
}, _ref3; | ||
}, _proto.forEach = function(callback) { | ||
for (var _step7, _iterator7 = _createForOfIteratorHelperLoose(this); !(_step7 = _iterator7()).done; ) { | ||
var entry = _step7.value; | ||
callback(entry[1], entry[0], this); | ||
} | ||
} | ||
function deprecateIf(condition, message, key) { | ||
if (key === void 0) { | ||
key = message; | ||
}, _createClass(LiveMap, [ { | ||
key: "size", | ||
get: function() { | ||
return this._map.size; | ||
} | ||
} ]), LiveMap; | ||
}(AbstractCrdt); | ||
if (process.env.NODE_ENV !== "production") { | ||
if (condition) { | ||
deprecate(message, key); | ||
} | ||
} | ||
} | ||
function remove(array, item) { | ||
for (var i = 0; i < array.length; i++) { | ||
if (array[i] === item) { | ||
array.splice(i, 1); | ||
break; | ||
} | ||
} | ||
} | ||
function compact(items) { | ||
return items.filter(function (item) { | ||
return item != null; | ||
}); | ||
} | ||
function creationOpToLiveStructure(op) { | ||
switch (op.type) { | ||
case exports.OpType.CreateRegister: | ||
return new LiveRegister(op.data); | ||
switch (op.type) { | ||
case exports.OpType.CreateRegister: | ||
return new LiveRegister(op.data); | ||
case exports.OpType.CreateObject: | ||
return new LiveObject(op.data); | ||
case exports.OpType.CreateObject: | ||
return new LiveObject(op.data); | ||
case exports.OpType.CreateMap: | ||
return new LiveMap(); | ||
case exports.OpType.CreateMap: | ||
return new LiveMap; | ||
case exports.OpType.CreateList: | ||
return new LiveList(); | ||
} | ||
case exports.OpType.CreateList: | ||
return new LiveList; | ||
} | ||
} | ||
function isSameNodeOrChildOf(node, parent) { | ||
if (node === parent) { | ||
return true; | ||
} | ||
if (node._parent) { | ||
return isSameNodeOrChildOf(node._parent, parent); | ||
} | ||
return false; | ||
} | ||
function deserialize(entry, parentToChildren, doc) { | ||
switch (entry[1].type) { | ||
case exports.CrdtType.Object: | ||
{ | ||
return LiveObject._deserialize(entry, parentToChildren, doc); | ||
} | ||
switch (entry[1].type) { | ||
case exports.CrdtType.Object: | ||
return LiveObject._deserialize(entry, parentToChildren, doc); | ||
case exports.CrdtType.List: | ||
{ | ||
return LiveList._deserialize(entry, parentToChildren, doc); | ||
} | ||
case exports.CrdtType.List: | ||
return LiveList._deserialize(entry, parentToChildren, doc); | ||
case exports.CrdtType.Map: | ||
{ | ||
return LiveMap._deserialize(entry, parentToChildren, doc); | ||
} | ||
case exports.CrdtType.Map: | ||
return LiveMap._deserialize(entry, parentToChildren, doc); | ||
case exports.CrdtType.Register: | ||
{ | ||
return LiveRegister._deserialize(entry, parentToChildren, doc); | ||
} | ||
case exports.CrdtType.Register: | ||
return LiveRegister._deserialize(entry, parentToChildren, doc); | ||
default: | ||
{ | ||
throw new Error("Unexpected CRDT type"); | ||
} | ||
} | ||
default: | ||
throw new Error("Unexpected CRDT type"); | ||
} | ||
} | ||
function isCrdt(obj) { | ||
return obj instanceof LiveObject || obj instanceof LiveMap || obj instanceof LiveList || obj instanceof LiveRegister; | ||
return obj instanceof LiveObject || obj instanceof LiveMap || obj instanceof LiveList || obj instanceof LiveRegister; | ||
} | ||
function selfOrRegisterValue(obj) { | ||
if (obj instanceof LiveRegister) { | ||
return obj.data; | ||
} | ||
return obj instanceof LiveRegister ? obj.data : obj; | ||
} | ||
return obj; | ||
} | ||
function selfOrRegister(obj) { | ||
if (obj instanceof LiveObject || obj instanceof LiveMap || obj instanceof LiveList) { | ||
return obj; | ||
} else if (obj instanceof LiveRegister) { | ||
throw new Error("Internal error. LiveRegister should not be created from selfOrRegister"); | ||
} else { | ||
return new LiveRegister(obj); | ||
} | ||
if (obj instanceof LiveObject || obj instanceof LiveMap || obj instanceof LiveList) return obj; | ||
if (obj instanceof LiveRegister) throw new Error("Internal error. LiveRegister should not be created from selfOrRegister"); | ||
return new LiveRegister(obj); | ||
} | ||
function getTreesDiffOperations(currentItems, newItems) { | ||
var ops = []; | ||
currentItems.forEach(function (_, id) { | ||
if (!newItems.get(id)) { | ||
ops.push({ | ||
type: exports.OpType.DeleteCrdt, | ||
id: id | ||
}); | ||
} | ||
}); | ||
newItems.forEach(function (crdt, id) { | ||
var currentCrdt = currentItems.get(id); | ||
if (currentCrdt) { | ||
if (crdt.type === exports.CrdtType.Object) { | ||
if (JSON.stringify(crdt.data) !== JSON.stringify(currentCrdt.data)) { | ||
ops.push({ | ||
type: exports.OpType.UpdateObject, | ||
id: id, | ||
data: crdt.data | ||
}); | ||
} | ||
} | ||
if (crdt.parentKey !== currentCrdt.parentKey) { | ||
ops.push({ | ||
type: exports.OpType.SetParentKey, | ||
id: id, | ||
parentKey: crdt.parentKey | ||
}); | ||
} | ||
} else { | ||
switch (crdt.type) { | ||
case exports.CrdtType.Register: | ||
ops.push({ | ||
type: exports.OpType.CreateRegister, | ||
id: id, | ||
parentId: crdt.parentId, | ||
parentKey: crdt.parentKey, | ||
data: crdt.data | ||
}); | ||
break; | ||
case exports.CrdtType.List: | ||
ops.push({ | ||
type: exports.OpType.CreateList, | ||
id: id, | ||
parentId: crdt.parentId, | ||
parentKey: crdt.parentKey | ||
}); | ||
break; | ||
case exports.CrdtType.Object: | ||
ops.push({ | ||
type: exports.OpType.CreateObject, | ||
id: id, | ||
parentId: crdt.parentId, | ||
parentKey: crdt.parentKey, | ||
data: crdt.data | ||
}); | ||
break; | ||
case exports.CrdtType.Map: | ||
ops.push({ | ||
type: exports.OpType.CreateMap, | ||
id: id, | ||
parentId: crdt.parentId, | ||
parentKey: crdt.parentKey | ||
}); | ||
break; | ||
} | ||
} | ||
}); | ||
return ops; | ||
} | ||
function mergeObjectStorageUpdates(first, second) { | ||
var updates = first.updates; | ||
for (var _iterator = _createForOfIteratorHelperLoose(entries(second.updates)), _step; !(_step = _iterator()).done;) { | ||
var _step$value = _step.value, | ||
_key = _step$value[0], | ||
value = _step$value[1]; | ||
updates[_key] = value; | ||
} | ||
return _extends({}, second, { | ||
updates: updates | ||
}); | ||
} | ||
function mergeMapStorageUpdates(first, second) { | ||
var updates = first.updates; | ||
for (var _iterator2 = _createForOfIteratorHelperLoose(entries(second.updates)), _step2; !(_step2 = _iterator2()).done;) { | ||
var _step2$value = _step2.value, | ||
_key2 = _step2$value[0], | ||
value = _step2$value[1]; | ||
updates[_key2] = value; | ||
} | ||
return _extends({}, second, { | ||
updates: updates | ||
}); | ||
} | ||
function mergeListStorageUpdates(first, second) { | ||
var updates = first.updates; | ||
return _extends({}, second, { | ||
updates: updates.concat(second.updates) | ||
}); | ||
} | ||
function mergeStorageUpdates(first, second) { | ||
if (!first) { | ||
return second; | ||
} | ||
if (first.type === "LiveObject" && second.type === "LiveObject") { | ||
return mergeObjectStorageUpdates(first, second); | ||
} else if (first.type === "LiveMap" && second.type === "LiveMap") { | ||
return mergeMapStorageUpdates(first, second); | ||
} else if (first.type === "LiveList" && second.type === "LiveList") { | ||
return mergeListStorageUpdates(first, second); | ||
} else ; | ||
return second; | ||
} | ||
function isPlain(value) { | ||
var type = typeof value; | ||
return type === "undefined" || value === null || type === "string" || type === "boolean" || type === "number" || Array.isArray(value) || isPlainObject(value); | ||
} | ||
function isPlainObject(value) { | ||
if (typeof value !== "object" || value === null) return false; | ||
var type = typeof value; | ||
return "undefined" === type || null === value || "string" === type || "boolean" === type || "number" === type || Array.isArray(value) || function(value) { | ||
if ("object" != typeof value || null === value) return !1; | ||
var proto = Object.getPrototypeOf(value); | ||
if (proto === null) return true; | ||
if (null === proto) return !0; | ||
var baseProto = proto; | ||
while (Object.getPrototypeOf(baseProto) !== null) { | ||
baseProto = Object.getPrototypeOf(baseProto); | ||
} | ||
for (;null !== Object.getPrototypeOf(baseProto); ) baseProto = Object.getPrototypeOf(baseProto); | ||
return proto === baseProto; | ||
}(value); | ||
} | ||
function findNonSerializableValue(value, path) { | ||
if (path === void 0) { | ||
path = ""; | ||
} | ||
if (!isPlain) { | ||
return { | ||
path: path || "root", | ||
value: value | ||
}; | ||
} | ||
if (typeof value !== "object" || value === null) { | ||
return false; | ||
} | ||
for (var _i = 0, _Object$entries = Object.entries(value); _i < _Object$entries.length; _i++) { | ||
var _Object$entries$_i = _Object$entries[_i], | ||
_key3 = _Object$entries$_i[0], | ||
nestedValue = _Object$entries$_i[1]; | ||
var nestedPath = path ? path + "." + _key3 : _key3; | ||
if (!isPlain(nestedValue)) { | ||
return { | ||
path: nestedPath, | ||
value: nestedValue | ||
}; | ||
} | ||
if (typeof nestedValue === "object") { | ||
var nonSerializableNestedValue = findNonSerializableValue(nestedValue, nestedPath); | ||
if (nonSerializableNestedValue) { | ||
return nonSerializableNestedValue; | ||
} | ||
} | ||
} | ||
return false; | ||
function entries(obj) { | ||
return Object.entries(obj); | ||
} | ||
function isTokenValid(token) { | ||
var tokenParts = token.split("."); | ||
if (tokenParts.length !== 3) { | ||
return false; | ||
var LiveObject = function(_AbstractCrdt) { | ||
function LiveObject(obj) { | ||
var _this; | ||
for (var key in void 0 === obj && (obj = {}), (_this = _AbstractCrdt.call(this) || this)._map = void 0, | ||
_this._propToLastUpdate = void 0, _this._propToLastUpdate = new Map, obj) { | ||
var value = obj[key]; | ||
value instanceof AbstractCrdt && value._setParentLink(_assertThisInitialized(_this), key); | ||
} | ||
var data = parseJson(atob(tokenParts[1])); | ||
if (data === undefined || !isJsonObject(data) || typeof data.exp !== "number") { | ||
return false; | ||
return _this._map = new Map(Object.entries(obj)), _this; | ||
} | ||
_inheritsLoose(LiveObject, _AbstractCrdt); | ||
var _proto = LiveObject.prototype; | ||
return _proto._serialize = function(parentId, parentKey, doc, intent) { | ||
if (null == this._id) throw new Error("Cannot serialize item is not attached"); | ||
var ops = [], op = { | ||
id: this._id, | ||
opId: null == doc ? void 0 : doc.generateOpId(), | ||
intent: intent, | ||
type: exports.OpType.CreateObject, | ||
parentId: parentId, | ||
parentKey: parentKey, | ||
data: {} | ||
}; | ||
ops.push(op); | ||
for (var _step, _iterator = _createForOfIteratorHelperLoose(this._map); !(_step = _iterator()).done; ) { | ||
var _step$value = _step.value, key = _step$value[0], value = _step$value[1]; | ||
value instanceof AbstractCrdt ? ops.push.apply(ops, value._serialize(this._id, key, doc)) : op.data[key] = value; | ||
} | ||
var now = Date.now(); | ||
if (now / 1000 > data.exp - 300) { | ||
return false; | ||
return ops; | ||
}, LiveObject._deserialize = function(_ref, parentToChildren, doc) { | ||
var id = _ref[0], item = _ref[1]; | ||
if (item.type !== exports.CrdtType.Object) throw new Error('Tried to deserialize a record but item type is "' + item.type + '"'); | ||
var liveObj = new LiveObject(item.data); | ||
return liveObj._attach(id, doc), this._deserializeChildren(liveObj, parentToChildren, doc); | ||
}, LiveObject._deserializeChildren = function(liveObj, parentToChildren, doc) { | ||
var children = parentToChildren.get(liveObj._id); | ||
if (null == children) return liveObj; | ||
for (var _step2, _iterator2 = _createForOfIteratorHelperLoose(children); !(_step2 = _iterator2()).done; ) { | ||
var entry = _step2.value, crdt = entry[1]; | ||
if (null == crdt.parentKey) throw new Error("Tried to deserialize a crdt but it does not have a parentKey and is not the root"); | ||
var child = deserialize(entry, parentToChildren, doc); | ||
child._setParentLink(liveObj, crdt.parentKey), liveObj._map.set(crdt.parentKey, child); | ||
} | ||
return true; | ||
} | ||
function entries(obj) { | ||
return Object.entries(obj); | ||
} | ||
var LiveObject = function (_AbstractCrdt) { | ||
_inheritsLoose(LiveObject, _AbstractCrdt); | ||
function LiveObject(object) { | ||
var _this; | ||
if (object === void 0) { | ||
object = {}; | ||
} | ||
_this = _AbstractCrdt.call(this) || this; | ||
_this._propToLastUpdate = new Map(); | ||
for (var key in object) { | ||
var value = object[key]; | ||
if (value instanceof AbstractCrdt) { | ||
value._setParentLink(_assertThisInitialized(_this), key); | ||
} | ||
} | ||
_this._map = new Map(Object.entries(object)); | ||
return _this; | ||
return liveObj; | ||
}, _proto._attach = function(id, doc) { | ||
_AbstractCrdt.prototype._attach.call(this, id, doc); | ||
for (var _step3, _iterator3 = _createForOfIteratorHelperLoose(this._map); !(_step3 = _iterator3()).done; ) { | ||
var _step3$value = _step3.value; | ||
_step3$value[0]; | ||
var value = _step3$value[1]; | ||
value instanceof AbstractCrdt && value._attach(doc.generateId(), doc); | ||
} | ||
var _proto = LiveObject.prototype; | ||
_proto._serialize = function _serialize(parentId, parentKey, doc, intent) { | ||
if (this._id == null) { | ||
throw new Error("Cannot serialize item is not attached"); | ||
} | ||
var ops = []; | ||
var op = { | ||
id: this._id, | ||
opId: doc == null ? void 0 : doc.generateOpId(), | ||
intent: intent, | ||
type: exports.OpType.CreateObject, | ||
parentId: parentId, | ||
parentKey: parentKey, | ||
data: {} | ||
}; | ||
ops.push(op); | ||
for (var _iterator = _createForOfIteratorHelperLoose(this._map), _step; !(_step = _iterator()).done;) { | ||
var _step$value = _step.value, | ||
key = _step$value[0], | ||
value = _step$value[1]; | ||
if (value instanceof AbstractCrdt) { | ||
ops.push.apply(ops, value._serialize(this._id, key, doc)); | ||
} else { | ||
op.data[key] = value; | ||
} | ||
} | ||
return ops; | ||
}, _proto._attachChild = function(op, isLocal) { | ||
var _updates; | ||
if (null == this._doc) throw new Error("Can't attach child if doc is not present"); | ||
var id = op.id, parentKey = op.parentKey, opId = op.opId, key = parentKey, child = creationOpToLiveStructure(op); | ||
if (void 0 !== this._doc.getItem(id)) return this._propToLastUpdate.get(key) === opId && this._propToLastUpdate.delete(key), | ||
{ | ||
modified: !1 | ||
}; | ||
LiveObject._deserialize = function _deserialize(_ref, parentToChildren, doc) { | ||
var id = _ref[0], | ||
item = _ref[1]; | ||
if (item.type !== exports.CrdtType.Object) { | ||
throw new Error("Tried to deserialize a record but item type is \"" + item.type + "\""); | ||
} | ||
var object = new LiveObject(item.data); | ||
object._attach(id, doc); | ||
return this._deserializeChildren(object, parentToChildren, doc); | ||
if (isLocal) this._propToLastUpdate.set(key, opId); else if (void 0 !== this._propToLastUpdate.get(key)) return this._propToLastUpdate.get(key) === opId ? (this._propToLastUpdate.delete(key), | ||
{ | ||
modified: !1 | ||
}) : { | ||
modified: !1 | ||
}; | ||
LiveObject._deserializeChildren = function _deserializeChildren(object, parentToChildren, doc) { | ||
var children = parentToChildren.get(object._id); | ||
if (children == null) { | ||
return object; | ||
} | ||
for (var _iterator2 = _createForOfIteratorHelperLoose(children), _step2; !(_step2 = _iterator2()).done;) { | ||
var entry = _step2.value; | ||
var crdt = entry[1]; | ||
if (crdt.parentKey == null) { | ||
throw new Error("Tried to deserialize a crdt but it does not have a parentKey and is not the root"); | ||
} | ||
var child = deserialize(entry, parentToChildren, doc); | ||
child._setParentLink(object, crdt.parentKey); | ||
object._map.set(crdt.parentKey, child); | ||
} | ||
return object; | ||
var reverse, previousValue = this._map.get(key); | ||
if (isCrdt(previousValue)) reverse = previousValue._serialize(this._id, key), previousValue._detach(); else if (void 0 === previousValue) reverse = [ { | ||
type: exports.OpType.DeleteObjectKey, | ||
id: this._id, | ||
key: key | ||
} ]; else { | ||
var _data; | ||
reverse = [ { | ||
type: exports.OpType.UpdateObject, | ||
id: this._id, | ||
data: (_data = {}, _data[key] = previousValue, _data) | ||
} ]; | ||
} | ||
return this._map.set(key, child), child._setParentLink(this, key), child._attach(id, this._doc), | ||
{ | ||
reverse: reverse, | ||
modified: { | ||
node: this, | ||
type: "LiveObject", | ||
updates: (_updates = {}, _updates[key] = { | ||
type: "update" | ||
}, _updates) | ||
} | ||
}; | ||
_proto._attach = function _attach(id, doc) { | ||
_AbstractCrdt.prototype._attach.call(this, id, doc); | ||
for (var _iterator3 = _createForOfIteratorHelperLoose(this._map), _step3; !(_step3 = _iterator3()).done;) { | ||
var _step3$value = _step3.value; | ||
_step3$value[0]; | ||
var value = _step3$value[1]; | ||
if (value instanceof AbstractCrdt) { | ||
value._attach(doc.generateId(), doc); | ||
} | ||
} | ||
}, _proto._detachChild = function(child) { | ||
if (child) { | ||
for (var _updates2, _step4, reverse = child._serialize(this._id, child._parentKey, this._doc), _iterator4 = _createForOfIteratorHelperLoose(this._map); !(_step4 = _iterator4()).done; ) { | ||
var _step4$value = _step4.value, key = _step4$value[0]; | ||
_step4$value[1] === child && this._map.delete(key); | ||
} | ||
return child._detach(), { | ||
modified: { | ||
node: this, | ||
type: "LiveObject", | ||
updates: (_updates2 = {}, _updates2[child._parentKey] = { | ||
type: "delete" | ||
}, _updates2) | ||
}, | ||
reverse: reverse | ||
}; | ||
} | ||
return { | ||
modified: !1 | ||
}; | ||
_proto._attachChild = function _attachChild(op, isLocal) { | ||
var _updates; | ||
if (this._doc == null) { | ||
throw new Error("Can't attach child if doc is not present"); | ||
} | ||
var id = op.id, | ||
parentKey = op.parentKey, | ||
opId = op.opId; | ||
var key = parentKey; | ||
var child = creationOpToLiveStructure(op); | ||
if (this._doc.getItem(id) !== undefined) { | ||
if (this._propToLastUpdate.get(key) === opId) { | ||
this._propToLastUpdate.delete(key); | ||
} | ||
return { | ||
modified: false | ||
}; | ||
} | ||
if (isLocal) { | ||
this._propToLastUpdate.set(key, opId); | ||
} else if (this._propToLastUpdate.get(key) === undefined) ; else if (this._propToLastUpdate.get(key) === opId) { | ||
this._propToLastUpdate.delete(key); | ||
return { | ||
modified: false | ||
}; | ||
} else { | ||
return { | ||
modified: false | ||
}; | ||
} | ||
var previousValue = this._map.get(key); | ||
var reverse; | ||
if (isCrdt(previousValue)) { | ||
reverse = previousValue._serialize(this._id, key); | ||
previousValue._detach(); | ||
} else if (previousValue === undefined) { | ||
reverse = [{ | ||
type: exports.OpType.DeleteObjectKey, | ||
id: this._id, | ||
key: key | ||
}]; | ||
} else { | ||
var _data; | ||
reverse = [{ | ||
type: exports.OpType.UpdateObject, | ||
id: this._id, | ||
data: (_data = {}, _data[key] = previousValue, _data) | ||
}]; | ||
} | ||
this._map.set(key, child); | ||
child._setParentLink(this, key); | ||
child._attach(id, this._doc); | ||
return { | ||
reverse: reverse, | ||
modified: { | ||
node: this, | ||
type: "LiveObject", | ||
updates: (_updates = {}, _updates[key] = { | ||
type: "update" | ||
}, _updates) | ||
} | ||
}; | ||
}, _proto._detachChildren = function() { | ||
for (var _step5, _iterator5 = _createForOfIteratorHelperLoose(this._map); !(_step5 = _iterator5()).done; ) { | ||
var _step5$value = _step5.value, key = _step5$value[0], value = _step5$value[1]; | ||
this._map.delete(key), value._detach(); | ||
} | ||
}, _proto._detach = function() { | ||
_AbstractCrdt.prototype._detach.call(this); | ||
for (var _step6, _iterator6 = _createForOfIteratorHelperLoose(this._map.values()); !(_step6 = _iterator6()).done; ) { | ||
var value = _step6.value; | ||
isCrdt(value) && value._detach(); | ||
} | ||
}, _proto._apply = function(op, isLocal) { | ||
return op.type === exports.OpType.UpdateObject ? this._applyUpdate(op, isLocal) : op.type === exports.OpType.DeleteObjectKey ? this._applyDeleteObjectKey(op) : _AbstractCrdt.prototype._apply.call(this, op, isLocal); | ||
}, _proto._toSerializedCrdt = function() { | ||
for (var _this$_parent, _step7, data = {}, _iterator7 = _createForOfIteratorHelperLoose(this._map); !(_step7 = _iterator7()).done; ) { | ||
var _step7$value = _step7.value, key = _step7$value[0], value = _step7$value[1]; | ||
value instanceof AbstractCrdt == !1 && (data[key] = value); | ||
} | ||
return { | ||
type: exports.CrdtType.Object, | ||
parentId: null == (_this$_parent = this._parent) ? void 0 : _this$_parent._id, | ||
parentKey: this._parentKey, | ||
data: data | ||
}; | ||
_proto._detachChild = function _detachChild(child) { | ||
if (child) { | ||
var _updates2; | ||
var reverse = child._serialize(this._id, child._parentKey, this._doc); | ||
for (var _iterator4 = _createForOfIteratorHelperLoose(this._map), _step4; !(_step4 = _iterator4()).done;) { | ||
var _step4$value = _step4.value, | ||
key = _step4$value[0], | ||
value = _step4$value[1]; | ||
if (value === child) { | ||
this._map.delete(key); | ||
} | ||
} | ||
child._detach(); | ||
var storageUpdate = { | ||
node: this, | ||
type: "LiveObject", | ||
updates: (_updates2 = {}, _updates2[child._parentKey] = { | ||
type: "delete" | ||
}, _updates2) | ||
}; | ||
return { | ||
modified: storageUpdate, | ||
reverse: reverse | ||
}; | ||
} | ||
return { | ||
modified: false | ||
}; | ||
}, _proto._applyUpdate = function(op, isLocal) { | ||
var isModified = !1, reverse = [], reverseUpdate = { | ||
type: exports.OpType.UpdateObject, | ||
id: this._id, | ||
data: {} | ||
}; | ||
_proto._detachChildren = function _detachChildren() { | ||
for (var _iterator5 = _createForOfIteratorHelperLoose(this._map), _step5; !(_step5 = _iterator5()).done;) { | ||
var _step5$value = _step5.value, | ||
key = _step5$value[0], | ||
value = _step5$value[1]; | ||
this._map.delete(key); | ||
value._detach(); | ||
for (var key in reverse.push(reverseUpdate), op.data) { | ||
var oldValue = this._map.get(key); | ||
oldValue instanceof AbstractCrdt ? (reverse.push.apply(reverse, oldValue._serialize(this._id, key)), | ||
oldValue._detach()) : void 0 !== oldValue ? reverseUpdate.data[key] = oldValue : void 0 === oldValue && reverse.push({ | ||
type: exports.OpType.DeleteObjectKey, | ||
id: this._id, | ||
key: key | ||
}); | ||
} | ||
var updateDelta = {}; | ||
for (var _key2 in op.data) { | ||
if (isLocal) this._propToLastUpdate.set(_key2, op.opId); else { | ||
if (null != this._propToLastUpdate.get(_key2)) { | ||
if (this._propToLastUpdate.get(_key2) === op.opId) { | ||
this._propToLastUpdate.delete(_key2); | ||
continue; | ||
} | ||
continue; | ||
} | ||
isModified = !0; | ||
} | ||
var _oldValue = this._map.get(_key2); | ||
isCrdt(_oldValue) && _oldValue._detach(), isModified = !0, updateDelta[_key2] = { | ||
type: "update" | ||
}, this._map.set(_key2, op.data[_key2]); | ||
} | ||
return 0 !== Object.keys(reverseUpdate.data).length && reverse.unshift(reverseUpdate), | ||
isModified ? { | ||
modified: { | ||
node: this, | ||
type: "LiveObject", | ||
updates: updateDelta | ||
}, | ||
reverse: reverse | ||
} : { | ||
modified: !1 | ||
}; | ||
_proto._detach = function _detach() { | ||
_AbstractCrdt.prototype._detach.call(this); | ||
for (var _iterator6 = _createForOfIteratorHelperLoose(this._map.values()), _step6; !(_step6 = _iterator6()).done;) { | ||
var value = _step6.value; | ||
if (isCrdt(value)) { | ||
value._detach(); | ||
} | ||
} | ||
}, _proto._applyDeleteObjectKey = function(op) { | ||
var _updates3, key = op.key; | ||
if (!1 === this._map.has(key)) return { | ||
modified: !1 | ||
}; | ||
_proto._apply = function _apply(op, isLocal) { | ||
if (op.type === exports.OpType.UpdateObject) { | ||
return this._applyUpdate(op, isLocal); | ||
} else if (op.type === exports.OpType.DeleteObjectKey) { | ||
return this._applyDeleteObjectKey(op); | ||
} | ||
return _AbstractCrdt.prototype._apply.call(this, op, isLocal); | ||
if (void 0 !== this._propToLastUpdate.get(key)) return { | ||
modified: !1 | ||
}; | ||
_proto._toSerializedCrdt = function _toSerializedCrdt() { | ||
var _this$_parent; | ||
var data = {}; | ||
for (var _iterator7 = _createForOfIteratorHelperLoose(this._map), _step7; !(_step7 = _iterator7()).done;) { | ||
var _step7$value = _step7.value, | ||
key = _step7$value[0], | ||
value = _step7$value[1]; | ||
if (value instanceof AbstractCrdt === false) { | ||
data[key] = value; | ||
} | ||
} | ||
return { | ||
type: exports.CrdtType.Object, | ||
parentId: (_this$_parent = this._parent) == null ? void 0 : _this$_parent._id, | ||
parentKey: this._parentKey, | ||
data: data | ||
}; | ||
var oldValue = this._map.get(key), reverse = []; | ||
if (isCrdt(oldValue)) reverse = oldValue._serialize(this._id, op.key), oldValue._detach(); else if (void 0 !== oldValue) { | ||
var _data2; | ||
reverse = [ { | ||
type: exports.OpType.UpdateObject, | ||
id: this._id, | ||
data: (_data2 = {}, _data2[key] = oldValue, _data2) | ||
} ]; | ||
} | ||
return this._map.delete(key), { | ||
modified: { | ||
node: this, | ||
type: "LiveObject", | ||
updates: (_updates3 = {}, _updates3[op.key] = { | ||
type: "delete" | ||
}, _updates3) | ||
}, | ||
reverse: reverse | ||
}; | ||
_proto._applyUpdate = function _applyUpdate(op, isLocal) { | ||
var isModified = false; | ||
var reverse = []; | ||
var reverseUpdate = { | ||
type: exports.OpType.UpdateObject, | ||
id: this._id, | ||
data: {} | ||
}, _proto.toObject = function() { | ||
return function(iterable) { | ||
for (var _step3, obj = {}, _iterator3 = _createForOfIteratorHelperLoose(iterable); !(_step3 = _iterator3()).done; ) { | ||
var _step3$value = _step3.value, _key4 = _step3$value[0], val = _step3$value[1]; | ||
obj[_key4] = val; | ||
} | ||
return obj; | ||
}(this._map); | ||
}, _proto.set = function(key, value) { | ||
var _this$update; | ||
this.update(((_this$update = {})[key] = value, _this$update)); | ||
}, _proto.get = function(key) { | ||
return this._map.get(key); | ||
}, _proto.delete = function(key) { | ||
var _updates4, keyAsString = key, oldValue = this._map.get(keyAsString); | ||
if (void 0 !== oldValue) { | ||
if (null == this._doc || null == this._id) return oldValue instanceof AbstractCrdt && oldValue._detach(), | ||
void this._map.delete(keyAsString); | ||
var reverse, _data3; | ||
if (oldValue instanceof AbstractCrdt) oldValue._detach(), reverse = oldValue._serialize(this._id, keyAsString); else reverse = [ { | ||
type: exports.OpType.UpdateObject, | ||
data: (_data3 = {}, _data3[keyAsString] = oldValue, _data3), | ||
id: this._id | ||
} ]; | ||
this._map.delete(keyAsString); | ||
var storageUpdates = new Map; | ||
storageUpdates.set(this._id, { | ||
node: this, | ||
type: "LiveObject", | ||
updates: (_updates4 = {}, _updates4[key] = { | ||
type: "delete" | ||
}, _updates4) | ||
}), this._doc.dispatch([ { | ||
type: exports.OpType.DeleteObjectKey, | ||
key: keyAsString, | ||
id: this._id, | ||
opId: this._doc.generateOpId() | ||
} ], reverse, storageUpdates); | ||
} | ||
}, _proto.update = function(overrides) { | ||
var _this2 = this; | ||
if (null != this._doc && null != this._id) { | ||
var ops = [], reverseOps = [], opId = this._doc.generateOpId(), updatedProps = {}, reverseUpdateOp = { | ||
id: this._id, | ||
type: exports.OpType.UpdateObject, | ||
data: {} | ||
}, updateDelta = {}; | ||
for (var _key3 in overrides) { | ||
var _oldValue2 = this._map.get(_key3); | ||
_oldValue2 instanceof AbstractCrdt ? (reverseOps.push.apply(reverseOps, _oldValue2._serialize(this._id, _key3)), | ||
_oldValue2._detach()) : void 0 === _oldValue2 ? reverseOps.push({ | ||
type: exports.OpType.DeleteObjectKey, | ||
id: this._id, | ||
key: _key3 | ||
}) : reverseUpdateOp.data[_key3] = _oldValue2; | ||
var _newValue = overrides[_key3]; | ||
if (_newValue instanceof AbstractCrdt) { | ||
_newValue._setParentLink(this, _key3), _newValue._attach(this._doc.generateId(), this._doc); | ||
var newAttachChildOps = _newValue._serialize(this._id, _key3, this._doc), createCrdtOp = newAttachChildOps.find((function(op) { | ||
return op.parentId === _this2._id; | ||
})); | ||
createCrdtOp && this._propToLastUpdate.set(_key3, createCrdtOp.opId), ops.push.apply(ops, newAttachChildOps); | ||
} else updatedProps[_key3] = _newValue, this._propToLastUpdate.set(_key3, opId); | ||
this._map.set(_key3, _newValue), updateDelta[_key3] = { | ||
type: "update" | ||
}; | ||
reverse.push(reverseUpdate); | ||
} | ||
0 !== Object.keys(reverseUpdateOp.data).length && reverseOps.unshift(reverseUpdateOp), | ||
0 !== Object.keys(updatedProps).length && ops.unshift({ | ||
opId: opId, | ||
id: this._id, | ||
type: exports.OpType.UpdateObject, | ||
data: updatedProps | ||
}); | ||
var storageUpdates = new Map; | ||
storageUpdates.set(this._id, { | ||
node: this, | ||
type: "LiveObject", | ||
updates: updateDelta | ||
}), this._doc.dispatch(ops, reverseOps, storageUpdates); | ||
} else for (var key in overrides) { | ||
var oldValue = this._map.get(key); | ||
oldValue instanceof AbstractCrdt && oldValue._detach(); | ||
var newValue = overrides[key]; | ||
newValue instanceof AbstractCrdt && newValue._setParentLink(this, key), this._map.set(key, newValue); | ||
} | ||
}, LiveObject; | ||
}(AbstractCrdt); | ||
for (var key in op.data) { | ||
var oldValue = this._map.get(key); | ||
if (oldValue instanceof AbstractCrdt) { | ||
reverse.push.apply(reverse, oldValue._serialize(this._id, key)); | ||
oldValue._detach(); | ||
} else if (oldValue !== undefined) { | ||
reverseUpdate.data[key] = oldValue; | ||
} else if (oldValue === undefined) { | ||
reverse.push({ | ||
type: exports.OpType.DeleteObjectKey, | ||
id: this._id, | ||
key: key | ||
}); | ||
} | ||
} | ||
var updateDelta = {}; | ||
for (var _key2 in op.data) { | ||
if (isLocal) { | ||
this._propToLastUpdate.set(_key2, op.opId); | ||
} else if (this._propToLastUpdate.get(_key2) == null) { | ||
isModified = true; | ||
} else if (this._propToLastUpdate.get(_key2) === op.opId) { | ||
this._propToLastUpdate.delete(_key2); | ||
continue; | ||
} else { | ||
continue; | ||
} | ||
var _oldValue = this._map.get(_key2); | ||
if (isCrdt(_oldValue)) { | ||
_oldValue._detach(); | ||
} | ||
isModified = true; | ||
updateDelta[_key2] = { | ||
type: "update" | ||
}; | ||
this._map.set(_key2, op.data[_key2]); | ||
} | ||
if (Object.keys(reverseUpdate.data).length !== 0) { | ||
reverse.unshift(reverseUpdate); | ||
} | ||
return isModified ? { | ||
modified: { | ||
node: this, | ||
type: "LiveObject", | ||
updates: updateDelta | ||
}, | ||
reverse: reverse | ||
} : { | ||
modified: false | ||
}; | ||
exports.AbstractCrdt = AbstractCrdt, exports.LiveList = LiveList, exports.LiveMap = LiveMap, | ||
exports.LiveObject = LiveObject, exports.LiveRegister = LiveRegister, exports._createForOfIteratorHelperLoose = _createForOfIteratorHelperLoose, | ||
exports._extends = _extends, exports._inheritsLoose = _inheritsLoose, exports._objectWithoutPropertiesLoose = function(source, excluded) { | ||
if (null == source) return {}; | ||
var key, i, target = {}, sourceKeys = Object.keys(source); | ||
for (i = 0; i < sourceKeys.length; i++) key = sourceKeys[i], excluded.indexOf(key) >= 0 || (target[key] = source[key]); | ||
return target; | ||
}, exports._wrapNativeSuper = _wrapNativeSuper, exports.compact = function(items) { | ||
return items.filter((function(item) { | ||
return null != item; | ||
})); | ||
}, exports.deprecate = deprecate, exports.deprecateIf = deprecateIf, exports.errorIf = function(condition, message) { | ||
"production" !== process.env.NODE_ENV && condition && throwUsageError(message); | ||
}, exports.findNonSerializableValue = function findNonSerializableValue(value, path) { | ||
if (void 0 === path && (path = ""), !isPlain) return { | ||
path: path || "root", | ||
value: value | ||
}; | ||
if ("object" != typeof value || null === value) return !1; | ||
for (var _i = 0, _Object$entries = Object.entries(value); _i < _Object$entries.length; _i++) { | ||
var _Object$entries$_i = _Object$entries[_i], _key3 = _Object$entries$_i[0], nestedValue = _Object$entries$_i[1], nestedPath = path ? path + "." + _key3 : _key3; | ||
if (!isPlain(nestedValue)) return { | ||
path: nestedPath, | ||
value: nestedValue | ||
}; | ||
if ("object" == typeof nestedValue) { | ||
var nonSerializableNestedValue = findNonSerializableValue(nestedValue, nestedPath); | ||
if (nonSerializableNestedValue) return nonSerializableNestedValue; | ||
} | ||
} | ||
return !1; | ||
}, exports.getTreesDiffOperations = function(currentItems, newItems) { | ||
var ops = []; | ||
return currentItems.forEach((function(_, id) { | ||
newItems.get(id) || ops.push({ | ||
type: exports.OpType.DeleteCrdt, | ||
id: id | ||
}); | ||
})), newItems.forEach((function(crdt, id) { | ||
var currentCrdt = currentItems.get(id); | ||
if (currentCrdt) crdt.type === exports.CrdtType.Object && JSON.stringify(crdt.data) !== JSON.stringify(currentCrdt.data) && ops.push({ | ||
type: exports.OpType.UpdateObject, | ||
id: id, | ||
data: crdt.data | ||
}), crdt.parentKey !== currentCrdt.parentKey && ops.push({ | ||
type: exports.OpType.SetParentKey, | ||
id: id, | ||
parentKey: crdt.parentKey | ||
}); else switch (crdt.type) { | ||
case exports.CrdtType.Register: | ||
ops.push({ | ||
type: exports.OpType.CreateRegister, | ||
id: id, | ||
parentId: crdt.parentId, | ||
parentKey: crdt.parentKey, | ||
data: crdt.data | ||
}); | ||
break; | ||
_proto._applyDeleteObjectKey = function _applyDeleteObjectKey(op) { | ||
var _updates3; | ||
case exports.CrdtType.List: | ||
ops.push({ | ||
type: exports.OpType.CreateList, | ||
id: id, | ||
parentId: crdt.parentId, | ||
parentKey: crdt.parentKey | ||
}); | ||
break; | ||
var key = op.key; | ||
case exports.CrdtType.Object: | ||
ops.push({ | ||
type: exports.OpType.CreateObject, | ||
id: id, | ||
parentId: crdt.parentId, | ||
parentKey: crdt.parentKey, | ||
data: crdt.data | ||
}); | ||
break; | ||
if (this._map.has(key) === false) { | ||
return { | ||
modified: false | ||
}; | ||
} | ||
if (this._propToLastUpdate.get(key) !== undefined) { | ||
return { | ||
modified: false | ||
}; | ||
} | ||
var oldValue = this._map.get(key); | ||
var reverse = []; | ||
if (isCrdt(oldValue)) { | ||
reverse = oldValue._serialize(this._id, op.key); | ||
oldValue._detach(); | ||
} else if (oldValue !== undefined) { | ||
var _data2; | ||
reverse = [{ | ||
type: exports.OpType.UpdateObject, | ||
id: this._id, | ||
data: (_data2 = {}, _data2[key] = oldValue, _data2) | ||
}]; | ||
} | ||
this._map.delete(key); | ||
return { | ||
modified: { | ||
node: this, | ||
type: "LiveObject", | ||
updates: (_updates3 = {}, _updates3[op.key] = { | ||
type: "delete" | ||
}, _updates3) | ||
}, | ||
reverse: reverse | ||
}; | ||
}; | ||
_proto.toObject = function toObject() { | ||
return Object.fromEntries(this._map); | ||
}; | ||
_proto.set = function set(key, value) { | ||
var _this$update; | ||
this.update((_this$update = {}, _this$update[key] = value, _this$update)); | ||
}; | ||
_proto.get = function get(key) { | ||
return this._map.get(key); | ||
}; | ||
_proto.delete = function _delete(key) { | ||
var _updates4; | ||
var keyAsString = key; | ||
var oldValue = this._map.get(keyAsString); | ||
if (oldValue === undefined) { | ||
return; | ||
} | ||
if (this._doc == null || this._id == null) { | ||
if (oldValue instanceof AbstractCrdt) { | ||
oldValue._detach(); | ||
} | ||
this._map.delete(keyAsString); | ||
return; | ||
} | ||
var reverse; | ||
if (oldValue instanceof AbstractCrdt) { | ||
oldValue._detach(); | ||
reverse = oldValue._serialize(this._id, keyAsString); | ||
} else { | ||
var _data3; | ||
reverse = [{ | ||
type: exports.OpType.UpdateObject, | ||
data: (_data3 = {}, _data3[keyAsString] = oldValue, _data3), | ||
id: this._id | ||
}]; | ||
} | ||
this._map.delete(keyAsString); | ||
var storageUpdates = new Map(); | ||
storageUpdates.set(this._id, { | ||
node: this, | ||
type: "LiveObject", | ||
updates: (_updates4 = {}, _updates4[key] = { | ||
type: "delete" | ||
}, _updates4) | ||
}); | ||
this._doc.dispatch([{ | ||
type: exports.OpType.DeleteObjectKey, | ||
key: keyAsString, | ||
id: this._id, | ||
opId: this._doc.generateOpId() | ||
}], reverse, storageUpdates); | ||
}; | ||
_proto.update = function update(overrides) { | ||
var _this2 = this; | ||
if (this._doc == null || this._id == null) { | ||
for (var key in overrides) { | ||
var oldValue = this._map.get(key); | ||
if (oldValue instanceof AbstractCrdt) { | ||
oldValue._detach(); | ||
} | ||
var newValue = overrides[key]; | ||
if (newValue instanceof AbstractCrdt) { | ||
newValue._setParentLink(this, key); | ||
} | ||
this._map.set(key, newValue); | ||
} | ||
return; | ||
} | ||
var ops = []; | ||
var reverseOps = []; | ||
var opId = this._doc.generateOpId(); | ||
var updatedProps = {}; | ||
var reverseUpdateOp = { | ||
id: this._id, | ||
type: exports.OpType.UpdateObject, | ||
data: {} | ||
}; | ||
var updateDelta = {}; | ||
for (var _key3 in overrides) { | ||
var _oldValue2 = this._map.get(_key3); | ||
if (_oldValue2 instanceof AbstractCrdt) { | ||
reverseOps.push.apply(reverseOps, _oldValue2._serialize(this._id, _key3)); | ||
_oldValue2._detach(); | ||
} else if (_oldValue2 === undefined) { | ||
reverseOps.push({ | ||
type: exports.OpType.DeleteObjectKey, | ||
id: this._id, | ||
key: _key3 | ||
}); | ||
} else { | ||
reverseUpdateOp.data[_key3] = _oldValue2; | ||
} | ||
var _newValue = overrides[_key3]; | ||
if (_newValue instanceof AbstractCrdt) { | ||
_newValue._setParentLink(this, _key3); | ||
_newValue._attach(this._doc.generateId(), this._doc); | ||
var newAttachChildOps = _newValue._serialize(this._id, _key3, this._doc); | ||
var createCrdtOp = newAttachChildOps.find(function (op) { | ||
return op.parentId === _this2._id; | ||
}); | ||
if (createCrdtOp) { | ||
this._propToLastUpdate.set(_key3, createCrdtOp.opId); | ||
} | ||
ops.push.apply(ops, newAttachChildOps); | ||
} else { | ||
updatedProps[_key3] = _newValue; | ||
this._propToLastUpdate.set(_key3, opId); | ||
} | ||
this._map.set(_key3, _newValue); | ||
updateDelta[_key3] = { | ||
type: "update" | ||
}; | ||
} | ||
if (Object.keys(reverseUpdateOp.data).length !== 0) { | ||
reverseOps.unshift(reverseUpdateOp); | ||
} | ||
if (Object.keys(updatedProps).length !== 0) { | ||
ops.unshift({ | ||
opId: opId, | ||
id: this._id, | ||
type: exports.OpType.UpdateObject, | ||
data: updatedProps | ||
}); | ||
} | ||
var storageUpdates = new Map(); | ||
storageUpdates.set(this._id, { | ||
node: this, | ||
type: "LiveObject", | ||
updates: updateDelta | ||
}); | ||
this._doc.dispatch(ops, reverseOps, storageUpdates); | ||
}; | ||
return LiveObject; | ||
}(AbstractCrdt); | ||
exports.AbstractCrdt = AbstractCrdt; | ||
exports.LiveList = LiveList; | ||
exports.LiveMap = LiveMap; | ||
exports.LiveObject = LiveObject; | ||
exports.LiveRegister = LiveRegister; | ||
exports._createForOfIteratorHelperLoose = _createForOfIteratorHelperLoose; | ||
exports._extends = _extends; | ||
exports._inheritsLoose = _inheritsLoose; | ||
exports._objectWithoutPropertiesLoose = _objectWithoutPropertiesLoose; | ||
exports._wrapNativeSuper = _wrapNativeSuper; | ||
exports.compact = compact; | ||
exports.deprecate = deprecate; | ||
exports.deprecateIf = deprecateIf; | ||
exports.findNonSerializableValue = findNonSerializableValue; | ||
exports.getTreesDiffOperations = getTreesDiffOperations; | ||
exports.isJsonArray = isJsonArray; | ||
exports.isJsonObject = isJsonObject; | ||
exports.isSameNodeOrChildOf = isSameNodeOrChildOf; | ||
exports.isTokenValid = isTokenValid; | ||
exports.mergeStorageUpdates = mergeStorageUpdates; | ||
exports.parseJson = parseJson; | ||
exports.remove = remove; | ||
case exports.CrdtType.Map: | ||
ops.push({ | ||
type: exports.OpType.CreateMap, | ||
id: id, | ||
parentId: crdt.parentId, | ||
parentKey: crdt.parentKey | ||
}); | ||
} | ||
})), ops; | ||
}, exports.isJsonArray = isJsonArray, exports.isJsonObject = isJsonObject, exports.isSameNodeOrChildOf = function isSameNodeOrChildOf(node, parent) { | ||
return node === parent || !!node._parent && isSameNodeOrChildOf(node._parent, parent); | ||
}, exports.isTokenValid = function(token) { | ||
var tokenParts = token.split("."); | ||
if (3 !== tokenParts.length) return !1; | ||
var data = parseJson(atob(tokenParts[1])); | ||
return !(void 0 === data || !isJsonObject(data) || "number" != typeof data.exp) && !(Date.now() / 1e3 > data.exp - 300); | ||
}, exports.mergeStorageUpdates = function(first, second) { | ||
return first ? "LiveObject" === first.type && "LiveObject" === second.type ? function(first, second) { | ||
for (var _step, updates = first.updates, _iterator = _createForOfIteratorHelperLoose(entries(second.updates)); !(_step = _iterator()).done; ) { | ||
var _step$value = _step.value, _key = _step$value[0], value = _step$value[1]; | ||
updates[_key] = value; | ||
} | ||
return _extends({}, second, { | ||
updates: updates | ||
}); | ||
}(first, second) : "LiveMap" === first.type && "LiveMap" === second.type ? function(first, second) { | ||
for (var _step2, updates = first.updates, _iterator2 = _createForOfIteratorHelperLoose(entries(second.updates)); !(_step2 = _iterator2()).done; ) { | ||
var _step2$value = _step2.value, _key2 = _step2$value[0], value = _step2$value[1]; | ||
updates[_key2] = value; | ||
} | ||
return _extends({}, second, { | ||
updates: updates | ||
}); | ||
}(first, second) : "LiveList" === first.type && "LiveList" === second.type ? function(first, second) { | ||
return _extends({}, second, { | ||
updates: first.updates.concat(second.updates) | ||
}); | ||
}(first, second) : second : second; | ||
}, exports.parseJson = parseJson, exports.remove = function(array, item) { | ||
for (var i = 0; i < array.length; i++) if (array[i] === item) { | ||
array.splice(i, 1); | ||
break; | ||
} | ||
}, exports.throwUsageError = throwUsageError; |
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
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
220787
5525