@pluv/client 1.0.1 → 2.0.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 +8 -8
- package/CHANGELOG.md +19 -0
- package/dist/index.d.mts +111 -172
- package/dist/index.d.ts +111 -172
- package/dist/index.js +117 -127
- package/dist/index.mjs +98 -106
- package/package.json +5 -5
- package/src/CrdtManager.ts +28 -18
- package/src/EventNotifier.ts +7 -6
- package/src/MockedRoom.ts +61 -41
- package/src/OtherNotifier.ts +7 -6
- package/src/PluvClient.ts +36 -28
- package/src/PluvProcedure.ts +2 -1
- package/src/PluvRoom.ts +123 -110
- package/src/PluvRouter.ts +1 -23
- package/src/StateNotifier.ts +1 -2
- package/src/UsersManager.ts +2 -2
- package/src/createClient.ts +5 -5
- package/src/index.ts +14 -12
- package/src/types.ts +5 -19
- package/src/AbstractRoom.ts +0 -84
- package/src/enums.ts +0 -9
package/dist/index.d.ts
CHANGED
|
@@ -1,19 +1,19 @@
|
|
|
1
|
-
import { CrdtType, AbstractCrdtDocFactory,
|
|
1
|
+
import { CrdtType, AbstractCrdtDocFactory, NoopCrdtDocFactory, InferStorage, InferCrdtJson } from '@pluv/crdt';
|
|
2
2
|
export { CrdtType, InferCrdtJson } from '@pluv/crdt';
|
|
3
|
-
import { IOLike,
|
|
4
|
-
export { BaseUser, EventMessage, EventRecord, IOEventMessage } from '@pluv/types';
|
|
3
|
+
import { IOLike, JsonObject, EventRecord, CrdtDocLike, UserInfo, MaybePromise, Id, ConnectionState, ProcedureLike, InputZodLike, IORouterLike, WebSocketState, InferIOAuthorizeUser, InferIOAuthorize, BaseUser, RoomLike, InferIOOutput, InferIOInput, MergeEvents, EventNotifierSubscriptionCallback, OtherNotifierSubscriptionCallback, UpdateMyPresenceAction } from '@pluv/types';
|
|
4
|
+
export { BaseUser, ConnectionState, EventMessage, EventNotifierSubscriptionCallback, EventRecord, IOEventMessage, MergeEvents, RoomLike, UserInfo, WebSocketState } from '@pluv/types';
|
|
5
5
|
import { Subject } from 'wonka';
|
|
6
6
|
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
7
|
+
declare abstract class AbstractStorageStore {
|
|
8
|
+
room: string;
|
|
9
|
+
constructor(room: string);
|
|
10
|
+
abstract addUpdate(update: string): Promise<void>;
|
|
11
|
+
abstract destroy(): Promise<void>;
|
|
12
|
+
abstract flatten(encodedState: string): Promise<void>;
|
|
13
|
+
abstract getShouldFlatten(): Promise<boolean>;
|
|
14
|
+
abstract getUpdates(start?: number): Promise<readonly string[]>;
|
|
15
|
+
abstract initialize(): Promise<void>;
|
|
16
|
+
}
|
|
17
17
|
|
|
18
18
|
declare const identity: <T extends unknown>(x: T) => T;
|
|
19
19
|
|
|
@@ -22,11 +22,59 @@ type InferCallback<TIO extends IOLike<any, any>> = (i: typeof identity) => {
|
|
|
22
22
|
};
|
|
23
23
|
declare const infer: <TIO extends IOLike<any, any>>(callback: InferCallback<TIO>) => InferCallback<TIO>;
|
|
24
24
|
|
|
25
|
+
type EventResolver<TIO extends IOLike = IOLike, TInput extends JsonObject = {}, TOutput extends EventRecord<string, any> = {}, TPresence extends JsonObject = {}, TStorage extends Record<string, CrdtType<any, any>> = {}> = (data: TInput, context: EventResolverContext<TIO, TPresence, TStorage>) => MaybePromise<TOutput | void>;
|
|
26
|
+
interface EventResolverContext<TIO extends IOLike = IOLike, TPresence extends JsonObject = {}, TStorage extends Record<string, CrdtType<any, any>> = {}> {
|
|
27
|
+
doc: CrdtDocLike<TStorage>;
|
|
28
|
+
others: readonly UserInfo<TIO, TPresence>[];
|
|
29
|
+
room: string;
|
|
30
|
+
user: UserInfo<TIO, TPresence>;
|
|
31
|
+
}
|
|
32
|
+
type InferMetadata<TClient extends PluvClient<any, any, any, any>> = TClient extends PluvClient<any, any, any, infer IMetadata> ? IMetadata : never;
|
|
33
|
+
type MergeEventRecords<TEventRecords extends EventRecord<string, any>[], TRoot extends EventRecord<string, any> = {}> = TEventRecords extends [
|
|
34
|
+
infer IHead extends EventRecord<string, any>,
|
|
35
|
+
...infer ITail extends EventRecord<string, any>[]
|
|
36
|
+
] ? MergeEventRecords<ITail, Omit<TRoot, keyof IHead> & {
|
|
37
|
+
[P in keyof IHead]: TRoot extends Record<P, any> ? TRoot[P] | IHead[P] : IHead[P];
|
|
38
|
+
}> : Id<TRoot>;
|
|
39
|
+
interface PluvClientLimits {
|
|
40
|
+
/**
|
|
41
|
+
* @description Maximum size of presence object in bytes
|
|
42
|
+
*/
|
|
43
|
+
presenceMaxSize?: number | null;
|
|
44
|
+
}
|
|
45
|
+
interface PublicKeyParams<TMetadata extends JsonObject> {
|
|
46
|
+
metadata: TMetadata;
|
|
47
|
+
}
|
|
48
|
+
type PublicKey<TMetadata extends JsonObject> = string | ((params: PublicKeyParams<TMetadata>) => string);
|
|
49
|
+
interface WebSocketConnection {
|
|
50
|
+
/**
|
|
51
|
+
* @description How many times a connection attempt was made. This will increment upon each
|
|
52
|
+
* unsuccessful attempt, and will reset upon a successful connection.
|
|
53
|
+
* @date April 13, 2025
|
|
54
|
+
*/
|
|
55
|
+
attempts: number;
|
|
56
|
+
/**
|
|
57
|
+
* @description How many times the user has connected to the room. This can be more than 1 in
|
|
58
|
+
* the case of reconnects. This is tracked because on the very first connection (i.e. when
|
|
59
|
+
* count is 0) we don't want to send the storage state as an update to the room and overwrite
|
|
60
|
+
* the upstream state.
|
|
61
|
+
* @date April 13, 2025
|
|
62
|
+
*/
|
|
63
|
+
count: number;
|
|
64
|
+
id: string | null;
|
|
65
|
+
state: ConnectionState;
|
|
66
|
+
}
|
|
67
|
+
type WithMetadata<TMetadata extends JsonObject = {}> = keyof TMetadata extends never ? {
|
|
68
|
+
metadata?: undefined;
|
|
69
|
+
} : {
|
|
70
|
+
metadata: TMetadata;
|
|
71
|
+
};
|
|
72
|
+
|
|
25
73
|
interface PluvProcedureConfig<TIO extends IOLike = IOLike, TInput extends JsonObject = {}, TOutput extends EventRecord<string, any> = {}, TPresence extends JsonObject = {}, TStorage extends Record<string, CrdtType<any, any>> = {}> {
|
|
26
74
|
broadcast?: EventResolver<TIO, TInput, TOutput, TPresence, TStorage> | null;
|
|
27
75
|
input?: InputZodLike<TInput>;
|
|
28
76
|
}
|
|
29
|
-
declare class PluvProcedure<TIO extends IOLike = IOLike, TInput extends JsonObject = {}, TOutput extends EventRecord<string, any> = {}, TPresence extends JsonObject = {}, TStorage extends Record<string, CrdtType<any, any>> = {}, TFilled extends "input" | "broadcast" | "" = ""> {
|
|
77
|
+
declare class PluvProcedure<TIO extends IOLike = IOLike, TInput extends JsonObject = {}, TOutput extends EventRecord<string, any> = {}, TPresence extends JsonObject = {}, TStorage extends Record<string, CrdtType<any, any>> = {}, TFilled extends "input" | "broadcast" | "" = ""> implements ProcedureLike<TInput, TOutput> {
|
|
30
78
|
private _broadcast;
|
|
31
79
|
private _input;
|
|
32
80
|
get config(): ProcedureLike<TInput, TOutput>["config"];
|
|
@@ -36,19 +84,8 @@ declare class PluvProcedure<TIO extends IOLike = IOLike, TInput extends JsonObje
|
|
|
36
84
|
private _resolver;
|
|
37
85
|
}
|
|
38
86
|
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
constructor(room: string);
|
|
42
|
-
abstract addUpdate(update: string): Promise<void>;
|
|
43
|
-
abstract destroy(): Promise<void>;
|
|
44
|
-
abstract flatten(encodedState: string): Promise<void>;
|
|
45
|
-
abstract getShouldFlatten(): Promise<boolean>;
|
|
46
|
-
abstract getUpdates(start?: number): Promise<readonly string[]>;
|
|
47
|
-
abstract initialize(): Promise<void>;
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
type CrdtManagerOptions<TStorage extends Record<string, CrdtType<any, any>> = {}> = {
|
|
51
|
-
initialStorage?: AbstractCrdtDocFactory<TStorage>;
|
|
87
|
+
type CrdtManagerOptions<TCrdt extends AbstractCrdtDocFactory<any>> = {
|
|
88
|
+
initialStorage?: TCrdt;
|
|
52
89
|
};
|
|
53
90
|
|
|
54
91
|
type PluvRouterEventConfig<TIO extends IOLike = IOLike, TPresence extends JsonObject = {}, TStorage extends Record<string, CrdtType<any, any>> = {}> = {
|
|
@@ -58,11 +95,6 @@ type MergedRouter<TRouters extends PluvRouter<TIO, TPresence, TStorage, any>[] =
|
|
|
58
95
|
infer IHead extends PluvRouter<TIO, TPresence, TStorage, any>,
|
|
59
96
|
...infer ITail extends PluvRouter<TIO, TPresence, TStorage, any>[]
|
|
60
97
|
] ? MergedRouter<ITail, TIO, TPresence, TStorage, TRoot & IHead["_defs"]["events"]> : PluvRouter<TIO, TPresence, TStorage, TRoot>;
|
|
61
|
-
type MergeEvents<TClientEvents extends PluvRouterEventConfig<any, any, any>, TServerIO extends IOLike<any, any>> = TServerIO extends IOLike<infer IAuthorize, infer IServerEvents> ? IOLike<IAuthorize, {
|
|
62
|
-
[P in keyof TClientEvents]: TClientEvents[P] extends ProcedureLike<infer IClientInput, infer IClientOutput> ? {
|
|
63
|
-
[K in keyof IClientOutput]: K extends keyof IServerEvents ? IServerEvents[K] : ProcedureLike<IClientInput, Id<Pick<IClientOutput, K>>>;
|
|
64
|
-
}[keyof IClientOutput] : never;
|
|
65
|
-
} & IServerEvents> : never;
|
|
66
98
|
declare class PluvRouter<TIO extends IOLike = IOLike, TPresence extends JsonObject = {}, TStorage extends Record<string, CrdtType<any, any>> = {}, TEvents extends PluvRouterEventConfig<TIO, TPresence, TStorage> = {}> implements IORouterLike<TEvents> {
|
|
67
99
|
readonly _defs: {
|
|
68
100
|
events: TEvents;
|
|
@@ -112,9 +144,9 @@ type RoomEndpoints<TIO extends IOLike<any, any>, TMetadata extends JsonObject> =
|
|
|
112
144
|
} : {
|
|
113
145
|
authEndpoint?: undefined;
|
|
114
146
|
});
|
|
115
|
-
type PluvRoomAddon<TIO extends IOLike
|
|
116
|
-
interface PluvRoomAddonInput<TIO extends IOLike
|
|
117
|
-
room: PluvRoom<TIO, TMetadata, TPresence,
|
|
147
|
+
type PluvRoomAddon<TIO extends IOLike, TMetadata extends JsonObject, TPresence extends JsonObject, TCrdt extends AbstractCrdtDocFactory<any>> = (input: PluvRoomAddonInput<TIO, TMetadata, TPresence, TCrdt>) => Partial<PluvRoomAddonResult>;
|
|
148
|
+
interface PluvRoomAddonInput<TIO extends IOLike, TMetadata extends JsonObject, TPresence extends JsonObject, TCrdt extends AbstractCrdtDocFactory<any>> {
|
|
149
|
+
room: PluvRoom<TIO, TMetadata, TPresence, TCrdt>;
|
|
118
150
|
}
|
|
119
151
|
interface PluvRoomAddonResult {
|
|
120
152
|
storage: AbstractStorageStore;
|
|
@@ -128,18 +160,19 @@ interface ReconnectTimeoutMsParams {
|
|
|
128
160
|
attempts: number;
|
|
129
161
|
}
|
|
130
162
|
type ReconnectTimeoutMs = number | ((params: ReconnectTimeoutMsParams) => number);
|
|
131
|
-
type RoomConfig<TIO extends IOLike, TMetadata extends JsonObject
|
|
132
|
-
addons?: readonly PluvRoomAddon<TIO, TMetadata, TPresence,
|
|
163
|
+
type RoomConfig<TIO extends IOLike, TMetadata extends JsonObject, TPresence extends JsonObject, TCrdt extends AbstractCrdtDocFactory<any>, TEvents extends PluvRouterEventConfig<TIO, TPresence, InferStorage<TCrdt>>> = Id<{
|
|
164
|
+
addons?: readonly PluvRoomAddon<TIO, TMetadata, TPresence, TCrdt>[];
|
|
133
165
|
debug?: boolean | PluvRoomDebug<TIO>;
|
|
134
166
|
limits: PluvClientLimits;
|
|
135
167
|
onAuthorizationFail?: (error: Error) => void;
|
|
136
168
|
metadata?: InputZodLike<TMetadata>;
|
|
137
169
|
publicKey?: PublicKey<TMetadata>;
|
|
138
170
|
reconnectTimeoutMs?: ReconnectTimeoutMs;
|
|
139
|
-
router?: PluvRouter<TIO, TPresence,
|
|
140
|
-
} & RoomEndpoints<TIO, TMetadata> & Pick<CrdtManagerOptions<
|
|
141
|
-
declare class PluvRoom<TIO extends IOLike<any, any>, TMetadata extends JsonObject = {}, TPresence extends JsonObject = {},
|
|
171
|
+
router?: PluvRouter<TIO, TPresence, InferStorage<TCrdt>, TEvents>;
|
|
172
|
+
} & RoomEndpoints<TIO, TMetadata> & Pick<CrdtManagerOptions<TCrdt>, "initialStorage"> & UsersManagerConfig<TPresence>>;
|
|
173
|
+
declare class PluvRoom<TIO extends IOLike<any, any>, TMetadata extends JsonObject = {}, TPresence extends JsonObject = {}, TCrdt extends AbstractCrdtDocFactory<any> = NoopCrdtDocFactory, TEvents extends PluvRouterEventConfig<TIO, TPresence, InferStorage<TCrdt>> = {}> implements RoomLike<TIO, TPresence, InferStorage<TCrdt>> {
|
|
142
174
|
readonly _endpoints: RoomEndpoints<TIO, TMetadata>;
|
|
175
|
+
readonly id: string;
|
|
143
176
|
readonly metadata?: InputZodLike<TMetadata>;
|
|
144
177
|
private readonly _crdtManager;
|
|
145
178
|
private readonly _crdtNotifier;
|
|
@@ -161,7 +194,7 @@ declare class PluvRoom<TIO extends IOLike<any, any>, TMetadata extends JsonObjec
|
|
|
161
194
|
private _state;
|
|
162
195
|
private _windowListeners;
|
|
163
196
|
private _wsListeners;
|
|
164
|
-
constructor(room: string, options: RoomConfig<TIO, TMetadata, TPresence,
|
|
197
|
+
constructor(room: string, options: RoomConfig<TIO, TMetadata, TPresence, TCrdt, TEvents>);
|
|
165
198
|
get storageLoaded(): boolean;
|
|
166
199
|
get webSocket(): WebSocket | null;
|
|
167
200
|
broadcast: (<TEvent extends keyof InferIOInput<MergeEvents<TEvents, TIO>>>(event: TEvent, data: Id<InferIOInput<MergeEvents<TEvents, TIO>>[TEvent]>) => Promise<void>) & { [PEvent in keyof InferIOInput<MergeEvents<TEvents, TIO>>]: (data: Id<InferIOInput<MergeEvents<TEvents, TIO>>[PEvent]>) => Promise<void>; };
|
|
@@ -171,24 +204,23 @@ declare class PluvRoom<TIO extends IOLike<any, any>, TMetadata extends JsonObjec
|
|
|
171
204
|
disconnect(): Promise<void>;
|
|
172
205
|
event: (<TEvent extends keyof InferIOOutput<MergeEvents<TEvents, TIO>>>(event: TEvent, callback: EventNotifierSubscriptionCallback<MergeEvents<TEvents, TIO>, TEvent>) => () => void) & { [PEvent in keyof InferIOOutput<MergeEvents<TEvents, TIO>>]: (callback: EventNotifierSubscriptionCallback<MergeEvents<TEvents, TIO>, PEvent>) => () => void; };
|
|
173
206
|
getConnection: () => WebSocketConnection;
|
|
174
|
-
getDoc: () =>
|
|
207
|
+
getDoc: () => CrdtDocLike<InferStorage<TCrdt>>;
|
|
175
208
|
getMyPresence: () => TPresence;
|
|
176
209
|
getMyself: () => Id<UserInfo<TIO, TPresence>> | null;
|
|
177
210
|
getOther: (connectionId: string) => Id<UserInfo<TIO, TPresence>> | null;
|
|
178
211
|
getOthers: () => readonly Id<UserInfo<TIO, TPresence>>[];
|
|
179
|
-
getStorage: <TKey extends keyof
|
|
180
|
-
getStorageJson(): InferCrdtJson<
|
|
181
|
-
getStorageJson<TKey extends keyof
|
|
212
|
+
getStorage: <TKey extends keyof InferStorage<TCrdt>>(type: TKey) => InferStorage<TCrdt>[TKey] | null;
|
|
213
|
+
getStorageJson(): InferCrdtJson<InferStorage<TCrdt>> | null;
|
|
214
|
+
getStorageJson<TKey extends keyof InferStorage<TCrdt>>(type: TKey): InferCrdtJson<InferStorage<TCrdt>[TKey]> | null;
|
|
182
215
|
other: (connectionId: string, callback: OtherNotifierSubscriptionCallback<TIO, TPresence>) => (() => void);
|
|
183
216
|
redo: () => void;
|
|
184
|
-
storage: <TKey extends keyof
|
|
185
|
-
storageRoot: (fn: (value: { [P in keyof
|
|
217
|
+
storage: <TKey extends keyof InferStorage<TCrdt>>(key: TKey, fn: (value: InferCrdtJson<InferStorage<TCrdt>[TKey]>) => void) => (() => void);
|
|
218
|
+
storageRoot: (fn: (value: { [P in keyof InferStorage<TCrdt>]: InferCrdtJson<InferStorage<TCrdt>[P]>; }) => void) => (() => void);
|
|
186
219
|
subscribe: <TSubject extends keyof StateNotifierSubjects<TIO, TPresence>>(name: TSubject, callback: SubscriptionCallback<TIO, TPresence, TSubject>) => (() => void);
|
|
187
|
-
transact: (fn: (storage:
|
|
220
|
+
transact: (fn: (storage: InferStorage<TCrdt>) => void, origin?: string) => void;
|
|
188
221
|
undo: () => void;
|
|
189
222
|
updateMyPresence: (presence: UpdateMyPresenceAction<TPresence>) => void;
|
|
190
223
|
private _addToStorageStore;
|
|
191
|
-
private _applyStorageStore;
|
|
192
224
|
private _attachWindowListeners;
|
|
193
225
|
private _attachWsListeners;
|
|
194
226
|
private _clearInterval;
|
|
@@ -236,9 +268,9 @@ declare class PluvRoom<TIO extends IOLike<any, any>, TMetadata extends JsonObjec
|
|
|
236
268
|
private _updateState;
|
|
237
269
|
}
|
|
238
270
|
|
|
239
|
-
type PluvClientOptions<TIO extends IOLike<any, any>, TPresence extends JsonObject,
|
|
271
|
+
type PluvClientOptions<TIO extends IOLike<any, any>, TPresence extends JsonObject, TCrdt extends AbstractCrdtDocFactory<any>, TMetadata extends JsonObject> = RoomEndpoints<TIO, TMetadata> & {
|
|
240
272
|
debug?: boolean;
|
|
241
|
-
initialStorage?:
|
|
273
|
+
initialStorage?: TCrdt;
|
|
242
274
|
/**
|
|
243
275
|
* @description Configurable limits defined for client-side validation. You should only set
|
|
244
276
|
* this if you control the server and have changed the limits there.
|
|
@@ -249,17 +281,17 @@ type PluvClientOptions<TIO extends IOLike<any, any>, TPresence extends JsonObjec
|
|
|
249
281
|
publicKey?: PublicKey<TMetadata>;
|
|
250
282
|
types: InferCallback<TIO>;
|
|
251
283
|
};
|
|
252
|
-
type CreateRoomOptions<TIO extends IOLike<any, any>, TPresence extends JsonObject,
|
|
253
|
-
addons?: readonly PluvRoomAddon<TIO, TMetadata, TPresence,
|
|
284
|
+
type CreateRoomOptions<TIO extends IOLike<any, any>, TPresence extends JsonObject, TCrdt extends AbstractCrdtDocFactory<any>, TMetadata extends JsonObject, TEvents extends PluvRouterEventConfig<TIO, TPresence, InferStorage<TCrdt>> = {}> = {
|
|
285
|
+
addons?: readonly PluvRoomAddon<TIO, TMetadata, TPresence, InferStorage<TCrdt>>[];
|
|
254
286
|
debug?: boolean | PluvRoomDebug<TIO>;
|
|
255
287
|
initialPresence?: TPresence;
|
|
256
|
-
initialStorage?:
|
|
288
|
+
initialStorage?: TCrdt;
|
|
257
289
|
onAuthorizationFail?: (error: Error) => void;
|
|
258
290
|
reconnectTimeoutMs?: ReconnectTimeoutMs;
|
|
259
|
-
router?: PluvRouter<TIO, TPresence,
|
|
291
|
+
router?: PluvRouter<TIO, TPresence, InferStorage<TCrdt>, TEvents>;
|
|
260
292
|
};
|
|
261
293
|
type EnterRoomParams<TMetadata extends JsonObject = {}> = keyof TMetadata extends never ? [] : [WithMetadata<TMetadata>];
|
|
262
|
-
declare class PluvClient<TIO extends IOLike<any, any>, TPresence extends JsonObject = {},
|
|
294
|
+
declare class PluvClient<TIO extends IOLike<any, any>, TPresence extends JsonObject = {}, TCrdt extends AbstractCrdtDocFactory<any> = NoopCrdtDocFactory, TMetadata extends JsonObject = {}> {
|
|
263
295
|
readonly metadata?: InputZodLike<TMetadata>;
|
|
264
296
|
private readonly _authEndpoint;
|
|
265
297
|
private readonly _debug;
|
|
@@ -270,124 +302,31 @@ declare class PluvClient<TIO extends IOLike<any, any>, TPresence extends JsonObj
|
|
|
270
302
|
private readonly _rooms;
|
|
271
303
|
private readonly _wsEndpoint;
|
|
272
304
|
get _defs(): {
|
|
273
|
-
initialStorage:
|
|
305
|
+
initialStorage: TCrdt | undefined;
|
|
274
306
|
};
|
|
275
|
-
get procedure(): PluvProcedure<TIO, {}, {}, TPresence,
|
|
276
|
-
constructor(options: PluvClientOptions<TIO, TPresence,
|
|
277
|
-
createRoom: <TEvents extends PluvRouterEventConfig<TIO, TPresence,
|
|
278
|
-
enter: (room: string | PluvRoom<TIO, TMetadata, any, any, any>, ...args: EnterRoomParams<TMetadata>) => Promise<PluvRoom<TIO, TMetadata, TPresence,
|
|
279
|
-
getRoom: (room: string) => PluvRoom<TIO, TMetadata, TPresence,
|
|
280
|
-
getRooms: () => readonly PluvRoom<TIO, TMetadata, TPresence,
|
|
307
|
+
get procedure(): PluvProcedure<TIO, {}, {}, TPresence, InferStorage<TCrdt>>;
|
|
308
|
+
constructor(options: PluvClientOptions<TIO, TPresence, TCrdt, TMetadata>);
|
|
309
|
+
createRoom: <TEvents extends PluvRouterEventConfig<TIO, TPresence, InferStorage<TCrdt>> = {}>(room: string, options?: CreateRoomOptions<TIO, TPresence, TCrdt, TMetadata, TEvents>) => PluvRoom<TIO, TMetadata, TPresence, TCrdt, TEvents>;
|
|
310
|
+
enter: (room: string | PluvRoom<TIO, TMetadata, any, any, any>, ...args: EnterRoomParams<TMetadata>) => Promise<PluvRoom<TIO, TMetadata, TPresence, TCrdt, any>>;
|
|
311
|
+
getRoom: (room: string) => PluvRoom<TIO, TMetadata, TPresence, TCrdt, any> | null;
|
|
312
|
+
getRooms: () => readonly PluvRoom<TIO, TMetadata, TPresence, TCrdt, any>[];
|
|
281
313
|
leave: (room: string | PluvRoom<TIO, any, any, any>) => Promise<void>;
|
|
282
|
-
router<TEvents extends PluvRouterEventConfig<TIO, TPresence,
|
|
314
|
+
router<TEvents extends PluvRouterEventConfig<TIO, TPresence, InferStorage<TCrdt>> = {}>(events: TEvents): PluvRouter<TIO, TPresence, InferStorage<TCrdt>, TEvents>;
|
|
283
315
|
private _logDebug;
|
|
284
316
|
}
|
|
285
317
|
|
|
286
|
-
|
|
287
|
-
token: string | null;
|
|
288
|
-
user: Id<InferIOAuthorizeUser<InferIOAuthorize<TIO>>> | null;
|
|
289
|
-
}
|
|
290
|
-
type EventResolver<TIO extends IOLike = IOLike, TInput extends JsonObject = {}, TOutput extends EventRecord<string, any> = {}, TPresence extends JsonObject = {}, TStorage extends Record<string, CrdtType<any, any>> = {}> = (data: TInput, context: EventResolverContext<TIO, TPresence, TStorage>) => MaybePromise<TOutput | void>;
|
|
291
|
-
interface EventResolverContext<TIO extends IOLike = IOLike, TPresence extends JsonObject = {}, TStorage extends Record<string, CrdtType<any, any>> = {}> {
|
|
292
|
-
doc: AbstractCrdtDoc<TStorage>;
|
|
293
|
-
others: readonly UserInfo<TIO, TPresence>[];
|
|
294
|
-
room: string;
|
|
295
|
-
user: UserInfo<TIO, TPresence>;
|
|
296
|
-
}
|
|
297
|
-
type InferMetadata<TClient extends PluvClient<any, any, any, any>> = TClient extends PluvClient<any, any, any, infer IMetadata> ? IMetadata : never;
|
|
298
|
-
type MergeEventRecords<TEventRecords extends EventRecord<string, any>[], TRoot extends EventRecord<string, any> = {}> = TEventRecords extends [
|
|
299
|
-
infer IHead extends EventRecord<string, any>,
|
|
300
|
-
...infer ITail extends EventRecord<string, any>[]
|
|
301
|
-
] ? MergeEventRecords<ITail, Omit<TRoot, keyof IHead> & {
|
|
302
|
-
[P in keyof IHead]: TRoot extends Record<P, any> ? TRoot[P] | IHead[P] : IHead[P];
|
|
303
|
-
}> : Id<TRoot>;
|
|
304
|
-
interface PluvClientLimits {
|
|
305
|
-
/**
|
|
306
|
-
* @description Maximum size of presence object in bytes
|
|
307
|
-
*/
|
|
308
|
-
presenceMaxSize?: number | null;
|
|
309
|
-
}
|
|
310
|
-
interface PublicKeyParams<TMetadata extends JsonObject> {
|
|
311
|
-
metadata: TMetadata;
|
|
312
|
-
}
|
|
313
|
-
type PublicKey<TMetadata extends JsonObject> = string | ((params: PublicKeyParams<TMetadata>) => string);
|
|
314
|
-
type UpdateMyPresenceAction<TPresence extends JsonObject> = Partial<TPresence> | ((oldPresence: TPresence | null) => Partial<TPresence>);
|
|
315
|
-
interface UserInfo<TIO extends IOLike, TPresence extends JsonObject = {}> {
|
|
316
|
-
connectionId: string;
|
|
317
|
-
presence: TPresence;
|
|
318
|
-
user: Id<InferIOAuthorizeUser<InferIOAuthorize<TIO>>>;
|
|
319
|
-
}
|
|
320
|
-
interface WebSocketConnection {
|
|
321
|
-
/**
|
|
322
|
-
* @description How many times a connection attempt was made. This will increment upon each
|
|
323
|
-
* unsuccessful attempt, and will reset upon a successful connection.
|
|
324
|
-
* @date April 13, 2025
|
|
325
|
-
*/
|
|
326
|
-
attempts: number;
|
|
327
|
-
/**
|
|
328
|
-
* @description How many times the user has connected to the room. This can be more than 1 in
|
|
329
|
-
* the case of reconnects. This is tracked because on the very first connection (i.e. when
|
|
330
|
-
* count is 0) we don't want to send the storage state as an update to the room and overwrite
|
|
331
|
-
* the upstream state.
|
|
332
|
-
* @date April 13, 2025
|
|
333
|
-
*/
|
|
334
|
-
count: number;
|
|
335
|
-
id: string | null;
|
|
336
|
-
state: ConnectionState;
|
|
337
|
-
}
|
|
338
|
-
interface WebSocketState<TIO extends IOLike> {
|
|
339
|
-
authorization: AuthorizationState<TIO>;
|
|
340
|
-
connection: WebSocketConnection;
|
|
341
|
-
webSocket: WebSocket | null;
|
|
342
|
-
}
|
|
343
|
-
type WithMetadata<TMetadata extends JsonObject = {}> = keyof TMetadata extends never ? {
|
|
344
|
-
metadata?: undefined;
|
|
345
|
-
} : {
|
|
346
|
-
metadata: TMetadata;
|
|
347
|
-
};
|
|
348
|
-
|
|
349
|
-
type OtherNotifierSubscriptionCallback<TIO extends IOLike, TPresence extends JsonObject> = (value: Id<UserInfo<TIO, TPresence>> | null) => void;
|
|
350
|
-
|
|
351
|
-
declare abstract class AbstractRoom<TIO extends IOLike, TPresence extends JsonObject = {}, TStorage extends Record<string, CrdtType<any, any>> = {}, TEvents extends PluvRouterEventConfig<TIO, TPresence, TStorage> = {}> {
|
|
352
|
-
readonly id: string;
|
|
353
|
-
constructor(room: string);
|
|
354
|
-
abstract storageLoaded: boolean;
|
|
355
|
-
abstract broadcast<TEvent extends keyof InferIOInput<MergeEvents<TEvents, TIO>>>(event: TEvent, data: Id<InferIOInput<MergeEvents<TEvents, TIO>>[TEvent]>): void;
|
|
356
|
-
abstract canRedo(): boolean;
|
|
357
|
-
abstract canUndo(): boolean;
|
|
358
|
-
abstract getDoc(): AbstractCrdtDoc<TStorage>;
|
|
359
|
-
abstract event<TEvent extends keyof InferIOOutput<MergeEvents<TEvents, TIO>>>(event: TEvent, callback: EventNotifierSubscriptionCallback<MergeEvents<TEvents, TIO>, TEvent>): () => void;
|
|
360
|
-
abstract getConnection(): WebSocketConnection;
|
|
361
|
-
abstract getMyPresence(): TPresence;
|
|
362
|
-
abstract getMyself(): Id<UserInfo<TIO, TPresence>> | null;
|
|
363
|
-
abstract getOther(connectionId: string): Id<UserInfo<TIO, TPresence>> | null;
|
|
364
|
-
abstract getOthers(): readonly Id<UserInfo<TIO, TPresence>>[];
|
|
365
|
-
abstract getStorage<TKey extends keyof TStorage>(type: TKey): TStorage[TKey] | null;
|
|
366
|
-
abstract getStorageJson(): InferCrdtJson<TStorage> | null;
|
|
367
|
-
abstract getStorageJson<TKey extends keyof TStorage>(type: TKey): InferCrdtJson<TStorage[TKey]> | null;
|
|
368
|
-
abstract other(connectionId: string, callback: OtherNotifierSubscriptionCallback<TIO, TPresence>): () => void;
|
|
369
|
-
abstract redo(): void;
|
|
370
|
-
abstract storage<TKey extends keyof TStorage>(key: TKey, fn: (value: InferCrdtJson<TStorage[TKey]>) => void): () => void;
|
|
371
|
-
abstract storageRoot(fn: (value: {
|
|
372
|
-
[P in keyof TStorage]: InferCrdtJson<TStorage[P]>;
|
|
373
|
-
}) => void): () => void;
|
|
374
|
-
abstract subscribe<TSubject extends keyof StateNotifierSubjects<TIO, TPresence>>(name: TSubject, callback: SubscriptionCallback<TIO, TPresence, TSubject>): () => void;
|
|
375
|
-
abstract transact(fn: (storage: TStorage) => void, origin?: string): void;
|
|
376
|
-
abstract undo(): void;
|
|
377
|
-
abstract updateMyPresence(presence: UpdateMyPresenceAction<TPresence>): void;
|
|
378
|
-
}
|
|
379
|
-
|
|
380
|
-
declare const createClient: <TIO extends IOLike<any, any>, TPresence extends JsonObject = {}, TStorage extends Record<string, CrdtType<any, any>> = {}, TMetadata extends JsonObject = {}>(options: PluvClientOptions<TIO, TPresence, TStorage, TMetadata>) => PluvClient<TIO, TPresence, TStorage, TMetadata>;
|
|
318
|
+
declare const createClient: <TIO extends IOLike<any, any>, TPresence extends JsonObject = {}, TCrdt extends AbstractCrdtDocFactory<any> = NoopCrdtDocFactory, TMetadata extends JsonObject = {}>(options: PluvClientOptions<TIO, TPresence, TCrdt, TMetadata>) => PluvClient<TIO, TPresence, TCrdt, TMetadata>;
|
|
381
319
|
|
|
382
320
|
type MockedRoomEvents<TIO extends IOLike> = Partial<{
|
|
383
321
|
[P in keyof InferIOInput<TIO>]: (data: Id<InferIOInput<TIO>[P]>) => Partial<InferIOOutput<TIO>>;
|
|
384
322
|
}>;
|
|
385
|
-
type MockedRoomConfig<TIO extends IOLike, TPresence extends JsonObject
|
|
323
|
+
type MockedRoomConfig<TIO extends IOLike, TPresence extends JsonObject, TCrdt extends AbstractCrdtDocFactory<any>, TEvents extends PluvRouterEventConfig<TIO, TPresence, InferStorage<TCrdt>>> = {
|
|
386
324
|
events?: MockedRoomEvents<MergeEvents<TEvents, TIO>>;
|
|
387
325
|
limits?: PluvClientLimits;
|
|
388
|
-
router?: PluvRouter<TIO, TPresence,
|
|
389
|
-
} & Pick<CrdtManagerOptions<
|
|
390
|
-
declare class MockedRoom<TIO extends IOLike, TPresence extends JsonObject
|
|
326
|
+
router?: PluvRouter<TIO, TPresence, InferStorage<TCrdt>, TEvents>;
|
|
327
|
+
} & Pick<CrdtManagerOptions<TCrdt>, "initialStorage"> & Omit<UsersManagerConfig<TPresence>, "limits">;
|
|
328
|
+
declare class MockedRoom<TIO extends IOLike, TPresence extends JsonObject, TCrdt extends AbstractCrdtDocFactory<any>, TEvents extends PluvRouterEventConfig<TIO, TPresence, InferStorage<TCrdt>>> implements RoomLike<TIO, TPresence, InferStorage<TCrdt>> {
|
|
329
|
+
readonly id: string;
|
|
391
330
|
private readonly _crdtManager;
|
|
392
331
|
private readonly _crdtNotifier;
|
|
393
332
|
private readonly _eventNotifier;
|
|
@@ -399,27 +338,27 @@ declare class MockedRoom<TIO extends IOLike, TPresence extends JsonObject = {},
|
|
|
399
338
|
private readonly _stateNotifier;
|
|
400
339
|
private readonly _subscriptions;
|
|
401
340
|
private readonly _usersManager;
|
|
402
|
-
constructor(room: string, options: MockedRoomConfig<TIO, TPresence,
|
|
341
|
+
constructor(room: string, options: MockedRoomConfig<TIO, TPresence, TCrdt, TEvents>);
|
|
403
342
|
get storageLoaded(): boolean;
|
|
404
343
|
broadcast: (<TEvent extends keyof InferIOInput<MergeEvents<TEvents, TIO>>>(event: TEvent, data: Id<InferIOInput<MergeEvents<TEvents, TIO>>[TEvent]>) => Promise<void>) & { [event in keyof InferIOInput<TIO>]: (data: Id<InferIOInput<TIO>[event]>) => Promise<void>; };
|
|
405
344
|
canRedo: () => boolean;
|
|
406
345
|
canUndo: () => boolean;
|
|
407
346
|
event: (<TEvent extends keyof InferIOOutput<MergeEvents<TEvents, TIO>>>(event: TEvent, callback: EventNotifierSubscriptionCallback<MergeEvents<TEvents, TIO>, TEvent>) => () => void) & { [event in keyof InferIOOutput<MergeEvents<TEvents, TIO>>]: (callback: EventNotifierSubscriptionCallback<MergeEvents<TEvents, TIO>, any>) => () => void; };
|
|
408
347
|
getConnection: () => WebSocketConnection;
|
|
409
|
-
getDoc():
|
|
348
|
+
getDoc(): CrdtDocLike<InferStorage<TCrdt>>;
|
|
410
349
|
getMyPresence: () => TPresence;
|
|
411
350
|
getMyself: () => Id<UserInfo<TIO, TPresence>> | null;
|
|
412
351
|
getOther: (connectionId: string) => Id<UserInfo<TIO, TPresence>> | null;
|
|
413
352
|
getOthers: () => readonly Id<UserInfo<TIO, TPresence>>[];
|
|
414
|
-
getStorage: <TKey extends keyof
|
|
415
|
-
getStorageJson(): InferCrdtJson<
|
|
416
|
-
getStorageJson<TKey extends keyof
|
|
353
|
+
getStorage: <TKey extends keyof InferStorage<TCrdt>>(type: TKey) => InferStorage<TCrdt>[TKey] | null;
|
|
354
|
+
getStorageJson(): InferCrdtJson<InferStorage<TCrdt>> | null;
|
|
355
|
+
getStorageJson<TKey extends keyof InferStorage<TCrdt>>(type: TKey): InferCrdtJson<InferStorage<TCrdt>[TKey]> | null;
|
|
417
356
|
other: (connectionId: string, callback: OtherNotifierSubscriptionCallback<TIO, TPresence>) => (() => void);
|
|
418
357
|
redo: () => void;
|
|
419
|
-
storage: <TKey extends keyof
|
|
420
|
-
storageRoot: (fn: (value: { [P in keyof
|
|
358
|
+
storage: <TKey extends keyof InferStorage<TCrdt>>(key: TKey, fn: (value: InferCrdtJson<InferStorage<TCrdt>[TKey]>) => void) => (() => void);
|
|
359
|
+
storageRoot: (fn: (value: { [P in keyof InferStorage<TCrdt>]: InferCrdtJson<InferStorage<TCrdt>[P]>; }) => void) => (() => void);
|
|
421
360
|
subscribe: <TSubject extends keyof StateNotifierSubjects<TIO, TPresence>>(name: TSubject, callback: SubscriptionCallback<TIO, TPresence, TSubject>) => (() => void);
|
|
422
|
-
transact: (fn: (storage:
|
|
361
|
+
transact: (fn: (storage: InferStorage<TCrdt>) => void, origin?: string) => void;
|
|
423
362
|
undo: () => void;
|
|
424
363
|
updateMyPresence: (presence: UpdateMyPresenceAction<TPresence>) => void;
|
|
425
364
|
private _observeCrdt;
|
|
@@ -436,4 +375,4 @@ declare const register: <TMetadata extends JsonObject>(params: RegisterParams<TM
|
|
|
436
375
|
wsEndpoint: (params: EndpointParams<TMetadata>) => string;
|
|
437
376
|
};
|
|
438
377
|
|
|
439
|
-
export {
|
|
378
|
+
export { AbstractStorageStore, type CreateRoomOptions, type EnterRoomParams, type InferCallback, type InferMetadata, MockedRoom, type MockedRoomConfig, type MockedRoomEvents, PluvClient, type PluvClientOptions, type PluvProcedureConfig, PluvRoom, type PluvRoomAddon, type PluvRoomAddonInput, type PluvRoomAddonResult, type PluvRoomDebug, PluvRouter, type PluvRouterEventConfig, type PublicKey, type PublicKeyParams, type RegisterParams, type RoomConnectParams, type RoomEndpoints, type WebSocketConnection, createClient, infer, register };
|