@pluv/io 0.30.2 → 0.32.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.
@@ -13,19 +13,14 @@ export type InferPlatformWebSocketType<TPlatform extends AbstractPlatform> =
13
13
  export type InferPlatformWebSocketSource<TPlatform> =
14
14
  TPlatform extends AbstractPlatform<infer IAbstractWebSocket> ? InferWebSocketSource<IAbstractWebSocket> : never;
15
15
 
16
- export type InferPlatformContextType<TPlatform extends AbstractPlatform> =
17
- TPlatform extends AbstractPlatform<any, infer IPlatformContext> ? IPlatformContext : never;
16
+ export type InferInitContextType<TPlatform extends AbstractPlatform> =
17
+ TPlatform extends AbstractPlatform<any, infer IInitContext> ? IInitContext : never;
18
18
 
19
19
  export type InferRoomContextType<TPlatform extends AbstractPlatform> =
20
- TPlatform extends AbstractPlatform<any, infer IPlatformContext, infer IRoomContext>
21
- ? IPlatformContext & IRoomContext
22
- : never;
20
+ TPlatform extends AbstractPlatform<any, any, infer IRoomContext> ? IRoomContext : never;
23
21
 
24
- export type AbstractPlatformConfig<
25
- TPlatformContext extends Record<string, any> = {},
26
- TRoomContext extends Record<string, any> = {},
27
- > = {
28
- context?: TPlatformContext & TRoomContext;
22
+ export type AbstractPlatformConfig<TRoomContext extends Record<string, any> = {}> = {
23
+ context?: TRoomContext;
29
24
  persistence?: AbstractPersistence;
30
25
  pubSub?: AbstractPubSub;
31
26
  };
@@ -36,10 +31,10 @@ export interface ConvertWebSocketConfig {
36
31
 
37
32
  export abstract class AbstractPlatform<
38
33
  TWebSocket extends AbstractWebSocket = AbstractWebSocket,
39
- TPlatformContext extends Record<string, any> = {},
34
+ TInitContext extends Record<string, any> = {},
40
35
  TRoomContext extends Record<string, any> = {},
41
36
  > {
42
- protected readonly _ioContext: TPlatformContext | undefined;
37
+ protected readonly _initContext: TInitContext | undefined;
43
38
  protected readonly _roomContext: TRoomContext | undefined;
44
39
 
45
40
  private _initialized: boolean = false;
@@ -49,11 +44,10 @@ export abstract class AbstractPlatform<
49
44
 
50
45
  public abstract readonly _registrationMode: WebSocketRegistrationMode;
51
46
 
52
- constructor(config: AbstractPlatformConfig<TPlatformContext, TRoomContext> = {}) {
47
+ constructor(config: AbstractPlatformConfig<TRoomContext> = {}) {
53
48
  const { context, persistence, pubSub } = config;
54
49
 
55
50
  (this as any)._meta = (config as any)._meta;
56
- context && (this._ioContext = context);
57
51
  context && (this._roomContext = context);
58
52
 
59
53
  this.persistence = persistence ?? new Persistence();
@@ -75,7 +69,7 @@ export abstract class AbstractPlatform<
75
69
 
76
70
  public abstract getWebSockets(): readonly InferWebSocketSource<TWebSocket>[];
77
71
 
78
- public abstract initialize(config: AbstractPlatformConfig<TPlatformContext, TRoomContext>): this;
72
+ public abstract initialize(config: AbstractPlatformConfig<TRoomContext>): this;
79
73
 
80
74
  public abstract parseData(data: string | ArrayBuffer): Record<string, any>;
81
75
 
package/src/IORoom.ts CHANGED
@@ -18,7 +18,12 @@ import type {
18
18
  Maybe,
19
19
  } from "@pluv/types";
20
20
  import colors from "kleur";
21
- import type { AbstractPlatform, InferPlatformWebSocketSource, InferRoomContextType } from "./AbstractPlatform";
21
+ import type {
22
+ AbstractPlatform,
23
+ InferInitContextType,
24
+ InferPlatformWebSocketSource,
25
+ InferRoomContextType,
26
+ } from "./AbstractPlatform";
22
27
  import { AbstractCloseEvent, AbstractErrorEvent, AbstractMessageEvent, AbstractWebSocket } from "./AbstractWebSocket";
23
28
  import type { PluvRouter, PluvRouterEventConfig } from "./PluvRouter";
24
29
  import { authorize } from "./authorize";
@@ -42,8 +47,8 @@ interface BroadcastParams<TIO extends IORoom<any, any, any, any>> {
42
47
 
43
48
  export interface IORoomListeners<
44
49
  TPlatform extends AbstractPlatform<any>,
45
- TAuthorize extends IOAuthorize<any, any, InferRoomContextType<TPlatform>>,
46
- TContext extends JsonObject,
50
+ TAuthorize extends IOAuthorize<any, any, InferInitContextType<TPlatform>>,
51
+ TContext extends Record<string, any>,
47
52
  TEvents extends PluvRouterEventConfig<TPlatform, TAuthorize, TContext>,
48
53
  > {
49
54
  onDestroy: (event: IORoomListenerEvent<TPlatform, TAuthorize, TContext, TEvents>) => void;
@@ -59,15 +64,16 @@ export type BroadcastProxy<TIO extends IORoom<any, any, any, any>> = (<TEvent ex
59
64
 
60
65
  export type IORoomConfig<
61
66
  TPlatform extends AbstractPlatform<any> = AbstractPlatform<any>,
62
- TAuthorize extends IOAuthorize<any, any, InferRoomContextType<TPlatform>> = BaseIOAuthorize,
63
- TContext extends JsonObject = {},
67
+ TAuthorize extends IOAuthorize<any, any, InferInitContextType<TPlatform>> = BaseIOAuthorize,
68
+ TContext extends Record<string, any> = {},
64
69
  TEvents extends PluvRouterEventConfig<TPlatform, TAuthorize, TContext> = {},
65
70
  > = Partial<IORoomListeners<TPlatform, TAuthorize, TContext, TEvents>> & {
66
71
  authorize?: TAuthorize;
67
- context: TContext & InferRoomContextType<TPlatform>;
72
+ context: TContext;
68
73
  crdt?: { doc: (value: any) => AbstractCrdtDocFactory<any> };
69
74
  debug: boolean;
70
75
  platform: TPlatform;
76
+ roomContext: InferRoomContextType<TPlatform>;
71
77
  router: PluvRouter<TPlatform, TAuthorize, TContext, TEvents>;
72
78
  };
73
79
 
@@ -76,13 +82,13 @@ interface SendMessageSender {
76
82
  user: JsonObject | null;
77
83
  }
78
84
 
79
- export interface WebsocketRegisterOptions {
85
+ export type WebsocketRegisterConfig<TPlatform extends AbstractPlatform<any> = AbstractPlatform<any>> = {
80
86
  token?: string | null;
81
- }
87
+ } & InferInitContextType<TPlatform>;
82
88
 
83
89
  export class IORoom<
84
90
  TPlatform extends AbstractPlatform<any> = AbstractPlatform<any>,
85
- TAuthorize extends IOAuthorize<any, any, InferRoomContextType<TPlatform>> = BaseIOAuthorize,
91
+ TAuthorize extends IOAuthorize<any, any, InferInitContextType<TPlatform>> = BaseIOAuthorize,
86
92
  TContext extends Record<string, any> = {},
87
93
  TEvents extends PluvRouterEventConfig<TPlatform, TAuthorize, TContext> = {},
88
94
  > implements IOLike<TAuthorize, TEvents>
@@ -93,7 +99,7 @@ export class IORoom<
93
99
  private _uninitialize: Promise<() => Promise<void>> | null = null;
94
100
 
95
101
  private readonly _authorize: TAuthorize | null = null;
96
- private readonly _context: TContext & InferRoomContextType<TPlatform>;
102
+ private readonly _context: TContext;
97
103
  private readonly _debug: boolean;
98
104
  private readonly _docFactory: AbstractCrdtDocFactory<any>;
99
105
  private readonly _listeners: IORoomListeners<TPlatform, TAuthorize, TContext, TEvents>;
@@ -146,6 +152,7 @@ export class IORoom<
146
152
  onDestroy,
147
153
  onMessage,
148
154
  platform,
155
+ roomContext,
149
156
  router,
150
157
  } = config as IORoomConfig<TPlatform, TAuthorize, TContext, TEvents> & { _meta?: any };
151
158
 
@@ -155,7 +162,7 @@ export class IORoom<
155
162
  this._debug = debug;
156
163
  this._docFactory = crdt.doc(() => ({}));
157
164
  this._router = router;
158
- this._platform = platform.initialize({ ...(!!_meta ? { _meta } : {}), context });
165
+ this._platform = platform.initialize({ ...(!!_meta ? { _meta } : {}), context: roomContext });
159
166
 
160
167
  this._listeners = {
161
168
  onDestroy: (event) => onDestroy?.(event),
@@ -234,9 +241,12 @@ export class IORoom<
234
241
 
235
242
  public async register(
236
243
  webSocket: InferPlatformWebSocketSource<TPlatform>,
237
- options: WebsocketRegisterOptions = {},
244
+ ...options: keyof InferInitContextType<TPlatform> extends never
245
+ ? [{ token?: string }?]
246
+ : [WebsocketRegisterConfig<TPlatform>]
238
247
  ): Promise<void> {
239
- const { token } = options;
248
+ const _options = (options[0] ?? {}) as WebsocketRegisterConfig<TPlatform>;
249
+ const token = _options.token ?? null;
240
250
 
241
251
  const sessionId = this._platform.getSessionId(webSocket);
242
252
  const sessionExists = typeof sessionId === "string" && this._sessions.has(sessionId);
@@ -248,8 +258,8 @@ export class IORoom<
248
258
  await this._initialized;
249
259
  }
250
260
 
251
- const user = await this._getAuthorizedUser(token);
252
- const ioAuthorize = this._getIOAuthorize();
261
+ const user = await this._getAuthorizedUser(token, _options);
262
+ const ioAuthorize = this._getIOAuthorize(_options);
253
263
  const isUnauthorized = !!ioAuthorize?.required && !user;
254
264
 
255
265
  // There is an attempt for multiple of the same identities. Probably malicious.
@@ -362,8 +372,11 @@ export class IORoom<
362
372
  return sessions.find((pluvWs) => pluvWs.webSocket === webSocket) ?? null;
363
373
  }
364
374
 
365
- private async _getAuthorizedUser(token: Maybe<string>): Promise<InferIOAuthorizeUser<InferIOAuthorize<this>>> {
366
- const ioAuthorize = this._getIOAuthorize();
375
+ private async _getAuthorizedUser(
376
+ token: Maybe<string>,
377
+ options: WebsocketRegisterConfig<TPlatform>,
378
+ ): Promise<InferIOAuthorizeUser<InferIOAuthorize<this>>> {
379
+ const ioAuthorize = this._getIOAuthorize(options);
367
380
 
368
381
  if (!ioAuthorize) return null as InferIOAuthorizeUser<InferIOAuthorize<this>>;
369
382
  if (!token) return null as InferIOAuthorizeUser<InferIOAuthorize<this>>;
@@ -406,9 +419,9 @@ export class IORoom<
406
419
  return doc;
407
420
  }
408
421
 
409
- private _getIOAuthorize() {
422
+ private _getIOAuthorize(options: WebsocketRegisterConfig<TPlatform>) {
410
423
  if (typeof this._authorize === "function") {
411
- return this._authorize(this._context);
424
+ return this._authorize(options);
412
425
  }
413
426
 
414
427
  return this._authorize as {
@@ -566,7 +579,7 @@ export class IORoom<
566
579
  ]);
567
580
 
568
581
  const doc = await this._doc;
569
- const baseContext: EventResolverContext<TPlatform, TAuthorize, TContext> = {
582
+ const eventContext: EventResolverContext<TPlatform, TAuthorize, TContext> = {
570
583
  context: this._context,
571
584
  doc,
572
585
  room: this.id,
@@ -622,16 +635,10 @@ export class IORoom<
622
635
  return;
623
636
  }
624
637
 
625
- const extendedContext: EventResolverContext<
626
- TPlatform,
627
- TAuthorize,
628
- TContext & InferRoomContextType<TPlatform>
629
- > = { ...baseContext, context: { ...this._context } };
630
-
631
638
  await Promise.all([
632
- procedure.config.broadcast?.(inputs, extendedContext),
633
- procedure.config.self?.(inputs, extendedContext),
634
- procedure.config.sync?.(inputs, baseContext),
639
+ procedure.config.broadcast?.(inputs, eventContext),
640
+ procedure.config.self?.(inputs, eventContext),
641
+ procedure.config.sync?.(inputs, eventContext),
635
642
  ]).then(async ([broadcast, self, sync]) => {
636
643
  const handleBroadcast = async () => {
637
644
  if (!broadcast) return;
package/src/PluvIO.ts CHANGED
@@ -1,23 +1,23 @@
1
1
  import type { AbstractCrdtDocFactory } from "@pluv/crdt";
2
2
  import { noop } from "@pluv/crdt";
3
- import type { BaseIOAuthorize, IOAuthorize, InferIOAuthorizeUser, JsonObject } from "@pluv/types";
4
- import type { AbstractPlatform, InferPlatformContextType } from "./AbstractPlatform";
3
+ import type { BaseIOAuthorize, IOAuthorize, InferIOAuthorizeUser } from "@pluv/types";
4
+ import type { AbstractPlatform, InferInitContextType } from "./AbstractPlatform";
5
5
  import { PluvProcedure } from "./PluvProcedure";
6
6
  import type { MergedRouter, PluvRouterEventConfig } from "./PluvRouter";
7
7
  import { PluvRouter } from "./PluvRouter";
8
8
  import { PluvServer } from "./PluvServer";
9
9
  import type { JWTEncodeParams } from "./authorize";
10
10
  import { authorize } from "./authorize";
11
- import type { CrdtLibraryType, GetInitialStorageFn, PluvIOListeners } from "./types";
11
+ import type { CrdtLibraryType, GetInitialStorageFn, PluvContext, PluvIOListeners } from "./types";
12
12
  import { __PLUV_VERSION } from "./version";
13
13
 
14
14
  export type PluvIOConfig<
15
15
  TPlatform extends AbstractPlatform<any>,
16
- TAuthorize extends IOAuthorize<any, any, InferPlatformContextType<TPlatform>>,
17
- TContext extends JsonObject,
16
+ TAuthorize extends IOAuthorize<any, any, InferInitContextType<TPlatform>>,
17
+ TContext extends Record<string, any>,
18
18
  > = {
19
19
  authorize?: TAuthorize;
20
- context?: TContext;
20
+ context?: PluvContext<TPlatform, TContext>;
21
21
  crdt?: CrdtLibraryType;
22
22
  debug?: boolean;
23
23
  platform: TPlatform;
@@ -25,8 +25,8 @@ export type PluvIOConfig<
25
25
 
26
26
  export type ServerConfig<
27
27
  TPlatform extends AbstractPlatform<any> = AbstractPlatform<any>,
28
- TAuthorize extends IOAuthorize<any, any, InferPlatformContextType<TPlatform>> = BaseIOAuthorize,
29
- TContext extends JsonObject = {},
28
+ TAuthorize extends IOAuthorize<any, any, InferInitContextType<TPlatform>> = BaseIOAuthorize,
29
+ TContext extends Record<string, any> = {},
30
30
  TEvents extends PluvRouterEventConfig<TPlatform, TAuthorize, TContext> = {},
31
31
  > = Partial<PluvIOListeners<TPlatform, TAuthorize, TContext, TEvents>> & {
32
32
  getInitialStorage?: GetInitialStorageFn<TPlatform>;
@@ -35,13 +35,13 @@ export type ServerConfig<
35
35
 
36
36
  export class PluvIO<
37
37
  TPlatform extends AbstractPlatform<any> = AbstractPlatform<any>,
38
- TAuthorize extends IOAuthorize<any, any, InferPlatformContextType<TPlatform>> = BaseIOAuthorize,
39
- TContext extends JsonObject = {},
38
+ TAuthorize extends IOAuthorize<any, any, InferInitContextType<TPlatform>> = BaseIOAuthorize,
39
+ TContext extends Record<string, any> = {},
40
40
  > {
41
41
  public readonly version: string = __PLUV_VERSION as any;
42
42
 
43
43
  private readonly _authorize: TAuthorize | null = null;
44
- private readonly _context: TContext = {} as TContext;
44
+ private readonly _context: PluvContext<TPlatform, TContext> = {} as PluvContext<TPlatform, TContext>;
45
45
  private readonly _crdt: { doc: (value: any) => AbstractCrdtDocFactory<any> };
46
46
  private readonly _debug: boolean;
47
47
  private readonly _platform: TPlatform;
@@ -1,55 +1,31 @@
1
1
  import type { EventRecord, IOAuthorize, InputZodLike, JsonObject, ProcedureLike } from "@pluv/types";
2
- import type { AbstractPlatform, InferRoomContextType } from "./AbstractPlatform";
2
+ import type { AbstractPlatform, InferInitContextType } from "./AbstractPlatform";
3
3
  import type { EventResolver, MergeEventRecords } from "./types";
4
4
 
5
5
  export interface PluvProcedureConfig<
6
6
  TPlatform extends AbstractPlatform<any>,
7
- TAuthorize extends IOAuthorize<any, any, InferRoomContextType<TPlatform>>,
8
- TContext extends JsonObject,
7
+ TAuthorize extends IOAuthorize<any, any, InferInitContextType<TPlatform>>,
8
+ TContext extends Record<string, any>,
9
9
  TInput extends JsonObject = {},
10
10
  TOutput extends EventRecord<string, any> = {},
11
11
  > {
12
- broadcast?: EventResolver<
13
- TPlatform,
14
- TAuthorize,
15
- TContext & InferRoomContextType<TPlatform>,
16
- TInput,
17
- Partial<TOutput>
18
- > | null;
12
+ broadcast?: EventResolver<TPlatform, TAuthorize, TContext, TInput, Partial<TOutput>> | null;
19
13
  input?: InputZodLike<TInput>;
20
- self?: EventResolver<
21
- TPlatform,
22
- TAuthorize,
23
- TContext & InferRoomContextType<TPlatform>,
24
- TInput,
25
- Partial<TOutput>
26
- > | null;
14
+ self?: EventResolver<TPlatform, TAuthorize, TContext, TInput, Partial<TOutput>> | null;
27
15
  sync?: EventResolver<TPlatform, TAuthorize, TContext, TInput, Partial<TOutput>> | null;
28
16
  }
29
17
 
30
18
  export class PluvProcedure<
31
19
  TPlatform extends AbstractPlatform<any>,
32
- TAuthorize extends IOAuthorize<any, any, InferRoomContextType<TPlatform>>,
33
- TContext extends JsonObject,
20
+ TAuthorize extends IOAuthorize<any, any, InferInitContextType<TPlatform>>,
21
+ TContext extends Record<string, any>,
34
22
  TInput extends JsonObject = {},
35
23
  TOutput extends EventRecord<string, any> = {},
36
24
  TFilled extends "input" | "broadcast" | "self" | "sync" | "" = "",
37
25
  > {
38
- private _broadcast: EventResolver<
39
- TPlatform,
40
- TAuthorize,
41
- TContext & InferRoomContextType<TPlatform>,
42
- TInput,
43
- Partial<TOutput>
44
- > | null = null;
26
+ private _broadcast: EventResolver<TPlatform, TAuthorize, TContext, TInput, Partial<TOutput>> | null = null;
45
27
  private _input: InputZodLike<TInput> | null = null;
46
- private _self: EventResolver<
47
- TPlatform,
48
- TAuthorize,
49
- TContext & InferRoomContextType<TPlatform>,
50
- TInput,
51
- Partial<TOutput>
52
- > | null = null;
28
+ private _self: EventResolver<TPlatform, TAuthorize, TContext, TInput, Partial<TOutput>> | null = null;
53
29
  private _sync: EventResolver<TPlatform, TAuthorize, TContext, TInput, Partial<TOutput>> | null = null;
54
30
 
55
31
  public get config(): ProcedureLike<TInput, TOutput>["config"] {
@@ -72,7 +48,7 @@ export class PluvProcedure<
72
48
  }
73
49
 
74
50
  public broadcast<TResult extends EventRecord<string, any> = {}>(
75
- resolver: EventResolver<TPlatform, TAuthorize, TContext & InferRoomContextType<TPlatform>, TInput, TResult>,
51
+ resolver: EventResolver<TPlatform, TAuthorize, TContext, TInput, TResult>,
76
52
  ): Omit<
77
53
  PluvProcedure<
78
54
  TPlatform,
@@ -108,7 +84,7 @@ export class PluvProcedure<
108
84
  }
109
85
 
110
86
  public self<TResult extends EventRecord<string, any> = {}>(
111
- resolver: EventResolver<TPlatform, TAuthorize, TContext & InferRoomContextType<TPlatform>, TInput, TResult>,
87
+ resolver: EventResolver<TPlatform, TAuthorize, TContext, TInput, TResult>,
112
88
  ): Omit<
113
89
  PluvProcedure<
114
90
  TPlatform,
@@ -138,7 +114,7 @@ export class PluvProcedure<
138
114
  }
139
115
 
140
116
  public sync<TResult extends EventRecord<string, any> = {}>(
141
- resolver: EventResolver<TPlatform, TAuthorize, TContext & InferRoomContextType<TPlatform>, TInput, TResult>,
117
+ resolver: EventResolver<TPlatform, TAuthorize, TContext, TInput, TResult>,
142
118
  ): Omit<
143
119
  PluvProcedure<
144
120
  TPlatform,
@@ -167,13 +143,7 @@ export class PluvProcedure<
167
143
  });
168
144
  }
169
145
 
170
- private _resolver(): EventResolver<
171
- TPlatform,
172
- TAuthorize,
173
- TContext & InferRoomContextType<TPlatform>,
174
- TInput,
175
- TOutput
176
- > {
146
+ private _resolver(): EventResolver<TPlatform, TAuthorize, TContext, TInput, TOutput> {
177
147
  return (data, context) => {
178
148
  return {
179
149
  ...this._broadcast?.(data, context),
package/src/PluvRouter.ts CHANGED
@@ -1,18 +1,18 @@
1
- import type { BaseIOAuthorize, IOAuthorize, IORouterLike, JsonObject } from "@pluv/types";
2
- import type { AbstractPlatform, InferRoomContextType } from "./AbstractPlatform";
1
+ import type { BaseIOAuthorize, IOAuthorize, IORouterLike } from "@pluv/types";
2
+ import type { AbstractPlatform, InferInitContextType } from "./AbstractPlatform";
3
3
  import type { PluvProcedure } from "./PluvProcedure";
4
4
 
5
5
  export type PluvRouterEventConfig<
6
6
  TPlatform extends AbstractPlatform<any> = AbstractPlatform<any>,
7
- TAuthorize extends IOAuthorize<any, any, InferRoomContextType<TPlatform>> = BaseIOAuthorize,
8
- TContext extends JsonObject = {},
7
+ TAuthorize extends IOAuthorize<any, any, InferInitContextType<TPlatform>> = BaseIOAuthorize,
8
+ TContext extends Record<string, any> = {},
9
9
  > = { [P: string]: Pick<PluvProcedure<TPlatform, TAuthorize, TContext, any, any>, "config"> };
10
10
 
11
11
  export type MergedRouter<
12
12
  TRouters extends PluvRouter<TPlatform, TAuthorize, TContext, any>[] = [],
13
13
  TPlatform extends AbstractPlatform<any> = AbstractPlatform<any>,
14
- TAuthorize extends IOAuthorize<any, any, InferRoomContextType<TPlatform>> = BaseIOAuthorize,
15
- TContext extends JsonObject = {},
14
+ TAuthorize extends IOAuthorize<any, any, InferInitContextType<TPlatform>> = BaseIOAuthorize,
15
+ TContext extends Record<string, any> = {},
16
16
  TRoot extends TRouters[0]["_defs"]["events"] = {},
17
17
  > = TRouters extends [
18
18
  infer IHead extends PluvRouter<TPlatform, TAuthorize, TContext, any>,
@@ -23,8 +23,8 @@ export type MergedRouter<
23
23
 
24
24
  export class PluvRouter<
25
25
  TPlatform extends AbstractPlatform<any> = AbstractPlatform<any>,
26
- TAuthorize extends IOAuthorize<any, any, InferRoomContextType<TPlatform>> = BaseIOAuthorize,
27
- TContext extends JsonObject = {},
26
+ TAuthorize extends IOAuthorize<any, any, InferInitContextType<TPlatform>> = BaseIOAuthorize,
27
+ TContext extends Record<string, any> = {},
28
28
  TEvents extends PluvRouterEventConfig<TPlatform, TAuthorize, TContext> = {},
29
29
  > implements IORouterLike<TEvents>
30
30
  {
package/src/PluvServer.ts CHANGED
@@ -11,7 +11,7 @@ import type {
11
11
  Maybe,
12
12
  } from "@pluv/types";
13
13
  import colors from "kleur";
14
- import type { AbstractPlatform, InferPlatformContextType, InferRoomContextType } from "./AbstractPlatform";
14
+ import type { AbstractPlatform, InferInitContextType, InferRoomContextType } from "./AbstractPlatform";
15
15
  import type { IORoomListeners } from "./IORoom";
16
16
  import { IORoom } from "./IORoom";
17
17
  import { PluvProcedure } from "./PluvProcedure";
@@ -20,7 +20,7 @@ import { PluvRouter } from "./PluvRouter";
20
20
  import type { JWTEncodeParams } from "./authorize";
21
21
  import { authorize } from "./authorize";
22
22
  import { PING_TIMEOUT_MS } from "./constants";
23
- import type { GetInitialStorageFn, PluvIOListeners } from "./types";
23
+ import type { GetInitialStorageFn, PluvContext, PluvIOListeners } from "./types";
24
24
  import { __PLUV_VERSION } from "./version";
25
25
 
26
26
  export type InferIORoom<TServer extends PluvServer<any, any, any, any>> =
@@ -30,12 +30,12 @@ export type InferIORoom<TServer extends PluvServer<any, any, any, any>> =
30
30
 
31
31
  export type PluvServerConfig<
32
32
  TPlatform extends AbstractPlatform<any> = AbstractPlatform<any>,
33
- TAuthorize extends IOAuthorize<any, any, InferPlatformContextType<TPlatform>> = BaseIOAuthorize,
34
- TContext extends JsonObject = {},
33
+ TAuthorize extends IOAuthorize<any, any, InferInitContextType<TPlatform>> = BaseIOAuthorize,
34
+ TContext extends Record<string, any> = {},
35
35
  TEvents extends PluvRouterEventConfig<TPlatform, TAuthorize, TContext> = {},
36
36
  > = Partial<PluvIOListeners<TPlatform, TAuthorize, TContext, TEvents>> & {
37
37
  authorize?: TAuthorize;
38
- context?: TContext;
38
+ context?: PluvContext<TPlatform, TContext>;
39
39
  crdt?: { doc: (value: any) => AbstractCrdtDocFactory<any> };
40
40
  debug?: boolean;
41
41
  getInitialStorage?: GetInitialStorageFn<TPlatform>;
@@ -45,8 +45,8 @@ export type PluvServerConfig<
45
45
 
46
46
  type BaseCreateRoomOptions<
47
47
  TPlatform extends AbstractPlatform<any>,
48
- TAuthorize extends IOAuthorize<any, any, InferPlatformContextType<TPlatform>>,
49
- TContext extends JsonObject,
48
+ TAuthorize extends IOAuthorize<any, any, InferInitContextType<TPlatform>>,
49
+ TContext extends Record<string, any>,
50
50
  TEvents extends PluvRouterEventConfig<TPlatform, TAuthorize, TContext>,
51
51
  > = Partial<IORoomListeners<TPlatform, TAuthorize, TContext, TEvents>> & {
52
52
  debug?: boolean;
@@ -54,8 +54,8 @@ type BaseCreateRoomOptions<
54
54
 
55
55
  export type CreateRoomOptions<
56
56
  TPlatform extends AbstractPlatform<any>,
57
- TAuthorize extends IOAuthorize<any, any, InferPlatformContextType<TPlatform>>,
58
- TContext extends JsonObject,
57
+ TAuthorize extends IOAuthorize<any, any, InferInitContextType<TPlatform>>,
58
+ TContext extends Record<string, any>,
59
59
  TEvents extends PluvRouterEventConfig<TPlatform, TAuthorize, TContext>,
60
60
  > = keyof InferRoomContextType<TPlatform> extends never
61
61
  ? [BaseCreateRoomOptions<TPlatform, TAuthorize, TContext, TEvents>] | []
@@ -63,8 +63,8 @@ export type CreateRoomOptions<
63
63
 
64
64
  export class PluvServer<
65
65
  TPlatform extends AbstractPlatform<any> = AbstractPlatform<any>,
66
- TAuthorize extends IOAuthorize<any, any, InferPlatformContextType<TPlatform>> = BaseIOAuthorize,
67
- TContext extends JsonObject = {},
66
+ TAuthorize extends IOAuthorize<any, any, InferInitContextType<TPlatform>> = BaseIOAuthorize,
67
+ TContext extends Record<string, any> = {},
68
68
  TEvents extends PluvRouterEventConfig<TPlatform, TAuthorize, TContext> = {},
69
69
  > implements IORouterLike<TEvents>
70
70
  {
@@ -188,7 +188,7 @@ export class PluvServer<
188
188
  return { $STORAGE_UPDATED: { state: encodedState } };
189
189
  }),
190
190
  });
191
- private readonly _context: TContext = {} as TContext;
191
+ private readonly _context: PluvContext<TPlatform, TContext> = {} as PluvContext<TPlatform, TContext>;
192
192
  private readonly _crdt: { doc: (value: any) => AbstractCrdtDocFactory<any> };
193
193
  private readonly _debug: boolean;
194
194
  private readonly _getInitialStorage: GetInitialStorageFn<TPlatform> | null = null;
@@ -261,15 +261,13 @@ export class PluvServer<
261
261
 
262
262
  if (!/^[a-z0-9]+[a-z0-9\-_]+[a-z0-9]+$/i.test(room)) throw new Error("Unsupported room name");
263
263
 
264
- const roomContext = {
265
- ...this._context,
266
- ...platformRoomContext,
267
- } as TContext & InferRoomContextType<TPlatform>;
264
+ const roomContext = platformRoomContext as InferRoomContextType<TPlatform>;
265
+ const context: TContext = typeof this._context === "function" ? this._context(roomContext) : this._context;
268
266
 
269
267
  const newRoom = new IORoom<TPlatform, TAuthorize, TContext, TEvents>(room, {
270
268
  ...(!!_meta ? { _meta } : {}),
271
269
  authorize: this._authorize ?? undefined,
272
- context: roomContext,
270
+ context,
273
271
  crdt: this._crdt,
274
272
  debug: debug ?? this._debug,
275
273
  onDestroy: async (event) => {
@@ -286,6 +284,7 @@ export class PluvServer<
286
284
  await Promise.resolve(this._getListeners().onRoomMessage(event));
287
285
  },
288
286
  platform: this._platform,
287
+ roomContext,
289
288
  router: this._router,
290
289
  });
291
290
 
package/src/authorize.ts CHANGED
@@ -1,7 +1,7 @@
1
1
  import hkdf from "@panva/hkdf";
2
2
  import type { BaseUser } from "@pluv/types";
3
3
  import { EncryptJWT, jwtDecrypt } from "jose";
4
- import type { AbstractPlatform, InferPlatformContextType } from "./AbstractPlatform";
4
+ import type { AbstractPlatform, InferInitContextType } from "./AbstractPlatform";
5
5
 
6
6
  const DEFAULT_MAX_AGE_MS = 60_000;
7
7
 
@@ -19,7 +19,7 @@ export type JWTEncodeParams<TUser extends BaseUser, TPlatform extends AbstractPl
19
19
  maxAge?: number;
20
20
  room: string;
21
21
  user: TUser;
22
- } & InferPlatformContextType<TPlatform>;
22
+ } & InferInitContextType<TPlatform>;
23
23
 
24
24
  export interface AuthorizeParams {
25
25
  platform: AbstractPlatform;
package/src/createIO.ts CHANGED
@@ -1,16 +1,16 @@
1
- import type { BaseUser, IOAuthorize, JsonObject } from "@pluv/types";
2
- import type { AbstractPlatform, InferPlatformContextType } from "./AbstractPlatform";
1
+ import type { BaseUser, IOAuthorize } from "@pluv/types";
2
+ import type { AbstractPlatform, InferInitContextType } from "./AbstractPlatform";
3
3
  import { PluvIO } from "./PluvIO";
4
- import { CrdtLibraryType } from "./types";
4
+ import type { CrdtLibraryType, PluvContext } from "./types";
5
5
 
6
6
  export type CreateIOParams<
7
7
  TPlatform extends AbstractPlatform<any> = AbstractPlatform<any>,
8
- TContext extends JsonObject = {},
8
+ TContext extends Record<string, any> = {},
9
9
  TAuthorizeUser extends BaseUser = BaseUser,
10
10
  TAuthorizeRequired extends boolean = false,
11
11
  > = {
12
- authorize?: IOAuthorize<TAuthorizeUser, TAuthorizeRequired, InferPlatformContextType<TPlatform>>;
13
- context?: TContext;
12
+ authorize?: IOAuthorize<TAuthorizeUser, TAuthorizeRequired, InferInitContextType<TPlatform>>;
13
+ context?: PluvContext<TPlatform, TContext>;
14
14
  crdt?: CrdtLibraryType;
15
15
  debug?: boolean;
16
16
  platform: TPlatform;
@@ -18,21 +18,17 @@ export type CreateIOParams<
18
18
 
19
19
  export const createIO = <
20
20
  TPlatform extends AbstractPlatform<any> = AbstractPlatform<any>,
21
- TContext extends JsonObject = {},
21
+ TContext extends Record<string, any> = {},
22
22
  TAuthorizeUser extends BaseUser = BaseUser,
23
23
  TAuthorizeRequired extends boolean = false,
24
24
  >(
25
25
  params: CreateIOParams<TPlatform, TContext, TAuthorizeUser, TAuthorizeRequired>,
26
- ): PluvIO<
27
- TPlatform,
28
- IOAuthorize<TAuthorizeUser, TAuthorizeRequired, InferPlatformContextType<TPlatform>>,
29
- TContext
30
- > => {
26
+ ): PluvIO<TPlatform, IOAuthorize<TAuthorizeUser, TAuthorizeRequired, InferInitContextType<TPlatform>>, TContext> => {
31
27
  const { authorize, context, crdt, debug, platform } = params;
32
28
 
33
29
  return new PluvIO<
34
30
  TPlatform,
35
- IOAuthorize<TAuthorizeUser, TAuthorizeRequired, InferPlatformContextType<TPlatform>>,
31
+ IOAuthorize<TAuthorizeUser, TAuthorizeRequired, InferInitContextType<TPlatform>>,
36
32
  TContext
37
33
  >({
38
34
  authorize,
package/src/index.ts CHANGED
@@ -4,7 +4,7 @@ export { AbstractPlatform } from "./AbstractPlatform";
4
4
  export type {
5
5
  AbstractPlatformConfig,
6
6
  ConvertWebSocketConfig,
7
- InferPlatformContextType,
7
+ InferInitContextType,
8
8
  InferPlatformWebSocketType,
9
9
  InferRoomContextType,
10
10
  WebSocketRegistrationMode,