@pluv/client 0.0.0-canary-20261027014949

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.mjs","names":["ConnectionState","ConnectionState"],"sources":["../src/AbstractStorageStore.ts","../src/constants.ts","../src/utils/assertSerializingSchema.ts","../src/CrdtManager.ts","../src/CrdtNotifier.ts","../src/EventNotifier.ts","../src/ListenerManager.ts","../src/PendingRequestManager.ts","../src/StateNotifier.ts","../src/StorageStore.ts","../src/StorageSync.ts","../src/utils/assertExhaustive.ts","../src/utils/parsePluvSchema.ts","../src/utils/pickBy.ts","../src/UsersManager.ts","../src/UsersNotifier.ts","../src/utils/sequenceCommit.ts","../src/utils/debounce.ts","../src/utils/inRange.ts","../src/PluvRoom.ts","../src/PluvClient.ts","../src/createClient.ts","../src/MockedRoom.ts"],"sourcesContent":["export abstract class AbstractStorageStore {\n public room: string;\n\n constructor(room: string) {\n this.room = room;\n }\n\n public abstract addUpdate(update: string): Promise<void>;\n\n public abstract destroy(): Promise<void>;\n\n public abstract flatten(encodedState: string): Promise<void>;\n\n public abstract getShouldFlatten(): Promise<boolean>;\n\n public abstract getUpdates(start?: number): Promise<readonly string[]>;\n\n public abstract initialize(): Promise<void>;\n}\n","export const MAX_PRESENCE_SIZE_BYTES = 512;\nexport const PLUV_PRESENCE_META_KEY = \"__pluv\";\nexport const LIST_USERS_DEFAULT_LIMIT = 50;\nexport const LIST_USERS_MAX_LIMIT = 100;\nexport const LIST_USERS_TIMEOUT_MS = 10_000;\n","const getJsonSchemaProducer = (\n schema: unknown,\n): { input: (options?: { target?: string }) => unknown } | null => {\n const jsonSchema = (schema as { \"~standard\"?: { jsonSchema?: { input?: unknown } } })?.[\n \"~standard\"\n ]?.jsonSchema;\n\n if (!jsonSchema || typeof jsonSchema.input !== \"function\") return null;\n\n return jsonSchema as { input: (options?: { target?: string }) => unknown };\n};\n\nexport const assertSerializingSchema = (schema: unknown): void => {\n if (!getJsonSchemaProducer(schema)) {\n throw new Error(\n \"Schema must implement Standard Schema and Standard JSON Schema on the same object (e.g. Zod 4.2+ or ArkType).\",\n );\n }\n};\n","import type { AbstractCrdtDocFactory, InferDocLike, InferSeed, InferStorage } from \"@pluv/crdt\";\nimport { noop } from \"@pluv/crdt\";\n\nexport type CrdtManagerOptions<TCrdt extends AbstractCrdtDocFactory<any, any, any, any>> = {\n storage?: TCrdt;\n initialStorage?: InferSeed<TCrdt>;\n};\n\ninterface CrdtManagerInitializeParams {\n origin?: any;\n update: string | readonly string[];\n}\n\ninterface ApplyUpdateParams {\n origin?: any;\n update: string | readonly string[];\n}\n\nexport class CrdtManager<TCrdt extends AbstractCrdtDocFactory<any, any, any, any>> {\n public doc: InferDocLike<TCrdt>;\n public initialized: boolean = false;\n\n private readonly _docFactory: TCrdt;\n\n constructor(options: CrdtManagerOptions<TCrdt>) {\n const { initialStorage, storage = noop.doc() as TCrdt } = options;\n\n this._docFactory = storage.getFactory(initialStorage) as TCrdt;\n this.doc = this._docFactory.getEmpty() as InferDocLike<TCrdt>;\n }\n\n /**\n * !HACK\n * @description If this is called before the doc is initialized. Omit the\n * update. This unfortunately means updates can be dropped entirely\n * @date June 13, 2023\n */\n public applyUpdate(params: ApplyUpdateParams): this {\n const { origin, update } = params;\n\n if (!this.initialized) return this;\n\n const updates: readonly string[] = typeof update === \"string\" ? [update] : update;\n\n this._applyDocUpdates(this.doc, updates, origin);\n\n return this;\n }\n\n public destroy(): void {\n this.initialized = false;\n this.doc.destroy();\n this.doc = this._docFactory.getEmpty() as InferDocLike<TCrdt>;\n }\n\n public get<TKey extends keyof InferStorage<TCrdt>>(key: TKey): InferStorage<TCrdt>[TKey] {\n return this.doc.get(key);\n }\n\n public getInitialState(): string {\n return this._docFactory.getInitialized().getEncodedState();\n }\n\n public initialize(params: CrdtManagerInitializeParams): this {\n const { origin, update } = params;\n\n /**\n * !HACK\n * @description If the doc was already initialized, we don't want to re-initialize\n * the doc and overwrite what's already there. Skip the initialization and log a\n * warning.\n * @date May 7, 2025\n */\n if (this.initialized) {\n console.warn(\"Attempted to initialize storage multiple times\");\n return this;\n }\n\n /**\n * !HACK\n * @description If the doc is already populated, somehow we're attempting to overwrite\n * a doc that was presumably initialized but not identified as initialized. Skip the\n * initialization and log a warning.\n * @date May 7, 2025\n */\n if (!this.doc.isEmpty()) {\n console.warn(\"Attempted to initialize over a non-empty storage\");\n return this;\n }\n\n const updates = typeof update === \"string\" ? [update] : update;\n\n if (!updates.length) return this;\n\n this.doc = this._applyDocUpdates(this.doc, updates, origin).rebuildStorage();\n this.initialized = true;\n\n return this;\n }\n\n public resolveEncodedState(updates: string | string[] | readonly string[]): string | null {\n return this._docFactory.resolveEncodedState(updates);\n }\n\n private _applyDocUpdates(\n doc: InferDocLike<TCrdt>,\n updates: readonly string[],\n origin?: string,\n ): InferDocLike<TCrdt> {\n doc.transact(() => {\n doc.batchApplyEncodedState({ origin, updates });\n }, origin);\n\n return doc;\n }\n}\n","import type { StorageSubscriptionCallback } from \"@pluv/types\";\nimport type { Subject } from \"wonka\";\nimport { makeSubject, subscribe } from \"wonka\";\n\nexport class CrdtNotifier<TJson extends Record<string, any>> {\n public rootSubject = makeSubject<TJson>();\n\n public subjects = new Map<keyof TJson, Subject<TJson[keyof TJson]> | null>();\n\n public subject<TKey extends keyof TJson>(key: TKey): Subject<TJson[TKey]> {\n const subject = this.subjects.get(key);\n\n if (subject) {\n return subject as Subject<TJson[TKey]>;\n }\n\n const newSubject = makeSubject<TJson[TKey]>();\n\n this.subjects.set(key, newSubject);\n\n return newSubject as Subject<TJson[TKey]>;\n }\n\n public subcribeRoot(callback: (value: TJson) => void): () => void {\n const subscription = subscribe(callback)(this.rootSubject.source);\n\n return () => {\n subscription.unsubscribe();\n };\n }\n\n public subscribe<TKey extends keyof TJson>(\n key: TKey,\n callback: StorageSubscriptionCallback<TJson, TKey>,\n ): () => void {\n const subject = this.subject(key);\n const subscription = subscribe(callback)(subject.source);\n\n return () => {\n subscription.unsubscribe();\n };\n }\n}\n","import type {\n EventNotifierSubscriptionCallback,\n Id,\n InferIOOutput,\n IOEventMessage,\n IOLike,\n} from \"@pluv/types\";\nimport type { Subject } from \"wonka\";\nimport { makeSubject, subscribe } from \"wonka\";\n\nexport class EventNotifier<TIO extends IOLike> {\n public subjects = new Map<\n keyof InferIOOutput<TIO>,\n Subject<Id<IOEventMessage<TIO, keyof InferIOOutput<TIO>>>>\n >();\n\n public subject<TEvent extends keyof InferIOOutput<TIO>>(\n name: TEvent,\n ): Subject<Id<IOEventMessage<TIO, TEvent>>> {\n const subject = this.subjects.get(name);\n\n if (subject) return subject;\n\n const newSubject = makeSubject<Id<IOEventMessage<TIO, TEvent>>>();\n\n this.subjects.set(name, newSubject);\n\n return newSubject;\n }\n\n public subscribe<TEvent extends keyof InferIOOutput<TIO>>(\n name: TEvent,\n callback: EventNotifierSubscriptionCallback<TIO, TEvent>,\n ): () => void {\n const subject = this.subject(name);\n const subscription = subscribe(callback)(subject.source);\n\n return () => {\n subscription.unsubscribe();\n };\n }\n}\n","import { makeSubject, subscribe, TypeOfSource } from \"wonka\";\n\nexport class ListenerManager {\n public subjects = {\n close: makeSubject<CloseEvent>(),\n error: makeSubject<Event>(),\n message: makeSubject<MessageEvent<any>>(),\n open: makeSubject<Event>(),\n };\n\n public subscribe<TKind extends keyof typeof this.subjects>(\n kind: TKind,\n callback: (event: TypeOfSource<(typeof this.subjects)[TKind][\"source\"]>) => void,\n ): () => void {\n const source = this.subjects[kind]?.source;\n\n if (!source) return () => undefined;\n\n const subscription = subscribe(callback)(source as any);\n\n return () => {\n subscription.unsubscribe();\n };\n }\n}\n","type PendingRequest = {\n onAbort: () => unknown;\n resolve: (result: unknown) => void;\n timeoutId: ReturnType<typeof setTimeout>;\n};\n\n/**\n * Correlate in-flight request ids to replies on a multiplexed socket.\n */\nexport class PendingRequestManager {\n private readonly _waiters = new Map<string, PendingRequest>();\n\n public get size(): number {\n return this._waiters.size;\n }\n\n public request<TResult>(params: {\n onAbort: () => TResult;\n onTimeout: () => TResult;\n timeoutMs: number;\n }): { promise: Promise<TResult>; requestId: string } {\n const requestId = globalThis.crypto.randomUUID();\n const promise = new Promise<TResult>((resolve) => {\n const timeoutId = setTimeout(() => {\n this.complete(requestId, params.onTimeout());\n }, params.timeoutMs);\n\n this._waiters.set(requestId, {\n onAbort: params.onAbort,\n resolve: resolve as (result: unknown) => void,\n timeoutId,\n });\n });\n\n return { promise, requestId };\n }\n\n public complete(requestId: string, result: unknown): boolean {\n const pending = this._waiters.get(requestId) ?? null;\n\n if (!pending) return false;\n\n this._waiters.delete(requestId);\n clearTimeout(pending.timeoutId);\n pending.resolve(result);\n\n return true;\n }\n\n public failAll(): void {\n Array.from(this._waiters.entries()).forEach(([requestId, pending]) => {\n this.complete(requestId, pending.onAbort());\n });\n }\n}\n","import type {\n Id,\n IOLike,\n RoomStats,\n StateNotifierSubjects,\n SubscriptionCallback,\n UserInfo,\n WebSocketState,\n} from \"@pluv/types\";\nimport { makeSubject, subscribe } from \"wonka\";\n\nexport class StateNotifier<TIO extends IOLike, TPresence extends Record<string, any> = {}> {\n public subjects: StateNotifierSubjects<TIO, TPresence> = {\n connection: makeSubject<Id<WebSocketState<TIO>>>(),\n \"my-presence\": makeSubject<TPresence>(),\n myself: makeSubject<Readonly<Id<UserInfo<TIO, TPresence>>> | null>(),\n others: makeSubject<readonly Id<UserInfo<TIO, TPresence>>[]>(),\n roomStats: makeSubject<RoomStats>(),\n \"storage-loaded\": makeSubject<true>(),\n };\n\n public subscribe<TSubject extends keyof StateNotifierSubjects<TIO, TPresence>>(\n name: TSubject,\n callback: SubscriptionCallback<TIO, TPresence, TSubject>,\n ): () => void {\n const source = this.subjects[name]?.source as any;\n\n if (!source) throw new Error(`Could not subscribe to source: ${name}`);\n\n const subscription = subscribe(callback)(source);\n\n return () => {\n subscription.unsubscribe();\n };\n }\n}\n","import { AbstractStorageStore } from \"./AbstractStorageStore\";\n\nexport class StorageStore extends AbstractStorageStore {\n public addUpdate() {\n return Promise.resolve();\n }\n\n public applyUpdates() {\n return Promise.resolve();\n }\n\n public destroy() {\n return Promise.resolve();\n }\n\n public flatten() {\n return Promise.resolve();\n }\n\n public getShouldFlatten() {\n return Promise.resolve(false);\n }\n\n public getUpdates() {\n return Promise.resolve([]);\n }\n\n public initialize() {\n return Promise.resolve();\n }\n}\n","/**\n * Holds remote storage updates until the document has loaded, and remembers when a catch-up\n * reply did not move the document.\n */\nexport class StorageSync {\n private _queue: string[] = [];\n private _ready = false;\n private _stalled = false;\n\n public get isReady(): boolean {\n return this._ready;\n }\n\n public hold(update: string): void {\n this._queue.push(update);\n }\n\n public markReady(): readonly string[] {\n this._ready = true;\n\n return this._takeQueue();\n }\n\n public clearStall(): void {\n this._stalled = false;\n }\n\n /**\n * @description The first time a catch-up reply does not move the document. Later calls\n * stay quiet until `clearStall()` or `reset()`.\n */\n public noteStall(): boolean {\n if (this._stalled) return false;\n\n this._stalled = true;\n\n return true;\n }\n\n public reset(): void {\n this._queue = [];\n this._ready = false;\n this._stalled = false;\n }\n\n private _takeQueue(): readonly string[] {\n const queued = this._queue.splice(0);\n\n if (queued.length) this.clearStall();\n\n return queued;\n }\n}\n","export const assertExhaustive = (value: never): never => {\n // oxlint-disable-next-line typescript/restrict-template-expressions\n throw new Error(`Unhandled value: ${value}`);\n};\n","import type { StandardSchemaV1 } from \"@pluv/types\";\n\nexport function parsePluvSchema<TData>(schema: StandardSchemaV1<any, TData>, data: unknown): TData {\n const result = schema[\"~standard\"].validate(data);\n\n if (result instanceof Promise) {\n throw new Error(\"Async schemas are not supported. Schema validate() must be synchronous.\");\n }\n\n if (result.issues) {\n const message = result.issues[0]?.message ?? \"Invalid input\";\n\n throw new Error(message);\n }\n\n return result.value as TData;\n}\n","export const pickBy = <T extends Record<string, any>>(\n obj: T,\n by: (value: T[keyof T]) => boolean,\n): Partial<T> => {\n const result: Partial<T> = {};\n const keys: (keyof T)[] = Object.keys(obj);\n\n for (let i = 0; i < keys.length; ++i) {\n const key = keys[i];\n const value = obj[key];\n\n if (by(value)) result[key] = value;\n }\n\n return result;\n};\n","import type {\n BaseIOEventRecord,\n IOLike,\n InferIOAuthorize,\n OperatorUser,\n ParticipantKind,\n ParticipantKindOptions,\n ParticipantKindsOptions,\n RoomStats,\n StandardSchemaV1,\n UserInfo,\n} from \"@pluv/types\";\nimport { PLUV_PRESENCE_META_KEY } from \"./constants\";\nimport type { PluvClientLimits } from \"./types\";\nimport { assertExhaustive } from \"./utils/assertExhaustive\";\nimport { parsePluvSchema } from \"./utils/parsePluvSchema\";\nimport { pickBy } from \"./utils/pickBy\";\n\nexport type Presence = Record<string, unknown>;\n\nexport type UsersManagerConfig<TPresence extends Record<string, any> = {}> = {\n initialPresence?: Record<string, any>;\n limits: PluvClientLimits;\n presence?: StandardSchemaV1<any, TPresence>;\n};\n\nexport type AddConnectionParams<TIO extends IOLike, TPresence extends Record<string, any> = {}> = {\n connectionId: string;\n data: UserInfo<TIO, TPresence>[\"data\"];\n kind: ParticipantKind;\n operator?: OperatorUser | null;\n presence?: TPresence;\n presenceSeq?: number | null;\n};\n\nexport type AddConnectionResult<TIO extends IOLike, TPresence extends Record<string, any> = {}> = {\n data: UserInfo<TIO, TPresence>;\n isMyself: boolean;\n presenceChanged: boolean;\n remaining: number;\n};\n\nexport type DeleteConnectionResult<\n TIO extends IOLike,\n TPresence extends Record<string, any> = {},\n> = {\n data: UserInfo<TIO, TPresence>;\n remaining: number;\n};\n\nexport type OthersSnapshotRow<TIO extends IOLike, TPresence extends Record<string, any> = {}> = {\n connectionIds: readonly string[];\n data: UserInfo<TIO, TPresence>[\"data\"];\n kind: ParticipantKind;\n operator?: OperatorUser | null;\n presence: TPresence | null;\n presenceSeq?: number | null;\n};\n\nexport type ApplyPresenceResult<TPresence extends Record<string, any> = {}> = {\n applied: boolean;\n presence: TPresence;\n};\n\ntype ClientKey = {\n kind: ParticipantKind;\n id: string;\n};\n\nexport class UsersManager<TIO extends IOLike, TPresence extends Record<string, any> = {}> {\n public readonly initialPresence: TPresence;\n\n private readonly _idMap = {\n fromConnectionId: new Map<string, ClientKey>(),\n fromClientKey: {\n operator: new Map<string, Set<string>>(),\n user: new Map<string, Set<string>>(),\n },\n };\n private _limits: PluvClientLimits;\n /**\n * @description This presence can be updated while the user is not\n * connected.\n */\n private _myPresence: TPresence;\n /**\n * @description This is only set when the user is connected.\n */\n private _myself: UserInfo<TIO, TPresence> | null = null;\n private _operators = new Map<string, UserInfo<TIO, TPresence>>();\n private _others = new Map<string, UserInfo<TIO, TPresence>>();\n private _presence: StandardSchemaV1<any, TPresence> | null = null;\n private _presenceSeqs = {\n operator: new Map<string, number | null>(),\n user: new Map<string, number | null>(),\n };\n /**\n * Own `$updatePresence` broadcasts not yet echoed on this connection.\n * Per-tab only; other tabs are a different connectionId.\n */\n private _localPresenceInFlight = 0;\n\n constructor(config: UsersManagerConfig<TPresence>) {\n const { initialPresence, limits, presence = null } = config;\n\n this._presence = presence;\n this._limits = limits;\n\n const resolved = presence\n ? parsePluvSchema(presence, initialPresence ?? {})\n : ((initialPresence ?? {}) as TPresence);\n\n this.initialPresence = resolved;\n this._myPresence = resolved;\n }\n\n public get myPresence(): TPresence {\n return this._myPresence;\n }\n\n public get myself(): UserInfo<TIO, TPresence> | null {\n return this._myself;\n }\n\n public addConnection(\n params: AddConnectionParams<TIO, TPresence>,\n ): AddConnectionResult<TIO, TPresence> {\n /**\n * @description Ensure that the presence is complete, so that it does not fail schema\n * validation\n * @date April 20, 2025\n */\n const cleaned = pickBy(params.presence ?? {}, (value) => typeof value !== \"undefined\");\n const presence = { ...this.initialPresence, ...cleaned } as TPresence;\n const info = this._toUserInfo(params, presence);\n const clientKey = this._clientKeyFromInfo(info);\n const myClientKey = this._myself ? this._clientKeyFromInfo(this._myself) : null;\n const remaining = this._setConnectionId(params.connectionId, clientKey).size;\n\n if (this._sameClientKey(myClientKey, clientKey)) {\n return {\n data: this._myself ?? info,\n isMyself: true,\n presenceChanged: false,\n remaining,\n };\n }\n\n const others = this._mapForKind(clientKey.kind);\n const other = others.get(clientKey.id);\n\n if (!other) {\n others.set(clientKey.id, info);\n this._setPresenceSeq(clientKey, params.presenceSeq ?? null);\n\n return {\n data: info,\n isMyself: false,\n presenceChanged: true,\n remaining,\n };\n }\n\n const presenceChanged = this._isNewerPresenceSeq(clientKey, params.presenceSeq);\n\n if (presenceChanged) {\n others.set(clientKey.id, info);\n this._setPresenceSeq(clientKey, params.presenceSeq);\n }\n\n return {\n data: others.get(clientKey.id) ?? info,\n isMyself: false,\n presenceChanged,\n remaining,\n };\n }\n\n public clearConnections(): void {\n this.removeMyself();\n this._operators.clear();\n this._others.clear();\n this._presenceSeqs.operator.clear();\n this._presenceSeqs.user.clear();\n this._localPresenceInFlight = 0;\n this._idMap.fromClientKey.operator.clear();\n this._idMap.fromClientKey.user.clear();\n this._idMap.fromConnectionId.clear();\n }\n\n public deleteConnection(connectionId: string): DeleteConnectionResult<TIO, TPresence> | null {\n const clientKey = this._clientKeyForConnection(connectionId);\n\n this._deleteConnectionId(connectionId);\n\n if (!clientKey) return null;\n\n const userInfo = this._getByClientKey(clientKey);\n\n if (!userInfo) return null;\n\n const remaining = this._getConnectionIds(clientKey)?.size ?? 0;\n const result: DeleteConnectionResult<TIO, TPresence> = {\n remaining,\n data: userInfo,\n };\n\n /**\n * @description A user may have multiple websocket connections open. If one connection is\n * dropped, the user may still be connected via another websocket (e.g. on anther browser\n * tab). In this case, we just want to remove the connection mapping for the connection\n * that is dropped, but keep the remaining connections and the user.\n * @date April 16, 2025\n */\n if (!remaining) {\n this._mapForKind(clientKey.kind).delete(clientKey.id);\n this._presenceSeqsForKind(clientKey.kind).delete(clientKey.id);\n }\n\n return result;\n }\n\n /**\n * Public participant id. Both kinds use `data.id`.\n */\n public getParticipantId(info: UserInfo<TIO, TPresence>): string {\n return this._clientKeyFromInfo(info).id;\n }\n\n public isMyselfConnection(connectionId: string): boolean {\n if (!this._myself) return false;\n\n return this._sameClientKey(\n this._clientKeyForConnection(connectionId),\n this._clientKeyFromInfo(this._myself),\n );\n }\n\n public getOther(\n userId: string,\n options?: ParticipantKindOptions,\n ): UserInfo<TIO, TPresence> | null {\n const kind = options?.kind ?? \"user\";\n\n switch (kind) {\n case \"user\":\n return this._others.get(userId) ?? null;\n case \"operator\":\n return this._operators.get(userId) ?? null;\n default:\n return assertExhaustive(kind);\n }\n }\n\n public getOtherByConnectionId(\n connectionId: string,\n options?: ParticipantKindsOptions,\n ): UserInfo<TIO, TPresence> | null {\n const clientKey = this._clientKeyForConnection(connectionId);\n\n if (!clientKey) return null;\n\n const info = this._getByClientKey(clientKey);\n\n if (!info) return null;\n\n const kinds = options?.kinds ?? [\"user\"];\n\n return kinds.includes(info.kind) ? info : null;\n }\n\n public getOthers(options?: ParticipantKindsOptions): readonly UserInfo<TIO, TPresence>[] {\n const kinds = options?.kinds ?? [\"user\"];\n const others: UserInfo<TIO, TPresence>[] = [];\n\n if (kinds.includes(\"user\")) others.push(...this._others.values());\n if (kinds.includes(\"operator\")) others.push(...this._operators.values());\n\n return others;\n }\n\n public getOccupancy(options?: ParticipantKindsOptions): RoomStats {\n const kinds = new Set(options?.kinds ?? [\"user\"]);\n const myselfKind = this._myself?.kind ?? \"user\";\n const includeMyself = !!this._myself && kinds.has(myselfKind);\n const myClientKey = this._myself ? this._clientKeyFromInfo(this._myself) : null;\n let connectionCount = 0;\n\n this._idMap.fromConnectionId.forEach((clientKey) => {\n const info = this._sameClientKey(clientKey, myClientKey)\n ? this._myself\n : this._getByClientKey(clientKey);\n\n if (info && kinds.has(info.kind)) connectionCount += 1;\n });\n\n const userCount =\n (kinds.has(\"user\") ? this._others.size : 0) +\n (kinds.has(\"operator\") ? this._operators.size : 0) +\n (includeMyself ? 1 : 0);\n\n return { connectionCount, userCount };\n }\n\n public beginLocalPresenceWrite(): void {\n this._localPresenceInFlight += 1;\n }\n\n /**\n * @returns Whether this own-connection echo should apply. Stale echoes\n * during a burst of local writes return false so they cannot rewind.\n */\n public ackOwnPresenceEcho(): boolean {\n if (this._localPresenceInFlight > 0) this._localPresenceInFlight -= 1;\n\n return this._localPresenceInFlight === 0;\n }\n\n public patchPresence(\n params: { connectionId: string } & BaseIOEventRecord<\n InferIOAuthorize<TIO>\n >[\"$presenceUpdated\"],\n ): ApplyPresenceResult<TPresence> | null {\n const { connectionId, session, user } = params;\n const { operator, presence: patch, seq } = session;\n const presenceSeq = seq.presence;\n const clientKey = this._clientKeyForConnection(connectionId);\n const myClientKey = this._myself ? this._clientKeyFromInfo(this._myself) : null;\n\n if (!clientKey) return null;\n\n if (this._sameClientKey(myClientKey, clientKey)) {\n if (!this._shouldApplyPresenceSeq(clientKey, presenceSeq)) {\n return { applied: false, presence: this._myself?.presence ?? this._myPresence };\n }\n\n return {\n applied: true,\n presence: this.updateMyPresence(patch as Partial<TPresence>, presenceSeq),\n };\n }\n\n const other = this._getByClientKey(clientKey);\n\n if (!other) return null;\n\n if (!this._shouldApplyPresenceSeq(clientKey, presenceSeq)) {\n return { applied: false, presence: other.presence };\n }\n\n const cleanedPatch = pickBy(patch ?? {}, (value) => typeof value !== \"undefined\");\n const cleanedPresence = pickBy(\n other.presence ?? {},\n (value) => typeof value !== \"undefined\",\n );\n const presence = {\n ...this.initialPresence,\n ...cleanedPresence,\n ...cleanedPatch,\n } as TPresence;\n const validated = this._presence ? parsePluvSchema(this._presence, presence) : presence;\n\n /**\n * !HACK\n * @description We're patching internal metadata back into the presence field so it doesn't\n * get stripped from validation\n * @date May 13, 2025\n */\n if (!!presence[PLUV_PRESENCE_META_KEY]) {\n (validated as any)[PLUV_PRESENCE_META_KEY] = presence[PLUV_PRESENCE_META_KEY];\n }\n\n this._mapForKind(clientKey.kind).set(clientKey.id, {\n ...other,\n data: user,\n operator,\n presence: validated,\n });\n this._setPresenceSeq(clientKey, presenceSeq);\n\n return { applied: true, presence: validated };\n }\n\n public pruneConnections(activeConnectionIds: ReadonlySet<string>): UserInfo<TIO, TPresence>[] {\n const myClientKey = this._myself ? this._clientKeyFromInfo(this._myself) : null;\n const left: UserInfo<TIO, TPresence>[] = [];\n\n Array.from(this._idMap.fromConnectionId.keys()).forEach((connectionId) => {\n if (activeConnectionIds.has(connectionId)) return;\n\n const clientKey = this._clientKeyForConnection(connectionId);\n\n if (!clientKey || this._sameClientKey(clientKey, myClientKey)) return;\n\n const deleted = this.deleteConnection(connectionId);\n\n if (deleted && !deleted.remaining) left.push(deleted.data);\n });\n\n return left;\n }\n\n public removeMyself(): void {\n if (!this._myself) return;\n\n const clientKey = this._clientKeyFromInfo(this._myself);\n const connectionIds = this._getConnectionIds(clientKey);\n\n connectionIds?.forEach((connectionId) => {\n this._idMap.fromConnectionId.delete(connectionId);\n });\n this._connectionsForKind(clientKey.kind).delete(clientKey.id);\n this._presenceSeqsForKind(clientKey.kind).delete(clientKey.id);\n this._localPresenceInFlight = 0;\n this._myself = null;\n }\n\n public replaceOthers(\n rows: readonly OthersSnapshotRow<TIO, TPresence>[],\n ): { id: string; kind: ParticipantKind }[] {\n const myClientKey = this._myself ? this._clientKeyFromInfo(this._myself) : null;\n const previousUsers = new Map(this._others);\n const previousOperators = new Map(this._operators);\n const previousUserSeqs = new Map(this._presenceSeqs.user);\n const previousOperatorSeqs = new Map(this._presenceSeqs.operator);\n\n Array.from(this._idMap.fromConnectionId.entries()).forEach(([connectionId, clientKey]) => {\n if (this._sameClientKey(clientKey, myClientKey)) return;\n\n this._idMap.fromConnectionId.delete(connectionId);\n });\n Array.from(this._idMap.fromClientKey.user.keys()).forEach((id) => {\n if (myClientKey?.kind === \"user\" && myClientKey.id === id) return;\n\n this._idMap.fromClientKey.user.delete(id);\n });\n Array.from(this._idMap.fromClientKey.operator.keys()).forEach((id) => {\n if (myClientKey?.kind === \"operator\" && myClientKey.id === id) return;\n\n this._idMap.fromClientKey.operator.delete(id);\n });\n this._others.clear();\n this._operators.clear();\n this._presenceSeqs.user.clear();\n this._presenceSeqs.operator.clear();\n\n if (myClientKey) {\n const mySeq = (() => {\n switch (myClientKey.kind) {\n case \"user\":\n return previousUserSeqs.get(myClientKey.id);\n case \"operator\":\n return previousOperatorSeqs.get(myClientKey.id);\n default:\n return assertExhaustive(myClientKey.kind);\n }\n })();\n\n if (mySeq !== undefined) this._setPresenceSeq(myClientKey, mySeq);\n }\n\n rows.forEach((row) => {\n const cleaned = pickBy(row.presence ?? {}, (value) => typeof value !== \"undefined\");\n const snapshotPresence = { ...this.initialPresence, ...cleaned } as TPresence;\n const info = this._toUserInfo(row, snapshotPresence);\n const clientKey = this._clientKeyFromInfo(info);\n const previous = (() => {\n switch (clientKey.kind) {\n case \"user\":\n return previousUsers.get(clientKey.id);\n case \"operator\":\n return previousOperators.get(clientKey.id);\n default:\n return assertExhaustive(clientKey.kind);\n }\n })();\n const previousSeq = (() => {\n switch (clientKey.kind) {\n case \"user\":\n return previousUserSeqs.get(clientKey.id);\n case \"operator\":\n return previousOperatorSeqs.get(clientKey.id);\n default:\n return assertExhaustive(clientKey.kind);\n }\n })();\n const snapshotNewer = this._isNewerPresenceSeqValue(previousSeq, row.presenceSeq);\n\n if (previous && !snapshotNewer) {\n this._mapForKind(previous.kind).set(clientKey.id, previous);\n this._setPresenceSeq(clientKey, previousSeq ?? null);\n } else {\n this._mapForKind(info.kind).set(clientKey.id, info);\n this._setPresenceSeq(clientKey, row.presenceSeq ?? null);\n }\n\n row.connectionIds.forEach((connectionId) => {\n this._setConnectionId(connectionId, clientKey);\n });\n });\n\n const left: { id: string; kind: ParticipantKind }[] = [];\n\n previousUsers.forEach((_, id) => {\n if (!this._others.has(id)) left.push({ id, kind: \"user\" });\n });\n previousOperators.forEach((_, id) => {\n if (!this._operators.has(id)) left.push({ id, kind: \"operator\" });\n });\n\n return left;\n }\n\n public setMyself(params: AddConnectionParams<TIO, TPresence>): void {\n const presence = params.presence ?? this.initialPresence;\n const info = this._toUserInfo(params, presence);\n const clientKey = this._clientKeyFromInfo(info);\n\n this._myself = info;\n this._myPresence = presence;\n this._setPresenceSeq(clientKey, params.presenceSeq ?? null);\n\n this._setConnectionId(params.connectionId, clientKey);\n }\n\n public setMyConnectionIds(connectionIds: readonly string[]): void {\n if (!this._myself) return;\n\n const clientKey = this._clientKeyFromInfo(this._myself);\n const previous = this._getConnectionIds(clientKey);\n\n previous?.forEach((connectionId) => {\n this._idMap.fromConnectionId.delete(connectionId);\n });\n this._connectionsForKind(clientKey.kind).delete(clientKey.id);\n\n connectionIds.forEach((connectionId) => {\n this._setConnectionId(connectionId, clientKey);\n });\n }\n\n public setPresence(\n connectionId: string,\n presence: TPresence,\n presenceSeq?: number | null,\n ): void {\n const clientKey = this._clientKeyForConnection(connectionId);\n const myClientKey = this._myself ? this._clientKeyFromInfo(this._myself) : null;\n\n if (!clientKey) return;\n if (!this._shouldApplyPresenceSeq(clientKey, presenceSeq)) return;\n\n if (this._sameClientKey(myClientKey, clientKey)) {\n if (!this._myself) return;\n\n this._myself.presence = presence;\n this._myPresence = presence;\n this._setPresenceSeq(clientKey, presenceSeq);\n\n return;\n }\n\n const other = this._getByClientKey(clientKey);\n\n if (!other) return;\n\n this._mapForKind(clientKey.kind).set(clientKey.id, { ...other, presence });\n this._setPresenceSeq(clientKey, presenceSeq);\n }\n\n /**\n * @description This method need not care about being connected. This is because a user should\n * be able to view and update their own presence without being online\n * @date April 20, 2025\n */\n public updateMyPresence(patch: Partial<TPresence>, presenceSeq?: number | null): TPresence {\n const cleanedPatch = pickBy(patch, (value) => typeof value !== \"undefined\");\n const cleanedPresence = pickBy(this._myPresence, (value) => typeof value !== \"undefined\");\n const updated = {\n ...this.initialPresence,\n ...cleanedPresence,\n ...cleanedPatch,\n } as TPresence;\n const bytes = new TextEncoder().encode(JSON.stringify(updated)).length;\n\n if (!!this._limits.presenceMaxSize && bytes > this._limits.presenceMaxSize) {\n throw new Error(\n `Large presence. Presence must be at most 512 bytes. Current size: ${bytes.toLocaleString()}`,\n );\n }\n\n this._myPresence = updated;\n\n if (!this._myself) return updated;\n\n this._myself.presence = updated;\n this._setPresenceSeq(this._clientKeyFromInfo(this._myself), presenceSeq);\n\n return updated;\n }\n\n private _toUserInfo(\n params: {\n data: UserInfo<TIO, TPresence>[\"data\"];\n kind: ParticipantKind;\n operator?: OperatorUser | null;\n },\n presence: TPresence,\n ): UserInfo<TIO, TPresence> {\n switch (params.kind) {\n case \"operator\":\n return {\n data: params.data,\n kind: params.kind,\n operator: params.operator ?? null,\n presence,\n };\n case \"user\":\n return {\n data: params.data,\n kind: params.kind,\n operator: null,\n presence,\n };\n default:\n return assertExhaustive(params.kind);\n }\n }\n\n private _clientKeyForConnection(connectionId: string): ClientKey | null {\n return this._idMap.fromConnectionId.get(connectionId) ?? null;\n }\n\n private _clientKeyFromInfo(info: UserInfo<TIO, TPresence>): ClientKey {\n const id = info.data && typeof info.data.id === \"string\" ? info.data.id : null;\n\n if (!id) throw new Error(\"Could not resolve user id\");\n\n switch (info.kind) {\n case \"operator\":\n case \"user\":\n return { kind: info.kind, id };\n default:\n return assertExhaustive(info.kind);\n }\n }\n\n private _sameClientKey(a: ClientKey | null, b: ClientKey | null): boolean {\n return !!a && !!b && a.kind === b.kind && a.id === b.id;\n }\n\n private _mapForKind(kind: ParticipantKind): Map<string, UserInfo<TIO, TPresence>> {\n switch (kind) {\n case \"operator\":\n return this._operators;\n case \"user\":\n return this._others;\n default:\n return assertExhaustive(kind);\n }\n }\n\n private _presenceSeqsForKind(kind: ParticipantKind): Map<string, number | null> {\n switch (kind) {\n case \"operator\":\n return this._presenceSeqs.operator;\n case \"user\":\n return this._presenceSeqs.user;\n default:\n return assertExhaustive(kind);\n }\n }\n\n private _connectionsForKind(kind: ParticipantKind): Map<string, Set<string>> {\n switch (kind) {\n case \"operator\":\n return this._idMap.fromClientKey.operator;\n case \"user\":\n return this._idMap.fromClientKey.user;\n default:\n return assertExhaustive(kind);\n }\n }\n\n private _getByClientKey(clientKey: ClientKey): UserInfo<TIO, TPresence> | null {\n return this._mapForKind(clientKey.kind).get(clientKey.id) ?? null;\n }\n\n /**\n * Extra-tab joins and occupancy snapshots only replace presence when the\n * incoming seq is a newer number. Connecting with no seq is not an\n * interact. Equal seqs keep the value already applied.\n */\n private _isNewerPresenceSeq(clientKey: ClientKey, incoming?: number | null): boolean {\n return this._isNewerPresenceSeqValue(\n this._presenceSeqsForKind(clientKey.kind).get(clientKey.id),\n incoming,\n );\n }\n\n private _isNewerPresenceSeqValue(\n previous: number | null | undefined,\n incoming?: number | null,\n ): boolean {\n if (typeof incoming !== \"number\") return false;\n if (typeof previous !== \"number\") return true;\n\n return incoming > previous;\n }\n\n /**\n * Local writes omit a seq and always apply. Remote writes apply when the\n * seq is newer or equal (last-applied wins among equal seqs).\n * A null seq applies only when we do not already have one.\n */\n private _shouldApplyPresenceSeq(clientKey: ClientKey, incoming?: number | null): boolean {\n if (incoming === undefined) return true;\n if (typeof incoming !== \"number\") {\n return typeof this._presenceSeqsForKind(clientKey.kind).get(clientKey.id) !== \"number\";\n }\n\n const previous = this._presenceSeqsForKind(clientKey.kind).get(clientKey.id);\n\n if (typeof previous !== \"number\") return true;\n\n return incoming >= previous;\n }\n\n private _setPresenceSeq(clientKey: ClientKey, incoming?: number | null): void {\n if (typeof incoming === \"number\") {\n this._presenceSeqsForKind(clientKey.kind).set(clientKey.id, incoming);\n return;\n }\n\n if (incoming === undefined) {\n return;\n }\n\n this._presenceSeqsForKind(clientKey.kind).set(clientKey.id, null);\n }\n\n private _deleteConnectionId(connectionId: string): void {\n const clientKey = this._clientKeyForConnection(connectionId);\n\n this._idMap.fromConnectionId.delete(connectionId);\n\n if (!clientKey) return;\n\n const connections = this._connectionsForKind(clientKey.kind);\n const set = connections.get(clientKey.id) ?? null;\n\n if (!set) return;\n\n set.delete(connectionId);\n\n if (!!set.size) return;\n\n connections.delete(clientKey.id);\n }\n\n private _getConnectionIds(clientKey: ClientKey): Set<string> | null {\n return this._connectionsForKind(clientKey.kind).get(clientKey.id) ?? null;\n }\n\n private _setConnectionId(connectionId: string, clientKey: ClientKey): Set<string> {\n const connections = this._connectionsForKind(clientKey.kind);\n const set = connections.get(clientKey.id) ?? new Set<string>();\n const updated = set.add(connectionId);\n\n this._idMap.fromConnectionId.set(connectionId, clientKey);\n connections.set(clientKey.id, updated);\n\n return updated;\n }\n}\n","import type {\n Id,\n IOLike,\n OtherSubscriptionCallback,\n OthersSubscriptionCallback,\n OthersSubscriptionEvent,\n ParticipantKind,\n ParticipantKindOptions,\n ParticipantKindsOptions,\n UserInfo,\n} from \"@pluv/types\";\nimport type { Subject } from \"wonka\";\nimport { makeSubject, subscribe, TypeOfSource } from \"wonka\";\nimport { assertExhaustive } from \"./utils/assertExhaustive\";\n\nexport interface OtherSubjectParams {\n id: string;\n kind: ParticipantKind;\n}\n\nexport class UsersNotifier<TIO extends IOLike, TPresence extends Record<string, any> = {}> {\n public readonly others = makeSubject<{\n others: readonly Id<UserInfo<TIO, TPresence>>[];\n event: OthersSubscriptionEvent<TIO, TPresence>;\n }>();\n\n private readonly _otherSubjects = {\n operator: new Map<string, Subject<Id<UserInfo<TIO, TPresence>> | null>>(),\n user: new Map<string, Subject<Id<UserInfo<TIO, TPresence>> | null>>(),\n };\n\n public clear(): void {\n this._subjectsForKind(\"user\").forEach((subject) => {\n subject.next(null);\n });\n this._subjectsForKind(\"operator\").forEach((subject) => {\n subject.next(null);\n });\n this._subjectsForKind(\"user\").clear();\n this._subjectsForKind(\"operator\").clear();\n }\n\n public delete(params: OtherSubjectParams): void {\n const { id, kind } = params;\n const subjects = this._subjectsForKind(kind);\n const subject = subjects.get(id);\n\n if (!subject) return;\n\n subject.next(null);\n subjects.delete(id);\n }\n\n public other(params: OtherSubjectParams): Subject<Id<UserInfo<TIO, TPresence>> | null> {\n const { id, kind } = params;\n const subjects = this._subjectsForKind(kind);\n const subject = subjects.get(id);\n\n if (subject) return subject;\n\n const created = makeSubject<Id<UserInfo<TIO, TPresence>> | null>();\n\n subjects.set(id, created);\n\n return created;\n }\n\n public subscribeOther(\n id: string,\n callback: OtherSubscriptionCallback<TIO, TPresence>,\n options?: ParticipantKindOptions,\n ): () => void {\n const kind = options?.kind ?? \"user\";\n const subscription = subscribe(callback)(this.other({ id, kind }).source);\n\n return () => {\n subscription.unsubscribe();\n };\n }\n\n public subscribeOthers(\n callback: OthersSubscriptionCallback<TIO, TPresence>,\n options?: ParticipantKindsOptions,\n ): () => void {\n const kinds = options?.kinds ?? [\"user\"];\n const subscription = subscribe<TypeOfSource<typeof this.others.source>>(\n ({ others, event }) => {\n switch (event.kind) {\n case \"clear\":\n case \"sync\":\n break;\n case \"enter\":\n case \"leave\":\n case \"update\":\n if (!kinds.includes(event.user.kind)) return;\n break;\n default:\n assertExhaustive(event);\n }\n\n callback(others, event);\n },\n )(this.others.source);\n\n return () => {\n subscription.unsubscribe();\n };\n }\n\n private _subjectsForKind(\n kind: ParticipantKind,\n ): Map<string, Subject<Id<UserInfo<TIO, TPresence>> | null>> {\n switch (kind) {\n case \"operator\":\n return this._otherSubjects.operator;\n case \"user\":\n return this._otherSubjects.user;\n default:\n return assertExhaustive(kind);\n }\n }\n}\n","/**\n * Runs `commit` after earlier commits. `ready` should already be running.\n * A rejection, or a throw from `commit`, is logged, and the next call still runs.\n * The storage caller returns before the write. This promise only orders the next commit.\n */\nexport const sequenceCommit = <T>(params: {\n tail: Promise<void>;\n ready: Promise<T>;\n commit: (value: T) => void;\n}): Promise<void> => {\n const turn = params.tail.then(() => params.ready);\n\n return turn.then(\n (value) => {\n try {\n params.commit(value);\n } catch (error) {\n console.error(error);\n }\n },\n (error: unknown) => {\n console.error(error);\n },\n );\n};\n","export const debounce = <TFunc extends (...args: any[]) => any>(\n fn: TFunc,\n options?: { wait: number; immediate?: boolean },\n): ((...args: Parameters<TFunc>) => void) => {\n const { wait, immediate = false } = options ?? {};\n\n let prevResult: ReturnType<TFunc> | undefined;\n let timeout: number | null = null;\n\n return (...args: Parameters<TFunc>): void => {\n if (typeof timeout === \"number\") clearTimeout(timeout);\n\n timeout = setTimeout(() => {\n timeout = null;\n\n if (!immediate) prevResult = fn(args);\n }, wait) as number;\n\n if (immediate && !timeout) {\n fn(args);\n\n return;\n }\n\n return prevResult;\n };\n};\n","export const inRange = (value: number, range: { max: number; min: number }): boolean => {\n const { max, min } = range;\n\n return Number.isInteger(value) && value >= min && value <= max;\n};\n","import type { InferDoc, InferJson, InferStorage } from \"@pluv/crdt\";\nimport type {\n BaseIOEventRecord,\n BroadcastProxy,\n CrdtDocLike,\n EventMessage,\n EventNotifierSubscriptionCallback,\n EventProxy,\n IOEventMessage,\n IOLike,\n Id,\n InferIOAuthorize,\n InferIOAuthorizeUser,\n InferIOInput,\n InferIOOutput,\n JsonObject,\n ListUsersOptions,\n ListUsersResult,\n OtherSubscriptionCallback,\n OthersSubscriptionCallback,\n PresenceProcedureProxy,\n RoomError,\n RoomErrorSubscriptionCallback,\n RoomEventListenerMap,\n ParticipantKindOptions,\n ParticipantKindsOptions,\n RoomLike,\n RoomStats,\n RoomStatsByKind,\n StateNotifierSubjects,\n StorageProcedureProxy,\n StorageProxy,\n StorageRootSubscriptionCallback,\n StorageSubscriptionCallback,\n SubscribeProxy,\n SubscriptionCallback,\n UpdateMyPresenceAction,\n UserInfo,\n WebSocketConnection,\n WebSocketState,\n} from \"@pluv/types\";\nimport { ConnectionState, StorageState } from \"@pluv/types\";\nimport { makeSubject, subscribe } from \"wonka\";\nimport type { AbstractStorageStore } from \"./AbstractStorageStore\";\nimport type { ClientDefs } from \"./ClientDefs\";\nimport { LIST_USERS_DEFAULT_LIMIT, LIST_USERS_MAX_LIMIT, LIST_USERS_TIMEOUT_MS } from \"./constants\";\nimport type { CrdtManagerOptions } from \"./CrdtManager\";\nimport { CrdtManager } from \"./CrdtManager\";\nimport { CrdtNotifier } from \"./CrdtNotifier\";\nimport { EventNotifier } from \"./EventNotifier\";\nimport { ListenerManager } from \"./ListenerManager\";\nimport { PendingRequestManager } from \"./PendingRequestManager\";\nimport { StateNotifier } from \"./StateNotifier\";\nimport { StorageStore } from \"./StorageStore\";\nimport { StorageSync } from \"./StorageSync\";\nimport type {\n AuthorizationState,\n InferClientInput,\n InferClientMetadata,\n InferClientOutput,\n InferClientPresence,\n InternalSubscriptions,\n PluvClientLimits,\n WithMetadata,\n} from \"./types\";\nimport type { UsersManagerConfig } from \"./UsersManager\";\nimport { UsersManager } from \"./UsersManager\";\nimport type { OtherSubjectParams } from \"./UsersNotifier\";\nimport { UsersNotifier } from \"./UsersNotifier\";\nimport { debounce, inRange, parsePluvSchema, sequenceCommit } from \"./utils\";\n\nconst ADD_TO_STORAGE_STATE_DEBOUNCE_MS = 1_000;\nconst HEARTBEAT_INTERVAL_MS = 10_000;\nconst PONG_TIMEOUT_MS = 2_000;\n\nconst RECONNECT_TIMEOUT_MS = 5_000;\nconst MIN_RECONNECT_TIMEOUT_MS = 1_000;\nconst MAX_RECONNECT_TIMEOUT_MS = 60_000;\n\nconst ORIGIN_INITIALIZED = \"$initialized\";\nconst ORIGIN_STORAGE_UPDATED = \"$storageUpdated\";\n\ndeclare global {\n var process: {\n env: {\n [key: string]: string | undefined;\n };\n };\n}\n\nexport const DEFAULT_PLUV_CLIENT_ADDON = <TDefs extends ClientDefs = ClientDefs>(\n input: PluvRoomAddonInput<TDefs>,\n): PluvRoomAddonResult => ({\n storage: new StorageStore(input.room.id),\n});\n\ninterface WindowListeners {\n onNavigatorOffline: () => void;\n onNavigatorOnline: () => void;\n onVisibilityChange: () => void;\n onWindowFocus: () => void;\n}\n\ninterface WebSocketListeners {\n onClose: (event: CloseEvent) => void;\n onError: (event: Event) => void;\n onMessage: (message: MessageEvent<string>) => void;\n onOpen: (event: Event) => void;\n}\n\ninterface IntervalIds {\n heartbeat: number | null;\n}\n\ninterface TimeoutIds {\n pong: number | null;\n reconnect: number | null;\n}\n\nexport interface EndpointParams<TMetadata extends JsonObject> {\n metadata: TMetadata;\n room: string;\n}\nexport type AuthEndpoint<TMetadata extends JsonObject> =\n | string\n | ((params: EndpointParams<TMetadata>) => string | FetchOptions)\n | true;\nexport type WsEndpoint<TMetadata extends JsonObject> =\n | string\n | ((params: EndpointParams<TMetadata>) => string);\n\ntype FetchOptions = { url: string; options?: RequestInit };\n\nexport type RoomEndpoints<TMetadata extends JsonObject> = {\n wsEndpoint?: WsEndpoint<TMetadata>;\n authEndpoint: AuthEndpoint<TMetadata>;\n};\n\ninterface InternalListeners {\n onAuthorizationFail: (error: Error) => void;\n}\n\nexport type PluvRoomAddon<TDefs extends ClientDefs = ClientDefs> = (\n input: PluvRoomAddonInput<TDefs>,\n) => Partial<PluvRoomAddonResult>;\n\nexport interface PluvRoomAddonInput<TDefs extends ClientDefs = ClientDefs> {\n room: PluvRoom<TDefs>;\n}\n\nexport interface PluvRoomAddonResult {\n storage: AbstractStorageStore;\n}\n\nexport type PluvRoomDebug<TIO extends IOLike> = Id<{\n output: readonly (keyof InferIOOutput<TIO>)[];\n input: readonly (keyof InferIOInput<TIO>)[];\n}>;\n\ntype GetAuthEndpointParams<TMetadata extends JsonObject = {}> = WithMetadata<TMetadata>;\ntype GetWsEndpointParams<TMetadata extends JsonObject = {}> = WithMetadata<TMetadata>;\n\nexport type RoomConnectParams<TMetadata extends JsonObject = {}> = keyof TMetadata extends never\n ? []\n : [WithMetadata<TMetadata>];\n\nexport interface ReconnectTimeoutMsParams {\n attempts: number;\n}\nexport type ReconnectTimeoutMs = number | ((params: ReconnectTimeoutMsParams) => number);\n\nexport type RoomConfig<TDefs extends ClientDefs = ClientDefs> = Id<\n {\n addons?: readonly PluvRoomAddon<any>[];\n debug?: boolean | PluvRoomDebug<TDefs[\"io\"]>;\n limits: PluvClientLimits;\n onAuthorizationFail?: (error: Error) => void;\n metadata?: TDefs[\"metadata\"];\n reconnectTimeoutMs?: ReconnectTimeoutMs;\n treaty: TDefs[\"treaty\"];\n } & RoomEndpoints<InferClientMetadata<TDefs>> &\n Pick<CrdtManagerOptions<TDefs[\"storage\"]>, \"initialStorage\" | \"storage\"> &\n UsersManagerConfig<InferClientPresence<TDefs>>\n>;\n\nexport class PluvRoom<TDefs extends ClientDefs = ClientDefs> implements RoomLike<\n TDefs[\"io\"],\n InferDoc<TDefs[\"storage\"]>,\n InferClientPresence<TDefs>,\n InferStorage<TDefs[\"storage\"]>,\n InferJson<TDefs[\"storage\"]>,\n TDefs[\"treaty\"]\n> {\n readonly _endpoints: RoomEndpoints<InferClientMetadata<TDefs>>;\n\n public readonly id: string;\n public readonly metadata?: TDefs[\"metadata\"];\n\n private readonly _crdtManager: CrdtManager<TDefs[\"storage\"]>;\n private readonly _crdtNotifier = new CrdtNotifier<InferJson<TDefs[\"storage\"]>>();\n private readonly _debug: boolean | PluvRoomDebug<TDefs[\"io\"]>;\n private readonly _eventNotifier = new EventNotifier<TDefs[\"io\"]>();\n private readonly _errorSubject = makeSubject<RoomError>();\n private readonly _intervals: IntervalIds = {\n heartbeat: null,\n };\n private readonly _limits: PluvClientLimits;\n private readonly _listenerManager = new ListenerManager();\n private readonly _listeners: InternalListeners;\n private readonly _reconnectTimeoutMs: ReconnectTimeoutMs;\n private readonly _requests = new PendingRequestManager();\n private readonly _stateNotifier = new StateNotifier<TDefs[\"io\"], InferClientPresence<TDefs>>();\n private readonly _storageStore: AbstractStorageStore;\n private readonly _subscriptions: InternalSubscriptions = {\n observeCrdt: null,\n };\n private readonly _timeouts: TimeoutIds = {\n pong: null,\n reconnect: null,\n };\n private readonly _treaty: TDefs[\"treaty\"];\n private readonly _usersManager: UsersManager<TDefs[\"io\"], InferClientPresence<TDefs>>;\n private readonly _usersNotifier = new UsersNotifier<TDefs[\"io\"], InferClientPresence<TDefs>>();\n private _roomStats: RoomStats = { connectionCount: 0, userCount: 0 };\n private _operatorStats: RoomStats = { connectionCount: 0, userCount: 0 };\n\n private _lastMetadata: InferClientMetadata<TDefs> | null = null;\n // Local sequences. `presence` drops an older resolver result once a newer call has started.\n private _seq = { presence: 0 };\n private readonly _storageSync = new StorageSync();\n private _state: WebSocketState<TDefs[\"io\"]> = {\n authorization: {\n token: null,\n user: null,\n kind: \"user\",\n operator: null,\n },\n connection: {\n attempts: 0,\n id: null,\n state: ConnectionState.Untouched,\n },\n storage: {\n state: StorageState.Unavailable,\n },\n webSocket: null,\n };\n private _windowListeners: WindowListeners | null = null;\n private _wsListeners: WebSocketListeners | null = null;\n private _storageProcedureNames: string[] = [];\n /** Prepared commits wait here so an earlier call writes before a later one. */\n private _storageCommits: Promise<void> = Promise.resolve();\n\n constructor(room: string, options: RoomConfig<TDefs>) {\n const {\n addons = [],\n authEndpoint,\n debug = false,\n initialPresence,\n initialStorage,\n limits,\n metadata,\n onAuthorizationFail,\n presence,\n reconnectTimeoutMs = RECONNECT_TIMEOUT_MS,\n storage: crdtStorage,\n treaty,\n wsEndpoint,\n } = options;\n\n this.id = room;\n this.metadata = metadata;\n\n const addon = this._getAddon(addons);\n const { storage } = {\n ...DEFAULT_PLUV_CLIENT_ADDON({ room: this }),\n ...addon({ room: this }),\n };\n this._storageStore = storage;\n\n this._debug = debug;\n this._endpoints = { authEndpoint, wsEndpoint } as RoomEndpoints<InferClientMetadata<TDefs>>;\n this._limits = limits;\n this._reconnectTimeoutMs = reconnectTimeoutMs;\n\n this._listeners = {\n onAuthorizationFail: (error) => {\n onAuthorizationFail?.(error);\n },\n };\n\n this._treaty = treaty;\n this._usersManager = new UsersManager<TDefs[\"io\"], InferClientPresence<TDefs>>({\n initialPresence,\n limits: this._limits,\n presence,\n });\n this._crdtManager = new CrdtManager<TDefs[\"storage\"]>({\n initialStorage,\n storage: crdtStorage,\n });\n }\n\n public get webSocket(): WebSocket | null {\n return this._state.webSocket;\n }\n\n public addEventListener<TKind extends keyof RoomEventListenerMap>(\n kind: TKind,\n handler: RoomEventListenerMap[TKind],\n ): () => void {\n return this._listenerManager.subscribe(kind, handler as any);\n }\n\n public broadcast = new Proxy(\n async <TEvent extends keyof InferClientInput<TDefs>>(\n event: TEvent,\n data: Id<InferClientInput<TDefs>[TEvent]>,\n ): Promise<void> => {\n if (!this._state.webSocket) return;\n if (this._state.connection.state !== ConnectionState.Open) return;\n\n this._sendMessage({ data, type: event.toString() });\n },\n {\n get(fn, prop) {\n return async (data: Id<InferClientInput<TDefs>[any]>): Promise<void> => {\n return await fn(prop, data);\n };\n },\n },\n ) as BroadcastProxy<TDefs[\"io\"]>;\n\n public canRedo = (): boolean => {\n return this._crdtManager.doc.canRedo();\n };\n\n public canUndo = (): boolean => {\n return this._crdtManager.doc.canUndo();\n };\n\n public async connect(...args: RoomConnectParams<InferClientMetadata<TDefs>>): Promise<void> {\n const params = (args[0] ?? {}) as WithMetadata<InferClientMetadata<TDefs>>;\n const metadata = params.metadata as InferClientMetadata<TDefs>;\n\n this._setMetadata(metadata);\n\n const canConnect = [\n ConnectionState.Closed,\n ConnectionState.Unavailable,\n ConnectionState.Untouched,\n ].some((state) => this._state.connection.state === state);\n\n if (!canConnect) return;\n\n this._clearTimeout(this._timeouts.reconnect);\n this._updateState((oldState) => {\n oldState.connection.state = ConnectionState.Connecting;\n\n return oldState;\n });\n\n await this._storageStore.initialize();\n\n const wsEndpoint = this._getWsEndpoint(this.id, params);\n const url = new URL(wsEndpoint);\n\n let authToken: string | null = null;\n let webSocket: WebSocket;\n\n try {\n authToken = await this._getAuthorization(this.id, params);\n\n if (authToken) url.searchParams.set(\"token\", encodeURIComponent(authToken));\n\n webSocket = new WebSocket(url.toString());\n } catch (err) {\n this._updateState((oldState) => {\n oldState.connection.attempts += 1;\n\n return oldState;\n });\n\n await this._storageStore.destroy();\n this._pollReconnect();\n await Promise.resolve(this._onAuthorizationFail(err));\n\n return;\n }\n\n this._updateState((oldState) => {\n oldState.connection.attempts = 0;\n oldState.authorization.token = authToken;\n oldState.storage.state = StorageState.Loading;\n oldState.webSocket = webSocket;\n\n return oldState;\n });\n\n this._attachWindowListeners();\n this._attachWsListeners();\n }\n\n public async disconnect(): Promise<void> {\n if (!this._state.webSocket) return;\n\n const canDisconnect = [ConnectionState.Connecting, ConnectionState.Open].some(\n (state) => this._state.connection.state === state,\n );\n\n if (!canDisconnect) return;\n\n this._closeWs();\n this._clearInterval(this._intervals.heartbeat);\n this._clearTimeout(this._timeouts.reconnect);\n this._updateState((oldState) => {\n oldState.authorization.token = null;\n oldState.connection.state = ConnectionState.Closed;\n // Unlike `_onClose`, this destroys the doc below, so storage is gone.\n oldState.storage.state = StorageState.Unavailable;\n oldState.webSocket = null;\n\n return oldState;\n });\n\n await this._storageStore.destroy();\n this._crdtManager.destroy();\n\n // `destroy` swaps in a new doc, so stop observing the destroyed one.\n this._observeCrdt();\n this._stateNotifier.subjects[\"my-presence\"].next(null);\n }\n\n public getConnection = (): WebSocketConnection => {\n // Create a read-only clone of the connection state\n return Object.freeze(JSON.parse(JSON.stringify(this._state.connection)));\n };\n\n public getDoc = (): CrdtDocLike<\n InferDoc<TDefs[\"storage\"]>,\n InferStorage<TDefs[\"storage\"]>,\n InferJson<TDefs[\"storage\"]>\n > => {\n return this._crdtManager.doc;\n };\n\n public getMyPresence = (): InferClientPresence<TDefs> => {\n return this._usersManager.myPresence;\n };\n\n public getMyself = (): Id<UserInfo<TDefs[\"io\"], InferClientPresence<TDefs>>> | null => {\n return this._usersManager.myself;\n };\n\n public getOther = (\n userId: string,\n options?: ParticipantKindOptions,\n ): Id<UserInfo<TDefs[\"io\"], InferClientPresence<TDefs>>> | null => {\n return this._usersManager.getOther(userId, options);\n };\n\n public getOtherByConnectionId = (\n connectionId: string,\n options?: ParticipantKindsOptions,\n ): Id<UserInfo<TDefs[\"io\"], InferClientPresence<TDefs>>> | null => {\n return this._usersManager.getOtherByConnectionId(connectionId, options);\n };\n\n public getOthers = (\n options?: ParticipantKindsOptions,\n ): readonly Id<UserInfo<TDefs[\"io\"], InferClientPresence<TDefs>>>[] => {\n return this._usersManager.getOthers(options);\n };\n\n public getRoomStats = (options?: ParticipantKindsOptions): RoomStats => {\n const kinds = options?.kinds;\n\n if (kinds === undefined) return this._roomStats;\n if (kinds.length === 0) return { connectionCount: 0, userCount: 0 };\n\n const includeUsers = kinds.includes(\"user\");\n const includeOperators = kinds.includes(\"operator\");\n\n return {\n connectionCount:\n (includeUsers ? this._roomStats.connectionCount : 0) +\n (includeOperators ? this._operatorStats.connectionCount : 0),\n userCount:\n (includeUsers ? this._roomStats.userCount : 0) +\n (includeOperators ? this._operatorStats.userCount : 0),\n };\n };\n\n public getStorage = <TKey extends keyof InferStorage<TDefs[\"storage\"]>>(\n type: TKey,\n ): InferStorage<TDefs[\"storage\"]>[TKey] | null => {\n // Updates aren't delivered until storage loads, so don't hand out a writable\n // shared-type that silently discards writes.\n if (!this.getStorageLoaded()) return null;\n\n const sharedType = this._crdtManager.get(type);\n\n if (typeof sharedType === \"undefined\") return null;\n\n return sharedType;\n };\n\n public getStorageJson(): InferJson<TDefs[\"storage\"]> | null;\n public getStorageJson<TKey extends keyof InferJson<TDefs[\"storage\"]>>(\n type: TKey,\n ): InferJson<TDefs[\"storage\"]>[TKey] | null;\n public getStorageJson<TKey extends keyof InferJson<TDefs[\"storage\"]>>(type?: TKey) {\n if (this._state.connection.id === null) return null;\n if (typeof type === \"undefined\") return this._crdtManager.doc.toJson();\n\n const sharedType = this._crdtManager.get(type);\n\n if (typeof sharedType === \"undefined\") return null;\n\n return this._crdtManager.doc.toJson(type);\n }\n\n public getStorageLoaded = (): boolean => {\n return (\n this._state.storage.state === StorageState.Offline ||\n this._state.storage.state === StorageState.Synced\n );\n };\n\n public listUsers = (options: ListUsersOptions = {}): Promise<ListUsersResult<TDefs[\"io\"]>> => {\n const resolved = options.limit ?? LIST_USERS_DEFAULT_LIMIT;\n\n if (!inRange(resolved, { min: 1, max: LIST_USERS_MAX_LIMIT })) {\n return Promise.resolve({\n success: false,\n error: {\n code: \"INVALID_LIMIT\",\n message: `Invalid listUsers limit. Limit must be an integer from 1 to ${LIST_USERS_MAX_LIMIT.toLocaleString()}. Received: ${String(options.limit)}.`,\n },\n });\n }\n\n if (!this._state.webSocket || this._state.connection.state !== ConnectionState.Open) {\n return Promise.resolve({\n success: false,\n error: { code: \"NOT_CONNECTED\", message: \"Room is not connected\" },\n });\n }\n\n const { promise, requestId } = this._requests.request<ListUsersResult<TDefs[\"io\"]>>({\n onAbort: () => ({\n success: false,\n error: { code: \"NOT_CONNECTED\", message: \"Room is not connected\" },\n }),\n onTimeout: () => ({\n success: false,\n error: { code: \"FAILED\", message: \"listUsers timed out\" },\n }),\n timeoutMs: LIST_USERS_TIMEOUT_MS,\n });\n\n this._sendMessage({\n type: \"$listUsers\",\n data: {\n cursor: options.cursor ?? null,\n kinds: options.kinds,\n limit: resolved,\n requestId,\n },\n });\n\n return promise;\n };\n\n public presence = new Proxy(\n async (name: string, data: unknown): Promise<void> => {\n await this._runPresenceProcedure(name, data);\n },\n {\n get(fn, prop) {\n return (data: unknown): Promise<void> => fn(prop as string, data);\n },\n },\n ) as PresenceProcedureProxy<TDefs[\"treaty\"][\"_defs\"][\"procedures\"][\"presence\"]>;\n\n public redo = (): void => {\n this._crdtManager.doc.redo();\n };\n\n public storage = new Proxy(\n (name: string, data: unknown): void => {\n this._runStorageProcedure(name, data);\n },\n {\n get(fn, prop) {\n return (data: unknown): void => fn(prop as string, data);\n },\n },\n ) as StorageProcedureProxy<TDefs[\"treaty\"][\"_defs\"][\"procedures\"][\"storage\"]>;\n\n public subscribe = new Proxy(\n <TSubject extends keyof StateNotifierSubjects<TDefs[\"io\"], InferClientPresence<TDefs>>>(\n name: TSubject,\n callback: SubscriptionCallback<TDefs[\"io\"], InferClientPresence<TDefs>, TSubject>,\n ): (() => void) => this._stateNotifier.subscribe(name, callback),\n {\n get: (fn, prop) => {\n if (prop === \"connection\") {\n return (\n callback: SubscriptionCallback<\n TDefs[\"io\"],\n InferClientPresence<TDefs>,\n \"connection\"\n >,\n ) => {\n return fn(\"connection\", callback);\n };\n }\n\n if (prop === \"error\") {\n return (callback: RoomErrorSubscriptionCallback): (() => void) => {\n const subscription = subscribe(callback)(this._errorSubject.source);\n\n return () => {\n subscription.unsubscribe();\n };\n };\n }\n\n if (prop === \"myPresence\") {\n return (\n callback: SubscriptionCallback<\n TDefs[\"io\"],\n InferClientPresence<TDefs>,\n \"my-presence\"\n >,\n ) => {\n return fn(\"my-presence\", callback);\n };\n }\n\n if (prop === \"myself\") {\n return (\n callback: SubscriptionCallback<\n TDefs[\"io\"],\n InferClientPresence<TDefs>,\n \"myself\"\n >,\n ) => {\n return fn(\"myself\", callback);\n };\n }\n\n if (prop === \"others\") {\n return (\n callback: OthersSubscriptionCallback<\n TDefs[\"io\"],\n InferClientPresence<TDefs>\n >,\n options?: ParticipantKindsOptions,\n ) => {\n return this._usersNotifier.subscribeOthers((_listed, event) => {\n const others = this._usersManager.getOthers(options);\n\n if (event.kind === \"sync\") {\n callback(others, { kind: \"sync\", users: others });\n return;\n }\n\n callback(others, event);\n }, options);\n };\n }\n\n if (prop === \"roomStats\") {\n return (\n callback: SubscriptionCallback<\n TDefs[\"io\"],\n InferClientPresence<TDefs>,\n \"roomStats\"\n >,\n ) => {\n return fn(\"roomStats\", callback);\n };\n }\n\n if (prop === \"storageLoaded\") {\n return (\n callback: SubscriptionCallback<\n TDefs[\"io\"],\n InferClientPresence<TDefs>,\n \"storage-loaded\"\n >,\n ) => {\n return fn(\"storage-loaded\", callback);\n };\n }\n\n if (prop === \"event\") return this._event;\n if (prop === \"other\") return this._other;\n if (prop === \"storage\") return this.#_storage;\n\n throw new Error(`Unknown subject: ${prop.toString()}`);\n },\n },\n ) as SubscribeProxy<TDefs[\"io\"], InferClientPresence<TDefs>, InferJson<TDefs[\"storage\"]>>;\n\n public transact = (\n fn: (storage: InferStorage<TDefs[\"storage\"]>) => void,\n origin?: string,\n ): void => {\n const _origin = origin ?? this._state.connection.id;\n\n /**\n * !HACK\n * @description Don't transact anything if there is no origin, because\n * that means the user isn't connected yet. This will mean events are\n * lost unfortunately.\n * @date September 23, 2023\n */\n if (typeof _origin !== \"string\") return;\n\n this._crdtManager.doc.transact(() => {\n const storage = this._crdtManager.doc.get();\n\n fn(storage);\n }, _origin);\n };\n\n public undo = (): void => {\n this._crdtManager.doc.undo();\n };\n\n public updateMyPresence = async (\n presence: UpdateMyPresenceAction<InferClientPresence<TDefs>>,\n ): Promise<void> => {\n await this._applyMyPresence(presence);\n };\n\n private async _applyMyPresence(\n presence: UpdateMyPresenceAction<InferClientPresence<TDefs>>,\n procedure?: string | null,\n ): Promise<void> {\n const newPresence =\n typeof presence === \"function\" ? presence(this.getMyPresence()) : presence;\n\n this._usersManager.updateMyPresence(newPresence);\n\n const myPresence = this._usersManager.myPresence;\n const myself = this._usersManager.myself ?? null;\n\n this._stateNotifier.subjects[\"my-presence\"].next(myPresence);\n if (myself) this._stateNotifier.subjects.myself.next(myself);\n\n const canSend =\n !!this._state.webSocket && this._state.connection.state === ConnectionState.Open;\n\n if (canSend) this._usersManager.beginLocalPresenceWrite();\n\n await this.broadcast(\n \"$updatePresence\" as keyof InferClientInput<TDefs>,\n {\n presence: newPresence,\n ...(procedure ? { procedure } : {}),\n } as any,\n );\n }\n\n private async _addToStorageStore(update: string): Promise<void> {\n await this._storageStore.addUpdate(update);\n\n this._flattenStorageStore();\n }\n\n private _attachWindowListeners(): void {\n if (typeof window === \"undefined\") return;\n if (typeof document === \"undefined\") return;\n\n this._windowListeners = this._windowListeners || {\n onNavigatorOffline: this._onNavigatorOffline.bind(this),\n onNavigatorOnline: this._onNavigatorOnline.bind(this),\n onVisibilityChange: this._onVisibilityChange.bind(this),\n onWindowFocus: this._onWindowFocus.bind(this),\n };\n\n window.addEventListener(\"offline\", this._windowListeners.onNavigatorOffline);\n window.addEventListener(\"online\", this._windowListeners.onNavigatorOnline);\n document.addEventListener(\"visibilitychange\", this._windowListeners.onVisibilityChange);\n window.addEventListener(\"focus\", this._windowListeners.onWindowFocus);\n }\n\n private _attachWsListeners(): void {\n if (!this._state.webSocket) return;\n\n this._wsListeners = this._wsListeners || {\n onClose: this._onClose.bind(this),\n onError: this._onError.bind(this),\n onMessage: this._onMessage.bind(this),\n onOpen: this._onOpen.bind(this),\n };\n\n this._state.webSocket.addEventListener(\"close\", this._wsListeners.onClose);\n this._state.webSocket.addEventListener(\"error\", this._wsListeners.onError);\n this._state.webSocket.addEventListener(\"message\", this._wsListeners.onMessage);\n this._state.webSocket.addEventListener(\"open\", this._wsListeners.onOpen);\n }\n\n private _clearInterval(interval: number | null) {\n if (Number.isNaN(interval)) return;\n\n clearInterval(interval as number);\n }\n\n private _clearTimeout(timeout: number | null) {\n if (Number.isNaN(timeout)) return;\n\n clearTimeout(timeout as number);\n }\n\n private _closeWs(): void {\n this._storageSync.reset();\n this._subscriptions.observeCrdt?.();\n\n this._clearInterval(this._intervals.heartbeat);\n this._clearTimeout(this._timeouts.pong);\n this._detachWindowListeners();\n this._usersManager.removeMyself();\n this._usersManager.clearConnections();\n this._usersNotifier.clear();\n this._stateNotifier.subjects.myself.next(null);\n this._stateNotifier.subjects.others.next([]);\n this._usersNotifier.others.next({ others: [], event: { kind: \"clear\" } });\n this._roomStats = { connectionCount: 0, userCount: 0 };\n this._operatorStats = { connectionCount: 0, userCount: 0 };\n this._stateNotifier.subjects.roomStats.next(this._roomStats);\n this._requests.failAll();\n this._state.webSocket?.close();\n\n this._detachWsListeners();\n }\n\n private _detachWindowListeners(): void {\n if (!this._windowListeners) return;\n if (typeof window === \"undefined\") return;\n if (typeof document === \"undefined\") return;\n\n window.removeEventListener(\"offline\", this._windowListeners.onNavigatorOffline);\n window.removeEventListener(\"online\", this._windowListeners.onNavigatorOnline);\n document.removeEventListener(\"visibilitychange\", this._windowListeners.onVisibilityChange);\n window.removeEventListener(\"focus\", this._windowListeners.onWindowFocus);\n\n this._windowListeners = null;\n }\n\n private _detachWsListeners(): void {\n if (!this._state.webSocket || !this._wsListeners) return;\n\n this._state.webSocket.removeEventListener(\"close\", this._wsListeners.onClose);\n this._state.webSocket.removeEventListener(\"error\", this._wsListeners.onError);\n this._state.webSocket.removeEventListener(\"message\", this._wsListeners.onMessage);\n this._state.webSocket.removeEventListener(\"open\", this._wsListeners.onOpen);\n\n this._wsListeners = null;\n }\n\n private _emitSharedTypes(): void {\n const sharedTypes = this._crdtManager.doc.get();\n\n const storageRoot = Object.keys(sharedTypes).reduce(\n (acc, prop) => {\n const serialized = this._crdtManager.doc.toJson(prop);\n\n this._crdtNotifier.subject(prop).next(serialized);\n\n acc[prop as keyof InferStorage<TDefs[\"storage\"]>] = serialized;\n\n return acc;\n },\n {} as InferJson<TDefs[\"storage\"]>,\n );\n\n this._crdtNotifier.rootSubject.next(storageRoot);\n }\n\n private _event = new Proxy(\n // oxlint-disable-next-line typescript/no-unnecessary-type-parameters -- callers pass a specific event\n <TEvent extends keyof InferClientOutput<TDefs>>(\n event: TEvent,\n callback: EventNotifierSubscriptionCallback<TDefs[\"io\"], any>,\n ): (() => void) => this._eventNotifier.subscribe(event, callback),\n {\n get(fn, prop) {\n return (\n callback: EventNotifierSubscriptionCallback<TDefs[\"io\"], any>,\n ): (() => void) => fn(prop as any, callback);\n },\n },\n ) as EventProxy<TDefs[\"io\"]>;\n\n private _flattenStorageStore = debounce(\n async (): Promise<void> => {\n const shouldFlatten = await this._storageStore.getShouldFlatten();\n\n if (!shouldFlatten) return;\n\n const updates = await this._storageStore.getUpdates();\n\n this._crdtManager.applyUpdate({ update: updates, origin: this });\n\n const encodedState = this._crdtManager.doc.getEncodedState();\n\n await this._storageStore.flatten(encodedState);\n },\n { wait: ADD_TO_STORAGE_STATE_DEBOUNCE_MS },\n );\n\n private _getAddon = (addons: readonly PluvRoomAddon<TDefs>[]): PluvRoomAddon<TDefs> => {\n return addons.reduce<PluvRoomAddon<TDefs>>(\n (acc, addon) => () => ({\n ...acc({ room: this }),\n ...addon({ room: this }),\n }),\n DEFAULT_PLUV_CLIENT_ADDON,\n );\n };\n\n private _getAuthFetchOptions(\n room: string,\n params: GetAuthEndpointParams<InferClientMetadata<TDefs>>,\n ): FetchOptions | null {\n const metadata = params.metadata as InferClientMetadata<TDefs>;\n\n if (typeof this._endpoints.authEndpoint === \"undefined\") return null;\n\n if (this._endpoints.authEndpoint === true) {\n return {\n url: `/api/pluv/authorize?room=${room}`,\n options: {},\n };\n }\n\n if (typeof this._endpoints.authEndpoint === \"string\") {\n return {\n url: this._endpoints.authEndpoint,\n options: {},\n };\n }\n\n const result = this._endpoints.authEndpoint({ metadata, room });\n\n return typeof result === \"string\" ? { url: result, options: {} } : result;\n }\n\n private async _getAuthorization(\n room: string,\n params: GetAuthEndpointParams<InferClientMetadata<TDefs>>,\n ): Promise<string | null> {\n const fetchOptions = this._getAuthFetchOptions(room, params);\n\n if (!fetchOptions) return null;\n\n const { url, options } = fetchOptions;\n const res = await fetch(url, options);\n\n if (!res.ok || res.status !== 200) throw new Error(\"Room is unauthorized\");\n\n try {\n return await res.text().then((text) => text.trim());\n } catch (err) {\n throw new Error(err instanceof Error ? err.message : \"Room is unauthorized\", {\n cause: err,\n });\n }\n }\n\n private _getWsEndpoint(\n room: string,\n params: GetWsEndpointParams<InferClientMetadata<TDefs>>,\n ): string {\n const metadata = params.metadata as InferClientMetadata<TDefs>;\n\n switch (typeof this._endpoints.wsEndpoint) {\n case \"undefined\":\n return `/api/pluv/room/${room}`;\n case \"string\":\n return this._endpoints.wsEndpoint;\n default:\n return this._endpoints.wsEndpoint({ metadata, room });\n }\n }\n\n private _handleExit(message: IOEventMessage<TDefs[\"io\"]>): void {\n const { connectionId } = message;\n\n if (!connectionId) return;\n // Should not reach here\n if (!this._state.webSocket) throw new Error(\"Could not find WebSocket\");\n\n const isMyself = this._usersManager.isMyselfConnection(connectionId);\n const deleted = this._usersManager.deleteConnection(connectionId);\n const others = this._usersManager.getOthers();\n\n this._stateNotifier.subjects.others.next(others);\n\n if (!deleted) {\n // Own sibling tabs live on `_myself`, not `_others`.\n if (isMyself) return;\n\n console.warn(\"Could not identify exited connection\");\n return;\n }\n\n const { data: user, remaining } = deleted;\n\n if (remaining) return;\n\n this._usersNotifier.others.next({\n others,\n event: { kind: \"leave\", user },\n });\n\n this._deleteOtherNotifier({\n id: this._usersManager.getParticipantId(user),\n kind: user.kind,\n });\n }\n\n private _handlePresenceUpdatedMessage(message: IOEventMessage<TDefs[\"io\"]>): void {\n const { connectionId } = message;\n\n if (!connectionId) return;\n // Should not reach here\n if (!this._state.webSocket) throw new Error(\"Could not find WebSocket\");\n\n const data = message.data as BaseIOEventRecord<\n InferIOAuthorize<TDefs[\"io\"]>\n >[\"$presenceUpdated\"];\n\n /**\n * This is our own presence coming back from the server. Ignore it if we\n * have already sent a newer local update, so a burst of writes (for\n * example dragging) cannot snap backward. Apply the last reply so we\n * can still pick up a newer value from another tab.\n */\n if (\n connectionId === this._state.connection.id &&\n !this._usersManager.ackOwnPresenceEcho()\n ) {\n return;\n }\n\n const patched = this._usersManager.patchPresence({\n connectionId,\n ...data,\n });\n\n if (!patched) {\n /**\n * !HACK\n * @description User could not be found. Add the connection to keep others up-to-date\n * @date April 19, 2025\n */\n const added = this._usersManager.addConnection({\n connectionId,\n data: message.user as Id<InferIOAuthorizeUser<InferIOAuthorize<TDefs[\"io\"]>>>,\n kind: data.session.kind,\n operator: data.session.operator,\n presence: data.session.presence as InferClientPresence<TDefs>,\n presenceSeq: data.session.seq.presence,\n });\n\n if (!added.presenceChanged) return;\n\n const other = this._usersManager.getOtherByConnectionId(connectionId, {\n kinds: [\"user\", \"operator\"],\n });\n const others = this._usersManager.getOthers();\n\n if (other) this._notifyOther(other);\n this._stateNotifier.subjects.others.next(others);\n\n this._usersNotifier.others.next({\n others,\n event: { kind: \"update\", user: added.data },\n });\n\n return;\n }\n\n if (!patched.applied) return;\n\n const updated = patched.presence;\n\n if (this._usersManager.isMyselfConnection(connectionId)) {\n this._stateNotifier.subjects[\"my-presence\"].next(updated);\n this._stateNotifier.subjects.myself.next(this._usersManager.myself);\n\n return;\n }\n\n const other = this._usersManager.getOtherByConnectionId(connectionId, {\n kinds: [\"user\", \"operator\"],\n });\n const others = this._usersManager.getOthers();\n\n if (other) this._notifyOther(other);\n this._stateNotifier.subjects.others.next(others);\n\n if (other) {\n this._usersNotifier.others.next({\n others,\n event: { kind: \"update\", user: other },\n });\n }\n }\n\n private _handleReceiveOthers(message: IOEventMessage<TDefs[\"io\"]>): void {\n // Should not reach here\n if (!this._state.webSocket) throw new Error(\"Could not find WebSocket\");\n\n const data = message.data as BaseIOEventRecord<\n InferIOAuthorize<TDefs[\"io\"]>\n >[\"$othersReceived\"];\n\n const leftIds = this._usersManager.replaceOthers(\n data.others.map((other) => ({\n connectionIds: other.connectionIds,\n data: other.data,\n kind: other.session.kind,\n operator: other.session.operator,\n presence: other.session.presence as InferClientPresence<TDefs> | null,\n presenceSeq: other.session.seq.presence,\n })),\n );\n this._usersManager.setMyConnectionIds(data.myConnectionIds);\n\n leftIds.forEach((subject) => {\n this._deleteOtherNotifier(subject);\n });\n\n data.others.forEach((row) => {\n const connectionId = row.connectionIds[0];\n if (!connectionId) return;\n\n const other = this._usersManager.getOtherByConnectionId(connectionId, {\n kinds: [\"user\", \"operator\"],\n });\n\n if (other) this._notifyOther(other);\n });\n\n const others = this._usersManager.getOthers();\n\n this._stateNotifier.subjects.others.next(others);\n this._usersNotifier.others.next({\n others,\n event: { kind: \"sync\", users: others },\n });\n }\n\n private async _handleRegisteredMessage(message: IOEventMessage<TDefs[\"io\"]>): Promise<void> {\n const { connectionId } = message;\n const user = message.user as Id<InferIOAuthorizeUser<InferIOAuthorize<TDefs[\"io\"]>>>;\n\n if (!connectionId) return;\n // Should not reach here\n if (!this._state.webSocket) throw new Error(\"Could not find WebSocket\");\n\n const data = message.data as BaseIOEventRecord<\n InferIOAuthorize<TDefs[\"io\"]>\n >[\"$registered\"];\n const state = data.state;\n\n this._setRoomStats(data.stats);\n\n this._updateState((oldState) => {\n oldState.connection.id = connectionId;\n oldState.authorization.user = user;\n oldState.authorization.kind = data.session.kind;\n oldState.authorization.operator = data.session.operator;\n\n return oldState;\n });\n\n this._usersManager.setMyself({\n connectionId,\n data: user,\n kind: data.session.kind,\n operator: data.session.operator,\n presence: (data.session.presence as InferClientPresence<TDefs> | null) ?? undefined,\n presenceSeq: data.session.seq.presence,\n });\n\n const presence = this._usersManager.myPresence;\n const myself = this._usersManager.myself ?? null;\n\n this._stateNotifier.subjects[\"my-presence\"].next(presence);\n this._stateNotifier.subjects.myself.next(myself);\n\n const update = await (async () => {\n if (state) {\n this._logDebug(\"Retrieving initial state\");\n return this._crdtManager.getInitialState();\n }\n\n const resolved = this._crdtManager.resolveEncodedState(\n await this._storageStore.getUpdates(),\n );\n\n if (resolved) {\n this._logDebug(\"Retrieving storage store state\");\n return resolved;\n }\n\n this._logDebug(\"Retrieving initial state\");\n return this._crdtManager.getInitialState();\n })();\n\n this._sendMessage({\n type: \"$initializeSession\",\n data: {\n presence,\n stateVector: this._crdtManager.doc.getStateVector(),\n update,\n },\n });\n }\n\n private async _handleStorageReceivedMessage(\n message: IOEventMessage<TDefs[\"io\"]>,\n ): Promise<void> {\n const { connectionId } = message;\n\n if (!connectionId) return;\n // Should not reach here\n if (!this._state.webSocket) throw new Error(\"Could not find WebSocket\");\n\n const data = message.data as BaseIOEventRecord<\n InferIOAuthorize<TDefs[\"io\"]>\n >[\"$storageReceived\"];\n const changeKind = data.changeKind;\n const state = data.state;\n\n const updates = await this._storageStore.getUpdates();\n const origin = ORIGIN_INITIALIZED;\n\n const updateStorage = (update: string | readonly string[]) => {\n return this._crdtManager.initialized\n ? this._crdtManager.applyUpdate({ update, origin })\n : this._crdtManager.initialize({ update, origin });\n };\n\n if (changeKind === \"empty\") {\n this._crdtManager.destroy();\n this._crdtManager.initialize({ origin, update: updates });\n } else if (changeKind === \"initialized\") {\n if (updates.length) updateStorage(updates);\n else {\n const encodedState = updateStorage(state).doc.getEncodedState();\n\n void this._addToStorageStore(encodedState);\n }\n } else {\n const encodedState = updateStorage(state).doc.getEncodedState();\n\n if (updates.length) this._crdtManager.applyUpdate({ update: updates, origin });\n\n void this._addToStorageStore(encodedState);\n }\n\n for (const update of this._storageSync.markReady()) {\n this._crdtManager.doc.applyEncodedState({\n origin: ORIGIN_STORAGE_UPDATED,\n update,\n });\n }\n\n const encodedState = this._crdtManager.doc.getEncodedState();\n\n // Must precede `_emitSharedTypes`, since `getStorage` returns null until loaded.\n this._updateState((oldState) => {\n oldState.storage.state = StorageState.Synced;\n\n return oldState;\n });\n this._emitSharedTypes();\n this._observeCrdt();\n this._stateNotifier.subjects[\"storage-loaded\"].next(true);\n this._settleStorageDiff({ fromDiff: false, moved: true });\n\n this._sendMessage({\n type: \"$updateStorage\",\n data: { origin, update: encodedState },\n });\n }\n\n private _handleStorageUpdatedMessage(message: IOEventMessage<TDefs[\"io\"]>): void {\n const { connectionId } = message;\n\n if (!connectionId) return;\n // Should not reach here\n if (!this._state.webSocket) throw new Error(\"Could not find WebSocket\");\n\n const data = message.data as BaseIOEventRecord<\n InferIOAuthorize<TDefs[\"io\"]>\n >[typeof ORIGIN_STORAGE_UPDATED];\n\n if (!this._storageSync.isReady) {\n this._storageSync.hold(data.state);\n\n return;\n }\n\n this._applyRemoteStorage(data.state, { fromDiff: false });\n }\n\n private _handleStorageDiffMessage(message: IOEventMessage<TDefs[\"io\"]>): void {\n const { connectionId } = message;\n\n if (!connectionId) return;\n // Should not reach here\n if (!this._state.webSocket) throw new Error(\"Could not find WebSocket\");\n\n const data = message.data as BaseIOEventRecord<\n InferIOAuthorize<TDefs[\"io\"]>\n >[\"$storageDiff\"];\n\n if (!this._storageSync.isReady) {\n if (data.update) this._storageSync.hold(data.update);\n\n return;\n }\n\n if (!data.update) {\n if (this._crdtManager.doc.hasPending() || !this._crdtManager.doc.canDetectPending()) {\n this._noteUnchangedStorage();\n }\n\n return;\n }\n\n this._applyRemoteStorage(data.update, { fromDiff: true });\n }\n\n private _handleStorageResyncMessage(message: IOEventMessage<TDefs[\"io\"]>): void {\n const { connectionId } = message;\n\n if (!connectionId || connectionId !== this._state.connection.id) return;\n if (!this._state.webSocket) return;\n\n const data = message.data as BaseIOEventRecord<\n InferIOAuthorize<TDefs[\"io\"]>\n >[\"$storageResync\"];\n const stateVector = data.stateVector;\n\n if (!stateVector) return;\n\n const update = this._crdtManager.doc.encodeDiff(stateVector);\n\n if (!update) return;\n\n this._sendMessage({\n type: \"$updateStorage\",\n data: { origin: connectionId, resync: true, update },\n });\n }\n\n private _applyRemoteStorage(update: string, params: { fromDiff: boolean }): void {\n const before = this._crdtManager.doc.getStateVector();\n\n this._crdtManager.doc.applyEncodedState({\n origin: ORIGIN_STORAGE_UPDATED,\n update,\n });\n\n const moved = this._crdtManager.doc.getStateVector() !== before;\n const sharedTypes = this._crdtManager.doc.get();\n\n const storageRoot = Object.keys(sharedTypes).reduce(\n (acc, prop) => {\n const serialized = this._crdtManager.doc.toJson(prop);\n\n this._crdtNotifier.subject(prop).next(serialized);\n\n acc[prop as keyof InferStorage<TDefs[\"storage\"]>] = serialized;\n\n return acc;\n },\n {} as InferJson<TDefs[\"storage\"]>,\n );\n\n this._crdtNotifier.rootSubject.next(storageRoot);\n this._settleStorageDiff({ fromDiff: params.fromDiff, moved });\n }\n\n private _noteUnchangedStorage(): void {\n if (!this._storageSync.noteStall()) return;\n\n console.warn(\"Storage update did not change the document\");\n }\n\n private _settleStorageDiff(params: { fromDiff: boolean; moved: boolean }): void {\n const { fromDiff, moved } = params;\n const doc = this._crdtManager.doc;\n const pending = doc.hasPending() || !doc.canDetectPending();\n\n if (!pending) {\n this._storageSync.clearStall();\n\n return;\n }\n\n // The server answered and the document did not move. It has nothing new.\n if (fromDiff && !moved) {\n this._noteUnchangedStorage();\n\n return;\n }\n\n this._storageSync.clearStall();\n this._requestStorageDiff();\n }\n\n private _requestStorageDiff(): void {\n const webSocket = this._state.webSocket;\n\n if (!webSocket || webSocket.readyState !== WebSocket.OPEN) return;\n\n this._sendMessage({\n type: \"$syncStorage\",\n data: {\n stateVector: this._crdtManager.doc.canDetectPending()\n ? this._crdtManager.doc.getStateVector()\n : \"\",\n },\n });\n }\n\n private _handleSyncStateReceived(message: IOEventMessage<TDefs[\"io\"]>): void {\n // Should not reach here\n if (!this._state.webSocket) throw new Error(\"Could not find WebSocket\");\n if (!this._usersManager.myself) return;\n\n const data = message.data as BaseIOEventRecord<\n InferIOAuthorize<TDefs[\"io\"]>\n >[\"$syncStateReceived\"];\n const active = new Set(data?.connectionIds ?? []);\n const left = this._usersManager.pruneConnections(active);\n\n left.forEach((quitter) => {\n const remaining = this._usersManager.getOthers();\n\n this._deleteOtherNotifier({\n id: this._usersManager.getParticipantId(quitter),\n kind: quitter.kind,\n });\n this._usersNotifier.others.next({\n others: remaining,\n event: { kind: \"leave\", user: quitter },\n });\n });\n\n const remaining = this._usersManager.getOthers();\n\n this._stateNotifier.subjects.others.next(remaining);\n }\n\n private _handleRoomError(message: IOEventMessage<TDefs[\"io\"]>): void {\n const data = message.data as BaseIOEventRecord<InferIOAuthorize<TDefs[\"io\"]>>[\"$error\"];\n\n this._errorSubject.next({\n message: data.message,\n stack: data.stack ?? null,\n });\n }\n\n private _handleRoomStats(message: IOEventMessage<TDefs[\"io\"]>): void {\n const data = message.data as BaseIOEventRecord<InferIOAuthorize<TDefs[\"io\"]>>[\"$roomStats\"];\n\n this._setRoomStats(data);\n }\n\n private _handleUsersPage(message: IOEventMessage<TDefs[\"io\"]>): void {\n const data = message.data as BaseIOEventRecord<InferIOAuthorize<TDefs[\"io\"]>>[\"$usersPage\"];\n\n this._requests.complete(\n data.requestId,\n data.success\n ? { success: true, pageInfo: data.pageInfo, users: data.users }\n : { success: false, error: data.error },\n );\n }\n\n private _handleUserJoinedMessage(message: IOEventMessage<TDefs[\"io\"]>): void {\n const { connectionId } = message;\n\n if (!connectionId) return;\n // Should not reach here\n if (!this._state.webSocket) throw new Error(\"Could not find WebSocket\");\n if (!this._usersManager.myself) return;\n\n const data = message.data as BaseIOEventRecord<\n InferIOAuthorize<TDefs[\"io\"]>\n >[\"$userJoined\"];\n\n if (connectionId === this._state.connection.id) {\n this._sendMessage({ type: \"$getOthers\", data: {} });\n return;\n }\n\n const added = this._usersManager.addConnection({\n connectionId,\n data: data.user,\n kind: data.session.kind,\n operator: data.session.operator,\n presence: data.session.presence as InferClientPresence<TDefs>,\n presenceSeq: data.session.seq.presence,\n });\n\n if (added.isMyself) return;\n\n const other = this._usersManager.getOtherByConnectionId(connectionId, {\n kinds: [\"user\", \"operator\"],\n });\n const others = this._usersManager.getOthers();\n\n if (added.remaining !== 1) {\n if (!added.presenceChanged || !other) return;\n\n this._notifyOther(other);\n this._stateNotifier.subjects.others.next(others);\n this._usersNotifier.others.next({\n others,\n event: { kind: \"update\", user: other },\n });\n\n return;\n }\n\n if (other) this._notifyOther(other);\n this._stateNotifier.subjects.others.next(others);\n this._usersNotifier.others.next({\n others,\n event: { kind: \"enter\", user: added.data },\n });\n }\n\n private _heartbeat(): void {\n this._clearTimeout(this._timeouts.pong);\n this._timeouts.pong = setTimeout(\n this._reconnect.bind(this),\n PONG_TIMEOUT_MS,\n ) as unknown as number;\n\n /**\n * !HACK\n * @description Send data as a stable string so that the server can react to this in a\n * consistent way.\n * @date July 8, 2024\n */\n this._sendMessage('{\"type\":\"$ping\",\"data\":{}}');\n }\n\n private _logDebug(...data: any[]): void {\n if (typeof process === \"undefined\") return;\n if (process.env?.NODE_ENV === \"production\") return;\n if (this._debug) console.log(...data);\n }\n\n private _observeCrdt(): void {\n this._subscriptions.observeCrdt?.();\n\n const unsubscribe = this._crdtManager.doc.subscribe((event) => {\n const origin = event.origin ?? null;\n\n this._emitSharedTypes();\n\n if (origin === ORIGIN_INITIALIZED || origin === ORIGIN_STORAGE_UPDATED) {\n return;\n }\n\n void this._addToStorageStore(event.update);\n\n const canSend =\n !!this._state.webSocket &&\n !!this._state.connection.id &&\n this._state.webSocket.readyState === WebSocket.OPEN;\n\n if (!canSend) {\n this._logDebug(\"Dropped a storage update: storage is not syncing\");\n\n return;\n }\n\n this._sendMessage({\n type: \"$updateStorage\",\n data: {\n origin,\n update: event.update,\n ...(this._storageProcedureNames.at(-1)\n ? { procedure: this._storageProcedureNames.at(-1) }\n : {}),\n },\n });\n });\n\n this._subscriptions.observeCrdt = unsubscribe;\n }\n\n private _onAuthorizationFail(error: unknown): void {\n const authError = error instanceof Error ? error : new Error(\"Authorization failed\");\n\n this._listeners.onAuthorizationFail(authError);\n\n this._updateState((oldState) => {\n oldState.connection.state = ConnectionState.Unavailable;\n oldState.storage.state = StorageState.Unavailable;\n\n return oldState;\n });\n }\n\n private async _onClose(event: CloseEvent): Promise<void> {\n this._listenerManager.subjects.close.next(event);\n\n this._logDebug(\"WebSocket closed\");\n if (event.reason) this._logDebug(event.reason);\n\n const shouldRetry = [\n // Going away: Client/server is shutting down or navigating\n 1001,\n // Abnormal closure: Usually network error\n 1006,\n // Internal error: may be a larger problem, but try reconnecting for now\n 1011,\n // Service restart: Server restarted\n 1012,\n // Try again later: server overloaded\n 1013,\n // Bad gateway\n 1014,\n ].some((okToRetryCode) => event.code === okToRetryCode);\n\n this._updateState((oldState) => {\n oldState.authorization.token = null;\n oldState.connection.state = shouldRetry\n ? ConnectionState.Unavailable\n : /**\n * !HACK\n * @description Assume these are not recoverable. We're just going to mark this\n * as Closed to avoid reconnect attempts.\n * @date April 28, 2025\n */\n ConnectionState.Closed;\n oldState.storage.state =\n oldState.storage.state === StorageState.Synced\n ? StorageState.Offline\n : StorageState.Unavailable;\n oldState.webSocket = null;\n\n return oldState;\n });\n\n if (shouldRetry) {\n await this._reconnect();\n return;\n }\n\n this._closeWs();\n this._clearTimeout(this._timeouts.reconnect);\n }\n\n /**\n * TODO\n * @description Handle websocket errors in a meaningful way, should they occur\n * @date August 19, 2022\n */\n private _onError(event: Event): void {\n this._listenerManager.subjects.error.next(event);\n }\n\n private _onMessage(event: MessageEvent<string>): void {\n this._listenerManager.subjects.message.next(event);\n\n const message = this._parseMessage(event);\n\n if (!message) return;\n\n const shouldLog =\n typeof this._debug === \"boolean\"\n ? this._debug\n : this._debug.output.find((value) => value === message.type);\n\n if (shouldLog) {\n this._logDebug(\"WebSocket event received: \", message.type, message);\n }\n\n if (!message.type.startsWith(\"$\")) {\n this._eventNotifier\n .subject(message.type as keyof InferClientOutput<TDefs>)\n .next(message as any);\n }\n\n switch (message.type) {\n case \"$error\": {\n this._handleRoomError(message);\n return;\n }\n case \"$exit\": {\n this._handleExit(message);\n return;\n }\n case \"$othersReceived\": {\n this._handleReceiveOthers(message);\n return;\n }\n case \"$pong\": {\n this._clearTimeout(this._timeouts.pong);\n return;\n }\n case \"$presenceUpdated\": {\n this._handlePresenceUpdatedMessage(message);\n return;\n }\n case \"$registered\": {\n void this._handleRegisteredMessage(message);\n return;\n }\n case \"$roomStats\": {\n this._handleRoomStats(message);\n return;\n }\n case \"$storageReceived\": {\n void this._handleStorageReceivedMessage(message);\n return;\n }\n case \"$storageDiff\": {\n this._handleStorageDiffMessage(message);\n return;\n }\n case \"$storageResync\": {\n this._handleStorageResyncMessage(message);\n return;\n }\n case \"$storageUpdated\": {\n this._handleStorageUpdatedMessage(message);\n return;\n }\n case \"$syncStateReceived\": {\n this._handleSyncStateReceived(message);\n return;\n }\n case \"$userJoined\": {\n this._handleUserJoinedMessage(message);\n return;\n }\n case \"$usersPage\": {\n this._handleUsersPage(message);\n return;\n }\n default:\n }\n }\n\n private _onOpen(event: Event): void {\n this._listenerManager.subjects.open.next(event);\n\n if (this._state.connection.state !== ConnectionState.Connecting) return;\n\n this._logDebug(\"WebSocket connected\");\n this._updateState((oldState) => {\n oldState.connection.state = ConnectionState.Open;\n\n return oldState;\n });\n\n this._clearInterval(this._intervals.heartbeat);\n this._intervals.heartbeat = setInterval(\n this._heartbeat.bind(this),\n HEARTBEAT_INTERVAL_MS,\n ) as unknown as number;\n }\n\n private async _onNavigatorOffline(): Promise<void> {\n if (this._state.connection.state === ConnectionState.Closed) return;\n\n this._updateState((oldState) => {\n oldState.connection.state = ConnectionState.Unavailable;\n oldState.storage.state =\n oldState.storage.state === StorageState.Synced\n ? StorageState.Offline\n : StorageState.Unavailable;\n\n return oldState;\n });\n }\n\n private async _onNavigatorOnline(): Promise<void> {\n if (this._state.connection.state !== ConnectionState.Unavailable) return;\n\n await this._reconnect();\n }\n\n private async _onVisibilityChange(): Promise<void> {\n if (typeof document === \"undefined\") return;\n if (document.visibilityState !== \"visible\") return;\n\n switch (this._state.connection.state) {\n case ConnectionState.Open: {\n this._clearInterval(this._intervals.heartbeat);\n setInterval(this._heartbeat.bind(this), HEARTBEAT_INTERVAL_MS);\n\n return;\n }\n case ConnectionState.Unavailable: {\n await this._reconnect();\n\n return;\n }\n default:\n }\n }\n\n private async _onWindowFocus(): Promise<void> {\n return await this._onVisibilityChange();\n }\n\n private _other = (\n userId: string,\n callback: OtherSubscriptionCallback<TDefs[\"io\"], InferClientPresence<TDefs>>,\n options?: ParticipantKindOptions,\n ): (() => void) => {\n return this._usersNotifier.subscribeOther(userId, callback, options);\n };\n\n private _parseMessage(message: {\n data: string | ArrayBuffer;\n }): IOEventMessage<TDefs[\"io\"]> | null {\n /**\n * !HACK\n * @description We'll only handle stringified JSONs for now\n * @date August 9, 2022\n */\n if (typeof message.data !== \"string\") return null;\n\n try {\n const config = JSON.parse(message.data);\n\n if (typeof config !== \"object\") return null;\n if (typeof config.type !== \"string\") return null;\n if (typeof config.data !== \"object\") return null;\n\n return config as IOEventMessage<TDefs[\"io\"]>;\n } catch {\n return null;\n }\n }\n\n private _pollReconnect(): void {\n this._clearTimeout(this._timeouts.reconnect);\n\n const timeoutMs =\n typeof this._reconnectTimeoutMs === \"number\"\n ? this._reconnectTimeoutMs\n : this._reconnectTimeoutMs({ attempts: this._state.connection.attempts });\n const clampedMs = Math.max(\n Math.min(MIN_RECONNECT_TIMEOUT_MS, timeoutMs),\n MAX_RECONNECT_TIMEOUT_MS,\n );\n\n this._timeouts.reconnect = setTimeout(\n this._reconnect.bind(this),\n clampedMs,\n ) as unknown as number;\n }\n\n private async _reconnect(): Promise<void> {\n this._closeWs();\n\n /**\n * @description User has manually closed this connection. We're not going to retry, since\n * the user probably intends for this to stay closed. They will need to invoke connect\n * themselves.\n * @date April 28, 2025\n */\n if (this._state.connection.state === ConnectionState.Closed) return;\n\n const metadata = this._lastMetadata;\n const params = (typeof metadata === \"undefined\" ? [] : [{ metadata }]) as RoomConnectParams<\n InferClientMetadata<TDefs>\n >;\n\n await this.connect(...params);\n }\n\n private async _runPresenceProcedure(name: string, data: unknown): Promise<void> {\n const procedures = this._treaty._defs.procedures.presence;\n\n if (!procedures || !Object.hasOwn(procedures, name)) {\n throw new Error(`Unknown presence procedure \"${name}\"`);\n }\n\n const procedure = procedures[name];\n const myself = this._usersManager.myself;\n\n if (!myself) {\n throw new Error(\"Cannot run a treaty procedure before the local user is available\");\n }\n\n const doc = this._crdtManager.doc;\n const seq = ++this._seq.presence;\n const patch = await procedure.apply(data, {\n user: myself.data,\n operator: myself.operator,\n presence: this.getMyPresence(),\n doc,\n });\n\n if (seq !== this._seq.presence) return;\n\n await this._applyMyPresence(patch as InferClientPresence<TDefs>, name);\n }\n\n private _runStorageProcedure(name: string, data: unknown): void {\n if (!this.getStorageLoaded()) {\n throw new Error(\"Cannot run a treaty storage procedure until storage is loaded\");\n }\n\n const origin = this._state.connection.id;\n\n if (typeof origin !== \"string\") {\n throw new Error(\"Cannot run a treaty storage procedure without a connection id\");\n }\n\n const procedures = this._treaty._defs.procedures.storage;\n\n if (!procedures || !Object.hasOwn(procedures, name)) {\n throw new Error(`Unknown storage procedure \"${name}\"`);\n }\n\n const procedure = procedures[name];\n const myself = this._usersManager.myself;\n\n if (!myself) {\n throw new Error(\"Cannot run a treaty procedure before the local user is available\");\n }\n\n const presence = this.getMyPresence();\n const commit = (loaded?: { input: unknown; prepared: unknown }): void => {\n // Silent. This storage is not synced yet, so the write would not land.\n if (!this.getStorageLoaded()) return;\n\n const doc = this._crdtManager.doc;\n const apply = (): void => {\n procedure.apply(\n loaded ? loaded.input : data,\n {\n user: myself.data,\n operator: myself.operator,\n presence,\n doc,\n },\n loaded?.prepared,\n );\n };\n\n this._storageProcedureNames.push(name);\n\n try {\n if (procedure.config.transact === false) {\n apply();\n\n return;\n }\n\n this.transact(() => {\n apply();\n });\n } finally {\n this._storageProcedureNames.pop();\n }\n };\n\n if (!procedure.prepared || !procedure.load) {\n commit(undefined);\n\n return;\n }\n\n const loading = procedure.load(data, {\n user: myself.data,\n operator: myself.operator,\n presence,\n });\n\n this._storageCommits = sequenceCommit({\n tail: this._storageCommits,\n ready: loading,\n commit,\n });\n }\n\n private _sendMessage(data: string): void;\n // oxlint-disable-next-line typescript/no-unnecessary-type-parameters -- callers pass a specific message\n private _sendMessage<TMessage extends EventMessage<string, any> = EventMessage<string, any>>(\n data: TMessage,\n ): void;\n private _sendMessage(data: any): void {\n const webSocket = this._state.webSocket;\n\n if (webSocket?.readyState !== WebSocket.OPEN) return;\n\n const dataType: string | null = ((): string | null => {\n if (typeof data === \"object\") return data.type ?? null;\n if (typeof data !== \"string\") return null;\n\n try {\n return JSON.parse(data)?.type ?? null;\n } catch {\n return null;\n }\n })();\n\n const shouldLog: boolean =\n typeof this._debug === \"boolean\"\n ? this._debug\n : !dataType\n ? false\n : this._debug.input.some((value) => value === data.type);\n\n if (shouldLog) this._logDebug(\"WebSocket event sent: \", data.type, data);\n\n const message = typeof data === \"string\" ? data : JSON.stringify(data);\n\n webSocket.send(message);\n }\n\n private _setMetadata(metadata: InferClientMetadata<TDefs>): InferClientMetadata<TDefs> {\n const parsed = this.metadata ? parsePluvSchema(this.metadata, metadata) : metadata;\n\n this._lastMetadata = parsed;\n\n return parsed;\n }\n\n #_storage = new Proxy(\n <TKey extends keyof InferJson<TDefs[\"storage\"]>>(\n key: TKey,\n callback: StorageSubscriptionCallback<InferJson<TDefs[\"storage\"]>, TKey>,\n ): (() => void) => this._crdtNotifier.subscribe(key, callback),\n {\n get: (fn, prop) => {\n type _Json = InferJson<TDefs[\"storage\"]>;\n\n if (prop) {\n return (callback: StorageRootSubscriptionCallback<_Json>) => {\n return this._crdtNotifier.subcribeRoot(callback);\n };\n }\n\n return (callback: StorageSubscriptionCallback<_Json, keyof _Json>) => {\n return fn(prop as keyof InferJson<TDefs[\"storage\"]>, callback);\n };\n },\n },\n ) as StorageProxy<InferJson<TDefs[\"storage\"]>>;\n\n private _setRoomStats(stats: RoomStatsByKind): void {\n this._roomStats = stats.user;\n this._operatorStats = stats.operator;\n this._stateNotifier.subjects.roomStats.next(this._roomStats);\n }\n\n private _notifyOther(other: Id<UserInfo<TDefs[\"io\"], InferClientPresence<TDefs>>>): void {\n this._usersNotifier\n .other({\n id: this._usersManager.getParticipantId(other),\n kind: other.kind,\n })\n .next(other);\n }\n\n private _deleteOtherNotifier(params: OtherSubjectParams): void {\n this._usersNotifier.delete(params);\n }\n\n private _updateState(\n updater: (oldState: WebSocketState<TDefs[\"io\"]>) => WebSocketState<TDefs[\"io\"]>,\n ): WebSocketState<TDefs[\"io\"]> {\n let authorization: AuthorizationState<TDefs[\"io\"]>;\n\n try {\n authorization = JSON.parse(JSON.stringify(this._state.authorization));\n } catch {\n throw new Error(\"User is not JSON serializable\");\n }\n\n const oldState: WebSocketState<TDefs[\"io\"]> = {\n ...this._state,\n authorization,\n connection: JSON.parse(JSON.stringify(this._state.connection)),\n storage: JSON.parse(JSON.stringify(this._state.storage)),\n webSocket: this._state.webSocket,\n };\n\n const newState = updater(oldState);\n this._state = newState;\n\n this._logDebug(\"WebSocket new state: \", newState);\n this._stateNotifier.subjects.connection.next(newState);\n\n return newState;\n }\n}\n","import type { AbstractCrdtDocFactory, HasStorage, InferSeed, NoopCrdtDocFactory } from \"@pluv/crdt\";\nimport { noop } from \"@pluv/crdt\";\nimport type { IOLike, InferIOTreaty, StandardSchemaV1, TreatyLike } from \"@pluv/types\";\nimport type { ClientDefs } from \"./ClientDefs\";\nimport { MAX_PRESENCE_SIZE_BYTES } from \"./constants\";\nimport type { InferIOLike } from \"./infer\";\nimport { assertSerializingSchema } from \"./utils/assertSerializingSchema\";\nimport type {\n AuthEndpoint,\n PluvRoomAddon,\n PluvRoomDebug,\n ReconnectTimeoutMs,\n RoomConfig,\n RoomEndpoints,\n WsEndpoint,\n} from \"./PluvRoom\";\nimport { PluvRoom } from \"./PluvRoom\";\nimport type {\n InferClientMetadata,\n InferSchemaInput,\n InferSchemaOutput,\n PluvClientLimits,\n WithMetadata,\n} from \"./types\";\n\nexport type InferMetadata<TClient extends PluvClient<any>> =\n TClient extends PluvClient<infer TDefs> ? InferSchemaOutput<TDefs[\"metadata\"]> : never;\n\nexport type PluvClientOptions<TDefs extends ClientDefs> = RoomEndpoints<\n InferClientMetadata<TDefs>\n> & {\n debug?: boolean;\n /**\n * @description Configurable limits defined for client-side validation. You should only set\n * this if you control the server and have changed the limits there.\n */\n limits?: PluvClientLimits;\n metadata?: TDefs[\"metadata\"];\n treaty: TDefs[\"treaty\"];\n} & (HasStorage<TDefs[\"treaty\"][\"storage\"]> extends true\n ? { initialStorage?: InferSeed<TDefs[\"storage\"]> }\n : { initialStorage?: \"[ERROR]: Must provide storage on treaty to use initialStorage\" });\n\nexport type CreateRoomOptions<TDefs extends ClientDefs = ClientDefs> = {\n addons?: readonly PluvRoomAddon<any>[];\n debug?: boolean | PluvRoomDebug<TDefs[\"io\"]>;\n initialPresence?: InferSchemaInput<TDefs[\"presence\"]>;\n initialStorage?: InferSeed<TDefs[\"storage\"]>;\n onAuthorizationFail?: (error: Error) => void;\n reconnectTimeoutMs?: ReconnectTimeoutMs;\n};\n\nexport type EnterRoomParams<TMetadata extends Record<string, any> = {}> =\n keyof TMetadata extends never ? [] : [WithMetadata<TMetadata>];\n\nexport type ConfiguredClientDefs<\n TIO extends IOLike,\n TTreaty extends TreatyLike,\n TMetadataSchema extends StandardSchemaV1<any, any> | undefined,\n> = {\n io: InferIOLike<TIO>;\n treaty: TTreaty;\n presence: TTreaty[\"presence\"];\n metadata: TMetadataSchema;\n storage: TTreaty[\"storage\"] extends AbstractCrdtDocFactory<any, any, any, any>\n ? TTreaty[\"storage\"]\n : NoopCrdtDocFactory;\n};\n\nexport class PluvClient<TDefs extends ClientDefs = ClientDefs> {\n public readonly metadata?: TDefs[\"metadata\"];\n\n private readonly _authEndpoint: AuthEndpoint<InferClientMetadata<TDefs>>;\n private readonly _debug: boolean;\n private readonly _initialStorage?: InferSeed<TDefs[\"storage\"]>;\n private readonly _limits: PluvClientLimits;\n private readonly _rooms = new Map<string, PluvRoom<TDefs>>();\n private readonly _treaty: TDefs[\"treaty\"];\n private readonly _wsEndpoint: WsEndpoint<InferClientMetadata<TDefs>> | undefined;\n\n public get _defs() {\n return {\n initialStorage: this._initialStorage,\n storage: this._treaty.storage,\n treaty: this._treaty,\n };\n }\n\n constructor(options: PluvClientOptions<TDefs>) {\n const {\n authEndpoint,\n debug = false,\n initialStorage,\n limits,\n metadata,\n treaty,\n wsEndpoint,\n } = options as PluvClientOptions<TDefs> & {\n initialStorage?: InferSeed<TDefs[\"storage\"]>;\n };\n\n this.metadata = metadata;\n\n if (metadata) {\n assertSerializingSchema(metadata);\n }\n\n this._authEndpoint = authEndpoint;\n this._debug = debug;\n this._initialStorage = initialStorage as InferSeed<TDefs[\"storage\"]> | undefined;\n this._limits = {\n presenceMaxSize: MAX_PRESENCE_SIZE_BYTES,\n ...limits,\n };\n this._treaty = treaty;\n this._wsEndpoint = wsEndpoint;\n }\n\n public createRoom = (room: string, options: CreateRoomOptions<TDefs> = {}): PluvRoom<TDefs> => {\n const oldRoom = this.getRoom(room);\n\n if (oldRoom) return oldRoom;\n\n const newRoom = new PluvRoom<TDefs>(room, {\n addons: options.addons,\n authEndpoint: this._authEndpoint,\n debug: options.debug,\n initialPresence: options.initialPresence,\n initialStorage: options.initialStorage ?? this._initialStorage,\n limits: this._limits,\n metadata: this.metadata,\n onAuthorizationFail: options.onAuthorizationFail,\n presence: this._treaty.presence,\n reconnectTimeoutMs: options.reconnectTimeoutMs,\n storage:\n (this._treaty.storage as TDefs[\"storage\"] | undefined) ??\n (noop.doc() as TDefs[\"storage\"]),\n treaty: this._treaty,\n wsEndpoint: this._wsEndpoint,\n } as RoomConfig<TDefs>);\n\n this._rooms.set(room, newRoom);\n\n this._logDebug(`New room was created: ${room}`);\n\n return newRoom;\n };\n\n public enter = async (\n room: string | PluvRoom<TDefs>,\n ...args: EnterRoomParams<InferSchemaInput<TDefs[\"metadata\"]>>\n ): Promise<PluvRoom<TDefs>> => {\n const toEnter = typeof room === \"string\" ? this.getRoom(room) : room;\n const roomId = typeof room === \"string\" ? room : room.id;\n\n if (!toEnter) throw new Error(`Could not find room: ${roomId}.`);\n\n this._rooms.set(toEnter.id, toEnter);\n await toEnter.connect(...(args as any));\n\n this._logDebug(`Entered room: ${roomId}`);\n\n return toEnter;\n };\n\n public getRoom = (room: string): PluvRoom<TDefs> | null => {\n return this._rooms.get(room) ?? null;\n };\n\n public getRooms = (): readonly PluvRoom<TDefs>[] => {\n return Array.from(this._rooms.values());\n };\n\n public leave = async (room: string | PluvRoom<any>): Promise<void> => {\n const toLeave = typeof room === \"string\" ? this.getRoom(room) : room;\n\n if (!toLeave) return;\n\n await toLeave.disconnect();\n\n this._rooms.delete(toLeave.id);\n\n this._logDebug(`Left and deleted room: ${toLeave.id}`);\n };\n\n private _logDebug(...data: any[]): void {\n if (typeof process === \"undefined\") return;\n if (process.env?.NODE_ENV === \"production\") return;\n\n if (this._debug) console.log(...data);\n }\n}\n\nexport interface CreateClientBuilder<TIO extends IOLike> {\n config: <\n TTreaty extends InferIOTreaty<TIO>,\n TMetadataSchema extends StandardSchemaV1<any, any> | undefined = undefined,\n >(\n options: PluvClientOptions<ConfiguredClientDefs<TIO, TTreaty, TMetadataSchema>>,\n ) => PluvClient<ConfiguredClientDefs<TIO, TTreaty, TMetadataSchema>>;\n}\n","import type { IOLike } from \"@pluv/types\";\nimport type { CreateClientBuilder } from \"./PluvClient\";\nimport { PluvClient } from \"./PluvClient\";\n\nexport const createClient = <TIO extends IOLike = any>(): CreateClientBuilder<TIO> => ({\n config: ((options) => new PluvClient(options as any)) as CreateClientBuilder<TIO>[\"config\"],\n});\n","import type { InferDoc, InferJson, InferStorage } from \"@pluv/crdt\";\nimport type {\n BroadcastProxy,\n CrdtDocLike,\n EventNotifierSubscriptionCallback,\n EventProxy,\n Id,\n IOEventMessage,\n ListUsersOptions,\n ListUsersResult,\n OtherSubscriptionCallback,\n OthersSubscriptionCallback,\n PresenceProcedureProxy,\n RoomError,\n RoomErrorSubscriptionCallback,\n RoomEventListenerMap,\n OperatorUser,\n ParticipantKind,\n ParticipantKindOptions,\n ParticipantKindsOptions,\n RoomLike,\n RoomStats,\n StateNotifierSubjects,\n StorageProcedureProxy,\n StorageProxy,\n StorageRootSubscriptionCallback,\n StorageSubscriptionCallback,\n SubscribeProxy,\n SubscriptionCallback,\n UpdateMyPresenceAction,\n UserInfo,\n WebSocketConnection,\n WebSocketState,\n} from \"@pluv/types\";\nimport { ConnectionState, StorageState } from \"@pluv/types\";\nimport { makeSubject, subscribe } from \"wonka\";\nimport type { ClientDefs } from \"./ClientDefs\";\nimport type { CrdtManagerOptions } from \"./CrdtManager\";\nimport { CrdtManager } from \"./CrdtManager\";\nimport { CrdtNotifier } from \"./CrdtNotifier\";\nimport { EventNotifier } from \"./EventNotifier\";\nimport { StateNotifier } from \"./StateNotifier\";\nimport type { UsersManagerConfig } from \"./UsersManager\";\nimport { UsersManager } from \"./UsersManager\";\nimport { UsersNotifier } from \"./UsersNotifier\";\nimport { MAX_PRESENCE_SIZE_BYTES } from \"./constants\";\nimport type {\n InferClientInput,\n InferClientOutput,\n InferClientPresence,\n InternalSubscriptions,\n PluvClientLimits,\n} from \"./types\";\nimport { assertExhaustive, sequenceCommit } from \"./utils\";\n\nexport type MockedRoomEvents<TDefs extends ClientDefs = ClientDefs> = Partial<{\n [P in keyof InferClientInput<TDefs>]: (\n data: Id<InferClientInput<TDefs>[P]>,\n ) => Partial<InferClientOutput<TDefs>>;\n}>;\n\nexport type MockedRoomConfig<TDefs extends ClientDefs = ClientDefs> = {\n events?: MockedRoomEvents<TDefs>;\n limits?: PluvClientLimits;\n myself?: {\n connectionId?: string;\n data: UserInfo<TDefs[\"io\"], InferClientPresence<TDefs>>[\"data\"];\n kind?: ParticipantKind;\n operator?: OperatorUser | null;\n };\n treaty: TDefs[\"treaty\"];\n} & Pick<CrdtManagerOptions<TDefs[\"storage\"]>, \"initialStorage\" | \"storage\"> &\n Omit<UsersManagerConfig<InferClientPresence<TDefs>>, \"limits\">;\n\nconst participantOrder = (kind: ParticipantKind): number => {\n switch (kind) {\n case \"user\":\n return 0;\n case \"operator\":\n return 1;\n default:\n return assertExhaustive(kind);\n }\n};\n\nexport class MockedRoom<TDefs extends ClientDefs = ClientDefs> implements RoomLike<\n TDefs[\"io\"],\n InferDoc<TDefs[\"storage\"]>,\n InferClientPresence<TDefs>,\n InferStorage<TDefs[\"storage\"]>,\n InferJson<TDefs[\"storage\"]>,\n TDefs[\"treaty\"]\n> {\n public readonly id: string;\n\n private readonly _crdtManager: CrdtManager<TDefs[\"storage\"]>;\n private readonly _crdtNotifier = new CrdtNotifier<InferJson<TDefs[\"storage\"]>>();\n private readonly _eventNotifier = new EventNotifier<TDefs[\"io\"]>();\n private readonly _errorSubject = makeSubject<RoomError>();\n private readonly _events?: MockedRoomEvents<TDefs>;\n private readonly _limits: PluvClientLimits;\n private readonly _usersNotifier = new UsersNotifier<TDefs[\"io\"], InferClientPresence<TDefs>>();\n private readonly _treaty: TDefs[\"treaty\"];\n // Local sequences. `presence` drops an older resolver result once a newer call has started.\n private _seq = { presence: 0 };\n /** Prepared commits wait here so an earlier call writes before a later one. */\n private _storageCommits: Promise<void> = Promise.resolve();\n private _state: WebSocketState<TDefs[\"io\"]> = {\n authorization: {\n token: null,\n user: null,\n kind: \"user\",\n operator: null,\n },\n connection: {\n attempts: 0,\n id: null,\n state: ConnectionState.Untouched,\n },\n storage: {\n state: StorageState.Unavailable,\n },\n webSocket: null,\n };\n private readonly _stateNotifier = new StateNotifier<TDefs[\"io\"], InferClientPresence<TDefs>>();\n private readonly _subscriptions: InternalSubscriptions = {\n observeCrdt: null,\n };\n private readonly _usersManager: UsersManager<TDefs[\"io\"], InferClientPresence<TDefs>>;\n\n constructor(room: string, options: MockedRoomConfig<TDefs>) {\n const {\n events,\n initialPresence,\n initialStorage,\n limits,\n myself,\n presence,\n storage,\n treaty,\n } = options;\n\n this.id = room;\n\n this._events = events;\n this._limits = {\n presenceMaxSize: MAX_PRESENCE_SIZE_BYTES,\n ...limits,\n };\n this._treaty = treaty;\n this._usersManager = new UsersManager<TDefs[\"io\"], InferClientPresence<TDefs>>({\n initialPresence,\n limits: this._limits,\n presence,\n });\n\n if (myself) {\n const connectionId = myself.connectionId ?? \"mocked\";\n const kind = myself.kind ?? \"user\";\n\n this._usersManager.setMyself({\n connectionId,\n data: myself.data,\n kind,\n operator: myself.operator,\n presence: initialPresence as InferClientPresence<TDefs> | undefined,\n });\n this._state.authorization.user = myself.data;\n this._state.authorization.kind = kind;\n this._state.authorization.operator = myself.operator ?? null;\n this._state.connection.id = connectionId;\n this._state.connection.state = ConnectionState.Open;\n }\n\n this._publishRoomStats();\n\n this._crdtManager = new CrdtManager<TDefs[\"storage\"]>({\n initialStorage,\n storage,\n });\n\n this._observeCrdt();\n }\n\n public addEventListener<TKind extends keyof RoomEventListenerMap>(\n kind: TKind,\n handler: RoomEventListenerMap[TKind],\n ): () => void {\n return () => undefined;\n }\n\n public broadcast = new Proxy(\n async <TEvent extends keyof InferClientInput<TDefs>>(\n event: TEvent,\n data: Id<InferClientInput<TDefs>[TEvent]>,\n ): Promise<void> => {\n this._simulateEvent(event, data);\n },\n {\n get(fn, prop) {\n return async (data: Id<InferClientInput<TDefs>[any]>): Promise<void> => {\n return await fn(prop, data);\n };\n },\n },\n ) as BroadcastProxy<TDefs[\"io\"]>;\n\n public canRedo = (): boolean => {\n return this._crdtManager.doc.canRedo();\n };\n\n public canUndo = (): boolean => {\n return this._crdtManager.doc.canUndo();\n };\n\n public getConnection = (): WebSocketConnection => {\n // Create a read-only clone of the connection state\n return Object.freeze(JSON.parse(JSON.stringify(this._state.connection)));\n };\n\n public getDoc(): CrdtDocLike<\n InferDoc<TDefs[\"storage\"]>,\n InferStorage<TDefs[\"storage\"]>,\n InferJson<TDefs[\"storage\"]>\n > {\n return this._crdtManager.doc;\n }\n\n public getMyPresence = (): InferClientPresence<TDefs> => {\n return this._usersManager.myPresence;\n };\n\n public getMyself = (): Id<UserInfo<TDefs[\"io\"], InferClientPresence<TDefs>>> | null => {\n return this._usersManager.myself;\n };\n\n public getOther = (\n userId: string,\n options?: ParticipantKindOptions,\n ): Id<UserInfo<TDefs[\"io\"], InferClientPresence<TDefs>>> | null => {\n return this._usersManager.getOther(userId, options);\n };\n\n public getOtherByConnectionId = (\n connectionId: string,\n options?: ParticipantKindsOptions,\n ): Id<UserInfo<TDefs[\"io\"], InferClientPresence<TDefs>>> | null => {\n return this._usersManager.getOtherByConnectionId(connectionId, options);\n };\n\n public getOthers = (\n options?: ParticipantKindsOptions,\n ): readonly Id<UserInfo<TDefs[\"io\"], InferClientPresence<TDefs>>>[] => {\n return this._usersManager.getOthers(options);\n };\n\n /**\n * Occupancy of mocked people currently tracked in this room. Empty until\n * occupants exist (`setMyself` / extra connections); MockedRoomProvider\n * does not seed them.\n */\n public getRoomStats = (options?: ParticipantKindsOptions): RoomStats => {\n return this._usersManager.getOccupancy(options);\n };\n\n public getStorage = <TKey extends keyof InferStorage<TDefs[\"storage\"]>>(\n type: TKey,\n ): InferStorage<TDefs[\"storage\"]>[TKey] | null => {\n const sharedType = this._crdtManager.get(type);\n\n if (typeof sharedType === \"undefined\") return null;\n\n return sharedType;\n };\n\n public getStorageJson(): InferJson<TDefs[\"storage\"]> | null;\n public getStorageJson<TKey extends keyof InferJson<TDefs[\"storage\"]>>(\n type: TKey,\n ): InferJson<TDefs[\"storage\"]>[TKey] | null;\n public getStorageJson<TKey extends keyof InferJson<TDefs[\"storage\"]>>(type?: TKey) {\n if (this._state.connection.id === null) return null;\n if (typeof type === \"undefined\") return this._crdtManager.doc.toJson();\n\n return this._crdtManager.doc.toJson(type);\n }\n\n public getStorageLoaded(): boolean {\n return true;\n }\n\n /**\n * Identity page of mocked people currently tracked in this room. Empty until\n * occupants exist; MockedRoomProvider does not seed them. Not a real\n * listUsers protocol (no limit/cursor paging).\n */\n public listUsers = (options: ListUsersOptions = {}): Promise<ListUsersResult<TDefs[\"io\"]>> => {\n const kinds = new Set<ParticipantKind>(options.kinds ?? [\"user\"]);\n const myself = this._usersManager.myself;\n const users = [\n ...(myself && kinds.has(myself.kind) ? [myself] : []),\n ...this._usersManager.getOthers({ kinds: [...kinds] }),\n ]\n .map((person) => ({\n data: person.data,\n kind: person.kind,\n operator: person.operator,\n }))\n .toSorted((left, right) => {\n const byKind = participantOrder(left.kind) - participantOrder(right.kind);\n\n if (byKind !== 0) return byKind;\n\n const a = String(left.data.id);\n const b = String(right.data.id);\n\n if (a < b) return -1;\n if (a > b) return 1;\n\n return 0;\n });\n const last = users.at(-1);\n\n return Promise.resolve({\n success: true,\n pageInfo: {\n endCursor: last ? { kind: last.kind, id: String(last.data.id) } : null,\n hasNextPage: false,\n },\n users,\n });\n };\n\n public presence = new Proxy(\n async (name: string, data: unknown): Promise<void> => {\n await this._runPresenceProcedure(name, data);\n },\n {\n get(fn, prop) {\n return (data: unknown): Promise<void> => fn(prop as string, data);\n },\n },\n ) as PresenceProcedureProxy<TDefs[\"treaty\"][\"_defs\"][\"procedures\"][\"presence\"]>;\n\n public redo = (): void => {\n this._crdtManager.doc.redo();\n };\n\n public storage = new Proxy(\n (name: string, data: unknown): void => {\n this._runStorageProcedure(name, data);\n },\n {\n get(fn, prop) {\n return (data: unknown): void => fn(prop as string, data);\n },\n },\n ) as StorageProcedureProxy<TDefs[\"treaty\"][\"_defs\"][\"procedures\"][\"storage\"]>;\n\n public storageRoot = (fn: (value: InferJson<TDefs[\"storage\"]>) => void): (() => void) => {\n return this._crdtNotifier.subcribeRoot(fn);\n };\n\n public subscribe = new Proxy(\n <TSubject extends keyof StateNotifierSubjects<TDefs[\"io\"], InferClientPresence<TDefs>>>(\n name: TSubject,\n callback: SubscriptionCallback<TDefs[\"io\"], InferClientPresence<TDefs>, TSubject>,\n ): (() => void) => {\n return this._stateNotifier.subscribe(name, callback);\n },\n {\n get: (fn, prop) => {\n if (prop === \"connection\") {\n return (\n callback: SubscriptionCallback<\n TDefs[\"io\"],\n InferClientPresence<TDefs>,\n \"connection\"\n >,\n ) => {\n return fn(\"connection\", callback);\n };\n }\n\n if (prop === \"error\") {\n return (callback: RoomErrorSubscriptionCallback): (() => void) => {\n const subscription = subscribe(callback)(this._errorSubject.source);\n\n return () => {\n subscription.unsubscribe();\n };\n };\n }\n\n if (prop === \"myPresence\") {\n return (\n callback: SubscriptionCallback<\n TDefs[\"io\"],\n InferClientPresence<TDefs>,\n \"my-presence\"\n >,\n ) => {\n return fn(\"my-presence\", callback);\n };\n }\n\n if (prop === \"myself\") {\n return (\n callback: SubscriptionCallback<\n TDefs[\"io\"],\n InferClientPresence<TDefs>,\n \"myself\"\n >,\n ) => {\n return fn(\"myself\", callback);\n };\n }\n\n if (prop === \"others\") {\n return (\n callback: OthersSubscriptionCallback<\n TDefs[\"io\"],\n InferClientPresence<TDefs>\n >,\n options?: ParticipantKindsOptions,\n ) => {\n return this._usersNotifier.subscribeOthers((_listed, event) => {\n const others = this._usersManager.getOthers(options);\n\n if (event.kind === \"sync\") {\n callback(others, { kind: \"sync\", users: others });\n return;\n }\n\n callback(others, event);\n }, options);\n };\n }\n\n if (prop === \"roomStats\") {\n return (\n callback: SubscriptionCallback<\n TDefs[\"io\"],\n InferClientPresence<TDefs>,\n \"roomStats\"\n >,\n ) => {\n return fn(\"roomStats\", callback);\n };\n }\n\n if (prop === \"storageLoaded\") {\n return (\n callback: SubscriptionCallback<\n TDefs[\"io\"],\n InferClientPresence<TDefs>,\n \"storage-loaded\"\n >,\n ) => {\n return fn(\"storage-loaded\", callback);\n };\n }\n\n if (prop === \"event\") return this._event;\n if (prop === \"other\") return this._other;\n if (prop === \"storage\") return this.#_storage;\n\n throw new Error(`Unknown subscription: ${String(prop)}`);\n },\n },\n ) as SubscribeProxy<TDefs[\"io\"], InferClientPresence<TDefs>, InferJson<TDefs[\"storage\"]>>;\n\n public transact = (\n fn: (storage: InferStorage<TDefs[\"storage\"]>) => void,\n origin?: string,\n ): void => {\n const _origin = origin ?? this._state.connection.id;\n const crdtManager = this._crdtManager;\n\n /**\n * !HACK\n * @description Don't transact anything if there is no origin, because\n * that means the user isn't connected yet. This will mean events are\n * lost unfortunately.\n * @date September 23, 2023\n */\n if (typeof _origin !== \"string\") return;\n if (!crdtManager) return;\n\n crdtManager.doc.transact(() => {\n const storage = crdtManager.doc.get();\n\n fn(storage);\n }, _origin);\n };\n\n public undo = (): void => {\n this._crdtManager.doc.undo();\n };\n\n public updateMyPresence = (\n presence: UpdateMyPresenceAction<InferClientPresence<TDefs>>,\n ): void => {\n this._applyMyPresence(presence);\n };\n\n private _applyMyPresence(presence: UpdateMyPresenceAction<InferClientPresence<TDefs>>): void {\n const newPresence =\n typeof presence === \"function\" ? presence(this.getMyPresence()) : presence;\n\n this._usersManager.updateMyPresence(newPresence);\n\n const myPresence = this._usersManager.myPresence;\n const myself = this._usersManager.myself ?? null;\n\n this._stateNotifier.subjects[\"my-presence\"].next(myPresence);\n if (!!myself) this._stateNotifier.subjects[\"myself\"].next(myself);\n }\n\n private _event = new Proxy(\n // oxlint-disable-next-line typescript/no-unnecessary-type-parameters\n <TEvent extends keyof InferClientOutput<TDefs>>(\n event: TEvent,\n callback: EventNotifierSubscriptionCallback<TDefs[\"io\"], any>,\n ): (() => void) => this._eventNotifier.subscribe(event, callback),\n {\n get(fn, prop) {\n return (\n callback: EventNotifierSubscriptionCallback<TDefs[\"io\"], any>,\n ): (() => void) => fn(prop as any, callback);\n },\n },\n ) as EventProxy<TDefs[\"io\"]>;\n\n private _observeCrdt(): void {\n this._subscriptions.observeCrdt?.();\n\n if (!this._crdtManager) return;\n\n const unsubscribe = this._crdtManager.doc.subscribe((event) => {\n const origin = event.origin ?? null;\n\n if (!this._crdtManager) return;\n if (origin === \"$storageUpdated\") return;\n\n const sharedTypes = this._crdtManager.doc.get();\n\n const storageRoot = Object.keys(sharedTypes).reduce(\n (acc, prop) => {\n if (!this._crdtManager) return acc;\n\n const serialized = this._crdtManager.doc.toJson(prop);\n\n this._crdtNotifier.subject(prop).next(serialized);\n\n acc[prop as keyof InferStorage<TDefs[\"storage\"]>] = serialized;\n\n return acc;\n },\n {} as InferJson<TDefs[\"storage\"]>,\n );\n\n this._crdtNotifier.rootSubject.next(storageRoot);\n });\n\n this._subscriptions.observeCrdt = unsubscribe;\n }\n\n private _publishRoomStats(): void {\n this._stateNotifier.subjects.roomStats.next(this._usersManager.getOccupancy());\n }\n\n private _other = (\n userId: string,\n callback: OtherSubscriptionCallback<TDefs[\"io\"], InferClientPresence<TDefs>>,\n options?: ParticipantKindOptions,\n ): (() => void) => {\n return this._usersNotifier.subscribeOther(userId, callback, options);\n };\n\n private async _runPresenceProcedure(name: string, data: unknown): Promise<void> {\n const procedures = this._treaty._defs.procedures.presence;\n\n if (!procedures || !Object.hasOwn(procedures, name)) {\n throw new Error(`Unknown presence procedure \"${name}\"`);\n }\n\n const procedure = procedures[name];\n const myself = this._usersManager.myself;\n\n if (!myself) {\n throw new Error(\"Cannot run a treaty procedure before the local user is available\");\n }\n\n const doc = this._crdtManager.doc;\n const seq = ++this._seq.presence;\n const patch = await procedure.apply(data, {\n user: myself.data,\n operator: myself.operator,\n presence: this.getMyPresence(),\n doc,\n });\n\n if (seq !== this._seq.presence) return;\n\n this._applyMyPresence(patch as InferClientPresence<TDefs>);\n }\n\n private _runStorageProcedure(name: string, data: unknown): void {\n const origin = this._state.connection.id ?? \"mocked\";\n const procedures = this._treaty._defs.procedures.storage;\n\n if (!procedures || !Object.hasOwn(procedures, name)) {\n throw new Error(`Unknown storage procedure \"${name}\"`);\n }\n\n const procedure = procedures[name];\n const myself = this._usersManager.myself;\n\n if (!myself) {\n throw new Error(\"Cannot run a treaty procedure before the local user is available\");\n }\n\n const presence = this.getMyPresence();\n const commit = (loaded?: { input: unknown; prepared: unknown }): void => {\n // Silent. This storage is not synced yet, so the write would not land.\n if (!this.getStorageLoaded()) return;\n\n const doc = this._crdtManager.doc;\n const apply = (): void => {\n procedure.apply(\n loaded ? loaded.input : data,\n {\n user: myself.data,\n operator: myself.operator,\n presence,\n doc,\n },\n loaded?.prepared,\n );\n };\n\n if (procedure.config.transact === false) {\n apply();\n\n return;\n }\n\n this.transact(() => {\n apply();\n }, origin);\n };\n\n if (!procedure.prepared || !procedure.load) {\n commit(undefined);\n\n return;\n }\n\n const loading = procedure.load(data, {\n user: myself.data,\n operator: myself.operator,\n presence,\n });\n\n this._storageCommits = sequenceCommit({\n tail: this._storageCommits,\n ready: loading,\n commit,\n });\n }\n\n private _simulateEvent<TEvent extends keyof InferClientInput<TDefs>>(\n event: TEvent,\n data: Id<InferClientInput<TDefs>[TEvent]>,\n ) {\n if (!this._events) return;\n\n const type = event.toString();\n const resolver = this._events[type as TEvent];\n\n if (!resolver) return;\n\n const result = resolver(data);\n\n Object.keys(result).forEach((outputType) => {\n const _type = outputType as keyof Partial<InferClientOutput<TDefs>>;\n const outputData = result[_type] as any;\n\n if (!outputData) return;\n\n this._eventNotifier.subject(_type).next({\n connectionId: this._state.connection.id,\n data: outputData,\n operator: this._state.authorization.operator,\n room: this.id,\n type: _type,\n user: this._state.authorization.user,\n } as Id<IOEventMessage<TDefs[\"io\"], typeof _type>>);\n });\n }\n\n #_storage = new Proxy(\n <TKey extends keyof InferJson<TDefs[\"storage\"]>>(\n key: TKey,\n callback: StorageSubscriptionCallback<InferJson<TDefs[\"storage\"]>, TKey>,\n ): (() => void) => this._crdtNotifier.subscribe(key, callback),\n {\n get: (fn, prop) => {\n type _Json = InferJson<TDefs[\"storage\"]>;\n\n if (!!prop) {\n return (callback: StorageRootSubscriptionCallback<_Json>) => {\n return this._crdtNotifier.subcribeRoot(callback);\n };\n }\n\n return (callback: StorageSubscriptionCallback<_Json, keyof _Json>) => {\n return fn(prop as keyof InferJson<TDefs[\"storage\"]>, callback);\n };\n },\n },\n ) as StorageProxy<InferJson<TDefs[\"storage\"]>>;\n}\n"],"mappings":"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"}
package/package.json ADDED
@@ -0,0 +1,45 @@
1
+ {
2
+ "name": "@pluv/client",
3
+ "version": "0.0.0-canary-20261027014949",
4
+ "description": "@pluv/io frontend client",
5
+ "author": {
6
+ "email": "david@pluv.io",
7
+ "name": "i3dly",
8
+ "url": "https://github.com/i3dly"
9
+ },
10
+ "license": "MIT",
11
+ "homepage": "https://github.com/pluv-io/pluv",
12
+ "repository": {
13
+ "type": "git",
14
+ "url": "git+https://github.com/pluv-io/pluv.git",
15
+ "directory": "packages/client"
16
+ },
17
+ "type": "module",
18
+ "types": "./dist/index.d.mts",
19
+ "files": [
20
+ "dist"
21
+ ],
22
+ "publishConfig": {
23
+ "access": "public"
24
+ },
25
+ "dependencies": {
26
+ "@pluv/crdt": "^0.0.0-canary-20261027014949",
27
+ "@pluv/types": "^0.0.0-canary-20261027014949",
28
+ "wonka": "^6.3.6"
29
+ },
30
+ "devDependencies": {
31
+ "@pluv/tsconfig": "^0.0.0-canary-20261027014949",
32
+ "tsdown": "^0.23.2",
33
+ "typescript": "7.1.0-beta"
34
+ },
35
+ "exports": {
36
+ ".": "./dist/index.mjs",
37
+ "./*": "./*"
38
+ },
39
+ "scripts": {
40
+ "build": "tsdown",
41
+ "dev": "tsdown --watch",
42
+ "typecheck": "tsc --noEmit",
43
+ "clean": "rm -rf .turbo && rm -rf node_modules && rm -rf dist"
44
+ }
45
+ }