@pluv/io 0.17.3 → 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 +129 -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.mjs
CHANGED
|
@@ -203,11 +203,7 @@ var AbstractWebSocket = class {
|
|
|
203
203
|
}
|
|
204
204
|
handleError(params) {
|
|
205
205
|
var _a, _b, _c;
|
|
206
|
-
const {
|
|
207
|
-
error,
|
|
208
|
-
message = error instanceof Error ? error.message : "Unexpected error",
|
|
209
|
-
session
|
|
210
|
-
} = params;
|
|
206
|
+
const { error, message = error instanceof Error ? error.message : "Unexpected error", session } = params;
|
|
211
207
|
const stack = error instanceof Error ? (_a = error.stack) != null ? _a : null : null;
|
|
212
208
|
return this.sendMessage({
|
|
213
209
|
connectionId: (_b = session == null ? void 0 : session.id) != null ? _b : null,
|
|
@@ -223,6 +219,79 @@ var AbstractWebSocket = class {
|
|
|
223
219
|
};
|
|
224
220
|
|
|
225
221
|
// src/PluvIO.ts
|
|
222
|
+
import { noop as noop3 } from "@pluv/crdt";
|
|
223
|
+
|
|
224
|
+
// src/PluvProcedure.ts
|
|
225
|
+
var PluvProcedure = class _PluvProcedure {
|
|
226
|
+
constructor(config = {}) {
|
|
227
|
+
this._broadcast = null;
|
|
228
|
+
this._input = null;
|
|
229
|
+
this._self = null;
|
|
230
|
+
this._sync = null;
|
|
231
|
+
const { broadcast, input, self, sync } = config;
|
|
232
|
+
this._broadcast = broadcast != null ? broadcast : null;
|
|
233
|
+
this._input = input != null ? input : null;
|
|
234
|
+
this._self = self != null ? self : null;
|
|
235
|
+
this._sync = sync != null ? sync : null;
|
|
236
|
+
}
|
|
237
|
+
get config() {
|
|
238
|
+
var _a, _b, _c, _d, _e, _f, _g;
|
|
239
|
+
return {
|
|
240
|
+
broadcast: (_b = (_a = this._broadcast) == null ? void 0 : _a.bind(this)) != null ? _b : null,
|
|
241
|
+
input: (_c = this._input) != null ? _c : null,
|
|
242
|
+
resolver: this._resolver,
|
|
243
|
+
self: (_e = (_d = this._self) == null ? void 0 : _d.bind(this)) != null ? _e : null,
|
|
244
|
+
sync: (_g = (_f = this._sync) == null ? void 0 : _f.bind(this)) != null ? _g : null
|
|
245
|
+
};
|
|
246
|
+
}
|
|
247
|
+
broadcast(resolver) {
|
|
248
|
+
const { broadcast } = this.config;
|
|
249
|
+
if (!!broadcast)
|
|
250
|
+
throw new Error("Broadcast was already defined for this procedure");
|
|
251
|
+
return new _PluvProcedure(__spreadProps(__spreadValues({}, this.config), {
|
|
252
|
+
broadcast: resolver
|
|
253
|
+
}));
|
|
254
|
+
}
|
|
255
|
+
input(input) {
|
|
256
|
+
return new _PluvProcedure({ input });
|
|
257
|
+
}
|
|
258
|
+
self(resolver) {
|
|
259
|
+
const { self } = this.config;
|
|
260
|
+
if (!!self)
|
|
261
|
+
throw new Error("Self was already defined for this procedure");
|
|
262
|
+
return new _PluvProcedure(__spreadProps(__spreadValues({}, this.config), {
|
|
263
|
+
self: resolver
|
|
264
|
+
}));
|
|
265
|
+
}
|
|
266
|
+
sync(resolver) {
|
|
267
|
+
const { sync } = this.config;
|
|
268
|
+
if (!!sync)
|
|
269
|
+
throw new Error("Sync was already defined for this procedure");
|
|
270
|
+
return new _PluvProcedure(__spreadProps(__spreadValues({}, this.config), {
|
|
271
|
+
sync: resolver
|
|
272
|
+
}));
|
|
273
|
+
}
|
|
274
|
+
_resolver() {
|
|
275
|
+
return (data, context) => {
|
|
276
|
+
var _a, _b, _c;
|
|
277
|
+
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));
|
|
278
|
+
};
|
|
279
|
+
}
|
|
280
|
+
};
|
|
281
|
+
|
|
282
|
+
// src/PluvRouter.ts
|
|
283
|
+
var PluvRouter = class _PluvRouter {
|
|
284
|
+
constructor(events) {
|
|
285
|
+
this._events = {};
|
|
286
|
+
this._events = events;
|
|
287
|
+
}
|
|
288
|
+
static merge(...routers) {
|
|
289
|
+
const events = Object.assign(/* @__PURE__ */ Object.create(null), ...routers.map((router) => router._events));
|
|
290
|
+
return new _PluvRouter(events);
|
|
291
|
+
}
|
|
292
|
+
};
|
|
293
|
+
|
|
294
|
+
// src/PluvServer.ts
|
|
226
295
|
import { noop as noop2 } from "@pluv/crdt";
|
|
227
296
|
import colors2 from "kleur";
|
|
228
297
|
|
|
@@ -235,13 +304,7 @@ import hkdf from "@panva/hkdf";
|
|
|
235
304
|
import { EncryptJWT, jwtDecrypt } from "jose";
|
|
236
305
|
var DEFAULT_MAX_AGE_MS = 6e4;
|
|
237
306
|
var getEncryptionKey = (secret) => __async(void 0, null, function* () {
|
|
238
|
-
return yield hkdf(
|
|
239
|
-
"sha256",
|
|
240
|
-
secret,
|
|
241
|
-
"",
|
|
242
|
-
"Pluv.io Generated Encryption Key",
|
|
243
|
-
32
|
|
244
|
-
);
|
|
307
|
+
return yield hkdf("sha256", secret, "", "Pluv.io Generated Encryption Key", 32);
|
|
245
308
|
});
|
|
246
309
|
var now = () => Date.now() / 1e3 | 0;
|
|
247
310
|
var authorize = (params) => {
|
|
@@ -273,20 +336,12 @@ var IORoom = class {
|
|
|
273
336
|
this._sessions = /* @__PURE__ */ new Map();
|
|
274
337
|
this._uninitialize = null;
|
|
275
338
|
this._authorize = null;
|
|
276
|
-
const {
|
|
277
|
-
authorize: authorize2,
|
|
278
|
-
context,
|
|
279
|
-
crdt = noop,
|
|
280
|
-
debug,
|
|
281
|
-
events,
|
|
282
|
-
onDestroy,
|
|
283
|
-
platform
|
|
284
|
-
} = config;
|
|
339
|
+
const { authorize: authorize2, context, crdt = noop, debug, onDestroy, platform, router } = config;
|
|
285
340
|
this._context = context;
|
|
286
341
|
this._debug = debug;
|
|
287
342
|
this._docFactory = crdt.doc(() => ({}));
|
|
288
343
|
this._doc = this._docFactory.getEmpty();
|
|
289
|
-
this.
|
|
344
|
+
this._router = router;
|
|
290
345
|
this._platform = platform;
|
|
291
346
|
this.id = id;
|
|
292
347
|
this._listeners = {
|
|
@@ -295,9 +350,19 @@ var IORoom = class {
|
|
|
295
350
|
if (authorize2)
|
|
296
351
|
this._authorize = authorize2;
|
|
297
352
|
}
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
353
|
+
get _events() {
|
|
354
|
+
return this._router._events;
|
|
355
|
+
}
|
|
356
|
+
get broadcast() {
|
|
357
|
+
const _broadcast = (event, data) => {
|
|
358
|
+
const message = { type: event, data };
|
|
359
|
+
return Promise.resolve(this._broadcast({ message }));
|
|
360
|
+
};
|
|
361
|
+
return new Proxy(_broadcast, {
|
|
362
|
+
get(fn, prop) {
|
|
363
|
+
return (data) => fn(prop, data);
|
|
364
|
+
}
|
|
365
|
+
});
|
|
301
366
|
}
|
|
302
367
|
getSize() {
|
|
303
368
|
const currentTime = (/* @__PURE__ */ new Date()).getTime();
|
|
@@ -321,26 +386,16 @@ var IORoom = class {
|
|
|
321
386
|
sessionId,
|
|
322
387
|
userId: (_b = user == null ? void 0 : user.id) != null ? _b : null
|
|
323
388
|
});
|
|
324
|
-
this._logDebug(
|
|
325
|
-
`${colors.blue(
|
|
326
|
-
`Registering connection for room ${this.id}:`
|
|
327
|
-
)} ${sessionId}`
|
|
328
|
-
);
|
|
389
|
+
this._logDebug(`${colors.blue(`Registering connection for room ${this.id}:`)} ${sessionId}`);
|
|
329
390
|
const uninitializeWs = yield pluvWs.initialize();
|
|
330
391
|
const ioAuthorize = this._getIOAuthorize(options);
|
|
331
392
|
const isUnauthorized = !!(ioAuthorize == null ? void 0 : ioAuthorize.required) && !user;
|
|
332
|
-
const isTokenInUse = !!user && Array.from(this._sessions.values()).some(
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
}
|
|
337
|
-
);
|
|
393
|
+
const isTokenInUse = !!user && Array.from(this._sessions.values()).some((session2) => {
|
|
394
|
+
var _a2;
|
|
395
|
+
return ((_a2 = session2.user) == null ? void 0 : _a2.id) === user.id;
|
|
396
|
+
});
|
|
338
397
|
if (isUnauthorized || isTokenInUse) {
|
|
339
|
-
this._logDebug(
|
|
340
|
-
`${colors.blue(
|
|
341
|
-
"Authorization failed for connection:"
|
|
342
|
-
)} ${sessionId}`
|
|
343
|
-
);
|
|
398
|
+
this._logDebug(`${colors.blue("Authorization failed for connection:")} ${sessionId}`);
|
|
344
399
|
pluvWs.handleError({ error: new Error("Not authorized") });
|
|
345
400
|
pluvWs.close(3e3, "WebSocket unauthorized.");
|
|
346
401
|
return;
|
|
@@ -358,24 +413,14 @@ var IORoom = class {
|
|
|
358
413
|
user
|
|
359
414
|
};
|
|
360
415
|
this._sessions.set(session.id, session);
|
|
361
|
-
yield this._platform.persistance.addUser(
|
|
362
|
-
this.id,
|
|
363
|
-
sessionId,
|
|
364
|
-
user != null ? user : {}
|
|
365
|
-
);
|
|
416
|
+
yield this._platform.persistance.addUser(this.id, sessionId, user != null ? user : {});
|
|
366
417
|
const onClose = this._onClose(session, uninitializeWs).bind(this);
|
|
367
|
-
const onMessage = this._onMessage(session, platformEventContext).bind(
|
|
368
|
-
this
|
|
369
|
-
);
|
|
418
|
+
const onMessage = this._onMessage(session, platformEventContext).bind(this);
|
|
370
419
|
pluvWs.addEventListener("close", onClose);
|
|
371
420
|
pluvWs.addEventListener("error", onClose);
|
|
372
421
|
pluvWs.addEventListener("message", onMessage);
|
|
373
422
|
this._emitRegistered(session);
|
|
374
|
-
this._logDebug(
|
|
375
|
-
`${colors.blue(
|
|
376
|
-
`Registered connection for room ${this.id}:`
|
|
377
|
-
)} ${sessionId}`
|
|
378
|
-
);
|
|
423
|
+
this._logDebug(`${colors.blue(`Registered connection for room ${this.id}:`)} ${sessionId}`);
|
|
379
424
|
const size = this.getSize();
|
|
380
425
|
this._logDebug(`${colors.blue(`Room ${this.id} size:`)} ${size}`);
|
|
381
426
|
});
|
|
@@ -442,9 +487,7 @@ var IORoom = class {
|
|
|
442
487
|
return null;
|
|
443
488
|
}
|
|
444
489
|
if (payload.room !== this.id) {
|
|
445
|
-
this._logDebug(
|
|
446
|
-
colors.blue(`Token is not authorized for room ${this.id}:`)
|
|
447
|
-
);
|
|
490
|
+
this._logDebug(colors.blue(`Token is not authorized for room ${this.id}:`));
|
|
448
491
|
this._logDebug(colors.blue("Received:"), payload.room);
|
|
449
492
|
this._logDebug(token);
|
|
450
493
|
return null;
|
|
@@ -452,29 +495,20 @@ var IORoom = class {
|
|
|
452
495
|
try {
|
|
453
496
|
return (_a = ioAuthorize.user.parse(payload.user)) != null ? _a : null;
|
|
454
497
|
} catch (e) {
|
|
455
|
-
this._logDebug(
|
|
456
|
-
`${colors.blue("Token fails validation:")} ${token}`
|
|
457
|
-
);
|
|
498
|
+
this._logDebug(`${colors.blue("Token fails validation:")} ${token}`);
|
|
458
499
|
return null;
|
|
459
500
|
}
|
|
460
501
|
});
|
|
461
502
|
}
|
|
462
|
-
|
|
503
|
+
_getProcedure(message) {
|
|
463
504
|
var _a;
|
|
464
|
-
return (_a = this._events[message.type]) != null ? _a : null;
|
|
505
|
+
return (_a = this._router._events[message.type]) != null ? _a : null;
|
|
465
506
|
}
|
|
466
|
-
|
|
467
|
-
const
|
|
468
|
-
if (!
|
|
507
|
+
_getProcedureInputs(message) {
|
|
508
|
+
const procedure = this._getProcedure(message);
|
|
509
|
+
if (!procedure)
|
|
469
510
|
return message.data;
|
|
470
|
-
return
|
|
471
|
-
}
|
|
472
|
-
_getEventResolverObject(message) {
|
|
473
|
-
const eventConfig = this._getEventConfig(message);
|
|
474
|
-
if (!eventConfig)
|
|
475
|
-
return {};
|
|
476
|
-
const resolver = eventConfig.resolver;
|
|
477
|
-
return typeof resolver === "function" ? { broadcast: resolver } : __spreadValues({}, resolver);
|
|
511
|
+
return procedure.config.input ? procedure.config.input.parse(message.data) : message.data;
|
|
478
512
|
}
|
|
479
513
|
_initialize() {
|
|
480
514
|
return __async(this, null, function* () {
|
|
@@ -483,17 +517,14 @@ var IORoom = class {
|
|
|
483
517
|
yield this._uninitialize();
|
|
484
518
|
this._uninitialize = null;
|
|
485
519
|
}
|
|
486
|
-
const pubSubId = yield this._platform.pubSub.subscribe(
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
this._sendMessage(message, session, options);
|
|
495
|
-
}
|
|
496
|
-
);
|
|
520
|
+
const pubSubId = yield this._platform.pubSub.subscribe(this.id, (_a) => {
|
|
521
|
+
var _b = _a, { options = {} } = _b, message = __objRest(_b, ["options"]);
|
|
522
|
+
const session = {
|
|
523
|
+
id: message.connectionId,
|
|
524
|
+
user: message.user
|
|
525
|
+
};
|
|
526
|
+
this._sendMessage(message, session, options);
|
|
527
|
+
});
|
|
497
528
|
this._uninitialize = () => __async(this, null, function* () {
|
|
498
529
|
this._platform.pubSub.unsubscribe(pubSubId);
|
|
499
530
|
const encodedState = this._doc.getEncodedState();
|
|
@@ -515,11 +546,7 @@ var IORoom = class {
|
|
|
515
546
|
if (!this._uninitialize)
|
|
516
547
|
return;
|
|
517
548
|
session.quit = true;
|
|
518
|
-
this._logDebug(
|
|
519
|
-
`${colors.blue(
|
|
520
|
-
`(Unregistering connection for room ${this.id}:`
|
|
521
|
-
)} ${session.id}`
|
|
522
|
-
);
|
|
549
|
+
this._logDebug(`${colors.blue(`(Unregistering connection for room ${this.id}:`)} ${session.id}`);
|
|
523
550
|
this._sessions.delete(session.id);
|
|
524
551
|
this._platform.persistance.deleteUser(this.id, session.id).finally(() => {
|
|
525
552
|
var _a;
|
|
@@ -532,14 +559,8 @@ var IORoom = class {
|
|
|
532
559
|
});
|
|
533
560
|
callback == null ? void 0 : callback();
|
|
534
561
|
const size = this.getSize();
|
|
535
|
-
this._logDebug(
|
|
536
|
-
|
|
537
|
-
`Unregistered connection for room ${this.id}:`
|
|
538
|
-
)} ${session.id}`
|
|
539
|
-
);
|
|
540
|
-
this._logDebug(
|
|
541
|
-
`${colors.blue(`Room ${this.id} size:`)} ${size}`
|
|
542
|
-
);
|
|
562
|
+
this._logDebug(`${colors.blue(`Unregistered connection for room ${this.id}:`)} ${session.id}`);
|
|
563
|
+
this._logDebug(`${colors.blue(`Room ${this.id} size:`)} ${size}`);
|
|
543
564
|
if (size)
|
|
544
565
|
return;
|
|
545
566
|
(_a = this._uninitialize) == null ? void 0 : _a.call(this);
|
|
@@ -548,7 +569,7 @@ var IORoom = class {
|
|
|
548
569
|
}
|
|
549
570
|
_onMessage(session, platformEventContext) {
|
|
550
571
|
return (event) => {
|
|
551
|
-
var _a, _b, _c;
|
|
572
|
+
var _a, _b, _c, _d, _e, _f;
|
|
552
573
|
const baseContext = {
|
|
553
574
|
context: this._context,
|
|
554
575
|
doc: this._doc,
|
|
@@ -565,10 +586,12 @@ var IORoom = class {
|
|
|
565
586
|
const message = this._parseMessage(event);
|
|
566
587
|
if (!message)
|
|
567
588
|
return;
|
|
568
|
-
const
|
|
589
|
+
const procedure = this._getProcedure(message);
|
|
590
|
+
if (!procedure)
|
|
591
|
+
return;
|
|
569
592
|
let inputs;
|
|
570
593
|
try {
|
|
571
|
-
inputs = this.
|
|
594
|
+
inputs = this._getProcedureInputs(message);
|
|
572
595
|
} catch (error) {
|
|
573
596
|
session == null ? void 0 : session.webSocket.handleError({
|
|
574
597
|
error,
|
|
@@ -581,9 +604,9 @@ var IORoom = class {
|
|
|
581
604
|
context: __spreadValues(__spreadValues({}, this._context), platformEventContext)
|
|
582
605
|
});
|
|
583
606
|
Promise.all([
|
|
584
|
-
(_a =
|
|
585
|
-
(
|
|
586
|
-
(
|
|
607
|
+
(_b = (_a = procedure.config).broadcast) == null ? void 0 : _b.call(_a, inputs, extendedContext),
|
|
608
|
+
(_d = (_c = procedure.config).self) == null ? void 0 : _d.call(_c, inputs, extendedContext),
|
|
609
|
+
(_f = (_e = procedure.config).sync) == null ? void 0 : _f.call(_e, inputs, baseContext)
|
|
587
610
|
]).then(([broadcast, self, sync]) => {
|
|
588
611
|
if (broadcast) {
|
|
589
612
|
Object.entries(broadcast).forEach(([type, data]) => {
|
|
@@ -672,6 +695,7 @@ var IORoom = class {
|
|
|
672
695
|
}, message));
|
|
673
696
|
}
|
|
674
697
|
_sendSyncMessage(message, sender) {
|
|
698
|
+
var _a;
|
|
675
699
|
const senderId = sender == null ? void 0 : sender.id;
|
|
676
700
|
if (!senderId)
|
|
677
701
|
return;
|
|
@@ -682,12 +706,12 @@ var IORoom = class {
|
|
|
682
706
|
session: null,
|
|
683
707
|
sessions: this._sessions
|
|
684
708
|
};
|
|
685
|
-
const resolver = this.
|
|
709
|
+
const resolver = (_a = this._getProcedure(message)) == null ? void 0 : _a.config.sync;
|
|
686
710
|
if (!resolver)
|
|
687
711
|
return;
|
|
688
712
|
let inputs;
|
|
689
713
|
try {
|
|
690
|
-
inputs = this.
|
|
714
|
+
inputs = this._getProcedureInputs(message);
|
|
691
715
|
} catch (e) {
|
|
692
716
|
return;
|
|
693
717
|
}
|
|
@@ -695,8 +719,8 @@ var IORoom = class {
|
|
|
695
719
|
if (!output)
|
|
696
720
|
return;
|
|
697
721
|
Object.keys(output).forEach((type) => {
|
|
698
|
-
var
|
|
699
|
-
const data = (
|
|
722
|
+
var _a2, _b;
|
|
723
|
+
const data = (_a2 = output[type]) != null ? _a2 : {};
|
|
700
724
|
this._platform.pubSub.publish(this.id, {
|
|
701
725
|
connectionId: senderId,
|
|
702
726
|
data,
|
|
@@ -711,149 +735,45 @@ var IORoom = class {
|
|
|
711
735
|
};
|
|
712
736
|
|
|
713
737
|
// src/version.generated.ts
|
|
714
|
-
var version = "0.
|
|
738
|
+
var version = "0.18.0";
|
|
715
739
|
|
|
716
|
-
// src/
|
|
717
|
-
var
|
|
740
|
+
// src/PluvServer.ts
|
|
741
|
+
var PluvServer = class {
|
|
718
742
|
constructor(options) {
|
|
719
743
|
this._rooms = /* @__PURE__ */ new Map();
|
|
720
744
|
this._authorize = null;
|
|
721
745
|
this._context = {};
|
|
722
|
-
this._events = {
|
|
723
|
-
$GET_OTHERS: {
|
|
724
|
-
resolver: {
|
|
725
|
-
sync: (data, { room, session, sessions }) => {
|
|
726
|
-
const others = Array.from(sessions.entries()).filter(([, wsSession]) => wsSession.id !== (session == null ? void 0 : session.id)).reduce(
|
|
727
|
-
(acc, [connectionId, { presence, user }]) => __spreadProps(__spreadValues({}, acc), {
|
|
728
|
-
[connectionId]: {
|
|
729
|
-
connectionId,
|
|
730
|
-
presence,
|
|
731
|
-
room,
|
|
732
|
-
user
|
|
733
|
-
}
|
|
734
|
-
}),
|
|
735
|
-
{}
|
|
736
|
-
);
|
|
737
|
-
return { $OTHERS_RECEIVED: { others } };
|
|
738
|
-
}
|
|
739
|
-
}
|
|
740
|
-
},
|
|
741
|
-
$INITIALIZE_SESSION: {
|
|
742
|
-
resolver: {
|
|
743
|
-
broadcast: ({ presence }, { session }) => {
|
|
744
|
-
if (!session)
|
|
745
|
-
return {};
|
|
746
|
-
session.presence = presence;
|
|
747
|
-
return {
|
|
748
|
-
$USER_JOINED: {
|
|
749
|
-
connectionId: session.id,
|
|
750
|
-
user: session.user,
|
|
751
|
-
presence
|
|
752
|
-
}
|
|
753
|
-
};
|
|
754
|
-
},
|
|
755
|
-
self: (_0, _1) => __async(this, [_0, _1], function* ({ update }, { context, doc, room }) {
|
|
756
|
-
var _a, _b;
|
|
757
|
-
const oldState = yield this._platform.persistance.getStorageState(room);
|
|
758
|
-
const updates = [
|
|
759
|
-
oldState ? null : yield (_a = this._getInitialStorage) == null ? void 0 : _a.call(this, __spreadProps(__spreadValues({}, context), {
|
|
760
|
-
room
|
|
761
|
-
})),
|
|
762
|
-
update
|
|
763
|
-
];
|
|
764
|
-
if (updates.some((_update) => !!_update)) {
|
|
765
|
-
const encodedState = doc.batchApplyEncodedState(updates).getEncodedState();
|
|
766
|
-
yield this._platform.persistance.setStorageState(
|
|
767
|
-
room,
|
|
768
|
-
encodedState
|
|
769
|
-
);
|
|
770
|
-
this._listeners.onStorageUpdated(__spreadProps(__spreadValues({}, context), {
|
|
771
|
-
encodedState,
|
|
772
|
-
room
|
|
773
|
-
}));
|
|
774
|
-
}
|
|
775
|
-
const state = (_b = yield this._platform.persistance.getStorageState(
|
|
776
|
-
room
|
|
777
|
-
)) != null ? _b : doc.getEncodedState();
|
|
778
|
-
return { $STORAGE_RECEIVED: { state } };
|
|
779
|
-
})
|
|
780
|
-
}
|
|
781
|
-
},
|
|
782
|
-
$PING: {
|
|
783
|
-
resolver: {
|
|
784
|
-
self: (data, { session }) => {
|
|
785
|
-
if (!session)
|
|
786
|
-
return {};
|
|
787
|
-
const currentTime = (/* @__PURE__ */ new Date()).getTime();
|
|
788
|
-
session.timers.ping = currentTime;
|
|
789
|
-
return { $PONG: {} };
|
|
790
|
-
}
|
|
791
|
-
}
|
|
792
|
-
},
|
|
793
|
-
$UPDATE_PRESENCE: {
|
|
794
|
-
resolver: ({ presence }, { session }) => {
|
|
795
|
-
if (!session)
|
|
796
|
-
return {};
|
|
797
|
-
session.presence = Object.assign(
|
|
798
|
-
/* @__PURE__ */ Object.create(null),
|
|
799
|
-
session.presence,
|
|
800
|
-
presence
|
|
801
|
-
);
|
|
802
|
-
return { $PRESENCE_UPDATED: { presence } };
|
|
803
|
-
}
|
|
804
|
-
},
|
|
805
|
-
$UPDATE_STORAGE: {
|
|
806
|
-
resolver: ({ origin, update }, { context, doc, room }) => {
|
|
807
|
-
if (origin === "$INITIALIZED" && Object.keys(doc.toJson()).length) {
|
|
808
|
-
return;
|
|
809
|
-
}
|
|
810
|
-
const updated = doc.applyEncodedState({ update });
|
|
811
|
-
const encodedState = updated.getEncodedState();
|
|
812
|
-
this._platform.persistance.setStorageState(room, encodedState).then(() => {
|
|
813
|
-
this._listeners.onStorageUpdated(__spreadProps(__spreadValues({}, context), {
|
|
814
|
-
encodedState,
|
|
815
|
-
room
|
|
816
|
-
}));
|
|
817
|
-
});
|
|
818
|
-
return { $STORAGE_UPDATED: { state: encodedState } };
|
|
819
|
-
}
|
|
820
|
-
}
|
|
821
|
-
};
|
|
822
|
-
this._getInitialStorage = null;
|
|
823
746
|
this._version = version;
|
|
824
747
|
const {
|
|
825
748
|
authorize: authorize2,
|
|
826
749
|
context,
|
|
827
750
|
crdt = noop2,
|
|
828
751
|
debug = false,
|
|
829
|
-
events,
|
|
830
|
-
getInitialStorage,
|
|
831
752
|
onRoomDeleted,
|
|
832
753
|
onStorageUpdated,
|
|
833
|
-
platform
|
|
754
|
+
platform,
|
|
755
|
+
router = new PluvRouter({})
|
|
834
756
|
} = options;
|
|
835
757
|
this._crdt = crdt;
|
|
836
758
|
this._debug = debug;
|
|
837
759
|
this._platform = platform;
|
|
760
|
+
this._router = router != null ? router : null;
|
|
838
761
|
if (authorize2)
|
|
839
762
|
this._authorize = authorize2;
|
|
840
763
|
if (context)
|
|
841
764
|
this._context = context;
|
|
842
|
-
if (events)
|
|
843
|
-
this._events = events;
|
|
844
|
-
if (getInitialStorage)
|
|
845
|
-
this._getInitialStorage = getInitialStorage;
|
|
846
765
|
this._listeners = {
|
|
847
766
|
onRoomDeleted: (event) => onRoomDeleted == null ? void 0 : onRoomDeleted(event),
|
|
848
767
|
onStorageUpdated: (event) => onStorageUpdated == null ? void 0 : onStorageUpdated(event)
|
|
849
768
|
};
|
|
850
769
|
}
|
|
770
|
+
get _events() {
|
|
771
|
+
return this._router._events;
|
|
772
|
+
}
|
|
851
773
|
createToken(params) {
|
|
852
774
|
return __async(this, null, function* () {
|
|
853
775
|
if (!this._authorize) {
|
|
854
|
-
throw new Error(
|
|
855
|
-
"IO does not specify authorize during initialization."
|
|
856
|
-
);
|
|
776
|
+
throw new Error("IO does not specify authorize during initialization.");
|
|
857
777
|
}
|
|
858
778
|
const ioAuthorize = typeof this._authorize === "function" ? this._authorize(params) : this._authorize;
|
|
859
779
|
const secret = ioAuthorize.secret;
|
|
@@ -863,22 +783,6 @@ var PluvIO = class _PluvIO {
|
|
|
863
783
|
}).encode(params);
|
|
864
784
|
});
|
|
865
785
|
}
|
|
866
|
-
event(event, config) {
|
|
867
|
-
if (event.startsWith("$")) {
|
|
868
|
-
throw new Error('Event name must not start with "$".');
|
|
869
|
-
}
|
|
870
|
-
const newEvent = {
|
|
871
|
-
[event]: config
|
|
872
|
-
};
|
|
873
|
-
return _PluvIO.merge(
|
|
874
|
-
this,
|
|
875
|
-
new _PluvIO({
|
|
876
|
-
crdt: this._crdt,
|
|
877
|
-
events: newEvent,
|
|
878
|
-
platform: this._platform
|
|
879
|
-
})
|
|
880
|
-
);
|
|
881
|
-
}
|
|
882
786
|
getRoom(room, options) {
|
|
883
787
|
var _b;
|
|
884
788
|
const _a = options, { debug } = _a, platformRoomContext = __objRest(_a, ["debug"]);
|
|
@@ -896,11 +800,8 @@ var PluvIO = class _PluvIO {
|
|
|
896
800
|
context: roomContext,
|
|
897
801
|
crdt: this._crdt,
|
|
898
802
|
debug: debug != null ? debug : this._debug,
|
|
899
|
-
events: this._events,
|
|
900
803
|
onDestroy: ({ encodedState, room: room2 }) => {
|
|
901
|
-
this._logDebug(
|
|
902
|
-
`${colors2.blue("Deleting empty room:")} ${room2}`
|
|
903
|
-
);
|
|
804
|
+
this._logDebug(`${colors2.blue("Deleting empty room:")} ${room2}`);
|
|
904
805
|
const roomContext2 = __spreadValues({
|
|
905
806
|
room: room2,
|
|
906
807
|
encodedState
|
|
@@ -910,49 +811,20 @@ var PluvIO = class _PluvIO {
|
|
|
910
811
|
if (this._debug) {
|
|
911
812
|
const rooms = Array.from(this._rooms.keys());
|
|
912
813
|
this._logDebug(`${colors2.blue("Deleted room:")} ${room2}`);
|
|
913
|
-
this._logDebug(
|
|
914
|
-
`${colors2.blue("Rooms available:")} ${rooms.join(
|
|
915
|
-
", "
|
|
916
|
-
)}`
|
|
917
|
-
);
|
|
814
|
+
this._logDebug(`${colors2.blue("Rooms available:")} ${rooms.join(", ")}`);
|
|
918
815
|
}
|
|
919
816
|
},
|
|
920
|
-
platform
|
|
817
|
+
platform,
|
|
818
|
+
router: this._router
|
|
921
819
|
});
|
|
922
820
|
this._rooms.set(room, newRoom);
|
|
923
821
|
if (this._debug) {
|
|
924
822
|
const rooms = Array.from(this._rooms.keys());
|
|
925
823
|
this._logDebug(`${colors2.blue("Created room:")} ${room}`);
|
|
926
|
-
this._logDebug(
|
|
927
|
-
`${colors2.blue("Rooms available:")} ${rooms.join(", ")}`
|
|
928
|
-
);
|
|
824
|
+
this._logDebug(`${colors2.blue("Rooms available:")} ${rooms.join(", ")}`);
|
|
929
825
|
}
|
|
930
826
|
return newRoom;
|
|
931
827
|
}
|
|
932
|
-
static merge(first, second) {
|
|
933
|
-
var _a;
|
|
934
|
-
const authorize2 = (_a = first._authorize) != null ? _a : void 0;
|
|
935
|
-
const context = first._context;
|
|
936
|
-
const crdt = first._crdt;
|
|
937
|
-
const debug = first._debug;
|
|
938
|
-
const platform = first._platform;
|
|
939
|
-
const getInitialStorage = first._getInitialStorage;
|
|
940
|
-
const events1 = first._events;
|
|
941
|
-
const events2 = second._events;
|
|
942
|
-
const { onRoomDeleted, onStorageUpdated } = first._listeners;
|
|
943
|
-
const events = Object.assign(/* @__PURE__ */ Object.create(null), events1, events2);
|
|
944
|
-
return new _PluvIO({
|
|
945
|
-
authorize: authorize2,
|
|
946
|
-
context,
|
|
947
|
-
crdt,
|
|
948
|
-
debug,
|
|
949
|
-
events,
|
|
950
|
-
getInitialStorage,
|
|
951
|
-
onRoomDeleted,
|
|
952
|
-
onStorageUpdated,
|
|
953
|
-
platform
|
|
954
|
-
});
|
|
955
|
-
}
|
|
956
828
|
_logDebug(...data) {
|
|
957
829
|
this._debug && console.log(...data);
|
|
958
830
|
}
|
|
@@ -966,18 +838,156 @@ var PluvIO = class _PluvIO {
|
|
|
966
838
|
}
|
|
967
839
|
};
|
|
968
840
|
|
|
841
|
+
// src/PluvIO.ts
|
|
842
|
+
var PluvIO = class {
|
|
843
|
+
constructor(options) {
|
|
844
|
+
this._router = new PluvRouter({
|
|
845
|
+
$GET_OTHERS: this.procedure.sync((data, { room, session, sessions }) => {
|
|
846
|
+
const others = Array.from(sessions.entries()).filter(([, wsSession]) => wsSession.id !== (session == null ? void 0 : session.id)).reduce(
|
|
847
|
+
(acc, [connectionId, { presence, user }]) => __spreadProps(__spreadValues({}, acc), {
|
|
848
|
+
[connectionId]: {
|
|
849
|
+
connectionId,
|
|
850
|
+
presence,
|
|
851
|
+
room,
|
|
852
|
+
user
|
|
853
|
+
}
|
|
854
|
+
}),
|
|
855
|
+
{}
|
|
856
|
+
);
|
|
857
|
+
return { $OTHERS_RECEIVED: { others } };
|
|
858
|
+
}),
|
|
859
|
+
$INITIALIZE_SESSION: this.procedure.broadcast((data, { session }) => {
|
|
860
|
+
const presence = data == null ? void 0 : data.presence;
|
|
861
|
+
if (!session)
|
|
862
|
+
return {};
|
|
863
|
+
session.presence = presence;
|
|
864
|
+
return {
|
|
865
|
+
$USER_JOINED: {
|
|
866
|
+
connectionId: session.id,
|
|
867
|
+
user: session.user,
|
|
868
|
+
presence
|
|
869
|
+
}
|
|
870
|
+
};
|
|
871
|
+
}).self((_0, _1) => __async(this, [_0, _1], function* (data, { context, doc, room }) {
|
|
872
|
+
var _a, _b;
|
|
873
|
+
const oldState = yield this._platform.persistance.getStorageState(room);
|
|
874
|
+
const update = data == null ? void 0 : data.update;
|
|
875
|
+
const updates = [
|
|
876
|
+
oldState ? null : yield (_a = this._getInitialStorage) == null ? void 0 : _a.call(this, __spreadProps(__spreadValues({}, context), {
|
|
877
|
+
room
|
|
878
|
+
})),
|
|
879
|
+
update
|
|
880
|
+
];
|
|
881
|
+
if (updates.some((_update) => !!_update)) {
|
|
882
|
+
const encodedState = doc.batchApplyEncodedState(updates).getEncodedState();
|
|
883
|
+
yield this._platform.persistance.setStorageState(room, encodedState);
|
|
884
|
+
this._listeners.onStorageUpdated(__spreadProps(__spreadValues({}, context), { encodedState, room }));
|
|
885
|
+
}
|
|
886
|
+
const state = (_b = yield this._platform.persistance.getStorageState(room)) != null ? _b : doc.getEncodedState();
|
|
887
|
+
return { $STORAGE_RECEIVED: { state } };
|
|
888
|
+
})),
|
|
889
|
+
$PING: this.procedure.self((data, { session }) => {
|
|
890
|
+
if (!session)
|
|
891
|
+
return {};
|
|
892
|
+
const currentTime = (/* @__PURE__ */ new Date()).getTime();
|
|
893
|
+
session.timers.ping = currentTime;
|
|
894
|
+
return { $PONG: {} };
|
|
895
|
+
}),
|
|
896
|
+
$UPDATE_PRESENCE: this.procedure.broadcast((data, { session }) => {
|
|
897
|
+
const presence = data == null ? void 0 : data.presence;
|
|
898
|
+
if (!session)
|
|
899
|
+
return {};
|
|
900
|
+
session.presence = Object.assign(/* @__PURE__ */ Object.create(null), session.presence, presence);
|
|
901
|
+
return { $PRESENCE_UPDATED: { presence } };
|
|
902
|
+
}),
|
|
903
|
+
$UPDATE_STORAGE: this.procedure.broadcast((data, { context, doc, room }) => {
|
|
904
|
+
var _a;
|
|
905
|
+
const origin = data == null ? void 0 : data.origin;
|
|
906
|
+
const update = (_a = data == null ? void 0 : data.update) != null ? _a : null;
|
|
907
|
+
if (origin === "$INITIALIZED" && Object.keys(doc.toJson()).length) {
|
|
908
|
+
return {};
|
|
909
|
+
}
|
|
910
|
+
const updated = update === null ? doc : doc.applyEncodedState({ update });
|
|
911
|
+
const encodedState = updated.getEncodedState();
|
|
912
|
+
this._platform.persistance.setStorageState(room, encodedState).then(() => {
|
|
913
|
+
this._listeners.onStorageUpdated(__spreadProps(__spreadValues({}, context), {
|
|
914
|
+
encodedState,
|
|
915
|
+
room
|
|
916
|
+
}));
|
|
917
|
+
});
|
|
918
|
+
return { $STORAGE_UPDATED: { state: encodedState } };
|
|
919
|
+
})
|
|
920
|
+
});
|
|
921
|
+
this._authorize = null;
|
|
922
|
+
this._context = {};
|
|
923
|
+
this._getInitialStorage = null;
|
|
924
|
+
this._version = version;
|
|
925
|
+
const {
|
|
926
|
+
authorize: authorize2,
|
|
927
|
+
context,
|
|
928
|
+
crdt = noop3,
|
|
929
|
+
debug = false,
|
|
930
|
+
getInitialStorage,
|
|
931
|
+
onRoomDeleted,
|
|
932
|
+
onStorageUpdated,
|
|
933
|
+
platform
|
|
934
|
+
} = options;
|
|
935
|
+
this._crdt = crdt;
|
|
936
|
+
this._debug = debug;
|
|
937
|
+
this._platform = platform;
|
|
938
|
+
if (authorize2)
|
|
939
|
+
this._authorize = authorize2;
|
|
940
|
+
if (context)
|
|
941
|
+
this._context = context;
|
|
942
|
+
if (getInitialStorage)
|
|
943
|
+
this._getInitialStorage = getInitialStorage;
|
|
944
|
+
this._listeners = {
|
|
945
|
+
onRoomDeleted: (event) => onRoomDeleted == null ? void 0 : onRoomDeleted(event),
|
|
946
|
+
onStorageUpdated: (event) => onStorageUpdated == null ? void 0 : onStorageUpdated(event)
|
|
947
|
+
};
|
|
948
|
+
}
|
|
949
|
+
get _events() {
|
|
950
|
+
return this._router._events;
|
|
951
|
+
}
|
|
952
|
+
get procedure() {
|
|
953
|
+
return new PluvProcedure();
|
|
954
|
+
}
|
|
955
|
+
createToken(params) {
|
|
956
|
+
return __async(this, null, function* () {
|
|
957
|
+
if (!this._authorize) {
|
|
958
|
+
throw new Error("IO does not specify authorize during initialization.");
|
|
959
|
+
}
|
|
960
|
+
const ioAuthorize = typeof this._authorize === "function" ? this._authorize(params) : this._authorize;
|
|
961
|
+
const secret = ioAuthorize.secret;
|
|
962
|
+
return yield authorize({
|
|
963
|
+
platform: this._platform,
|
|
964
|
+
secret
|
|
965
|
+
}).encode(params);
|
|
966
|
+
});
|
|
967
|
+
}
|
|
968
|
+
mergeRouters(...routers) {
|
|
969
|
+
return PluvRouter.merge(...routers);
|
|
970
|
+
}
|
|
971
|
+
router(events) {
|
|
972
|
+
return new PluvRouter(events);
|
|
973
|
+
}
|
|
974
|
+
server(config = {}) {
|
|
975
|
+
var _a;
|
|
976
|
+
const router = config.router ? this.mergeRouters(this._router, config.router) : this._router;
|
|
977
|
+
return new PluvServer(__spreadProps(__spreadValues({}, this._listeners), {
|
|
978
|
+
authorize: (_a = this._authorize) != null ? _a : void 0,
|
|
979
|
+
context: this._context,
|
|
980
|
+
crdt: this._crdt,
|
|
981
|
+
debug: this._debug,
|
|
982
|
+
platform: this._platform,
|
|
983
|
+
router
|
|
984
|
+
}));
|
|
985
|
+
}
|
|
986
|
+
};
|
|
987
|
+
|
|
969
988
|
// src/createIO.ts
|
|
970
989
|
var createIO = (params) => {
|
|
971
|
-
const {
|
|
972
|
-
authorize: authorize2,
|
|
973
|
-
context,
|
|
974
|
-
crdt,
|
|
975
|
-
debug,
|
|
976
|
-
getInitialStorage,
|
|
977
|
-
onRoomDeleted,
|
|
978
|
-
onStorageUpdated,
|
|
979
|
-
platform
|
|
980
|
-
} = params;
|
|
990
|
+
const { authorize: authorize2, context, crdt, debug, getInitialStorage, onRoomDeleted, onStorageUpdated, platform } = params;
|
|
981
991
|
return new PluvIO({
|
|
982
992
|
authorize: authorize2,
|
|
983
993
|
context,
|
|
@@ -995,5 +1005,8 @@ export {
|
|
|
995
1005
|
AbstractPubSub,
|
|
996
1006
|
AbstractWebSocket,
|
|
997
1007
|
PluvIO,
|
|
1008
|
+
PluvProcedure,
|
|
1009
|
+
PluvRouter,
|
|
1010
|
+
PluvServer,
|
|
998
1011
|
createIO
|
|
999
1012
|
};
|