@pluv/io 0.24.0 → 0.25.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 +48 -0
- package/README.md +2 -2
- package/dist/index.d.mts +37 -15
- package/dist/index.d.ts +37 -15
- package/dist/index.js +59 -43
- package/dist/index.mjs +58 -42
- package/package.json +6 -6
- package/src/{AbstractPersistance.ts → AbstractPersistence.ts} +1 -1
- package/src/AbstractPlatform.ts +8 -6
- package/src/AbstractWebSocket.ts +6 -6
- package/src/IORoom.ts +28 -20
- package/src/{Persistance.ts → Persistence.ts} +2 -2
- package/src/PluvIO.ts +1 -1
- package/src/PluvRouter.ts +5 -5
- package/src/PluvServer.ts +18 -12
- package/src/index.ts +1 -1
- package/src/version.generated.ts +1 -1
package/.turbo/turbo-build.log
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
|
|
2
|
-
> @pluv/io@0.
|
|
2
|
+
> @pluv/io@0.25.0 build /home/runner/work/pluv/pluv/packages/io
|
|
3
3
|
> pnpm run version && tsup src/index.ts --format esm,cjs --dts
|
|
4
4
|
|
|
5
5
|
|
|
6
|
-
> @pluv/io@0.
|
|
6
|
+
> @pluv/io@0.25.0 version /home/runner/work/pluv/pluv/packages/io
|
|
7
7
|
> genversion ./src/version.generated.ts --esm
|
|
8
8
|
|
|
9
9
|
[34mCLI[39m Building entry: src/index.ts
|
|
@@ -12,11 +12,11 @@
|
|
|
12
12
|
[34mCLI[39m Target: es6
|
|
13
13
|
[34mESM[39m Build start
|
|
14
14
|
[34mCJS[39m Build start
|
|
15
|
-
[
|
|
16
|
-
[
|
|
17
|
-
[
|
|
18
|
-
[
|
|
15
|
+
[32mCJS[39m [1mdist/index.js [22m[32m41.55 KB[39m
|
|
16
|
+
[32mCJS[39m ⚡️ Build success in 147ms
|
|
17
|
+
[32mESM[39m [1mdist/index.mjs [22m[32m39.41 KB[39m
|
|
18
|
+
[32mESM[39m ⚡️ Build success in 148ms
|
|
19
19
|
[34mDTS[39m Build start
|
|
20
|
-
[32mDTS[39m ⚡️ Build success in
|
|
21
|
-
[32mDTS[39m [1mdist/index.d.mts [22m[32m25.
|
|
22
|
-
[32mDTS[39m [1mdist/index.d.ts [22m[32m25.
|
|
20
|
+
[32mDTS[39m ⚡️ Build success in 2276ms
|
|
21
|
+
[32mDTS[39m [1mdist/index.d.mts [22m[32m25.78 KB[39m
|
|
22
|
+
[32mDTS[39m [1mdist/index.d.ts [22m[32m25.78 KB[39m
|
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,53 @@
|
|
|
1
1
|
# @pluv/io
|
|
2
2
|
|
|
3
|
+
## 0.25.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- 9db06ba: **BREAKING **
|
|
8
|
+
|
|
9
|
+
Fixed typos `persistance` to `persistence`.
|
|
10
|
+
|
|
11
|
+
This does mean that all properties referencing `persistance` will need to be fixed. Examples below:
|
|
12
|
+
|
|
13
|
+
```bash
|
|
14
|
+
# Re-install @pluv/persistence-redis
|
|
15
|
+
pnpm uninstall @pluv/persistance-redis
|
|
16
|
+
pnpm install @pluv/persistence-redis
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
```ts
|
|
20
|
+
// Before
|
|
21
|
+
createIO({
|
|
22
|
+
platform: platformNode({
|
|
23
|
+
persistance: new PersistanceRedis(/* ... */),
|
|
24
|
+
}),
|
|
25
|
+
});
|
|
26
|
+
|
|
27
|
+
// After
|
|
28
|
+
createIO({
|
|
29
|
+
platform: platformNode({
|
|
30
|
+
persistence: new PersistenceRedis(/* ... */),
|
|
31
|
+
}),
|
|
32
|
+
});
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
`@pluv/persistance-redis` has been deprecated for `@pluv/persistence-redis`.
|
|
36
|
+
|
|
37
|
+
### Patch Changes
|
|
38
|
+
|
|
39
|
+
- 4e078ca: Fix IORoom onRoomMessage event triggering on message sent instead of on message received.
|
|
40
|
+
- f556d30: Refactored PluvServer and IORoom properties to consolidate internal properties.
|
|
41
|
+
- @pluv/crdt@0.25.0
|
|
42
|
+
- @pluv/types@0.25.0
|
|
43
|
+
|
|
44
|
+
## 0.24.1
|
|
45
|
+
|
|
46
|
+
### Patch Changes
|
|
47
|
+
|
|
48
|
+
- @pluv/crdt@0.24.1
|
|
49
|
+
- @pluv/types@0.24.1
|
|
50
|
+
|
|
3
51
|
## 0.24.0
|
|
4
52
|
|
|
5
53
|
### Minor Changes
|
package/README.md
CHANGED
|
@@ -71,7 +71,7 @@ pluv.io allows you to more easily build real-time collaborative experiences with
|
|
|
71
71
|
- ✅ [Redis](https://redis.io/)
|
|
72
72
|
- ⬜ [RabbitMQ](https://www.rabbitmq.com/)
|
|
73
73
|
- ⬜ [Kafka](https://kafka.apache.org/)
|
|
74
|
-
- ✅ **CRDT State
|
|
74
|
+
- ✅ **CRDT State Persistence**
|
|
75
75
|
- ✅ [Redis](https://redis.io/)
|
|
76
76
|
- ⬜ [Prisma](https://www.prisma.io/)
|
|
77
77
|
|
|
@@ -95,7 +95,7 @@ Documentation is available at [pluv.io](https://pluv.io/docs/introduction).
|
|
|
95
95
|
- [@pluv/client](https://www.npmjs.com/package/@pluv/client) - Framework agnostic client
|
|
96
96
|
- [@pluv/crdt-loro](https://www.npmjs.com/package/@pluv/crdt-loro) - Loro CRDT for Pluv.IO
|
|
97
97
|
- [@pluv/crdt-yjs](https://www.npmjs.com/package/@pluv/crdt-yjs) - Yjs CRDT for Pluv.IO
|
|
98
|
-
- [@pluv/
|
|
98
|
+
- [@pluv/persistence-redis](https://www.npmjs.com/package/@pluv/persistence-redis) - Persistence for storage on distributed systems (Node.js only)
|
|
99
99
|
- [@pluv/platform-cloudflare](https://www.npmjs.com/package/@pluv/platform-cloudflare) - Adapter to run @pluv/io on Cloudflare Workers
|
|
100
100
|
- [@pluv/platform-node](https://www.npmjs.com/package/@pluv/platform-node) - Adapter to run @pluv/io on Node.js
|
|
101
101
|
- [@pluv/pubsub-redis](https://www.npmjs.com/package/@pluv/pubsub-redis) - PubSub for rooms across distributed systems
|
package/dist/index.d.mts
CHANGED
|
@@ -2,7 +2,7 @@ import { JsonObject, MaybePromise, IOAuthorize, IOEventMessage, EventRecord, Inp
|
|
|
2
2
|
export { BaseUser, EventMessage, EventRecord, IOEventMessage } from '@pluv/types';
|
|
3
3
|
import { AbstractCrdtDoc, AbstractCrdtDocFactory } from '@pluv/crdt';
|
|
4
4
|
|
|
5
|
-
declare abstract class
|
|
5
|
+
declare abstract class AbstractPersistence {
|
|
6
6
|
abstract addUser(room: string, connectionId: string, user: JsonObject | null): Promise<void>;
|
|
7
7
|
abstract deleteStorageState(room: string): Promise<void>;
|
|
8
8
|
abstract deleteUser(room: string, connectionId: string): Promise<void>;
|
|
@@ -41,7 +41,7 @@ interface AbstractWebSocketHandleErrorParams {
|
|
|
41
41
|
type AbstractListener<TType extends keyof AbstractEventMap> = (event: AbstractEventMap[TType]) => MaybePromise<void>;
|
|
42
42
|
type InferWebSocketSource<TAbstractWebSocket extends AbstractWebSocket> = TAbstractWebSocket extends AbstractWebSocket<infer IWebSocket> ? IWebSocket : never;
|
|
43
43
|
interface AbstractWebSocketConfig {
|
|
44
|
-
|
|
44
|
+
persistence: AbstractPersistence;
|
|
45
45
|
room: string;
|
|
46
46
|
}
|
|
47
47
|
declare abstract class AbstractWebSocket<TWebSocket = any> {
|
|
@@ -53,7 +53,7 @@ declare abstract class AbstractWebSocket<TWebSocket = any> {
|
|
|
53
53
|
readonly CLOSING = 2;
|
|
54
54
|
/** The connection is closed. */
|
|
55
55
|
readonly CLOSED = 3;
|
|
56
|
-
readonly
|
|
56
|
+
readonly persistence: AbstractPersistence;
|
|
57
57
|
readonly room: string;
|
|
58
58
|
readonly webSocket: TWebSocket;
|
|
59
59
|
private _user;
|
|
@@ -111,12 +111,14 @@ declare class PluvProcedure<TPlatform extends AbstractPlatform<any>, TAuthorize
|
|
|
111
111
|
type PluvRouterEventConfig<TPlatform extends AbstractPlatform<any> = AbstractPlatform<any>, TAuthorize extends IOAuthorize<any, any, InferRoomContextType<TPlatform>> = BaseIOAuthorize, TContext extends JsonObject = {}> = {
|
|
112
112
|
[P: string]: Pick<PluvProcedure<TPlatform, TAuthorize, TContext, any, any>, "config">;
|
|
113
113
|
};
|
|
114
|
-
type MergedRouter<TRouters extends PluvRouter<TPlatform, TAuthorize, TContext, any>[] = [], TPlatform extends AbstractPlatform<any> = AbstractPlatform<any>, TAuthorize extends IOAuthorize<any, any, InferRoomContextType<TPlatform>> = BaseIOAuthorize, TContext extends JsonObject = {}, TRoot extends TRouters[0]["
|
|
114
|
+
type MergedRouter<TRouters extends PluvRouter<TPlatform, TAuthorize, TContext, any>[] = [], TPlatform extends AbstractPlatform<any> = AbstractPlatform<any>, TAuthorize extends IOAuthorize<any, any, InferRoomContextType<TPlatform>> = BaseIOAuthorize, TContext extends JsonObject = {}, TRoot extends TRouters[0]["_defs"]["events"] = {}> = TRouters extends [
|
|
115
115
|
infer IHead extends PluvRouter<TPlatform, TAuthorize, TContext, any>,
|
|
116
116
|
...infer ITail extends PluvRouter<TPlatform, TAuthorize, TContext, any>[]
|
|
117
|
-
] ? MergedRouter<ITail, TPlatform, TAuthorize, TContext, TRoot & IHead["
|
|
117
|
+
] ? MergedRouter<ITail, TPlatform, TAuthorize, TContext, TRoot & IHead["_defs"]["events"]> : PluvRouter<TPlatform, TAuthorize, TContext, TRoot>;
|
|
118
118
|
declare class PluvRouter<TPlatform extends AbstractPlatform<any> = AbstractPlatform<any>, TAuthorize extends IOAuthorize<any, any, InferRoomContextType<TPlatform>> = BaseIOAuthorize, TContext extends JsonObject = {}, TEvents extends PluvRouterEventConfig<TPlatform, TAuthorize, TContext> = {}> implements IORouterLike<TEvents> {
|
|
119
|
-
readonly
|
|
119
|
+
readonly _defs: {
|
|
120
|
+
events: TEvents;
|
|
121
|
+
};
|
|
120
122
|
constructor(events: TEvents);
|
|
121
123
|
static merge<TRouters extends PluvRouter<any, any, any, any>[]>(...routers: TRouters): MergedRouter<TRouters>;
|
|
122
124
|
}
|
|
@@ -210,7 +212,7 @@ type InferPlatformContextType<TPlatform extends AbstractPlatform> = TPlatform ex
|
|
|
210
212
|
type InferRoomContextType<TPlatform extends AbstractPlatform> = TPlatform extends AbstractPlatform<any, infer IPlatformContext, infer IRoomContext> ? IPlatformContext & IRoomContext : never;
|
|
211
213
|
type AbstractPlatformConfig<TPlatformContext extends Record<string, any> = {}, TRoomContext extends Record<string, any> = {}> = {
|
|
212
214
|
context?: TPlatformContext & TRoomContext;
|
|
213
|
-
|
|
215
|
+
persistence?: AbstractPersistence;
|
|
214
216
|
pubSub?: AbstractPubSub;
|
|
215
217
|
};
|
|
216
218
|
interface ConvertWebSocketConfig {
|
|
@@ -220,8 +222,9 @@ declare abstract class AbstractPlatform<TWebSocket extends AbstractWebSocket = A
|
|
|
220
222
|
protected readonly _ioContext: TPlatformContext | undefined;
|
|
221
223
|
protected readonly _roomContext: TRoomContext | undefined;
|
|
222
224
|
private _initialized;
|
|
223
|
-
|
|
225
|
+
persistence: AbstractPersistence;
|
|
224
226
|
pubSub: AbstractPubSub;
|
|
227
|
+
readonly _meta: any;
|
|
225
228
|
abstract readonly _registrationMode: WebSocketRegistrationMode;
|
|
226
229
|
constructor(config?: AbstractPlatformConfig<TPlatformContext, TRoomContext>);
|
|
227
230
|
abstract acceptWebSocket(webSocket: AbstractWebSocket): Promise<void>;
|
|
@@ -278,9 +281,9 @@ interface WebsocketRegisterOptions {
|
|
|
278
281
|
}
|
|
279
282
|
declare class IORoom<TPlatform extends AbstractPlatform<any> = AbstractPlatform<any>, TAuthorize extends IOAuthorize<any, any, InferRoomContextType<TPlatform>> = BaseIOAuthorize, TContext extends Record<string, any> = {}, TEvents extends PluvRouterEventConfig<TPlatform, TAuthorize, TContext> = {}> implements IOLike<TAuthorize, TEvents> {
|
|
280
283
|
readonly id: string;
|
|
281
|
-
readonly _authorize: TAuthorize | null;
|
|
282
284
|
private _doc;
|
|
283
285
|
private _uninitialize;
|
|
286
|
+
private readonly _authorize;
|
|
284
287
|
private readonly _context;
|
|
285
288
|
private readonly _debug;
|
|
286
289
|
private readonly _docFactory;
|
|
@@ -288,7 +291,17 @@ declare class IORoom<TPlatform extends AbstractPlatform<any> = AbstractPlatform<
|
|
|
288
291
|
private readonly _platform;
|
|
289
292
|
private readonly _router;
|
|
290
293
|
private readonly _sessions;
|
|
291
|
-
|
|
294
|
+
/**
|
|
295
|
+
* @ignore
|
|
296
|
+
* @readonly
|
|
297
|
+
* @deprecated Internal use only. Changes to this will never be marked as breaking.
|
|
298
|
+
*/
|
|
299
|
+
get _defs(): {
|
|
300
|
+
authorize: TAuthorize | null;
|
|
301
|
+
context: TContext & InferRoomContextType<TPlatform>;
|
|
302
|
+
events: TEvents;
|
|
303
|
+
platform: TPlatform;
|
|
304
|
+
};
|
|
292
305
|
get broadcast(): BroadcastProxy<this>;
|
|
293
306
|
private get _initialized();
|
|
294
307
|
constructor(id: string, config: IORoomConfig<TPlatform, TAuthorize, TContext, TEvents>);
|
|
@@ -339,7 +352,7 @@ type CreateRoomOptions<TPlatform extends AbstractPlatform<any>, TAuthorize exten
|
|
|
339
352
|
declare class PluvServer<TPlatform extends AbstractPlatform<any> = AbstractPlatform<any>, TAuthorize extends IOAuthorize<any, any, InferPlatformContextType<TPlatform>> = BaseIOAuthorize, TContext extends JsonObject = {}, TEvents extends PluvRouterEventConfig<TPlatform, TAuthorize, TContext> = {}> implements IORouterLike<TEvents> {
|
|
340
353
|
_listeners: PluvIOListeners<TPlatform, TAuthorize, TContext, TEvents>;
|
|
341
354
|
readonly version: string;
|
|
342
|
-
readonly _authorize
|
|
355
|
+
private readonly _authorize;
|
|
343
356
|
private readonly _baseRouter;
|
|
344
357
|
private readonly _context;
|
|
345
358
|
private readonly _crdt;
|
|
@@ -347,8 +360,17 @@ declare class PluvServer<TPlatform extends AbstractPlatform<any> = AbstractPlatf
|
|
|
347
360
|
private readonly _getInitialStorage;
|
|
348
361
|
private readonly _platform;
|
|
349
362
|
private readonly _router;
|
|
350
|
-
|
|
351
|
-
|
|
363
|
+
/**
|
|
364
|
+
* @ignore
|
|
365
|
+
* @readonly
|
|
366
|
+
* @deprecated Internal use only. Changes to this will never be marked as breaking.
|
|
367
|
+
*/
|
|
368
|
+
get _defs(): {
|
|
369
|
+
authorize: TAuthorize | null;
|
|
370
|
+
context: TContext;
|
|
371
|
+
events: TEvents;
|
|
372
|
+
platform: TPlatform;
|
|
373
|
+
};
|
|
352
374
|
private get _procedure();
|
|
353
375
|
constructor(options: PluvServerConfig<TPlatform, TAuthorize, TContext, TEvents>);
|
|
354
376
|
createRoom(room: string, ...options: CreateRoomOptions<TPlatform, TAuthorize, TContext, TEvents>): IORoom<TPlatform, TAuthorize, TContext, TEvents>;
|
|
@@ -371,7 +393,7 @@ type ServerConfig<TPlatform extends AbstractPlatform<any> = AbstractPlatform<any
|
|
|
371
393
|
};
|
|
372
394
|
declare class PluvIO<TPlatform extends AbstractPlatform<any> = AbstractPlatform<any>, TAuthorize extends IOAuthorize<any, any, InferPlatformContextType<TPlatform>> = BaseIOAuthorize, TContext extends JsonObject = {}> {
|
|
373
395
|
readonly version: string;
|
|
374
|
-
readonly _authorize
|
|
396
|
+
private readonly _authorize;
|
|
375
397
|
private readonly _context;
|
|
376
398
|
private readonly _crdt;
|
|
377
399
|
private readonly _debug;
|
|
@@ -395,4 +417,4 @@ type CreateIOParams<TPlatform extends AbstractPlatform<any> = AbstractPlatform<a
|
|
|
395
417
|
};
|
|
396
418
|
declare const createIO: <TPlatform extends AbstractPlatform<any> = AbstractPlatform<any, {}, {}>, TContext extends JsonObject = {}, TAuthorizeUser extends BaseUser = BaseUser, TAuthorizeRequired extends boolean = false>(params: CreateIOParams<TPlatform, TContext, TAuthorizeUser, TAuthorizeRequired>) => PluvIO<TPlatform, IOAuthorize<TAuthorizeUser, TAuthorizeRequired, InferPlatformContextType<TPlatform>>, TContext>;
|
|
397
419
|
|
|
398
|
-
export { type AbstractCloseEvent, type AbstractErrorEvent, type AbstractEvent, type AbstractEventMap, type AbstractListener, type AbstractMessageEvent,
|
|
420
|
+
export { type AbstractCloseEvent, type AbstractErrorEvent, type AbstractEvent, type AbstractEventMap, type AbstractListener, type AbstractMessageEvent, AbstractPersistence, AbstractPlatform, type AbstractPlatformConfig, AbstractPubSub, AbstractWebSocket, type AbstractWebSocketConfig, type AbstractWebSocketHandleErrorParams, type AuthorizeModule, type AuthorizeParams, type ConvertWebSocketConfig, type CreateIOParams, type CreateRoomOptions, type IOPubSubEventMessage, IORoom, type InferIORoom, type InferPlatformContextType, type InferPlatformWebSocketType, type InferRoomContextType, type JWT, type JWTEncodeParams, type MergedRouter, PluvIO, type PluvIOConfig, PluvProcedure, type PluvProcedureConfig, PluvRouter, type PluvRouterEventConfig, PluvServer, type PluvServerConfig, type ServerConfig, type WebSocketRegistrationMode, type WebSocketSerializedState, type WebSocketSession, createIO };
|
package/dist/index.d.ts
CHANGED
|
@@ -2,7 +2,7 @@ import { JsonObject, MaybePromise, IOAuthorize, IOEventMessage, EventRecord, Inp
|
|
|
2
2
|
export { BaseUser, EventMessage, EventRecord, IOEventMessage } from '@pluv/types';
|
|
3
3
|
import { AbstractCrdtDoc, AbstractCrdtDocFactory } from '@pluv/crdt';
|
|
4
4
|
|
|
5
|
-
declare abstract class
|
|
5
|
+
declare abstract class AbstractPersistence {
|
|
6
6
|
abstract addUser(room: string, connectionId: string, user: JsonObject | null): Promise<void>;
|
|
7
7
|
abstract deleteStorageState(room: string): Promise<void>;
|
|
8
8
|
abstract deleteUser(room: string, connectionId: string): Promise<void>;
|
|
@@ -41,7 +41,7 @@ interface AbstractWebSocketHandleErrorParams {
|
|
|
41
41
|
type AbstractListener<TType extends keyof AbstractEventMap> = (event: AbstractEventMap[TType]) => MaybePromise<void>;
|
|
42
42
|
type InferWebSocketSource<TAbstractWebSocket extends AbstractWebSocket> = TAbstractWebSocket extends AbstractWebSocket<infer IWebSocket> ? IWebSocket : never;
|
|
43
43
|
interface AbstractWebSocketConfig {
|
|
44
|
-
|
|
44
|
+
persistence: AbstractPersistence;
|
|
45
45
|
room: string;
|
|
46
46
|
}
|
|
47
47
|
declare abstract class AbstractWebSocket<TWebSocket = any> {
|
|
@@ -53,7 +53,7 @@ declare abstract class AbstractWebSocket<TWebSocket = any> {
|
|
|
53
53
|
readonly CLOSING = 2;
|
|
54
54
|
/** The connection is closed. */
|
|
55
55
|
readonly CLOSED = 3;
|
|
56
|
-
readonly
|
|
56
|
+
readonly persistence: AbstractPersistence;
|
|
57
57
|
readonly room: string;
|
|
58
58
|
readonly webSocket: TWebSocket;
|
|
59
59
|
private _user;
|
|
@@ -111,12 +111,14 @@ declare class PluvProcedure<TPlatform extends AbstractPlatform<any>, TAuthorize
|
|
|
111
111
|
type PluvRouterEventConfig<TPlatform extends AbstractPlatform<any> = AbstractPlatform<any>, TAuthorize extends IOAuthorize<any, any, InferRoomContextType<TPlatform>> = BaseIOAuthorize, TContext extends JsonObject = {}> = {
|
|
112
112
|
[P: string]: Pick<PluvProcedure<TPlatform, TAuthorize, TContext, any, any>, "config">;
|
|
113
113
|
};
|
|
114
|
-
type MergedRouter<TRouters extends PluvRouter<TPlatform, TAuthorize, TContext, any>[] = [], TPlatform extends AbstractPlatform<any> = AbstractPlatform<any>, TAuthorize extends IOAuthorize<any, any, InferRoomContextType<TPlatform>> = BaseIOAuthorize, TContext extends JsonObject = {}, TRoot extends TRouters[0]["
|
|
114
|
+
type MergedRouter<TRouters extends PluvRouter<TPlatform, TAuthorize, TContext, any>[] = [], TPlatform extends AbstractPlatform<any> = AbstractPlatform<any>, TAuthorize extends IOAuthorize<any, any, InferRoomContextType<TPlatform>> = BaseIOAuthorize, TContext extends JsonObject = {}, TRoot extends TRouters[0]["_defs"]["events"] = {}> = TRouters extends [
|
|
115
115
|
infer IHead extends PluvRouter<TPlatform, TAuthorize, TContext, any>,
|
|
116
116
|
...infer ITail extends PluvRouter<TPlatform, TAuthorize, TContext, any>[]
|
|
117
|
-
] ? MergedRouter<ITail, TPlatform, TAuthorize, TContext, TRoot & IHead["
|
|
117
|
+
] ? MergedRouter<ITail, TPlatform, TAuthorize, TContext, TRoot & IHead["_defs"]["events"]> : PluvRouter<TPlatform, TAuthorize, TContext, TRoot>;
|
|
118
118
|
declare class PluvRouter<TPlatform extends AbstractPlatform<any> = AbstractPlatform<any>, TAuthorize extends IOAuthorize<any, any, InferRoomContextType<TPlatform>> = BaseIOAuthorize, TContext extends JsonObject = {}, TEvents extends PluvRouterEventConfig<TPlatform, TAuthorize, TContext> = {}> implements IORouterLike<TEvents> {
|
|
119
|
-
readonly
|
|
119
|
+
readonly _defs: {
|
|
120
|
+
events: TEvents;
|
|
121
|
+
};
|
|
120
122
|
constructor(events: TEvents);
|
|
121
123
|
static merge<TRouters extends PluvRouter<any, any, any, any>[]>(...routers: TRouters): MergedRouter<TRouters>;
|
|
122
124
|
}
|
|
@@ -210,7 +212,7 @@ type InferPlatformContextType<TPlatform extends AbstractPlatform> = TPlatform ex
|
|
|
210
212
|
type InferRoomContextType<TPlatform extends AbstractPlatform> = TPlatform extends AbstractPlatform<any, infer IPlatformContext, infer IRoomContext> ? IPlatformContext & IRoomContext : never;
|
|
211
213
|
type AbstractPlatformConfig<TPlatformContext extends Record<string, any> = {}, TRoomContext extends Record<string, any> = {}> = {
|
|
212
214
|
context?: TPlatformContext & TRoomContext;
|
|
213
|
-
|
|
215
|
+
persistence?: AbstractPersistence;
|
|
214
216
|
pubSub?: AbstractPubSub;
|
|
215
217
|
};
|
|
216
218
|
interface ConvertWebSocketConfig {
|
|
@@ -220,8 +222,9 @@ declare abstract class AbstractPlatform<TWebSocket extends AbstractWebSocket = A
|
|
|
220
222
|
protected readonly _ioContext: TPlatformContext | undefined;
|
|
221
223
|
protected readonly _roomContext: TRoomContext | undefined;
|
|
222
224
|
private _initialized;
|
|
223
|
-
|
|
225
|
+
persistence: AbstractPersistence;
|
|
224
226
|
pubSub: AbstractPubSub;
|
|
227
|
+
readonly _meta: any;
|
|
225
228
|
abstract readonly _registrationMode: WebSocketRegistrationMode;
|
|
226
229
|
constructor(config?: AbstractPlatformConfig<TPlatformContext, TRoomContext>);
|
|
227
230
|
abstract acceptWebSocket(webSocket: AbstractWebSocket): Promise<void>;
|
|
@@ -278,9 +281,9 @@ interface WebsocketRegisterOptions {
|
|
|
278
281
|
}
|
|
279
282
|
declare class IORoom<TPlatform extends AbstractPlatform<any> = AbstractPlatform<any>, TAuthorize extends IOAuthorize<any, any, InferRoomContextType<TPlatform>> = BaseIOAuthorize, TContext extends Record<string, any> = {}, TEvents extends PluvRouterEventConfig<TPlatform, TAuthorize, TContext> = {}> implements IOLike<TAuthorize, TEvents> {
|
|
280
283
|
readonly id: string;
|
|
281
|
-
readonly _authorize: TAuthorize | null;
|
|
282
284
|
private _doc;
|
|
283
285
|
private _uninitialize;
|
|
286
|
+
private readonly _authorize;
|
|
284
287
|
private readonly _context;
|
|
285
288
|
private readonly _debug;
|
|
286
289
|
private readonly _docFactory;
|
|
@@ -288,7 +291,17 @@ declare class IORoom<TPlatform extends AbstractPlatform<any> = AbstractPlatform<
|
|
|
288
291
|
private readonly _platform;
|
|
289
292
|
private readonly _router;
|
|
290
293
|
private readonly _sessions;
|
|
291
|
-
|
|
294
|
+
/**
|
|
295
|
+
* @ignore
|
|
296
|
+
* @readonly
|
|
297
|
+
* @deprecated Internal use only. Changes to this will never be marked as breaking.
|
|
298
|
+
*/
|
|
299
|
+
get _defs(): {
|
|
300
|
+
authorize: TAuthorize | null;
|
|
301
|
+
context: TContext & InferRoomContextType<TPlatform>;
|
|
302
|
+
events: TEvents;
|
|
303
|
+
platform: TPlatform;
|
|
304
|
+
};
|
|
292
305
|
get broadcast(): BroadcastProxy<this>;
|
|
293
306
|
private get _initialized();
|
|
294
307
|
constructor(id: string, config: IORoomConfig<TPlatform, TAuthorize, TContext, TEvents>);
|
|
@@ -339,7 +352,7 @@ type CreateRoomOptions<TPlatform extends AbstractPlatform<any>, TAuthorize exten
|
|
|
339
352
|
declare class PluvServer<TPlatform extends AbstractPlatform<any> = AbstractPlatform<any>, TAuthorize extends IOAuthorize<any, any, InferPlatformContextType<TPlatform>> = BaseIOAuthorize, TContext extends JsonObject = {}, TEvents extends PluvRouterEventConfig<TPlatform, TAuthorize, TContext> = {}> implements IORouterLike<TEvents> {
|
|
340
353
|
_listeners: PluvIOListeners<TPlatform, TAuthorize, TContext, TEvents>;
|
|
341
354
|
readonly version: string;
|
|
342
|
-
readonly _authorize
|
|
355
|
+
private readonly _authorize;
|
|
343
356
|
private readonly _baseRouter;
|
|
344
357
|
private readonly _context;
|
|
345
358
|
private readonly _crdt;
|
|
@@ -347,8 +360,17 @@ declare class PluvServer<TPlatform extends AbstractPlatform<any> = AbstractPlatf
|
|
|
347
360
|
private readonly _getInitialStorage;
|
|
348
361
|
private readonly _platform;
|
|
349
362
|
private readonly _router;
|
|
350
|
-
|
|
351
|
-
|
|
363
|
+
/**
|
|
364
|
+
* @ignore
|
|
365
|
+
* @readonly
|
|
366
|
+
* @deprecated Internal use only. Changes to this will never be marked as breaking.
|
|
367
|
+
*/
|
|
368
|
+
get _defs(): {
|
|
369
|
+
authorize: TAuthorize | null;
|
|
370
|
+
context: TContext;
|
|
371
|
+
events: TEvents;
|
|
372
|
+
platform: TPlatform;
|
|
373
|
+
};
|
|
352
374
|
private get _procedure();
|
|
353
375
|
constructor(options: PluvServerConfig<TPlatform, TAuthorize, TContext, TEvents>);
|
|
354
376
|
createRoom(room: string, ...options: CreateRoomOptions<TPlatform, TAuthorize, TContext, TEvents>): IORoom<TPlatform, TAuthorize, TContext, TEvents>;
|
|
@@ -371,7 +393,7 @@ type ServerConfig<TPlatform extends AbstractPlatform<any> = AbstractPlatform<any
|
|
|
371
393
|
};
|
|
372
394
|
declare class PluvIO<TPlatform extends AbstractPlatform<any> = AbstractPlatform<any>, TAuthorize extends IOAuthorize<any, any, InferPlatformContextType<TPlatform>> = BaseIOAuthorize, TContext extends JsonObject = {}> {
|
|
373
395
|
readonly version: string;
|
|
374
|
-
readonly _authorize
|
|
396
|
+
private readonly _authorize;
|
|
375
397
|
private readonly _context;
|
|
376
398
|
private readonly _crdt;
|
|
377
399
|
private readonly _debug;
|
|
@@ -395,4 +417,4 @@ type CreateIOParams<TPlatform extends AbstractPlatform<any> = AbstractPlatform<a
|
|
|
395
417
|
};
|
|
396
418
|
declare const createIO: <TPlatform extends AbstractPlatform<any> = AbstractPlatform<any, {}, {}>, TContext extends JsonObject = {}, TAuthorizeUser extends BaseUser = BaseUser, TAuthorizeRequired extends boolean = false>(params: CreateIOParams<TPlatform, TContext, TAuthorizeUser, TAuthorizeRequired>) => PluvIO<TPlatform, IOAuthorize<TAuthorizeUser, TAuthorizeRequired, InferPlatformContextType<TPlatform>>, TContext>;
|
|
397
419
|
|
|
398
|
-
export { type AbstractCloseEvent, type AbstractErrorEvent, type AbstractEvent, type AbstractEventMap, type AbstractListener, type AbstractMessageEvent,
|
|
420
|
+
export { type AbstractCloseEvent, type AbstractErrorEvent, type AbstractEvent, type AbstractEventMap, type AbstractListener, type AbstractMessageEvent, AbstractPersistence, AbstractPlatform, type AbstractPlatformConfig, AbstractPubSub, AbstractWebSocket, type AbstractWebSocketConfig, type AbstractWebSocketHandleErrorParams, type AuthorizeModule, type AuthorizeParams, type ConvertWebSocketConfig, type CreateIOParams, type CreateRoomOptions, type IOPubSubEventMessage, IORoom, type InferIORoom, type InferPlatformContextType, type InferPlatformWebSocketType, type InferRoomContextType, type JWT, type JWTEncodeParams, type MergedRouter, PluvIO, type PluvIOConfig, PluvProcedure, type PluvProcedureConfig, PluvRouter, type PluvRouterEventConfig, PluvServer, type PluvServerConfig, type ServerConfig, type WebSocketRegistrationMode, type WebSocketSerializedState, type WebSocketSession, createIO };
|
package/dist/index.js
CHANGED
|
@@ -79,7 +79,7 @@ var __async = (__this, __arguments, generator) => {
|
|
|
79
79
|
// src/index.ts
|
|
80
80
|
var src_exports = {};
|
|
81
81
|
__export(src_exports, {
|
|
82
|
-
|
|
82
|
+
AbstractPersistence: () => AbstractPersistence,
|
|
83
83
|
AbstractPlatform: () => AbstractPlatform,
|
|
84
84
|
AbstractPubSub: () => AbstractPubSub,
|
|
85
85
|
AbstractWebSocket: () => AbstractWebSocket,
|
|
@@ -91,12 +91,12 @@ __export(src_exports, {
|
|
|
91
91
|
});
|
|
92
92
|
module.exports = __toCommonJS(src_exports);
|
|
93
93
|
|
|
94
|
-
// src/
|
|
95
|
-
var
|
|
94
|
+
// src/AbstractPersistence.ts
|
|
95
|
+
var AbstractPersistence = class {
|
|
96
96
|
};
|
|
97
97
|
|
|
98
|
-
// src/
|
|
99
|
-
var
|
|
98
|
+
// src/Persistence.ts
|
|
99
|
+
var Persistence = class extends AbstractPersistence {
|
|
100
100
|
constructor() {
|
|
101
101
|
super(...arguments);
|
|
102
102
|
this._storages = /* @__PURE__ */ new Map();
|
|
@@ -217,10 +217,11 @@ var PubSub = class extends AbstractPubSub {
|
|
|
217
217
|
var AbstractPlatform = class {
|
|
218
218
|
constructor(config = {}) {
|
|
219
219
|
this._initialized = false;
|
|
220
|
-
|
|
220
|
+
this._meta = void 0;
|
|
221
|
+
const { context, persistence, pubSub } = config;
|
|
221
222
|
context && (this._ioContext = context);
|
|
222
223
|
context && (this._roomContext = context);
|
|
223
|
-
this.
|
|
224
|
+
this.persistence = persistence != null ? persistence : new Persistence();
|
|
224
225
|
this.pubSub = pubSub != null ? pubSub : new PubSub();
|
|
225
226
|
}
|
|
226
227
|
_initialize() {
|
|
@@ -242,8 +243,8 @@ var AbstractWebSocket = class {
|
|
|
242
243
|
/** The connection is closed. */
|
|
243
244
|
this.CLOSED = 3;
|
|
244
245
|
this._user = null;
|
|
245
|
-
const {
|
|
246
|
-
this.
|
|
246
|
+
const { persistence, room } = config;
|
|
247
|
+
this.persistence = persistence;
|
|
247
248
|
this.room = room;
|
|
248
249
|
this.webSocket = webSocket;
|
|
249
250
|
}
|
|
@@ -253,7 +254,7 @@ var AbstractWebSocket = class {
|
|
|
253
254
|
const sessionId = this.sessionId;
|
|
254
255
|
const state = this.state;
|
|
255
256
|
const room = state.room;
|
|
256
|
-
const user = (_a = this._user) != null ? _a : yield this.
|
|
257
|
+
const user = (_a = this._user) != null ? _a : yield this.persistence.getUser(room, sessionId);
|
|
257
258
|
this._user = user;
|
|
258
259
|
return __spreadProps(__spreadValues({}, state), {
|
|
259
260
|
id: sessionId,
|
|
@@ -341,11 +342,11 @@ var PluvProcedure = class _PluvProcedure {
|
|
|
341
342
|
// src/PluvRouter.ts
|
|
342
343
|
var PluvRouter = class _PluvRouter {
|
|
343
344
|
constructor(events) {
|
|
344
|
-
this.
|
|
345
|
-
this.
|
|
345
|
+
this._defs = { events: {} };
|
|
346
|
+
this._defs = { events };
|
|
346
347
|
}
|
|
347
348
|
static merge(...routers) {
|
|
348
|
-
const events = Object.assign(/* @__PURE__ */ Object.create(null), ...routers.map((router) => router.
|
|
349
|
+
const events = Object.assign(/* @__PURE__ */ Object.create(null), ...routers.map((router) => router._defs.events));
|
|
349
350
|
return new _PluvRouter(events);
|
|
350
351
|
}
|
|
351
352
|
};
|
|
@@ -394,8 +395,8 @@ var PING_TIMEOUT_MS = 3e4;
|
|
|
394
395
|
// src/IORoom.ts
|
|
395
396
|
var IORoom = class {
|
|
396
397
|
constructor(id, config) {
|
|
397
|
-
this._authorize = null;
|
|
398
398
|
this._uninitialize = null;
|
|
399
|
+
this._authorize = null;
|
|
399
400
|
this._sessions = /* @__PURE__ */ new Map();
|
|
400
401
|
const { authorize: authorize2, context, crdt = import_crdt.noop, debug, onDestroy, onMessage, platform, router } = config;
|
|
401
402
|
this.id = id;
|
|
@@ -422,8 +423,18 @@ var IORoom = class {
|
|
|
422
423
|
this._doc = doc;
|
|
423
424
|
this._uninitialize = uninitialize;
|
|
424
425
|
}
|
|
425
|
-
|
|
426
|
-
|
|
426
|
+
/**
|
|
427
|
+
* @ignore
|
|
428
|
+
* @readonly
|
|
429
|
+
* @deprecated Internal use only. Changes to this will never be marked as breaking.
|
|
430
|
+
*/
|
|
431
|
+
get _defs() {
|
|
432
|
+
return {
|
|
433
|
+
authorize: this._authorize,
|
|
434
|
+
context: this._context,
|
|
435
|
+
events: this._router._defs.events,
|
|
436
|
+
platform: this._platform
|
|
437
|
+
};
|
|
427
438
|
}
|
|
428
439
|
get broadcast() {
|
|
429
440
|
const _broadcast = (event, data) => {
|
|
@@ -500,7 +511,7 @@ var IORoom = class {
|
|
|
500
511
|
return;
|
|
501
512
|
}
|
|
502
513
|
this._sessions.set(pluvWs.sessionId, pluvWs);
|
|
503
|
-
yield this._platform.
|
|
514
|
+
yield this._platform.persistence.addUser(this.id, pluvWs.sessionId, user != null ? user : {});
|
|
504
515
|
if (this._platform._registrationMode === "attached") {
|
|
505
516
|
const onClose = this._onClose(pluvWs).bind(this);
|
|
506
517
|
const onMessage = this._onMessage(pluvWs).bind(this);
|
|
@@ -604,7 +615,7 @@ var IORoom = class {
|
|
|
604
615
|
_getInitialDoc() {
|
|
605
616
|
return __async(this, null, function* () {
|
|
606
617
|
const doc = this._docFactory.getEmpty();
|
|
607
|
-
const encodedState = yield this._platform.
|
|
618
|
+
const encodedState = yield this._platform.persistence.getStorageState(this.id);
|
|
608
619
|
if (typeof encodedState === "string") doc.applyEncodedState({ update: encodedState });
|
|
609
620
|
return doc;
|
|
610
621
|
});
|
|
@@ -617,7 +628,7 @@ var IORoom = class {
|
|
|
617
628
|
}
|
|
618
629
|
_getProcedure(message) {
|
|
619
630
|
var _a;
|
|
620
|
-
return (_a = this._router.
|
|
631
|
+
return (_a = this._router._defs.events[message.type]) != null ? _a : null;
|
|
621
632
|
}
|
|
622
633
|
_getProcedureInputs(message) {
|
|
623
634
|
const procedure = this._getProcedure(message);
|
|
@@ -679,11 +690,11 @@ var IORoom = class {
|
|
|
679
690
|
const encodedState = doc2.getEncodedState();
|
|
680
691
|
doc2.destroy();
|
|
681
692
|
this._doc = Promise.resolve(this._docFactory.getEmpty());
|
|
682
|
-
this._listeners.onDestroy({
|
|
693
|
+
this._listeners.onDestroy(__spreadProps(__spreadValues({}, this._platform._meta ? { _meta: this._platform._meta } : {}), {
|
|
683
694
|
context: this._context,
|
|
684
695
|
encodedState,
|
|
685
696
|
room: this.id
|
|
686
|
-
});
|
|
697
|
+
}));
|
|
687
698
|
this._uninitialize = null;
|
|
688
699
|
});
|
|
689
700
|
return { doc, uninitialize };
|
|
@@ -701,7 +712,7 @@ var IORoom = class {
|
|
|
701
712
|
webSocket.state = __spreadProps(__spreadValues({}, webSocket.state), { quit: true });
|
|
702
713
|
this._logDebug(`${import_kleur.default.blue(`Unregistering connection for room ${this.id}:`)} ${webSocket.sessionId}`);
|
|
703
714
|
this._sessions.delete(webSocket.sessionId);
|
|
704
|
-
this._platform.
|
|
715
|
+
this._platform.persistence.deleteUser(this.id, webSocket.sessionId).finally(() => __async(this, null, function* () {
|
|
705
716
|
yield this._broadcast({
|
|
706
717
|
message: {
|
|
707
718
|
type: "$EXIT",
|
|
@@ -745,6 +756,13 @@ var IORoom = class {
|
|
|
745
756
|
const message = this._parseMessage(event);
|
|
746
757
|
if (!message) return;
|
|
747
758
|
const procedure = this._getProcedure(message);
|
|
759
|
+
this._listeners.onMessage(__spreadProps(__spreadValues({}, this._platform._meta ? { _meta: this._platform._meta } : {}), {
|
|
760
|
+
context: this._context,
|
|
761
|
+
encodedState: doc.getEncodedState(),
|
|
762
|
+
message,
|
|
763
|
+
room: this.id,
|
|
764
|
+
user: session.user
|
|
765
|
+
}));
|
|
748
766
|
if (!procedure) return;
|
|
749
767
|
let inputs;
|
|
750
768
|
try {
|
|
@@ -816,16 +834,7 @@ var IORoom = class {
|
|
|
816
834
|
}
|
|
817
835
|
_sendMessage(pluvWs, message) {
|
|
818
836
|
return __async(this, null, function* () {
|
|
819
|
-
const { data, type } = message;
|
|
820
837
|
if (!(yield this._initialized)) return;
|
|
821
|
-
const doc = yield this._doc;
|
|
822
|
-
this._listeners.onMessage({
|
|
823
|
-
context: this._context,
|
|
824
|
-
encodedState: doc.getEncodedState(),
|
|
825
|
-
message: { data, type },
|
|
826
|
-
room: this.id,
|
|
827
|
-
user: message.user
|
|
828
|
-
});
|
|
829
838
|
yield Promise.resolve(pluvWs.sendMessage(message));
|
|
830
839
|
});
|
|
831
840
|
}
|
|
@@ -905,7 +914,7 @@ var IORoom = class {
|
|
|
905
914
|
};
|
|
906
915
|
|
|
907
916
|
// src/version.generated.ts
|
|
908
|
-
var version = "0.
|
|
917
|
+
var version = "0.25.0";
|
|
909
918
|
|
|
910
919
|
// src/PluvServer.ts
|
|
911
920
|
var PluvServer = class {
|
|
@@ -946,7 +955,7 @@ var PluvServer = class {
|
|
|
946
955
|
};
|
|
947
956
|
}).self((_0, _1) => __async(this, [_0, _1], function* (data, { context, doc, room }) {
|
|
948
957
|
var _a, _b;
|
|
949
|
-
const oldState = yield this._platform.
|
|
958
|
+
const oldState = yield this._platform.persistence.getStorageState(room);
|
|
950
959
|
const update = data == null ? void 0 : data.update;
|
|
951
960
|
const updates = [
|
|
952
961
|
oldState ? null : yield (_a = this._getInitialStorage) == null ? void 0 : _a.call(this, __spreadProps(__spreadValues({}, context), { room })),
|
|
@@ -954,10 +963,10 @@ var PluvServer = class {
|
|
|
954
963
|
];
|
|
955
964
|
if (updates.some((_update) => !!_update)) {
|
|
956
965
|
const encodedState = doc.batchApplyEncodedState(updates).getEncodedState();
|
|
957
|
-
yield this._platform.
|
|
966
|
+
yield this._platform.persistence.setStorageState(room, encodedState);
|
|
958
967
|
this._listeners.onStorageUpdated({ context, encodedState, room });
|
|
959
968
|
}
|
|
960
|
-
const state = (_b = yield this._platform.
|
|
969
|
+
const state = (_b = yield this._platform.persistence.getStorageState(room)) != null ? _b : doc.getEncodedState();
|
|
961
970
|
return { $STORAGE_RECEIVED: { state } };
|
|
962
971
|
})),
|
|
963
972
|
$PING: this._procedure.self((data, { session }) => {
|
|
@@ -985,7 +994,7 @@ var PluvServer = class {
|
|
|
985
994
|
if (origin === "$INITIALIZED" && Object.keys(doc.toJson()).length) return {};
|
|
986
995
|
const updated = update === null ? doc : doc.applyEncodedState({ update });
|
|
987
996
|
const encodedState = updated.getEncodedState();
|
|
988
|
-
this._platform.
|
|
997
|
+
this._platform.persistence.setStorageState(room, encodedState).then(() => {
|
|
989
998
|
this._listeners.onStorageUpdated({
|
|
990
999
|
context,
|
|
991
1000
|
encodedState,
|
|
@@ -1022,11 +1031,18 @@ var PluvServer = class {
|
|
|
1022
1031
|
onStorageUpdated: (event) => onStorageUpdated == null ? void 0 : onStorageUpdated(event)
|
|
1023
1032
|
};
|
|
1024
1033
|
}
|
|
1025
|
-
|
|
1026
|
-
|
|
1027
|
-
|
|
1028
|
-
|
|
1029
|
-
|
|
1034
|
+
/**
|
|
1035
|
+
* @ignore
|
|
1036
|
+
* @readonly
|
|
1037
|
+
* @deprecated Internal use only. Changes to this will never be marked as breaking.
|
|
1038
|
+
*/
|
|
1039
|
+
get _defs() {
|
|
1040
|
+
return {
|
|
1041
|
+
authorize: this._authorize,
|
|
1042
|
+
context: this._context,
|
|
1043
|
+
events: this._router._defs.events,
|
|
1044
|
+
platform: this._platform
|
|
1045
|
+
};
|
|
1030
1046
|
}
|
|
1031
1047
|
get _procedure() {
|
|
1032
1048
|
return new PluvProcedure();
|
|
@@ -1047,7 +1063,7 @@ var PluvServer = class {
|
|
|
1047
1063
|
this._logDebug(`${import_kleur2.default.blue("Deleting empty room:")} ${room}`);
|
|
1048
1064
|
yield Promise.resolve(onDestroy == null ? void 0 : onDestroy(event));
|
|
1049
1065
|
yield Promise.resolve(this._listeners.onRoomDeleted(event));
|
|
1050
|
-
yield this._platform.
|
|
1066
|
+
yield this._platform.persistence.deleteStorageState(room);
|
|
1051
1067
|
this._logDebug(`${import_kleur2.default.blue("Deleted room:")} ${room}`);
|
|
1052
1068
|
}),
|
|
1053
1069
|
onMessage: (event) => __async(this, null, function* () {
|
|
@@ -1136,7 +1152,7 @@ var createIO = (params) => {
|
|
|
1136
1152
|
};
|
|
1137
1153
|
// Annotate the CommonJS export names for ESM import in node:
|
|
1138
1154
|
0 && (module.exports = {
|
|
1139
|
-
|
|
1155
|
+
AbstractPersistence,
|
|
1140
1156
|
AbstractPlatform,
|
|
1141
1157
|
AbstractPubSub,
|
|
1142
1158
|
AbstractWebSocket,
|
package/dist/index.mjs
CHANGED
|
@@ -50,12 +50,12 @@ var __async = (__this, __arguments, generator) => {
|
|
|
50
50
|
});
|
|
51
51
|
};
|
|
52
52
|
|
|
53
|
-
// src/
|
|
54
|
-
var
|
|
53
|
+
// src/AbstractPersistence.ts
|
|
54
|
+
var AbstractPersistence = class {
|
|
55
55
|
};
|
|
56
56
|
|
|
57
|
-
// src/
|
|
58
|
-
var
|
|
57
|
+
// src/Persistence.ts
|
|
58
|
+
var Persistence = class extends AbstractPersistence {
|
|
59
59
|
constructor() {
|
|
60
60
|
super(...arguments);
|
|
61
61
|
this._storages = /* @__PURE__ */ new Map();
|
|
@@ -176,10 +176,11 @@ var PubSub = class extends AbstractPubSub {
|
|
|
176
176
|
var AbstractPlatform = class {
|
|
177
177
|
constructor(config = {}) {
|
|
178
178
|
this._initialized = false;
|
|
179
|
-
|
|
179
|
+
this._meta = void 0;
|
|
180
|
+
const { context, persistence, pubSub } = config;
|
|
180
181
|
context && (this._ioContext = context);
|
|
181
182
|
context && (this._roomContext = context);
|
|
182
|
-
this.
|
|
183
|
+
this.persistence = persistence != null ? persistence : new Persistence();
|
|
183
184
|
this.pubSub = pubSub != null ? pubSub : new PubSub();
|
|
184
185
|
}
|
|
185
186
|
_initialize() {
|
|
@@ -201,8 +202,8 @@ var AbstractWebSocket = class {
|
|
|
201
202
|
/** The connection is closed. */
|
|
202
203
|
this.CLOSED = 3;
|
|
203
204
|
this._user = null;
|
|
204
|
-
const {
|
|
205
|
-
this.
|
|
205
|
+
const { persistence, room } = config;
|
|
206
|
+
this.persistence = persistence;
|
|
206
207
|
this.room = room;
|
|
207
208
|
this.webSocket = webSocket;
|
|
208
209
|
}
|
|
@@ -212,7 +213,7 @@ var AbstractWebSocket = class {
|
|
|
212
213
|
const sessionId = this.sessionId;
|
|
213
214
|
const state = this.state;
|
|
214
215
|
const room = state.room;
|
|
215
|
-
const user = (_a = this._user) != null ? _a : yield this.
|
|
216
|
+
const user = (_a = this._user) != null ? _a : yield this.persistence.getUser(room, sessionId);
|
|
216
217
|
this._user = user;
|
|
217
218
|
return __spreadProps(__spreadValues({}, state), {
|
|
218
219
|
id: sessionId,
|
|
@@ -300,11 +301,11 @@ var PluvProcedure = class _PluvProcedure {
|
|
|
300
301
|
// src/PluvRouter.ts
|
|
301
302
|
var PluvRouter = class _PluvRouter {
|
|
302
303
|
constructor(events) {
|
|
303
|
-
this.
|
|
304
|
-
this.
|
|
304
|
+
this._defs = { events: {} };
|
|
305
|
+
this._defs = { events };
|
|
305
306
|
}
|
|
306
307
|
static merge(...routers) {
|
|
307
|
-
const events = Object.assign(/* @__PURE__ */ Object.create(null), ...routers.map((router) => router.
|
|
308
|
+
const events = Object.assign(/* @__PURE__ */ Object.create(null), ...routers.map((router) => router._defs.events));
|
|
308
309
|
return new _PluvRouter(events);
|
|
309
310
|
}
|
|
310
311
|
};
|
|
@@ -353,8 +354,8 @@ var PING_TIMEOUT_MS = 3e4;
|
|
|
353
354
|
// src/IORoom.ts
|
|
354
355
|
var IORoom = class {
|
|
355
356
|
constructor(id, config) {
|
|
356
|
-
this._authorize = null;
|
|
357
357
|
this._uninitialize = null;
|
|
358
|
+
this._authorize = null;
|
|
358
359
|
this._sessions = /* @__PURE__ */ new Map();
|
|
359
360
|
const { authorize: authorize2, context, crdt = noop, debug, onDestroy, onMessage, platform, router } = config;
|
|
360
361
|
this.id = id;
|
|
@@ -381,8 +382,18 @@ var IORoom = class {
|
|
|
381
382
|
this._doc = doc;
|
|
382
383
|
this._uninitialize = uninitialize;
|
|
383
384
|
}
|
|
384
|
-
|
|
385
|
-
|
|
385
|
+
/**
|
|
386
|
+
* @ignore
|
|
387
|
+
* @readonly
|
|
388
|
+
* @deprecated Internal use only. Changes to this will never be marked as breaking.
|
|
389
|
+
*/
|
|
390
|
+
get _defs() {
|
|
391
|
+
return {
|
|
392
|
+
authorize: this._authorize,
|
|
393
|
+
context: this._context,
|
|
394
|
+
events: this._router._defs.events,
|
|
395
|
+
platform: this._platform
|
|
396
|
+
};
|
|
386
397
|
}
|
|
387
398
|
get broadcast() {
|
|
388
399
|
const _broadcast = (event, data) => {
|
|
@@ -459,7 +470,7 @@ var IORoom = class {
|
|
|
459
470
|
return;
|
|
460
471
|
}
|
|
461
472
|
this._sessions.set(pluvWs.sessionId, pluvWs);
|
|
462
|
-
yield this._platform.
|
|
473
|
+
yield this._platform.persistence.addUser(this.id, pluvWs.sessionId, user != null ? user : {});
|
|
463
474
|
if (this._platform._registrationMode === "attached") {
|
|
464
475
|
const onClose = this._onClose(pluvWs).bind(this);
|
|
465
476
|
const onMessage = this._onMessage(pluvWs).bind(this);
|
|
@@ -563,7 +574,7 @@ var IORoom = class {
|
|
|
563
574
|
_getInitialDoc() {
|
|
564
575
|
return __async(this, null, function* () {
|
|
565
576
|
const doc = this._docFactory.getEmpty();
|
|
566
|
-
const encodedState = yield this._platform.
|
|
577
|
+
const encodedState = yield this._platform.persistence.getStorageState(this.id);
|
|
567
578
|
if (typeof encodedState === "string") doc.applyEncodedState({ update: encodedState });
|
|
568
579
|
return doc;
|
|
569
580
|
});
|
|
@@ -576,7 +587,7 @@ var IORoom = class {
|
|
|
576
587
|
}
|
|
577
588
|
_getProcedure(message) {
|
|
578
589
|
var _a;
|
|
579
|
-
return (_a = this._router.
|
|
590
|
+
return (_a = this._router._defs.events[message.type]) != null ? _a : null;
|
|
580
591
|
}
|
|
581
592
|
_getProcedureInputs(message) {
|
|
582
593
|
const procedure = this._getProcedure(message);
|
|
@@ -638,11 +649,11 @@ var IORoom = class {
|
|
|
638
649
|
const encodedState = doc2.getEncodedState();
|
|
639
650
|
doc2.destroy();
|
|
640
651
|
this._doc = Promise.resolve(this._docFactory.getEmpty());
|
|
641
|
-
this._listeners.onDestroy({
|
|
652
|
+
this._listeners.onDestroy(__spreadProps(__spreadValues({}, this._platform._meta ? { _meta: this._platform._meta } : {}), {
|
|
642
653
|
context: this._context,
|
|
643
654
|
encodedState,
|
|
644
655
|
room: this.id
|
|
645
|
-
});
|
|
656
|
+
}));
|
|
646
657
|
this._uninitialize = null;
|
|
647
658
|
});
|
|
648
659
|
return { doc, uninitialize };
|
|
@@ -660,7 +671,7 @@ var IORoom = class {
|
|
|
660
671
|
webSocket.state = __spreadProps(__spreadValues({}, webSocket.state), { quit: true });
|
|
661
672
|
this._logDebug(`${colors.blue(`Unregistering connection for room ${this.id}:`)} ${webSocket.sessionId}`);
|
|
662
673
|
this._sessions.delete(webSocket.sessionId);
|
|
663
|
-
this._platform.
|
|
674
|
+
this._platform.persistence.deleteUser(this.id, webSocket.sessionId).finally(() => __async(this, null, function* () {
|
|
664
675
|
yield this._broadcast({
|
|
665
676
|
message: {
|
|
666
677
|
type: "$EXIT",
|
|
@@ -704,6 +715,13 @@ var IORoom = class {
|
|
|
704
715
|
const message = this._parseMessage(event);
|
|
705
716
|
if (!message) return;
|
|
706
717
|
const procedure = this._getProcedure(message);
|
|
718
|
+
this._listeners.onMessage(__spreadProps(__spreadValues({}, this._platform._meta ? { _meta: this._platform._meta } : {}), {
|
|
719
|
+
context: this._context,
|
|
720
|
+
encodedState: doc.getEncodedState(),
|
|
721
|
+
message,
|
|
722
|
+
room: this.id,
|
|
723
|
+
user: session.user
|
|
724
|
+
}));
|
|
707
725
|
if (!procedure) return;
|
|
708
726
|
let inputs;
|
|
709
727
|
try {
|
|
@@ -775,16 +793,7 @@ var IORoom = class {
|
|
|
775
793
|
}
|
|
776
794
|
_sendMessage(pluvWs, message) {
|
|
777
795
|
return __async(this, null, function* () {
|
|
778
|
-
const { data, type } = message;
|
|
779
796
|
if (!(yield this._initialized)) return;
|
|
780
|
-
const doc = yield this._doc;
|
|
781
|
-
this._listeners.onMessage({
|
|
782
|
-
context: this._context,
|
|
783
|
-
encodedState: doc.getEncodedState(),
|
|
784
|
-
message: { data, type },
|
|
785
|
-
room: this.id,
|
|
786
|
-
user: message.user
|
|
787
|
-
});
|
|
788
797
|
yield Promise.resolve(pluvWs.sendMessage(message));
|
|
789
798
|
});
|
|
790
799
|
}
|
|
@@ -864,7 +873,7 @@ var IORoom = class {
|
|
|
864
873
|
};
|
|
865
874
|
|
|
866
875
|
// src/version.generated.ts
|
|
867
|
-
var version = "0.
|
|
876
|
+
var version = "0.25.0";
|
|
868
877
|
|
|
869
878
|
// src/PluvServer.ts
|
|
870
879
|
var PluvServer = class {
|
|
@@ -905,7 +914,7 @@ var PluvServer = class {
|
|
|
905
914
|
};
|
|
906
915
|
}).self((_0, _1) => __async(this, [_0, _1], function* (data, { context, doc, room }) {
|
|
907
916
|
var _a, _b;
|
|
908
|
-
const oldState = yield this._platform.
|
|
917
|
+
const oldState = yield this._platform.persistence.getStorageState(room);
|
|
909
918
|
const update = data == null ? void 0 : data.update;
|
|
910
919
|
const updates = [
|
|
911
920
|
oldState ? null : yield (_a = this._getInitialStorage) == null ? void 0 : _a.call(this, __spreadProps(__spreadValues({}, context), { room })),
|
|
@@ -913,10 +922,10 @@ var PluvServer = class {
|
|
|
913
922
|
];
|
|
914
923
|
if (updates.some((_update) => !!_update)) {
|
|
915
924
|
const encodedState = doc.batchApplyEncodedState(updates).getEncodedState();
|
|
916
|
-
yield this._platform.
|
|
925
|
+
yield this._platform.persistence.setStorageState(room, encodedState);
|
|
917
926
|
this._listeners.onStorageUpdated({ context, encodedState, room });
|
|
918
927
|
}
|
|
919
|
-
const state = (_b = yield this._platform.
|
|
928
|
+
const state = (_b = yield this._platform.persistence.getStorageState(room)) != null ? _b : doc.getEncodedState();
|
|
920
929
|
return { $STORAGE_RECEIVED: { state } };
|
|
921
930
|
})),
|
|
922
931
|
$PING: this._procedure.self((data, { session }) => {
|
|
@@ -944,7 +953,7 @@ var PluvServer = class {
|
|
|
944
953
|
if (origin === "$INITIALIZED" && Object.keys(doc.toJson()).length) return {};
|
|
945
954
|
const updated = update === null ? doc : doc.applyEncodedState({ update });
|
|
946
955
|
const encodedState = updated.getEncodedState();
|
|
947
|
-
this._platform.
|
|
956
|
+
this._platform.persistence.setStorageState(room, encodedState).then(() => {
|
|
948
957
|
this._listeners.onStorageUpdated({
|
|
949
958
|
context,
|
|
950
959
|
encodedState,
|
|
@@ -981,11 +990,18 @@ var PluvServer = class {
|
|
|
981
990
|
onStorageUpdated: (event) => onStorageUpdated == null ? void 0 : onStorageUpdated(event)
|
|
982
991
|
};
|
|
983
992
|
}
|
|
984
|
-
|
|
985
|
-
|
|
986
|
-
|
|
987
|
-
|
|
988
|
-
|
|
993
|
+
/**
|
|
994
|
+
* @ignore
|
|
995
|
+
* @readonly
|
|
996
|
+
* @deprecated Internal use only. Changes to this will never be marked as breaking.
|
|
997
|
+
*/
|
|
998
|
+
get _defs() {
|
|
999
|
+
return {
|
|
1000
|
+
authorize: this._authorize,
|
|
1001
|
+
context: this._context,
|
|
1002
|
+
events: this._router._defs.events,
|
|
1003
|
+
platform: this._platform
|
|
1004
|
+
};
|
|
989
1005
|
}
|
|
990
1006
|
get _procedure() {
|
|
991
1007
|
return new PluvProcedure();
|
|
@@ -1006,7 +1022,7 @@ var PluvServer = class {
|
|
|
1006
1022
|
this._logDebug(`${colors2.blue("Deleting empty room:")} ${room}`);
|
|
1007
1023
|
yield Promise.resolve(onDestroy == null ? void 0 : onDestroy(event));
|
|
1008
1024
|
yield Promise.resolve(this._listeners.onRoomDeleted(event));
|
|
1009
|
-
yield this._platform.
|
|
1025
|
+
yield this._platform.persistence.deleteStorageState(room);
|
|
1010
1026
|
this._logDebug(`${colors2.blue("Deleted room:")} ${room}`);
|
|
1011
1027
|
}),
|
|
1012
1028
|
onMessage: (event) => __async(this, null, function* () {
|
|
@@ -1094,7 +1110,7 @@ var createIO = (params) => {
|
|
|
1094
1110
|
});
|
|
1095
1111
|
};
|
|
1096
1112
|
export {
|
|
1097
|
-
|
|
1113
|
+
AbstractPersistence,
|
|
1098
1114
|
AbstractPlatform,
|
|
1099
1115
|
AbstractPubSub,
|
|
1100
1116
|
AbstractWebSocket,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@pluv/io",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.25.0",
|
|
4
4
|
"description": "@pluv/io server-side websocket manager",
|
|
5
5
|
"author": "leedavidcs",
|
|
6
6
|
"license": "MIT",
|
|
@@ -18,19 +18,19 @@
|
|
|
18
18
|
},
|
|
19
19
|
"dependencies": {
|
|
20
20
|
"@panva/hkdf": "^1.2.1",
|
|
21
|
-
"jose": "^5.
|
|
21
|
+
"jose": "^5.7.0",
|
|
22
22
|
"kleur": "^4.1.5",
|
|
23
23
|
"wonka": "^6.3.4",
|
|
24
|
-
"@pluv/crdt": "^0.
|
|
25
|
-
"@pluv/types": "^0.
|
|
24
|
+
"@pluv/crdt": "^0.25.0",
|
|
25
|
+
"@pluv/types": "^0.25.0"
|
|
26
26
|
},
|
|
27
27
|
"devDependencies": {
|
|
28
28
|
"eslint": "^8.57.0",
|
|
29
29
|
"genversion": "^3.2.0",
|
|
30
30
|
"tsup": "^8.2.4",
|
|
31
31
|
"typescript": "^5.5.4",
|
|
32
|
-
"@pluv/tsconfig": "^0.
|
|
33
|
-
"eslint-config-pluv": "^0.
|
|
32
|
+
"@pluv/tsconfig": "^0.25.0",
|
|
33
|
+
"eslint-config-pluv": "^0.25.0"
|
|
34
34
|
},
|
|
35
35
|
"scripts": {
|
|
36
36
|
"build": "pnpm run version && tsup src/index.ts --format esm,cjs --dts",
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { JsonObject } from "@pluv/types";
|
|
2
2
|
|
|
3
|
-
export abstract class
|
|
3
|
+
export abstract class AbstractPersistence {
|
|
4
4
|
public abstract addUser(room: string, connectionId: string, user: JsonObject | null): Promise<void>;
|
|
5
5
|
|
|
6
6
|
public abstract deleteStorageState(room: string): Promise<void>;
|
package/src/AbstractPlatform.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { AbstractPersistence } from "./AbstractPersistence";
|
|
2
2
|
import type { AbstractPubSub } from "./AbstractPubSub";
|
|
3
3
|
import type { AbstractWebSocket, InferWebSocketSource } from "./AbstractWebSocket";
|
|
4
|
-
import {
|
|
4
|
+
import { Persistence } from "./Persistence";
|
|
5
5
|
import { PubSub } from "./PubSub";
|
|
6
6
|
import type { WebSocketSerializedState } from "./types";
|
|
7
7
|
|
|
@@ -26,7 +26,7 @@ export type AbstractPlatformConfig<
|
|
|
26
26
|
TRoomContext extends Record<string, any> = {},
|
|
27
27
|
> = {
|
|
28
28
|
context?: TPlatformContext & TRoomContext;
|
|
29
|
-
|
|
29
|
+
persistence?: AbstractPersistence;
|
|
30
30
|
pubSub?: AbstractPubSub;
|
|
31
31
|
};
|
|
32
32
|
|
|
@@ -44,18 +44,20 @@ export abstract class AbstractPlatform<
|
|
|
44
44
|
|
|
45
45
|
private _initialized: boolean = false;
|
|
46
46
|
|
|
47
|
-
public
|
|
47
|
+
public persistence: AbstractPersistence;
|
|
48
48
|
public pubSub: AbstractPubSub;
|
|
49
49
|
|
|
50
|
+
public readonly _meta: any = undefined;
|
|
51
|
+
|
|
50
52
|
public abstract readonly _registrationMode: WebSocketRegistrationMode;
|
|
51
53
|
|
|
52
54
|
constructor(config: AbstractPlatformConfig<TPlatformContext, TRoomContext> = {}) {
|
|
53
|
-
const { context,
|
|
55
|
+
const { context, persistence, pubSub } = config;
|
|
54
56
|
|
|
55
57
|
context && (this._ioContext = context);
|
|
56
58
|
context && (this._roomContext = context);
|
|
57
59
|
|
|
58
|
-
this.
|
|
60
|
+
this.persistence = persistence ?? new Persistence();
|
|
59
61
|
this.pubSub = pubSub ?? new PubSub();
|
|
60
62
|
}
|
|
61
63
|
|
package/src/AbstractWebSocket.ts
CHANGED
|
@@ -6,7 +6,7 @@ import type {
|
|
|
6
6
|
JsonObject,
|
|
7
7
|
MaybePromise,
|
|
8
8
|
} from "@pluv/types";
|
|
9
|
-
import type {
|
|
9
|
+
import type { AbstractPersistence } from "./AbstractPersistence";
|
|
10
10
|
import type { WebSocketSerializedState, WebSocketSession } from "./types";
|
|
11
11
|
|
|
12
12
|
export type AbstractEvent = {};
|
|
@@ -48,7 +48,7 @@ export type InferWebSocketSource<TAbstractWebSocket extends AbstractWebSocket> =
|
|
|
48
48
|
TAbstractWebSocket extends AbstractWebSocket<infer IWebSocket> ? IWebSocket : never;
|
|
49
49
|
|
|
50
50
|
export interface AbstractWebSocketConfig {
|
|
51
|
-
|
|
51
|
+
persistence: AbstractPersistence;
|
|
52
52
|
room: string;
|
|
53
53
|
}
|
|
54
54
|
|
|
@@ -62,7 +62,7 @@ export abstract class AbstractWebSocket<TWebSocket = any> {
|
|
|
62
62
|
/** The connection is closed. */
|
|
63
63
|
public readonly CLOSED = 3;
|
|
64
64
|
|
|
65
|
-
public readonly
|
|
65
|
+
public readonly persistence: AbstractPersistence;
|
|
66
66
|
public readonly room: string;
|
|
67
67
|
public readonly webSocket: TWebSocket;
|
|
68
68
|
|
|
@@ -75,9 +75,9 @@ export abstract class AbstractWebSocket<TWebSocket = any> {
|
|
|
75
75
|
public abstract set state(state: WebSocketSerializedState);
|
|
76
76
|
|
|
77
77
|
constructor(webSocket: TWebSocket, config: AbstractWebSocketConfig) {
|
|
78
|
-
const {
|
|
78
|
+
const { persistence, room } = config;
|
|
79
79
|
|
|
80
|
-
this.
|
|
80
|
+
this.persistence = persistence;
|
|
81
81
|
this.room = room;
|
|
82
82
|
this.webSocket = webSocket;
|
|
83
83
|
}
|
|
@@ -105,7 +105,7 @@ export abstract class AbstractWebSocket<TWebSocket = any> {
|
|
|
105
105
|
const state = this.state;
|
|
106
106
|
const room = state.room;
|
|
107
107
|
|
|
108
|
-
const user = this._user ?? (await this.
|
|
108
|
+
const user = this._user ?? (await this.persistence.getUser(room, sessionId));
|
|
109
109
|
|
|
110
110
|
this._user = user as BaseUser;
|
|
111
111
|
|
package/src/IORoom.ts
CHANGED
|
@@ -88,11 +88,11 @@ export class IORoom<
|
|
|
88
88
|
> implements IOLike<TAuthorize, TEvents>
|
|
89
89
|
{
|
|
90
90
|
public readonly id: string;
|
|
91
|
-
public readonly _authorize: TAuthorize | null = null;
|
|
92
91
|
|
|
93
92
|
private _doc: Promise<AbstractCrdtDoc<any>>;
|
|
94
93
|
private _uninitialize: Promise<() => Promise<void>> | null = null;
|
|
95
94
|
|
|
95
|
+
private readonly _authorize: TAuthorize | null = null;
|
|
96
96
|
private readonly _context: TContext & InferRoomContextType<TPlatform>;
|
|
97
97
|
private readonly _debug: boolean;
|
|
98
98
|
private readonly _docFactory: AbstractCrdtDocFactory<any>;
|
|
@@ -101,8 +101,18 @@ export class IORoom<
|
|
|
101
101
|
private readonly _router: PluvRouter<TPlatform, TAuthorize, TContext, TEvents>;
|
|
102
102
|
private readonly _sessions = new Map<string, AbstractWebSocket>();
|
|
103
103
|
|
|
104
|
-
|
|
105
|
-
|
|
104
|
+
/**
|
|
105
|
+
* @ignore
|
|
106
|
+
* @readonly
|
|
107
|
+
* @deprecated Internal use only. Changes to this will never be marked as breaking.
|
|
108
|
+
*/
|
|
109
|
+
public get _defs() {
|
|
110
|
+
return {
|
|
111
|
+
authorize: this._authorize,
|
|
112
|
+
context: this._context,
|
|
113
|
+
events: this._router._defs.events,
|
|
114
|
+
platform: this._platform,
|
|
115
|
+
};
|
|
106
116
|
}
|
|
107
117
|
|
|
108
118
|
public get broadcast(): BroadcastProxy<this> {
|
|
@@ -254,7 +264,7 @@ export class IORoom<
|
|
|
254
264
|
|
|
255
265
|
this._sessions.set(pluvWs.sessionId, pluvWs);
|
|
256
266
|
|
|
257
|
-
await this._platform.
|
|
267
|
+
await this._platform.persistence.addUser(this.id, pluvWs.sessionId, user ?? {});
|
|
258
268
|
|
|
259
269
|
if (this._platform._registrationMode === "attached") {
|
|
260
270
|
const onClose = this._onClose(pluvWs).bind(this);
|
|
@@ -379,7 +389,7 @@ export class IORoom<
|
|
|
379
389
|
|
|
380
390
|
private async _getInitialDoc(): Promise<AbstractCrdtDoc<any>> {
|
|
381
391
|
const doc = this._docFactory.getEmpty();
|
|
382
|
-
const encodedState = await this._platform.
|
|
392
|
+
const encodedState = await this._platform.persistence.getStorageState(this.id);
|
|
383
393
|
|
|
384
394
|
if (typeof encodedState === "string") doc.applyEncodedState({ update: encodedState });
|
|
385
395
|
|
|
@@ -400,8 +410,8 @@ export class IORoom<
|
|
|
400
410
|
|
|
401
411
|
private _getProcedure(
|
|
402
412
|
message: EventMessage<string, any>,
|
|
403
|
-
): (typeof this._router)["
|
|
404
|
-
return this._router.
|
|
413
|
+
): (typeof this._router)["_defs"]["events"][keyof (typeof this._router)["_defs"]["events"]] | null {
|
|
414
|
+
return this._router._defs.events[message.type as keyof (typeof this._router)["_defs"]["events"]] ?? null;
|
|
405
415
|
}
|
|
406
416
|
|
|
407
417
|
private _getProcedureInputs(message: EventMessage<string, any>): InferIOInput<this>[keyof TEvents] {
|
|
@@ -477,6 +487,7 @@ export class IORoom<
|
|
|
477
487
|
this._doc = Promise.resolve(this._docFactory.getEmpty());
|
|
478
488
|
|
|
479
489
|
this._listeners.onDestroy({
|
|
490
|
+
...(this._platform._meta ? { _meta: this._platform._meta } : {}),
|
|
480
491
|
context: this._context,
|
|
481
492
|
encodedState,
|
|
482
493
|
room: this.id,
|
|
@@ -507,7 +518,7 @@ export class IORoom<
|
|
|
507
518
|
this._logDebug(`${colors.blue(`Unregistering connection for room ${this.id}:`)} ${webSocket.sessionId}`);
|
|
508
519
|
this._sessions.delete(webSocket.sessionId);
|
|
509
520
|
|
|
510
|
-
this._platform.
|
|
521
|
+
this._platform.persistence.deleteUser(this.id, webSocket.sessionId).finally(async () => {
|
|
511
522
|
await this._broadcast({
|
|
512
523
|
message: {
|
|
513
524
|
type: "$EXIT",
|
|
@@ -565,6 +576,15 @@ export class IORoom<
|
|
|
565
576
|
|
|
566
577
|
const procedure = this._getProcedure(message);
|
|
567
578
|
|
|
579
|
+
this._listeners.onMessage({
|
|
580
|
+
...(this._platform._meta ? { _meta: this._platform._meta } : {}),
|
|
581
|
+
context: this._context,
|
|
582
|
+
encodedState: doc.getEncodedState(),
|
|
583
|
+
message: message as InferEventMessage<InferEventsOutput<TEvents>, keyof InferEventsOutput<TEvents>>,
|
|
584
|
+
room: this.id,
|
|
585
|
+
user: session.user,
|
|
586
|
+
});
|
|
587
|
+
|
|
568
588
|
if (!procedure) return;
|
|
569
589
|
|
|
570
590
|
let inputs: InferIOInput<this>[keyof TEvents];
|
|
@@ -657,20 +677,8 @@ export class IORoom<
|
|
|
657
677
|
}
|
|
658
678
|
|
|
659
679
|
private async _sendMessage(pluvWs: AbstractWebSocket<any>, message: IOEventMessage<any>): Promise<void> {
|
|
660
|
-
const { data, type } = message;
|
|
661
|
-
|
|
662
680
|
if (!(await this._initialized)) return;
|
|
663
681
|
|
|
664
|
-
const doc = await this._doc;
|
|
665
|
-
|
|
666
|
-
this._listeners.onMessage({
|
|
667
|
-
context: this._context,
|
|
668
|
-
encodedState: doc.getEncodedState(),
|
|
669
|
-
message: { data, type } as InferEventMessage<InferEventsOutput<TEvents>, keyof InferEventsOutput<TEvents>>,
|
|
670
|
-
room: this.id,
|
|
671
|
-
user: message.user,
|
|
672
|
-
});
|
|
673
|
-
|
|
674
682
|
await Promise.resolve(pluvWs.sendMessage(message));
|
|
675
683
|
}
|
|
676
684
|
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type { JsonObject } from "@pluv/types";
|
|
2
|
-
import {
|
|
2
|
+
import { AbstractPersistence } from "./AbstractPersistence";
|
|
3
3
|
|
|
4
|
-
export class
|
|
4
|
+
export class Persistence extends AbstractPersistence {
|
|
5
5
|
private _storages = new Map<string, string>();
|
|
6
6
|
private _users = new Map<string, Map<string, JsonObject | null>>();
|
|
7
7
|
|
package/src/PluvIO.ts
CHANGED
|
@@ -39,8 +39,8 @@ export class PluvIO<
|
|
|
39
39
|
TContext extends JsonObject = {},
|
|
40
40
|
> {
|
|
41
41
|
public readonly version: string = __PLUV_VERSION as any;
|
|
42
|
-
public readonly _authorize: TAuthorize | null = null;
|
|
43
42
|
|
|
43
|
+
private readonly _authorize: TAuthorize | null = null;
|
|
44
44
|
private readonly _context: TContext = {} as TContext;
|
|
45
45
|
private readonly _crdt: { doc: (value: any) => AbstractCrdtDocFactory<any> };
|
|
46
46
|
private readonly _debug: boolean;
|
package/src/PluvRouter.ts
CHANGED
|
@@ -13,12 +13,12 @@ export type MergedRouter<
|
|
|
13
13
|
TPlatform extends AbstractPlatform<any> = AbstractPlatform<any>,
|
|
14
14
|
TAuthorize extends IOAuthorize<any, any, InferRoomContextType<TPlatform>> = BaseIOAuthorize,
|
|
15
15
|
TContext extends JsonObject = {},
|
|
16
|
-
TRoot extends TRouters[0]["
|
|
16
|
+
TRoot extends TRouters[0]["_defs"]["events"] = {},
|
|
17
17
|
> = TRouters extends [
|
|
18
18
|
infer IHead extends PluvRouter<TPlatform, TAuthorize, TContext, any>,
|
|
19
19
|
...infer ITail extends PluvRouter<TPlatform, TAuthorize, TContext, any>[],
|
|
20
20
|
]
|
|
21
|
-
? MergedRouter<ITail, TPlatform, TAuthorize, TContext, TRoot & IHead["
|
|
21
|
+
? MergedRouter<ITail, TPlatform, TAuthorize, TContext, TRoot & IHead["_defs"]["events"]>
|
|
22
22
|
: PluvRouter<TPlatform, TAuthorize, TContext, TRoot>;
|
|
23
23
|
|
|
24
24
|
export class PluvRouter<
|
|
@@ -28,16 +28,16 @@ export class PluvRouter<
|
|
|
28
28
|
TEvents extends PluvRouterEventConfig<TPlatform, TAuthorize, TContext> = {},
|
|
29
29
|
> implements IORouterLike<TEvents>
|
|
30
30
|
{
|
|
31
|
-
readonly
|
|
31
|
+
readonly _defs: { events: TEvents } = { events: {} as TEvents };
|
|
32
32
|
|
|
33
33
|
constructor(events: TEvents) {
|
|
34
|
-
this.
|
|
34
|
+
this._defs = { events };
|
|
35
35
|
}
|
|
36
36
|
|
|
37
37
|
public static merge<TRouters extends PluvRouter<any, any, any, any>[]>(
|
|
38
38
|
...routers: TRouters
|
|
39
39
|
): MergedRouter<TRouters> {
|
|
40
|
-
const events = Object.assign(Object.create(null), ...routers.map((router) => router.
|
|
40
|
+
const events = Object.assign(Object.create(null), ...routers.map((router) => router._defs.events));
|
|
41
41
|
|
|
42
42
|
return new PluvRouter<any, any, any, any>(events) as MergedRouter<TRouters>;
|
|
43
43
|
}
|
package/src/PluvServer.ts
CHANGED
|
@@ -76,8 +76,8 @@ export class PluvServer<
|
|
|
76
76
|
public _listeners: PluvIOListeners<TPlatform, TAuthorize, TContext, TEvents>;
|
|
77
77
|
|
|
78
78
|
public readonly version: string = __PLUV_VERSION as any;
|
|
79
|
-
public readonly _authorize: TAuthorize | null = null;
|
|
80
79
|
|
|
80
|
+
private readonly _authorize: TAuthorize | null = null;
|
|
81
81
|
private readonly _baseRouter: PluvRouter<TPlatform, TAuthorize, TContext, {}> = new PluvRouter({
|
|
82
82
|
$GET_OTHERS: this._procedure.sync((data, { room, session, sessions }) => {
|
|
83
83
|
const currentTime = new Date().getTime();
|
|
@@ -128,7 +128,7 @@ export class PluvServer<
|
|
|
128
128
|
};
|
|
129
129
|
})
|
|
130
130
|
.self(async (data, { context, doc, room }) => {
|
|
131
|
-
const oldState = await this._platform.
|
|
131
|
+
const oldState = await this._platform.persistence.getStorageState(room);
|
|
132
132
|
const update = (data as any)?.update as Maybe<string>;
|
|
133
133
|
|
|
134
134
|
const updates: readonly Maybe<string>[] = [
|
|
@@ -139,12 +139,12 @@ export class PluvServer<
|
|
|
139
139
|
if (updates.some((_update) => !!_update)) {
|
|
140
140
|
const encodedState = doc.batchApplyEncodedState(updates).getEncodedState();
|
|
141
141
|
|
|
142
|
-
await this._platform.
|
|
142
|
+
await this._platform.persistence.setStorageState(room, encodedState);
|
|
143
143
|
|
|
144
144
|
this._listeners.onStorageUpdated({ context, encodedState, room });
|
|
145
145
|
}
|
|
146
146
|
|
|
147
|
-
const state = (await this._platform.
|
|
147
|
+
const state = (await this._platform.persistence.getStorageState(room)) ?? doc.getEncodedState();
|
|
148
148
|
|
|
149
149
|
return { $STORAGE_RECEIVED: { state } };
|
|
150
150
|
}),
|
|
@@ -184,7 +184,7 @@ export class PluvServer<
|
|
|
184
184
|
const updated = update === null ? doc : doc.applyEncodedState({ update });
|
|
185
185
|
const encodedState = updated.getEncodedState();
|
|
186
186
|
|
|
187
|
-
this._platform.
|
|
187
|
+
this._platform.persistence.setStorageState(room, encodedState).then(() => {
|
|
188
188
|
this._listeners.onStorageUpdated({
|
|
189
189
|
context,
|
|
190
190
|
encodedState,
|
|
@@ -202,12 +202,18 @@ export class PluvServer<
|
|
|
202
202
|
private readonly _platform: TPlatform;
|
|
203
203
|
private readonly _router: PluvRouter<TPlatform, TAuthorize, TContext, TEvents>;
|
|
204
204
|
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
205
|
+
/**
|
|
206
|
+
* @ignore
|
|
207
|
+
* @readonly
|
|
208
|
+
* @deprecated Internal use only. Changes to this will never be marked as breaking.
|
|
209
|
+
*/
|
|
210
|
+
public get _defs() {
|
|
211
|
+
return {
|
|
212
|
+
authorize: this._authorize,
|
|
213
|
+
context: this._context,
|
|
214
|
+
events: this._router._defs.events,
|
|
215
|
+
platform: this._platform,
|
|
216
|
+
};
|
|
211
217
|
}
|
|
212
218
|
|
|
213
219
|
private get _procedure(): PluvProcedure<TPlatform, TAuthorize, TContext, {}, {}> {
|
|
@@ -274,7 +280,7 @@ export class PluvServer<
|
|
|
274
280
|
|
|
275
281
|
await Promise.resolve(onDestroy?.(event));
|
|
276
282
|
await Promise.resolve(this._listeners.onRoomDeleted(event));
|
|
277
|
-
await this._platform.
|
|
283
|
+
await this._platform.persistence.deleteStorageState(room);
|
|
278
284
|
|
|
279
285
|
this._logDebug(`${colors.blue("Deleted room:")} ${room}`);
|
|
280
286
|
},
|
package/src/index.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
export type { BaseUser, EventMessage, EventRecord, IOEventMessage } from "@pluv/types";
|
|
2
|
-
export {
|
|
2
|
+
export { AbstractPersistence } from "./AbstractPersistence";
|
|
3
3
|
export { AbstractPlatform } from "./AbstractPlatform";
|
|
4
4
|
export type {
|
|
5
5
|
AbstractPlatformConfig,
|
package/src/version.generated.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
// Generated by genversion.
|
|
2
|
-
export const version = '0.
|
|
2
|
+
export const version = '0.25.0'
|