UNPKG

@directus/api

Version:

Directus is a real-time API and App dashboard for managing SQL database content

126 lines (125 loc) 4.83 kB
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 {};