@pluv/io 0.23.0 → 0.24.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.
@@ -1,9 +1,9 @@
1
1
 
2
- > @pluv/io@0.23.0 build /home/runner/work/pluv/pluv/packages/io
2
+ > @pluv/io@0.24.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.23.0 version /home/runner/work/pluv/pluv/packages/io
6
+ > @pluv/io@0.24.0 version /home/runner/work/pluv/pluv/packages/io
7
7
  > genversion ./src/version.generated.ts --esm
8
8
 
9
9
  CLI Building entry: src/index.ts
@@ -12,11 +12,11 @@
12
12
  CLI Target: es6
13
13
  ESM Build start
14
14
  CJS Build start
15
- CJS dist/index.js 39.65 KB
16
- CJS ⚡️ Build success in 159ms
17
- ESM dist/index.mjs 37.48 KB
18
- ESM ⚡️ Build success in 160ms
15
+ ESM dist/index.mjs 38.86 KB
16
+ ESM ⚡️ Build success in 112ms
17
+ CJS dist/index.js 41.00 KB
18
+ CJS ⚡️ Build success in 111ms
19
19
  DTS Build start
20
- DTS ⚡️ Build success in 2147ms
21
- DTS dist/index.d.mts 24.62 KB
22
- DTS dist/index.d.ts 24.62 KB
20
+ DTS ⚡️ Build success in 2161ms
21
+ DTS dist/index.d.mts 25.28 KB
22
+ DTS dist/index.d.ts 25.28 KB
package/CHANGELOG.md CHANGED
@@ -1,5 +1,133 @@
1
1
  # @pluv/io
2
2
 
3
+ ## 0.24.0
4
+
5
+ ### Minor Changes
6
+
7
+ - 6ac8a46: \* Fixed errors thrown when using Cloudflare's websocket hibernation API caused by rooms being re-used between different instances of DurableObjects.
8
+
9
+ - Add configurable `onDelete` and `onMessage` event listeners that can be set when rooms are created.
10
+
11
+ **BREAKING**
12
+
13
+ - Changed `PluvServer.getRoom` to `PluvServer.createRoom`. This means `PluvServer` only handles room creation. Room management must now be handled manually. This mainly affects manually creating rooms with `@pluv/platform-node`, and will likely not affect you if you are either using `createPluvHandler` on any platform, or if you are using `@pluv/platform-cloudflare`.
14
+
15
+ ```ts
16
+ // For @pluv/platform-node
17
+
18
+ // Before
19
+
20
+ import { createIO } from "@pluv/io";
21
+
22
+ const io = createIO(/* ... */);
23
+ const ioServer = io.server(/* ... */);
24
+
25
+ const roomId = "my-room-id";
26
+ const room = ioServer.getRoom(roomId);
27
+
28
+ // After
29
+
30
+ import { createIO, type InferIORoom } from "@pluv/io";
31
+
32
+ const io = createIO(/* ... */);
33
+ const ioServer = io.server(/* ... */);
34
+
35
+ const rooms = new Map<string, InferIORoom<typeof ioServer>>();
36
+
37
+ const roomId = "my-room-id";
38
+ const room = ioServer.createRoom(roomId, {
39
+ // Use new onDelete event listener
40
+ onDelete: (event) => {
41
+ rooms.delete(event.room);
42
+ },
43
+ });
44
+
45
+ rooms.set(roomId, room);
46
+ ```
47
+
48
+ - c26986d: Fixed websocket messages getting lost after the Cloudflare Worker Durable Object wakes up from hibernation.
49
+
50
+ **BREAKING**
51
+
52
+ Updated `onMessage`, `onClose` and `onError` to all return `Promise.void` instead of `void`.
53
+
54
+ ```ts
55
+ // Before
56
+
57
+ const io = createIO(/* ... */);
58
+ const ioServer = io.server(/* ... */);
59
+
60
+ class RoomDurableObject implements DurableObject {
61
+ public webSocketClose(ws: WebSocket, code: number, reason: string): void {
62
+ const handler = this._room.onClose(ws);
63
+
64
+ // Previously returned `void`
65
+ handler({ code, reason });
66
+ }
67
+
68
+ public webSocketError(ws: WebSocket, error: unknown): void {
69
+ const handler = this._room.onError(ws);
70
+ const eventError =
71
+ error instanceof Error ? error : new Error("Internal Error");
72
+
73
+ // Previously returned `void`
74
+ handler({ error: eventError, message: eventError.message });
75
+ }
76
+
77
+ public webSocketMessage(
78
+ ws: WebSocket,
79
+ message: string | ArrayBuffer,
80
+ ): void {
81
+ const handler = this._room.onMessage(ws);
82
+
83
+ // Previously returned `void`
84
+ handler({ data: message });
85
+ }
86
+ }
87
+
88
+ // After
89
+
90
+ const io = createIO(/* ... */);
91
+ const ioServer = io.server(/* ... */);
92
+
93
+ class RoomDurableObject implements DurableObject {
94
+ public async webSocketClose(
95
+ ws: WebSocket,
96
+ code: number,
97
+ reason: string,
98
+ ): Promise<void> {
99
+ const handler = this._room.onClose(ws);
100
+
101
+ // Handler must now be awaited
102
+ await handler({ code, reason });
103
+ }
104
+
105
+ public async webSocketError(ws: WebSocket, error: unknown): Promise<void> {
106
+ const handler = this._room.onError(ws);
107
+ const eventError =
108
+ error instanceof Error ? error : new Error("Internal Error");
109
+
110
+ // Handler must now be awaited
111
+ await handler({ error: eventError, message: eventError.message });
112
+ }
113
+
114
+ public async webSocketMessage(
115
+ ws: WebSocket,
116
+ message: string | ArrayBuffer,
117
+ ): Promise<void> {
118
+ const handler = this._room.onMessage(ws);
119
+
120
+ // Handler must now be awaited
121
+ await handler({ data: message });
122
+ }
123
+ }
124
+ ```
125
+
126
+ ### Patch Changes
127
+
128
+ - @pluv/crdt@0.24.0
129
+ - @pluv/types@0.24.0
130
+
3
131
  ## 0.23.0
4
132
 
5
133
  ### Minor Changes
package/dist/index.d.mts CHANGED
@@ -290,22 +290,24 @@ declare class IORoom<TPlatform extends AbstractPlatform<any> = AbstractPlatform<
290
290
  private readonly _sessions;
291
291
  get _events(): TEvents;
292
292
  get broadcast(): BroadcastProxy<this>;
293
+ private get _initialized();
293
294
  constructor(id: string, config: IORoomConfig<TPlatform, TAuthorize, TContext, TEvents>);
294
295
  getSize(): number;
295
- onClose(webSocket: WebSocketType<TPlatform>): (event: AbstractCloseEvent) => void;
296
- onError(webSocket: WebSocketType<TPlatform>): (event: AbstractErrorEvent) => void;
297
- onMessage(webSocket: WebSocketType<TPlatform>): (event: AbstractMessageEvent) => void;
296
+ onClose(webSocket: WebSocketType<TPlatform>): (event: AbstractCloseEvent) => Promise<void>;
297
+ onError(webSocket: WebSocketType<TPlatform>): (event: AbstractErrorEvent) => Promise<void>;
298
+ onMessage(webSocket: WebSocketType<TPlatform>): (event: AbstractMessageEvent) => Promise<void>;
298
299
  register(webSocket: InferPlatformWebSocketSource<TPlatform>, options?: WebsocketRegisterOptions): Promise<void>;
299
300
  private _broadcast;
300
301
  private _emitQuitters;
301
302
  private _emitRegistered;
302
303
  private _ensureDetached;
303
304
  private _getAbstractWs;
304
- private _getSession;
305
305
  private _getAuthorizedUser;
306
+ private _getInitialDoc;
306
307
  private _getIOAuthorize;
307
308
  private _getProcedure;
308
309
  private _getProcedureInputs;
310
+ private _getSession;
309
311
  private _getSessions;
310
312
  private _initialize;
311
313
  private _logDebug;
@@ -330,11 +332,10 @@ type PluvServerConfig<TPlatform extends AbstractPlatform<any> = AbstractPlatform
330
332
  platform: TPlatform;
331
333
  router?: PluvRouter<TPlatform, TAuthorize, TContext, TEvents>;
332
334
  };
333
- type GetRoomOptions<TPlatform extends AbstractPlatform> = keyof InferRoomContextType<TPlatform> extends never ? [{
335
+ type BaseCreateRoomOptions<TPlatform extends AbstractPlatform<any>, TAuthorize extends IOAuthorize<any, any, InferPlatformContextType<TPlatform>>, TContext extends JsonObject, TEvents extends PluvRouterEventConfig<TPlatform, TAuthorize, TContext>> = Partial<IORoomListeners<TPlatform, TAuthorize, TContext, TEvents>> & {
334
336
  debug?: boolean;
335
- }] | [] : [Id<{
336
- debug?: boolean;
337
- } & InferRoomContextType<TPlatform>>];
337
+ };
338
+ type CreateRoomOptions<TPlatform extends AbstractPlatform<any>, TAuthorize extends IOAuthorize<any, any, InferPlatformContextType<TPlatform>>, TContext extends JsonObject, TEvents extends PluvRouterEventConfig<TPlatform, TAuthorize, TContext>> = keyof InferRoomContextType<TPlatform> extends never ? [BaseCreateRoomOptions<TPlatform, TAuthorize, TContext, TEvents>] | [] : [Id<BaseCreateRoomOptions<TPlatform, TAuthorize, TContext, TEvents> & InferRoomContextType<TPlatform>>];
338
339
  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> {
339
340
  _listeners: PluvIOListeners<TPlatform, TAuthorize, TContext, TEvents>;
340
341
  readonly version: string;
@@ -345,16 +346,14 @@ declare class PluvServer<TPlatform extends AbstractPlatform<any> = AbstractPlatf
345
346
  private readonly _debug;
346
347
  private readonly _getInitialStorage;
347
348
  private readonly _platform;
348
- private readonly _rooms;
349
349
  private readonly _router;
350
350
  get _events(): TEvents;
351
351
  get _registrationMode(): WebSocketRegistrationMode;
352
352
  private get _procedure();
353
353
  constructor(options: PluvServerConfig<TPlatform, TAuthorize, TContext, TEvents>);
354
+ createRoom(room: string, ...options: CreateRoomOptions<TPlatform, TAuthorize, TContext, TEvents>): IORoom<TPlatform, TAuthorize, TContext, TEvents>;
354
355
  createToken(params: JWTEncodeParams<InferIOAuthorizeUser<InferIOAuthorize<this>>, TPlatform>): Promise<string>;
355
- getRoom(room: string, ...options: GetRoomOptions<TPlatform>): IORoom<TPlatform, TAuthorize, TContext, TEvents>;
356
356
  private _logDebug;
357
- private _purgeEmptyRooms;
358
357
  }
359
358
 
360
359
  type PluvIOConfig<TPlatform extends AbstractPlatform<any>, TAuthorize extends IOAuthorize<any, any, InferPlatformContextType<TPlatform>>, TContext extends JsonObject> = {
@@ -396,4 +395,4 @@ type CreateIOParams<TPlatform extends AbstractPlatform<any> = AbstractPlatform<a
396
395
  };
397
396
  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>;
398
397
 
399
- export { type AbstractCloseEvent, type AbstractErrorEvent, type AbstractEvent, type AbstractEventMap, type AbstractListener, type AbstractMessageEvent, AbstractPersistance, AbstractPlatform, type AbstractPlatformConfig, AbstractPubSub, AbstractWebSocket, type AbstractWebSocketConfig, type AbstractWebSocketHandleErrorParams, type AuthorizeModule, type AuthorizeParams, type ConvertWebSocketConfig, type CreateIOParams, type GetRoomOptions, 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 };
398
+ export { type AbstractCloseEvent, type AbstractErrorEvent, type AbstractEvent, type AbstractEventMap, type AbstractListener, type AbstractMessageEvent, AbstractPersistance, 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
@@ -290,22 +290,24 @@ declare class IORoom<TPlatform extends AbstractPlatform<any> = AbstractPlatform<
290
290
  private readonly _sessions;
291
291
  get _events(): TEvents;
292
292
  get broadcast(): BroadcastProxy<this>;
293
+ private get _initialized();
293
294
  constructor(id: string, config: IORoomConfig<TPlatform, TAuthorize, TContext, TEvents>);
294
295
  getSize(): number;
295
- onClose(webSocket: WebSocketType<TPlatform>): (event: AbstractCloseEvent) => void;
296
- onError(webSocket: WebSocketType<TPlatform>): (event: AbstractErrorEvent) => void;
297
- onMessage(webSocket: WebSocketType<TPlatform>): (event: AbstractMessageEvent) => void;
296
+ onClose(webSocket: WebSocketType<TPlatform>): (event: AbstractCloseEvent) => Promise<void>;
297
+ onError(webSocket: WebSocketType<TPlatform>): (event: AbstractErrorEvent) => Promise<void>;
298
+ onMessage(webSocket: WebSocketType<TPlatform>): (event: AbstractMessageEvent) => Promise<void>;
298
299
  register(webSocket: InferPlatformWebSocketSource<TPlatform>, options?: WebsocketRegisterOptions): Promise<void>;
299
300
  private _broadcast;
300
301
  private _emitQuitters;
301
302
  private _emitRegistered;
302
303
  private _ensureDetached;
303
304
  private _getAbstractWs;
304
- private _getSession;
305
305
  private _getAuthorizedUser;
306
+ private _getInitialDoc;
306
307
  private _getIOAuthorize;
307
308
  private _getProcedure;
308
309
  private _getProcedureInputs;
310
+ private _getSession;
309
311
  private _getSessions;
310
312
  private _initialize;
311
313
  private _logDebug;
@@ -330,11 +332,10 @@ type PluvServerConfig<TPlatform extends AbstractPlatform<any> = AbstractPlatform
330
332
  platform: TPlatform;
331
333
  router?: PluvRouter<TPlatform, TAuthorize, TContext, TEvents>;
332
334
  };
333
- type GetRoomOptions<TPlatform extends AbstractPlatform> = keyof InferRoomContextType<TPlatform> extends never ? [{
335
+ type BaseCreateRoomOptions<TPlatform extends AbstractPlatform<any>, TAuthorize extends IOAuthorize<any, any, InferPlatformContextType<TPlatform>>, TContext extends JsonObject, TEvents extends PluvRouterEventConfig<TPlatform, TAuthorize, TContext>> = Partial<IORoomListeners<TPlatform, TAuthorize, TContext, TEvents>> & {
334
336
  debug?: boolean;
335
- }] | [] : [Id<{
336
- debug?: boolean;
337
- } & InferRoomContextType<TPlatform>>];
337
+ };
338
+ type CreateRoomOptions<TPlatform extends AbstractPlatform<any>, TAuthorize extends IOAuthorize<any, any, InferPlatformContextType<TPlatform>>, TContext extends JsonObject, TEvents extends PluvRouterEventConfig<TPlatform, TAuthorize, TContext>> = keyof InferRoomContextType<TPlatform> extends never ? [BaseCreateRoomOptions<TPlatform, TAuthorize, TContext, TEvents>] | [] : [Id<BaseCreateRoomOptions<TPlatform, TAuthorize, TContext, TEvents> & InferRoomContextType<TPlatform>>];
338
339
  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> {
339
340
  _listeners: PluvIOListeners<TPlatform, TAuthorize, TContext, TEvents>;
340
341
  readonly version: string;
@@ -345,16 +346,14 @@ declare class PluvServer<TPlatform extends AbstractPlatform<any> = AbstractPlatf
345
346
  private readonly _debug;
346
347
  private readonly _getInitialStorage;
347
348
  private readonly _platform;
348
- private readonly _rooms;
349
349
  private readonly _router;
350
350
  get _events(): TEvents;
351
351
  get _registrationMode(): WebSocketRegistrationMode;
352
352
  private get _procedure();
353
353
  constructor(options: PluvServerConfig<TPlatform, TAuthorize, TContext, TEvents>);
354
+ createRoom(room: string, ...options: CreateRoomOptions<TPlatform, TAuthorize, TContext, TEvents>): IORoom<TPlatform, TAuthorize, TContext, TEvents>;
354
355
  createToken(params: JWTEncodeParams<InferIOAuthorizeUser<InferIOAuthorize<this>>, TPlatform>): Promise<string>;
355
- getRoom(room: string, ...options: GetRoomOptions<TPlatform>): IORoom<TPlatform, TAuthorize, TContext, TEvents>;
356
356
  private _logDebug;
357
- private _purgeEmptyRooms;
358
357
  }
359
358
 
360
359
  type PluvIOConfig<TPlatform extends AbstractPlatform<any>, TAuthorize extends IOAuthorize<any, any, InferPlatformContextType<TPlatform>>, TContext extends JsonObject> = {
@@ -396,4 +395,4 @@ type CreateIOParams<TPlatform extends AbstractPlatform<any> = AbstractPlatform<a
396
395
  };
397
396
  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>;
398
397
 
399
- export { type AbstractCloseEvent, type AbstractErrorEvent, type AbstractEvent, type AbstractEventMap, type AbstractListener, type AbstractMessageEvent, AbstractPersistance, AbstractPlatform, type AbstractPlatformConfig, AbstractPubSub, AbstractWebSocket, type AbstractWebSocketConfig, type AbstractWebSocketHandleErrorParams, type AuthorizeModule, type AuthorizeParams, type ConvertWebSocketConfig, type CreateIOParams, type GetRoomOptions, 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 };
398
+ export { type AbstractCloseEvent, type AbstractErrorEvent, type AbstractEvent, type AbstractEventMap, type AbstractListener, type AbstractMessageEvent, AbstractPersistance, 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 };