@databutton/liveblocks-client
Version:
**At [Liveblocks](https://liveblocks.io), weβre building tools to help companies create world-class collaborative products that attract, engage and retain users.** This repository is a set of open-source packages for building performant and reliable multi
465 lines (464 loc) β’ 17.7 kB
TypeScript
import type { LiveList } from "./LiveList";
import type { LiveMap } from "./LiveMap";
import type { LiveObject } from "./LiveObject";
export declare type MyPresenceCallback<T extends Presence = Presence> = (me: T) => void;
export declare type OthersEventCallback<T extends Presence = Presence> = (others: Others<T>, event: OthersEvent<T>) => void;
export declare type EventCallback = ({ connectionId, event, }: {
connectionId: number;
event: any;
}) => void;
export declare type ErrorCallback = (error: Error) => void;
export declare type ConnectionCallback = (state: ConnectionState) => void;
export declare type RoomEventCallbackMap = {
"my-presence": MyPresenceCallback;
others: OthersEventCallback;
event: EventCallback;
error: ErrorCallback;
connection: ConnectionCallback;
};
export declare type LiveMapUpdates<TKey extends string = string, TValue = any> = {
type: "LiveMap";
node: LiveMap<TKey, TValue>;
};
export declare type LiveObjectUpdates<TData = any> = {
type: "LiveObject";
node: LiveObject<TData>;
};
export declare type LiveListUpdates<TItem = any> = {
type: "LiveList";
node: LiveList<TItem>;
};
export declare type BroadcastOptions = {
/**
* Whether or not event is queued if the connection is currently closed.
*
* β We are not sure if we want to support this option in the future so it might be deprecated to be replaced by something else
*/
shouldQueueEventIfNotReady: boolean;
};
export declare type StorageUpdate = LiveMapUpdates | LiveObjectUpdates | LiveListUpdates;
export declare type StorageCallback = (updates: StorageUpdate[]) => void;
export declare type Client = {
/**
* Gets a room. Returns null if {@link Client.enter} has not been called previously.
*
* @param roomId The id of the room
*/
getRoom(roomId: string): Room | null;
/**
* Enters a room and returns it.
* @param roomId The id of the room
* @param defaultPresence Optional. Should be serializable to JSON. If omitted, an empty object will be used.
*/
enter<TStorageRoot extends Record<string, any> = Record<string, any>>(roomId: string, options?: {
defaultPresence?: Presence;
defaultStorageRoot?: TStorageRoot;
}): Room;
/**
* Leaves a room.
* @param roomId The id of the room
*/
leave(roomId: string): void;
};
export declare type AuthenticationToken = {
actor: number;
id?: string;
info?: any;
};
/**
* Represents all the other users connected in the room. Treated as immutable.
*/
export interface Others<TPresence extends Presence = Presence> {
/**
* Number of other users in the room.
*/
readonly count: number;
/**
* Returns a new Iterator object that contains the users.
*/
[Symbol.iterator](): IterableIterator<User<TPresence>>;
/**
* Returns the array of connected users in room.
*/
toArray(): User<TPresence>[];
/**
* This function let you map over the connected users in the room.
*/
map<U>(callback: (user: User<TPresence>) => U): U[];
}
/**
* Represents a user connected in a room. Treated as immutable.
*/
export declare type User<TPresence extends Presence = Presence> = {
/**
* The connection id of the user. It is unique and increment at every new connection.
*/
readonly connectionId: number;
/**
* The id of the user that has been set in the authentication endpoint.
* Useful to get additional information about the connected user.
*/
readonly id?: string;
/**
* Additional user information that has been set in the authentication endpoint.
*/
readonly info?: any;
/**
* The user presence.
*/
readonly presence?: TPresence;
};
export declare type Presence = {
[key: string]: any;
};
declare type AuthEndpointCallback = (room: string) => Promise<{
token: string;
}>;
export declare type AuthEndpoint = string | AuthEndpointCallback;
/**
* The authentication endpoint that is called to ensure that the current user has access to a room.
* Can be an url or a callback if you need to add additional headers.
*/
export declare type ClientOptions = {
throttle?: number;
} & ({
publicApiKey: string;
authEndpoint?: never;
} | {
publicApiKey?: never;
authEndpoint: AuthEndpoint;
});
export declare type AuthorizeResponse = {
token: string;
};
declare type ConnectionState = "closed" | "authenticating" | "unavailable" | "failed" | "open" | "connecting";
export declare type Connection = {
state: "closed" | "authenticating" | "unavailable" | "failed";
} | {
state: "open" | "connecting";
id: number;
userId?: string;
userInfo?: any;
};
export declare type OthersEvent<T extends Presence = Presence> = {
type: "leave";
user: User<T>;
} | {
type: "enter";
user: User<T>;
} | {
type: "update";
user: User<T>;
updates: Partial<T>;
} | {
type: "reset";
};
export declare type Room = {
getConnectionState(): ConnectionState;
subscribe: {
/**
* Subscribe to the current user presence updates.
*
* @param listener the callback that is called every time the current user presence is updated with {@link Room.updatePresence}.
*
* @example
* room.subscribe("my-presence", (presence) => {
* // Do something
* });
*/
<T extends Presence>(type: "my-presence", listener: MyPresenceCallback<T>): () => void;
/**
* Subscribe to the other users updates.
*
* @param listener the callback that is called when a user enters or leaves the room or when a user update its presence.
*
* @example
* room.subscribe("others", (others) => {
* // Do something
* });
*/
<T extends Presence>(type: "others", listener: OthersEventCallback<T>): () => void;
/**
* Subscribe to events broadcasted by {@link Room.broadcastEvent}
*
* @param listener the callback that is called when a user calls {@link Room.broadcastEvent}
*
* @example
* room.subscribe("event", ({ event, connectionId }) => {
* // Do something
* });
*/
(type: "event", listener: EventCallback): () => void;
/**
* Subscribe to errors thrown in the room.
*/
(type: "error", listener: ErrorCallback): () => void;
/**
* Subscribe to connection state updates.
*/
(type: "connection", listener: ConnectionCallback): () => void;
/**
* Subscribes to changes made on a {@link LiveMap}. Returns an unsubscribe function.
* In a future version, we will also expose what exactly changed in the {@link LiveMap}.
*
* @param listener the callback this called when the {@link LiveMap} changes.
*
* @returns Unsubscribe function.
*
* @example
* const liveMap = new LiveMap();
* const unsubscribe = room.subscribe(liveMap, (liveMap) => { });
* unsubscribe();
*/
<TKey extends string, TValue>(liveMap: LiveMap<TKey, TValue>, listener: (liveMap: LiveMap<TKey, TValue>) => void): () => void;
/**
* Subscribes to changes made on a {@link LiveObject}. Returns an unsubscribe function.
* In a future version, we will also expose what exactly changed in the {@link LiveObject}.
*
* @param listener the callback this called when the {@link LiveObject} changes.
*
* @returns Unsubscribe function.
*
* @example
* const liveObject = new LiveObject();
* const unsubscribe = room.subscribe(liveObject, (liveObject) => { });
* unsubscribe();
*/
<TData>(liveObject: LiveObject<TData>, callback: (liveObject: LiveObject<TData>) => void): () => void;
/**
* Subscribes to changes made on a {@link LiveList}. Returns an unsubscribe function.
* In a future version, we will also expose what exactly changed in the {@link LiveList}.
*
* @param listener the callback this called when the {@link LiveList} changes.
*
* @returns Unsubscribe function.
*
* @example
* const liveList = new LiveList();
* const unsubscribe = room.subscribe(liveList, (liveList) => { });
* unsubscribe();
*/
<TItem>(liveList: LiveList<TItem>, callback: (liveList: LiveList<TItem>) => void): () => void;
/**
* Subscribes to changes made on a {@link LiveMap} and all the nested data structures. Returns an unsubscribe function.
* In a future version, we will also expose what exactly changed in the {@link LiveMap}.
*
* @param listener the callback this called when the {@link LiveMap} changes.
*
* @returns Unsubscribe function.
*
* @example
* const liveMap = new LiveMap();
* const unsubscribe = room.subscribe(liveMap, (liveMap) => { }, { isDeep: true });
* unsubscribe();
*/
<TKey extends string, TValue>(liveMap: LiveMap<TKey, TValue>, callback: (updates: StorageUpdate[]) => void, options: {
isDeep: true;
}): () => void;
/**
* Subscribes to changes made on a {@link LiveObject} and all the nested data structures. Returns an unsubscribe function.
* In a future version, we will also expose what exactly changed in the {@link LiveObject}.
*
* @param listener the callback this called when the {@link LiveObject} changes.
*
* @returns Unsubscribe function.
*
* @example
* const liveObject = new LiveObject();
* const unsubscribe = room.subscribe(liveObject, (liveObject) => { }, { isDeep: true });
* unsubscribe();
*/
<TData>(liveObject: LiveObject<TData>, callback: (updates: StorageUpdate[]) => void, options: {
isDeep: true;
}): () => void;
/**
* Subscribes to changes made on a {@link LiveList} and all the nested data structures. Returns an unsubscribe function.
* In a future version, we will also expose what exactly changed in the {@link LiveList}.
*
* @param listener the callback this called when the {@link LiveList} changes.
*
* @returns Unsubscribe function.
*
* @example
* const liveList = new LiveList();
* const unsubscribe = room.subscribe(liveList, (liveList) => { }, { isDeep: true });
* unsubscribe();
*/
<TItem>(liveList: LiveList<TItem>, callback: (updates: StorageUpdate[]) => void, options: {
isDeep: true;
}): () => void;
};
/**
* Room's history contains functions that let you undo and redo operation made on by the current client on the presence and storage.
*/
history: {
/**
* Undoes the last operation executed by the current client.
* It does not impact operations made by other clients.
*
* @example
* room.updatePresence({ selectedId: "xxx" }, { addToHistory: true });
* room.updatePresence({ selectedId: "yyy" }, { addToHistory: true });
* room.history.undo();
* // room.getPresence() equals { selectedId: "xxx" }
*/
undo: () => void;
/**
* Redoes the last operation executed by the current client.
* It does not impact operations made by other clients.
*
* @example
* room.updatePresence({ selectedId: "xxx" }, { addToHistory: true });
* room.updatePresence({ selectedId: "yyy" }, { addToHistory: true });
* room.history.undo();
* // room.getPresence() equals { selectedId: "xxx" }
* room.history.redo();
* // room.getPresence() equals { selectedId: "yyy" }
*/
redo: () => void;
/**
* All future modifications made on the Room will be merged together to create a single history item until resume is called.
*
* @example
* room.updatePresence({ cursor: { x: 0, y: 0 } }, { addToHistory: true });
* room.history.pause();
* room.updatePresence({ cursor: { x: 1, y: 1 } }, { addToHistory: true });
* room.updatePresence({ cursor: { x: 2, y: 2 } }, { addToHistory: true });
* room.history.resume();
* room.history.undo();
* // room.getPresence() equals { cursor: { x: 0, y: 0 } }
*/
pause: () => void;
/**
* Resumes history. Modifications made on the Room are not merged into a single history item anymore.
*
* @example
* room.updatePresence({ cursor: { x: 0, y: 0 } }, { addToHistory: true });
* room.history.pause();
* room.updatePresence({ cursor: { x: 1, y: 1 } }, { addToHistory: true });
* room.updatePresence({ cursor: { x: 2, y: 2 } }, { addToHistory: true });
* room.history.resume();
* room.history.undo();
* // room.getPresence() equals { cursor: { x: 0, y: 0 } }
*/
resume: () => void;
};
/**
* @deprecated use the callback returned by subscribe instead.
* See v0.13 release notes for more information.
* Will be removed in a future version.
*/
unsubscribe: {
/**
* @deprecated use the callback returned by subscribe instead.
* See v0.13 release notes for more information.
* Will be removed in a future version.
*/
<T extends Presence>(type: "my-presence", listener: MyPresenceCallback<T>): void;
/**
* @deprecated use the callback returned by subscribe instead.
* See v0.13 release notes for more information.
* Will be removed in a future version.
*/
<T extends Presence>(type: "others", listener: OthersEventCallback<T>): void;
/**
* @deprecated use the callback returned by subscribe instead.
* See v0.13 release notes for more information.
* Will be removed in a future version.
*/
(type: "event", listener: EventCallback): void;
/**
* @deprecated use the callback returned by subscribe instead.
* See v0.13 release notes for more information.
* Will be removed in a future version.
*/
(type: "error", listener: ErrorCallback): void;
/**
* @deprecated use the callback returned by subscribe instead.
* See v0.13 release notes for more information.
* Will be removed in a future version.
*/
(type: "connection", listener: ConnectionCallback): void;
};
/**
* Gets the current user.
* Returns null if not it is not yet connected to the room.
*
* @example
* const user = room.getSelf();
*/
getSelf<TPresence extends Presence = Presence>(): User<TPresence> | null;
/**
* Gets the presence of the current user.
*
* @example
* const presence = room.getPresence();
*/
getPresence: <T extends Presence>() => T;
/**
* Gets all the other users in the room.
*
* @example
* const others = room.getOthers();
*/
getOthers: <T extends Presence>() => Others<T>;
/**
* Updates the presence of the current user. Only pass the properties you want to update. No need to send the full presence.
* @param overrides A partial object that contains the properties you want to update.
* @param overrides Optional object to configure the behavior of updatePresence.
*
* @example
* room.updatePresence({ x: 0 });
* room.updatePresence({ y: 0 });
*
* const presence = room.getPresence();
* // presence is equivalent to { x: 0, y: 0 }
*/
updatePresence: <T extends Presence>(overrides: Partial<T>, options?: {
/**
* Whether or not the presence should have an impact on the undo/redo history.
*/
addToHistory: boolean;
}) => void;
/**
* Broadcasts an event to other users in the room. Event broadcasted to the room can be listened with {@link Room.subscribe}("event").
* @param {any} event the event to broadcast. Should be serializable to JSON
*
* @example
* // On client A
* room.broadcastEvent({ type: "EMOJI", emoji: "π₯" });
*
* // On client B
* room.subscribe("event", ({ event }) => {
* if(event.type === "EMOJI") {
* // Do something
* }
* });
*/
broadcastEvent: (event: any, options?: BroadcastOptions) => void;
/**
* Get the room's storage asynchronously.
* The storage's root is a {@link LiveObject}.
*
* @example
* const { root } = await room.getStorage();
*/
getStorage: <TRoot>() => Promise<{
root: LiveObject<TRoot>;
}>;
/**
* Batches modifications made during the given function.
* All the modifications are sent to other clients in a single message.
* All the subscribers are called only after the batch is over.
* All the modifications are merged in a single history item (undo/redo).
*
* @example
* const { root } = await room.getStorage();
* room.batch(() => {
* root.set("x", 0);
* room.updatePresence({ cursor: { x: 100, y: 100 }});
* });
*/
batch: (fn: () => void) => void;
};
export {};