@pluv/io 0.3.8 → 0.4.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 +7 -7
- package/CHANGELOG.md +25 -0
- package/dist/index.d.ts +29 -24
- package/dist/index.js +200 -179
- package/dist/index.mjs +200 -179
- package/package.json +9 -9
- package/src/IORoom.ts +243 -199
- package/src/PluvIO.ts +169 -59
- package/src/types.ts +38 -7
package/.turbo/turbo-build.log
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
|
|
2
|
-
> @pluv/io@0.
|
|
2
|
+
> @pluv/io@0.4.0 build /home/runner/work/pluv/pluv/packages/io
|
|
3
3
|
> tsup src/index.ts --format esm,cjs --dts
|
|
4
4
|
|
|
5
5
|
[34mCLI[39m Building entry: src/index.ts
|
|
@@ -8,10 +8,10 @@
|
|
|
8
8
|
[34mCLI[39m Target: es6
|
|
9
9
|
[34mESM[39m Build start
|
|
10
10
|
[34mCJS[39m Build start
|
|
11
|
-
[
|
|
12
|
-
[
|
|
13
|
-
[
|
|
14
|
-
[
|
|
11
|
+
[32mESM[39m [1mdist/index.mjs [22m[32m28.25 KB[39m
|
|
12
|
+
[32mESM[39m ⚡️ Build success in 154ms
|
|
13
|
+
[32mCJS[39m [1mdist/index.js [22m[32m30.31 KB[39m
|
|
14
|
+
[32mCJS[39m ⚡️ Build success in 155ms
|
|
15
15
|
[34mDTS[39m Build start
|
|
16
|
-
[32mDTS[39m ⚡️ Build success in
|
|
17
|
-
[32mDTS[39m [1mdist/index.d.ts [22m[
|
|
16
|
+
[32mDTS[39m ⚡️ Build success in 4082ms
|
|
17
|
+
[32mDTS[39m [1mdist/index.d.ts [22m[32m14.78 KB[39m
|
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,30 @@
|
|
|
1
1
|
# @pluv/io
|
|
2
2
|
|
|
3
|
+
## 0.4.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- bb2886b: allow sending multiple output types (broadcast, self, sync) per event
|
|
8
|
+
- ae679a8: updated offline presence to be set when reconnecting to a room
|
|
9
|
+
|
|
10
|
+
### Patch Changes
|
|
11
|
+
|
|
12
|
+
- 41943cf: bumped dependencies
|
|
13
|
+
- 0dd847e: updated storage to be synced when reconnected to the room
|
|
14
|
+
- 3518a83: bumped dependencies
|
|
15
|
+
- Updated dependencies [0dd847e]
|
|
16
|
+
- Updated dependencies [bb2886b]
|
|
17
|
+
- Updated dependencies [ae679a8]
|
|
18
|
+
- Updated dependencies [3518a83]
|
|
19
|
+
- @pluv/crdt-yjs@0.3.7
|
|
20
|
+
- @pluv/types@0.2.0
|
|
21
|
+
|
|
22
|
+
## 0.3.9
|
|
23
|
+
|
|
24
|
+
### Patch Changes
|
|
25
|
+
|
|
26
|
+
- abb3622: fixed @pluv/io yjs doc becoming unresponsive when the last user leaves on a cloudflare worker
|
|
27
|
+
|
|
3
28
|
## 0.3.8
|
|
4
29
|
|
|
5
30
|
### Patch Changes
|
package/dist/index.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { JsonObject, MaybePromise, IOEventMessage, EventRecord, InputZodLike, Id, IOLike, InferIOOutput, BaseUser, IOAuthorize, BaseIOAuthorize, InferIOInput, Maybe, InferIOAuthorizeUser, InferIOAuthorize, Spread, BaseClientEventRecord, BaseIOEventRecord } from '@pluv/types';
|
|
1
|
+
import { JsonObject, MaybePromise, IOEventMessage, EventRecord, InputZodLike, Id, IOLike, InferIOOutput, BaseUser, IOAuthorize, BaseIOAuthorize, InferIOInput, Maybe, InferIOAuthorizeUser, InferIOAuthorize, Spread, InferIOOutputBroadcast, InferIOOutputSelf, InferIOOutputSync, BaseClientEventRecord, BaseIOEventRecord } from '@pluv/types';
|
|
2
2
|
export { BaseUser, EventMessage, EventRecord, IOEventMessage } from '@pluv/types';
|
|
3
3
|
import { YjsDoc } from '@pluv/crdt-yjs';
|
|
4
4
|
|
|
@@ -79,12 +79,11 @@ declare global {
|
|
|
79
79
|
log: (...data: any[]) => void;
|
|
80
80
|
};
|
|
81
81
|
}
|
|
82
|
-
interface EventConfig<TContext extends JsonObject = {}, TData extends JsonObject = {},
|
|
82
|
+
interface EventConfig<TContext extends JsonObject = {}, TData extends JsonObject = {}, TResultBroadcast extends EventRecord<string, any> = {}, TResultSelf extends EventRecord<string, any> = {}, TResultSync extends EventRecord<string, any> = {}> {
|
|
83
83
|
input?: InputZodLike<TData>;
|
|
84
|
-
|
|
85
|
-
resolver: EventResolver<TContext, TData, TResult>;
|
|
84
|
+
resolver: EventResolver<TContext, TData, TResultBroadcast> | EventResolverObject<TContext, TData, TResultBroadcast, TResultSelf, TResultSync>;
|
|
86
85
|
}
|
|
87
|
-
type EventResolver<TContext extends JsonObject = {}, TData extends JsonObject = {},
|
|
86
|
+
type EventResolver<TContext extends JsonObject = {}, TData extends JsonObject = {}, TResultBroadcast extends EventRecord<string, any> = {}> = (data: TData, context: EventResolverContext<TContext>) => MaybePromise<TResultBroadcast | void>;
|
|
88
87
|
interface EventResolverContext<TContext extends JsonObject = {}> {
|
|
89
88
|
context: TContext;
|
|
90
89
|
doc: YjsDoc<any>;
|
|
@@ -104,8 +103,13 @@ interface EventResolverContext<TContext extends JsonObject = {}> {
|
|
|
104
103
|
session: WebSocketSession | null;
|
|
105
104
|
sessions: Map<string, WebSocketSession>;
|
|
106
105
|
}
|
|
107
|
-
type
|
|
108
|
-
|
|
106
|
+
type EventResolverObject<TContext extends JsonObject = {}, TData extends JsonObject = {}, TResultBroadcast extends EventRecord<string, any> = {}, TResultSelf extends EventRecord<string, any> = {}, TResultSync extends EventRecord<string, any> = {}> = {
|
|
107
|
+
broadcast?: EventResolver<TContext, TData, TResultBroadcast>;
|
|
108
|
+
self?: EventResolver<TContext, TData, TResultSelf>;
|
|
109
|
+
sync?: EventResolver<TContext, TData, TResultSync>;
|
|
110
|
+
};
|
|
111
|
+
type InferEventConfig<TContext extends JsonObject = {}, TInput extends EventRecord<string, any> = {}, TOutputBroadcast extends EventRecord<string, any> = {}, TOutputSelf extends EventRecord<string, any> = {}, TOutputSync extends EventRecord<string, any> = {}> = {
|
|
112
|
+
[P in keyof TInput]: P extends string ? Id<EventConfig<TContext, TInput[P], TOutputBroadcast, TOutputSelf, TOutputSync>> : never;
|
|
109
113
|
};
|
|
110
114
|
type SendMessageOptions = {
|
|
111
115
|
type?: "broadcast";
|
|
@@ -179,18 +183,18 @@ interface AuthorizeModule {
|
|
|
179
183
|
interface IORoomListeners {
|
|
180
184
|
onDestroy: (encodedState: string) => void;
|
|
181
185
|
}
|
|
182
|
-
type IORoomConfig<TPlatform extends AbstractPlatform<any> = AbstractPlatform<any>, TAuthorize extends IOAuthorize<any, any> = BaseIOAuthorize, TContext extends JsonObject = {}, TInput extends EventRecord<string, any> = {},
|
|
186
|
+
type IORoomConfig<TPlatform extends AbstractPlatform<any> = AbstractPlatform<any>, TAuthorize extends IOAuthorize<any, any> = BaseIOAuthorize, TContext extends JsonObject = {}, TInput extends EventRecord<string, any> = {}, TOutputBroadcast extends EventRecord<string, any> = {}, TOutputSelf extends EventRecord<string, any> = {}, TOutputSync extends EventRecord<string, any> = {}> = Partial<IORoomListeners> & {
|
|
183
187
|
authorize?: TAuthorize;
|
|
184
188
|
context: TContext;
|
|
185
189
|
debug: boolean;
|
|
186
|
-
events: InferEventConfig<TContext, TInput,
|
|
190
|
+
events: InferEventConfig<TContext, TInput, TOutputBroadcast, TOutputSelf, TOutputSync>;
|
|
187
191
|
initialStorage?: () => MaybePromise<Maybe<string>>;
|
|
188
192
|
platform: TPlatform;
|
|
189
193
|
};
|
|
190
194
|
interface WebsocketRegisterOptions {
|
|
191
195
|
token?: string;
|
|
192
196
|
}
|
|
193
|
-
declare class IORoom<TPlatform extends AbstractPlatform<any> = AbstractPlatform<any>, TAuthorize extends IOAuthorize<any, any> = BaseIOAuthorize, TContext extends JsonObject = {}, TInput extends EventRecord<string, any> = {},
|
|
197
|
+
declare class IORoom<TPlatform extends AbstractPlatform<any> = AbstractPlatform<any>, TAuthorize extends IOAuthorize<any, any> = BaseIOAuthorize, TContext extends JsonObject = {}, TInput extends EventRecord<string, any> = {}, TOutputBroadcast extends EventRecord<string, any> = {}, TOutputSelf extends EventRecord<string, any> = {}, TOutputSync extends EventRecord<string, any> = {}> implements IOLike<TAuthorize, TInput, TOutputBroadcast, TOutputSelf, TOutputSync> {
|
|
194
198
|
private readonly _context;
|
|
195
199
|
private readonly _debug;
|
|
196
200
|
private readonly _platform;
|
|
@@ -200,23 +204,24 @@ declare class IORoom<TPlatform extends AbstractPlatform<any> = AbstractPlatform<
|
|
|
200
204
|
private _sessions;
|
|
201
205
|
private _uninitialize;
|
|
202
206
|
readonly _authorize: TAuthorize | null;
|
|
203
|
-
readonly _events: InferEventConfig<TContext, TInput,
|
|
207
|
+
readonly _events: InferEventConfig<TContext, TInput, TOutputBroadcast, TOutputSelf, TOutputSync>;
|
|
204
208
|
readonly id: string;
|
|
205
|
-
constructor(id: string, config: IORoomConfig<TPlatform, TAuthorize, TContext, TInput,
|
|
209
|
+
constructor(id: string, config: IORoomConfig<TPlatform, TAuthorize, TContext, TInput, TOutputBroadcast, TOutputSelf, TOutputSync>);
|
|
206
210
|
broadcast<TEvent extends keyof InferIOInput<this>>(event: TEvent, data: Id<InferIOInput<this>[TEvent]>): Promise<void>;
|
|
207
211
|
getSize(): number;
|
|
208
212
|
register(webSocket: InferWebSocketType<TPlatform>, options?: WebsocketRegisterOptions): Promise<void>;
|
|
209
213
|
private _broadcast;
|
|
210
214
|
private _emitQuitters;
|
|
211
215
|
private _emitRegistered;
|
|
212
|
-
private _emitStorageReceived;
|
|
213
|
-
private _emitUserJoined;
|
|
214
216
|
private _getAuthorizedUser;
|
|
215
217
|
private _getEventConfig;
|
|
218
|
+
private _getEventInputs;
|
|
219
|
+
private _getEventResolverObject;
|
|
216
220
|
private _initialize;
|
|
217
221
|
private _logDebug;
|
|
222
|
+
private _onClose;
|
|
223
|
+
private _onMessage;
|
|
218
224
|
private _parseMessage;
|
|
219
|
-
private _resolveMessage;
|
|
220
225
|
private _sendMessage;
|
|
221
226
|
private _sendBroadcastMessage;
|
|
222
227
|
private _sendSelfMessage;
|
|
@@ -230,31 +235,31 @@ interface PluvIOListeners {
|
|
|
230
235
|
onRoomDeleted: (room: string, encodedState: string) => void;
|
|
231
236
|
onStorageUpdated: (room: string, encodedState: string) => void;
|
|
232
237
|
}
|
|
233
|
-
type PluvIOConfig<TPlatform extends AbstractPlatform<any> = AbstractPlatform<any>, TAuthorize extends IOAuthorize<any, any> | null = null, TContext extends JsonObject = {}, TInput extends EventRecord<string, any> = {},
|
|
238
|
+
type PluvIOConfig<TPlatform extends AbstractPlatform<any> = AbstractPlatform<any>, TAuthorize extends IOAuthorize<any, any> | null = null, TContext extends JsonObject = {}, TInput extends EventRecord<string, any> = {}, TOutputBroadcast extends EventRecord<string, any> = {}, TOutputSelf extends EventRecord<string, any> = {}, TOutputSync extends EventRecord<string, any> = {}> = Partial<PluvIOListeners> & {
|
|
234
239
|
authorize?: TAuthorize;
|
|
235
240
|
context?: TContext;
|
|
236
241
|
debug?: boolean;
|
|
237
|
-
events?: InferEventConfig<TContext, TInput,
|
|
242
|
+
events?: InferEventConfig<TContext, TInput, TOutputBroadcast, TOutputSelf, TOutputSync>;
|
|
238
243
|
initialStorage?: (room: string) => MaybePromise<Maybe<string>>;
|
|
239
244
|
platform: TPlatform;
|
|
240
245
|
};
|
|
241
246
|
interface GetRoomOptions {
|
|
242
247
|
debug?: boolean;
|
|
243
248
|
}
|
|
244
|
-
declare class PluvIO<TPlatform extends AbstractPlatform<any> = AbstractPlatform<any>, TAuthorize extends IOAuthorize<any, any> = BaseIOAuthorize, TContext extends JsonObject = {}, TInput extends EventRecord<string, any> = {},
|
|
249
|
+
declare class PluvIO<TPlatform extends AbstractPlatform<any> = AbstractPlatform<any>, TAuthorize extends IOAuthorize<any, any> = BaseIOAuthorize, TContext extends JsonObject = {}, TInput extends EventRecord<string, any> = {}, TOutputBroadcast extends EventRecord<string, any> = {}, TOutputSelf extends EventRecord<string, any> = {}, TOutputSync extends EventRecord<string, any> = {}> implements IOLike<TAuthorize, TInput, TOutputBroadcast, TOutputSelf, TOutputSync> {
|
|
245
250
|
private _context;
|
|
246
251
|
private _initialStorage;
|
|
247
252
|
private _listeners;
|
|
248
253
|
private _rooms;
|
|
249
254
|
readonly _authorize: TAuthorize | null;
|
|
250
255
|
readonly _debug: boolean;
|
|
251
|
-
readonly _events: InferEventConfig<TContext, TInput,
|
|
256
|
+
readonly _events: InferEventConfig<TContext, TInput, TOutputBroadcast, TOutputSelf, TOutputSync>;
|
|
252
257
|
readonly _platform: TPlatform;
|
|
253
|
-
constructor(options: PluvIOConfig<TPlatform, TAuthorize, TContext, TInput,
|
|
258
|
+
constructor(options: PluvIOConfig<TPlatform, TAuthorize, TContext, TInput, TOutputBroadcast, TOutputSelf, TOutputSync>);
|
|
254
259
|
createToken(params: JWTEncodeParams<InferIOAuthorizeUser<InferIOAuthorize<this>>>): Promise<string>;
|
|
255
|
-
event<TEvent extends string, TData extends JsonObject = {},
|
|
256
|
-
getRoom(room: string, options?: GetRoomOptions): IORoom<TPlatform, TAuthorize, TContext, TInput,
|
|
257
|
-
static merge<TIO1 extends PluvIO, TIO2 extends PluvIO>(first: TIO1, second: TIO2): PluvIO<InferIOPlatform<TIO1>, InferIOAuthorize<TIO1>, InferIOContext<TIO1>, Spread<[InferIOInput<TIO1>, InferIOInput<TIO2>]>, Spread<[
|
|
260
|
+
event<TEvent extends string, TData extends JsonObject = {}, TResultBroadcast extends EventRecord<string, any> = {}, TResultSelf extends EventRecord<string, any> = {}, TResultSync extends EventRecord<string, any> = {}>(event: TEvent, config: EventConfig<TContext, TData, TResultBroadcast, TResultSelf, TResultSync>): PluvIO<TPlatform, TAuthorize, TContext, Spread<[TInput, EventRecord<TEvent, TData>]>, Spread<[TOutputBroadcast, TResultBroadcast]>, Spread<[TOutputSelf, TResultSelf]>, Spread<[TOutputSync, TResultSync]>>;
|
|
261
|
+
getRoom(room: string, options?: GetRoomOptions): IORoom<TPlatform, TAuthorize, TContext, TInput, TOutputBroadcast, TOutputSelf, TOutputSync>;
|
|
262
|
+
static merge<TIO1 extends PluvIO, TIO2 extends PluvIO>(first: TIO1, second: TIO2): PluvIO<InferIOPlatform<TIO1>, InferIOAuthorize<TIO1>, InferIOContext<TIO1>, Spread<[InferIOInput<TIO1>, InferIOInput<TIO2>]>, Spread<[InferIOOutputBroadcast<TIO1>, InferIOOutputBroadcast<TIO2>]>, Spread<[InferIOOutputSelf<TIO1>, InferIOOutputSelf<TIO2>]>, Spread<[InferIOOutputSync<TIO1>, InferIOOutputSync<TIO2>]>>;
|
|
258
263
|
private _logDebug;
|
|
259
264
|
private _purgeEmptyRooms;
|
|
260
265
|
}
|
|
@@ -266,6 +271,6 @@ type CreateIOParams<TPlatform extends AbstractPlatform<any> = AbstractPlatform<a
|
|
|
266
271
|
initialStorage?: (room: string) => MaybePromise<Maybe<string>>;
|
|
267
272
|
platform: TPlatform;
|
|
268
273
|
};
|
|
269
|
-
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>, TContext, BaseClientEventRecord, BaseIOEventRecord<IOAuthorize<TAuthorizeUser, TAuthorizeRequired
|
|
274
|
+
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>, TContext, BaseClientEventRecord, BaseIOEventRecord<IOAuthorize<TAuthorizeUser, TAuthorizeRequired>>, {}, {}>;
|
|
270
275
|
|
|
271
276
|
export { AbstractCloseEvent, AbstractErrorEvent, AbstractEvent, AbstractEventMap, AbstractListener, AbstractMessageEvent, AbstractPersistance, AbstractPlatform, AbstractPubSub, AbstractWebSocket, AbstractWebSocketConfig, AbstractWebSocketHandleErrorParams, AuthorizeModule, AuthorizeParams, ConvertWebSocketConfig, CreateIOParams, GetRoomOptions, IOPubSubEventMessage, IORoom, InferIORoom, InferWebSocketType, JWT, JWTEncodeParams, PluvIO, createIO };
|
package/dist/index.js
CHANGED
|
@@ -261,6 +261,10 @@ var AbstractWebSocket = class {
|
|
|
261
261
|
// src/PluvIO.ts
|
|
262
262
|
var import_kleur2 = __toESM(require("kleur"));
|
|
263
263
|
|
|
264
|
+
// src/IORoom.ts
|
|
265
|
+
var import_crdt_yjs = require("@pluv/crdt-yjs");
|
|
266
|
+
var import_kleur = __toESM(require("kleur"));
|
|
267
|
+
|
|
264
268
|
// src/authorize.ts
|
|
265
269
|
var import_hkdf = __toESM(require("@panva/hkdf"));
|
|
266
270
|
var import_jose = require("jose");
|
|
@@ -298,8 +302,6 @@ var authorize = (params) => {
|
|
|
298
302
|
};
|
|
299
303
|
|
|
300
304
|
// src/IORoom.ts
|
|
301
|
-
var import_crdt_yjs = require("@pluv/crdt-yjs");
|
|
302
|
-
var import_kleur = __toESM(require("kleur"));
|
|
303
305
|
var PING_TIMEOUT_MS = 3e4;
|
|
304
306
|
var IORoom = class {
|
|
305
307
|
constructor(id, config) {
|
|
@@ -323,7 +325,9 @@ var IORoom = class {
|
|
|
323
325
|
this._platform = platform;
|
|
324
326
|
this.id = id;
|
|
325
327
|
this._listeners = {
|
|
326
|
-
onDestroy: (encodedState) =>
|
|
328
|
+
onDestroy: (encodedState) => {
|
|
329
|
+
onDestroy == null ? void 0 : onDestroy(encodedState);
|
|
330
|
+
}
|
|
327
331
|
};
|
|
328
332
|
if (authorize2)
|
|
329
333
|
this._authorize = authorize2;
|
|
@@ -394,101 +398,12 @@ var IORoom = class {
|
|
|
394
398
|
sessionId,
|
|
395
399
|
user != null ? user : {}
|
|
396
400
|
);
|
|
401
|
+
const onClose = this._onClose(session, uninitializeWs).bind(this);
|
|
402
|
+
const onMessage = this._onMessage(session).bind(this);
|
|
403
|
+
pluvWs.addEventListener("close", onClose);
|
|
404
|
+
pluvWs.addEventListener("error", onClose);
|
|
405
|
+
pluvWs.addEventListener("message", onMessage);
|
|
397
406
|
this._emitRegistered(session);
|
|
398
|
-
this._emitStorageReceived(session);
|
|
399
|
-
this._emitUserJoined(session);
|
|
400
|
-
const context = {
|
|
401
|
-
context: this._context,
|
|
402
|
-
doc: this._doc,
|
|
403
|
-
room: this.id,
|
|
404
|
-
session,
|
|
405
|
-
sessions: this._sessions
|
|
406
|
-
};
|
|
407
|
-
pluvWs.addEventListener("message", (event) => {
|
|
408
|
-
if (!this._uninitialize)
|
|
409
|
-
return;
|
|
410
|
-
if (session.quit) {
|
|
411
|
-
session.webSocket.close(1011, "WebSocket broken.");
|
|
412
|
-
return;
|
|
413
|
-
}
|
|
414
|
-
const message = this._parseMessage(event);
|
|
415
|
-
if (!message)
|
|
416
|
-
return;
|
|
417
|
-
const eventConfig = this._getEventConfig(message);
|
|
418
|
-
if (!eventConfig)
|
|
419
|
-
return;
|
|
420
|
-
this._resolveMessage(message, context).then((output) => {
|
|
421
|
-
var _a2, _b;
|
|
422
|
-
if (!output)
|
|
423
|
-
return;
|
|
424
|
-
const eventType = (_b = (_a2 = eventConfig.options) == null ? void 0 : _a2.type) != null ? _b : "broadcast";
|
|
425
|
-
switch (eventType) {
|
|
426
|
-
case "self": {
|
|
427
|
-
Object.entries(output).forEach(([type, data]) => {
|
|
428
|
-
this._sendSelfMessage({ data, type }, session);
|
|
429
|
-
});
|
|
430
|
-
return;
|
|
431
|
-
}
|
|
432
|
-
case "sync": {
|
|
433
|
-
this._platform.pubSub.publish(this.id, __spreadValues({
|
|
434
|
-
connectionId: session.id,
|
|
435
|
-
options: eventConfig.options,
|
|
436
|
-
room: this.id,
|
|
437
|
-
user: session.user
|
|
438
|
-
}, message));
|
|
439
|
-
Object.entries(output).forEach(([type, data]) => {
|
|
440
|
-
this._sendSelfMessage({ data, type }, session);
|
|
441
|
-
});
|
|
442
|
-
return;
|
|
443
|
-
}
|
|
444
|
-
case "broadcast":
|
|
445
|
-
default: {
|
|
446
|
-
Object.entries(output).forEach(([type, data]) => {
|
|
447
|
-
this._broadcast({
|
|
448
|
-
message: { data, type },
|
|
449
|
-
senderId: session.id
|
|
450
|
-
});
|
|
451
|
-
});
|
|
452
|
-
}
|
|
453
|
-
}
|
|
454
|
-
});
|
|
455
|
-
});
|
|
456
|
-
const closeHandler = () => {
|
|
457
|
-
if (!this._uninitialize)
|
|
458
|
-
return;
|
|
459
|
-
session.quit = true;
|
|
460
|
-
this._logDebug(
|
|
461
|
-
`${import_kleur.default.blue(
|
|
462
|
-
`(Unregistering connection for room ${this.id}:`
|
|
463
|
-
)} ${sessionId}`
|
|
464
|
-
);
|
|
465
|
-
this._sessions.delete(session.id);
|
|
466
|
-
this._platform.persistance.deleteUser(this.id, session.id).finally(() => {
|
|
467
|
-
var _a2;
|
|
468
|
-
this._broadcast({
|
|
469
|
-
message: {
|
|
470
|
-
type: "$EXIT",
|
|
471
|
-
data: { sessionId: session.id }
|
|
472
|
-
},
|
|
473
|
-
senderId: session.id
|
|
474
|
-
});
|
|
475
|
-
uninitializeWs();
|
|
476
|
-
const size2 = this.getSize();
|
|
477
|
-
this._logDebug(
|
|
478
|
-
`${import_kleur.default.blue(
|
|
479
|
-
`Unregistered connection for room ${this.id}:`
|
|
480
|
-
)} ${sessionId}`
|
|
481
|
-
);
|
|
482
|
-
this._logDebug(
|
|
483
|
-
`${import_kleur.default.blue(`Room ${this.id} size:`)} ${size2}`
|
|
484
|
-
);
|
|
485
|
-
if (size2)
|
|
486
|
-
return;
|
|
487
|
-
(_a2 = this._uninitialize) == null ? void 0 : _a2.call(this);
|
|
488
|
-
});
|
|
489
|
-
};
|
|
490
|
-
pluvWs.addEventListener("close", closeHandler);
|
|
491
|
-
pluvWs.addEventListener("error", closeHandler);
|
|
492
407
|
this._logDebug(
|
|
493
408
|
`${import_kleur.default.blue(
|
|
494
409
|
`Registered connection for room ${this.id}:`
|
|
@@ -536,34 +451,6 @@ var IORoom = class {
|
|
|
536
451
|
session
|
|
537
452
|
);
|
|
538
453
|
}
|
|
539
|
-
_emitStorageReceived(session) {
|
|
540
|
-
this._platform.persistance.getStorageState(this.id).then((_state) => __async(this, null, function* () {
|
|
541
|
-
var _a, _b;
|
|
542
|
-
const state = (_b = _state != null ? _state : yield (_a = this._initialStorage) == null ? void 0 : _a.call(this)) != null ? _b : this._doc.encodeStateAsUpdate();
|
|
543
|
-
this._sendSelfMessage(
|
|
544
|
-
{
|
|
545
|
-
type: "$STORAGE_RECEIVED",
|
|
546
|
-
data: { state }
|
|
547
|
-
},
|
|
548
|
-
session
|
|
549
|
-
);
|
|
550
|
-
}));
|
|
551
|
-
}
|
|
552
|
-
_emitUserJoined(session) {
|
|
553
|
-
const user = session.user;
|
|
554
|
-
if (!user)
|
|
555
|
-
return;
|
|
556
|
-
this._broadcast({
|
|
557
|
-
message: {
|
|
558
|
-
type: "$USER_JOINED",
|
|
559
|
-
data: {
|
|
560
|
-
connectionId: session.id,
|
|
561
|
-
user
|
|
562
|
-
}
|
|
563
|
-
},
|
|
564
|
-
senderId: session.id
|
|
565
|
-
});
|
|
566
|
-
}
|
|
567
454
|
_getAuthorizedUser(token) {
|
|
568
455
|
return __async(this, null, function* () {
|
|
569
456
|
var _a;
|
|
@@ -602,6 +489,19 @@ var IORoom = class {
|
|
|
602
489
|
var _a;
|
|
603
490
|
return (_a = this._events[message.type]) != null ? _a : null;
|
|
604
491
|
}
|
|
492
|
+
_getEventInputs(message) {
|
|
493
|
+
const eventConfig = this._getEventConfig(message);
|
|
494
|
+
if (!eventConfig)
|
|
495
|
+
return message.data;
|
|
496
|
+
return eventConfig.input ? eventConfig.input.parse(message.data) : message.data;
|
|
497
|
+
}
|
|
498
|
+
_getEventResolverObject(message) {
|
|
499
|
+
const eventConfig = this._getEventConfig(message);
|
|
500
|
+
if (!eventConfig)
|
|
501
|
+
return {};
|
|
502
|
+
const resolver = eventConfig.resolver;
|
|
503
|
+
return typeof resolver === "function" ? { broadcast: resolver } : __spreadValues({}, resolver);
|
|
504
|
+
}
|
|
605
505
|
_initialize() {
|
|
606
506
|
return __async(this, null, function* () {
|
|
607
507
|
this._logDebug(`${import_kleur.default.blue(`Initializing room ${this.id}:`)}`);
|
|
@@ -626,12 +526,112 @@ var IORoom = class {
|
|
|
626
526
|
this._doc.destroy();
|
|
627
527
|
this._doc = (0, import_crdt_yjs.doc)();
|
|
628
528
|
this._listeners.onDestroy(encodedState);
|
|
529
|
+
this._uninitialize = null;
|
|
629
530
|
});
|
|
630
531
|
});
|
|
631
532
|
}
|
|
632
533
|
_logDebug(...data) {
|
|
633
534
|
this._debug && console.log(...data);
|
|
634
535
|
}
|
|
536
|
+
_onClose(session, callback) {
|
|
537
|
+
return () => {
|
|
538
|
+
if (!this._uninitialize)
|
|
539
|
+
return;
|
|
540
|
+
session.quit = true;
|
|
541
|
+
this._logDebug(
|
|
542
|
+
`${import_kleur.default.blue(
|
|
543
|
+
`(Unregistering connection for room ${this.id}:`
|
|
544
|
+
)} ${session.id}`
|
|
545
|
+
);
|
|
546
|
+
this._sessions.delete(session.id);
|
|
547
|
+
this._platform.persistance.deleteUser(this.id, session.id).finally(() => {
|
|
548
|
+
var _a;
|
|
549
|
+
this._broadcast({
|
|
550
|
+
message: {
|
|
551
|
+
type: "$EXIT",
|
|
552
|
+
data: { sessionId: session.id }
|
|
553
|
+
},
|
|
554
|
+
senderId: session.id
|
|
555
|
+
});
|
|
556
|
+
callback == null ? void 0 : callback();
|
|
557
|
+
const size = this.getSize();
|
|
558
|
+
this._logDebug(
|
|
559
|
+
`${import_kleur.default.blue(
|
|
560
|
+
`Unregistered connection for room ${this.id}:`
|
|
561
|
+
)} ${session.id}`
|
|
562
|
+
);
|
|
563
|
+
this._logDebug(
|
|
564
|
+
`${import_kleur.default.blue(`Room ${this.id} size:`)} ${size}`
|
|
565
|
+
);
|
|
566
|
+
if (size)
|
|
567
|
+
return;
|
|
568
|
+
(_a = this._uninitialize) == null ? void 0 : _a.call(this);
|
|
569
|
+
});
|
|
570
|
+
};
|
|
571
|
+
}
|
|
572
|
+
_onMessage(session) {
|
|
573
|
+
return (event) => {
|
|
574
|
+
var _a, _b, _c;
|
|
575
|
+
const context = {
|
|
576
|
+
context: this._context,
|
|
577
|
+
doc: this._doc,
|
|
578
|
+
room: this.id,
|
|
579
|
+
session,
|
|
580
|
+
sessions: this._sessions
|
|
581
|
+
};
|
|
582
|
+
if (!this._uninitialize)
|
|
583
|
+
return;
|
|
584
|
+
if (session.quit) {
|
|
585
|
+
session.webSocket.close(1011, "WebSocket broken.");
|
|
586
|
+
return;
|
|
587
|
+
}
|
|
588
|
+
const message = this._parseMessage(event);
|
|
589
|
+
if (!message)
|
|
590
|
+
return;
|
|
591
|
+
const resolver = this._getEventResolverObject(message);
|
|
592
|
+
let inputs;
|
|
593
|
+
try {
|
|
594
|
+
inputs = this._getEventInputs(message);
|
|
595
|
+
} catch (error) {
|
|
596
|
+
session == null ? void 0 : session.webSocket.handleError({
|
|
597
|
+
error,
|
|
598
|
+
message: "Invalid input",
|
|
599
|
+
session
|
|
600
|
+
});
|
|
601
|
+
return;
|
|
602
|
+
}
|
|
603
|
+
Promise.all([
|
|
604
|
+
(_a = resolver.broadcast) == null ? void 0 : _a.call(resolver, inputs, context),
|
|
605
|
+
(_b = resolver.self) == null ? void 0 : _b.call(resolver, inputs, context),
|
|
606
|
+
(_c = resolver.sync) == null ? void 0 : _c.call(resolver, inputs, context)
|
|
607
|
+
]).then(([broadcast, self, sync]) => {
|
|
608
|
+
if (broadcast) {
|
|
609
|
+
Object.entries(broadcast).forEach(([type, data]) => {
|
|
610
|
+
this._broadcast({
|
|
611
|
+
message: { data, type },
|
|
612
|
+
senderId: session.id
|
|
613
|
+
});
|
|
614
|
+
});
|
|
615
|
+
}
|
|
616
|
+
if (self) {
|
|
617
|
+
Object.entries(self).forEach(([type, data]) => {
|
|
618
|
+
this._sendSelfMessage({ data, type }, session);
|
|
619
|
+
});
|
|
620
|
+
}
|
|
621
|
+
if (sync) {
|
|
622
|
+
this._platform.pubSub.publish(this.id, __spreadValues({
|
|
623
|
+
connectionId: session.id,
|
|
624
|
+
options: { type: "sync" },
|
|
625
|
+
room: this.id,
|
|
626
|
+
user: session.user
|
|
627
|
+
}, message));
|
|
628
|
+
Object.entries(sync).forEach(([type, data]) => {
|
|
629
|
+
this._sendSelfMessage({ data, type }, session);
|
|
630
|
+
});
|
|
631
|
+
}
|
|
632
|
+
});
|
|
633
|
+
};
|
|
634
|
+
}
|
|
635
635
|
_parseMessage(message) {
|
|
636
636
|
const parsed = this._platform.parseData(message.data);
|
|
637
637
|
try {
|
|
@@ -646,29 +646,6 @@ var IORoom = class {
|
|
|
646
646
|
return null;
|
|
647
647
|
}
|
|
648
648
|
}
|
|
649
|
-
_resolveMessage(message, context) {
|
|
650
|
-
return __async(this, null, function* () {
|
|
651
|
-
const { session } = context;
|
|
652
|
-
const eventConfig = this._getEventConfig(message);
|
|
653
|
-
if (!eventConfig)
|
|
654
|
-
return null;
|
|
655
|
-
let input;
|
|
656
|
-
try {
|
|
657
|
-
input = eventConfig.input ? eventConfig.input.parse(message.data) : message.data;
|
|
658
|
-
} catch (error) {
|
|
659
|
-
session == null ? void 0 : session.webSocket.handleError({
|
|
660
|
-
error,
|
|
661
|
-
message: "Invalid input",
|
|
662
|
-
session
|
|
663
|
-
});
|
|
664
|
-
return null;
|
|
665
|
-
}
|
|
666
|
-
const output = yield eventConfig.resolver(input, context);
|
|
667
|
-
if (!output)
|
|
668
|
-
return null;
|
|
669
|
-
return output;
|
|
670
|
-
});
|
|
671
|
-
}
|
|
672
649
|
_sendMessage(message, sender, options = {}) {
|
|
673
650
|
switch (options.type) {
|
|
674
651
|
case "self": {
|
|
@@ -718,13 +695,23 @@ var IORoom = class {
|
|
|
718
695
|
const senderId = sender == null ? void 0 : sender.id;
|
|
719
696
|
if (!senderId)
|
|
720
697
|
return;
|
|
721
|
-
|
|
698
|
+
const context = {
|
|
722
699
|
context: this._context,
|
|
723
700
|
doc: this._doc,
|
|
724
701
|
room: this.id,
|
|
725
702
|
session: null,
|
|
726
703
|
sessions: this._sessions
|
|
727
|
-
}
|
|
704
|
+
};
|
|
705
|
+
const resolver = this._getEventResolverObject(message).sync;
|
|
706
|
+
if (!resolver)
|
|
707
|
+
return;
|
|
708
|
+
let inputs;
|
|
709
|
+
try {
|
|
710
|
+
inputs = this._getEventInputs(message);
|
|
711
|
+
} catch (e) {
|
|
712
|
+
return;
|
|
713
|
+
}
|
|
714
|
+
Promise.resolve(resolver(inputs, context)).then((output) => {
|
|
728
715
|
if (!output)
|
|
729
716
|
return;
|
|
730
717
|
Object.keys(output).forEach((type) => {
|
|
@@ -751,32 +738,70 @@ var PluvIO = class {
|
|
|
751
738
|
this._rooms = /* @__PURE__ */ new Map();
|
|
752
739
|
this._authorize = null;
|
|
753
740
|
this._events = {
|
|
754
|
-
$PING: {
|
|
755
|
-
resolver: (data, { session }) => {
|
|
756
|
-
if (!session)
|
|
757
|
-
return {};
|
|
758
|
-
const currentTime = (/* @__PURE__ */ new Date()).getTime();
|
|
759
|
-
session.timers.ping = currentTime;
|
|
760
|
-
return { $PONG: {} };
|
|
761
|
-
},
|
|
762
|
-
options: { type: "self" }
|
|
763
|
-
},
|
|
764
741
|
$GET_OTHERS: {
|
|
765
|
-
resolver:
|
|
766
|
-
|
|
767
|
-
|
|
768
|
-
[connectionId]
|
|
769
|
-
connectionId
|
|
770
|
-
|
|
771
|
-
|
|
772
|
-
|
|
742
|
+
resolver: {
|
|
743
|
+
sync: (data, { room, session, sessions }) => {
|
|
744
|
+
const others = Array.from(sessions.entries()).filter(([, wsSession]) => wsSession.id !== (session == null ? void 0 : session.id)).reduce(
|
|
745
|
+
(acc, [connectionId, { presence, user }]) => __spreadProps(__spreadValues({}, acc), {
|
|
746
|
+
[connectionId]: {
|
|
747
|
+
connectionId,
|
|
748
|
+
presence,
|
|
749
|
+
room,
|
|
750
|
+
user
|
|
751
|
+
}
|
|
752
|
+
}),
|
|
753
|
+
{}
|
|
754
|
+
);
|
|
755
|
+
return { $OTHERS_RECEIVED: { others } };
|
|
756
|
+
}
|
|
757
|
+
}
|
|
758
|
+
},
|
|
759
|
+
$INITIALIZE_SESSION: {
|
|
760
|
+
resolver: {
|
|
761
|
+
broadcast: ({ presence }, { session }) => {
|
|
762
|
+
if (!session)
|
|
763
|
+
return {};
|
|
764
|
+
session.presence = presence;
|
|
765
|
+
return {
|
|
766
|
+
$USER_JOINED: {
|
|
767
|
+
connectionId: session.id,
|
|
768
|
+
user: session.user,
|
|
769
|
+
presence
|
|
773
770
|
}
|
|
774
|
-
}
|
|
775
|
-
|
|
776
|
-
)
|
|
777
|
-
|
|
778
|
-
|
|
779
|
-
|
|
771
|
+
};
|
|
772
|
+
},
|
|
773
|
+
self: (_0, _1) => __async(this, [_0, _1], function* ({ update }, { doc: doc2, room }) {
|
|
774
|
+
var _a, _b;
|
|
775
|
+
const oldState = yield this._platform.persistance.getStorageState(room);
|
|
776
|
+
const updates = [
|
|
777
|
+
oldState ? null : yield (_a = this._initialStorage) == null ? void 0 : _a.call(this, room),
|
|
778
|
+
update
|
|
779
|
+
];
|
|
780
|
+
if (updates.some((_update) => !!_update)) {
|
|
781
|
+
const state2 = updates.reduce((_doc, _up) => _doc.applyUpdate(_up), doc2).encodeStateAsUpdate();
|
|
782
|
+
yield this._platform.persistance.setStorageState(
|
|
783
|
+
room,
|
|
784
|
+
state2
|
|
785
|
+
);
|
|
786
|
+
this._listeners.onStorageUpdated(room, state2);
|
|
787
|
+
}
|
|
788
|
+
const state = (_b = yield this._platform.persistance.getStorageState(
|
|
789
|
+
room
|
|
790
|
+
)) != null ? _b : doc2.encodeStateAsUpdate();
|
|
791
|
+
return { $STORAGE_RECEIVED: { state } };
|
|
792
|
+
})
|
|
793
|
+
}
|
|
794
|
+
},
|
|
795
|
+
$PING: {
|
|
796
|
+
resolver: {
|
|
797
|
+
self: (data, { session }) => {
|
|
798
|
+
if (!session)
|
|
799
|
+
return {};
|
|
800
|
+
const currentTime = (/* @__PURE__ */ new Date()).getTime();
|
|
801
|
+
session.timers.ping = currentTime;
|
|
802
|
+
return { $PONG: {} };
|
|
803
|
+
}
|
|
804
|
+
}
|
|
780
805
|
},
|
|
781
806
|
$UPDATE_PRESENCE: {
|
|
782
807
|
resolver: ({ presence }, { session }) => {
|
|
@@ -886,6 +911,7 @@ var PluvIO = class {
|
|
|
886
911
|
`${import_kleur2.default.blue("Deleting empty room:")} ${room}`
|
|
887
912
|
);
|
|
888
913
|
this._rooms.delete(room);
|
|
914
|
+
this._listeners.onRoomDeleted(room, encodedState);
|
|
889
915
|
if (this._debug) {
|
|
890
916
|
const rooms = Array.from(this._rooms.keys());
|
|
891
917
|
this._logDebug(`${import_kleur2.default.blue("Deleted room:")} ${room}`);
|
|
@@ -893,11 +919,6 @@ var PluvIO = class {
|
|
|
893
919
|
`${import_kleur2.default.blue("Rooms available:")} ${rooms.join(", ")}`
|
|
894
920
|
);
|
|
895
921
|
}
|
|
896
|
-
this._platform.persistance.getSize(room).then((size) => {
|
|
897
|
-
if (size)
|
|
898
|
-
return;
|
|
899
|
-
this._listeners.onRoomDeleted(room, encodedState);
|
|
900
|
-
});
|
|
901
922
|
},
|
|
902
923
|
platform
|
|
903
924
|
});
|