atom.io 0.46.4 → 0.46.6

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.
Files changed (46) hide show
  1. package/dist/realtime/index.d.ts +7 -6
  2. package/dist/realtime/index.d.ts.map +1 -1
  3. package/dist/realtime/index.js +19 -10
  4. package/dist/realtime/index.js.map +1 -1
  5. package/dist/realtime-client/index.d.ts +13 -13
  6. package/dist/realtime-client/index.d.ts.map +1 -1
  7. package/dist/realtime-client/index.js +10 -3
  8. package/dist/realtime-client/index.js.map +1 -1
  9. package/dist/realtime-react/index.d.ts +12 -3
  10. package/dist/realtime-react/index.d.ts.map +1 -1
  11. package/dist/realtime-react/index.js +26 -3
  12. package/dist/realtime-react/index.js.map +1 -1
  13. package/dist/realtime-server/index.d.ts +50 -42
  14. package/dist/realtime-server/index.d.ts.map +1 -1
  15. package/dist/realtime-server/index.js +132 -101
  16. package/dist/realtime-server/index.js.map +1 -1
  17. package/dist/realtime-testing/index.js +2 -2
  18. package/dist/realtime-testing/index.js.map +1 -1
  19. package/package.json +20 -19
  20. package/src/realtime/realtime-continuity.ts +2 -2
  21. package/src/realtime/shared-room-store.ts +38 -17
  22. package/src/realtime/socket-interface.ts +1 -1
  23. package/src/realtime-client/continuity/register-and-attempt-confirmed-update.ts +3 -1
  24. package/src/realtime-client/continuity/use-conceal-state.ts +2 -1
  25. package/src/realtime-client/pull-atom-family-member.ts +1 -1
  26. package/src/realtime-client/pull-atom.ts +1 -1
  27. package/src/realtime-client/pull-mutable-atom-family-member.ts +1 -1
  28. package/src/realtime-client/pull-mutable-atom.ts +1 -1
  29. package/src/realtime-client/pull-selector-family-member.ts +1 -1
  30. package/src/realtime-client/pull-selector-roots.ts +1 -1
  31. package/src/realtime-client/pull-selector.ts +1 -1
  32. package/src/realtime-client/push-state.ts +1 -1
  33. package/src/realtime-client/realtime-client-stores/client-main-store.ts +16 -3
  34. package/src/realtime-client/sync-continuity.ts +1 -2
  35. package/src/realtime-react/use-realtime-rooms.ts +54 -6
  36. package/src/realtime-server/continuity/provide-outcomes.ts +1 -1
  37. package/src/realtime-server/ipc-sockets/parent-socket.ts +11 -15
  38. package/src/realtime-server/provide-rooms.ts +64 -16
  39. package/src/realtime-server/realtime-family-provider.ts +51 -35
  40. package/src/realtime-server/realtime-mutable-family-provider.ts +50 -34
  41. package/src/realtime-server/realtime-mutable-provider.ts +4 -4
  42. package/src/realtime-server/realtime-state-provider.ts +7 -7
  43. package/src/realtime-server/realtime-state-receiver.ts +2 -2
  44. package/src/realtime-server/server-config.ts +20 -13
  45. package/src/realtime-server/server-socket-state.ts +3 -3
  46. package/src/realtime-testing/setup-realtime-test.tsx +2 -2
@@ -2,7 +2,8 @@ import { IMPLICIT, OWN_OP, Subject, actUponStore, editRelationsInStore, findInSt
2
2
  import { Realm, atomFamily, join, mutableAtom } from "atom.io";
3
3
  import { parseJson, stringifyJson } from "atom.io/json";
4
4
  import { UList } from "atom.io/transceivers/u-list";
5
- import { castSocket, employSocket, isRoomKey, isSocketKey, isUserKey, mutexAtoms, ownersOfRooms, roomKeysAtom, usersInRooms, visibleUsersInRoomsSelector } from "atom.io/realtime";
5
+ import { castSocket, employSocket, isRoomKey, isSocketKey, isUserKey, mutexAtoms, ownersOfRooms, roomKeysAtom, usersInRooms, visibilityFromRoomSelector, visibleUsersInRoomsSelector } from "atom.io/realtime";
6
+ import { myRoomKeyAtom, myUserKeyAtom } from "atom.io/realtime-client";
6
7
  import { spawn } from "node:child_process";
7
8
 
8
9
  //#region src/realtime-server/continuity/continuity-store.ts
@@ -287,7 +288,7 @@ var ParentSocket = class extends CustomSocket {
287
288
  incompleteData = ``;
288
289
  unprocessedEvents = [];
289
290
  relays;
290
- relayServices;
291
+ initRelay;
291
292
  proc;
292
293
  id = `#####`;
293
294
  log(...args) {
@@ -313,7 +314,9 @@ var ParentSocket = class extends CustomSocket {
313
314
  this.proc = proc;
314
315
  this.proc.stdin.resume();
315
316
  this.relays = /* @__PURE__ */ new Map();
316
- this.relayServices = [];
317
+ this.initRelay = () => {
318
+ this.logger.info(`🔗`, `nothing to relay`);
319
+ };
317
320
  this.proc.stdin.on(`data`, (buffer) => {
318
321
  const pieces = buffer.toString().split(`\x03`);
319
322
  const initialMaybeWellFormed = pieces[0];
@@ -361,14 +364,12 @@ var ParentSocket = class extends CustomSocket {
361
364
  });
362
365
  if (this.proc.pid) this.id = this.proc.pid?.toString();
363
366
  this.on(`user-joins`, (userKey) => {
364
- this.logger.info(`👤`, `user`, userKey, `joined`);
367
+ this.logger.info(`👤`, userKey, `joined`);
365
368
  const relay = new SubjectSocket(userKey);
366
369
  this.relays.set(userKey, relay);
367
- this.logger.info(`🔗`, `attaching services:`, `[${[...this.relayServices.keys()].join(`, `)}]`);
368
- for (const attachRelay of this.relayServices) {
369
- const cleanupRelay = attachRelay(relay, userKey);
370
- if (cleanupRelay) relay.disposalFunctions.push(cleanupRelay);
371
- }
370
+ this.logger.info(`🔗`, `attaching services for user`, userKey);
371
+ const cleanupRelay = this.initRelay(relay, userKey);
372
+ if (cleanupRelay) relay.disposalFunctions.push(cleanupRelay);
372
373
  this.on(userKey, (...data) => {
373
374
  relay.in.next(data);
374
375
  });
@@ -388,7 +389,7 @@ var ParentSocket = class extends CustomSocket {
388
389
  }
389
390
  receiveRelay(attachServices) {
390
391
  this.logger.info(`🔗`, `running relay method`);
391
- this.relayServices.push(attachServices);
392
+ this.initRelay = attachServices;
392
393
  }
393
394
  };
394
395
 
@@ -541,8 +542,12 @@ const isAvailable = (exposedSubKeys, subKey) => {
541
542
  for (const exposedSubKey of exposedSubKeys) if (stringifyJson(exposedSubKey) === stringifyJson(subKey)) return true;
542
543
  return false;
543
544
  };
544
- function realtimeMutableFamilyProvider({ socket, userKey, store = IMPLICIT.STORE }) {
545
+ function realtimeMutableFamilyProvider({ socket, consumer, store = IMPLICIT.STORE }) {
545
546
  return function mutableFamilyProvider(family, index) {
547
+ const [dynamicIndex, staticIndex] = (() => {
548
+ if (typeof index === `object` && `key` in index && `type` in index) return [index, void 0];
549
+ return [void 0, index];
550
+ })();
546
551
  const coreSubscriptions = /* @__PURE__ */ new Set();
547
552
  const clearCoreSubscriptions = () => {
548
553
  for (const unsub of coreSubscriptions) unsub();
@@ -580,21 +585,24 @@ function realtimeMutableFamilyProvider({ socket, userKey, store = IMPLICIT.STORE
580
585
  }));
581
586
  };
582
587
  const start = () => {
583
- store.logger.info(`👀`, `user`, userKey, `can subscribe to family "${family.key}"`);
588
+ store.logger.info(`👀`, `user`, consumer, `can subscribe to family "${family.key}"`);
584
589
  coreSubscriptions.add(employSocket(socket, `sub:${family.key}`, (subKey) => {
585
- if (isAvailable(getFromStore(store, index), subKey)) {
586
- store.logger.info(`👀`, `user`, userKey, `is approved for a subscription to`, subKey, `in family "${family.key}"`);
590
+ let exposedSubKeys;
591
+ if (dynamicIndex) exposedSubKeys = getFromStore(store, dynamicIndex);
592
+ else exposedSubKeys = staticIndex;
593
+ if (isAvailable(exposedSubKeys, subKey)) {
594
+ store.logger.info(`👀`, `user`, consumer, `is approved for a subscription to`, subKey, `in family "${family.key}"`);
587
595
  exposeFamilyMembers(subKey);
588
596
  } else {
589
- store.logger.info(`❌`, `user`, userKey, `is denied for a subscription to`, subKey, `in family "${family.key}"`);
597
+ store.logger.info(`❌`, `user`, consumer, `is denied for a subscription to`, subKey, `in family "${family.key}"`);
590
598
  familyMemberSubscriptionsWanted.add(stringifyJson(subKey));
591
599
  socket.emit(`unavailable:${family.key}`, subKey);
592
600
  }
593
601
  }));
594
- coreSubscriptions.add(subscribeToState(store, index, `expose-family:${family.key}:${socket.id}`, ({ newValue: newExposedSubKeys }) => {
595
- store.logger.info(`👀`, `user`, userKey, `has the following keys available for family "${family.key}"`, newExposedSubKeys);
602
+ if (dynamicIndex) coreSubscriptions.add(subscribeToState(store, dynamicIndex, `expose-family:${family.key}:${socket.id}`, ({ newValue: newExposedSubKeys }) => {
603
+ store.logger.info(`👀`, `user`, consumer, `has the following keys available for family "${family.key}"`, newExposedSubKeys);
596
604
  for (const subKey of newExposedSubKeys) if (familyMemberSubscriptionsWanted.has(stringifyJson(subKey))) {
597
- store.logger.info(`👀`, `user`, userKey, `is retroactively approved for a subscription to`, subKey, `in family "${family.key}"`);
605
+ store.logger.info(`👀`, `user`, consumer, `is retroactively approved for a subscription to`, subKey, `in family "${family.key}"`);
598
606
  exposeFamilyMembers(subKey);
599
607
  }
600
608
  }));
@@ -609,7 +617,7 @@ function realtimeMutableFamilyProvider({ socket, userKey, store = IMPLICIT.STORE
609
617
 
610
618
  //#endregion
611
619
  //#region src/realtime-server/realtime-mutable-provider.ts
612
- function realtimeMutableProvider({ socket, userKey, store = IMPLICIT.STORE }) {
620
+ function realtimeMutableProvider({ socket, consumer, store = IMPLICIT.STORE }) {
613
621
  return function mutableProvider(token) {
614
622
  const subscriptions = /* @__PURE__ */ new Set();
615
623
  const clearSubscriptions = () => {
@@ -619,16 +627,16 @@ function realtimeMutableProvider({ socket, userKey, store = IMPLICIT.STORE }) {
619
627
  const jsonToken = getJsonToken(store, token);
620
628
  const trackerToken = getUpdateToken(token);
621
629
  const start = () => {
622
- store.logger.info(`👀`, `user`, userKey, `can subscribe to state "${token.key}"`);
630
+ store.logger.info(`👀`, `user`, consumer, `can subscribe to state "${token.key}"`);
623
631
  subscriptions.add(employSocket(socket, `sub:${token.key}`, () => {
624
- store.logger.info(`👀`, `user`, userKey, `subscribes to state "${token.key}"`);
632
+ store.logger.info(`👀`, `user`, consumer, `subscribes to state "${token.key}"`);
625
633
  clearSubscriptions();
626
634
  socket.emit(`init:${token.key}`, getFromStore(store, jsonToken));
627
635
  subscriptions.add(subscribeToState(store, trackerToken, `expose-single:${socket.id}`, ({ newValue }) => {
628
636
  socket.emit(`next:${token.key}`, newValue);
629
637
  }));
630
638
  subscriptions.add(employSocket(socket, `unsub:${token.key}`, () => {
631
- store.logger.info(`🙈`, `user`, userKey, `unsubscribes from state "${token.key}"`);
639
+ store.logger.info(`🙈`, `user`, consumer, `unsubscribes from state "${token.key}"`);
632
640
  clearSubscriptions();
633
641
  start();
634
642
  }));
@@ -639,6 +647,47 @@ function realtimeMutableProvider({ socket, userKey, store = IMPLICIT.STORE }) {
639
647
  };
640
648
  }
641
649
 
650
+ //#endregion
651
+ //#region src/realtime-server/realtime-state-provider.ts
652
+ function isReadableToken(input) {
653
+ return typeof input === `object` && input !== null && `key` in input && `type` in input;
654
+ }
655
+ function realtimeStateProvider({ socket, consumer, store = IMPLICIT.STORE }) {
656
+ store.logger.info(`🔌`, `user`, consumer, `initialized state provider`);
657
+ return function stateProvider(clientToken, serverData = clientToken) {
658
+ const isStatic = !isReadableToken(serverData);
659
+ const subscriptions = /* @__PURE__ */ new Set();
660
+ const clearSubscriptions = () => {
661
+ for (const unsub of subscriptions) unsub();
662
+ subscriptions.clear();
663
+ };
664
+ const start = () => {
665
+ if (isStatic) store.logger.info(`👀`, `user`, consumer, `will be served`, serverData, `as "${clientToken.key}"`);
666
+ else store.logger.info(`👀`, `user`, consumer, `can subscribe to state "${serverData.key}" as "${clientToken.key}"`);
667
+ subscriptions.add(employSocket(socket, `sub:${clientToken.key}`, () => {
668
+ if (isStatic) {
669
+ store.logger.info(`👀`, `user`, consumer, `requests`, `"${clientToken.key}"`);
670
+ socket.emit(`serve:${clientToken.key}`, serverData);
671
+ } else {
672
+ store.logger.info(`👀`, `user`, consumer, `subscribes to state "${serverData.key}"`, clientToken === serverData ? `directly` : `as "${clientToken.key}"`);
673
+ clearSubscriptions();
674
+ socket.emit(`serve:${clientToken.key}`, getFromStore(store, serverData));
675
+ subscriptions.add(subscribeToState(store, serverData, `expose-single:${socket.id}`, ({ newValue }) => {
676
+ socket.emit(`serve:${clientToken.key}`, newValue);
677
+ }));
678
+ subscriptions.add(employSocket(socket, `unsub:${serverData.key}`, () => {
679
+ store.logger.info(`🙈`, `user`, consumer, `unsubscribes from state "${serverData.key}", served`, clientToken === serverData ? `directly` : `as "${clientToken.key}"`);
680
+ clearSubscriptions();
681
+ start();
682
+ }));
683
+ }
684
+ }));
685
+ };
686
+ start();
687
+ return clearSubscriptions;
688
+ };
689
+ }
690
+
642
691
  //#endregion
643
692
  //#region src/realtime-server/provide-rooms.ts
644
693
  const ROOMS = globalThis.ATOM_IO_REALTIME_SERVER_ROOMS ?? (globalThis.ATOM_IO_REALTIME_SERVER_ROOMS = /* @__PURE__ */ new Map());
@@ -648,17 +697,17 @@ function spawnRoom({ store, socket, userKey, resolveRoomScript }) {
648
697
  store.logger.info(`📡`, `socket`, socket.id ?? `[ID MISSING?!]`, `👤 ${userKey} spawns room ${roomName}`);
649
698
  const roomKey = `room::${roomMeta.count++}`;
650
699
  const [command, args] = resolveRoomScript(roomName);
651
- const roomSocket = new ChildSocket(await new Promise((resolve) => {
652
- const room = spawn(command, args, { env: process.env });
700
+ const room = new ChildSocket(await new Promise((resolve) => {
701
+ const room$1 = spawn(command, args, { env: process.env });
653
702
  const resolver = (data) => {
654
703
  if (data.toString() === PROOF_OF_LIFE_SIGNAL) {
655
- room.stdout.off(`data`, resolver);
656
- resolve(room);
704
+ room$1.stdout.off(`data`, resolver);
705
+ resolve(room$1);
657
706
  }
658
707
  };
659
- room.stdout.on(`data`, resolver);
708
+ room$1.stdout.on(`data`, resolver);
660
709
  }), roomKey);
661
- ROOMS.set(roomKey, roomSocket);
710
+ ROOMS.set(roomKey, room);
662
711
  setIntoStore(store, roomKeysAtom, (index) => (index.add(roomKey), index));
663
712
  editRelationsInStore(store, ownersOfRooms, (relations) => {
664
713
  relations.set({
@@ -666,23 +715,41 @@ function spawnRoom({ store, socket, userKey, resolveRoomScript }) {
666
715
  user: userKey
667
716
  });
668
717
  });
669
- roomSocket.on(`close`, () => {
718
+ const provideMutableFamily = realtimeMutableFamilyProvider({
719
+ socket: room,
720
+ consumer: roomKey,
721
+ store
722
+ });
723
+ const unsubFromRoomKey = realtimeStateProvider({
724
+ socket: room,
725
+ consumer: roomKey,
726
+ store
727
+ })(myRoomKeyAtom, roomKey);
728
+ const unsubFromOwnerKeys = provideMutableFamily(getInternalRelationsFromStore(store, ownersOfRooms), [roomKey]);
729
+ const unsubFromUsersInRooms = provideMutableFamily(getInternalRelationsFromStore(store, usersInRooms), findInStore(store, visibilityFromRoomSelector, roomKey));
730
+ room.on(`close`, () => {
731
+ unsubFromRoomKey();
732
+ unsubFromOwnerKeys();
733
+ unsubFromUsersInRooms();
670
734
  destroyRoom({
671
735
  store,
672
736
  socket,
673
737
  userKey
674
738
  })(roomKey);
675
739
  });
676
- return roomSocket;
740
+ return room;
677
741
  };
678
742
  }
679
743
  function provideEnterAndExit({ store, socket, roomSocket, userKey }) {
680
744
  const enterRoom = (roomKey) => {
681
745
  store.logger.info(`📡`, `socket`, socket.id ?? `[ID MISSING?!]`, `👤 ${userKey} enters room ${roomKey}`);
746
+ const dcUserFromRoom = () => {
747
+ toRoom([`user-leaves`]);
748
+ };
682
749
  const exitRoom = () => {
683
750
  store.logger.info(`📡`, `socket`, socket.id ?? `[ID MISSING?!]`, `👤 ${userKey} leaves room ${roomKey}`);
684
751
  socket.offAny(forward);
685
- toRoom([`user-leaves`]);
752
+ dcUserFromRoom();
686
753
  editRelationsInStore(store, usersInRooms, (relations) => {
687
754
  relations.delete({
688
755
  room: roomKey,
@@ -692,8 +759,6 @@ function provideEnterAndExit({ store, socket, roomSocket, userKey }) {
692
759
  roomSocket.off(`leaveRoom`, exitRoom);
693
760
  roomSocket.on(`joinRoom`, enterRoom);
694
761
  };
695
- roomSocket.on(`leaveRoom`, exitRoom);
696
- roomSocket.off(`joinRoom`, enterRoom);
697
762
  const roomQueue = [];
698
763
  const pushToRoomQueue = (payload) => {
699
764
  roomQueue.push(payload);
@@ -712,7 +777,7 @@ function provideEnterAndExit({ store, socket, roomSocket, userKey }) {
712
777
  const childSocket = ROOMS.get(roomKey);
713
778
  if (!childSocket) {
714
779
  store.logger.error(`❌`, `unknown`, roomKey, `no room found with this id`);
715
- return null;
780
+ return;
716
781
  }
717
782
  childSocket.onAny((...payload) => {
718
783
  socket.emit(...payload);
@@ -725,6 +790,9 @@ function provideEnterAndExit({ store, socket, roomSocket, userKey }) {
725
790
  const payload = roomQueue.shift();
726
791
  if (payload) toRoom(payload);
727
792
  }
793
+ socket.on(`disconnect`, dcUserFromRoom);
794
+ roomSocket.on(`leaveRoom`, exitRoom);
795
+ roomSocket.off(`joinRoom`, enterRoom);
728
796
  };
729
797
  roomSocket.on(`joinRoom`, enterRoom);
730
798
  return enterRoom;
@@ -754,7 +822,7 @@ function provideRooms({ store = IMPLICIT.STORE, socket, resolveRoomScript, roomN
754
822
  const unsubFromRoomKeys = realtimeMutableProvider({
755
823
  socket,
756
824
  store,
757
- userKey
825
+ consumer: userKey
758
826
  })(roomKeysAtom);
759
827
  const usersInRoomsAtoms = getInternalRelationsFromStore(store, usersInRooms);
760
828
  const [, usersInRoomsAtomsUsersOnly] = getInternalRelationsFromStore(store, usersInRooms, `split`);
@@ -763,7 +831,7 @@ function provideRooms({ store = IMPLICIT.STORE, socket, resolveRoomScript, roomN
763
831
  const exposeMutableFamily = realtimeMutableFamilyProvider({
764
832
  socket,
765
833
  store,
766
- userKey
834
+ consumer: userKey
767
835
  });
768
836
  const unsubFromUsersInRooms = exposeMutableFamily(usersInRoomsAtoms, usersWhoseRoomsCanBeSeenSelector);
769
837
  const unsubFromOwnersOfRooms = exposeMutableFamily(ownersOfRoomsAtoms, usersWhoseRoomsCanBeSeenSelector);
@@ -828,8 +896,12 @@ function createRoomSocketGuard(roomNames) {
828
896
 
829
897
  //#endregion
830
898
  //#region src/realtime-server/realtime-family-provider.ts
831
- function realtimeAtomFamilyProvider({ socket, userKey, store = IMPLICIT.STORE }) {
899
+ function realtimeAtomFamilyProvider({ socket, consumer, store = IMPLICIT.STORE }) {
832
900
  return function familyProvider(family, index) {
901
+ const [dynamicIndex, staticIndex] = (() => {
902
+ if (typeof index === `object` && `key` in index && `type` in index) return [index, void 0];
903
+ return [void 0, index];
904
+ })();
833
905
  const coreSubscriptions = /* @__PURE__ */ new Set();
834
906
  const clearCoreSubscriptions = () => {
835
907
  for (const unsub of coreSubscriptions) unsub();
@@ -861,7 +933,7 @@ function realtimeAtomFamilyProvider({ socket, userKey, store = IMPLICIT.STORE })
861
933
  socket.emit(`serve:${token.key}`, newValue);
862
934
  }));
863
935
  familyMemberSubscriptions.set(`${token.key}:unsub`, employSocket(socket, `unsub:${token.key}`, () => {
864
- store.logger.info(`🙈`, `user`, userKey, `unsubscribed from state "${token.key}"`);
936
+ store.logger.info(`🙈`, `user`, consumer, `unsubscribed from state "${token.key}"`);
865
937
  fillUnsubRequest(token.key);
866
938
  }));
867
939
  };
@@ -870,21 +942,24 @@ function realtimeAtomFamilyProvider({ socket, userKey, store = IMPLICIT.STORE })
870
942
  return false;
871
943
  };
872
944
  const start = () => {
873
- store.logger.info(`👀`, `user`, userKey, `can subscribe to family "${family.key}"`);
945
+ store.logger.info(`👀`, `user`, consumer, `can subscribe to family "${family.key}"`);
874
946
  coreSubscriptions.add(employSocket(socket, `sub:${family.key}`, (subKey) => {
875
- if (isAvailable$1(getFromStore(store, index), subKey)) {
876
- store.logger.info(`👀`, `user`, userKey, `is approved for a subscription to`, subKey, `in family "${family.key}"`);
947
+ let exposedSubKeys;
948
+ if (dynamicIndex) exposedSubKeys = getFromStore(store, dynamicIndex);
949
+ else exposedSubKeys = staticIndex;
950
+ if (isAvailable$1(exposedSubKeys, subKey)) {
951
+ store.logger.info(`👀`, `user`, consumer, `is approved for a subscription to`, subKey, `in family "${family.key}"`);
877
952
  exposeFamilyMembers(subKey);
878
953
  } else {
879
- store.logger.info(`❌`, `user`, userKey, `is denied for a subscription to`, subKey, `in family "${family.key}"`);
954
+ store.logger.info(`❌`, `user`, consumer, `is denied for a subscription to`, subKey, `in family "${family.key}"`);
880
955
  familyMemberSubscriptionsWanted.add(stringifyJson(subKey));
881
956
  socket.emit(`unavailable:${family.key}`, subKey);
882
957
  }
883
958
  }));
884
- coreSubscriptions.add(subscribeToState(store, index, `expose-family:${family.key}:${socket.id}`, ({ newValue: newExposedSubKeys }) => {
885
- store.logger.info(`👀`, `user`, userKey, `has the following keys available for family "${family.key}"`, newExposedSubKeys);
959
+ if (dynamicIndex) coreSubscriptions.add(subscribeToState(store, dynamicIndex, `expose-family:${family.key}:${socket.id}`, ({ newValue: newExposedSubKeys }) => {
960
+ store.logger.info(`👀`, `user`, consumer, `has the following keys available for family "${family.key}"`, newExposedSubKeys);
886
961
  for (const subKey of newExposedSubKeys) if (familyMemberSubscriptionsWanted.has(stringifyJson(subKey))) {
887
- store.logger.info(`👀`, `user`, userKey, `is retroactively approved for a subscription to`, subKey, `in family "${family.key}"`);
962
+ store.logger.info(`👀`, `user`, consumer, `is retroactively approved for a subscription to`, subKey, `in family "${family.key}"`);
888
963
  exposeFamilyMembers(subKey);
889
964
  }
890
965
  }));
@@ -897,50 +972,9 @@ function realtimeAtomFamilyProvider({ socket, userKey, store = IMPLICIT.STORE })
897
972
  };
898
973
  }
899
974
 
900
- //#endregion
901
- //#region src/realtime-server/realtime-state-provider.ts
902
- function isReadableToken(input) {
903
- return typeof input === `object` && input !== null && `key` in input && `type` in input;
904
- }
905
- function realtimeStateProvider({ socket, userKey, store = IMPLICIT.STORE }) {
906
- store.logger.info(`🔌`, `user`, userKey, `initialized state provider`);
907
- return function stateProvider(clientToken, serverData = clientToken) {
908
- const isStatic = !isReadableToken(serverData);
909
- const subscriptions = /* @__PURE__ */ new Set();
910
- const clearSubscriptions = () => {
911
- for (const unsub of subscriptions) unsub();
912
- subscriptions.clear();
913
- };
914
- const start = () => {
915
- if (isStatic) store.logger.info(`👀`, `user`, userKey, `will be served`, serverData, `as "${clientToken.key}"`);
916
- else store.logger.info(`👀`, `user`, userKey, `can subscribe to state "${serverData.key}" as "${clientToken.key}"`);
917
- subscriptions.add(employSocket(socket, `sub:${clientToken.key}`, () => {
918
- if (isStatic) {
919
- store.logger.info(`👀`, `user`, userKey, `requests`, `"${clientToken.key}"`);
920
- socket.emit(`serve:${clientToken.key}`, serverData);
921
- } else {
922
- store.logger.info(`👀`, `user`, userKey, `subscribes to state "${serverData.key}"`, clientToken === serverData ? `directly` : `as "${clientToken.key}"`);
923
- clearSubscriptions();
924
- socket.emit(`serve:${clientToken.key}`, getFromStore(store, serverData));
925
- subscriptions.add(subscribeToState(store, serverData, `expose-single:${socket.id}`, ({ newValue }) => {
926
- socket.emit(`serve:${clientToken.key}`, newValue);
927
- }));
928
- subscriptions.add(employSocket(socket, `unsub:${serverData.key}`, () => {
929
- store.logger.info(`🙈`, `user`, userKey, `unsubscribes from state "${serverData.key}", served`, clientToken === serverData ? `directly` : `as "${clientToken.key}"`);
930
- clearSubscriptions();
931
- start();
932
- }));
933
- }
934
- }));
935
- };
936
- start();
937
- return clearSubscriptions;
938
- };
939
- }
940
-
941
975
  //#endregion
942
976
  //#region src/realtime-server/realtime-state-receiver.ts
943
- function realtimeStateReceiver({ socket, userKey, store = IMPLICIT.STORE }) {
977
+ function realtimeStateReceiver({ socket, consumer, store = IMPLICIT.STORE }) {
944
978
  return function stateReceiver(schema, clientToken, serverToken = clientToken) {
945
979
  const socketKey = `socket::${socket.id}`;
946
980
  const mutexAtom = findInStore(store, mutexAtoms, serverToken.key);
@@ -954,7 +988,7 @@ function realtimeStateReceiver({ socket, userKey, store = IMPLICIT.STORE }) {
954
988
  subscriptions.add(employSocket(socket, `pub:${clientToken.key}`, async (newValue) => {
955
989
  const parsed = await schema[`~standard`].validate(newValue);
956
990
  if (parsed.issues) {
957
- store.logger.error(`❌`, `user`, userKey, `attempted to publish invalid value`, newValue, `to state "${serverToken.key}"`);
991
+ store.logger.error(`❌`, `user`, consumer, `attempted to publish invalid value`, newValue, `to state "${serverToken.key}"`);
958
992
  return;
959
993
  }
960
994
  setIntoStore(store, serverToken, parsed.value);
@@ -996,11 +1030,11 @@ const socketAtoms = atomFamily({
996
1030
  default: null
997
1031
  });
998
1032
  const socketKeysAtom = mutableAtom({
999
- key: `socketsIndex`,
1033
+ key: `socketKeys`,
1000
1034
  class: UList
1001
1035
  });
1002
- const userKeysAtom = mutableAtom({
1003
- key: `usersIndex`,
1036
+ const onlineUsersAtom = mutableAtom({
1037
+ key: `onlineUsers`,
1004
1038
  class: UList
1005
1039
  });
1006
1040
  const usersOfSockets = join({
@@ -1027,29 +1061,26 @@ function realtime(server, auth, onConnect, store = IMPLICIT.STORE) {
1027
1061
  editRelationsInStore(store, usersOfSockets, (relations) => {
1028
1062
  relations.set(userClaim, socketClaim);
1029
1063
  });
1030
- setIntoStore(store, userKeysAtom, (index) => index.add(userClaim));
1064
+ setIntoStore(store, onlineUsersAtom, (index) => index.add(userClaim));
1031
1065
  setIntoStore(store, socketKeysAtom, (index) => index.add(socketClaim));
1032
1066
  next();
1033
1067
  }).on(`connection`, async (socket) => {
1034
1068
  const socketKey = `socket::${socket.id}`;
1035
- const userKeyState = findRelationsInStore(store, usersOfSockets, socketKey).userKeyOfSocket;
1036
- const userKey = getFromStore(store, userKeyState);
1069
+ const userKeySelector = findRelationsInStore(store, usersOfSockets, socketKey).userKeyOfSocket;
1070
+ const userKey = getFromStore(store, userKeySelector);
1037
1071
  const serverConfig = {
1038
1072
  store,
1039
1073
  socket,
1040
- userKey
1074
+ consumer: userKey
1041
1075
  };
1042
- const unsubFromMyUserKey = realtimeStateProvider(serverConfig)({
1043
- key: `myUserKey`,
1044
- type: `atom`
1045
- }, userKey);
1076
+ const unsubFromMyUserKey = realtimeStateProvider(serverConfig)(myUserKeyAtom, userKey);
1046
1077
  const disposeServices = await onConnect(serverConfig);
1047
1078
  socket.on(`disconnect`, async () => {
1048
1079
  store.logger.info(`📡`, `socket`, socketKey, `👤 ${userKey} disconnects`);
1049
1080
  await disposeServices();
1050
1081
  unsubFromMyUserKey();
1051
1082
  editRelationsInStore(store, usersOfSockets, (rel) => rel.delete(socketKey));
1052
- setIntoStore(store, userKeysAtom, (keys) => (keys.delete(userKey), keys));
1083
+ setIntoStore(store, onlineUsersAtom, (keys) => (keys.delete(userKey), keys));
1053
1084
  setIntoStore(store, socketKeysAtom, (keys) => (keys.delete(socketKey), keys));
1054
1085
  });
1055
1086
  });
@@ -1060,5 +1091,5 @@ function realtime(server, auth, onConnect, store = IMPLICIT.STORE) {
1060
1091
  }
1061
1092
 
1062
1093
  //#endregion
1063
- export { ChildSocket, CustomSocket, PROOF_OF_LIFE_SIGNAL, ParentSocket, ROOMS, SubjectSocket, destroyRoom, prepareToProvideContinuity, provideEnterAndExit, provideRooms, realtime, realtimeAtomFamilyProvider, realtimeMutableFamilyProvider, realtimeMutableProvider, realtimeStateProvider, realtimeStateReceiver, roomMeta, socketAtoms, socketKeysAtom, spawnRoom, userKeysAtom, usersOfSockets };
1094
+ export { ChildSocket, CustomSocket, PROOF_OF_LIFE_SIGNAL, ParentSocket, ROOMS, SubjectSocket, destroyRoom, onlineUsersAtom, prepareToProvideContinuity, provideEnterAndExit, provideRooms, realtime, realtimeAtomFamilyProvider, realtimeMutableFamilyProvider, realtimeMutableProvider, realtimeStateProvider, realtimeStateReceiver, roomMeta, socketAtoms, socketKeysAtom, spawnRoom, usersOfSockets };
1064
1095
  //# sourceMappingURL=index.js.map