@pluv/io 0.17.2 → 0.18.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.turbo/turbo-build.log +9 -9
- package/CHANGELOG.md +136 -0
- package/dist/index.d.mts +121 -57
- package/dist/index.d.ts +121 -57
- package/dist/index.js +300 -284
- package/dist/index.mjs +297 -284
- package/package.json +6 -6
- package/src/AbstractPersistance.ts +4 -16
- package/src/AbstractPlatform.ts +4 -14
- package/src/AbstractPubSub.ts +1 -4
- package/src/AbstractWebSocket.ts +6 -21
- package/src/IORoom.ts +117 -270
- package/src/Persistance.ts +3 -11
- package/src/PluvIO.ts +156 -473
- package/src/PluvProcedure.ts +203 -0
- package/src/PluvRouter.ts +46 -0
- package/src/PluvServer.ts +182 -0
- package/src/PubSub.ts +6 -18
- package/src/authorize.ts +5 -22
- package/src/createIO.ts +10 -49
- package/src/index.ts +9 -13
- package/src/types.ts +49 -101
- package/src/version.generated.ts +1 -1
package/dist/index.js
CHANGED
|
@@ -84,6 +84,9 @@ __export(src_exports, {
|
|
|
84
84
|
AbstractPubSub: () => AbstractPubSub,
|
|
85
85
|
AbstractWebSocket: () => AbstractWebSocket,
|
|
86
86
|
PluvIO: () => PluvIO,
|
|
87
|
+
PluvProcedure: () => PluvProcedure,
|
|
88
|
+
PluvRouter: () => PluvRouter,
|
|
89
|
+
PluvServer: () => PluvServer,
|
|
87
90
|
createIO: () => createIO
|
|
88
91
|
});
|
|
89
92
|
module.exports = __toCommonJS(src_exports);
|
|
@@ -241,11 +244,7 @@ var AbstractWebSocket = class {
|
|
|
241
244
|
}
|
|
242
245
|
handleError(params) {
|
|
243
246
|
var _a, _b, _c;
|
|
244
|
-
const {
|
|
245
|
-
error,
|
|
246
|
-
message = error instanceof Error ? error.message : "Unexpected error",
|
|
247
|
-
session
|
|
248
|
-
} = params;
|
|
247
|
+
const { error, message = error instanceof Error ? error.message : "Unexpected error", session } = params;
|
|
249
248
|
const stack = error instanceof Error ? (_a = error.stack) != null ? _a : null : null;
|
|
250
249
|
return this.sendMessage({
|
|
251
250
|
connectionId: (_b = session == null ? void 0 : session.id) != null ? _b : null,
|
|
@@ -261,6 +260,79 @@ var AbstractWebSocket = class {
|
|
|
261
260
|
};
|
|
262
261
|
|
|
263
262
|
// src/PluvIO.ts
|
|
263
|
+
var import_crdt3 = require("@pluv/crdt");
|
|
264
|
+
|
|
265
|
+
// src/PluvProcedure.ts
|
|
266
|
+
var PluvProcedure = class _PluvProcedure {
|
|
267
|
+
constructor(config = {}) {
|
|
268
|
+
this._broadcast = null;
|
|
269
|
+
this._input = null;
|
|
270
|
+
this._self = null;
|
|
271
|
+
this._sync = null;
|
|
272
|
+
const { broadcast, input, self, sync } = config;
|
|
273
|
+
this._broadcast = broadcast != null ? broadcast : null;
|
|
274
|
+
this._input = input != null ? input : null;
|
|
275
|
+
this._self = self != null ? self : null;
|
|
276
|
+
this._sync = sync != null ? sync : null;
|
|
277
|
+
}
|
|
278
|
+
get config() {
|
|
279
|
+
var _a, _b, _c, _d, _e, _f, _g;
|
|
280
|
+
return {
|
|
281
|
+
broadcast: (_b = (_a = this._broadcast) == null ? void 0 : _a.bind(this)) != null ? _b : null,
|
|
282
|
+
input: (_c = this._input) != null ? _c : null,
|
|
283
|
+
resolver: this._resolver,
|
|
284
|
+
self: (_e = (_d = this._self) == null ? void 0 : _d.bind(this)) != null ? _e : null,
|
|
285
|
+
sync: (_g = (_f = this._sync) == null ? void 0 : _f.bind(this)) != null ? _g : null
|
|
286
|
+
};
|
|
287
|
+
}
|
|
288
|
+
broadcast(resolver) {
|
|
289
|
+
const { broadcast } = this.config;
|
|
290
|
+
if (!!broadcast)
|
|
291
|
+
throw new Error("Broadcast was already defined for this procedure");
|
|
292
|
+
return new _PluvProcedure(__spreadProps(__spreadValues({}, this.config), {
|
|
293
|
+
broadcast: resolver
|
|
294
|
+
}));
|
|
295
|
+
}
|
|
296
|
+
input(input) {
|
|
297
|
+
return new _PluvProcedure({ input });
|
|
298
|
+
}
|
|
299
|
+
self(resolver) {
|
|
300
|
+
const { self } = this.config;
|
|
301
|
+
if (!!self)
|
|
302
|
+
throw new Error("Self was already defined for this procedure");
|
|
303
|
+
return new _PluvProcedure(__spreadProps(__spreadValues({}, this.config), {
|
|
304
|
+
self: resolver
|
|
305
|
+
}));
|
|
306
|
+
}
|
|
307
|
+
sync(resolver) {
|
|
308
|
+
const { sync } = this.config;
|
|
309
|
+
if (!!sync)
|
|
310
|
+
throw new Error("Sync was already defined for this procedure");
|
|
311
|
+
return new _PluvProcedure(__spreadProps(__spreadValues({}, this.config), {
|
|
312
|
+
sync: resolver
|
|
313
|
+
}));
|
|
314
|
+
}
|
|
315
|
+
_resolver() {
|
|
316
|
+
return (data, context) => {
|
|
317
|
+
var _a, _b, _c;
|
|
318
|
+
return __spreadValues(__spreadValues(__spreadValues({}, (_a = this._broadcast) == null ? void 0 : _a.call(this, data, context)), (_b = this._self) == null ? void 0 : _b.call(this, data, context)), (_c = this._sync) == null ? void 0 : _c.call(this, data, context));
|
|
319
|
+
};
|
|
320
|
+
}
|
|
321
|
+
};
|
|
322
|
+
|
|
323
|
+
// src/PluvRouter.ts
|
|
324
|
+
var PluvRouter = class _PluvRouter {
|
|
325
|
+
constructor(events) {
|
|
326
|
+
this._events = {};
|
|
327
|
+
this._events = events;
|
|
328
|
+
}
|
|
329
|
+
static merge(...routers) {
|
|
330
|
+
const events = Object.assign(/* @__PURE__ */ Object.create(null), ...routers.map((router) => router._events));
|
|
331
|
+
return new _PluvRouter(events);
|
|
332
|
+
}
|
|
333
|
+
};
|
|
334
|
+
|
|
335
|
+
// src/PluvServer.ts
|
|
264
336
|
var import_crdt2 = require("@pluv/crdt");
|
|
265
337
|
var import_kleur2 = __toESM(require("kleur"));
|
|
266
338
|
|
|
@@ -273,13 +345,7 @@ var import_hkdf = __toESM(require("@panva/hkdf"));
|
|
|
273
345
|
var import_jose = require("jose");
|
|
274
346
|
var DEFAULT_MAX_AGE_MS = 6e4;
|
|
275
347
|
var getEncryptionKey = (secret) => __async(void 0, null, function* () {
|
|
276
|
-
return yield (0, import_hkdf.default)(
|
|
277
|
-
"sha256",
|
|
278
|
-
secret,
|
|
279
|
-
"",
|
|
280
|
-
"Pluv.io Generated Encryption Key",
|
|
281
|
-
32
|
|
282
|
-
);
|
|
348
|
+
return yield (0, import_hkdf.default)("sha256", secret, "", "Pluv.io Generated Encryption Key", 32);
|
|
283
349
|
});
|
|
284
350
|
var now = () => Date.now() / 1e3 | 0;
|
|
285
351
|
var authorize = (params) => {
|
|
@@ -311,20 +377,12 @@ var IORoom = class {
|
|
|
311
377
|
this._sessions = /* @__PURE__ */ new Map();
|
|
312
378
|
this._uninitialize = null;
|
|
313
379
|
this._authorize = null;
|
|
314
|
-
const {
|
|
315
|
-
authorize: authorize2,
|
|
316
|
-
context,
|
|
317
|
-
crdt = import_crdt.noop,
|
|
318
|
-
debug,
|
|
319
|
-
events,
|
|
320
|
-
onDestroy,
|
|
321
|
-
platform
|
|
322
|
-
} = config;
|
|
380
|
+
const { authorize: authorize2, context, crdt = import_crdt.noop, debug, onDestroy, platform, router } = config;
|
|
323
381
|
this._context = context;
|
|
324
382
|
this._debug = debug;
|
|
325
383
|
this._docFactory = crdt.doc(() => ({}));
|
|
326
384
|
this._doc = this._docFactory.getEmpty();
|
|
327
|
-
this.
|
|
385
|
+
this._router = router;
|
|
328
386
|
this._platform = platform;
|
|
329
387
|
this.id = id;
|
|
330
388
|
this._listeners = {
|
|
@@ -333,9 +391,19 @@ var IORoom = class {
|
|
|
333
391
|
if (authorize2)
|
|
334
392
|
this._authorize = authorize2;
|
|
335
393
|
}
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
394
|
+
get _events() {
|
|
395
|
+
return this._router._events;
|
|
396
|
+
}
|
|
397
|
+
get broadcast() {
|
|
398
|
+
const _broadcast = (event, data) => {
|
|
399
|
+
const message = { type: event, data };
|
|
400
|
+
return Promise.resolve(this._broadcast({ message }));
|
|
401
|
+
};
|
|
402
|
+
return new Proxy(_broadcast, {
|
|
403
|
+
get(fn, prop) {
|
|
404
|
+
return (data) => fn(prop, data);
|
|
405
|
+
}
|
|
406
|
+
});
|
|
339
407
|
}
|
|
340
408
|
getSize() {
|
|
341
409
|
const currentTime = (/* @__PURE__ */ new Date()).getTime();
|
|
@@ -359,26 +427,16 @@ var IORoom = class {
|
|
|
359
427
|
sessionId,
|
|
360
428
|
userId: (_b = user == null ? void 0 : user.id) != null ? _b : null
|
|
361
429
|
});
|
|
362
|
-
this._logDebug(
|
|
363
|
-
`${import_kleur.default.blue(
|
|
364
|
-
`Registering connection for room ${this.id}:`
|
|
365
|
-
)} ${sessionId}`
|
|
366
|
-
);
|
|
430
|
+
this._logDebug(`${import_kleur.default.blue(`Registering connection for room ${this.id}:`)} ${sessionId}`);
|
|
367
431
|
const uninitializeWs = yield pluvWs.initialize();
|
|
368
432
|
const ioAuthorize = this._getIOAuthorize(options);
|
|
369
433
|
const isUnauthorized = !!(ioAuthorize == null ? void 0 : ioAuthorize.required) && !user;
|
|
370
|
-
const isTokenInUse = !!user && Array.from(this._sessions.values()).some(
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
}
|
|
375
|
-
);
|
|
434
|
+
const isTokenInUse = !!user && Array.from(this._sessions.values()).some((session2) => {
|
|
435
|
+
var _a2;
|
|
436
|
+
return ((_a2 = session2.user) == null ? void 0 : _a2.id) === user.id;
|
|
437
|
+
});
|
|
376
438
|
if (isUnauthorized || isTokenInUse) {
|
|
377
|
-
this._logDebug(
|
|
378
|
-
`${import_kleur.default.blue(
|
|
379
|
-
"Authorization failed for connection:"
|
|
380
|
-
)} ${sessionId}`
|
|
381
|
-
);
|
|
439
|
+
this._logDebug(`${import_kleur.default.blue("Authorization failed for connection:")} ${sessionId}`);
|
|
382
440
|
pluvWs.handleError({ error: new Error("Not authorized") });
|
|
383
441
|
pluvWs.close(3e3, "WebSocket unauthorized.");
|
|
384
442
|
return;
|
|
@@ -396,24 +454,14 @@ var IORoom = class {
|
|
|
396
454
|
user
|
|
397
455
|
};
|
|
398
456
|
this._sessions.set(session.id, session);
|
|
399
|
-
yield this._platform.persistance.addUser(
|
|
400
|
-
this.id,
|
|
401
|
-
sessionId,
|
|
402
|
-
user != null ? user : {}
|
|
403
|
-
);
|
|
457
|
+
yield this._platform.persistance.addUser(this.id, sessionId, user != null ? user : {});
|
|
404
458
|
const onClose = this._onClose(session, uninitializeWs).bind(this);
|
|
405
|
-
const onMessage = this._onMessage(session, platformEventContext).bind(
|
|
406
|
-
this
|
|
407
|
-
);
|
|
459
|
+
const onMessage = this._onMessage(session, platformEventContext).bind(this);
|
|
408
460
|
pluvWs.addEventListener("close", onClose);
|
|
409
461
|
pluvWs.addEventListener("error", onClose);
|
|
410
462
|
pluvWs.addEventListener("message", onMessage);
|
|
411
463
|
this._emitRegistered(session);
|
|
412
|
-
this._logDebug(
|
|
413
|
-
`${import_kleur.default.blue(
|
|
414
|
-
`Registered connection for room ${this.id}:`
|
|
415
|
-
)} ${sessionId}`
|
|
416
|
-
);
|
|
464
|
+
this._logDebug(`${import_kleur.default.blue(`Registered connection for room ${this.id}:`)} ${sessionId}`);
|
|
417
465
|
const size = this.getSize();
|
|
418
466
|
this._logDebug(`${import_kleur.default.blue(`Room ${this.id} size:`)} ${size}`);
|
|
419
467
|
});
|
|
@@ -480,9 +528,7 @@ var IORoom = class {
|
|
|
480
528
|
return null;
|
|
481
529
|
}
|
|
482
530
|
if (payload.room !== this.id) {
|
|
483
|
-
this._logDebug(
|
|
484
|
-
import_kleur.default.blue(`Token is not authorized for room ${this.id}:`)
|
|
485
|
-
);
|
|
531
|
+
this._logDebug(import_kleur.default.blue(`Token is not authorized for room ${this.id}:`));
|
|
486
532
|
this._logDebug(import_kleur.default.blue("Received:"), payload.room);
|
|
487
533
|
this._logDebug(token);
|
|
488
534
|
return null;
|
|
@@ -490,29 +536,20 @@ var IORoom = class {
|
|
|
490
536
|
try {
|
|
491
537
|
return (_a = ioAuthorize.user.parse(payload.user)) != null ? _a : null;
|
|
492
538
|
} catch (e) {
|
|
493
|
-
this._logDebug(
|
|
494
|
-
`${import_kleur.default.blue("Token fails validation:")} ${token}`
|
|
495
|
-
);
|
|
539
|
+
this._logDebug(`${import_kleur.default.blue("Token fails validation:")} ${token}`);
|
|
496
540
|
return null;
|
|
497
541
|
}
|
|
498
542
|
});
|
|
499
543
|
}
|
|
500
|
-
|
|
544
|
+
_getProcedure(message) {
|
|
501
545
|
var _a;
|
|
502
|
-
return (_a = this._events[message.type]) != null ? _a : null;
|
|
546
|
+
return (_a = this._router._events[message.type]) != null ? _a : null;
|
|
503
547
|
}
|
|
504
|
-
|
|
505
|
-
const
|
|
506
|
-
if (!
|
|
548
|
+
_getProcedureInputs(message) {
|
|
549
|
+
const procedure = this._getProcedure(message);
|
|
550
|
+
if (!procedure)
|
|
507
551
|
return message.data;
|
|
508
|
-
return
|
|
509
|
-
}
|
|
510
|
-
_getEventResolverObject(message) {
|
|
511
|
-
const eventConfig = this._getEventConfig(message);
|
|
512
|
-
if (!eventConfig)
|
|
513
|
-
return {};
|
|
514
|
-
const resolver = eventConfig.resolver;
|
|
515
|
-
return typeof resolver === "function" ? { broadcast: resolver } : __spreadValues({}, resolver);
|
|
552
|
+
return procedure.config.input ? procedure.config.input.parse(message.data) : message.data;
|
|
516
553
|
}
|
|
517
554
|
_initialize() {
|
|
518
555
|
return __async(this, null, function* () {
|
|
@@ -521,17 +558,14 @@ var IORoom = class {
|
|
|
521
558
|
yield this._uninitialize();
|
|
522
559
|
this._uninitialize = null;
|
|
523
560
|
}
|
|
524
|
-
const pubSubId = yield this._platform.pubSub.subscribe(
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
this._sendMessage(message, session, options);
|
|
533
|
-
}
|
|
534
|
-
);
|
|
561
|
+
const pubSubId = yield this._platform.pubSub.subscribe(this.id, (_a) => {
|
|
562
|
+
var _b = _a, { options = {} } = _b, message = __objRest(_b, ["options"]);
|
|
563
|
+
const session = {
|
|
564
|
+
id: message.connectionId,
|
|
565
|
+
user: message.user
|
|
566
|
+
};
|
|
567
|
+
this._sendMessage(message, session, options);
|
|
568
|
+
});
|
|
535
569
|
this._uninitialize = () => __async(this, null, function* () {
|
|
536
570
|
this._platform.pubSub.unsubscribe(pubSubId);
|
|
537
571
|
const encodedState = this._doc.getEncodedState();
|
|
@@ -553,11 +587,7 @@ var IORoom = class {
|
|
|
553
587
|
if (!this._uninitialize)
|
|
554
588
|
return;
|
|
555
589
|
session.quit = true;
|
|
556
|
-
this._logDebug(
|
|
557
|
-
`${import_kleur.default.blue(
|
|
558
|
-
`(Unregistering connection for room ${this.id}:`
|
|
559
|
-
)} ${session.id}`
|
|
560
|
-
);
|
|
590
|
+
this._logDebug(`${import_kleur.default.blue(`(Unregistering connection for room ${this.id}:`)} ${session.id}`);
|
|
561
591
|
this._sessions.delete(session.id);
|
|
562
592
|
this._platform.persistance.deleteUser(this.id, session.id).finally(() => {
|
|
563
593
|
var _a;
|
|
@@ -570,14 +600,8 @@ var IORoom = class {
|
|
|
570
600
|
});
|
|
571
601
|
callback == null ? void 0 : callback();
|
|
572
602
|
const size = this.getSize();
|
|
573
|
-
this._logDebug(
|
|
574
|
-
|
|
575
|
-
`Unregistered connection for room ${this.id}:`
|
|
576
|
-
)} ${session.id}`
|
|
577
|
-
);
|
|
578
|
-
this._logDebug(
|
|
579
|
-
`${import_kleur.default.blue(`Room ${this.id} size:`)} ${size}`
|
|
580
|
-
);
|
|
603
|
+
this._logDebug(`${import_kleur.default.blue(`Unregistered connection for room ${this.id}:`)} ${session.id}`);
|
|
604
|
+
this._logDebug(`${import_kleur.default.blue(`Room ${this.id} size:`)} ${size}`);
|
|
581
605
|
if (size)
|
|
582
606
|
return;
|
|
583
607
|
(_a = this._uninitialize) == null ? void 0 : _a.call(this);
|
|
@@ -586,7 +610,7 @@ var IORoom = class {
|
|
|
586
610
|
}
|
|
587
611
|
_onMessage(session, platformEventContext) {
|
|
588
612
|
return (event) => {
|
|
589
|
-
var _a, _b, _c;
|
|
613
|
+
var _a, _b, _c, _d, _e, _f;
|
|
590
614
|
const baseContext = {
|
|
591
615
|
context: this._context,
|
|
592
616
|
doc: this._doc,
|
|
@@ -603,10 +627,12 @@ var IORoom = class {
|
|
|
603
627
|
const message = this._parseMessage(event);
|
|
604
628
|
if (!message)
|
|
605
629
|
return;
|
|
606
|
-
const
|
|
630
|
+
const procedure = this._getProcedure(message);
|
|
631
|
+
if (!procedure)
|
|
632
|
+
return;
|
|
607
633
|
let inputs;
|
|
608
634
|
try {
|
|
609
|
-
inputs = this.
|
|
635
|
+
inputs = this._getProcedureInputs(message);
|
|
610
636
|
} catch (error) {
|
|
611
637
|
session == null ? void 0 : session.webSocket.handleError({
|
|
612
638
|
error,
|
|
@@ -619,9 +645,9 @@ var IORoom = class {
|
|
|
619
645
|
context: __spreadValues(__spreadValues({}, this._context), platformEventContext)
|
|
620
646
|
});
|
|
621
647
|
Promise.all([
|
|
622
|
-
(_a =
|
|
623
|
-
(
|
|
624
|
-
(
|
|
648
|
+
(_b = (_a = procedure.config).broadcast) == null ? void 0 : _b.call(_a, inputs, extendedContext),
|
|
649
|
+
(_d = (_c = procedure.config).self) == null ? void 0 : _d.call(_c, inputs, extendedContext),
|
|
650
|
+
(_f = (_e = procedure.config).sync) == null ? void 0 : _f.call(_e, inputs, baseContext)
|
|
625
651
|
]).then(([broadcast, self, sync]) => {
|
|
626
652
|
if (broadcast) {
|
|
627
653
|
Object.entries(broadcast).forEach(([type, data]) => {
|
|
@@ -710,6 +736,7 @@ var IORoom = class {
|
|
|
710
736
|
}, message));
|
|
711
737
|
}
|
|
712
738
|
_sendSyncMessage(message, sender) {
|
|
739
|
+
var _a;
|
|
713
740
|
const senderId = sender == null ? void 0 : sender.id;
|
|
714
741
|
if (!senderId)
|
|
715
742
|
return;
|
|
@@ -720,12 +747,12 @@ var IORoom = class {
|
|
|
720
747
|
session: null,
|
|
721
748
|
sessions: this._sessions
|
|
722
749
|
};
|
|
723
|
-
const resolver = this.
|
|
750
|
+
const resolver = (_a = this._getProcedure(message)) == null ? void 0 : _a.config.sync;
|
|
724
751
|
if (!resolver)
|
|
725
752
|
return;
|
|
726
753
|
let inputs;
|
|
727
754
|
try {
|
|
728
|
-
inputs = this.
|
|
755
|
+
inputs = this._getProcedureInputs(message);
|
|
729
756
|
} catch (e) {
|
|
730
757
|
return;
|
|
731
758
|
}
|
|
@@ -733,8 +760,8 @@ var IORoom = class {
|
|
|
733
760
|
if (!output)
|
|
734
761
|
return;
|
|
735
762
|
Object.keys(output).forEach((type) => {
|
|
736
|
-
var
|
|
737
|
-
const data = (
|
|
763
|
+
var _a2, _b;
|
|
764
|
+
const data = (_a2 = output[type]) != null ? _a2 : {};
|
|
738
765
|
this._platform.pubSub.publish(this.id, {
|
|
739
766
|
connectionId: senderId,
|
|
740
767
|
data,
|
|
@@ -749,149 +776,45 @@ var IORoom = class {
|
|
|
749
776
|
};
|
|
750
777
|
|
|
751
778
|
// src/version.generated.ts
|
|
752
|
-
var version = "0.
|
|
779
|
+
var version = "0.18.0";
|
|
753
780
|
|
|
754
|
-
// src/
|
|
755
|
-
var
|
|
781
|
+
// src/PluvServer.ts
|
|
782
|
+
var PluvServer = class {
|
|
756
783
|
constructor(options) {
|
|
757
784
|
this._rooms = /* @__PURE__ */ new Map();
|
|
758
785
|
this._authorize = null;
|
|
759
786
|
this._context = {};
|
|
760
|
-
this._events = {
|
|
761
|
-
$GET_OTHERS: {
|
|
762
|
-
resolver: {
|
|
763
|
-
sync: (data, { room, session, sessions }) => {
|
|
764
|
-
const others = Array.from(sessions.entries()).filter(([, wsSession]) => wsSession.id !== (session == null ? void 0 : session.id)).reduce(
|
|
765
|
-
(acc, [connectionId, { presence, user }]) => __spreadProps(__spreadValues({}, acc), {
|
|
766
|
-
[connectionId]: {
|
|
767
|
-
connectionId,
|
|
768
|
-
presence,
|
|
769
|
-
room,
|
|
770
|
-
user
|
|
771
|
-
}
|
|
772
|
-
}),
|
|
773
|
-
{}
|
|
774
|
-
);
|
|
775
|
-
return { $OTHERS_RECEIVED: { others } };
|
|
776
|
-
}
|
|
777
|
-
}
|
|
778
|
-
},
|
|
779
|
-
$INITIALIZE_SESSION: {
|
|
780
|
-
resolver: {
|
|
781
|
-
broadcast: ({ presence }, { session }) => {
|
|
782
|
-
if (!session)
|
|
783
|
-
return {};
|
|
784
|
-
session.presence = presence;
|
|
785
|
-
return {
|
|
786
|
-
$USER_JOINED: {
|
|
787
|
-
connectionId: session.id,
|
|
788
|
-
user: session.user,
|
|
789
|
-
presence
|
|
790
|
-
}
|
|
791
|
-
};
|
|
792
|
-
},
|
|
793
|
-
self: (_0, _1) => __async(this, [_0, _1], function* ({ update }, { context, doc, room }) {
|
|
794
|
-
var _a, _b;
|
|
795
|
-
const oldState = yield this._platform.persistance.getStorageState(room);
|
|
796
|
-
const updates = [
|
|
797
|
-
oldState ? null : yield (_a = this._getInitialStorage) == null ? void 0 : _a.call(this, __spreadProps(__spreadValues({}, context), {
|
|
798
|
-
room
|
|
799
|
-
})),
|
|
800
|
-
update
|
|
801
|
-
];
|
|
802
|
-
if (updates.some((_update) => !!_update)) {
|
|
803
|
-
const encodedState = doc.batchApplyEncodedState(updates).getEncodedState();
|
|
804
|
-
yield this._platform.persistance.setStorageState(
|
|
805
|
-
room,
|
|
806
|
-
encodedState
|
|
807
|
-
);
|
|
808
|
-
this._listeners.onStorageUpdated(__spreadProps(__spreadValues({}, context), {
|
|
809
|
-
encodedState,
|
|
810
|
-
room
|
|
811
|
-
}));
|
|
812
|
-
}
|
|
813
|
-
const state = (_b = yield this._platform.persistance.getStorageState(
|
|
814
|
-
room
|
|
815
|
-
)) != null ? _b : doc.getEncodedState();
|
|
816
|
-
return { $STORAGE_RECEIVED: { state } };
|
|
817
|
-
})
|
|
818
|
-
}
|
|
819
|
-
},
|
|
820
|
-
$PING: {
|
|
821
|
-
resolver: {
|
|
822
|
-
self: (data, { session }) => {
|
|
823
|
-
if (!session)
|
|
824
|
-
return {};
|
|
825
|
-
const currentTime = (/* @__PURE__ */ new Date()).getTime();
|
|
826
|
-
session.timers.ping = currentTime;
|
|
827
|
-
return { $PONG: {} };
|
|
828
|
-
}
|
|
829
|
-
}
|
|
830
|
-
},
|
|
831
|
-
$UPDATE_PRESENCE: {
|
|
832
|
-
resolver: ({ presence }, { session }) => {
|
|
833
|
-
if (!session)
|
|
834
|
-
return {};
|
|
835
|
-
session.presence = Object.assign(
|
|
836
|
-
/* @__PURE__ */ Object.create(null),
|
|
837
|
-
session.presence,
|
|
838
|
-
presence
|
|
839
|
-
);
|
|
840
|
-
return { $PRESENCE_UPDATED: { presence } };
|
|
841
|
-
}
|
|
842
|
-
},
|
|
843
|
-
$UPDATE_STORAGE: {
|
|
844
|
-
resolver: ({ origin, update }, { context, doc, room }) => {
|
|
845
|
-
if (origin === "$INITIALIZED" && Object.keys(doc.toJson()).length) {
|
|
846
|
-
return;
|
|
847
|
-
}
|
|
848
|
-
const updated = doc.applyEncodedState({ update });
|
|
849
|
-
const encodedState = updated.getEncodedState();
|
|
850
|
-
this._platform.persistance.setStorageState(room, encodedState).then(() => {
|
|
851
|
-
this._listeners.onStorageUpdated(__spreadProps(__spreadValues({}, context), {
|
|
852
|
-
encodedState,
|
|
853
|
-
room
|
|
854
|
-
}));
|
|
855
|
-
});
|
|
856
|
-
return { $STORAGE_UPDATED: { state: encodedState } };
|
|
857
|
-
}
|
|
858
|
-
}
|
|
859
|
-
};
|
|
860
|
-
this._getInitialStorage = null;
|
|
861
787
|
this._version = version;
|
|
862
788
|
const {
|
|
863
789
|
authorize: authorize2,
|
|
864
790
|
context,
|
|
865
791
|
crdt = import_crdt2.noop,
|
|
866
792
|
debug = false,
|
|
867
|
-
events,
|
|
868
|
-
getInitialStorage,
|
|
869
793
|
onRoomDeleted,
|
|
870
794
|
onStorageUpdated,
|
|
871
|
-
platform
|
|
795
|
+
platform,
|
|
796
|
+
router = new PluvRouter({})
|
|
872
797
|
} = options;
|
|
873
798
|
this._crdt = crdt;
|
|
874
799
|
this._debug = debug;
|
|
875
800
|
this._platform = platform;
|
|
801
|
+
this._router = router != null ? router : null;
|
|
876
802
|
if (authorize2)
|
|
877
803
|
this._authorize = authorize2;
|
|
878
804
|
if (context)
|
|
879
805
|
this._context = context;
|
|
880
|
-
if (events)
|
|
881
|
-
this._events = events;
|
|
882
|
-
if (getInitialStorage)
|
|
883
|
-
this._getInitialStorage = getInitialStorage;
|
|
884
806
|
this._listeners = {
|
|
885
807
|
onRoomDeleted: (event) => onRoomDeleted == null ? void 0 : onRoomDeleted(event),
|
|
886
808
|
onStorageUpdated: (event) => onStorageUpdated == null ? void 0 : onStorageUpdated(event)
|
|
887
809
|
};
|
|
888
810
|
}
|
|
811
|
+
get _events() {
|
|
812
|
+
return this._router._events;
|
|
813
|
+
}
|
|
889
814
|
createToken(params) {
|
|
890
815
|
return __async(this, null, function* () {
|
|
891
816
|
if (!this._authorize) {
|
|
892
|
-
throw new Error(
|
|
893
|
-
"IO does not specify authorize during initialization."
|
|
894
|
-
);
|
|
817
|
+
throw new Error("IO does not specify authorize during initialization.");
|
|
895
818
|
}
|
|
896
819
|
const ioAuthorize = typeof this._authorize === "function" ? this._authorize(params) : this._authorize;
|
|
897
820
|
const secret = ioAuthorize.secret;
|
|
@@ -901,22 +824,6 @@ var PluvIO = class _PluvIO {
|
|
|
901
824
|
}).encode(params);
|
|
902
825
|
});
|
|
903
826
|
}
|
|
904
|
-
event(event, config) {
|
|
905
|
-
if (event.startsWith("$")) {
|
|
906
|
-
throw new Error('Event name must not start with "$".');
|
|
907
|
-
}
|
|
908
|
-
const newEvent = {
|
|
909
|
-
[event]: config
|
|
910
|
-
};
|
|
911
|
-
return _PluvIO.merge(
|
|
912
|
-
this,
|
|
913
|
-
new _PluvIO({
|
|
914
|
-
crdt: this._crdt,
|
|
915
|
-
events: newEvent,
|
|
916
|
-
platform: this._platform
|
|
917
|
-
})
|
|
918
|
-
);
|
|
919
|
-
}
|
|
920
827
|
getRoom(room, options) {
|
|
921
828
|
var _b;
|
|
922
829
|
const _a = options, { debug } = _a, platformRoomContext = __objRest(_a, ["debug"]);
|
|
@@ -934,11 +841,8 @@ var PluvIO = class _PluvIO {
|
|
|
934
841
|
context: roomContext,
|
|
935
842
|
crdt: this._crdt,
|
|
936
843
|
debug: debug != null ? debug : this._debug,
|
|
937
|
-
events: this._events,
|
|
938
844
|
onDestroy: ({ encodedState, room: room2 }) => {
|
|
939
|
-
this._logDebug(
|
|
940
|
-
`${import_kleur2.default.blue("Deleting empty room:")} ${room2}`
|
|
941
|
-
);
|
|
845
|
+
this._logDebug(`${import_kleur2.default.blue("Deleting empty room:")} ${room2}`);
|
|
942
846
|
const roomContext2 = __spreadValues({
|
|
943
847
|
room: room2,
|
|
944
848
|
encodedState
|
|
@@ -948,49 +852,20 @@ var PluvIO = class _PluvIO {
|
|
|
948
852
|
if (this._debug) {
|
|
949
853
|
const rooms = Array.from(this._rooms.keys());
|
|
950
854
|
this._logDebug(`${import_kleur2.default.blue("Deleted room:")} ${room2}`);
|
|
951
|
-
this._logDebug(
|
|
952
|
-
`${import_kleur2.default.blue("Rooms available:")} ${rooms.join(
|
|
953
|
-
", "
|
|
954
|
-
)}`
|
|
955
|
-
);
|
|
855
|
+
this._logDebug(`${import_kleur2.default.blue("Rooms available:")} ${rooms.join(", ")}`);
|
|
956
856
|
}
|
|
957
857
|
},
|
|
958
|
-
platform
|
|
858
|
+
platform,
|
|
859
|
+
router: this._router
|
|
959
860
|
});
|
|
960
861
|
this._rooms.set(room, newRoom);
|
|
961
862
|
if (this._debug) {
|
|
962
863
|
const rooms = Array.from(this._rooms.keys());
|
|
963
864
|
this._logDebug(`${import_kleur2.default.blue("Created room:")} ${room}`);
|
|
964
|
-
this._logDebug(
|
|
965
|
-
`${import_kleur2.default.blue("Rooms available:")} ${rooms.join(", ")}`
|
|
966
|
-
);
|
|
865
|
+
this._logDebug(`${import_kleur2.default.blue("Rooms available:")} ${rooms.join(", ")}`);
|
|
967
866
|
}
|
|
968
867
|
return newRoom;
|
|
969
868
|
}
|
|
970
|
-
static merge(first, second) {
|
|
971
|
-
var _a;
|
|
972
|
-
const authorize2 = (_a = first._authorize) != null ? _a : void 0;
|
|
973
|
-
const context = first._context;
|
|
974
|
-
const crdt = first._crdt;
|
|
975
|
-
const debug = first._debug;
|
|
976
|
-
const platform = first._platform;
|
|
977
|
-
const getInitialStorage = first._getInitialStorage;
|
|
978
|
-
const events1 = first._events;
|
|
979
|
-
const events2 = second._events;
|
|
980
|
-
const { onRoomDeleted, onStorageUpdated } = first._listeners;
|
|
981
|
-
const events = Object.assign(/* @__PURE__ */ Object.create(null), events1, events2);
|
|
982
|
-
return new _PluvIO({
|
|
983
|
-
authorize: authorize2,
|
|
984
|
-
context,
|
|
985
|
-
crdt,
|
|
986
|
-
debug,
|
|
987
|
-
events,
|
|
988
|
-
getInitialStorage,
|
|
989
|
-
onRoomDeleted,
|
|
990
|
-
onStorageUpdated,
|
|
991
|
-
platform
|
|
992
|
-
});
|
|
993
|
-
}
|
|
994
869
|
_logDebug(...data) {
|
|
995
870
|
this._debug && console.log(...data);
|
|
996
871
|
}
|
|
@@ -1004,18 +879,156 @@ var PluvIO = class _PluvIO {
|
|
|
1004
879
|
}
|
|
1005
880
|
};
|
|
1006
881
|
|
|
882
|
+
// src/PluvIO.ts
|
|
883
|
+
var PluvIO = class {
|
|
884
|
+
constructor(options) {
|
|
885
|
+
this._router = new PluvRouter({
|
|
886
|
+
$GET_OTHERS: this.procedure.sync((data, { room, session, sessions }) => {
|
|
887
|
+
const others = Array.from(sessions.entries()).filter(([, wsSession]) => wsSession.id !== (session == null ? void 0 : session.id)).reduce(
|
|
888
|
+
(acc, [connectionId, { presence, user }]) => __spreadProps(__spreadValues({}, acc), {
|
|
889
|
+
[connectionId]: {
|
|
890
|
+
connectionId,
|
|
891
|
+
presence,
|
|
892
|
+
room,
|
|
893
|
+
user
|
|
894
|
+
}
|
|
895
|
+
}),
|
|
896
|
+
{}
|
|
897
|
+
);
|
|
898
|
+
return { $OTHERS_RECEIVED: { others } };
|
|
899
|
+
}),
|
|
900
|
+
$INITIALIZE_SESSION: this.procedure.broadcast((data, { session }) => {
|
|
901
|
+
const presence = data == null ? void 0 : data.presence;
|
|
902
|
+
if (!session)
|
|
903
|
+
return {};
|
|
904
|
+
session.presence = presence;
|
|
905
|
+
return {
|
|
906
|
+
$USER_JOINED: {
|
|
907
|
+
connectionId: session.id,
|
|
908
|
+
user: session.user,
|
|
909
|
+
presence
|
|
910
|
+
}
|
|
911
|
+
};
|
|
912
|
+
}).self((_0, _1) => __async(this, [_0, _1], function* (data, { context, doc, room }) {
|
|
913
|
+
var _a, _b;
|
|
914
|
+
const oldState = yield this._platform.persistance.getStorageState(room);
|
|
915
|
+
const update = data == null ? void 0 : data.update;
|
|
916
|
+
const updates = [
|
|
917
|
+
oldState ? null : yield (_a = this._getInitialStorage) == null ? void 0 : _a.call(this, __spreadProps(__spreadValues({}, context), {
|
|
918
|
+
room
|
|
919
|
+
})),
|
|
920
|
+
update
|
|
921
|
+
];
|
|
922
|
+
if (updates.some((_update) => !!_update)) {
|
|
923
|
+
const encodedState = doc.batchApplyEncodedState(updates).getEncodedState();
|
|
924
|
+
yield this._platform.persistance.setStorageState(room, encodedState);
|
|
925
|
+
this._listeners.onStorageUpdated(__spreadProps(__spreadValues({}, context), { encodedState, room }));
|
|
926
|
+
}
|
|
927
|
+
const state = (_b = yield this._platform.persistance.getStorageState(room)) != null ? _b : doc.getEncodedState();
|
|
928
|
+
return { $STORAGE_RECEIVED: { state } };
|
|
929
|
+
})),
|
|
930
|
+
$PING: this.procedure.self((data, { session }) => {
|
|
931
|
+
if (!session)
|
|
932
|
+
return {};
|
|
933
|
+
const currentTime = (/* @__PURE__ */ new Date()).getTime();
|
|
934
|
+
session.timers.ping = currentTime;
|
|
935
|
+
return { $PONG: {} };
|
|
936
|
+
}),
|
|
937
|
+
$UPDATE_PRESENCE: this.procedure.broadcast((data, { session }) => {
|
|
938
|
+
const presence = data == null ? void 0 : data.presence;
|
|
939
|
+
if (!session)
|
|
940
|
+
return {};
|
|
941
|
+
session.presence = Object.assign(/* @__PURE__ */ Object.create(null), session.presence, presence);
|
|
942
|
+
return { $PRESENCE_UPDATED: { presence } };
|
|
943
|
+
}),
|
|
944
|
+
$UPDATE_STORAGE: this.procedure.broadcast((data, { context, doc, room }) => {
|
|
945
|
+
var _a;
|
|
946
|
+
const origin = data == null ? void 0 : data.origin;
|
|
947
|
+
const update = (_a = data == null ? void 0 : data.update) != null ? _a : null;
|
|
948
|
+
if (origin === "$INITIALIZED" && Object.keys(doc.toJson()).length) {
|
|
949
|
+
return {};
|
|
950
|
+
}
|
|
951
|
+
const updated = update === null ? doc : doc.applyEncodedState({ update });
|
|
952
|
+
const encodedState = updated.getEncodedState();
|
|
953
|
+
this._platform.persistance.setStorageState(room, encodedState).then(() => {
|
|
954
|
+
this._listeners.onStorageUpdated(__spreadProps(__spreadValues({}, context), {
|
|
955
|
+
encodedState,
|
|
956
|
+
room
|
|
957
|
+
}));
|
|
958
|
+
});
|
|
959
|
+
return { $STORAGE_UPDATED: { state: encodedState } };
|
|
960
|
+
})
|
|
961
|
+
});
|
|
962
|
+
this._authorize = null;
|
|
963
|
+
this._context = {};
|
|
964
|
+
this._getInitialStorage = null;
|
|
965
|
+
this._version = version;
|
|
966
|
+
const {
|
|
967
|
+
authorize: authorize2,
|
|
968
|
+
context,
|
|
969
|
+
crdt = import_crdt3.noop,
|
|
970
|
+
debug = false,
|
|
971
|
+
getInitialStorage,
|
|
972
|
+
onRoomDeleted,
|
|
973
|
+
onStorageUpdated,
|
|
974
|
+
platform
|
|
975
|
+
} = options;
|
|
976
|
+
this._crdt = crdt;
|
|
977
|
+
this._debug = debug;
|
|
978
|
+
this._platform = platform;
|
|
979
|
+
if (authorize2)
|
|
980
|
+
this._authorize = authorize2;
|
|
981
|
+
if (context)
|
|
982
|
+
this._context = context;
|
|
983
|
+
if (getInitialStorage)
|
|
984
|
+
this._getInitialStorage = getInitialStorage;
|
|
985
|
+
this._listeners = {
|
|
986
|
+
onRoomDeleted: (event) => onRoomDeleted == null ? void 0 : onRoomDeleted(event),
|
|
987
|
+
onStorageUpdated: (event) => onStorageUpdated == null ? void 0 : onStorageUpdated(event)
|
|
988
|
+
};
|
|
989
|
+
}
|
|
990
|
+
get _events() {
|
|
991
|
+
return this._router._events;
|
|
992
|
+
}
|
|
993
|
+
get procedure() {
|
|
994
|
+
return new PluvProcedure();
|
|
995
|
+
}
|
|
996
|
+
createToken(params) {
|
|
997
|
+
return __async(this, null, function* () {
|
|
998
|
+
if (!this._authorize) {
|
|
999
|
+
throw new Error("IO does not specify authorize during initialization.");
|
|
1000
|
+
}
|
|
1001
|
+
const ioAuthorize = typeof this._authorize === "function" ? this._authorize(params) : this._authorize;
|
|
1002
|
+
const secret = ioAuthorize.secret;
|
|
1003
|
+
return yield authorize({
|
|
1004
|
+
platform: this._platform,
|
|
1005
|
+
secret
|
|
1006
|
+
}).encode(params);
|
|
1007
|
+
});
|
|
1008
|
+
}
|
|
1009
|
+
mergeRouters(...routers) {
|
|
1010
|
+
return PluvRouter.merge(...routers);
|
|
1011
|
+
}
|
|
1012
|
+
router(events) {
|
|
1013
|
+
return new PluvRouter(events);
|
|
1014
|
+
}
|
|
1015
|
+
server(config = {}) {
|
|
1016
|
+
var _a;
|
|
1017
|
+
const router = config.router ? this.mergeRouters(this._router, config.router) : this._router;
|
|
1018
|
+
return new PluvServer(__spreadProps(__spreadValues({}, this._listeners), {
|
|
1019
|
+
authorize: (_a = this._authorize) != null ? _a : void 0,
|
|
1020
|
+
context: this._context,
|
|
1021
|
+
crdt: this._crdt,
|
|
1022
|
+
debug: this._debug,
|
|
1023
|
+
platform: this._platform,
|
|
1024
|
+
router
|
|
1025
|
+
}));
|
|
1026
|
+
}
|
|
1027
|
+
};
|
|
1028
|
+
|
|
1007
1029
|
// src/createIO.ts
|
|
1008
1030
|
var createIO = (params) => {
|
|
1009
|
-
const {
|
|
1010
|
-
authorize: authorize2,
|
|
1011
|
-
context,
|
|
1012
|
-
crdt,
|
|
1013
|
-
debug,
|
|
1014
|
-
getInitialStorage,
|
|
1015
|
-
onRoomDeleted,
|
|
1016
|
-
onStorageUpdated,
|
|
1017
|
-
platform
|
|
1018
|
-
} = params;
|
|
1031
|
+
const { authorize: authorize2, context, crdt, debug, getInitialStorage, onRoomDeleted, onStorageUpdated, platform } = params;
|
|
1019
1032
|
return new PluvIO({
|
|
1020
1033
|
authorize: authorize2,
|
|
1021
1034
|
context,
|
|
@@ -1034,5 +1047,8 @@ var createIO = (params) => {
|
|
|
1034
1047
|
AbstractPubSub,
|
|
1035
1048
|
AbstractWebSocket,
|
|
1036
1049
|
PluvIO,
|
|
1050
|
+
PluvProcedure,
|
|
1051
|
+
PluvRouter,
|
|
1052
|
+
PluvServer,
|
|
1037
1053
|
createIO
|
|
1038
1054
|
});
|