@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/src/MockedRoom.ts
CHANGED
|
@@ -1,32 +1,40 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
import type {
|
|
3
|
-
|
|
1
|
+
import type { AbstractCrdtDocFactory, CrdtType, InferCrdtJson, InferStorage } from "@pluv/crdt";
|
|
2
|
+
import type {
|
|
3
|
+
CrdtDocLike,
|
|
4
|
+
EventNotifierSubscriptionCallback,
|
|
5
|
+
IOLike,
|
|
6
|
+
Id,
|
|
7
|
+
InferIOInput,
|
|
8
|
+
InferIOOutput,
|
|
9
|
+
JsonObject,
|
|
10
|
+
MergeEvents,
|
|
11
|
+
OtherNotifierSubscriptionCallback,
|
|
12
|
+
RoomLike,
|
|
13
|
+
UpdateMyPresenceAction,
|
|
14
|
+
UserInfo,
|
|
15
|
+
WebSocketState,
|
|
16
|
+
} from "@pluv/types";
|
|
17
|
+
import { ConnectionState } from "@pluv/types";
|
|
4
18
|
import type { CrdtManagerOptions } from "./CrdtManager";
|
|
5
19
|
import { CrdtManager } from "./CrdtManager";
|
|
6
20
|
import { CrdtNotifier } from "./CrdtNotifier";
|
|
7
|
-
import type { EventNotifierSubscriptionCallback } from "./EventNotifier";
|
|
8
21
|
import { EventNotifier } from "./EventNotifier";
|
|
9
|
-
import type { OtherNotifierSubscriptionCallback } from "./OtherNotifier";
|
|
10
22
|
import { OtherNotifier } from "./OtherNotifier";
|
|
11
23
|
import { PluvProcedure } from "./PluvProcedure";
|
|
12
|
-
import type {
|
|
24
|
+
import type { PluvRouterEventConfig } from "./PluvRouter";
|
|
13
25
|
import { PluvRouter } from "./PluvRouter";
|
|
14
26
|
import type { StateNotifierSubjects, SubscriptionCallback } from "./StateNotifier";
|
|
15
27
|
import { StateNotifier } from "./StateNotifier";
|
|
16
28
|
import type { UsersManagerConfig } from "./UsersManager";
|
|
17
29
|
import { UsersManager } from "./UsersManager";
|
|
18
|
-
import {
|
|
30
|
+
import { MAX_PRESENCE_SIZE_BYTES } from "./constants";
|
|
19
31
|
import type {
|
|
20
32
|
EventResolver,
|
|
21
33
|
EventResolverContext,
|
|
22
34
|
InternalSubscriptions,
|
|
23
35
|
PluvClientLimits,
|
|
24
|
-
UpdateMyPresenceAction,
|
|
25
|
-
UserInfo,
|
|
26
36
|
WebSocketConnection,
|
|
27
|
-
WebSocketState,
|
|
28
37
|
} from "./types";
|
|
29
|
-
import { MAX_PRESENCE_SIZE_BYTES } from "./constants";
|
|
30
38
|
|
|
31
39
|
export type MockedRoomEvents<TIO extends IOLike> = Partial<{
|
|
32
40
|
[P in keyof InferIOInput<TIO>]: (data: Id<InferIOInput<TIO>[P]>) => Partial<InferIOOutput<TIO>>;
|
|
@@ -34,29 +42,32 @@ export type MockedRoomEvents<TIO extends IOLike> = Partial<{
|
|
|
34
42
|
|
|
35
43
|
export type MockedRoomConfig<
|
|
36
44
|
TIO extends IOLike,
|
|
37
|
-
TPresence extends JsonObject
|
|
38
|
-
|
|
39
|
-
TEvents extends PluvRouterEventConfig<TIO, TPresence,
|
|
45
|
+
TPresence extends JsonObject,
|
|
46
|
+
TCrdt extends AbstractCrdtDocFactory<any>,
|
|
47
|
+
TEvents extends PluvRouterEventConfig<TIO, TPresence, InferStorage<TCrdt>>,
|
|
40
48
|
> = {
|
|
41
49
|
events?: MockedRoomEvents<MergeEvents<TEvents, TIO>>;
|
|
42
50
|
limits?: PluvClientLimits;
|
|
43
|
-
router?: PluvRouter<TIO, TPresence,
|
|
44
|
-
} & Pick<CrdtManagerOptions<
|
|
51
|
+
router?: PluvRouter<TIO, TPresence, InferStorage<TCrdt>, TEvents>;
|
|
52
|
+
} & Pick<CrdtManagerOptions<TCrdt>, "initialStorage"> &
|
|
45
53
|
Omit<UsersManagerConfig<TPresence>, "limits">;
|
|
46
54
|
|
|
47
55
|
export class MockedRoom<
|
|
48
56
|
TIO extends IOLike,
|
|
49
|
-
TPresence extends JsonObject
|
|
50
|
-
|
|
51
|
-
TEvents extends PluvRouterEventConfig<TIO, TPresence,
|
|
52
|
-
>
|
|
53
|
-
|
|
54
|
-
|
|
57
|
+
TPresence extends JsonObject,
|
|
58
|
+
TCrdt extends AbstractCrdtDocFactory<any>,
|
|
59
|
+
TEvents extends PluvRouterEventConfig<TIO, TPresence, InferStorage<TCrdt>>,
|
|
60
|
+
> implements RoomLike<TIO, TPresence, InferStorage<TCrdt>>
|
|
61
|
+
{
|
|
62
|
+
public readonly id: string;
|
|
63
|
+
|
|
64
|
+
private readonly _crdtManager: CrdtManager<TCrdt>;
|
|
65
|
+
private readonly _crdtNotifier = new CrdtNotifier<InferStorage<TCrdt>>();
|
|
55
66
|
private readonly _eventNotifier = new EventNotifier<MergeEvents<TEvents, TIO>>();
|
|
56
67
|
private readonly _events?: MockedRoomEvents<MergeEvents<TEvents, TIO>>;
|
|
57
68
|
private readonly _limits: PluvClientLimits;
|
|
58
69
|
private readonly _otherNotifier = new OtherNotifier<TIO, TPresence>();
|
|
59
|
-
private readonly _router: PluvRouter<TIO, TPresence,
|
|
70
|
+
private readonly _router: PluvRouter<TIO, TPresence, InferStorage<TCrdt>, TEvents>;
|
|
60
71
|
private _state: WebSocketState<TIO> = {
|
|
61
72
|
authorization: {
|
|
62
73
|
token: null,
|
|
@@ -76,10 +87,10 @@ export class MockedRoom<
|
|
|
76
87
|
};
|
|
77
88
|
private readonly _usersManager: UsersManager<TIO, TPresence>;
|
|
78
89
|
|
|
79
|
-
constructor(room: string, options: MockedRoomConfig<TIO, TPresence,
|
|
90
|
+
constructor(room: string, options: MockedRoomConfig<TIO, TPresence, TCrdt, TEvents>) {
|
|
80
91
|
const { events, initialPresence, initialStorage, limits, presence, router } = options;
|
|
81
92
|
|
|
82
|
-
|
|
93
|
+
this.id = room;
|
|
83
94
|
|
|
84
95
|
this._events = events;
|
|
85
96
|
this._limits = {
|
|
@@ -87,14 +98,15 @@ export class MockedRoom<
|
|
|
87
98
|
...limits,
|
|
88
99
|
};
|
|
89
100
|
this._router =
|
|
90
|
-
router ??
|
|
101
|
+
router ??
|
|
102
|
+
(new PluvRouter({}) as PluvRouter<TIO, TPresence, InferStorage<TCrdt>, TEvents>);
|
|
91
103
|
this._usersManager = new UsersManager<TIO, TPresence>({
|
|
92
104
|
initialPresence,
|
|
93
105
|
limits: this._limits,
|
|
94
106
|
presence,
|
|
95
107
|
});
|
|
96
108
|
|
|
97
|
-
this._crdtManager = new CrdtManager<
|
|
109
|
+
this._crdtManager = new CrdtManager<TCrdt>({
|
|
98
110
|
initialStorage,
|
|
99
111
|
});
|
|
100
112
|
|
|
@@ -120,7 +132,7 @@ export class MockedRoom<
|
|
|
120
132
|
any,
|
|
121
133
|
any,
|
|
122
134
|
TPresence,
|
|
123
|
-
|
|
135
|
+
InferStorage<TCrdt>
|
|
124
136
|
> | null;
|
|
125
137
|
|
|
126
138
|
if (!procedure?.config.broadcast) {
|
|
@@ -134,7 +146,7 @@ export class MockedRoom<
|
|
|
134
146
|
if (!myself) return;
|
|
135
147
|
|
|
136
148
|
const parsed = procedure.config.input ? procedure.config.input.parse(data) : data;
|
|
137
|
-
const context: EventResolverContext<TIO, TPresence,
|
|
149
|
+
const context: EventResolverContext<TIO, TPresence, InferStorage<TCrdt>> = {
|
|
138
150
|
doc: this._crdtManager.doc,
|
|
139
151
|
others: this._usersManager.getOthers(),
|
|
140
152
|
room: this.id,
|
|
@@ -142,7 +154,13 @@ export class MockedRoom<
|
|
|
142
154
|
};
|
|
143
155
|
|
|
144
156
|
const output = await (
|
|
145
|
-
procedure.config.broadcast as EventResolver<
|
|
157
|
+
procedure.config.broadcast as EventResolver<
|
|
158
|
+
TIO,
|
|
159
|
+
any,
|
|
160
|
+
any,
|
|
161
|
+
TPresence,
|
|
162
|
+
InferStorage<TCrdt>
|
|
163
|
+
>
|
|
146
164
|
)(parsed, context);
|
|
147
165
|
|
|
148
166
|
Object.entries(output).forEach(([_type, _data]) => {
|
|
@@ -199,7 +217,7 @@ export class MockedRoom<
|
|
|
199
217
|
return Object.freeze(JSON.parse(JSON.stringify(this._state.connection)));
|
|
200
218
|
};
|
|
201
219
|
|
|
202
|
-
public getDoc():
|
|
220
|
+
public getDoc(): CrdtDocLike<InferStorage<TCrdt>> {
|
|
203
221
|
return this._crdtManager.doc;
|
|
204
222
|
}
|
|
205
223
|
|
|
@@ -219,7 +237,9 @@ export class MockedRoom<
|
|
|
219
237
|
return this._usersManager.getOthers();
|
|
220
238
|
};
|
|
221
239
|
|
|
222
|
-
public getStorage = <TKey extends keyof
|
|
240
|
+
public getStorage = <TKey extends keyof InferStorage<TCrdt>>(
|
|
241
|
+
type: TKey,
|
|
242
|
+
): InferStorage<TCrdt>[TKey] | null => {
|
|
223
243
|
const sharedType = this._crdtManager.get(type);
|
|
224
244
|
|
|
225
245
|
if (typeof sharedType === "undefined") return null;
|
|
@@ -227,11 +247,11 @@ export class MockedRoom<
|
|
|
227
247
|
return sharedType;
|
|
228
248
|
};
|
|
229
249
|
|
|
230
|
-
public getStorageJson(): InferCrdtJson<
|
|
231
|
-
public getStorageJson<TKey extends keyof
|
|
250
|
+
public getStorageJson(): InferCrdtJson<InferStorage<TCrdt>> | null;
|
|
251
|
+
public getStorageJson<TKey extends keyof InferStorage<TCrdt>>(
|
|
232
252
|
type: TKey,
|
|
233
|
-
): InferCrdtJson<
|
|
234
|
-
public getStorageJson<TKey extends keyof
|
|
253
|
+
): InferCrdtJson<InferStorage<TCrdt>[TKey]> | null;
|
|
254
|
+
public getStorageJson<TKey extends keyof InferStorage<TCrdt>>(type?: TKey) {
|
|
235
255
|
if (this._state.connection.id === null) return null;
|
|
236
256
|
|
|
237
257
|
if (typeof type === "undefined") return this._crdtManager.doc.toJson();
|
|
@@ -254,16 +274,16 @@ export class MockedRoom<
|
|
|
254
274
|
this._crdtManager.doc.redo();
|
|
255
275
|
};
|
|
256
276
|
|
|
257
|
-
public storage = <TKey extends keyof
|
|
277
|
+
public storage = <TKey extends keyof InferStorage<TCrdt>>(
|
|
258
278
|
key: TKey,
|
|
259
|
-
fn: (value: InferCrdtJson<
|
|
279
|
+
fn: (value: InferCrdtJson<InferStorage<TCrdt>[TKey]>) => void,
|
|
260
280
|
): (() => void) => {
|
|
261
281
|
return this._crdtNotifier.subscribe(key, fn);
|
|
262
282
|
};
|
|
263
283
|
|
|
264
284
|
public storageRoot = (
|
|
265
285
|
fn: (value: {
|
|
266
|
-
[P in keyof
|
|
286
|
+
[P in keyof InferStorage<TCrdt>]: InferCrdtJson<InferStorage<TCrdt>[P]>;
|
|
267
287
|
}) => void,
|
|
268
288
|
): (() => void) => {
|
|
269
289
|
return this._crdtNotifier.subcribeRoot(fn);
|
|
@@ -276,7 +296,7 @@ export class MockedRoom<
|
|
|
276
296
|
return this._stateNotifier.subscribe(name, callback);
|
|
277
297
|
};
|
|
278
298
|
|
|
279
|
-
public transact = (fn: (storage:
|
|
299
|
+
public transact = (fn: (storage: InferStorage<TCrdt>) => void, origin?: string): void => {
|
|
280
300
|
const _origin = origin ?? this._state.connection.id;
|
|
281
301
|
const crdtManager = this._crdtManager;
|
|
282
302
|
|
|
@@ -338,7 +358,7 @@ export class MockedRoom<
|
|
|
338
358
|
return { ...acc, [prop]: serialized };
|
|
339
359
|
},
|
|
340
360
|
{} as {
|
|
341
|
-
[P in keyof
|
|
361
|
+
[P in keyof InferStorage<TCrdt>]: InferCrdtJson<InferStorage<TCrdt>[P]>;
|
|
342
362
|
},
|
|
343
363
|
);
|
|
344
364
|
|
package/src/OtherNotifier.ts
CHANGED
|
@@ -1,11 +1,12 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type {
|
|
2
|
+
Id,
|
|
3
|
+
IOLike,
|
|
4
|
+
JsonObject,
|
|
5
|
+
OtherNotifierSubscriptionCallback,
|
|
6
|
+
UserInfo,
|
|
7
|
+
} from "@pluv/types";
|
|
2
8
|
import type { Subject } from "wonka";
|
|
3
9
|
import { makeSubject, subscribe } from "wonka";
|
|
4
|
-
import type { UserInfo } from "./types";
|
|
5
|
-
|
|
6
|
-
export type OtherNotifierSubscriptionCallback<TIO extends IOLike, TPresence extends JsonObject> = (
|
|
7
|
-
value: Id<UserInfo<TIO, TPresence>> | null,
|
|
8
|
-
) => void;
|
|
9
10
|
|
|
10
11
|
export class OtherNotifier<TIO extends IOLike, TPresence extends JsonObject = {}> {
|
|
11
12
|
private _subjects = new Map<
|
package/src/PluvClient.ts
CHANGED
|
@@ -1,4 +1,9 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type {
|
|
2
|
+
AbstractCrdtDocFactory,
|
|
3
|
+
CrdtType,
|
|
4
|
+
InferStorage,
|
|
5
|
+
NoopCrdtDocFactory,
|
|
6
|
+
} from "@pluv/crdt";
|
|
2
7
|
import type { InputZodLike, IOLike, JsonObject } from "@pluv/types";
|
|
3
8
|
import { MAX_PRESENCE_SIZE_BYTES } from "./constants";
|
|
4
9
|
import type { InferCallback } from "./infer";
|
|
@@ -20,11 +25,11 @@ import type { PluvClientLimits, PublicKey, WithMetadata } from "./types";
|
|
|
20
25
|
export type PluvClientOptions<
|
|
21
26
|
TIO extends IOLike<any, any>,
|
|
22
27
|
TPresence extends JsonObject,
|
|
23
|
-
|
|
28
|
+
TCrdt extends AbstractCrdtDocFactory<any>,
|
|
24
29
|
TMetadata extends JsonObject,
|
|
25
30
|
> = RoomEndpoints<TIO, TMetadata> & {
|
|
26
31
|
debug?: boolean;
|
|
27
|
-
initialStorage?:
|
|
32
|
+
initialStorage?: TCrdt;
|
|
28
33
|
/**
|
|
29
34
|
* @description Configurable limits defined for client-side validation. You should only set
|
|
30
35
|
* this if you control the server and have changed the limits there.
|
|
@@ -39,17 +44,17 @@ export type PluvClientOptions<
|
|
|
39
44
|
export type CreateRoomOptions<
|
|
40
45
|
TIO extends IOLike<any, any>,
|
|
41
46
|
TPresence extends JsonObject,
|
|
42
|
-
|
|
47
|
+
TCrdt extends AbstractCrdtDocFactory<any>,
|
|
43
48
|
TMetadata extends JsonObject,
|
|
44
|
-
TEvents extends PluvRouterEventConfig<TIO, TPresence,
|
|
49
|
+
TEvents extends PluvRouterEventConfig<TIO, TPresence, InferStorage<TCrdt>> = {},
|
|
45
50
|
> = {
|
|
46
|
-
addons?: readonly PluvRoomAddon<TIO, TMetadata, TPresence,
|
|
51
|
+
addons?: readonly PluvRoomAddon<TIO, TMetadata, TPresence, InferStorage<TCrdt>>[];
|
|
47
52
|
debug?: boolean | PluvRoomDebug<TIO>;
|
|
48
53
|
initialPresence?: TPresence;
|
|
49
|
-
initialStorage?:
|
|
54
|
+
initialStorage?: TCrdt;
|
|
50
55
|
onAuthorizationFail?: (error: Error) => void;
|
|
51
56
|
reconnectTimeoutMs?: ReconnectTimeoutMs;
|
|
52
|
-
router?: PluvRouter<TIO, TPresence,
|
|
57
|
+
router?: PluvRouter<TIO, TPresence, InferStorage<TCrdt>, TEvents>;
|
|
53
58
|
};
|
|
54
59
|
|
|
55
60
|
export type EnterRoomParams<TMetadata extends JsonObject = {}> = keyof TMetadata extends never
|
|
@@ -59,18 +64,18 @@ export type EnterRoomParams<TMetadata extends JsonObject = {}> = keyof TMetadata
|
|
|
59
64
|
export class PluvClient<
|
|
60
65
|
TIO extends IOLike<any, any>,
|
|
61
66
|
TPresence extends JsonObject = {},
|
|
62
|
-
|
|
67
|
+
TCrdt extends AbstractCrdtDocFactory<any> = NoopCrdtDocFactory,
|
|
63
68
|
TMetadata extends JsonObject = {},
|
|
64
69
|
> {
|
|
65
70
|
public readonly metadata?: InputZodLike<TMetadata>;
|
|
66
71
|
|
|
67
72
|
private readonly _authEndpoint: AuthEndpoint<TMetadata> | undefined;
|
|
68
73
|
private readonly _debug: boolean;
|
|
69
|
-
private readonly _initialStorage?:
|
|
74
|
+
private readonly _initialStorage?: TCrdt;
|
|
70
75
|
private readonly _limits: PluvClientLimits;
|
|
71
76
|
private readonly _presence?: InputZodLike<TPresence>;
|
|
72
77
|
private readonly _publicKey: PublicKey<TMetadata> | null = null;
|
|
73
|
-
private readonly _rooms = new Map<string, PluvRoom<TIO, TMetadata, TPresence,
|
|
78
|
+
private readonly _rooms = new Map<string, PluvRoom<TIO, TMetadata, TPresence, TCrdt, any>>();
|
|
74
79
|
private readonly _wsEndpoint: WsEndpoint<TMetadata> | undefined;
|
|
75
80
|
|
|
76
81
|
public get _defs() {
|
|
@@ -79,11 +84,11 @@ export class PluvClient<
|
|
|
79
84
|
};
|
|
80
85
|
}
|
|
81
86
|
|
|
82
|
-
public get procedure(): PluvProcedure<TIO, {}, {}, TPresence,
|
|
83
|
-
return new PluvProcedure<TIO, {}, {}, TPresence,
|
|
87
|
+
public get procedure(): PluvProcedure<TIO, {}, {}, TPresence, InferStorage<TCrdt>> {
|
|
88
|
+
return new PluvProcedure<TIO, {}, {}, TPresence, InferStorage<TCrdt>>();
|
|
84
89
|
}
|
|
85
90
|
|
|
86
|
-
constructor(options: PluvClientOptions<TIO, TPresence,
|
|
91
|
+
constructor(options: PluvClientOptions<TIO, TPresence, TCrdt, TMetadata>) {
|
|
87
92
|
const {
|
|
88
93
|
authEndpoint,
|
|
89
94
|
debug = false,
|
|
@@ -110,20 +115,22 @@ export class PluvClient<
|
|
|
110
115
|
if (!!publicKey) this._publicKey = publicKey;
|
|
111
116
|
}
|
|
112
117
|
|
|
113
|
-
public createRoom = <
|
|
118
|
+
public createRoom = <
|
|
119
|
+
TEvents extends PluvRouterEventConfig<TIO, TPresence, InferStorage<TCrdt>> = {},
|
|
120
|
+
>(
|
|
114
121
|
room: string,
|
|
115
|
-
options: CreateRoomOptions<TIO, TPresence,
|
|
116
|
-
): PluvRoom<TIO, TMetadata, TPresence,
|
|
122
|
+
options: CreateRoomOptions<TIO, TPresence, TCrdt, TMetadata, TEvents> = {},
|
|
123
|
+
): PluvRoom<TIO, TMetadata, TPresence, TCrdt, TEvents> => {
|
|
117
124
|
const oldRoom = this.getRoom(room);
|
|
118
125
|
|
|
119
126
|
if (oldRoom) return oldRoom;
|
|
120
127
|
|
|
121
|
-
const newRoom = new PluvRoom<TIO, TMetadata, TPresence,
|
|
128
|
+
const newRoom = new PluvRoom<TIO, TMetadata, TPresence, TCrdt, TEvents>(room, {
|
|
122
129
|
addons: options.addons,
|
|
123
130
|
authEndpoint: this._authEndpoint,
|
|
124
131
|
debug: options.debug,
|
|
125
132
|
initialPresence: options.initialPresence,
|
|
126
|
-
initialStorage: this._initialStorage,
|
|
133
|
+
initialStorage: options.initialStorage ?? this._initialStorage,
|
|
127
134
|
limits: this._limits,
|
|
128
135
|
metadata: this.metadata,
|
|
129
136
|
onAuthorizationFail: options.onAuthorizationFail,
|
|
@@ -132,7 +139,7 @@ export class PluvClient<
|
|
|
132
139
|
reconnectTimeoutMs: options.reconnectTimeoutMs,
|
|
133
140
|
router: options.router,
|
|
134
141
|
wsEndpoint: this._wsEndpoint,
|
|
135
|
-
} as RoomConfig<TIO, TMetadata, TPresence,
|
|
142
|
+
} as RoomConfig<TIO, TMetadata, TPresence, TCrdt, TEvents>);
|
|
136
143
|
|
|
137
144
|
this._rooms.set(room, newRoom);
|
|
138
145
|
|
|
@@ -144,7 +151,7 @@ export class PluvClient<
|
|
|
144
151
|
public enter = async (
|
|
145
152
|
room: string | PluvRoom<TIO, TMetadata, any, any, any>,
|
|
146
153
|
...args: EnterRoomParams<TMetadata>
|
|
147
|
-
): Promise<PluvRoom<TIO, TMetadata, TPresence,
|
|
154
|
+
): Promise<PluvRoom<TIO, TMetadata, TPresence, TCrdt, any>> => {
|
|
148
155
|
const toEnter = typeof room === "string" ? this.getRoom(room) : room;
|
|
149
156
|
|
|
150
157
|
if (!toEnter) throw new Error(`Could not find room: ${room}.`);
|
|
@@ -157,15 +164,15 @@ export class PluvClient<
|
|
|
157
164
|
return toEnter;
|
|
158
165
|
};
|
|
159
166
|
|
|
160
|
-
public getRoom = (room: string): PluvRoom<TIO, TMetadata, TPresence,
|
|
167
|
+
public getRoom = (room: string): PluvRoom<TIO, TMetadata, TPresence, TCrdt, any> | null => {
|
|
161
168
|
const found = this._rooms.get(room) as
|
|
162
|
-
| PluvRoom<TIO, TMetadata, TPresence,
|
|
169
|
+
| PluvRoom<TIO, TMetadata, TPresence, TCrdt, any>
|
|
163
170
|
| undefined;
|
|
164
171
|
|
|
165
172
|
return found ?? null;
|
|
166
173
|
};
|
|
167
174
|
|
|
168
|
-
public getRooms = (): readonly PluvRoom<TIO, TMetadata, TPresence,
|
|
175
|
+
public getRooms = (): readonly PluvRoom<TIO, TMetadata, TPresence, TCrdt, any>[] => {
|
|
169
176
|
return Array.from(this._rooms.values());
|
|
170
177
|
};
|
|
171
178
|
|
|
@@ -181,20 +188,21 @@ export class PluvClient<
|
|
|
181
188
|
this._logDebug(`Left and deleted room: ${room}`);
|
|
182
189
|
};
|
|
183
190
|
|
|
184
|
-
public router<TEvents extends PluvRouterEventConfig<TIO, TPresence,
|
|
191
|
+
public router<TEvents extends PluvRouterEventConfig<TIO, TPresence, InferStorage<TCrdt>> = {}>(
|
|
185
192
|
events: TEvents,
|
|
186
|
-
): PluvRouter<TIO, TPresence,
|
|
193
|
+
): PluvRouter<TIO, TPresence, InferStorage<TCrdt>, TEvents> {
|
|
187
194
|
const invalidName = Object.keys(events).find((name) => name.includes("$"));
|
|
188
195
|
|
|
189
196
|
if (typeof invalidName === "string") {
|
|
190
197
|
throw new Error(`Invalid event name. Event names must not contain $: "${invalidName}"`);
|
|
191
198
|
}
|
|
192
199
|
|
|
193
|
-
return new PluvRouter<TIO, TPresence,
|
|
200
|
+
return new PluvRouter<TIO, TPresence, InferStorage<TCrdt>, TEvents>(events);
|
|
194
201
|
}
|
|
195
202
|
|
|
196
203
|
private _logDebug(...data: any[]): void {
|
|
197
|
-
if (process
|
|
204
|
+
if (typeof process === "undefined") return;
|
|
205
|
+
if (process.env?.NODE_ENV === "production") return;
|
|
198
206
|
|
|
199
207
|
if (this._debug) console.log(...data);
|
|
200
208
|
}
|
package/src/PluvProcedure.ts
CHANGED
|
@@ -20,7 +20,8 @@ export class PluvProcedure<
|
|
|
20
20
|
TPresence extends JsonObject = {},
|
|
21
21
|
TStorage extends Record<string, CrdtType<any, any>> = {},
|
|
22
22
|
TFilled extends "input" | "broadcast" | "" = "",
|
|
23
|
-
>
|
|
23
|
+
> implements ProcedureLike<TInput, TOutput>
|
|
24
|
+
{
|
|
24
25
|
private _broadcast: EventResolver<TIO, TInput, Partial<TOutput>, TPresence, TStorage> | null =
|
|
25
26
|
null;
|
|
26
27
|
private _input: InputZodLike<TInput> | null = null;
|