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.
- package/dist/realtime/index.d.ts +7 -6
- package/dist/realtime/index.d.ts.map +1 -1
- package/dist/realtime/index.js +19 -10
- package/dist/realtime/index.js.map +1 -1
- package/dist/realtime-client/index.d.ts +13 -13
- package/dist/realtime-client/index.d.ts.map +1 -1
- package/dist/realtime-client/index.js +10 -3
- package/dist/realtime-client/index.js.map +1 -1
- package/dist/realtime-react/index.d.ts +12 -3
- package/dist/realtime-react/index.d.ts.map +1 -1
- package/dist/realtime-react/index.js +26 -3
- package/dist/realtime-react/index.js.map +1 -1
- package/dist/realtime-server/index.d.ts +50 -42
- package/dist/realtime-server/index.d.ts.map +1 -1
- package/dist/realtime-server/index.js +132 -101
- package/dist/realtime-server/index.js.map +1 -1
- package/dist/realtime-testing/index.js +2 -2
- package/dist/realtime-testing/index.js.map +1 -1
- package/package.json +20 -19
- package/src/realtime/realtime-continuity.ts +2 -2
- package/src/realtime/shared-room-store.ts +38 -17
- package/src/realtime/socket-interface.ts +1 -1
- package/src/realtime-client/continuity/register-and-attempt-confirmed-update.ts +3 -1
- package/src/realtime-client/continuity/use-conceal-state.ts +2 -1
- package/src/realtime-client/pull-atom-family-member.ts +1 -1
- package/src/realtime-client/pull-atom.ts +1 -1
- package/src/realtime-client/pull-mutable-atom-family-member.ts +1 -1
- package/src/realtime-client/pull-mutable-atom.ts +1 -1
- package/src/realtime-client/pull-selector-family-member.ts +1 -1
- package/src/realtime-client/pull-selector-roots.ts +1 -1
- package/src/realtime-client/pull-selector.ts +1 -1
- package/src/realtime-client/push-state.ts +1 -1
- package/src/realtime-client/realtime-client-stores/client-main-store.ts +16 -3
- package/src/realtime-client/sync-continuity.ts +1 -2
- package/src/realtime-react/use-realtime-rooms.ts +54 -6
- package/src/realtime-server/continuity/provide-outcomes.ts +1 -1
- package/src/realtime-server/ipc-sockets/parent-socket.ts +11 -15
- package/src/realtime-server/provide-rooms.ts +64 -16
- package/src/realtime-server/realtime-family-provider.ts +51 -35
- package/src/realtime-server/realtime-mutable-family-provider.ts +50 -34
- package/src/realtime-server/realtime-mutable-provider.ts +4 -4
- package/src/realtime-server/realtime-state-provider.ts +7 -7
- package/src/realtime-server/realtime-state-receiver.ts +2 -2
- package/src/realtime-server/server-config.ts +20 -13
- package/src/realtime-server/server-socket-state.ts +3 -3
- 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
|
-
|
|
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.
|
|
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(`👤`,
|
|
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
|
|
368
|
-
|
|
369
|
-
|
|
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.
|
|
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,
|
|
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`,
|
|
588
|
+
store.logger.info(`👀`, `user`, consumer, `can subscribe to family "${family.key}"`);
|
|
584
589
|
coreSubscriptions.add(employSocket(socket, `sub:${family.key}`, (subKey) => {
|
|
585
|
-
|
|
586
|
-
|
|
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`,
|
|
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,
|
|
595
|
-
store.logger.info(`👀`, `user`,
|
|
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`,
|
|
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,
|
|
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`,
|
|
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`,
|
|
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`,
|
|
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
|
|
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,
|
|
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
|
-
|
|
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
|
|
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
|
-
|
|
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
|
|
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,
|
|
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`,
|
|
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`,
|
|
945
|
+
store.logger.info(`👀`, `user`, consumer, `can subscribe to family "${family.key}"`);
|
|
874
946
|
coreSubscriptions.add(employSocket(socket, `sub:${family.key}`, (subKey) => {
|
|
875
|
-
|
|
876
|
-
|
|
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`,
|
|
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,
|
|
885
|
-
store.logger.info(`👀`, `user`,
|
|
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`,
|
|
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,
|
|
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`,
|
|
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: `
|
|
1033
|
+
key: `socketKeys`,
|
|
1000
1034
|
class: UList
|
|
1001
1035
|
});
|
|
1002
|
-
const
|
|
1003
|
-
key: `
|
|
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,
|
|
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
|
|
1036
|
-
const userKey = getFromStore(store,
|
|
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,
|
|
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,
|
|
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
|