@pluv/io 0.22.0 → 0.23.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/dist/index.mjs CHANGED
@@ -353,10 +353,10 @@ var PING_TIMEOUT_MS = 3e4;
353
353
  // src/IORoom.ts
354
354
  var IORoom = class {
355
355
  constructor(id, config) {
356
- this._sessions = /* @__PURE__ */ new Map();
357
- this._uninitialize = null;
358
356
  this._authorize = null;
359
- const { authorize: authorize2, context, crdt = noop, debug, onDestroy, platform, router } = config;
357
+ this._uninitialize = null;
358
+ this._sessions = /* @__PURE__ */ new Map();
359
+ const { authorize: authorize2, context, crdt = noop, debug, onDestroy, onMessage, platform, router } = config;
360
360
  this._context = context;
361
361
  this._debug = debug;
362
362
  this._docFactory = crdt.doc(() => ({}));
@@ -365,7 +365,8 @@ var IORoom = class {
365
365
  this._platform = platform.initialize({ context });
366
366
  this.id = id;
367
367
  this._listeners = {
368
- onDestroy: (event) => onDestroy == null ? void 0 : onDestroy(event)
368
+ onDestroy: (event) => onDestroy == null ? void 0 : onDestroy(event),
369
+ onMessage: (event) => onMessage == null ? void 0 : onMessage(event)
369
370
  };
370
371
  if (authorize2) this._authorize = authorize2;
371
372
  const webSockets = this._platform.getWebSockets();
@@ -582,9 +583,25 @@ var IORoom = class {
582
583
  this.id,
583
584
  (_a) => __async(this, null, function* () {
584
585
  var _b = _a, { options = {} } = _b, message = __objRest(_b, ["options"]);
585
- const sessionId = message.connectionId;
586
- const user = message.user;
587
- yield this._sendMessage(message, { sessionId, user }, options);
586
+ const sender = {
587
+ sessionId: message.connectionId,
588
+ user: message.user
589
+ };
590
+ switch (options.type) {
591
+ case "self": {
592
+ yield this._sendSelfMessage(message, sender);
593
+ return;
594
+ }
595
+ case "sync": {
596
+ yield this._sendSyncMessage(message, sender);
597
+ return;
598
+ }
599
+ case "broadcast":
600
+ default: {
601
+ const sessionIds = options.sessionIds;
602
+ yield this._sendBroadcastMessage(message, sender, sessionIds);
603
+ }
604
+ }
588
605
  })
589
606
  );
590
607
  this._uninitialize = () => __async(this, null, function* () {
@@ -592,10 +609,11 @@ var IORoom = class {
592
609
  const encodedState = this._doc.getEncodedState();
593
610
  this._doc.destroy();
594
611
  this._doc = this._docFactory.getEmpty();
595
- this._listeners.onDestroy(__spreadProps(__spreadValues({}, this._context), {
612
+ this._listeners.onDestroy({
613
+ context: this._context,
596
614
  encodedState,
597
615
  room: this.id
598
- }));
616
+ });
599
617
  this._uninitialize = null;
600
618
  });
601
619
  });
@@ -713,23 +731,17 @@ var IORoom = class {
713
731
  return null;
714
732
  }
715
733
  }
716
- _sendMessage(_0, _1) {
717
- return __async(this, arguments, function* (message, sender, options = {}) {
718
- switch (options.type) {
719
- case "self": {
720
- yield this._sendSelfMessage(message, sender);
721
- return;
722
- }
723
- case "sync": {
724
- yield this._sendSyncMessage(message, sender);
725
- return;
726
- }
727
- case "broadcast":
728
- default: {
729
- const sessionIds = options.sessionIds;
730
- yield this._sendBroadcastMessage(message, sender, sessionIds);
731
- }
732
- }
734
+ _sendMessage(pluvWs, message) {
735
+ return __async(this, null, function* () {
736
+ const { data, type } = message;
737
+ this._listeners.onMessage({
738
+ context: this._context,
739
+ encodedState: this._doc.getEncodedState(),
740
+ message: { data, type },
741
+ room: this.id,
742
+ user: message.user
743
+ });
744
+ yield Promise.resolve(pluvWs.sendMessage(message));
733
745
  });
734
746
  }
735
747
  _sendBroadcastMessage(message, sender, sessionIds) {
@@ -746,7 +758,7 @@ var IORoom = class {
746
758
  var _a2;
747
759
  const session = yield pluvWs.getSession();
748
760
  const user = (_a2 = session.user) != null ? _a2 : null;
749
- pluvWs.sendMessage({ connectionId, data, room, type, user });
761
+ this._sendMessage(pluvWs, { connectionId, data, room, type, user });
750
762
  }));
751
763
  yield Promise.all(promises);
752
764
  });
@@ -761,7 +773,7 @@ var IORoom = class {
761
773
  if (message.type === "$PONG") yield this._emitQuitters();
762
774
  const session = yield pluvWs.getSession();
763
775
  const user = (_b = session.user) != null ? _b : null;
764
- pluvWs.sendMessage(__spreadValues({
776
+ this._sendMessage(pluvWs, __spreadValues({
765
777
  connectionId: senderId,
766
778
  room: this.id,
767
779
  user
@@ -807,114 +819,15 @@ var IORoom = class {
807
819
  };
808
820
 
809
821
  // src/version.generated.ts
810
- var version = "0.22.0";
822
+ var version = "0.23.0";
811
823
 
812
824
  // src/PluvServer.ts
813
825
  var PluvServer = class {
814
826
  constructor(options) {
815
- this._rooms = /* @__PURE__ */ new Map();
827
+ this.version = version;
816
828
  this._authorize = null;
817
- this._context = {};
818
- this._version = version;
819
- const {
820
- authorize: authorize2,
821
- context,
822
- crdt = noop2,
823
- debug = false,
824
- onRoomDeleted,
825
- onStorageUpdated,
826
- platform,
827
- router = new PluvRouter({})
828
- } = options;
829
- this._crdt = crdt;
830
- this._debug = debug;
831
- this._platform = platform;
832
- this._router = router != null ? router : null;
833
- if (authorize2) this._authorize = authorize2;
834
- if (context) this._context = context;
835
- this._listeners = {
836
- onRoomDeleted: (event) => onRoomDeleted == null ? void 0 : onRoomDeleted(event),
837
- onStorageUpdated: (event) => onStorageUpdated == null ? void 0 : onStorageUpdated(event)
838
- };
839
- }
840
- get _events() {
841
- return this._router._events;
842
- }
843
- get _registrationMode() {
844
- return this._platform._registrationMode;
845
- }
846
- createToken(params) {
847
- return __async(this, null, function* () {
848
- if (!this._authorize) {
849
- throw new Error("IO does not specify authorize during initialization.");
850
- }
851
- const ioAuthorize = typeof this._authorize === "function" ? this._authorize(params) : this._authorize;
852
- const secret = ioAuthorize.secret;
853
- return yield authorize({
854
- platform: this._platform,
855
- secret
856
- }).encode(params);
857
- });
858
- }
859
- getRoom(room, ...options) {
860
- var _a, _c;
861
- const _b = (_a = options[0]) != null ? _a : {}, { debug } = _b, platformRoomContext = __objRest(_b, ["debug"]);
862
- this._purgeEmptyRooms();
863
- if (!/^[a-z0-9]+[a-z0-9\-_]+[a-z0-9]+$/i.test(room)) {
864
- throw new Error("Unsupported room name");
865
- }
866
- const platform = this._platform;
867
- const oldRoom = this._rooms.get(room);
868
- if (oldRoom) return oldRoom;
869
- const roomContext = __spreadValues(__spreadValues({}, this._context), platformRoomContext);
870
- const newRoom = new IORoom(room, {
871
- authorize: (_c = this._authorize) != null ? _c : void 0,
872
- context: roomContext,
873
- crdt: this._crdt,
874
- debug: debug != null ? debug : this._debug,
875
- onDestroy: (_0) => __async(this, [_0], function* ({ encodedState, room: room2 }) {
876
- this._logDebug(`${colors2.blue("Deleting empty room:")} ${room2}`);
877
- const roomContext2 = __spreadValues({
878
- room: room2,
879
- encodedState
880
- }, platformRoomContext);
881
- this._rooms.delete(room2);
882
- yield Promise.resolve(this._listeners.onRoomDeleted(roomContext2));
883
- yield this._platform.persistance.deleteStorageState(room2);
884
- if (this._debug) {
885
- const rooms = Array.from(this._rooms.keys());
886
- this._logDebug(`${colors2.blue("Deleted room:")} ${room2}`);
887
- this._logDebug(`${colors2.blue("Rooms available:")} ${rooms.join(", ")}`);
888
- }
889
- }),
890
- platform,
891
- router: this._router
892
- });
893
- this._rooms.set(room, newRoom);
894
- if (this._debug) {
895
- const rooms = Array.from(this._rooms.keys());
896
- this._logDebug(`${colors2.blue("Created room:")} ${room}`);
897
- this._logDebug(`${colors2.blue("Rooms available:")} ${rooms.join(", ")}`);
898
- }
899
- return newRoom;
900
- }
901
- _logDebug(...data) {
902
- this._debug && console.log(...data);
903
- }
904
- _purgeEmptyRooms() {
905
- const rooms = Array.from(this._rooms.entries());
906
- rooms.forEach(([id, room]) => {
907
- if (!!(room == null ? void 0 : room.getSize())) return;
908
- this._rooms.delete(id);
909
- });
910
- }
911
- };
912
-
913
- // src/PluvIO.ts
914
- var PluvIO = class {
915
- constructor(options) {
916
- this._router = new PluvRouter({
917
- $GET_OTHERS: this.procedure.sync((data, { room, session, sessions }) => {
829
+ this._baseRouter = new PluvRouter({
830
+ $GET_OTHERS: this._procedure.sync((data, { room, session, sessions }) => {
918
831
  const currentTime = (/* @__PURE__ */ new Date()).getTime();
919
832
  const others = sessions.filter((wsSession) => {
920
833
  if (wsSession.id === (session == null ? void 0 : session.id)) return false;
@@ -934,7 +847,7 @@ var PluvIO = class {
934
847
  );
935
848
  return { $OTHERS_RECEIVED: { others } };
936
849
  }),
937
- $INITIALIZE_SESSION: this.procedure.broadcast((data, { session }) => {
850
+ $INITIALIZE_SESSION: this._procedure.broadcast((data, { session }) => {
938
851
  const presence = data == null ? void 0 : data.presence;
939
852
  if (!session) return {};
940
853
  session.presence = presence;
@@ -958,12 +871,12 @@ var PluvIO = class {
958
871
  if (updates.some((_update) => !!_update)) {
959
872
  const encodedState = doc.batchApplyEncodedState(updates).getEncodedState();
960
873
  yield this._platform.persistance.setStorageState(room, encodedState);
961
- this._listeners.onStorageUpdated(__spreadProps(__spreadValues({}, context), { encodedState, room }));
874
+ this._listeners.onStorageUpdated({ context, encodedState, room });
962
875
  }
963
876
  const state = (_b = yield this._platform.persistance.getStorageState(room)) != null ? _b : doc.getEncodedState();
964
877
  return { $STORAGE_RECEIVED: { state } };
965
878
  })),
966
- $PING: this.procedure.self((data, { session }) => {
879
+ $PING: this._procedure.self((data, { session }) => {
967
880
  if (!session) return {};
968
881
  const currentTime = (/* @__PURE__ */ new Date()).getTime();
969
882
  const prevState = session.webSocket.state;
@@ -974,14 +887,14 @@ var PluvIO = class {
974
887
  });
975
888
  return { $PONG: {} };
976
889
  }),
977
- $UPDATE_PRESENCE: this.procedure.broadcast((data, { session }) => {
890
+ $UPDATE_PRESENCE: this._procedure.broadcast((data, { session }) => {
978
891
  const presence = data == null ? void 0 : data.presence;
979
892
  if (!session) return {};
980
893
  const updated = Object.assign(/* @__PURE__ */ Object.create(null), session.presence, presence);
981
894
  session.webSocket.presence = updated;
982
895
  return { $PRESENCE_UPDATED: { presence: updated } };
983
896
  }),
984
- $UPDATE_STORAGE: this.procedure.broadcast((data, { context, doc, room }) => {
897
+ $UPDATE_STORAGE: this._procedure.broadcast((data, { context, doc, room }) => {
985
898
  var _a;
986
899
  const origin = data == null ? void 0 : data.origin;
987
900
  const update = (_a = data == null ? void 0 : data.update) != null ? _a : null;
@@ -991,36 +904,40 @@ var PluvIO = class {
991
904
  const updated = update === null ? doc : doc.applyEncodedState({ update });
992
905
  const encodedState = updated.getEncodedState();
993
906
  this._platform.persistance.setStorageState(room, encodedState).then(() => {
994
- this._listeners.onStorageUpdated(__spreadProps(__spreadValues({}, context), {
907
+ this._listeners.onStorageUpdated({
908
+ context,
995
909
  encodedState,
996
910
  room
997
- }));
911
+ });
998
912
  });
999
913
  return { $STORAGE_UPDATED: { state: encodedState } };
1000
914
  })
1001
915
  });
1002
- this._authorize = null;
1003
916
  this._context = {};
1004
917
  this._getInitialStorage = null;
1005
- this._version = version;
918
+ this._rooms = /* @__PURE__ */ new Map();
1006
919
  const {
1007
920
  authorize: authorize2,
1008
921
  context,
1009
- crdt = noop3,
922
+ crdt = noop2,
1010
923
  debug = false,
1011
924
  getInitialStorage,
1012
925
  onRoomDeleted,
926
+ onRoomMessage,
1013
927
  onStorageUpdated,
1014
- platform
928
+ platform,
929
+ router = new PluvRouter({})
1015
930
  } = options;
1016
931
  this._crdt = crdt;
1017
932
  this._debug = debug;
1018
933
  this._platform = platform;
934
+ this._router = router ? this._baseRouter : PluvRouter.merge(this._baseRouter, router);
1019
935
  if (authorize2) this._authorize = authorize2;
1020
936
  if (context) this._context = context;
1021
937
  if (getInitialStorage) this._getInitialStorage = getInitialStorage;
1022
938
  this._listeners = {
1023
939
  onRoomDeleted: (event) => onRoomDeleted == null ? void 0 : onRoomDeleted(event),
940
+ onRoomMessage: (event) => onRoomMessage == null ? void 0 : onRoomMessage(event),
1024
941
  onStorageUpdated: (event) => onStorageUpdated == null ? void 0 : onStorageUpdated(event)
1025
942
  };
1026
943
  }
@@ -1030,6 +947,88 @@ var PluvIO = class {
1030
947
  get _registrationMode() {
1031
948
  return this._platform._registrationMode;
1032
949
  }
950
+ get _procedure() {
951
+ return new PluvProcedure();
952
+ }
953
+ createToken(params) {
954
+ return __async(this, null, function* () {
955
+ if (!this._authorize) {
956
+ throw new Error("IO does not specify authorize during initialization.");
957
+ }
958
+ const ioAuthorize = typeof this._authorize === "function" ? this._authorize(params) : this._authorize;
959
+ const secret = ioAuthorize.secret;
960
+ return yield authorize({
961
+ platform: this._platform,
962
+ secret
963
+ }).encode(params);
964
+ });
965
+ }
966
+ getRoom(room, ...options) {
967
+ var _a, _c;
968
+ const _b = (_a = options[0]) != null ? _a : {}, { debug } = _b, platformRoomContext = __objRest(_b, ["debug"]);
969
+ this._purgeEmptyRooms();
970
+ if (!/^[a-z0-9]+[a-z0-9\-_]+[a-z0-9]+$/i.test(room)) {
971
+ throw new Error("Unsupported room name");
972
+ }
973
+ const platform = this._platform;
974
+ const oldRoom = this._rooms.get(room);
975
+ if (oldRoom) return oldRoom;
976
+ const roomContext = __spreadValues(__spreadValues({}, this._context), platformRoomContext);
977
+ const newRoom = new IORoom(room, {
978
+ authorize: (_c = this._authorize) != null ? _c : void 0,
979
+ context: roomContext,
980
+ crdt: this._crdt,
981
+ debug: debug != null ? debug : this._debug,
982
+ onDestroy: (event) => __async(this, null, function* () {
983
+ this._logDebug(`${colors2.blue("Deleting empty room:")} ${room}`);
984
+ this._rooms.delete(room);
985
+ yield Promise.resolve(this._listeners.onRoomDeleted(event));
986
+ yield this._platform.persistance.deleteStorageState(room);
987
+ if (this._debug) {
988
+ const rooms = Array.from(this._rooms.keys());
989
+ this._logDebug(`${colors2.blue("Deleted room:")} ${room}`);
990
+ this._logDebug(`${colors2.blue("Rooms available:")} ${rooms.join(", ")}`);
991
+ }
992
+ }),
993
+ onMessage: (event) => __async(this, null, function* () {
994
+ yield Promise.resolve(this._listeners.onRoomMessage(event));
995
+ }),
996
+ platform,
997
+ router: this._router
998
+ });
999
+ this._rooms.set(room, newRoom);
1000
+ if (this._debug) {
1001
+ const rooms = Array.from(this._rooms.keys());
1002
+ this._logDebug(`${colors2.blue("Created room:")} ${room}`);
1003
+ this._logDebug(`${colors2.blue("Rooms available:")} ${rooms.join(", ")}`);
1004
+ }
1005
+ return newRoom;
1006
+ }
1007
+ _logDebug(...data) {
1008
+ this._debug && console.log(...data);
1009
+ }
1010
+ _purgeEmptyRooms() {
1011
+ const rooms = Array.from(this._rooms.entries());
1012
+ rooms.forEach(([id, room]) => {
1013
+ if (!!(room == null ? void 0 : room.getSize())) return;
1014
+ this._rooms.delete(id);
1015
+ });
1016
+ }
1017
+ };
1018
+
1019
+ // src/PluvIO.ts
1020
+ var PluvIO = class {
1021
+ constructor(options) {
1022
+ this.version = version;
1023
+ this._authorize = null;
1024
+ this._context = {};
1025
+ const { authorize: authorize2, context, crdt = noop3, debug = false, platform } = options;
1026
+ this._crdt = crdt;
1027
+ this._debug = debug;
1028
+ this._platform = platform;
1029
+ if (authorize2) this._authorize = authorize2;
1030
+ if (context) this._context = context;
1031
+ }
1033
1032
  get procedure() {
1034
1033
  return new PluvProcedure();
1035
1034
  }
@@ -1052,29 +1051,24 @@ var PluvIO = class {
1052
1051
  }
1053
1052
  server(config = {}) {
1054
1053
  var _a;
1055
- const router = config.router ? this.mergeRouters(this._router, config.router) : this._router;
1056
- return new PluvServer(__spreadProps(__spreadValues({}, this._listeners), {
1054
+ return new PluvServer(__spreadProps(__spreadValues({}, config), {
1057
1055
  authorize: (_a = this._authorize) != null ? _a : void 0,
1058
1056
  context: this._context,
1059
1057
  crdt: this._crdt,
1060
1058
  debug: this._debug,
1061
- platform: this._platform,
1062
- router
1059
+ platform: this._platform
1063
1060
  }));
1064
1061
  }
1065
1062
  };
1066
1063
 
1067
1064
  // src/createIO.ts
1068
1065
  var createIO = (params) => {
1069
- const { authorize: authorize2, context, crdt, debug, getInitialStorage, onRoomDeleted, onStorageUpdated, platform } = params;
1066
+ const { authorize: authorize2, context, crdt, debug, platform } = params;
1070
1067
  return new PluvIO({
1071
1068
  authorize: authorize2,
1072
1069
  context,
1073
1070
  crdt,
1074
1071
  debug,
1075
- getInitialStorage,
1076
- onRoomDeleted,
1077
- onStorageUpdated,
1078
1072
  platform
1079
1073
  });
1080
1074
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pluv/io",
3
- "version": "0.22.0",
3
+ "version": "0.23.0",
4
4
  "description": "@pluv/io server-side websocket manager",
5
5
  "author": "leedavidcs",
6
6
  "license": "MIT",
@@ -21,16 +21,16 @@
21
21
  "jose": "^5.6.3",
22
22
  "kleur": "^4.1.5",
23
23
  "wonka": "^6.3.4",
24
- "@pluv/crdt": "^0.22.0",
25
- "@pluv/types": "^0.22.0"
24
+ "@pluv/crdt": "^0.23.0",
25
+ "@pluv/types": "^0.23.0"
26
26
  },
27
27
  "devDependencies": {
28
28
  "eslint": "^8.57.0",
29
29
  "genversion": "^3.2.0",
30
30
  "tsup": "^8.2.4",
31
31
  "typescript": "^5.5.4",
32
- "@pluv/tsconfig": "^0.22.0",
33
- "eslint-config-pluv": "^0.22.0"
32
+ "@pluv/tsconfig": "^0.23.0",
33
+ "eslint-config-pluv": "^0.23.0"
34
34
  },
35
35
  "scripts": {
36
36
  "build": "pnpm run version && tsup src/index.ts --format esm,cjs --dts",
@@ -39,16 +39,16 @@ export abstract class AbstractPlatform<
39
39
  TPlatformContext extends Record<string, any> = {},
40
40
  TRoomContext extends Record<string, any> = {},
41
41
  > {
42
- private _initialized: boolean = false;
43
-
44
- readonly _ioContext: TPlatformContext | undefined;
45
- readonly _roomContext: TRoomContext | undefined;
42
+ protected readonly _ioContext: TPlatformContext | undefined;
43
+ protected readonly _roomContext: TRoomContext | undefined;
46
44
 
47
- abstract readonly _registrationMode: WebSocketRegistrationMode;
45
+ private _initialized: boolean = false;
48
46
 
49
47
  public persistance: AbstractPersistance;
50
48
  public pubSub: AbstractPubSub;
51
49
 
50
+ public abstract readonly _registrationMode: WebSocketRegistrationMode;
51
+
52
52
  constructor(config: AbstractPlatformConfig<TPlatformContext, TRoomContext> = {}) {
53
53
  const { context, persistance, pubSub } = config;
54
54