Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More β†’
Socket
Sign inDemoInstall
Socket

@liveblocks/core

Package Overview
Dependencies
Maintainers
5
Versions
297
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@liveblocks/core - npm Package Compare versions

Comparing version 0.19.0-beta0 to 0.19.0

1340

dist/index.d.ts
/**
* Helper function that can be used to implement exhaustive switch statements
* with TypeScript. Example usage:
* Represents an indefinitely deep arbitrary JSON data structure. There are
* four types that make up the Json family:
*
* type Fruit = "🍎" | "🍌";
* - Json any legal JSON value
* - JsonScalar any legal JSON leaf value (no lists or objects)
* - JsonArray a JSON value whose outer type is an array
* - JsonObject a JSON value whose outer type is an object
*
* switch (fruit) {
* case "🍎":
* case "🍌":
* return doSomething();
*
* default:
* return assertNever(fruit, "Unknown fruit");
* }
*
* If now the Fruit union is extended (i.e. add "πŸ’"), TypeScript will catch
* this *statically*, rather than at runtime, and force you to handle the
* πŸ’ case.
*/
declare function assertNever(_value: never, errmsg: string): never;
declare type Json = JsonScalar | JsonArray | JsonObject;
declare type JsonScalar = string | number | boolean | null;
declare type JsonArray = Json[];
declare type JsonObject = {
[key: string]: Json | undefined;
};
declare function isJsonScalar(data: Json): data is JsonScalar;
declare function isJsonArray(data: Json): data is JsonArray;
declare function isJsonObject(data: Json): data is JsonObject;
declare type AppOnlyAuthToken = {
appId: string;
roomId?: never;
scopes: string[];
};
declare type RoomAuthToken = {
appId: string;
roomId: string;
scopes: string[];
actor: number;
maxConnectionsPerRoom?: number;
id?: string;
info?: Json;
};
declare type AuthToken = AppOnlyAuthToken | RoomAuthToken;
declare function isAppOnlyAuthToken(data: JsonObject): data is AppOnlyAuthToken;
declare function isRoomAuthToken(data: JsonObject): data is RoomAuthToken;
declare function isAuthToken(data: JsonObject): data is AuthToken;
declare enum OpCode {
INIT = 0,
SET_PARENT_KEY = 1,
CREATE_LIST = 2,
UPDATE_OBJECT = 3,
CREATE_OBJECT = 4,
DELETE_CRDT = 5,
DELETE_OBJECT_KEY = 6,
CREATE_MAP = 7,
CREATE_REGISTER = 8
}
/**
* Asserts that a given value is non-nullable. This is similar to TypeScript's
* `!` operator, but will throw an error at runtime (dev-mode only) indicating
* an incorrect assumption.
*
* Instead of:
*
* foo!.bar
*
* Use:
*
* nn(foo).bar
*
* These operations are the payload for {@link UpdateStorageServerMsg} messages
* only.
*/
declare function nn<T>(value: T, errmsg?: string): NonNullable<T>;
declare type Op = CreateOp | UpdateObjectOp | DeleteCrdtOp | SetParentKeyOp | DeleteObjectKeyOp;
declare type CreateOp = CreateRootObjectOp | CreateChildOp;
declare type CreateChildOp = CreateObjectOp | CreateRegisterOp | CreateMapOp | CreateListOp;
declare type UpdateObjectOp = {
opId?: string;
id: string;
type: OpCode.UPDATE_OBJECT;
data: Partial<JsonObject>;
};
declare type CreateObjectOp = {
opId?: string;
id: string;
intent?: "set";
deletedId?: string;
type: OpCode.CREATE_OBJECT;
parentId: string;
parentKey: string;
data: JsonObject;
};
declare type CreateRootObjectOp = {
opId?: string;
id: string;
type: OpCode.CREATE_OBJECT;
data: JsonObject;
parentId?: never;
parentKey?: never;
};
declare type CreateListOp = {
opId?: string;
id: string;
intent?: "set";
deletedId?: string;
type: OpCode.CREATE_LIST;
parentId: string;
parentKey: string;
};
declare type CreateMapOp = {
opId?: string;
id: string;
intent?: "set";
deletedId?: string;
type: OpCode.CREATE_MAP;
parentId: string;
parentKey: string;
};
declare type CreateRegisterOp = {
opId?: string;
id: string;
intent?: "set";
deletedId?: string;
type: OpCode.CREATE_REGISTER;
parentId: string;
parentKey: string;
data: Json;
};
declare type DeleteCrdtOp = {
opId?: string;
id: string;
type: OpCode.DELETE_CRDT;
};
declare type SetParentKeyOp = {
opId?: string;
id: string;
type: OpCode.SET_PARENT_KEY;
parentKey: string;
};
declare type DeleteObjectKeyOp = {
opId?: string;
id: string;
type: OpCode.DELETE_OBJECT_KEY;
key: string;
};
declare type Callback<T> = (event: T) => void;
declare type UnsubscribeCallback = () => void;
declare type Observable<T> = {
subscribe(callback: Callback<T>): UnsubscribeCallback;
subscribeOnce(callback: Callback<T>): UnsubscribeCallback;
/**
* Represents an indefinitely deep arbitrary immutable data
* structure, as returned by the .toImmutable().
*/
declare type Immutable = Scalar | ImmutableList | ImmutableObject | ImmutableMap;
declare type Scalar = string | number | boolean | null;
declare type ImmutableList = readonly Immutable[];
declare type ImmutableObject = {
readonly [key: string]: Immutable | undefined;
};
declare type ImmutableMap = ReadonlyMap<string, Immutable>;
declare type ReadonlyArrayWithLegacyMethods<T> = readonly T[] & {
declare type UpdateDelta = {
type: "update";
} | {
type: "delete";
};
declare type LiveObjectUpdateDelta<O extends {
[key: string]: unknown;
}> = {
[K in keyof O]?: UpdateDelta | undefined;
};
/**
* A LiveObject notification that is sent in-client to any subscribers whenever
* one or more of the entries inside the LiveObject instance have changed.
*/
declare type LiveObjectUpdates<TData extends LsonObject> = {
type: "LiveObject";
node: LiveObject<TData>;
updates: LiveObjectUpdateDelta<TData>;
};
/**
* The LiveObject class is similar to a JavaScript object that is synchronized on all clients.
* Keys should be a string, and values should be serializable to JSON.
* If multiple clients update the same property simultaneously, the last modification received by the Liveblocks servers is the winner.
*/
declare class LiveObject<O extends LsonObject> extends AbstractCrdt {
constructor(obj?: O);
/**
* @deprecated Prefer the normal .length property on arrays.
* Transform the LiveObject into a javascript object
*/
readonly count: number;
toObject(): O;
/**
* @deprecated Calling .toArray() is no longer needed
* Adds or updates a property with a specified key and a value.
* @param key The key of the property to add
* @param value The value of the property to add
*/
readonly toArray: () => readonly T[];
};
declare function asArrayWithLegacyMethods<T>(arr: readonly T[]): ReadonlyArrayWithLegacyMethods<T>;
set<TKey extends keyof O>(key: TKey, value: O[TKey]): void;
/**
* Returns a specified property from the LiveObject.
* @param key The key of the property to get
*/
get<TKey extends keyof O>(key: TKey): O[TKey];
/**
* Deletes a key from the LiveObject
* @param key The key of the property to delete
*/
delete(key: keyof O): void;
/**
* Adds or updates multiple properties at once with an object.
* @param patch The object used to overrides properties
*/
update(patch: Partial<O>): void;
toImmutable(): ToImmutable<O>;
}
/**
* Helper type to convert any valid Lson type to the equivalent Json type.
*
* Examples:
*
* ToImmutable<42> // 42
* ToImmutable<'hi'> // 'hi'
* ToImmutable<number> // number
* ToImmutable<string> // string
* ToImmutable<string | LiveList<number>> // string | readonly number[]
* ToImmutable<LiveMap<string, LiveList<number>>>
* // ReadonlyMap<string, readonly number[]>
* ToImmutable<LiveObject<{ a: number, b: LiveList<string>, c?: number }>>
* // { readonly a: null, readonly b: readonly string[], readonly c?: number }
*
*/
declare type ToImmutable<L extends Lson | LsonObject> = L extends LiveList<infer I> ? readonly ToImmutable<I>[] : L extends LiveObject<infer O> ? ToImmutable<O> : L extends LiveMap<infer K, infer V> ? ReadonlyMap<K, ToImmutable<V>> : L extends LsonObject ? {
readonly [K in keyof L]: ToImmutable<Exclude<L[K], undefined>> | (undefined extends L[K] ? undefined : never);
} : L extends Json ? L : never;
/**
* A LiveMap notification that is sent in-client to any subscribers whenever
* one or more of the values inside the LiveMap instance have changed.
*/
declare type LiveMapUpdates<TKey extends string, TValue extends Lson> = {
type: "LiveMap";
node: LiveMap<TKey, TValue>;
updates: {
[key: string]: UpdateDelta;
};
};
/**
* The LiveMap class is similar to a JavaScript Map that is synchronized on all clients.

@@ -114,138 +284,10 @@ * Keys should be a string, and values should be serializable to JSON.

declare type StorageCallback = (updates: StorageUpdate[]) => void;
/**
* The LiveObject class is similar to a JavaScript object that is synchronized on all clients.
* Keys should be a string, and values should be serializable to JSON.
* If multiple clients update the same property simultaneously, the last modification received by the Liveblocks servers is the winner.
* The payload of notifications sent (in-client) when LiveStructures change.
* Messages of this kind are not originating from the network, but are 100%
* in-client.
*/
declare class LiveObject<O extends LsonObject> extends AbstractCrdt {
constructor(obj?: O);
/**
* Transform the LiveObject into a javascript object
*/
toObject(): O;
/**
* Adds or updates a property with a specified key and a value.
* @param key The key of the property to add
* @param value The value of the property to add
*/
set<TKey extends keyof O>(key: TKey, value: O[TKey]): void;
/**
* Returns a specified property from the LiveObject.
* @param key The key of the property to get
*/
get<TKey extends keyof O>(key: TKey): O[TKey];
/**
* Deletes a key from the LiveObject
* @param key The key of the property to delete
*/
delete(key: keyof O): void;
/**
* Adds or updates multiple properties at once with an object.
* @param patch The object used to overrides properties
*/
update(patch: Partial<O>): void;
toImmutable(): ToImmutable<O>;
}
declare type StorageUpdate = LiveMapUpdates<string, Lson> | LiveObjectUpdates<LsonObject> | LiveListUpdates<Lson>;
/**
* Represents an indefinitely deep arbitrary JSON data structure. There are
* four types that make up the Json family:
*
* - Json any legal JSON value
* - JsonScalar any legal JSON leaf value (no lists or objects)
* - JsonArray a JSON value whose outer type is an array
* - JsonObject a JSON value whose outer type is an object
*
*/
declare type Json = JsonScalar | JsonArray | JsonObject;
declare type JsonScalar = string | number | boolean | null;
declare type JsonArray = Json[];
declare type JsonObject = {
[key: string]: Json | undefined;
};
declare function isJsonScalar(data: Json): data is JsonScalar;
declare function isJsonArray(data: Json): data is JsonArray;
declare function isJsonObject(data: Json): data is JsonObject;
/**
* INTERNAL
*/
declare class LiveRegister<TValue extends Json> extends AbstractCrdt {
constructor(data: TValue);
get data(): TValue;
}
declare type LiveStructure = LiveObject<LsonObject> | LiveList<Lson> | LiveMap<string, Lson>;
/**
* Think of Lson as a sibling of the Json data tree, except that the nested
* data structure can contain a mix of Json values and LiveStructure instances.
*/
declare type Lson = Json | LiveStructure;
/**
* LiveNode is the internal tree for managing Live data structures. The key
* difference with Lson is that all the Json values get represented in
* a LiveRegister node.
*/
declare type LiveNode = LiveStructure | LiveRegister<Json>;
/**
* A mapping of keys to Lson values. A Lson value is any valid JSON
* value or a Live storage data structure (LiveMap, LiveList, etc.)
*/
declare type LsonObject = {
[key: string]: Lson | undefined;
};
/**
* Helper type to convert any valid Lson type to the equivalent Json type.
*
* Examples:
*
* ToJson<42> // 42
* ToJson<'hi'> // 'hi'
* ToJson<number> // number
* ToJson<string> // string
* ToJson<string | LiveList<number>> // string | number[]
* ToJson<LiveMap<string, LiveList<number>>>
* // { [key: string]: number[] }
* ToJson<LiveObject<{ a: number, b: LiveList<string>, c?: number }>>
* // { a: null, b: string[], c?: number }
*
*/
declare type ToJson<T extends Lson | LsonObject> = T extends Json ? T : T extends LsonObject ? {
[K in keyof T]: ToJson<Exclude<T[K], undefined>> | (undefined extends T[K] ? undefined : never);
} : T extends LiveList<infer I> ? ToJson<I>[] : T extends LiveObject<infer O> ? ToJson<O> : T extends LiveMap<infer KS, infer V> ? {
[K in KS]: ToJson<V>;
} : never;
/**
* Represents an indefinitely deep arbitrary immutable data
* structure, as returned by the .toImmutable().
*/
declare type Immutable = Scalar | ImmutableList | ImmutableObject | ImmutableMap;
declare type Scalar = string | number | boolean | null;
declare type ImmutableList = readonly Immutable[];
declare type ImmutableObject = {
readonly [key: string]: Immutable | undefined;
};
declare type ImmutableMap = ReadonlyMap<string, Immutable>;
/**
* Helper type to convert any valid Lson type to the equivalent Json type.
*
* Examples:
*
* ToImmutable<42> // 42
* ToImmutable<'hi'> // 'hi'
* ToImmutable<number> // number
* ToImmutable<string> // string
* ToImmutable<string | LiveList<number>> // string | readonly number[]
* ToImmutable<LiveMap<string, LiveList<number>>>
* // ReadonlyMap<string, readonly number[]>
* ToImmutable<LiveObject<{ a: number, b: LiveList<string>, c?: number }>>
* // { readonly a: null, readonly b: readonly string[], readonly c?: number }
*
*/
declare type ToImmutable<L extends Lson | LsonObject> = L extends LiveList<infer I> ? readonly ToImmutable<I>[] : L extends LiveObject<infer O> ? ToImmutable<O> : L extends LiveMap<infer K, infer V> ? ReadonlyMap<K, ToImmutable<V>> : L extends LsonObject ? {
readonly [K in keyof L]: ToImmutable<Exclude<L[K], undefined>> | (undefined extends L[K] ? undefined : never);
} : L extends Json ? L : never;
declare abstract class AbstractCrdt {

@@ -259,3 +301,29 @@ get roomId(): string | null;

declare type LiveListUpdateDelta = {
index: number;
item: Lson;
type: "insert";
} | {
index: number;
type: "delete";
} | {
index: number;
previousIndex: number;
item: Lson;
type: "move";
} | {
index: number;
item: Lson;
type: "set";
};
/**
* A LiveList notification that is sent in-client to any subscribers whenever
* one or more of the items inside the LiveList instance have changed.
*/
declare type LiveListUpdates<TItem extends Lson> = {
type: "LiveList";
node: LiveList<TItem>;
updates: LiveListUpdateDelta[];
};
/**
* The LiveList class represents an ordered collection of items that is synchronized across clients.

@@ -363,2 +431,51 @@ */

/**
* INTERNAL
*/
declare class LiveRegister<TValue extends Json> extends AbstractCrdt {
constructor(data: TValue);
get data(): TValue;
}
declare type LiveStructure = LiveObject<LsonObject> | LiveList<Lson> | LiveMap<string, Lson>;
/**
* Think of Lson as a sibling of the Json data tree, except that the nested
* data structure can contain a mix of Json values and LiveStructure instances.
*/
declare type Lson = Json | LiveStructure;
/**
* LiveNode is the internal tree for managing Live data structures. The key
* difference with Lson is that all the Json values get represented in
* a LiveRegister node.
*/
declare type LiveNode = LiveStructure | LiveRegister<Json>;
/**
* A mapping of keys to Lson values. A Lson value is any valid JSON
* value or a Live storage data structure (LiveMap, LiveList, etc.)
*/
declare type LsonObject = {
[key: string]: Lson | undefined;
};
/**
* Helper type to convert any valid Lson type to the equivalent Json type.
*
* Examples:
*
* ToJson<42> // 42
* ToJson<'hi'> // 'hi'
* ToJson<number> // number
* ToJson<string> // string
* ToJson<string | LiveList<number>> // string | number[]
* ToJson<LiveMap<string, LiveList<number>>>
* // { [key: string]: number[] }
* ToJson<LiveObject<{ a: number, b: LiveList<string>, c?: number }>>
* // { a: null, b: string[], c?: number }
*
*/
declare type ToJson<T extends Lson | LsonObject> = T extends Json ? T : T extends LsonObject ? {
[K in keyof T]: ToJson<Exclude<T[K], undefined>> | (undefined extends T[K] ? undefined : never);
} : T extends LiveList<infer I> ? ToJson<I>[] : T extends LiveObject<infer O> ? ToJson<O> : T extends LiveMap<infer KS, infer V> ? {
[K in KS]: ToJson<V>;
} : never;
/**
* This type is used by clients to define the metadata for a user.

@@ -378,89 +495,34 @@ */

declare enum OpCode {
INIT = 0,
SET_PARENT_KEY = 1,
CREATE_LIST = 2,
UPDATE_OBJECT = 3,
CREATE_OBJECT = 4,
DELETE_CRDT = 5,
DELETE_OBJECT_KEY = 6,
CREATE_MAP = 7,
CREATE_REGISTER = 8
}
declare type Callback<T> = (event: T) => void;
declare type UnsubscribeCallback = () => void;
declare type Observable<T> = {
subscribe(callback: Callback<T>): UnsubscribeCallback;
subscribeOnce(callback: Callback<T>): UnsubscribeCallback;
};
/**
* These operations are the payload for {@link UpdateStorageServerMsg} messages
* only.
* This helper type is effectively a no-op, but will force TypeScript to
* "evaluate" any named helper types in its definition. This can sometimes make
* API signatures clearer in IDEs.
*
* For example, in:
*
* type Payload<T> = { data: T };
*
* let r1: Payload<string>;
* let r2: Resolve<Payload<string>>;
*
* The inferred type of `r1` is going to be `Payload<string>` which shows up in
* editor hints, and it may be unclear what's inside if you don't know the
* definition of `Payload`.
*
* The inferred type of `r2` is going to be `{ data: string }`, which may be
* more helpful.
*
* This trick comes from:
* https://effectivetypescript.com/2022/02/25/gentips-4-display/
*/
declare type Op = CreateOp | UpdateObjectOp | DeleteCrdtOp | SetParentKeyOp | DeleteObjectKeyOp;
declare type CreateOp = CreateRootObjectOp | CreateChildOp;
declare type CreateChildOp = CreateObjectOp | CreateRegisterOp | CreateMapOp | CreateListOp;
declare type UpdateObjectOp = {
opId?: string;
id: string;
type: OpCode.UPDATE_OBJECT;
data: Partial<JsonObject>;
declare type Resolve<T> = T extends (...args: unknown[]) => unknown ? T : {
[K in keyof T]: T[K];
};
declare type CreateObjectOp = {
opId?: string;
id: string;
intent?: "set";
deletedId?: string;
type: OpCode.CREATE_OBJECT;
parentId: string;
parentKey: string;
data: JsonObject;
};
declare type CreateRootObjectOp = {
opId?: string;
id: string;
type: OpCode.CREATE_OBJECT;
data: JsonObject;
parentId?: never;
parentKey?: never;
};
declare type CreateListOp = {
opId?: string;
id: string;
intent?: "set";
deletedId?: string;
type: OpCode.CREATE_LIST;
parentId: string;
parentKey: string;
};
declare type CreateMapOp = {
opId?: string;
id: string;
intent?: "set";
deletedId?: string;
type: OpCode.CREATE_MAP;
parentId: string;
parentKey: string;
};
declare type CreateRegisterOp = {
opId?: string;
id: string;
intent?: "set";
deletedId?: string;
type: OpCode.CREATE_REGISTER;
parentId: string;
parentKey: string;
data: Json;
};
declare type DeleteCrdtOp = {
opId?: string;
id: string;
type: OpCode.DELETE_CRDT;
};
declare type SetParentKeyOp = {
opId?: string;
id: string;
type: OpCode.SET_PARENT_KEY;
parentKey: string;
};
declare type DeleteObjectKeyOp = {
opId?: string;
id: string;
type: OpCode.DELETE_OBJECT_KEY;
key: string;
};

@@ -515,341 +577,15 @@ declare enum ClientMsgCode {

declare type IdTuple<T> = [id: string, value: T];
declare enum CrdtType {
OBJECT = 0,
LIST = 1,
MAP = 2,
REGISTER = 3
}
declare type SerializedCrdt = SerializedRootObject | SerializedChild;
declare type SerializedChild = SerializedObject | SerializedList | SerializedMap | SerializedRegister;
declare type SerializedRootObject = {
type: CrdtType.OBJECT;
data: JsonObject;
parentId?: never;
parentKey?: never;
};
declare type SerializedObject = {
type: CrdtType.OBJECT;
parentId: string;
parentKey: string;
data: JsonObject;
};
declare type SerializedList = {
type: CrdtType.LIST;
parentId: string;
parentKey: string;
};
declare type SerializedMap = {
type: CrdtType.MAP;
parentId: string;
parentKey: string;
};
declare type SerializedRegister = {
type: CrdtType.REGISTER;
parentId: string;
parentKey: string;
data: Json;
};
declare function isRootCrdt(crdt: SerializedCrdt): crdt is SerializedRootObject;
declare function isChildCrdt(crdt: SerializedCrdt): crdt is SerializedChild;
/**
* Lookup table for nodes (= SerializedCrdt values) by their IDs.
*/
declare type NodeMap = Map<string, // Node ID
SerializedCrdt>;
/**
* Reverse lookup table for all child nodes (= list of SerializedCrdt values)
* by their parent node's IDs.
*/
declare type ParentToChildNodeMap = Map<string, // Parent's node ID
IdTuple<SerializedChild>[]>;
declare enum ServerMsgCode {
UPDATE_PRESENCE = 100,
USER_JOINED = 101,
USER_LEFT = 102,
BROADCASTED_EVENT = 103,
ROOM_STATE = 104,
INITIAL_STORAGE_STATE = 200,
UPDATE_STORAGE = 201
}
/**
* Messages that can be sent from the server to the client.
*/
declare type ServerMsg<TPresence extends JsonObject, TUserMeta extends BaseUserMeta, TRoomEvent extends Json> = UpdatePresenceServerMsg<TPresence> | UserJoinServerMsg<TUserMeta> | UserLeftServerMsg | BroadcastedEventServerMsg<TRoomEvent> | RoomStateServerMsg<TUserMeta> | InitialDocumentStateServerMsg | UpdateStorageServerMsg;
/**
* Sent by the WebSocket server and broadcasted to all clients to announce that
* a User updated their presence. For example, when a user moves their cursor.
*
* In most cases, the data payload will only include the fields from the
* Presence that have been changed since the last announcement. However, after
* a new user joins a room, a "full presence" will be announced so the newly
* connected user will get each other's user full presence at least once. In
* those cases, the `targetActor` field indicates the newly connected client,
* so all other existing clients can ignore this broadcasted message.
*/
declare type UpdatePresenceServerMsg<TPresence extends JsonObject> = {
type: ServerMsgCode.UPDATE_PRESENCE;
declare type ReadonlyArrayWithLegacyMethods<T> = readonly T[] & {
/**
* The User whose Presence has changed.
* @deprecated Prefer the normal .length property on arrays.
*/
actor: number;
readonly count: number;
/**
* When set, signifies that this is a Full Presenceβ„’ update, not a patch.
*
* The numeric value itself no longer has specific meaning. Historically,
* this field was intended so that clients could ignore these broadcasted
* full presence messages, but it turned out that getting a full presence
* "keyframe" from time to time was useful.
*
* So nowadays, the presence (pun intended) of this `targetActor` field
* is a backward-compatible way of expressing that the `data` contains
* all presence fields, and isn't a partial "patch".
* @deprecated Calling .toArray() is no longer needed
*/
targetActor: number;
/**
* The partial or full Presence of a User. If the `targetActor` field is set,
* this will be the full Presence, otherwise it only contain the fields that
* have changed since the last broadcast.
*/
data: TPresence;
} | {
type: ServerMsgCode.UPDATE_PRESENCE;
/**
* The User whose Presence has changed.
*/
actor: number;
/**
* Not set for partial presence updates.
*/
targetActor?: undefined;
/**
* A partial Presence patch to apply to the User. It will only contain the
* fields that have changed since the last broadcast.
*/
data: Partial<TPresence>;
readonly toArray: () => readonly T[];
};
/**
* Sent by the WebSocket server and broadcasted to all clients to announce that
* a new User has joined the Room.
*/
declare type UserJoinServerMsg<TUserMeta extends BaseUserMeta> = {
type: ServerMsgCode.USER_JOINED;
actor: number;
/**
* The id of the User that has been set in the authentication endpoint.
* Useful to get additional information about the connected user.
*/
id: TUserMeta["id"];
/**
* Additional user information that has been set in the authentication
* endpoint.
*/
info: TUserMeta["info"];
/**
* Permissions that the user has in the Room.
*/
scopes: string[];
};
/**
* Sent by the WebSocket server and broadcasted to all clients to announce that
* a new User has left the Room.
*/
declare type UserLeftServerMsg = {
type: ServerMsgCode.USER_LEFT;
actor: number;
};
/**
* Sent by the WebSocket server and broadcasted to all clients to announce that
* a User broadcasted an Event to everyone in the Room.
*/
declare type BroadcastedEventServerMsg<TRoomEvent extends Json> = {
type: ServerMsgCode.BROADCASTED_EVENT;
/**
* The User who broadcasted the Event.
*/
actor: number;
/**
* The arbitrary payload of the Event. This can be any JSON value. Clients
* will have to manually verify/decode this event.
*/
event: TRoomEvent;
};
/**
* Sent by the WebSocket server to a single client in response to the client
* joining the Room, to provide the initial state of the Room. The payload
* includes a list of all other Users that already are in the Room.
*/
declare type RoomStateServerMsg<TUserMeta extends BaseUserMeta> = {
type: ServerMsgCode.ROOM_STATE;
users: {
[actor: number]: TUserMeta & {
scopes: string[];
};
};
};
/**
* Sent by the WebSocket server to a single client in response to the client
* joining the Room, to provide the initial Storage state of the Room. The
* payload includes the entire Storage document.
*/
declare type InitialDocumentStateServerMsg = {
type: ServerMsgCode.INITIAL_STORAGE_STATE;
items: IdTuple<SerializedCrdt>[];
};
/**
* Sent by the WebSocket server and broadcasted to all clients to announce that
* a change occurred in the Storage document.
*
* The payload of this message contains a list of Ops (aka incremental
* mutations to make to the initially loaded document).
*/
declare type UpdateStorageServerMsg = {
type: ServerMsgCode.UPDATE_STORAGE;
ops: Op[];
};
declare function asArrayWithLegacyMethods<T>(arr: readonly T[]): ReadonlyArrayWithLegacyMethods<T>;
/**
* This helper type is effectively a no-op, but will force TypeScript to
* "evaluate" any named helper types in its definition. This can sometimes make
* API signatures clearer in IDEs.
*
* For example, in:
*
* type Payload<T> = { data: T };
*
* let r1: Payload<string>;
* let r2: Resolve<Payload<string>>;
*
* The inferred type of `r1` is going to be `Payload<string>` which shows up in
* editor hints, and it may be unclear what's inside if you don't know the
* definition of `Payload`.
*
* The inferred type of `r2` is going to be `{ data: string }`, which may be
* more helpful.
*
* This trick comes from:
* https://effectivetypescript.com/2022/02/25/gentips-4-display/
*/
declare type Resolve<T> = T extends (...args: unknown[]) => unknown ? T : {
[K in keyof T]: T[K];
};
declare type CustomEvent<TRoomEvent extends Json> = {
connectionId: number;
event: TRoomEvent;
};
declare type UpdateDelta = {
type: "update";
} | {
type: "delete";
};
/**
* A LiveMap notification that is sent in-client to any subscribers whenever
* one or more of the values inside the LiveMap instance have changed.
*/
declare type LiveMapUpdates<TKey extends string, TValue extends Lson> = {
type: "LiveMap";
node: LiveMap<TKey, TValue>;
updates: {
[key: string]: UpdateDelta;
};
};
declare type LiveObjectUpdateDelta<O extends {
[key: string]: unknown;
}> = {
[K in keyof O]?: UpdateDelta | undefined;
};
/**
* A LiveObject notification that is sent in-client to any subscribers whenever
* one or more of the entries inside the LiveObject instance have changed.
*/
declare type LiveObjectUpdates<TData extends LsonObject> = {
type: "LiveObject";
node: LiveObject<TData>;
updates: LiveObjectUpdateDelta<TData>;
};
declare type LiveListUpdateDelta = {
index: number;
item: Lson;
type: "insert";
} | {
index: number;
type: "delete";
} | {
index: number;
previousIndex: number;
item: Lson;
type: "move";
} | {
index: number;
item: Lson;
type: "set";
};
/**
* A LiveList notification that is sent in-client to any subscribers whenever
* one or more of the items inside the LiveList instance have changed.
*/
declare type LiveListUpdates<TItem extends Lson> = {
type: "LiveList";
node: LiveList<TItem>;
updates: LiveListUpdateDelta[];
};
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;
};
/**
* The payload of notifications sent (in-client) when LiveStructures change.
* Messages of this kind are not originating from the network, but are 100%
* in-client.
*/
declare type StorageUpdate = LiveMapUpdates<string, Lson> | LiveObjectUpdates<LsonObject> | LiveListUpdates<Lson>;
declare type StorageCallback = (updates: StorageUpdate[]) => void;
declare type RoomInitializers<TPresence extends JsonObject, TStorage extends LsonObject> = Resolve<{
/**
* The initial Presence to use and announce when you enter the Room. The
* Presence is available on all users in the Room (me & others).
*/
initialPresence: TPresence | ((roomId: string) => TPresence);
/**
* The initial Storage to use when entering a new Room.
*/
initialStorage?: TStorage | ((roomId: string) => TStorage);
/**
* Whether or not the room connects to Liveblock servers. Default is true.
*
* Usually set to false when the client is used from the server to not call
* the authentication endpoint or connect via WebSocket.
*/
shouldInitiallyConnect?: boolean;
}>;
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<TPresence extends JsonObject, TStorage extends LsonObject = LsonObject, TUserMeta extends BaseUserMeta = BaseUserMeta, TRoomEvent extends Json = never>(roomId: string): Room<TPresence, TStorage, TUserMeta, TRoomEvent> | null;
/**
* Enters a room and returns it.
* @param roomId The id of the room
* @param options Optional. You can provide initializers for the Presence or Storage when entering the Room.
*/
enter<TPresence extends JsonObject, TStorage extends LsonObject = LsonObject, TUserMeta extends BaseUserMeta = BaseUserMeta, TRoomEvent extends Json = never>(roomId: string, options: RoomInitializers<TPresence, TStorage>): Room<TPresence, TStorage, TUserMeta, TRoomEvent>;
/**
* Leaves a room.
* @param roomId The id of the room
*/
leave(roomId: string): void;
};
/**
* Represents all the other users connected in the room. Treated as immutable.
*/
declare type Others<TPresence extends JsonObject, TUserMeta extends BaseUserMeta> = ReadonlyArrayWithLegacyMethods<User<TPresence, TUserMeta>>;
/**
* Represents a user connected in a room. Treated as immutable.

@@ -880,33 +616,25 @@ */

};
declare type AuthEndpointCallback = (room: string) => Promise<{
token: string;
}>;
declare type AuthEndpoint = string | AuthEndpointCallback;
declare type Polyfills = {
atob?: (data: string) => string;
fetch?: typeof fetch;
WebSocket?: any;
};
/**
* 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.
* Represents all the other users connected in the room. Treated as immutable.
*/
declare type ClientOptions = {
throttle?: number;
polyfills?: Polyfills;
/**
* Backward-compatible way to set `polyfills.fetch`.
*/
fetchPolyfill?: Polyfills["fetch"];
/**
* Backward-compatible way to set `polyfills.WebSocket`.
*/
WebSocketPolyfill?: Polyfills["WebSocket"];
} & ({
publicApiKey: string;
authEndpoint?: never;
declare type Others<TPresence extends JsonObject, TUserMeta extends BaseUserMeta> = ReadonlyArrayWithLegacyMethods<User<TPresence, TUserMeta>>;
declare type OthersEvent<TPresence extends JsonObject, TUserMeta extends BaseUserMeta> = {
type: "leave";
user: User<TPresence, TUserMeta>;
} | {
publicApiKey?: never;
authEndpoint: AuthEndpoint;
});
type: "enter";
user: User<TPresence, TUserMeta>;
} | {
type: "update";
user: User<TPresence, TUserMeta>;
updates: Partial<TPresence>;
} | {
type: "reset";
};
declare type CustomEvent<TRoomEvent extends Json> = {
connectionId: number;
event: TRoomEvent;
};
declare type Connection = {

@@ -934,15 +662,2 @@ state: "closed";

declare type ConnectionState = Connection["state"];
declare type OthersEvent<TPresence extends JsonObject, TUserMeta extends BaseUserMeta> = {
type: "leave";
user: User<TPresence, TUserMeta>;
} | {
type: "enter";
user: User<TPresence, TUserMeta>;
} | {
type: "update";
user: User<TPresence, TUserMeta>;
updates: Partial<TPresence>;
} | {
type: "reset";
};
interface History {

@@ -1025,2 +740,10 @@ /**

}
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;
};
declare type Room<TPresence extends JsonObject, TStorage extends LsonObject, TUserMeta extends BaseUserMeta, TRoomEvent extends Json> = {

@@ -1251,33 +974,71 @@ /**

};
declare enum WebsocketCloseCodes {
CLOSE_ABNORMAL = 1006,
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,
MAX_NUMBER_OF_CONCURRENT_CONNECTIONS_PER_ROOM = 4005,
CLOSE_WITHOUT_RETRY = 4999
}
declare type Polyfills = {
atob?: (data: string) => string;
fetch?: typeof fetch;
WebSocket?: any;
};
declare type RoomInitializers<TPresence extends JsonObject, TStorage extends LsonObject> = Resolve<{
/**
* The initial Presence to use and announce when you enter the Room. The
* Presence is available on all users in the Room (me & others).
*/
initialPresence: TPresence | ((roomId: string) => TPresence);
/**
* The initial Storage to use when entering a new Room.
*/
initialStorage?: TStorage | ((roomId: string) => TStorage);
/**
* Whether or not the room connects to Liveblock servers. Default is true.
*
* Usually set to false when the client is used from the server to not call
* the authentication endpoint or connect via WebSocket.
*/
shouldInitiallyConnect?: boolean;
}>;
declare type AppOnlyAuthToken = {
appId: string;
roomId?: never;
scopes: string[];
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<TPresence extends JsonObject, TStorage extends LsonObject = LsonObject, TUserMeta extends BaseUserMeta = BaseUserMeta, TRoomEvent extends Json = never>(roomId: string): Room<TPresence, TStorage, TUserMeta, TRoomEvent> | null;
/**
* Enters a room and returns it.
* @param roomId The id of the room
* @param options Optional. You can provide initializers for the Presence or Storage when entering the Room.
*/
enter<TPresence extends JsonObject, TStorage extends LsonObject = LsonObject, TUserMeta extends BaseUserMeta = BaseUserMeta, TRoomEvent extends Json = never>(roomId: string, options: RoomInitializers<TPresence, TStorage>): Room<TPresence, TStorage, TUserMeta, TRoomEvent>;
/**
* Leaves a room.
* @param roomId The id of the room
*/
leave(roomId: string): void;
};
declare type RoomAuthToken = {
appId: string;
roomId: string;
scopes: string[];
actor: number;
maxConnectionsPerRoom?: number;
id?: string;
info?: Json;
};
declare type AuthToken = AppOnlyAuthToken | RoomAuthToken;
declare function isAppOnlyAuthToken(data: JsonObject): data is AppOnlyAuthToken;
declare function isRoomAuthToken(data: JsonObject): data is RoomAuthToken;
declare function isAuthToken(data: JsonObject): data is AuthToken;
declare type AuthEndpoint = string | ((room: string) => Promise<{
token: string;
}>);
/**
* 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.
*/
declare type ClientOptions = {
throttle?: number;
polyfills?: Polyfills;
/**
* Backward-compatible way to set `polyfills.fetch`.
*/
fetchPolyfill?: Polyfills["fetch"];
/**
* Backward-compatible way to set `polyfills.WebSocket`.
*/
WebSocketPolyfill?: Polyfills["WebSocket"];
} & ({
publicApiKey: string;
authEndpoint?: never;
} | {
publicApiKey?: never;
authEndpoint: AuthEndpoint;
});
/**
* Create a client that will be responsible to communicate with liveblocks servers.

@@ -1309,3 +1070,43 @@ *

declare function lsonToJson(value: Lson): Json;
declare function patchLiveObjectKey<O extends LsonObject, K extends keyof O, V extends Json>(liveObject: LiveObject<O>, key: K, prev?: V, next?: V): void;
declare function legacy_patchImmutableObject<S extends JsonObject>(state: S, updates: StorageUpdate[]): S;
/**
* Helper function that can be used to implement exhaustive switch statements
* with TypeScript. Example usage:
*
* type Fruit = "🍎" | "🍌";
*
* switch (fruit) {
* case "🍎":
* case "🍌":
* return doSomething();
*
* default:
* return assertNever(fruit, "Unknown fruit");
* }
*
* If now the Fruit union is extended (i.e. add "πŸ’"), TypeScript will catch
* this *statically*, rather than at runtime, and force you to handle the
* πŸ’ case.
*/
declare function assertNever(_value: never, errmsg: string): never;
/**
* Asserts that a given value is non-nullable. This is similar to TypeScript's
* `!` operator, but will throw an error at runtime (dev-mode only) indicating
* an incorrect assumption.
*
* Instead of:
*
* foo!.bar
*
* Use:
*
* nn(foo).bar
*
*/
declare function nn<T>(value: T, errmsg?: string): NonNullable<T>;
/**
* Displays a deprecation warning in the dev console. Only in dev mode, and

@@ -1336,5 +1137,7 @@ * only once per message/key. In production, this is a no-op.

declare function lsonToJson(value: Lson): Json;
declare function patchLiveObjectKey<O extends LsonObject, K extends keyof O, V extends Json>(liveObject: LiveObject<O>, key: K, prev?: V, next?: V): void;
declare function legacy_patchImmutableObject<S extends JsonObject>(state: S, updates: StorageUpdate[]): S;
/**
* Freezes the given argument, but only in development builds. In production
* builds, this is a no-op for performance reasons.
*/
declare const freeze: typeof Object.freeze;

@@ -1355,7 +1158,2 @@ declare function makePosition(before?: string, after?: string): string;

/**
* Freezes the given argument, but only in development builds. In production
* builds, this is a no-op for performance reasons.
*/
declare const freeze: typeof Object.freeze;
declare function isPlainObject(blob: unknown): blob is {

@@ -1374,3 +1172,211 @@ [key: string]: unknown;

declare type IdTuple<T> = [id: string, value: T];
declare enum CrdtType {
OBJECT = 0,
LIST = 1,
MAP = 2,
REGISTER = 3
}
declare type SerializedCrdt = SerializedRootObject | SerializedChild;
declare type SerializedChild = SerializedObject | SerializedList | SerializedMap | SerializedRegister;
declare type SerializedRootObject = {
type: CrdtType.OBJECT;
data: JsonObject;
parentId?: never;
parentKey?: never;
};
declare type SerializedObject = {
type: CrdtType.OBJECT;
parentId: string;
parentKey: string;
data: JsonObject;
};
declare type SerializedList = {
type: CrdtType.LIST;
parentId: string;
parentKey: string;
};
declare type SerializedMap = {
type: CrdtType.MAP;
parentId: string;
parentKey: string;
};
declare type SerializedRegister = {
type: CrdtType.REGISTER;
parentId: string;
parentKey: string;
data: Json;
};
declare function isRootCrdt(crdt: SerializedCrdt): crdt is SerializedRootObject;
declare function isChildCrdt(crdt: SerializedCrdt): crdt is SerializedChild;
declare enum ServerMsgCode {
UPDATE_PRESENCE = 100,
USER_JOINED = 101,
USER_LEFT = 102,
BROADCASTED_EVENT = 103,
ROOM_STATE = 104,
INITIAL_STORAGE_STATE = 200,
UPDATE_STORAGE = 201
}
/**
* Messages that can be sent from the server to the client.
*/
declare type ServerMsg<TPresence extends JsonObject, TUserMeta extends BaseUserMeta, TRoomEvent extends Json> = UpdatePresenceServerMsg<TPresence> | UserJoinServerMsg<TUserMeta> | UserLeftServerMsg | BroadcastedEventServerMsg<TRoomEvent> | RoomStateServerMsg<TUserMeta> | InitialDocumentStateServerMsg | UpdateStorageServerMsg;
/**
* Sent by the WebSocket server and broadcasted to all clients to announce that
* a User updated their presence. For example, when a user moves their cursor.
*
* In most cases, the data payload will only include the fields from the
* Presence that have been changed since the last announcement. However, after
* a new user joins a room, a "full presence" will be announced so the newly
* connected user will get each other's user full presence at least once. In
* those cases, the `targetActor` field indicates the newly connected client,
* so all other existing clients can ignore this broadcasted message.
*/
declare type UpdatePresenceServerMsg<TPresence extends JsonObject> = {
type: ServerMsgCode.UPDATE_PRESENCE;
/**
* The User whose Presence has changed.
*/
actor: number;
/**
* When set, signifies that this is a Full Presenceβ„’ update, not a patch.
*
* The numeric value itself no longer has specific meaning. Historically,
* this field was intended so that clients could ignore these broadcasted
* full presence messages, but it turned out that getting a full presence
* "keyframe" from time to time was useful.
*
* So nowadays, the presence (pun intended) of this `targetActor` field
* is a backward-compatible way of expressing that the `data` contains
* all presence fields, and isn't a partial "patch".
*/
targetActor: number;
/**
* The partial or full Presence of a User. If the `targetActor` field is set,
* this will be the full Presence, otherwise it only contain the fields that
* have changed since the last broadcast.
*/
data: TPresence;
} | {
type: ServerMsgCode.UPDATE_PRESENCE;
/**
* The User whose Presence has changed.
*/
actor: number;
/**
* Not set for partial presence updates.
*/
targetActor?: undefined;
/**
* A partial Presence patch to apply to the User. It will only contain the
* fields that have changed since the last broadcast.
*/
data: Partial<TPresence>;
};
/**
* Sent by the WebSocket server and broadcasted to all clients to announce that
* a new User has joined the Room.
*/
declare type UserJoinServerMsg<TUserMeta extends BaseUserMeta> = {
type: ServerMsgCode.USER_JOINED;
actor: number;
/**
* The id of the User that has been set in the authentication endpoint.
* Useful to get additional information about the connected user.
*/
id: TUserMeta["id"];
/**
* Additional user information that has been set in the authentication
* endpoint.
*/
info: TUserMeta["info"];
/**
* Permissions that the user has in the Room.
*/
scopes: string[];
};
/**
* Sent by the WebSocket server and broadcasted to all clients to announce that
* a new User has left the Room.
*/
declare type UserLeftServerMsg = {
type: ServerMsgCode.USER_LEFT;
actor: number;
};
/**
* Sent by the WebSocket server and broadcasted to all clients to announce that
* a User broadcasted an Event to everyone in the Room.
*/
declare type BroadcastedEventServerMsg<TRoomEvent extends Json> = {
type: ServerMsgCode.BROADCASTED_EVENT;
/**
* The User who broadcasted the Event.
*/
actor: number;
/**
* The arbitrary payload of the Event. This can be any JSON value. Clients
* will have to manually verify/decode this event.
*/
event: TRoomEvent;
};
/**
* Sent by the WebSocket server to a single client in response to the client
* joining the Room, to provide the initial state of the Room. The payload
* includes a list of all other Users that already are in the Room.
*/
declare type RoomStateServerMsg<TUserMeta extends BaseUserMeta> = {
type: ServerMsgCode.ROOM_STATE;
users: {
[actor: number]: TUserMeta & {
scopes: string[];
};
};
};
/**
* Sent by the WebSocket server to a single client in response to the client
* joining the Room, to provide the initial Storage state of the Room. The
* payload includes the entire Storage document.
*/
declare type InitialDocumentStateServerMsg = {
type: ServerMsgCode.INITIAL_STORAGE_STATE;
items: IdTuple<SerializedCrdt>[];
};
/**
* Sent by the WebSocket server and broadcasted to all clients to announce that
* a change occurred in the Storage document.
*
* The payload of this message contains a list of Ops (aka incremental
* mutations to make to the initially loaded document).
*/
declare type UpdateStorageServerMsg = {
type: ServerMsgCode.UPDATE_STORAGE;
ops: Op[];
};
/**
* Lookup table for nodes (= SerializedCrdt values) by their IDs.
*/
declare type NodeMap = Map<string, // Node ID
SerializedCrdt>;
/**
* Reverse lookup table for all child nodes (= list of SerializedCrdt values)
* by their parent node's IDs.
*/
declare type ParentToChildNodeMap = Map<string, // Parent's node ID
IdTuple<SerializedChild>[]>;
declare enum WebsocketCloseCodes {
CLOSE_ABNORMAL = 1006,
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,
MAX_NUMBER_OF_CONCURRENT_CONNECTIONS_PER_ROOM = 4005,
CLOSE_WITHOUT_RETRY = 4999
}
/**
* PRIVATE / INTERNAL APIS

@@ -1377,0 +1383,0 @@ * -----------------------

{
"name": "@liveblocks/core",
"version": "0.19.0-beta0",
"version": "0.19.0",
"description": "Shared code and foundational internals for Liveblocks",

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

Sorry, the diff of this file is too big to display

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