@pluv/client 0.15.0 → 0.16.0
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.
- package/.turbo/turbo-build.log +9 -9
- package/CHANGELOG.md +182 -37
- package/README.md +9 -12
- package/dist/index.d.mts +65 -77
- package/dist/index.d.ts +65 -77
- package/dist/index.js +271 -303
- package/dist/index.mjs +270 -313
- package/package.json +7 -11
- package/src/AbstractRoom.ts +13 -8
- package/src/CrdtManager.ts +55 -57
- package/src/CrdtNotifier.ts +12 -12
- package/src/MockedRoom.ts +44 -40
- package/src/OtherNotifier.ts +1 -1
- package/src/PluvClient.ts +4 -4
- package/src/PluvRoom.ts +67 -76
- package/src/StateNotifier.ts +8 -5
- package/src/index.ts +6 -11
- package/src/y.ts +0 -9
package/dist/index.d.ts
CHANGED
|
@@ -1,10 +1,8 @@
|
|
|
1
|
-
import {
|
|
2
|
-
export {
|
|
1
|
+
import { AbstractCrdtType, AbstractCrdtDoc, InferCrdtStorageJson, AbstractCrdtDocFactory } from '@pluv/crdt';
|
|
2
|
+
export { AbstractCrdtType, InferCrdtStorageJson } from '@pluv/crdt';
|
|
3
3
|
import * as _pluv_types from '@pluv/types';
|
|
4
4
|
import { IOLike, InferIOOutput, Id, IOEventMessage, JsonObject, InferIOAuthorizeUser, InferIOAuthorize, InferIOInput, InputZodLike, InferIOAuthorizeRequired } from '@pluv/types';
|
|
5
5
|
export { BaseUser, EventMessage, EventRecord, IOEventMessage } from '@pluv/types';
|
|
6
|
-
import { AbstractType, Doc } from 'yjs';
|
|
7
|
-
export { AbstractType } from 'yjs';
|
|
8
6
|
import { Subject } from 'wonka';
|
|
9
7
|
|
|
10
8
|
type EventNotifierSubscriptionCallback<TIO extends IOLike, TEvent extends keyof InferIOOutput<TIO>> = (value: Id<IOEventMessage<TIO, TEvent>>) => void;
|
|
@@ -43,29 +41,31 @@ interface StateNotifierSubjects<TIO extends IOLike, TPresence extends JsonObject
|
|
|
43
41
|
"my-presence": Subject<TPresence | null>;
|
|
44
42
|
myself: Subject<Readonly<Id<UserInfo<TIO>>> | null>;
|
|
45
43
|
others: Subject<readonly Id<UserInfo<TIO>>[]>;
|
|
44
|
+
"storage-loaded": Subject<boolean>;
|
|
46
45
|
}
|
|
47
46
|
type InferSubjectValue<TIO extends IOLike, TPresence extends JsonObject, TSubject extends keyof StateNotifierSubjects<TIO, TPresence>> = StateNotifierSubjects<TIO, TPresence>[TSubject] extends Subject<infer IValue> ? Id<IValue> : never;
|
|
48
47
|
type SubscriptionCallback<TIO extends IOLike, TPresence extends JsonObject, TSubject extends keyof StateNotifierSubjects<TIO, TPresence>> = (value: InferSubjectValue<TIO, TPresence, TSubject>) => void;
|
|
49
48
|
|
|
50
|
-
declare abstract class AbstractRoom<TIO extends IOLike, TPresence extends JsonObject = {}, TStorage extends Record<string,
|
|
49
|
+
declare abstract class AbstractRoom<TIO extends IOLike, TPresence extends JsonObject = {}, TStorage extends Record<string, AbstractCrdtType<any, any>> = {}> {
|
|
51
50
|
readonly id: string;
|
|
52
51
|
constructor(room: string);
|
|
52
|
+
abstract storageLoaded: boolean;
|
|
53
53
|
abstract broadcast<TEvent extends keyof InferIOInput<TIO>>(event: TEvent, data: Id<InferIOInput<TIO>[TEvent]>): void;
|
|
54
54
|
abstract canRedo(): boolean;
|
|
55
55
|
abstract canUndo(): boolean;
|
|
56
|
-
abstract getDoc():
|
|
56
|
+
abstract getDoc(): AbstractCrdtDoc<TStorage>;
|
|
57
57
|
abstract event<TEvent extends keyof InferIOOutput<TIO>>(event: TEvent, callback: EventNotifierSubscriptionCallback<TIO, TEvent>): () => void;
|
|
58
58
|
abstract getConnection(): WebSocketConnection;
|
|
59
59
|
abstract getMyPresence(): TPresence;
|
|
60
60
|
abstract getMyself(): Id<UserInfo<TIO, TPresence>> | null;
|
|
61
61
|
abstract getOther(connectionId: string): Id<UserInfo<TIO, TPresence>> | null;
|
|
62
62
|
abstract getOthers(): readonly Id<UserInfo<TIO, TPresence>>[];
|
|
63
|
-
abstract getStorage<TKey extends keyof TStorage>(key: TKey): TStorage[TKey];
|
|
63
|
+
abstract getStorage<TKey extends keyof TStorage>(key: TKey): TStorage[TKey] | null;
|
|
64
64
|
abstract other(connectionId: string, callback: OtherNotifierSubscriptionCallback<TIO>): () => void;
|
|
65
65
|
abstract redo(): void;
|
|
66
|
-
abstract storage<TKey extends keyof TStorage>(key: TKey, fn: (value:
|
|
66
|
+
abstract storage<TKey extends keyof TStorage>(key: TKey, fn: (value: InferCrdtStorageJson<TStorage[TKey]>) => void): () => void;
|
|
67
67
|
abstract storageRoot(fn: (value: {
|
|
68
|
-
[P in keyof TStorage]:
|
|
68
|
+
[P in keyof TStorage]: InferCrdtStorageJson<TStorage[P]>;
|
|
69
69
|
}) => void): () => void;
|
|
70
70
|
abstract subscribe<TSubject extends keyof StateNotifierSubjects<TIO, TPresence>>(name: TSubject, callback: SubscriptionCallback<TIO, TPresence, TSubject>): () => void;
|
|
71
71
|
abstract transact(fn: (storage: TStorage) => void, origin?: string): void;
|
|
@@ -84,16 +84,56 @@ declare abstract class AbstractStorageStore {
|
|
|
84
84
|
abstract initialize(): Promise<void>;
|
|
85
85
|
}
|
|
86
86
|
|
|
87
|
-
type CrdtManagerOptions<TStorage extends Record<string,
|
|
87
|
+
type CrdtManagerOptions<TStorage extends Record<string, AbstractCrdtType<any, any>> = {}> = {
|
|
88
88
|
encodedState?: string | Uint8Array | null;
|
|
89
|
-
initialStorage?:
|
|
90
|
-
}
|
|
89
|
+
initialStorage?: AbstractCrdtDocFactory<TStorage>;
|
|
90
|
+
};
|
|
91
91
|
|
|
92
92
|
type UsersManagerConfig<TPresence extends JsonObject = {}> = {
|
|
93
93
|
initialPresence?: TPresence;
|
|
94
94
|
presence?: InputZodLike<TPresence>;
|
|
95
95
|
};
|
|
96
96
|
|
|
97
|
+
type MockedRoomEvents<TIO extends IOLike> = Partial<{
|
|
98
|
+
[P in keyof InferIOInput<TIO>]: (data: Id<InferIOInput<TIO>[P]>) => Partial<InferIOOutput<TIO>>;
|
|
99
|
+
}>;
|
|
100
|
+
type MockedRoomConfig<TIO extends IOLike, TPresence extends JsonObject = {}, TStorage extends Record<string, AbstractCrdtType<any, any>> = {}> = {
|
|
101
|
+
events?: MockedRoomEvents<TIO>;
|
|
102
|
+
} & Omit<CrdtManagerOptions<TStorage>, "encodedState"> & UsersManagerConfig<TPresence>;
|
|
103
|
+
declare class MockedRoom<TIO extends IOLike, TPresence extends JsonObject = {}, TStorage extends Record<string, AbstractCrdtType<any, any>> = {}> extends AbstractRoom<TIO, TPresence, TStorage> {
|
|
104
|
+
private _crdtManager;
|
|
105
|
+
private _crdtNotifier;
|
|
106
|
+
private _eventNotifier;
|
|
107
|
+
private _events?;
|
|
108
|
+
private _otherNotifier;
|
|
109
|
+
private _state;
|
|
110
|
+
private _stateNotifier;
|
|
111
|
+
private _subscriptions;
|
|
112
|
+
private _usersManager;
|
|
113
|
+
constructor(room: string, options: MockedRoomConfig<TIO, TPresence, TStorage>);
|
|
114
|
+
get storageLoaded(): boolean;
|
|
115
|
+
broadcast<TEvent extends keyof InferIOInput<TIO>>(event: TEvent, data: Id<InferIOInput<TIO>[TEvent]>): void;
|
|
116
|
+
canRedo: () => boolean;
|
|
117
|
+
canUndo: () => boolean;
|
|
118
|
+
event: <TEvent extends keyof InferIOOutput<TIO>>(event: TEvent, callback: EventNotifierSubscriptionCallback<TIO, TEvent>) => (() => void);
|
|
119
|
+
getConnection(): WebSocketConnection;
|
|
120
|
+
getDoc(): AbstractCrdtDoc<TStorage>;
|
|
121
|
+
getMyPresence: () => TPresence;
|
|
122
|
+
getMyself: () => Id<UserInfo<TIO, TPresence>> | null;
|
|
123
|
+
getOther: (connectionId: string) => Id<UserInfo<TIO, TPresence>> | null;
|
|
124
|
+
getOthers: () => readonly Id<UserInfo<TIO, TPresence>>[];
|
|
125
|
+
getStorage: <TKey extends keyof TStorage>(key: TKey) => TStorage[TKey] | null;
|
|
126
|
+
other: (connectionId: string, callback: OtherNotifierSubscriptionCallback<TIO>) => (() => void);
|
|
127
|
+
redo: () => void;
|
|
128
|
+
storage: <TKey extends keyof TStorage>(key: TKey, fn: (value: InferCrdtStorageJson<TStorage[TKey]>) => void) => (() => void);
|
|
129
|
+
storageRoot: (fn: (value: { [P in keyof TStorage]: InferCrdtStorageJson<TStorage[P]>; }) => void) => (() => void);
|
|
130
|
+
subscribe: <TSubject extends keyof StateNotifierSubjects<TIO, TPresence>>(name: TSubject, callback: SubscriptionCallback<TIO, TPresence, TSubject>) => (() => void);
|
|
131
|
+
transact: (fn: (storage: TStorage) => void, origin?: string) => void;
|
|
132
|
+
undo: () => void;
|
|
133
|
+
updateMyPresence: (presence: Partial<TPresence>) => void;
|
|
134
|
+
private _observeCrdt;
|
|
135
|
+
}
|
|
136
|
+
|
|
97
137
|
declare global {
|
|
98
138
|
var process: {
|
|
99
139
|
env: {
|
|
@@ -114,8 +154,8 @@ type RoomEndpoints<TIO extends IOLike> = {
|
|
|
114
154
|
} : {
|
|
115
155
|
authEndpoint?: undefined;
|
|
116
156
|
});
|
|
117
|
-
type PluvRoomAddon<TIO extends IOLike = IOLike, TPresence extends JsonObject = {}, TStorage extends Record<string,
|
|
118
|
-
interface PluvRoomAddonInput<TIO extends IOLike = IOLike, TPresence extends JsonObject = {}, TStorage extends Record<string,
|
|
157
|
+
type PluvRoomAddon<TIO extends IOLike = IOLike, TPresence extends JsonObject = {}, TStorage extends Record<string, AbstractCrdtType<any, any>> = {}> = (input: PluvRoomAddonInput<TIO, TPresence, TStorage>) => Partial<PluvRoomAddonResult>;
|
|
158
|
+
interface PluvRoomAddonInput<TIO extends IOLike = IOLike, TPresence extends JsonObject = {}, TStorage extends Record<string, AbstractCrdtType<any, any>> = {}> {
|
|
119
159
|
room: PluvRoom<TIO, TPresence, TStorage>;
|
|
120
160
|
}
|
|
121
161
|
interface PluvRoomAddonResult {
|
|
@@ -125,15 +165,14 @@ type PluvRoomDebug<TIO extends IOLike> = Id<{
|
|
|
125
165
|
output: readonly (keyof InferIOOutput<TIO>)[];
|
|
126
166
|
input: readonly (keyof InferIOInput<TIO>)[];
|
|
127
167
|
}>;
|
|
128
|
-
type PluvRoomOptions<TIO extends IOLike, TPresence extends JsonObject = {}, TStorage extends Record<string,
|
|
168
|
+
type PluvRoomOptions<TIO extends IOLike, TPresence extends JsonObject = {}, TStorage extends Record<string, AbstractCrdtType<any, any>> = {}> = {
|
|
129
169
|
addons?: readonly PluvRoomAddon<TIO, TPresence, TStorage>[];
|
|
130
170
|
debug?: boolean | PluvRoomDebug<TIO>;
|
|
131
171
|
onAuthorizationFail?: (error: Error) => void;
|
|
132
172
|
} & Omit<CrdtManagerOptions<TStorage>, "encodedState"> & UsersManagerConfig<TPresence>;
|
|
133
|
-
type RoomConfig<TIO extends IOLike, TPresence extends JsonObject = {}, TStorage extends Record<string,
|
|
134
|
-
declare class PluvRoom<TIO extends IOLike, TPresence extends JsonObject = {}, TStorage extends Record<string,
|
|
173
|
+
type RoomConfig<TIO extends IOLike, TPresence extends JsonObject = {}, TStorage extends Record<string, AbstractCrdtType<any, any>> = {}> = RoomEndpoints<TIO> & PluvRoomOptions<TIO, TPresence, TStorage>;
|
|
174
|
+
declare class PluvRoom<TIO extends IOLike, TPresence extends JsonObject = {}, TStorage extends Record<string, AbstractCrdtType<any, any>> = {}> extends AbstractRoom<TIO, TPresence, TStorage> {
|
|
135
175
|
readonly _endpoints: RoomEndpoints<TIO>;
|
|
136
|
-
private _captureTimeout;
|
|
137
176
|
private _crdtManager;
|
|
138
177
|
private _crdtNotifier;
|
|
139
178
|
private _debug;
|
|
@@ -146,11 +185,11 @@ declare class PluvRoom<TIO extends IOLike, TPresence extends JsonObject = {}, TS
|
|
|
146
185
|
private _storageStore;
|
|
147
186
|
private _subscriptions;
|
|
148
187
|
private _timeouts;
|
|
149
|
-
private _trackedOrigins;
|
|
150
188
|
private _windowListeners;
|
|
151
189
|
private _wsListeners;
|
|
152
190
|
private _usersManager;
|
|
153
191
|
constructor(room: string, options: RoomConfig<TIO, TPresence, TStorage>);
|
|
192
|
+
get storageLoaded(): boolean;
|
|
154
193
|
get webSocket(): WebSocket | null;
|
|
155
194
|
broadcast<TEvent extends keyof InferIOInput<TIO>>(event: TEvent, data: Id<InferIOInput<TIO>[TEvent]>): void;
|
|
156
195
|
canRedo: () => boolean;
|
|
@@ -159,16 +198,16 @@ declare class PluvRoom<TIO extends IOLike, TPresence extends JsonObject = {}, TS
|
|
|
159
198
|
disconnect(): Promise<void>;
|
|
160
199
|
event: <TEvent extends keyof InferIOOutput<TIO>>(event: TEvent, callback: EventNotifierSubscriptionCallback<TIO, TEvent>) => (() => void);
|
|
161
200
|
getConnection(): WebSocketConnection;
|
|
162
|
-
getDoc():
|
|
201
|
+
getDoc(): AbstractCrdtDoc<TStorage>;
|
|
163
202
|
getMyPresence: () => TPresence;
|
|
164
203
|
getMyself: () => Id<UserInfo<TIO, TPresence>> | null;
|
|
165
204
|
getOther: (connectionId: string) => Id<UserInfo<TIO, TPresence>> | null;
|
|
166
205
|
getOthers: () => readonly Id<UserInfo<TIO, TPresence>>[];
|
|
167
|
-
getStorage: <TKey extends keyof TStorage>(key: TKey) => TStorage[TKey];
|
|
206
|
+
getStorage: <TKey extends keyof TStorage>(key: TKey) => TStorage[TKey] | null;
|
|
168
207
|
other: (connectionId: string, callback: OtherNotifierSubscriptionCallback<TIO>) => (() => void);
|
|
169
208
|
redo: () => void;
|
|
170
|
-
storage: <TKey extends keyof TStorage>(key: TKey, fn: (value:
|
|
171
|
-
storageRoot: (fn: (value: { [P in keyof TStorage]:
|
|
209
|
+
storage: <TKey extends keyof TStorage>(key: TKey, fn: (value: InferCrdtStorageJson<TStorage[TKey]>) => void) => (() => void);
|
|
210
|
+
storageRoot: (fn: (value: { [P in keyof TStorage]: InferCrdtStorageJson<TStorage[P]>; }) => void) => (() => void);
|
|
172
211
|
subscribe: <TSubject extends keyof StateNotifierSubjects<TIO, TPresence>>(name: TSubject, callback: SubscriptionCallback<TIO, TPresence, TSubject>) => (() => void);
|
|
173
212
|
transact: (fn: (storage: TStorage) => void, origin?: string) => void;
|
|
174
213
|
undo: () => void;
|
|
@@ -187,7 +226,6 @@ declare class PluvRoom<TIO extends IOLike, TPresence extends JsonObject = {}, TS
|
|
|
187
226
|
private _getAddon;
|
|
188
227
|
private _getAuthFetchOptions;
|
|
189
228
|
private _getAuthorization;
|
|
190
|
-
private _getTrackedOrigins;
|
|
191
229
|
private _getWsEndpoint;
|
|
192
230
|
private _handleExit;
|
|
193
231
|
private _handlePresenceUpdatedMessage;
|
|
@@ -234,9 +272,9 @@ declare class PluvClient<TIO extends IOLike = IOLike> {
|
|
|
234
272
|
private _wsEndpoint;
|
|
235
273
|
private _rooms;
|
|
236
274
|
constructor(options: PluvClientOptions<TIO>);
|
|
237
|
-
createRoom: <TPresence extends JsonObject = {}, TStorage extends Record<string,
|
|
275
|
+
createRoom: <TPresence extends JsonObject = {}, TStorage extends Record<string, AbstractCrdtType<any, any>> = {}>(room: string, options: PluvRoomOptions<TIO, TPresence, TStorage>) => PluvRoom<TIO, TPresence, TStorage>;
|
|
238
276
|
enter: (room: string | PluvRoom<TIO, any, any>) => Promise<PluvRoom<TIO, JsonObject, any>>;
|
|
239
|
-
getRoom: <TPresence extends JsonObject = {}, TStorage extends Record<string,
|
|
277
|
+
getRoom: <TPresence extends JsonObject = {}, TStorage extends Record<string, AbstractCrdtType<any, any>> = {}>(room: string) => PluvRoom<TIO, TPresence, TStorage> | null;
|
|
240
278
|
getRooms: () => readonly PluvRoom<TIO, JsonObject, any>[];
|
|
241
279
|
leave: (room: string | PluvRoom<TIO, any, any>) => Promise<void>;
|
|
242
280
|
private _logDebug;
|
|
@@ -244,54 +282,4 @@ declare class PluvClient<TIO extends IOLike = IOLike> {
|
|
|
244
282
|
|
|
245
283
|
declare const createClient: <TIO extends IOLike<_pluv_types.IOAuthorize<any, any>, {}, {}, {}, {}> = IOLike<_pluv_types.IOAuthorize<any, any>, {}, {}, {}, {}>>(options: PluvClientOptions<TIO>) => PluvClient<TIO>;
|
|
246
284
|
|
|
247
|
-
type MockedRoomEvents
|
|
248
|
-
[P in keyof InferIOInput<TIO>]: (data: Id<InferIOInput<TIO>[P]>) => Partial<InferIOOutput<TIO>>;
|
|
249
|
-
}>;
|
|
250
|
-
type MockedRoomConfig<TIO extends IOLike, TPresence extends JsonObject = {}, TStorage extends Record<string, AbstractType<any>> = {}> = {
|
|
251
|
-
events?: MockedRoomEvents<TIO>;
|
|
252
|
-
} & Omit<CrdtManagerOptions<TStorage>, "encodedState"> & UsersManagerConfig<TPresence>;
|
|
253
|
-
declare class MockedRoom<TIO extends IOLike, TPresence extends JsonObject = {}, TStorage extends Record<string, AbstractType<any>> = {}> extends AbstractRoom<TIO, TPresence, TStorage> {
|
|
254
|
-
private _crdtManager;
|
|
255
|
-
private _crdtNotifier;
|
|
256
|
-
private _eventNotifier;
|
|
257
|
-
private _events?;
|
|
258
|
-
private _otherNotifier;
|
|
259
|
-
private _state;
|
|
260
|
-
private _stateNotifier;
|
|
261
|
-
private _subscriptions;
|
|
262
|
-
private _usersManager;
|
|
263
|
-
constructor(room: string, options: MockedRoomConfig<TIO, TPresence, TStorage>);
|
|
264
|
-
broadcast<TEvent extends keyof InferIOInput<TIO>>(event: TEvent, data: Id<InferIOInput<TIO>[TEvent]>): void;
|
|
265
|
-
canRedo: () => boolean;
|
|
266
|
-
canUndo: () => boolean;
|
|
267
|
-
event: <TEvent extends keyof InferIOOutput<TIO>>(event: TEvent, callback: EventNotifierSubscriptionCallback<TIO, TEvent>) => (() => void);
|
|
268
|
-
getConnection(): WebSocketConnection;
|
|
269
|
-
getDoc(): Doc;
|
|
270
|
-
getMyPresence: () => TPresence;
|
|
271
|
-
getMyself: () => Id<UserInfo<TIO, TPresence>> | null;
|
|
272
|
-
getOther: (connectionId: string) => Id<UserInfo<TIO, TPresence>> | null;
|
|
273
|
-
getOthers: () => readonly Id<UserInfo<TIO, TPresence>>[];
|
|
274
|
-
getStorage: <TKey extends keyof TStorage>(key: TKey) => TStorage[TKey];
|
|
275
|
-
other: (connectionId: string, callback: OtherNotifierSubscriptionCallback<TIO>) => (() => void);
|
|
276
|
-
redo: () => void;
|
|
277
|
-
storage: <TKey extends keyof TStorage>(key: TKey, fn: (value: InferYjsSharedTypeJson<TStorage[TKey]>) => void) => (() => void);
|
|
278
|
-
storageRoot: (fn: (value: { [P in keyof TStorage]: InferYjsSharedTypeJson<TStorage[P]>; }) => void) => (() => void);
|
|
279
|
-
subscribe: <TSubject extends keyof StateNotifierSubjects<TIO, TPresence>>(name: TSubject, callback: SubscriptionCallback<TIO, TPresence, TSubject>) => (() => void);
|
|
280
|
-
transact: (fn: (storage: TStorage) => void, origin?: string) => void;
|
|
281
|
-
undo: () => void;
|
|
282
|
-
updateMyPresence: (presence: Partial<TPresence>) => void;
|
|
283
|
-
private _observeCrdt;
|
|
284
|
-
}
|
|
285
|
-
|
|
286
|
-
declare const y_array: typeof array;
|
|
287
|
-
declare const y_map: typeof map;
|
|
288
|
-
declare const y_object: typeof object;
|
|
289
|
-
declare const y_text: typeof text;
|
|
290
|
-
declare const y_xmlElement: typeof xmlElement;
|
|
291
|
-
declare const y_xmlFragment: typeof xmlFragment;
|
|
292
|
-
declare const y_xmlText: typeof xmlText;
|
|
293
|
-
declare namespace y {
|
|
294
|
-
export { y_array as array, y_map as map, y_object as object, y_text as text, y_xmlElement as xmlElement, y_xmlFragment as xmlFragment, y_xmlText as xmlText };
|
|
295
|
-
}
|
|
296
|
-
|
|
297
|
-
export { AbstractRoom, AbstractStorageStore, ConnectionState, MockedRoom, type MockedRoomConfig, type MockedRoomEvents, PluvClient, type PluvClientOptions, PluvRoom, type PluvRoomAddon, type PluvRoomAddonInput, type PluvRoomAddonResult, type PluvRoomDebug, type UserInfo, type WebSocketConnection, type WebSocketState, createClient, y };
|
|
285
|
+
export { AbstractRoom, AbstractStorageStore, ConnectionState, MockedRoom, type MockedRoomConfig, type MockedRoomEvents, PluvClient, type PluvClientOptions, PluvRoom, type PluvRoomAddon, type PluvRoomAddonInput, type PluvRoomAddonResult, type PluvRoomDebug, type UserInfo, type WebSocketConnection, type WebSocketState, createClient };
|