@directus/api
Version:
Directus is a real-time API and App dashboard for managing SQL database content
126 lines (125 loc) • 4.83 kB
TypeScript
import { type Accountability, type Item, type PrimaryKey, type WebSocketClient } from '@directus/types';
import { type BaseServerMessage, type ClientID, type Color, type ServerError } from '@directus/types/collab';
import { Messenger } from './messenger.js';
import type { JoinMessage, PermissionClient } from './types.js';
/**
* Store and manage all active collaborative editing rooms
*/
export declare class RoomManager {
rooms: Record<string, Room>;
messenger: Messenger;
constructor(messenger?: Messenger);
/**
* Create a new collaborative editing room or return an existing one matching collection, item and version.
*/
createRoom(collection: string, item: PrimaryKey | null, version: string | null, initialChanges?: Item): Promise<Room>;
/**
* Remove a room from local memory
*/
removeRoom(uid: string): void;
/**
* Get an existing room by UID.
* If the room is not part of the local rooms, it will be loaded from shared memory.
* The room will not be persisted in local memory.
*/
getRoom(uid: string): Promise<Room | undefined>;
/**
* Get all rooms a client is currently in from local memory
*/
getClientRooms(uid: ClientID): Promise<Room[]>;
/**
* Returns all clients that are part of a room in the local memory
*/
getLocalRoomClients(): Promise<RoomClient[]>;
/**
* Remove empty rooms from local memory
*/
cleanupRooms(uids?: string[]): Promise<void>;
/**
* Forcefully close all local rooms and notify clients.
*/
terminateAll(): Promise<void>;
}
type RoomClient = {
uid: ClientID;
accountability: Accountability;
color: Color;
};
type RoomData = {
uid: string;
collection: string;
item: PrimaryKey | null;
version: string | null;
changes: Item;
clients: RoomClient[];
focuses: Record<ClientID, string>;
};
/**
* Represents a single collaborative editing room for a specific item
*/
export declare class Room {
uid: string;
collection: string;
item: PrimaryKey | null;
version: string | null;
initialChanges: Item | undefined;
messenger: Messenger;
store: <T>(callback: (store: import("./store.js").RedisStore<RoomData>) => Promise<T>) => Promise<T>;
onUpdateHandler: (meta: Record<string, any>, context?: any) => Promise<void>;
onDeleteHandler: (meta: Record<string, any>, context?: any) => Promise<void>;
constructor(uid: string, collection: string, item: PrimaryKey | null, version: string | null, initialChanges?: Item, messenger?: Messenger);
/**
* Ensures that foundational room state (metadata) exists in shared memory even after restarts
*/
ensureInitialized(): Promise<void>;
getDisplayName(): string;
getClients(): Promise<RoomClient[]>;
getFocuses(): Promise<Record<ClientID, string>>;
getChanges(): Promise<Item>;
hasClient(id: ClientID): Promise<boolean>;
getFocusByUser(id: ClientID): Promise<string | undefined>;
getFocusByField(field: string): Promise<string | undefined>;
/**
* Client requesting to join a room. If the client hasn't entered the room already, add a new client.
* Otherwise all users just will be informed again that the user has joined.
*/
join(client: WebSocketClient, color?: JoinMessage['color']): Promise<void>;
/**
* Leave the room
*/
leave(uid: ClientID): Promise<void>;
/**
* Propagate an update to other clients
*/
update(sender: WebSocketClient, changes: Record<string, unknown>): Promise<void>;
/**
* Propagate an unset to other clients
*/
unset(sender: PermissionClient, field: string): Promise<void>;
/**
* Discard specified changes in the room and propagate to other clients
*/
discard(fields: string[]): Promise<void>;
/**
* Atomically acquire or release focus and propagate focus state to other clients
*/
focus(sender: PermissionClient, field: string | null): Promise<boolean>;
sendAll(message: BaseServerMessage): Promise<void>;
sendExcluding(message: BaseServerMessage, exclude: ClientID): Promise<void>;
send(client: ClientID, message: BaseServerMessage): void;
/**
* Close the room and clean up shared state
*
* @param options.force If true, close the room even if active clients are present
* @param options.reason Optional reason to be sent to clients
* @param options.terminate If true, forcefully terminate the client connection after closing
*/
close(options?: {
force?: boolean;
reason?: ServerError;
terminate?: boolean;
}): Promise<boolean>;
dispose(): void;
}
export declare function getRoomHash(collection: string, item: PrimaryKey | null, version: string | null): string;
export {};