@pluv/io 0.4.1 → 0.5.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/src/PluvIO.ts CHANGED
@@ -15,8 +15,11 @@ import type {
15
15
  Spread,
16
16
  } from "@pluv/types";
17
17
  import colors from "kleur";
18
- import type { AbstractPlatform } from "./AbstractPlatform";
19
- import { IORoom } from "./IORoom";
18
+ import type {
19
+ AbstractPlatform,
20
+ InferPlatformRoomContextType,
21
+ } from "./AbstractPlatform";
22
+ import { IORoom, IORoomListenerEvent } from "./IORoom";
20
23
  import type { JWTEncodeParams } from "./authorize";
21
24
  import { authorize } from "./authorize";
22
25
  import type { EventConfig, InferEventConfig } from "./types";
@@ -54,13 +57,9 @@ export type InferIORoom<TIO extends PluvIO<any, any, any, any, any, any, any>> =
54
57
  >
55
58
  : never;
56
59
 
57
- export interface PluvIORegisterOptions {
58
- token?: string;
59
- }
60
-
61
- export interface PluvIOListeners {
62
- onRoomDeleted: (room: string, encodedState: string) => void;
63
- onStorageUpdated: (room: string, encodedState: string) => void;
60
+ export interface PluvIOListeners<TPlatform extends AbstractPlatform> {
61
+ onRoomDeleted: (event: IORoomListenerEvent<TPlatform>) => void;
62
+ onStorageUpdated: (event: IORoomListenerEvent<TPlatform>) => void;
64
63
  }
65
64
 
66
65
  export type PluvIOConfig<
@@ -71,11 +70,12 @@ export type PluvIOConfig<
71
70
  TOutputBroadcast extends EventRecord<string, any> = {},
72
71
  TOutputSelf extends EventRecord<string, any> = {},
73
72
  TOutputSync extends EventRecord<string, any> = {}
74
- > = Partial<PluvIOListeners> & {
73
+ > = Partial<PluvIOListeners<TPlatform>> & {
75
74
  authorize?: TAuthorize;
76
75
  context?: TContext;
77
76
  debug?: boolean;
78
77
  events?: InferEventConfig<
78
+ TPlatform,
79
79
  TContext,
80
80
  TInput,
81
81
  TOutputBroadcast,
@@ -86,9 +86,9 @@ export type PluvIOConfig<
86
86
  platform: TPlatform;
87
87
  };
88
88
 
89
- export interface GetRoomOptions {
89
+ export type GetRoomOptions<TPlatform extends AbstractPlatform> = {
90
90
  debug?: boolean;
91
- }
91
+ } & InferPlatformRoomContextType<TPlatform>;
92
92
 
93
93
  export class PluvIO<
94
94
  TPlatform extends AbstractPlatform<any> = AbstractPlatform<any>,
@@ -105,7 +105,6 @@ export class PluvIO<
105
105
  private _initialStorage:
106
106
  | ((room: string) => MaybePromise<Maybe<string>>)
107
107
  | null = null;
108
- private _listeners: PluvIOListeners;
109
108
  private _rooms = new Map<
110
109
  string,
111
110
  IORoom<
@@ -122,6 +121,7 @@ export class PluvIO<
122
121
  readonly _authorize: TAuthorize | null = null;
123
122
  readonly _debug: boolean;
124
123
  readonly _events: InferEventConfig<
124
+ TPlatform,
125
125
  TContext,
126
126
  TInput,
127
127
  TOutputBroadcast,
@@ -171,7 +171,7 @@ export class PluvIO<
171
171
  },
172
172
  };
173
173
  },
174
- self: async ({ update }, { doc, room }) => {
174
+ self: async ({ update }, { context, doc, room }) => {
175
175
  const oldState =
176
176
  await this._platform.persistance.getStorageState(room);
177
177
 
@@ -181,16 +181,20 @@ export class PluvIO<
181
181
  ];
182
182
 
183
183
  if (updates.some((_update) => !!_update)) {
184
- const state = updates
184
+ const encodedState = updates
185
185
  .reduce((_doc, _up) => _doc.applyUpdate(_up), doc)
186
186
  .encodeStateAsUpdate();
187
187
 
188
188
  await this._platform.persistance.setStorageState(
189
189
  room,
190
- state
190
+ encodedState
191
191
  );
192
192
 
193
- this._listeners.onStorageUpdated(room, state);
193
+ this._listeners.onStorageUpdated({
194
+ ...context,
195
+ encodedState,
196
+ room,
197
+ });
194
198
  }
195
199
 
196
200
  const state =
@@ -229,7 +233,7 @@ export class PluvIO<
229
233
  },
230
234
  },
231
235
  $UPDATE_STORAGE: {
232
- resolver: ({ origin, update }, { doc, room }) => {
236
+ resolver: ({ origin, update }, { context, doc, room }) => {
233
237
  if (
234
238
  origin === "$STORAGE_RECEIVED" &&
235
239
  Object.keys(doc.toJSON()).length
@@ -238,24 +242,30 @@ export class PluvIO<
238
242
  }
239
243
 
240
244
  const updated = doc.applyUpdate(update);
241
- const state = updated.encodeStateAsUpdate();
245
+ const encodedState = updated.encodeStateAsUpdate();
242
246
 
243
247
  this._platform.persistance
244
- .setStorageState(room, state)
248
+ .setStorageState(room, encodedState)
245
249
  .then(() => {
246
- this._listeners.onStorageUpdated(room, state);
250
+ this._listeners.onStorageUpdated({
251
+ ...context,
252
+ encodedState,
253
+ room,
254
+ });
247
255
  });
248
256
 
249
- return { $STORAGE_UPDATED: { state } };
257
+ return { $STORAGE_UPDATED: { state: encodedState } };
250
258
  },
251
259
  },
252
260
  } as InferEventConfig<
261
+ TPlatform,
253
262
  TContext,
254
263
  TInput,
255
264
  TOutputBroadcast,
256
265
  TOutputSelf,
257
266
  TOutputSync
258
267
  >;
268
+ readonly _listeners: PluvIOListeners<TPlatform>;
259
269
  readonly _platform: TPlatform;
260
270
 
261
271
  constructor(
@@ -289,12 +299,8 @@ export class PluvIO<
289
299
  if (initialStorage) this._initialStorage = initialStorage;
290
300
 
291
301
  this._listeners = {
292
- onRoomDeleted: (room, encodedState) => {
293
- return onRoomDeleted?.(room, encodedState);
294
- },
295
- onStorageUpdated: (room, encodedState) => {
296
- return onStorageUpdated?.(room, encodedState);
297
- },
302
+ onRoomDeleted: (event) => onRoomDeleted?.(event),
303
+ onStorageUpdated: (event) => onStorageUpdated?.(event),
298
304
  };
299
305
  }
300
306
 
@@ -322,6 +328,7 @@ export class PluvIO<
322
328
  >(
323
329
  event: TEvent,
324
330
  config: EventConfig<
331
+ TPlatform,
325
332
  TContext,
326
333
  TData,
327
334
  TResultBroadcast,
@@ -344,6 +351,7 @@ export class PluvIO<
344
351
  const newEvent = {
345
352
  [event]: config,
346
353
  } as InferEventConfig<
354
+ TPlatform,
347
355
  TContext,
348
356
  EventRecord<TEvent, TData>,
349
357
  TResultBroadcast extends EventRecord<string, any>
@@ -377,7 +385,7 @@ export class PluvIO<
377
385
 
378
386
  public getRoom(
379
387
  room: string,
380
- options: GetRoomOptions = {}
388
+ options: GetRoomOptions<TPlatform>
381
389
  ): IORoom<
382
390
  TPlatform,
383
391
  TAuthorize,
@@ -387,7 +395,7 @@ export class PluvIO<
387
395
  TOutputSelf,
388
396
  TOutputSync
389
397
  > {
390
- const { debug } = options;
398
+ const { debug, ...platformRoomContext } = options;
391
399
 
392
400
  this._purgeEmptyRooms();
393
401
 
@@ -400,6 +408,11 @@ export class PluvIO<
400
408
 
401
409
  if (oldRoom) return oldRoom;
402
410
 
411
+ const roomContext = {
412
+ ...this._context,
413
+ ...platformRoomContext,
414
+ } as TContext & InferPlatformRoomContextType<TPlatform>;
415
+
403
416
  const newRoom = new IORoom<
404
417
  TPlatform,
405
418
  TAuthorize,
@@ -410,16 +423,23 @@ export class PluvIO<
410
423
  TOutputSync
411
424
  >(room, {
412
425
  authorize: this._authorize ?? undefined,
413
- context: this._context,
426
+ context: roomContext,
414
427
  debug: debug ?? this._debug,
415
428
  events: this._events,
416
- onDestroy: (encodedState) => {
429
+ onDestroy: ({ encodedState, room }) => {
417
430
  this._logDebug(
418
431
  `${colors.blue("Deleting empty room:")} ${room}`
419
432
  );
420
433
 
434
+ const roomContext = {
435
+ room,
436
+ encodedState,
437
+ ...platformRoomContext,
438
+ } as IORoomListenerEvent<TPlatform> &
439
+ InferPlatformRoomContextType<TPlatform>;
440
+
421
441
  this._rooms.delete(room);
422
- this._listeners.onRoomDeleted(room, encodedState);
442
+ this._listeners.onRoomDeleted(roomContext);
423
443
 
424
444
  if (this._debug) {
425
445
  const rooms = Array.from(this._rooms.keys());
@@ -467,12 +487,16 @@ export class PluvIO<
467
487
  const events1 = first._events;
468
488
  const events2 = second._events;
469
489
 
490
+ const { onRoomDeleted, onStorageUpdated } = first._listeners;
491
+
470
492
  const events = Object.assign(Object.create(null), events1, events2);
471
493
 
472
494
  return new PluvIO({
473
495
  authorize,
474
496
  debug,
475
497
  events,
498
+ onRoomDeleted,
499
+ onStorageUpdated,
476
500
  platform,
477
501
  });
478
502
  }
package/src/createIO.ts CHANGED
@@ -16,7 +16,7 @@ export type CreateIOParams<
16
16
  TContext extends JsonObject = {},
17
17
  TAuthorizeUser extends BaseUser = BaseUser,
18
18
  TAuthorizeRequired extends boolean = false
19
- > = Partial<PluvIOListeners> & {
19
+ > = Partial<PluvIOListeners<TPlatform>> & {
20
20
  authorize?: IOAuthorize<TAuthorizeUser, TAuthorizeRequired>;
21
21
  context?: TContext;
22
22
  debug?: boolean;
package/src/index.ts CHANGED
@@ -4,32 +4,34 @@ export type {
4
4
  EventRecord,
5
5
  IOEventMessage,
6
6
  } from "@pluv/types";
7
+ export { AbstractPersistance } from "./AbstractPersistance";
8
+ export { AbstractPlatform } from "./AbstractPlatform";
7
9
  export type {
8
10
  ConvertWebSocketConfig,
9
- InferWebSocketType,
11
+ InferPlatformEventContextType,
12
+ InferPlatformRoomContextType,
13
+ InferPlatformWebSocketType,
10
14
  } from "./AbstractPlatform";
11
- export { AbstractPersistance } from "./AbstractPersistance";
12
- export { AbstractPlatform } from "./AbstractPlatform";
13
- export type { IOPubSubEventMessage } from "./AbstractPubSub";
14
15
  export { AbstractPubSub } from "./AbstractPubSub";
16
+ export type { IOPubSubEventMessage } from "./AbstractPubSub";
17
+ export { AbstractWebSocket } from "./AbstractWebSocket";
15
18
  export type {
16
19
  AbstractCloseEvent,
17
20
  AbstractErrorEvent,
18
21
  AbstractEvent,
19
- AbstractMessageEvent,
20
22
  AbstractEventMap,
21
23
  AbstractListener,
24
+ AbstractMessageEvent,
22
25
  AbstractWebSocketConfig,
23
26
  AbstractWebSocketHandleErrorParams,
24
27
  } from "./AbstractWebSocket";
25
- export { AbstractWebSocket } from "./AbstractWebSocket";
28
+ export type { IORoom } from "./IORoom";
29
+ export type { GetRoomOptions, InferIORoom, PluvIO } from "./PluvIO";
26
30
  export type {
27
31
  AuthorizeModule,
28
32
  AuthorizeParams,
29
33
  JWT,
30
34
  JWTEncodeParams,
31
35
  } from "./authorize";
32
- export type { CreateIOParams } from "./createIO";
33
36
  export { createIO } from "./createIO";
34
- export type { IORoom } from "./IORoom";
35
- export type { GetRoomOptions, InferIORoom, PluvIO } from "./PluvIO";
37
+ export type { CreateIOParams } from "./createIO";
package/src/types.ts CHANGED
@@ -6,6 +6,11 @@ import type {
6
6
  JsonObject,
7
7
  MaybePromise,
8
8
  } from "@pluv/types";
9
+ import {
10
+ AbstractPlatform,
11
+ InferPlatformEventContextType,
12
+ InferPlatformRoomContextType,
13
+ } from "./AbstractPlatform";
9
14
  import type { AbstractWebSocket } from "./AbstractWebSocket";
10
15
 
11
16
  export interface Console {
@@ -23,7 +28,8 @@ declare global {
23
28
  }
24
29
 
25
30
  export interface EventConfig<
26
- TContext extends JsonObject = {},
31
+ TPlatform extends AbstractPlatform = AbstractPlatform,
32
+ TContext extends Record<string, any> = {},
27
33
  TData extends JsonObject = {},
28
34
  TResultBroadcast extends EventRecord<string, any> = {},
29
35
  TResultSelf extends EventRecord<string, any> = {},
@@ -31,8 +37,15 @@ export interface EventConfig<
31
37
  > {
32
38
  input?: InputZodLike<TData>;
33
39
  resolver:
34
- | EventResolver<TContext, TData, TResultBroadcast>
40
+ | EventResolver<
41
+ TContext &
42
+ InferPlatformRoomContextType<TPlatform> &
43
+ InferPlatformEventContextType<TPlatform>,
44
+ TData,
45
+ TResultBroadcast
46
+ >
35
47
  | EventResolverObject<
48
+ TPlatform,
36
49
  TContext,
37
50
  TData,
38
51
  TResultBroadcast,
@@ -43,8 +56,17 @@ export interface EventConfig<
43
56
 
44
57
  export type EventConfigType = "broadcast" | "self" | "sync";
45
58
 
59
+ export type SyncEventResolver<
60
+ TContext extends Record<string, any> = {},
61
+ TData extends JsonObject = {},
62
+ TResultBroadcast extends EventRecord<string, any> = {}
63
+ > = (
64
+ data: TData,
65
+ context: EventResolverContext<TContext>
66
+ ) => MaybePromise<TResultBroadcast | void>;
67
+
46
68
  export type EventResolver<
47
- TContext extends JsonObject = {},
69
+ TContext extends Record<string, any> = {},
48
70
  TData extends JsonObject = {},
49
71
  TResultBroadcast extends EventRecord<string, any> = {}
50
72
  > = (
@@ -52,7 +74,9 @@ export type EventResolver<
52
74
  context: EventResolverContext<TContext>
53
75
  ) => MaybePromise<TResultBroadcast | void>;
54
76
 
55
- export interface EventResolverContext<TContext extends JsonObject = {}> {
77
+ export interface EventResolverContext<
78
+ TContext extends Record<string, any> = {}
79
+ > {
56
80
  context: TContext;
57
81
  doc: YjsDoc<any>;
58
82
  room: string;
@@ -73,19 +97,33 @@ export interface EventResolverContext<TContext extends JsonObject = {}> {
73
97
  }
74
98
 
75
99
  export type EventResolverObject<
76
- TContext extends JsonObject = {},
100
+ TPlatform extends AbstractPlatform = AbstractPlatform,
101
+ TContext extends Record<string, any> = {},
77
102
  TData extends JsonObject = {},
78
103
  TResultBroadcast extends EventRecord<string, any> = {},
79
104
  TResultSelf extends EventRecord<string, any> = {},
80
105
  TResultSync extends EventRecord<string, any> = {}
81
106
  > = {
82
- broadcast?: EventResolver<TContext, TData, TResultBroadcast>;
83
- self?: EventResolver<TContext, TData, TResultSelf>;
84
- sync?: EventResolver<TContext, TData, TResultSync>;
107
+ broadcast?: EventResolver<
108
+ TContext &
109
+ InferPlatformRoomContextType<TPlatform> &
110
+ InferPlatformEventContextType<TPlatform>,
111
+ TData,
112
+ TResultBroadcast
113
+ >;
114
+ self?: EventResolver<
115
+ TContext &
116
+ InferPlatformRoomContextType<TPlatform> &
117
+ InferPlatformEventContextType<TPlatform>,
118
+ TData,
119
+ TResultSelf
120
+ >;
121
+ sync?: SyncEventResolver<TContext, TData, TResultSync>;
85
122
  };
86
123
 
87
124
  export type InferEventConfig<
88
- TContext extends JsonObject = {},
125
+ TPlatform extends AbstractPlatform = AbstractPlatform,
126
+ TContext extends Record<string, any> = {},
89
127
  TInput extends EventRecord<string, any> = {},
90
128
  TOutputBroadcast extends EventRecord<string, any> = {},
91
129
  TOutputSelf extends EventRecord<string, any> = {},
@@ -94,6 +132,7 @@ export type InferEventConfig<
94
132
  [P in keyof TInput]: P extends string
95
133
  ? Id<
96
134
  EventConfig<
135
+ TPlatform,
97
136
  TContext,
98
137
  TInput[P],
99
138
  TOutputBroadcast,