UNPKG

@textea/y-socket.io

Version:
109 lines (100 loc) 4.15 kB
import { Server } from 'http'; import { Socket, Server as Server$1 } from 'socket.io'; import { Room as Room$1 } from 'socket.io-adapter'; import { Awareness } from 'y-protocols/awareness'; import * as Y from 'yjs'; import { CorsOptions, CorsOptionsDelegate } from 'cors'; import { ServerOptions } from 'engine.io/build/server'; declare type RoomName = Room$1; declare type ClientId = Awareness['clientID']; interface DefaultClientData { } declare type EventHandler = (...args: any[]) => void; declare type DefaultEvents = { [eventName: string]: EventHandler; }; declare type EventNameWithScope<Scope extends string, Type extends string = string> = `${Scope}:${Type}`; declare type DataScope = 'data'; declare type RoomScope = 'room'; declare type YDocScope = 'doc'; declare type AwarenessScope = 'awareness'; declare type ObservableScope = YDocScope | AwarenessScope; declare type ValidEventScope = DataScope | RoomScope | ObservableScope; declare type ValidateEvents<Events extends DefaultEvents & { [EventName in keyof Events]: EventName extends EventNameWithScope<infer EventScope> ? EventScope extends ValidEventScope ? Events[EventName] : never : Events[EventName]; }> = Events; declare type DefaultServerToClientEvents<ClientData extends DefaultClientData = DefaultClientData> = ValidateEvents<{ ['data:update']: (data: ClientData) => void; ['doc:diff']: (diff: ArrayBuffer) => void; ['doc:update']: (updateV2: ArrayBuffer) => void; ['awareness:update']: (update: ArrayBuffer) => void; }>; interface ServerToClientEvents<ClientData extends DefaultClientData = DefaultClientData> extends DefaultServerToClientEvents<ClientData> { } declare type DefaultClientToServerEvents = ValidateEvents<{ ['room:close']: () => void; ['doc:diff']: (diff: Uint8Array) => void; ['doc:update']: (updateV2: Uint8Array, callback?: () => void) => void; ['awareness:update']: (update: Uint8Array) => void; }>; interface ClientToServerEvents extends DefaultClientToServerEvents { } interface Persistence { bindState: (roomName: RoomName, doc: Y.Doc) => Promise<void>; writeState: (roomName: RoomName, doc: Y.Doc) => Promise<void>; } declare type UserId = string | ClientId; declare type GetUserId = (socket: Omit<Socket, 'userId'>) => UserId | Error; interface Room { owner: UserId; awareness: Awareness; getDoc: () => Promise<Y.Doc>; destroy: () => Promise<void>; } declare type RoomMap = Map<RoomName, Room>; declare module 'socket.io' { /** * Data related to yjs */ interface SocketYjsData { roomMap: RoomMap; roomName: RoomName; clientId: ClientId; } interface Socket { yjs: SocketYjsData; userId: UserId; } } interface Options { /** * Handle auth and room permission */ getUserId?: GetUserId; persistence?: Persistence; /** * @default false */ autoDeleteRoom?: boolean; /** * cors settings */ cors?: CorsOptions | CorsOptionsDelegate; allowRequest?: ServerOptions['allowRequest']; } declare type CreateSocketIOServer = <ClientData extends DefaultClientData = DefaultClientData>(httpServer: Server, options?: Options) => Server$1<ClientToServerEvents, ServerToClientEvents<ClientData>>; /** * There are four scenarios: * 1. Signed User share sheet to specified person with write permission (both side need authorization) * 2. Signed User share sheet to specified person with only view permission (both side need authorization) * 3. Signed User share sheet to everyone with write permission (only one side need authorization) * 4. Signed User share sheet to everyone with only view permission (only one side need authorization) * * If sheet owner close sharing (or disable sharing), others won't see the sheet anymore, * which means we will delete the sheet in their browser. * * We only consider scenario 3 for now, because It's easy to implement */ declare const createSocketIOServer: CreateSocketIOServer; declare const createSimpleServer: (options?: Options) => Server; export { Options, createSimpleServer, createSocketIOServer };