@liveblocks/core
Advanced tools
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
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
185101
5730