@liveblocks/client
Advanced tools
Comparing version 0.6.0-beta.4 to 0.7.0
@@ -5,3 +5,2 @@ "use strict"; | ||
const room_1 = require("./room"); | ||
const utils_1 = require("./utils"); | ||
function createClient(options) { | ||
@@ -14,33 +13,22 @@ if (typeof options.throttle === "number") { | ||
const rooms = new Map(); | ||
const _listeners = { | ||
error: [], | ||
}; | ||
function onError(error) { | ||
for (const listener of _listeners.error) { | ||
listener(error); | ||
} | ||
function getRoom(roomId) { | ||
return rooms.get(roomId) || null; | ||
} | ||
function getRoomOrInit(name) { | ||
let room = rooms.get(name); | ||
if (room == null) { | ||
room = room_1.createRoom(name, Object.assign(Object.assign({}, options), { onError })); | ||
rooms.set(name, room); | ||
function enter(roomId, initialPresence) { | ||
let room = rooms.get(roomId); | ||
if (room) { | ||
return room; | ||
} | ||
room = room_1.createRoom(roomId, Object.assign(Object.assign({}, options), { initialPresence })); | ||
rooms.set(roomId, room); | ||
room.connect(); | ||
return room; | ||
} | ||
function getRoom(room) { | ||
return getRoomOrInit(room); | ||
} | ||
function addEventListener(type, listener) { | ||
if (type !== "error") { | ||
throw new Error(`"${type}" is not a valid event name`); | ||
function leave(roomId) { | ||
let room = rooms.get(roomId); | ||
if (room) { | ||
room.disconnect(); | ||
rooms.delete(roomId); | ||
} | ||
_listeners.error.push(listener); | ||
} | ||
function removeEventListener(type, listener) { | ||
if (type !== "error") { | ||
throw new Error(`"${type}" is not a valid event name`); | ||
} | ||
utils_1.remove(_listeners.error, listener); | ||
} | ||
if (typeof window !== "undefined") { | ||
@@ -62,7 +50,7 @@ // TODO: Expose a way to clear these | ||
return { | ||
addEventListener, | ||
removeEventListener, | ||
getRoom, | ||
enter, | ||
leave, | ||
}; | ||
} | ||
exports.createClient = createClient; |
@@ -135,3 +135,4 @@ import { Presence } from "./types"; | ||
MAX_NUMBER_OF_CONCURRENT_CONNECTIONS = 4003, | ||
MAX_NUMBER_OF_MESSAGES_PER_DAY_PER_APP = 4004 | ||
MAX_NUMBER_OF_MESSAGES_PER_DAY_PER_APP = 4004, | ||
MAX_NUMBER_OF_CONCURRENT_CONNECTIONS_PER_ROOM = 4005 | ||
} |
@@ -43,2 +43,3 @@ "use strict"; | ||
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 = exports.WebsocketCloseCodes || (exports.WebsocketCloseCodes = {})); |
import { RecordData, List } from "."; | ||
import { Doc, Record } from "./doc"; | ||
import { Others, Presence, ClientOptions, Room, InitialStorageFactory, MyPresenceEventCallback, OthersPresenceEventCallback, StorageEventCallback, AuthEndpoint, LiveStorageState, LiveStorage, EventEventCallback, User, Connection, Serializable } from "./types"; | ||
import { Others, Presence, ClientOptions, Room, InitialStorageFactory, MyPresenceCallback, OthersEventCallback, StorageCallback, AuthEndpoint, LiveStorageState, LiveStorage, EventCallback, User, Connection, Serializable, ErrorCallback } from "./types"; | ||
import { ClientMessage, Op } from "./live"; | ||
@@ -24,8 +24,9 @@ declare type IdFactory = () => string; | ||
listeners: { | ||
storage: StorageEventCallback[]; | ||
event: EventEventCallback[]; | ||
"others-presence": OthersPresenceEventCallback[]; | ||
"my-presence": MyPresenceEventCallback[]; | ||
storage: StorageCallback[]; | ||
event: EventCallback[]; | ||
others: OthersEventCallback[]; | ||
"my-presence": MyPresenceCallback[]; | ||
error: ErrorCallback[]; | ||
}; | ||
me: Presence | null; | ||
me: Presence; | ||
others: Others; | ||
@@ -54,3 +55,2 @@ users: { | ||
throttleDelay: number; | ||
onError: (error: Error) => void; | ||
}; | ||
@@ -71,13 +71,15 @@ export declare function makeStateMachine(state: State, context: Context, mockedEffects?: Effects): { | ||
disconnect: () => void; | ||
addEventListener: { | ||
<T extends Serializable>(type: "my-presence", listener: MyPresenceEventCallback<T>): void; | ||
<T_1 extends Serializable>(type: "others-presence", listener: OthersPresenceEventCallback<T_1>): void; | ||
(type: "event", listener: EventEventCallback): void; | ||
<T_2 extends RecordData>(type: "storage", listener: StorageEventCallback<T_2>): void; | ||
subscribe: { | ||
<T extends Serializable>(type: "my-presence", listener: MyPresenceCallback<T>): void; | ||
<T_1 extends Serializable>(type: "others", listener: OthersEventCallback<T_1>): void; | ||
(type: "event", listener: EventCallback): void; | ||
<T_2 extends RecordData>(type: "storage", listener: StorageCallback<T_2>): void; | ||
(type: "error", listener: ErrorCallback): void; | ||
}; | ||
removeEventListener: { | ||
<T_3 extends Serializable>(type: "my-presence", listener: MyPresenceEventCallback<T_3>): void; | ||
<T_4 extends Serializable>(type: "others-presence", listener: OthersPresenceEventCallback<T_4>): void; | ||
(type: "event", listener: EventEventCallback): void; | ||
<T_5 extends RecordData>(type: "storage", listener: StorageEventCallback<T_5>): void; | ||
unsubscribe: { | ||
<T_3 extends Serializable>(type: "my-presence", listener: MyPresenceCallback<T_3>): void; | ||
<T_4 extends Serializable>(type: "others", listener: OthersEventCallback<T_4>): void; | ||
(type: "event", listener: EventCallback): void; | ||
<T_5 extends RecordData>(type: "storage", listener: StorageCallback<T_5>): void; | ||
(type: "error", listener: ErrorCallback): void; | ||
}; | ||
@@ -94,5 +96,4 @@ updatePresence: <T_6 extends Serializable>(overrides: Partial<T_6>) => void; | ||
selectors: { | ||
getListenersCount: () => number; | ||
getConnectionState: () => Connection; | ||
getPresence: <T_13 extends Serializable>() => T_13 | null; | ||
getPresence: <T_13 extends Serializable>() => T_13; | ||
getOthers: <T_14 extends Serializable>() => Others<T_14>; | ||
@@ -102,6 +103,6 @@ getStorage: () => LiveStorage; | ||
}; | ||
export declare function defaultState(): State; | ||
export declare function defaultState(me?: Presence): State; | ||
export declare function createRoom(name: string, options: ClientOptions & { | ||
onError: (error: Error) => void; | ||
initialPresence?: Presence; | ||
}): Room; | ||
export {}; |
@@ -30,13 +30,2 @@ "use strict"; | ||
}; | ||
var __rest = (this && this.__rest) || function (s, e) { | ||
var t = {}; | ||
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0) | ||
t[p] = s[p]; | ||
if (s != null && typeof Object.getOwnPropertySymbols === "function") | ||
for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) { | ||
if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i])) | ||
t[p[i]] = s[p[i]]; | ||
} | ||
return t; | ||
}; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
@@ -57,4 +46,5 @@ exports.createRoom = exports.defaultState = exports.makeStateMachine = void 0; | ||
value === "my-presence" || | ||
value === "others-presence" || | ||
value === "event"); | ||
value === "others" || | ||
value === "event" || | ||
value === "error"); | ||
} | ||
@@ -121,3 +111,3 @@ function makeIdFactory(connectionId) { | ||
}; | ||
function addEventListener(type, listener) { | ||
function subscribe(type, listener) { | ||
if (!isValidRoomEventType(type)) { | ||
@@ -128,3 +118,3 @@ throw new Error(`"${type}" is not a valid event name`); | ||
} | ||
function removeEventListener(event, callback) { | ||
function unsubscribe(event, callback) { | ||
if (!isValidRoomEventType(event)) { | ||
@@ -139,9 +129,6 @@ throw new Error(`"${event}" is not a valid event name`); | ||
} | ||
function getListenersCount() { | ||
return (state.listeners["my-presence"].length + | ||
state.listeners["others-presence"].length + | ||
state.listeners.storage.length + | ||
state.listeners.event.length); | ||
} | ||
function connect() { | ||
if (typeof window === "undefined") { | ||
return; | ||
} | ||
if (state.connection.state !== "closed" && | ||
@@ -189,4 +176,10 @@ state.connection.state !== "unavailable") { | ||
const user = state.users[message.actor]; | ||
const newUser = user | ||
? { | ||
if (user == null) { | ||
state.users[message.actor] = { | ||
connectionId: message.actor, | ||
presence: message.data, | ||
}; | ||
} | ||
else { | ||
state.users[message.actor] = { | ||
id: user.id, | ||
@@ -196,13 +189,9 @@ info: user.info, | ||
presence: Object.assign(Object.assign({}, user.presence), message.data), | ||
} | ||
: { | ||
connectionId: message.actor, | ||
presence: message.data, | ||
}; | ||
updateUsers(Object.assign(Object.assign({}, state.users), { [message.actor]: newUser })); | ||
} | ||
updateUsers(); | ||
} | ||
function updateUsers(newUsers) { | ||
state.users = newUsers; | ||
state.others = makeOthers(newUsers); | ||
for (const listener of state.listeners["others-presence"]) { | ||
function updateUsers() { | ||
state.others = makeOthers(state.users); | ||
for (const listener of state.listeners["others"]) { | ||
listener(state.others); | ||
@@ -213,4 +202,4 @@ } | ||
const userLeftMessage = message; | ||
const _a = state.users, _b = userLeftMessage.actor, notUsed = _a[_b], rest = __rest(_a, [typeof _b === "symbol" ? _b : _b + ""]); | ||
updateUsers(rest); | ||
delete state.users[userLeftMessage.actor]; | ||
updateUsers(); | ||
} | ||
@@ -228,3 +217,4 @@ function onRoomStateMessage(message) { | ||
} | ||
updateUsers(newUsers); | ||
state.users = newUsers; | ||
updateUsers(); | ||
} | ||
@@ -243,7 +233,8 @@ function onNavigatorOnline() { | ||
function onUserJoinedMessage(message) { | ||
updateUsers(Object.assign(Object.assign({}, state.users), { [message.actor]: { | ||
connectionId: message.actor, | ||
info: message.info, | ||
id: message.id, | ||
} })); | ||
state.users[message.actor] = { | ||
connectionId: message.actor, | ||
info: message.info, | ||
id: message.id, | ||
}; | ||
updateUsers(); | ||
if (state.me) { | ||
@@ -314,6 +305,10 @@ // Send current presence to new user | ||
clearTimeout(state.timeoutHandles.reconnect); | ||
updateUsers({}); | ||
state.users = {}; | ||
updateUsers(); | ||
if (event.code >= 4000 && event.code <= 4100) { | ||
updateConnection({ state: "failed" }); | ||
context.onError(new Error(event.reason)); | ||
const error = new LiveblocksError(event.reason, event.code); | ||
for (const listener of state.listeners.error) { | ||
listener(error); | ||
} | ||
} | ||
@@ -436,3 +431,2 @@ else if (event.wasClean === false) { | ||
updateConnection({ state: "closed" }); | ||
state.me = null; | ||
if (state.timeoutHandles.flush) { | ||
@@ -444,8 +438,11 @@ clearTimeout(state.timeoutHandles.flush); | ||
clearInterval(state.intervalHandles.heartbeat); | ||
updateUsers({}); | ||
state.listeners["my-presence"] = []; | ||
state.listeners["others-presence"] = []; | ||
state.listeners.event = []; | ||
state.listeners.storage = []; | ||
state.users = {}; | ||
updateUsers(); | ||
clearListeners(); | ||
} | ||
function clearListeners() { | ||
for (const key in state.listeners) { | ||
state.listeners[key] = []; | ||
} | ||
} | ||
function getPresence() { | ||
@@ -557,4 +554,4 @@ return state.me; | ||
disconnect, | ||
addEventListener, | ||
removeEventListener, | ||
subscribe, | ||
unsubscribe, | ||
// Presence | ||
@@ -573,3 +570,2 @@ updatePresence, | ||
// Core | ||
getListenersCount, | ||
getConnectionState, | ||
@@ -585,3 +581,3 @@ // Presence | ||
exports.makeStateMachine = makeStateMachine; | ||
function defaultState() { | ||
function defaultState(me) { | ||
return { | ||
@@ -593,4 +589,5 @@ connection: { state: "closed" }, | ||
event: [], | ||
"others-presence": [], | ||
others: [], | ||
"my-presence": [], | ||
error: [], | ||
}, | ||
@@ -612,3 +609,3 @@ numberOfRetry: 0, | ||
}, | ||
me: null, | ||
me: me == null ? {} : me, | ||
users: {}, | ||
@@ -627,3 +624,3 @@ others: makeOthers({}), | ||
const authEndpoint = options.authEndpoint; | ||
const state = defaultState(); | ||
const state = defaultState(options.initialPresence); | ||
const machine = makeStateMachine(state, { | ||
@@ -633,3 +630,2 @@ throttleDelay, | ||
authEndpoint, | ||
onError: options.onError, | ||
room: name, | ||
@@ -644,5 +640,4 @@ }); | ||
getConnectionState: machine.selectors.getConnectionState, | ||
getListenersCount: machine.selectors.getListenersCount, | ||
addEventListener: machine.addEventListener, | ||
removeEventListener: machine.removeEventListener, | ||
subscribe: machine.subscribe, | ||
unsubscribe: machine.unsubscribe, | ||
///////////// | ||
@@ -672,1 +667,7 @@ // Storage // | ||
exports.createRoom = createRoom; | ||
class LiveblocksError extends Error { | ||
constructor(message, code) { | ||
super(message); | ||
this.code = code; | ||
} | ||
} |
import { RecordData, Record, List } from "./doc"; | ||
/** | ||
* Represents all the other users conencted in the room. Treated as immutable. | ||
* Represents all the other users connected in the room. Treated as immutable. | ||
*/ | ||
@@ -80,15 +80,20 @@ export interface Others<TPresence extends Presence = Presence> { | ||
getConnectionState(): Connection; | ||
getListenersCount(): number; | ||
addEventListener: { | ||
<T extends Presence>(type: "my-presence", listener: MyPresenceEventCallback<T>): void; | ||
<T extends Presence>(type: "others-presence", listener: OthersPresenceEventCallback<T>): void; | ||
(type: "event", listener: EventEventCallback): void; | ||
<T extends RecordData>(type: "storage", listener: StorageEventCallback<T>): void; | ||
subscribe: { | ||
<T extends Presence>(type: "my-presence", listener: MyPresenceCallback<T>): void; | ||
<T extends Presence>(type: "others", listener: OthersEventCallback<T>): void; | ||
(type: "event", listener: EventCallback): void; | ||
<T extends RecordData>(type: "storage", listener: StorageCallback<T>): void; | ||
(type: "error", listener: (error: Error) => void): void; | ||
}; | ||
removeEventListener: { | ||
<T extends Presence>(type: "my-presence", listener: MyPresenceEventCallback<T>): void; | ||
<T extends Presence>(type: "others-presence", listener: OthersPresenceEventCallback<T>): void; | ||
(type: "event", listener: EventEventCallback): void; | ||
<T extends RecordData>(type: "storage", listener: StorageEventCallback<T>): void; | ||
unsubscribe: { | ||
<T extends Presence>(type: "my-presence", listener: MyPresenceCallback<T>): void; | ||
<T extends Presence>(type: "others", listener: OthersEventCallback<T>): void; | ||
(type: "event", listener: EventCallback): void; | ||
<T extends RecordData>(type: "storage", listener: StorageCallback<T>): void; | ||
(type: "error", listener: (error: Error) => void): void; | ||
}; | ||
getPresence: <T extends Presence>() => T; | ||
getOthers: <T extends Presence>() => Others<T>; | ||
updatePresence: <T extends Presence>(overrides: Partial<T>) => void; | ||
broadcastEvent: (event: any) => void; | ||
getStorage: () => LiveStorage; | ||
@@ -102,14 +107,18 @@ fetchStorage(initialStorageFactory: InitialStorageFactory): void; | ||
moveItem<T extends RecordData>(list: List<Record<T>>, index: number, targetIndex: number): void; | ||
getPresence: <T extends Presence>() => T | null; | ||
getOthers: <T extends Presence>() => Others<T>; | ||
updatePresence: <T extends Presence>(overrides: Partial<T>) => void; | ||
broadcastEvent: (event: any) => void; | ||
}; | ||
export declare type StorageEventCallback<T extends RecordData = RecordData> = (storage: LiveStorage<T>) => void; | ||
export declare type MyPresenceEventCallback<T extends Presence = Presence> = (me: T) => void; | ||
export declare type OthersPresenceEventCallback<T extends Presence = Presence> = (others: Others<T>) => void; | ||
export declare type EventEventCallback = ({ connectionId, event, }: { | ||
export declare type StorageCallback<T extends RecordData = RecordData> = (storage: LiveStorage<T>) => void; | ||
export declare type MyPresenceCallback<T extends Presence = Presence> = (me: T) => void; | ||
export declare type OthersEventCallback<T extends Presence = Presence> = (others: Others<T>) => void; | ||
export declare type EventCallback = ({ connectionId, event, }: { | ||
connectionId: number; | ||
event: any; | ||
}) => void; | ||
export declare type ErrorCallback = (error: Error) => void; | ||
export declare type RoomEventCallbackMap = { | ||
storage: StorageCallback; | ||
"my-presence": MyPresenceCallback; | ||
others: OthersEventCallback; | ||
event: EventCallback; | ||
error: ErrorCallback; | ||
}; | ||
export declare type CreateRecord = Room["createRecord"]; | ||
@@ -121,16 +130,7 @@ export declare type CreateList = Room["createList"]; | ||
}) => TRoot; | ||
export declare type RoomEventCallbackMap = { | ||
storage: StorageEventCallback; | ||
"my-presence": MyPresenceEventCallback; | ||
"others-presence": OthersPresenceEventCallback; | ||
}; | ||
declare type ClientErrorCallback = (error: Error) => void; | ||
declare type ClientEventCallbackMap = { | ||
error: ClientErrorCallback; | ||
}; | ||
export declare type Client = { | ||
addEventListener: <T extends "error">(type: T, listener: ClientEventCallbackMap[T]) => void; | ||
removeEventListener: <T extends "error">(type: T, listener: ClientEventCallbackMap[T]) => void; | ||
getRoom: (room: string) => Room; | ||
getRoom(roomId: string): Room | null; | ||
enter(roomId: string, defaultPresence?: Presence): Room; | ||
leave(roomId: string): void; | ||
}; | ||
export {}; |
import { createRoom } from "./room"; | ||
import { remove } from "./utils"; | ||
export function createClient(options) { | ||
@@ -10,33 +9,22 @@ if (typeof options.throttle === "number") { | ||
const rooms = new Map(); | ||
const _listeners = { | ||
error: [], | ||
}; | ||
function onError(error) { | ||
for (const listener of _listeners.error) { | ||
listener(error); | ||
} | ||
function getRoom(roomId) { | ||
return rooms.get(roomId) || null; | ||
} | ||
function getRoomOrInit(name) { | ||
let room = rooms.get(name); | ||
if (room == null) { | ||
room = createRoom(name, Object.assign(Object.assign({}, options), { onError })); | ||
rooms.set(name, room); | ||
function enter(roomId, initialPresence) { | ||
let room = rooms.get(roomId); | ||
if (room) { | ||
return room; | ||
} | ||
room = createRoom(roomId, Object.assign(Object.assign({}, options), { initialPresence })); | ||
rooms.set(roomId, room); | ||
room.connect(); | ||
return room; | ||
} | ||
function getRoom(room) { | ||
return getRoomOrInit(room); | ||
} | ||
function addEventListener(type, listener) { | ||
if (type !== "error") { | ||
throw new Error(`"${type}" is not a valid event name`); | ||
function leave(roomId) { | ||
let room = rooms.get(roomId); | ||
if (room) { | ||
room.disconnect(); | ||
rooms.delete(roomId); | ||
} | ||
_listeners.error.push(listener); | ||
} | ||
function removeEventListener(type, listener) { | ||
if (type !== "error") { | ||
throw new Error(`"${type}" is not a valid event name`); | ||
} | ||
remove(_listeners.error, listener); | ||
} | ||
if (typeof window !== "undefined") { | ||
@@ -58,6 +46,6 @@ // TODO: Expose a way to clear these | ||
return { | ||
addEventListener, | ||
removeEventListener, | ||
getRoom, | ||
enter, | ||
leave, | ||
}; | ||
} |
@@ -135,3 +135,4 @@ import { Presence } from "./types"; | ||
MAX_NUMBER_OF_CONCURRENT_CONNECTIONS = 4003, | ||
MAX_NUMBER_OF_MESSAGES_PER_DAY_PER_APP = 4004 | ||
MAX_NUMBER_OF_MESSAGES_PER_DAY_PER_APP = 4004, | ||
MAX_NUMBER_OF_CONCURRENT_CONNECTIONS_PER_ROOM = 4005 | ||
} |
@@ -40,2 +40,3 @@ export var ServerMessageType; | ||
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 = {})); |
import { RecordData, List } from "."; | ||
import { Doc, Record } from "./doc"; | ||
import { Others, Presence, ClientOptions, Room, InitialStorageFactory, MyPresenceEventCallback, OthersPresenceEventCallback, StorageEventCallback, AuthEndpoint, LiveStorageState, LiveStorage, EventEventCallback, User, Connection, Serializable } from "./types"; | ||
import { Others, Presence, ClientOptions, Room, InitialStorageFactory, MyPresenceCallback, OthersEventCallback, StorageCallback, AuthEndpoint, LiveStorageState, LiveStorage, EventCallback, User, Connection, Serializable, ErrorCallback } from "./types"; | ||
import { ClientMessage, Op } from "./live"; | ||
@@ -24,8 +24,9 @@ declare type IdFactory = () => string; | ||
listeners: { | ||
storage: StorageEventCallback[]; | ||
event: EventEventCallback[]; | ||
"others-presence": OthersPresenceEventCallback[]; | ||
"my-presence": MyPresenceEventCallback[]; | ||
storage: StorageCallback[]; | ||
event: EventCallback[]; | ||
others: OthersEventCallback[]; | ||
"my-presence": MyPresenceCallback[]; | ||
error: ErrorCallback[]; | ||
}; | ||
me: Presence | null; | ||
me: Presence; | ||
others: Others; | ||
@@ -54,3 +55,2 @@ users: { | ||
throttleDelay: number; | ||
onError: (error: Error) => void; | ||
}; | ||
@@ -71,13 +71,15 @@ export declare function makeStateMachine(state: State, context: Context, mockedEffects?: Effects): { | ||
disconnect: () => void; | ||
addEventListener: { | ||
<T extends Serializable>(type: "my-presence", listener: MyPresenceEventCallback<T>): void; | ||
<T_1 extends Serializable>(type: "others-presence", listener: OthersPresenceEventCallback<T_1>): void; | ||
(type: "event", listener: EventEventCallback): void; | ||
<T_2 extends RecordData>(type: "storage", listener: StorageEventCallback<T_2>): void; | ||
subscribe: { | ||
<T extends Serializable>(type: "my-presence", listener: MyPresenceCallback<T>): void; | ||
<T_1 extends Serializable>(type: "others", listener: OthersEventCallback<T_1>): void; | ||
(type: "event", listener: EventCallback): void; | ||
<T_2 extends RecordData>(type: "storage", listener: StorageCallback<T_2>): void; | ||
(type: "error", listener: ErrorCallback): void; | ||
}; | ||
removeEventListener: { | ||
<T_3 extends Serializable>(type: "my-presence", listener: MyPresenceEventCallback<T_3>): void; | ||
<T_4 extends Serializable>(type: "others-presence", listener: OthersPresenceEventCallback<T_4>): void; | ||
(type: "event", listener: EventEventCallback): void; | ||
<T_5 extends RecordData>(type: "storage", listener: StorageEventCallback<T_5>): void; | ||
unsubscribe: { | ||
<T_3 extends Serializable>(type: "my-presence", listener: MyPresenceCallback<T_3>): void; | ||
<T_4 extends Serializable>(type: "others", listener: OthersEventCallback<T_4>): void; | ||
(type: "event", listener: EventCallback): void; | ||
<T_5 extends RecordData>(type: "storage", listener: StorageCallback<T_5>): void; | ||
(type: "error", listener: ErrorCallback): void; | ||
}; | ||
@@ -94,5 +96,4 @@ updatePresence: <T_6 extends Serializable>(overrides: Partial<T_6>) => void; | ||
selectors: { | ||
getListenersCount: () => number; | ||
getConnectionState: () => Connection; | ||
getPresence: <T_13 extends Serializable>() => T_13 | null; | ||
getPresence: <T_13 extends Serializable>() => T_13; | ||
getOthers: <T_14 extends Serializable>() => Others<T_14>; | ||
@@ -102,6 +103,6 @@ getStorage: () => LiveStorage; | ||
}; | ||
export declare function defaultState(): State; | ||
export declare function defaultState(me?: Presence): State; | ||
export declare function createRoom(name: string, options: ClientOptions & { | ||
onError: (error: Error) => void; | ||
initialPresence?: Presence; | ||
}): Room; | ||
export {}; |
@@ -10,13 +10,2 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { | ||
}; | ||
var __rest = (this && this.__rest) || function (s, e) { | ||
var t = {}; | ||
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0) | ||
t[p] = s[p]; | ||
if (s != null && typeof Object.getOwnPropertySymbols === "function") | ||
for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) { | ||
if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i])) | ||
t[p[i]] = s[p[i]]; | ||
} | ||
return t; | ||
}; | ||
import { Doc } from "./doc"; | ||
@@ -35,4 +24,5 @@ import { LiveStorageState, } from "./types"; | ||
value === "my-presence" || | ||
value === "others-presence" || | ||
value === "event"); | ||
value === "others" || | ||
value === "event" || | ||
value === "error"); | ||
} | ||
@@ -99,3 +89,3 @@ function makeIdFactory(connectionId) { | ||
}; | ||
function addEventListener(type, listener) { | ||
function subscribe(type, listener) { | ||
if (!isValidRoomEventType(type)) { | ||
@@ -106,3 +96,3 @@ throw new Error(`"${type}" is not a valid event name`); | ||
} | ||
function removeEventListener(event, callback) { | ||
function unsubscribe(event, callback) { | ||
if (!isValidRoomEventType(event)) { | ||
@@ -117,9 +107,6 @@ throw new Error(`"${event}" is not a valid event name`); | ||
} | ||
function getListenersCount() { | ||
return (state.listeners["my-presence"].length + | ||
state.listeners["others-presence"].length + | ||
state.listeners.storage.length + | ||
state.listeners.event.length); | ||
} | ||
function connect() { | ||
if (typeof window === "undefined") { | ||
return; | ||
} | ||
if (state.connection.state !== "closed" && | ||
@@ -167,4 +154,10 @@ state.connection.state !== "unavailable") { | ||
const user = state.users[message.actor]; | ||
const newUser = user | ||
? { | ||
if (user == null) { | ||
state.users[message.actor] = { | ||
connectionId: message.actor, | ||
presence: message.data, | ||
}; | ||
} | ||
else { | ||
state.users[message.actor] = { | ||
id: user.id, | ||
@@ -174,13 +167,9 @@ info: user.info, | ||
presence: Object.assign(Object.assign({}, user.presence), message.data), | ||
} | ||
: { | ||
connectionId: message.actor, | ||
presence: message.data, | ||
}; | ||
updateUsers(Object.assign(Object.assign({}, state.users), { [message.actor]: newUser })); | ||
} | ||
updateUsers(); | ||
} | ||
function updateUsers(newUsers) { | ||
state.users = newUsers; | ||
state.others = makeOthers(newUsers); | ||
for (const listener of state.listeners["others-presence"]) { | ||
function updateUsers() { | ||
state.others = makeOthers(state.users); | ||
for (const listener of state.listeners["others"]) { | ||
listener(state.others); | ||
@@ -191,4 +180,4 @@ } | ||
const userLeftMessage = message; | ||
const _a = state.users, _b = userLeftMessage.actor, notUsed = _a[_b], rest = __rest(_a, [typeof _b === "symbol" ? _b : _b + ""]); | ||
updateUsers(rest); | ||
delete state.users[userLeftMessage.actor]; | ||
updateUsers(); | ||
} | ||
@@ -206,3 +195,4 @@ function onRoomStateMessage(message) { | ||
} | ||
updateUsers(newUsers); | ||
state.users = newUsers; | ||
updateUsers(); | ||
} | ||
@@ -221,7 +211,8 @@ function onNavigatorOnline() { | ||
function onUserJoinedMessage(message) { | ||
updateUsers(Object.assign(Object.assign({}, state.users), { [message.actor]: { | ||
connectionId: message.actor, | ||
info: message.info, | ||
id: message.id, | ||
} })); | ||
state.users[message.actor] = { | ||
connectionId: message.actor, | ||
info: message.info, | ||
id: message.id, | ||
}; | ||
updateUsers(); | ||
if (state.me) { | ||
@@ -292,6 +283,10 @@ // Send current presence to new user | ||
clearTimeout(state.timeoutHandles.reconnect); | ||
updateUsers({}); | ||
state.users = {}; | ||
updateUsers(); | ||
if (event.code >= 4000 && event.code <= 4100) { | ||
updateConnection({ state: "failed" }); | ||
context.onError(new Error(event.reason)); | ||
const error = new LiveblocksError(event.reason, event.code); | ||
for (const listener of state.listeners.error) { | ||
listener(error); | ||
} | ||
} | ||
@@ -414,3 +409,2 @@ else if (event.wasClean === false) { | ||
updateConnection({ state: "closed" }); | ||
state.me = null; | ||
if (state.timeoutHandles.flush) { | ||
@@ -422,8 +416,11 @@ clearTimeout(state.timeoutHandles.flush); | ||
clearInterval(state.intervalHandles.heartbeat); | ||
updateUsers({}); | ||
state.listeners["my-presence"] = []; | ||
state.listeners["others-presence"] = []; | ||
state.listeners.event = []; | ||
state.listeners.storage = []; | ||
state.users = {}; | ||
updateUsers(); | ||
clearListeners(); | ||
} | ||
function clearListeners() { | ||
for (const key in state.listeners) { | ||
state.listeners[key] = []; | ||
} | ||
} | ||
function getPresence() { | ||
@@ -535,4 +532,4 @@ return state.me; | ||
disconnect, | ||
addEventListener, | ||
removeEventListener, | ||
subscribe, | ||
unsubscribe, | ||
// Presence | ||
@@ -551,3 +548,2 @@ updatePresence, | ||
// Core | ||
getListenersCount, | ||
getConnectionState, | ||
@@ -562,3 +558,3 @@ // Presence | ||
} | ||
export function defaultState() { | ||
export function defaultState(me) { | ||
return { | ||
@@ -570,4 +566,5 @@ connection: { state: "closed" }, | ||
event: [], | ||
"others-presence": [], | ||
others: [], | ||
"my-presence": [], | ||
error: [], | ||
}, | ||
@@ -589,3 +586,3 @@ numberOfRetry: 0, | ||
}, | ||
me: null, | ||
me: me == null ? {} : me, | ||
users: {}, | ||
@@ -603,3 +600,3 @@ others: makeOthers({}), | ||
const authEndpoint = options.authEndpoint; | ||
const state = defaultState(); | ||
const state = defaultState(options.initialPresence); | ||
const machine = makeStateMachine(state, { | ||
@@ -609,3 +606,2 @@ throttleDelay, | ||
authEndpoint, | ||
onError: options.onError, | ||
room: name, | ||
@@ -620,5 +616,4 @@ }); | ||
getConnectionState: machine.selectors.getConnectionState, | ||
getListenersCount: machine.selectors.getListenersCount, | ||
addEventListener: machine.addEventListener, | ||
removeEventListener: machine.removeEventListener, | ||
subscribe: machine.subscribe, | ||
unsubscribe: machine.unsubscribe, | ||
///////////// | ||
@@ -647,1 +642,7 @@ // Storage // | ||
} | ||
class LiveblocksError extends Error { | ||
constructor(message, code) { | ||
super(message); | ||
this.code = code; | ||
} | ||
} |
import { RecordData, Record, List } from "./doc"; | ||
/** | ||
* Represents all the other users conencted in the room. Treated as immutable. | ||
* Represents all the other users connected in the room. Treated as immutable. | ||
*/ | ||
@@ -80,15 +80,20 @@ export interface Others<TPresence extends Presence = Presence> { | ||
getConnectionState(): Connection; | ||
getListenersCount(): number; | ||
addEventListener: { | ||
<T extends Presence>(type: "my-presence", listener: MyPresenceEventCallback<T>): void; | ||
<T extends Presence>(type: "others-presence", listener: OthersPresenceEventCallback<T>): void; | ||
(type: "event", listener: EventEventCallback): void; | ||
<T extends RecordData>(type: "storage", listener: StorageEventCallback<T>): void; | ||
subscribe: { | ||
<T extends Presence>(type: "my-presence", listener: MyPresenceCallback<T>): void; | ||
<T extends Presence>(type: "others", listener: OthersEventCallback<T>): void; | ||
(type: "event", listener: EventCallback): void; | ||
<T extends RecordData>(type: "storage", listener: StorageCallback<T>): void; | ||
(type: "error", listener: (error: Error) => void): void; | ||
}; | ||
removeEventListener: { | ||
<T extends Presence>(type: "my-presence", listener: MyPresenceEventCallback<T>): void; | ||
<T extends Presence>(type: "others-presence", listener: OthersPresenceEventCallback<T>): void; | ||
(type: "event", listener: EventEventCallback): void; | ||
<T extends RecordData>(type: "storage", listener: StorageEventCallback<T>): void; | ||
unsubscribe: { | ||
<T extends Presence>(type: "my-presence", listener: MyPresenceCallback<T>): void; | ||
<T extends Presence>(type: "others", listener: OthersEventCallback<T>): void; | ||
(type: "event", listener: EventCallback): void; | ||
<T extends RecordData>(type: "storage", listener: StorageCallback<T>): void; | ||
(type: "error", listener: (error: Error) => void): void; | ||
}; | ||
getPresence: <T extends Presence>() => T; | ||
getOthers: <T extends Presence>() => Others<T>; | ||
updatePresence: <T extends Presence>(overrides: Partial<T>) => void; | ||
broadcastEvent: (event: any) => void; | ||
getStorage: () => LiveStorage; | ||
@@ -102,14 +107,18 @@ fetchStorage(initialStorageFactory: InitialStorageFactory): void; | ||
moveItem<T extends RecordData>(list: List<Record<T>>, index: number, targetIndex: number): void; | ||
getPresence: <T extends Presence>() => T | null; | ||
getOthers: <T extends Presence>() => Others<T>; | ||
updatePresence: <T extends Presence>(overrides: Partial<T>) => void; | ||
broadcastEvent: (event: any) => void; | ||
}; | ||
export declare type StorageEventCallback<T extends RecordData = RecordData> = (storage: LiveStorage<T>) => void; | ||
export declare type MyPresenceEventCallback<T extends Presence = Presence> = (me: T) => void; | ||
export declare type OthersPresenceEventCallback<T extends Presence = Presence> = (others: Others<T>) => void; | ||
export declare type EventEventCallback = ({ connectionId, event, }: { | ||
export declare type StorageCallback<T extends RecordData = RecordData> = (storage: LiveStorage<T>) => void; | ||
export declare type MyPresenceCallback<T extends Presence = Presence> = (me: T) => void; | ||
export declare type OthersEventCallback<T extends Presence = Presence> = (others: Others<T>) => void; | ||
export declare type EventCallback = ({ connectionId, event, }: { | ||
connectionId: number; | ||
event: any; | ||
}) => void; | ||
export declare type ErrorCallback = (error: Error) => void; | ||
export declare type RoomEventCallbackMap = { | ||
storage: StorageCallback; | ||
"my-presence": MyPresenceCallback; | ||
others: OthersEventCallback; | ||
event: EventCallback; | ||
error: ErrorCallback; | ||
}; | ||
export declare type CreateRecord = Room["createRecord"]; | ||
@@ -121,16 +130,7 @@ export declare type CreateList = Room["createList"]; | ||
}) => TRoot; | ||
export declare type RoomEventCallbackMap = { | ||
storage: StorageEventCallback; | ||
"my-presence": MyPresenceEventCallback; | ||
"others-presence": OthersPresenceEventCallback; | ||
}; | ||
declare type ClientErrorCallback = (error: Error) => void; | ||
declare type ClientEventCallbackMap = { | ||
error: ClientErrorCallback; | ||
}; | ||
export declare type Client = { | ||
addEventListener: <T extends "error">(type: T, listener: ClientEventCallbackMap[T]) => void; | ||
removeEventListener: <T extends "error">(type: T, listener: ClientEventCallbackMap[T]) => void; | ||
getRoom: (room: string) => Room; | ||
getRoom(roomId: string): Room | null; | ||
enter(roomId: string, defaultPresence?: Presence): Room; | ||
leave(roomId: string): void; | ||
}; | ||
export {}; |
{ | ||
"name": "@liveblocks/client", | ||
"version": "0.6.0-beta.4", | ||
"version": "0.7.0", | ||
"description": "", | ||
@@ -5,0 +5,0 @@ "main": "./lib/cjs/index.js", |
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
125412
3565