Socket
Socket
Sign inDemoInstall

@liveblocks/client

Package Overview
Dependencies
Maintainers
2
Versions
376
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@liveblocks/client - npm Package Compare versions

Comparing version 0.6.0-beta.2 to 0.6.0-beta.3

5

lib/cjs/client.js

@@ -7,2 +7,7 @@ "use strict";

function createClient(options) {
if (typeof options.throttle === "number") {
if (options.throttle < 80 || options.throttle > 1000) {
throw new Error("Liveblocks client throttle should be between 80 and 1000 ms");
}
}
const rooms = new Map();

@@ -9,0 +14,0 @@ const _listeners = {

25

lib/cjs/live.d.ts
import { Presence } from "./types";
export declare type ServerMessage = UpdatePresenceMessage | UserJoinMessage | UserLeftMessage | EventMessage | InitialDocumentStateMessage | UpdateStorageMessage;
export declare type ServerMessage = UpdatePresenceMessage | UserJoinMessage | UserLeftMessage | EventMessage | RoomStateMessage | InitialDocumentStateMessage | UpdateStorageMessage;
export declare enum ServerMessageType {

@@ -8,9 +8,19 @@ UpdatePresence = 100,

Event = 103,
RoomState = 104,
InitialStorageState = 200,
UpdateStorage = 201
}
export declare type RoomStateMessage = {
type: ServerMessageType.RoomState;
users: {
[actor: number]: {
id?: string;
info?: any;
};
};
};
export declare type UpdatePresenceMessage = {
type: ServerMessageType.UpdatePresence;
actor: number;
data: Partial<Presence>;
data: Presence;
};

@@ -20,2 +30,4 @@ export declare type UserJoinMessage = {

actor: number;
id?: string;
info?: string;
};

@@ -52,3 +64,3 @@ export declare type UserLeftMessage = {

type: ClientMessageType.UpdatePresence;
data: Partial<Presence>;
data: Presence;
targetActor?: number;

@@ -122,3 +134,8 @@ };

CLOSE_ABNORMAL = 1006,
INVALID_MESSAGE_FORMAT = 4000
INVALID_MESSAGE_FORMAT = 4000,
NOT_ALLOWED = 4001,
MAX_NUMBER_OF_MESSAGES_PER_SECONDS = 4002,
MAX_NUMBER_OF_CONCURRENT_CONNECTIONS = 4003,
MAX_NUMBER_OF_MESSAGES_PER_DAY_PER_APP = 4004,
INTERNAL_ERROR = 4005
}

@@ -10,2 +10,3 @@ "use strict";

ServerMessageType[ServerMessageType["Event"] = 103] = "Event";
ServerMessageType[ServerMessageType["RoomState"] = 104] = "RoomState";
ServerMessageType[ServerMessageType["InitialStorageState"] = 200] = "InitialStorageState";

@@ -39,2 +40,7 @@ ServerMessageType[ServerMessageType["UpdateStorage"] = 201] = "UpdateStorage";

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["INTERNAL_ERROR"] = 4005] = "INTERNAL_ERROR";
})(WebsocketCloseCodes = exports.WebsocketCloseCodes || (exports.WebsocketCloseCodes = {}));

290

lib/cjs/room.js

@@ -61,3 +61,2 @@ "use strict";

];
const WAIT = 50;
function isValidRoomEventType(value) {

@@ -76,3 +75,3 @@ return (value === "open" ||

function makeOthers(presenceMap) {
const array = Object.entries(presenceMap).map((entry) => [parseInt(entry[0]), entry[1]]);
const array = Object.values(presenceMap);
return {

@@ -91,2 +90,3 @@ get count() {

function createRoom(name, options) {
const throttleDelay = options.throttle || 100;
const liveblocksServer = options.liveblocksServer || "wss://live.liveblocks.io";

@@ -103,24 +103,26 @@ const authEndpoint = options.authEndpoint;

let _idFactory = null;
let _socket = null;
let _doc = null;
let _storageState = types_1.LiveStorageState.NotInitialized;
let toFlush = [];
let _lastEmit = 0;
let _timeout = null;
let _initialStorageFactory = null;
let _me = null;
const _state = {
me: null,
socket: null,
lastFlushTime: 0,
flushTimeout: null,
flushData: {
presence: null,
messages: [],
storageOperations: [],
},
};
let _users = {};
let _others = makeOthers({});
let _others = makeOthers(_users);
let state = types_1.RoomState.Default;
let numberOfRetry = 0;
let retryTimeoutId = 0;
let _toSend = null;
let _presenceTimeout = null;
let _lastPresenceEmit = 0;
let onSocketOpenCallbacks = [];
function send(clientMessage) {
if (_socket == null) {
throw new Error("Can't send message if socket is not ready");
function send(messageOrMessages) {
if (_state.socket == null) {
throw new Error("Can't send message if socket is null");
}
_socket.send(JSON.stringify(clientMessage));
_state.socket.send(JSON.stringify(messageOrMessages));
}

@@ -133,5 +135,5 @@ function makeId() {

}
function updateUsers(users) {
_users = users;
_others = makeOthers(users);
function updateUsers(newUsers) {
_users = newUsers;
_others = makeOthers(newUsers);
for (const listener of _listeners["others-presence"]) {

@@ -142,25 +144,4 @@ listener(_others);

function dispatch(op) {
toFlush.push(op);
const now = Date.now();
if (now - _lastEmit > WAIT) {
send({
type: live_1.ClientMessageType.UpdateStorage,
ops: toFlush,
});
toFlush = [];
_lastEmit = now;
return;
}
if (_timeout) {
clearTimeout(_timeout);
_timeout = null;
}
_timeout = setTimeout(() => {
send({
type: live_1.ClientMessageType.UpdateStorage,
ops: toFlush,
});
toFlush = [];
_lastEmit = Date.now();
}, WAIT - (now - _lastEmit));
_state.flushData.storageOperations.push(op);
tryFlushing();
}

@@ -181,12 +162,4 @@ function getStorage() {

_storageState = types_1.LiveStorageState.Loading;
if (state === types_1.RoomState.Connected) {
send({ type: live_1.ClientMessageType.FetchStorage });
}
else {
function onConnect() {
send({ type: live_1.ClientMessageType.FetchStorage });
utils_1.remove(_listeners.open, onConnect);
}
_listeners.open.push(onConnect);
}
_state.flushData.messages.push({ type: live_1.ClientMessageType.FetchStorage });
tryFlushing();
}

@@ -207,8 +180,2 @@ function updateDoc(doc) {

}
function updateMyPresence(me) {
_me = me;
for (const listener of _listeners["my-presence"]) {
listener(_me);
}
}
function onInitialStorageState(message) {

@@ -238,5 +205,3 @@ _storageState = types_1.LiveStorageState.Loaded;

numberOfRetry = 0;
if (_me != null) {
send({ type: live_1.ClientMessageType.UpdatePresence, data: _me });
}
tryFlushing();
for (const callback of _listeners.open) {

@@ -251,2 +216,50 @@ callback();

}
function onRoomStateMessage(message) {
const newUsers = {};
for (const key in message.users) {
const connectionId = Number.parseInt(key);
const user = message.users[key];
newUsers[connectionId] = {
connectionId,
info: user.info,
id: user.id,
};
}
updateUsers(newUsers);
}
function onUpdatePresenceMessage(message) {
const user = _users[message.actor];
const newUser = user
? {
id: user.id,
info: user.info,
connectionId: message.actor,
presence: Object.assign(Object.assign({}, user.presence), message.data),
}
: {
connectionId: message.actor,
presence: message.data,
};
updateUsers(Object.assign(Object.assign({}, _users), { [message.actor]: newUser }));
}
function onUserLeftMessage(message) {
const userLeftMessage = message;
const _a = _users, _b = userLeftMessage.actor, notUsed = _a[_b], rest = __rest(_a, [typeof _b === "symbol" ? _b : _b + ""]);
updateUsers(rest);
}
function onUserJoinedMessage(message) {
updateUsers(Object.assign(Object.assign({}, _users), { [message.actor]: {
connectionId: message.actor,
info: message.info,
id: message.id,
} }));
// Send current presence to new user
// TODO: Consider storing it on the backend
_state.flushData.messages.push({
type: live_1.ClientMessageType.UpdatePresence,
data: _state.me,
targetActor: message.actor,
});
tryFlushing();
}
function onMessage(event) {

@@ -264,14 +277,7 @@ const message = JSON.parse(event.data);

case live_1.ServerMessageType.UserJoined: {
// Send current presence to new user
send({
type: live_1.ClientMessageType.UpdatePresence,
data: _me,
targetActor: message.actor,
});
onUserJoinedMessage(message);
break;
}
case live_1.ServerMessageType.UpdatePresence: {
const currentUser = _users[message.actor];
updateUsers(Object.assign(Object.assign({}, _users), { [message.actor]: currentUser
? Object.assign(Object.assign({}, currentUser), message.data) : message.data }));
onUpdatePresenceMessage(message);
break;

@@ -284,14 +290,19 @@ }

case live_1.ServerMessageType.UserLeft: {
const userLeftMessage = message;
const _a = _users, _b = userLeftMessage.actor, notUsed = _a[_b], rest = __rest(_a, [typeof _b === "symbol" ? _b : _b + ""]);
updateUsers(rest);
onUserLeftMessage(message);
break;
}
case live_1.ServerMessageType.RoomState: {
onRoomStateMessage(message);
break;
}
}
}
function onClose(event) {
if (event.code >= 4000 && event.code <= 4100) {
options.onError(new Error(event.reason));
}
for (const listener of _listeners.close) {
listener();
}
_socket = null;
_state.socket = null;
updateUsers({});

@@ -325,17 +336,17 @@ if (event.wasClean === false) {

_idFactory = makeIdFactory(actor);
_socket = new WebSocket(`${liveblocksServer}/?token=${token}`);
_socket.addEventListener("message", onMessage);
_socket.addEventListener("open", onOpen);
_socket.addEventListener("close", onClose);
_socket.addEventListener("error", onError);
_state.socket = new WebSocket(`${liveblocksServer}/?token=${token}`);
_state.socket.addEventListener("message", onMessage);
_state.socket.addEventListener("open", onOpen);
_state.socket.addEventListener("close", onClose);
_state.socket.addEventListener("error", onError);
});
}
function disconnect() {
if (_socket) {
_socket.removeEventListener("open", onOpen);
_socket.removeEventListener("message", onMessage);
_socket.removeEventListener("close", onClose);
_socket.removeEventListener("error", onError);
_socket.close();
_socket = null;
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;
}

@@ -356,3 +367,3 @@ state = types_1.RoomState.Default;

function getPresence() {
return _me;
return _state.me;
}

@@ -363,38 +374,50 @@ function getOthers() {

function updatePresence(overrides) {
updateMyPresence(Object.assign(Object.assign({}, _me), overrides));
if (state !== types_1.RoomState.Connected) {
onSocketOpenCallbacks.push(() => send({
type: live_1.ClientMessageType.UpdatePresence,
data: _me,
}));
return;
// Create new local presence right away and call listeners
const newPresence = Object.assign(Object.assign({}, _state.me), overrides);
_state.me = newPresence;
for (const listener of _listeners["my-presence"]) {
listener(_state.me);
}
updatePresenceToSend(_state, overrides);
tryFlushing();
}
function tryFlushing() {
const now = Date.now();
if (now - _lastPresenceEmit > WAIT) {
send({
type: live_1.ClientMessageType.UpdatePresence,
data: Object.assign(Object.assign({}, _toSend), overrides),
});
_toSend = {};
_lastPresenceEmit = now;
return;
if (canSend(now, _state, throttleDelay)) {
send(flushDataToMessages(_state));
_state.flushData = {
messages: [],
storageOperations: [],
presence: null,
};
_state.lastFlushTime = Date.now();
}
_toSend = Object.assign(Object.assign({}, _toSend), overrides);
if (_presenceTimeout) {
clearTimeout(_presenceTimeout);
_presenceTimeout = null;
else {
if (_state.flushTimeout) {
clearTimeout(_state.flushTimeout);
_state.flushTimeout = null;
}
_state.flushTimeout = setTimeout(() => {
if (isSocketReady(_state)) {
flushDataToMessages(_state);
send(flushDataToMessages(_state));
_state.flushData = {
messages: [],
storageOperations: [],
presence: null,
};
_state.lastFlushTime = Date.now();
}
}, throttleDelay - (now - _state.lastFlushTime));
}
_presenceTimeout = setTimeout(() => {
send({
type: live_1.ClientMessageType.UpdatePresence,
data: _toSend,
});
_toSend = {};
_lastPresenceEmit = Date.now();
}, WAIT - (now - _lastPresenceEmit));
}
function broadcastEvent(event) {
if (state === types_1.RoomState.Connected) {
send({ type: live_1.ClientMessageType.ClientEvent, event });
if (!isSocketReady(_state)) {
return;
}
_state.flushData.messages.push({
type: live_1.ClientMessageType.ClientEvent,
event,
});
tryFlushing();
}

@@ -461,1 +484,36 @@ function addEventListener(type, listener) {

exports.createRoom = createRoom;
function flushDataToMessages(state) {
const messages = [];
if (state.flushData.presence) {
messages.push({
type: live_1.ClientMessageType.UpdatePresence,
data: state.flushData.presence,
});
}
for (const event of state.flushData.messages) {
messages.push(event);
}
if (state.flushData.storageOperations.length > 0) {
messages.push({
type: live_1.ClientMessageType.UpdateStorage,
ops: state.flushData.storageOperations,
});
}
return messages;
}
function isSocketReady(state) {
return state.socket !== null && state.socket.readyState === WebSocket.OPEN;
}
function canSend(now, state, wait) {
return isSocketReady(state) && now - state.lastFlushTime > wait;
}
function updatePresenceToSend(state, overrides) {
if (state.flushData.presence == null) {
state.flushData.presence = overrides;
}
else {
for (const key in overrides) {
state.flushData.presence[key] = overrides[key];
}
}
}
import { RecordData, Record, List } from "./doc";
export declare type User<T extends Presence = Presence> = {
connectionId: number;
id?: string;
info?: any;
presence?: T;
};
/**

@@ -7,4 +13,4 @@ * Public

readonly count: number;
toArray(): Array<[connectionId: number, presence: T | undefined]>;
map<U>(callback: (entry: [connectionId: number, presence: T | undefined]) => U): Array<U>;
toArray(): Array<User<T>>;
map<U>(callback: (user: User<T>) => U): Array<U>;
}

@@ -21,2 +27,3 @@ export declare type Presence = Serializable;

liveblocksServer?: string;
throttle?: number;
};

@@ -23,0 +30,0 @@ export declare type AuthorizeResponse = {

import { createRoom } from "./room";
import { remove } from "./utils";
export function createClient(options) {
if (typeof options.throttle === "number") {
if (options.throttle < 80 || options.throttle > 1000) {
throw new Error("Liveblocks client throttle should be between 80 and 1000 ms");
}
}
const rooms = new Map();

@@ -5,0 +10,0 @@ const _listeners = {

import { Presence } from "./types";
export declare type ServerMessage = UpdatePresenceMessage | UserJoinMessage | UserLeftMessage | EventMessage | InitialDocumentStateMessage | UpdateStorageMessage;
export declare type ServerMessage = UpdatePresenceMessage | UserJoinMessage | UserLeftMessage | EventMessage | RoomStateMessage | InitialDocumentStateMessage | UpdateStorageMessage;
export declare enum ServerMessageType {

@@ -8,9 +8,19 @@ UpdatePresence = 100,

Event = 103,
RoomState = 104,
InitialStorageState = 200,
UpdateStorage = 201
}
export declare type RoomStateMessage = {
type: ServerMessageType.RoomState;
users: {
[actor: number]: {
id?: string;
info?: any;
};
};
};
export declare type UpdatePresenceMessage = {
type: ServerMessageType.UpdatePresence;
actor: number;
data: Partial<Presence>;
data: Presence;
};

@@ -20,2 +30,4 @@ export declare type UserJoinMessage = {

actor: number;
id?: string;
info?: string;
};

@@ -52,3 +64,3 @@ export declare type UserLeftMessage = {

type: ClientMessageType.UpdatePresence;
data: Partial<Presence>;
data: Presence;
targetActor?: number;

@@ -122,3 +134,8 @@ };

CLOSE_ABNORMAL = 1006,
INVALID_MESSAGE_FORMAT = 4000
INVALID_MESSAGE_FORMAT = 4000,
NOT_ALLOWED = 4001,
MAX_NUMBER_OF_MESSAGES_PER_SECONDS = 4002,
MAX_NUMBER_OF_CONCURRENT_CONNECTIONS = 4003,
MAX_NUMBER_OF_MESSAGES_PER_DAY_PER_APP = 4004,
INTERNAL_ERROR = 4005
}

@@ -7,2 +7,3 @@ export var ServerMessageType;

ServerMessageType[ServerMessageType["Event"] = 103] = "Event";
ServerMessageType[ServerMessageType["RoomState"] = 104] = "RoomState";
ServerMessageType[ServerMessageType["InitialStorageState"] = 200] = "InitialStorageState";

@@ -36,2 +37,7 @@ ServerMessageType[ServerMessageType["UpdateStorage"] = 201] = "UpdateStorage";

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["INTERNAL_ERROR"] = 4005] = "INTERNAL_ERROR";
})(WebsocketCloseCodes || (WebsocketCloseCodes = {}));

@@ -39,3 +39,2 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {

];
const WAIT = 50;
function isValidRoomEventType(value) {

@@ -54,3 +53,3 @@ return (value === "open" ||

function makeOthers(presenceMap) {
const array = Object.entries(presenceMap).map((entry) => [parseInt(entry[0]), entry[1]]);
const array = Object.values(presenceMap);
return {

@@ -69,2 +68,3 @@ get count() {

export function createRoom(name, options) {
const throttleDelay = options.throttle || 100;
const liveblocksServer = options.liveblocksServer || "wss://live.liveblocks.io";

@@ -81,24 +81,26 @@ const authEndpoint = options.authEndpoint;

let _idFactory = null;
let _socket = null;
let _doc = null;
let _storageState = LiveStorageState.NotInitialized;
let toFlush = [];
let _lastEmit = 0;
let _timeout = null;
let _initialStorageFactory = null;
let _me = null;
const _state = {
me: null,
socket: null,
lastFlushTime: 0,
flushTimeout: null,
flushData: {
presence: null,
messages: [],
storageOperations: [],
},
};
let _users = {};
let _others = makeOthers({});
let _others = makeOthers(_users);
let state = RoomState.Default;
let numberOfRetry = 0;
let retryTimeoutId = 0;
let _toSend = null;
let _presenceTimeout = null;
let _lastPresenceEmit = 0;
let onSocketOpenCallbacks = [];
function send(clientMessage) {
if (_socket == null) {
throw new Error("Can't send message if socket is not ready");
function send(messageOrMessages) {
if (_state.socket == null) {
throw new Error("Can't send message if socket is null");
}
_socket.send(JSON.stringify(clientMessage));
_state.socket.send(JSON.stringify(messageOrMessages));
}

@@ -111,5 +113,5 @@ function makeId() {

}
function updateUsers(users) {
_users = users;
_others = makeOthers(users);
function updateUsers(newUsers) {
_users = newUsers;
_others = makeOthers(newUsers);
for (const listener of _listeners["others-presence"]) {

@@ -120,25 +122,4 @@ listener(_others);

function dispatch(op) {
toFlush.push(op);
const now = Date.now();
if (now - _lastEmit > WAIT) {
send({
type: ClientMessageType.UpdateStorage,
ops: toFlush,
});
toFlush = [];
_lastEmit = now;
return;
}
if (_timeout) {
clearTimeout(_timeout);
_timeout = null;
}
_timeout = setTimeout(() => {
send({
type: ClientMessageType.UpdateStorage,
ops: toFlush,
});
toFlush = [];
_lastEmit = Date.now();
}, WAIT - (now - _lastEmit));
_state.flushData.storageOperations.push(op);
tryFlushing();
}

@@ -159,12 +140,4 @@ function getStorage() {

_storageState = LiveStorageState.Loading;
if (state === RoomState.Connected) {
send({ type: ClientMessageType.FetchStorage });
}
else {
function onConnect() {
send({ type: ClientMessageType.FetchStorage });
remove(_listeners.open, onConnect);
}
_listeners.open.push(onConnect);
}
_state.flushData.messages.push({ type: ClientMessageType.FetchStorage });
tryFlushing();
}

@@ -185,8 +158,2 @@ function updateDoc(doc) {

}
function updateMyPresence(me) {
_me = me;
for (const listener of _listeners["my-presence"]) {
listener(_me);
}
}
function onInitialStorageState(message) {

@@ -216,5 +183,3 @@ _storageState = LiveStorageState.Loaded;

numberOfRetry = 0;
if (_me != null) {
send({ type: ClientMessageType.UpdatePresence, data: _me });
}
tryFlushing();
for (const callback of _listeners.open) {

@@ -229,2 +194,50 @@ callback();

}
function onRoomStateMessage(message) {
const newUsers = {};
for (const key in message.users) {
const connectionId = Number.parseInt(key);
const user = message.users[key];
newUsers[connectionId] = {
connectionId,
info: user.info,
id: user.id,
};
}
updateUsers(newUsers);
}
function onUpdatePresenceMessage(message) {
const user = _users[message.actor];
const newUser = user
? {
id: user.id,
info: user.info,
connectionId: message.actor,
presence: Object.assign(Object.assign({}, user.presence), message.data),
}
: {
connectionId: message.actor,
presence: message.data,
};
updateUsers(Object.assign(Object.assign({}, _users), { [message.actor]: newUser }));
}
function onUserLeftMessage(message) {
const userLeftMessage = message;
const _a = _users, _b = userLeftMessage.actor, notUsed = _a[_b], rest = __rest(_a, [typeof _b === "symbol" ? _b : _b + ""]);
updateUsers(rest);
}
function onUserJoinedMessage(message) {
updateUsers(Object.assign(Object.assign({}, _users), { [message.actor]: {
connectionId: message.actor,
info: message.info,
id: message.id,
} }));
// Send current presence to new user
// TODO: Consider storing it on the backend
_state.flushData.messages.push({
type: ClientMessageType.UpdatePresence,
data: _state.me,
targetActor: message.actor,
});
tryFlushing();
}
function onMessage(event) {

@@ -242,14 +255,7 @@ const message = JSON.parse(event.data);

case ServerMessageType.UserJoined: {
// Send current presence to new user
send({
type: ClientMessageType.UpdatePresence,
data: _me,
targetActor: message.actor,
});
onUserJoinedMessage(message);
break;
}
case ServerMessageType.UpdatePresence: {
const currentUser = _users[message.actor];
updateUsers(Object.assign(Object.assign({}, _users), { [message.actor]: currentUser
? Object.assign(Object.assign({}, currentUser), message.data) : message.data }));
onUpdatePresenceMessage(message);
break;

@@ -262,14 +268,19 @@ }

case ServerMessageType.UserLeft: {
const userLeftMessage = message;
const _a = _users, _b = userLeftMessage.actor, notUsed = _a[_b], rest = __rest(_a, [typeof _b === "symbol" ? _b : _b + ""]);
updateUsers(rest);
onUserLeftMessage(message);
break;
}
case ServerMessageType.RoomState: {
onRoomStateMessage(message);
break;
}
}
}
function onClose(event) {
if (event.code >= 4000 && event.code <= 4100) {
options.onError(new Error(event.reason));
}
for (const listener of _listeners.close) {
listener();
}
_socket = null;
_state.socket = null;
updateUsers({});

@@ -303,17 +314,17 @@ if (event.wasClean === false) {

_idFactory = makeIdFactory(actor);
_socket = new WebSocket(`${liveblocksServer}/?token=${token}`);
_socket.addEventListener("message", onMessage);
_socket.addEventListener("open", onOpen);
_socket.addEventListener("close", onClose);
_socket.addEventListener("error", onError);
_state.socket = new WebSocket(`${liveblocksServer}/?token=${token}`);
_state.socket.addEventListener("message", onMessage);
_state.socket.addEventListener("open", onOpen);
_state.socket.addEventListener("close", onClose);
_state.socket.addEventListener("error", onError);
});
}
function disconnect() {
if (_socket) {
_socket.removeEventListener("open", onOpen);
_socket.removeEventListener("message", onMessage);
_socket.removeEventListener("close", onClose);
_socket.removeEventListener("error", onError);
_socket.close();
_socket = null;
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;
}

@@ -334,3 +345,3 @@ state = RoomState.Default;

function getPresence() {
return _me;
return _state.me;
}

@@ -341,38 +352,50 @@ function getOthers() {

function updatePresence(overrides) {
updateMyPresence(Object.assign(Object.assign({}, _me), overrides));
if (state !== RoomState.Connected) {
onSocketOpenCallbacks.push(() => send({
type: ClientMessageType.UpdatePresence,
data: _me,
}));
return;
// Create new local presence right away and call listeners
const newPresence = Object.assign(Object.assign({}, _state.me), overrides);
_state.me = newPresence;
for (const listener of _listeners["my-presence"]) {
listener(_state.me);
}
updatePresenceToSend(_state, overrides);
tryFlushing();
}
function tryFlushing() {
const now = Date.now();
if (now - _lastPresenceEmit > WAIT) {
send({
type: ClientMessageType.UpdatePresence,
data: Object.assign(Object.assign({}, _toSend), overrides),
});
_toSend = {};
_lastPresenceEmit = now;
return;
if (canSend(now, _state, throttleDelay)) {
send(flushDataToMessages(_state));
_state.flushData = {
messages: [],
storageOperations: [],
presence: null,
};
_state.lastFlushTime = Date.now();
}
_toSend = Object.assign(Object.assign({}, _toSend), overrides);
if (_presenceTimeout) {
clearTimeout(_presenceTimeout);
_presenceTimeout = null;
else {
if (_state.flushTimeout) {
clearTimeout(_state.flushTimeout);
_state.flushTimeout = null;
}
_state.flushTimeout = setTimeout(() => {
if (isSocketReady(_state)) {
flushDataToMessages(_state);
send(flushDataToMessages(_state));
_state.flushData = {
messages: [],
storageOperations: [],
presence: null,
};
_state.lastFlushTime = Date.now();
}
}, throttleDelay - (now - _state.lastFlushTime));
}
_presenceTimeout = setTimeout(() => {
send({
type: ClientMessageType.UpdatePresence,
data: _toSend,
});
_toSend = {};
_lastPresenceEmit = Date.now();
}, WAIT - (now - _lastPresenceEmit));
}
function broadcastEvent(event) {
if (state === RoomState.Connected) {
send({ type: ClientMessageType.ClientEvent, event });
if (!isSocketReady(_state)) {
return;
}
_state.flushData.messages.push({
type: ClientMessageType.ClientEvent,
event,
});
tryFlushing();
}

@@ -438,1 +461,36 @@ function addEventListener(type, listener) {

}
function flushDataToMessages(state) {
const messages = [];
if (state.flushData.presence) {
messages.push({
type: ClientMessageType.UpdatePresence,
data: state.flushData.presence,
});
}
for (const event of state.flushData.messages) {
messages.push(event);
}
if (state.flushData.storageOperations.length > 0) {
messages.push({
type: ClientMessageType.UpdateStorage,
ops: state.flushData.storageOperations,
});
}
return messages;
}
function isSocketReady(state) {
return state.socket !== null && state.socket.readyState === WebSocket.OPEN;
}
function canSend(now, state, wait) {
return isSocketReady(state) && now - state.lastFlushTime > wait;
}
function updatePresenceToSend(state, overrides) {
if (state.flushData.presence == null) {
state.flushData.presence = overrides;
}
else {
for (const key in overrides) {
state.flushData.presence[key] = overrides[key];
}
}
}
import { RecordData, Record, List } from "./doc";
export declare type User<T extends Presence = Presence> = {
connectionId: number;
id?: string;
info?: any;
presence?: T;
};
/**

@@ -7,4 +13,4 @@ * Public

readonly count: number;
toArray(): Array<[connectionId: number, presence: T | undefined]>;
map<U>(callback: (entry: [connectionId: number, presence: T | undefined]) => U): Array<U>;
toArray(): Array<User<T>>;
map<U>(callback: (user: User<T>) => U): Array<U>;
}

@@ -21,2 +27,3 @@ export declare type Presence = Serializable;

liveblocksServer?: string;
throttle?: number;
};

@@ -23,0 +30,0 @@ export declare type AuthorizeResponse = {

{
"name": "@liveblocks/client",
"version": "0.6.0-beta.2",
"version": "0.6.0-beta.3",
"description": "",

@@ -5,0 +5,0 @@ "main": "./lib/cjs/index.js",

SocketSocket SOC 2 Logo

Product

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

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc