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
|
@@ -23,7 +23,7 @@ export type RoomSocketInterface<RoomNames extends string> = {
|
|
|
23
23
|
}
|
|
24
24
|
|
|
25
25
|
export const roomKeysAtom: MutableAtomToken<UList<RoomKey>> = mutableAtom({
|
|
26
|
-
key: `
|
|
26
|
+
key: `roomKeys`,
|
|
27
27
|
class: UList,
|
|
28
28
|
})
|
|
29
29
|
|
|
@@ -43,10 +43,10 @@ export const usersInRooms: JoinToken<`room`, RoomKey, `user`, UserKey, `1:n`> =
|
|
|
43
43
|
})
|
|
44
44
|
|
|
45
45
|
export const visibleUsersInRoomsSelector: PureSelectorFamilyToken<
|
|
46
|
-
|
|
46
|
+
[self: UserKey, ...RoomKey[]],
|
|
47
47
|
UserKey
|
|
48
48
|
> = selectorFamily({
|
|
49
|
-
key: `
|
|
49
|
+
key: `visibleUsersInRooms`,
|
|
50
50
|
get:
|
|
51
51
|
(userKey) =>
|
|
52
52
|
({ get }) => {
|
|
@@ -56,6 +56,41 @@ export const visibleUsersInRoomsSelector: PureSelectorFamilyToken<
|
|
|
56
56
|
},
|
|
57
57
|
})
|
|
58
58
|
|
|
59
|
+
export const visibilityFromRoomSelector: PureSelectorFamilyToken<
|
|
60
|
+
[self: RoomKey, ...UserKey[]],
|
|
61
|
+
RoomKey
|
|
62
|
+
> = selectorFamily({
|
|
63
|
+
key: `visibilityFromRoom`,
|
|
64
|
+
get:
|
|
65
|
+
(roomKey) =>
|
|
66
|
+
({ get }) => {
|
|
67
|
+
const [usersOfRoomsAtoms] = getInternalRelations(usersInRooms, `split`)
|
|
68
|
+
const users = get(usersOfRoomsAtoms, roomKey)
|
|
69
|
+
return [roomKey, ...users]
|
|
70
|
+
},
|
|
71
|
+
})
|
|
72
|
+
|
|
73
|
+
export const mutualUsersSelector: ReadonlyPureSelectorFamilyToken<
|
|
74
|
+
UserKey[],
|
|
75
|
+
UserKey
|
|
76
|
+
> = selectorFamily({
|
|
77
|
+
key: `mutualUsers`,
|
|
78
|
+
get:
|
|
79
|
+
(userKey) =>
|
|
80
|
+
({ get }) => {
|
|
81
|
+
const [usersOfRoomsAtoms, roomsOfUsersAtoms] = getInternalRelations(
|
|
82
|
+
usersInRooms,
|
|
83
|
+
`split`,
|
|
84
|
+
)
|
|
85
|
+
const rooms = get(roomsOfUsersAtoms, userKey)
|
|
86
|
+
for (const room of rooms) {
|
|
87
|
+
const users = get(usersOfRoomsAtoms, room)
|
|
88
|
+
return [...users]
|
|
89
|
+
}
|
|
90
|
+
return []
|
|
91
|
+
},
|
|
92
|
+
})
|
|
93
|
+
|
|
59
94
|
export const ownersOfRooms: JoinToken<`user`, UserKey, `room`, RoomKey, `1:n`> =
|
|
60
95
|
join({
|
|
61
96
|
key: `ownersOfRooms`,
|
|
@@ -64,17 +99,3 @@ export const ownersOfRooms: JoinToken<`user`, UserKey, `room`, RoomKey, `1:n`> =
|
|
|
64
99
|
isAType: isUserKey,
|
|
65
100
|
isBType: isRoomKey,
|
|
66
101
|
})
|
|
67
|
-
|
|
68
|
-
export const usersInMyRoomView: ReadonlyPureSelectorFamilyToken<
|
|
69
|
-
MutableAtomToken<UList<RoomKey>>[],
|
|
70
|
-
UserKey
|
|
71
|
-
> = selectorFamily({
|
|
72
|
-
key: `usersInMyRoomView`,
|
|
73
|
-
get:
|
|
74
|
-
(myUsername) =>
|
|
75
|
-
({ find }) => {
|
|
76
|
-
const [, roomsOfUsersAtoms] = getInternalRelations(usersInRooms, `split`)
|
|
77
|
-
const myRoomIndex = find(roomsOfUsersAtoms, myUsername)
|
|
78
|
-
return [myRoomIndex]
|
|
79
|
-
},
|
|
80
|
-
})
|
|
@@ -48,7 +48,7 @@ export type Socket = {
|
|
|
48
48
|
onAnyOutgoing: (
|
|
49
49
|
listener: (event: string, ...args: Json.Serializable[]) => void,
|
|
50
50
|
) => void
|
|
51
|
-
off: (event: string, listener
|
|
51
|
+
off: (event: string, listener?: (...args: Json.Serializable[]) => void) => void
|
|
52
52
|
offAny: (
|
|
53
53
|
listener: (event: string, ...args: Json.Serializable[]) => void,
|
|
54
54
|
) => void
|
|
@@ -7,6 +7,7 @@ import {
|
|
|
7
7
|
setEpochNumberOfContinuity,
|
|
8
8
|
setIntoStore,
|
|
9
9
|
} from "atom.io/internal"
|
|
10
|
+
import type { Json } from "atom.io/json"
|
|
10
11
|
import type { Socket } from "atom.io/realtime"
|
|
11
12
|
|
|
12
13
|
import {
|
|
@@ -27,7 +28,8 @@ export const useRegisterAndAttemptConfirmedUpdate =
|
|
|
27
28
|
>[],
|
|
28
29
|
) =>
|
|
29
30
|
(
|
|
30
|
-
confirmed: AtomIO.TransactionOutcomeEvent<AtomIO.TransactionToken<Fn
|
|
31
|
+
confirmed: AtomIO.TransactionOutcomeEvent<AtomIO.TransactionToken<Fn>> &
|
|
32
|
+
Json.Serializable,
|
|
31
33
|
): void => {
|
|
32
34
|
function reconcileEpoch(
|
|
33
35
|
optimisticUpdate: AtomIO.TransactionOutcomeEvent<
|
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
import type { AtomToken } from "atom.io"
|
|
2
2
|
import type { Store } from "atom.io/internal"
|
|
3
3
|
import { disposeAtom } from "atom.io/internal"
|
|
4
|
+
import type { Json } from "atom.io/json"
|
|
4
5
|
|
|
5
6
|
export function useConcealState(store: Store) {
|
|
6
|
-
return (concealed: AtomToken<
|
|
7
|
+
return (concealed: AtomToken<Json.Serializable>[]): void => {
|
|
7
8
|
for (const token of concealed) {
|
|
8
9
|
disposeAtom(store, token)
|
|
9
10
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type * as AtomIO from "atom.io"
|
|
2
2
|
import { findInStore, setIntoStore, type Store } from "atom.io/internal"
|
|
3
3
|
import type { Canonical, Json } from "atom.io/json"
|
|
4
|
-
import type { Socket } from "
|
|
4
|
+
import type { Socket } from "atom.io/realtime"
|
|
5
5
|
|
|
6
6
|
export function pullAtomFamilyMember<
|
|
7
7
|
J extends Json.Serializable,
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type * as AtomIO from "atom.io"
|
|
2
2
|
import { setIntoStore, type Store } from "atom.io/internal"
|
|
3
3
|
import type { Json } from "atom.io/json"
|
|
4
|
-
import type { Socket } from "
|
|
4
|
+
import type { Socket } from "atom.io/realtime"
|
|
5
5
|
|
|
6
6
|
export function pullAtom<J extends Json.Serializable>(
|
|
7
7
|
store: Store,
|
|
@@ -7,7 +7,7 @@ import {
|
|
|
7
7
|
setIntoStore,
|
|
8
8
|
} from "atom.io/internal"
|
|
9
9
|
import type { Canonical } from "atom.io/json"
|
|
10
|
-
import type { Socket } from "
|
|
10
|
+
import type { Socket } from "atom.io/realtime"
|
|
11
11
|
|
|
12
12
|
export function pullMutableAtomFamilyMember<
|
|
13
13
|
T extends Transceiver<any, any, any>,
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type * as AtomIO from "atom.io"
|
|
2
2
|
import type { AsJSON, SignalFrom, Store, Transceiver } from "atom.io/internal"
|
|
3
3
|
import { getJsonToken, getUpdateToken, setIntoStore } from "atom.io/internal"
|
|
4
|
-
import type { Socket } from "
|
|
4
|
+
import type { Socket } from "atom.io/realtime"
|
|
5
5
|
|
|
6
6
|
export function pullMutableAtom<T extends Transceiver<any, any, any>>(
|
|
7
7
|
store: Store,
|
|
@@ -2,7 +2,7 @@ import type * as AtomIO from "atom.io"
|
|
|
2
2
|
import type { Store } from "atom.io/internal"
|
|
3
3
|
import { findInStore } from "atom.io/internal"
|
|
4
4
|
import type { Canonical } from "atom.io/json"
|
|
5
|
-
import type { Socket } from "
|
|
5
|
+
import type { Socket } from "atom.io/realtime"
|
|
6
6
|
|
|
7
7
|
import { pullSelectorRoots } from "./pull-selector-roots"
|
|
8
8
|
|
|
@@ -2,7 +2,7 @@ import type { AtomToken, SelectorToken } from "atom.io"
|
|
|
2
2
|
import type { Store } from "atom.io/internal"
|
|
3
3
|
import { getFamilyOfToken, subscribeToState } from "atom.io/internal"
|
|
4
4
|
import { parseJson } from "atom.io/json"
|
|
5
|
-
import type { Socket } from "
|
|
5
|
+
import type { Socket } from "atom.io/realtime"
|
|
6
6
|
|
|
7
7
|
import { pullAtom } from "./pull-atom"
|
|
8
8
|
import { pullAtomFamilyMember } from "./pull-atom-family-member"
|
|
@@ -2,8 +2,8 @@ import type { WritableToken } from "atom.io"
|
|
|
2
2
|
import type { Store } from "atom.io/internal"
|
|
3
3
|
import { setIntoStore, subscribeToState } from "atom.io/internal"
|
|
4
4
|
import type { Json } from "atom.io/json"
|
|
5
|
+
import type { Socket } from "atom.io/realtime"
|
|
5
6
|
import { employSocket, mutexAtoms } from "atom.io/realtime"
|
|
6
|
-
import type { Socket } from "socket.io-client"
|
|
7
7
|
|
|
8
8
|
export function pushState<J extends Json.Serializable>(
|
|
9
9
|
store: Store,
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import * as AtomIO from "atom.io"
|
|
2
|
-
import type { SocketKey, UserKey } from "atom.io/realtime"
|
|
3
|
-
import { storageSync } from "atom.io/web"
|
|
2
|
+
import type { RoomKey, SocketKey, UserKey } from "atom.io/realtime"
|
|
4
3
|
|
|
5
4
|
export const mySocketKeyAtom: AtomIO.RegularAtomToken<SocketKey | undefined> =
|
|
6
5
|
AtomIO.atom<SocketKey | undefined>({
|
|
@@ -12,5 +11,19 @@ export const myUserKeyAtom: AtomIO.RegularAtomToken<UserKey | null> =
|
|
|
12
11
|
AtomIO.atom<UserKey | null>({
|
|
13
12
|
key: `myUserKey`,
|
|
14
13
|
default: null,
|
|
15
|
-
effects: [
|
|
14
|
+
effects: [
|
|
15
|
+
(userKey) => {
|
|
16
|
+
if (typeof window !== `undefined`) {
|
|
17
|
+
void import(`atom.io/web`).then(({ storageSync }) => {
|
|
18
|
+
storageSync(globalThis.localStorage, JSON, `myUserKey`)(userKey)
|
|
19
|
+
})
|
|
20
|
+
}
|
|
21
|
+
},
|
|
22
|
+
],
|
|
23
|
+
})
|
|
24
|
+
|
|
25
|
+
export const myRoomKeyAtom: AtomIO.RegularAtomToken<RoomKey | null> =
|
|
26
|
+
AtomIO.atom<RoomKey | null>({
|
|
27
|
+
key: `myRoomKey`,
|
|
28
|
+
default: null,
|
|
16
29
|
})
|
|
@@ -8,8 +8,7 @@ import {
|
|
|
8
8
|
subscribeToTransaction,
|
|
9
9
|
} from "atom.io/internal"
|
|
10
10
|
import type { Json } from "atom.io/json"
|
|
11
|
-
import type { ContinuityToken } from "atom.io/realtime"
|
|
12
|
-
import type { Socket } from "socket.io-client"
|
|
11
|
+
import type { ContinuityToken, Socket } from "atom.io/realtime"
|
|
13
12
|
|
|
14
13
|
import { useRegisterAndAttemptConfirmedUpdate } from "./continuity/register-and-attempt-confirmed-update"
|
|
15
14
|
import { useConcealState } from "./continuity/use-conceal-state"
|
|
@@ -1,13 +1,61 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { MutableAtomToken } from "atom.io"
|
|
2
|
+
import { findInStore, getInternalRelationsFromStore } from "atom.io/internal"
|
|
3
|
+
import { StoreContext, useO } from "atom.io/react"
|
|
4
|
+
import type { RoomKey, RoomSocketInterface, UserKey } from "atom.io/realtime"
|
|
5
|
+
import { ownersOfRooms, roomKeysAtom, usersInRooms } from "atom.io/realtime"
|
|
6
|
+
import type { UList } from "atom.io/transceivers/u-list"
|
|
2
7
|
import * as React from "react"
|
|
3
8
|
import type { Socket } from "socket.io-client"
|
|
4
9
|
|
|
5
10
|
import { RealtimeContext } from "./realtime-context"
|
|
11
|
+
import { usePullMutable } from "./use-pull-mutable-atom"
|
|
12
|
+
import { usePullMutableAtomFamilyMember } from "./use-pull-mutable-family-member"
|
|
6
13
|
|
|
7
|
-
export
|
|
8
|
-
{},
|
|
9
|
-
|
|
10
|
-
|
|
14
|
+
export type RealtimeRoomsTools = {
|
|
15
|
+
socket: Socket<{}, RoomSocketInterface<string>>
|
|
16
|
+
myRoomKey: RoomKey | undefined
|
|
17
|
+
myMutualsAtom: MutableAtomToken<UList<UserKey>>
|
|
18
|
+
myOwnedRoomsAtom: MutableAtomToken<UList<RoomKey>>
|
|
19
|
+
allRoomKeysAtom: MutableAtomToken<UList<RoomKey>>
|
|
20
|
+
}
|
|
21
|
+
export function useRealtimeRooms<RoomNames extends string>(
|
|
22
|
+
userKey: UserKey,
|
|
23
|
+
): RealtimeRoomsTools {
|
|
24
|
+
const store = React.useContext(StoreContext)
|
|
11
25
|
const { socket } = React.useContext(RealtimeContext)
|
|
12
|
-
|
|
26
|
+
usePullMutable(roomKeysAtom)
|
|
27
|
+
|
|
28
|
+
const [userKeysFamily, roomKeysFamily] = getInternalRelationsFromStore(
|
|
29
|
+
store,
|
|
30
|
+
usersInRooms,
|
|
31
|
+
`split`,
|
|
32
|
+
)
|
|
33
|
+
|
|
34
|
+
usePullMutableAtomFamilyMember(roomKeysFamily, userKey)
|
|
35
|
+
const myJoinedRoomKeys = useO(roomKeysFamily, userKey)
|
|
36
|
+
let myRoomKey: RoomKey | undefined
|
|
37
|
+
for (const roomKey of myJoinedRoomKeys) {
|
|
38
|
+
myRoomKey = roomKey
|
|
39
|
+
break
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
const roomKey = myRoomKey ?? `room::$_NONE_$`
|
|
43
|
+
const myMutualsAtom = findInStore(store, userKeysFamily, roomKey)
|
|
44
|
+
usePullMutableAtomFamilyMember(userKeysFamily, roomKey)
|
|
45
|
+
|
|
46
|
+
const [ownedRoomsFamily] = getInternalRelationsFromStore(
|
|
47
|
+
store,
|
|
48
|
+
ownersOfRooms,
|
|
49
|
+
`split`,
|
|
50
|
+
)
|
|
51
|
+
const myOwnedRoomsAtom = findInStore(store, ownedRoomsFamily, userKey)
|
|
52
|
+
usePullMutableAtomFamilyMember(ownedRoomsFamily, userKey)
|
|
53
|
+
|
|
54
|
+
return {
|
|
55
|
+
socket: socket as Socket<{}, RoomSocketInterface<RoomNames>>,
|
|
56
|
+
myRoomKey,
|
|
57
|
+
allRoomKeysAtom: roomKeysAtom,
|
|
58
|
+
myMutualsAtom,
|
|
59
|
+
myOwnedRoomsAtom,
|
|
60
|
+
}
|
|
13
61
|
}
|
|
@@ -66,10 +66,10 @@ export class ParentSocket<
|
|
|
66
66
|
protected incompleteData = ``
|
|
67
67
|
protected unprocessedEvents: string[] = []
|
|
68
68
|
protected relays: Map<string, SubjectSocket<any, any>>
|
|
69
|
-
protected
|
|
69
|
+
protected initRelay: (
|
|
70
70
|
socket: SubjectSocket<any, any>,
|
|
71
71
|
userKey: UserKey,
|
|
72
|
-
) => (() => void) | void
|
|
72
|
+
) => (() => void) | void
|
|
73
73
|
public proc: P
|
|
74
74
|
|
|
75
75
|
public id = `#####`
|
|
@@ -104,7 +104,9 @@ export class ParentSocket<
|
|
|
104
104
|
this.proc = proc
|
|
105
105
|
this.proc.stdin.resume()
|
|
106
106
|
this.relays = new Map()
|
|
107
|
-
this.
|
|
107
|
+
this.initRelay = () => {
|
|
108
|
+
this.logger.info(`🔗`, `nothing to relay`)
|
|
109
|
+
}
|
|
108
110
|
|
|
109
111
|
this.proc.stdin.on(
|
|
110
112
|
`data`,
|
|
@@ -174,19 +176,13 @@ export class ParentSocket<
|
|
|
174
176
|
}
|
|
175
177
|
|
|
176
178
|
this.on(`user-joins`, (userKey: UserKey) => {
|
|
177
|
-
this.logger.info(`👤`,
|
|
179
|
+
this.logger.info(`👤`, userKey, `joined`)
|
|
178
180
|
const relay = new SubjectSocket(userKey)
|
|
179
181
|
this.relays.set(userKey, relay)
|
|
180
|
-
this.logger.info(
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
)
|
|
185
|
-
for (const attachRelay of this.relayServices) {
|
|
186
|
-
const cleanupRelay = attachRelay(relay, userKey)
|
|
187
|
-
if (cleanupRelay) {
|
|
188
|
-
relay.disposalFunctions.push(cleanupRelay)
|
|
189
|
-
}
|
|
182
|
+
this.logger.info(`🔗`, `attaching services for user`, userKey)
|
|
183
|
+
const cleanupRelay = this.initRelay(relay, userKey)
|
|
184
|
+
if (cleanupRelay) {
|
|
185
|
+
relay.disposalFunctions.push(cleanupRelay)
|
|
190
186
|
}
|
|
191
187
|
this.on(userKey, (...data) => {
|
|
192
188
|
relay.in.next(data)
|
|
@@ -215,6 +211,6 @@ export class ParentSocket<
|
|
|
215
211
|
) => (() => void) | void,
|
|
216
212
|
): void {
|
|
217
213
|
this.logger.info(`🔗`, `running relay method`)
|
|
218
|
-
this.
|
|
214
|
+
this.initRelay = attachServices
|
|
219
215
|
}
|
|
220
216
|
}
|
|
@@ -29,13 +29,15 @@ import {
|
|
|
29
29
|
ownersOfRooms,
|
|
30
30
|
roomKeysAtom,
|
|
31
31
|
usersInRooms,
|
|
32
|
+
visibilityFromRoomSelector,
|
|
32
33
|
visibleUsersInRoomsSelector,
|
|
33
34
|
} from "atom.io/realtime"
|
|
35
|
+
import { myRoomKeyAtom } from "atom.io/realtime-client"
|
|
34
36
|
|
|
35
37
|
import { ChildSocket, PROOF_OF_LIFE_SIGNAL } from "./ipc-sockets"
|
|
36
38
|
import { realtimeMutableFamilyProvider } from "./realtime-mutable-family-provider"
|
|
37
39
|
import { realtimeMutableProvider } from "./realtime-mutable-provider"
|
|
38
|
-
import
|
|
40
|
+
import { realtimeStateProvider } from "./realtime-state-provider"
|
|
39
41
|
|
|
40
42
|
export type RoomMap = Map<
|
|
41
43
|
string,
|
|
@@ -87,19 +89,47 @@ export function spawnRoom<RoomNames extends string>({
|
|
|
87
89
|
room.stdout.on(`data`, resolver)
|
|
88
90
|
},
|
|
89
91
|
)
|
|
90
|
-
const roomSocket = new ChildSocket(child, roomKey)
|
|
91
|
-
ROOMS.set(roomKey, roomSocket)
|
|
92
|
-
setIntoStore(store, roomKeysAtom, (index) => (index.add(roomKey), index))
|
|
93
92
|
|
|
93
|
+
const room = new ChildSocket(child, roomKey)
|
|
94
|
+
ROOMS.set(roomKey, room)
|
|
95
|
+
setIntoStore(store, roomKeysAtom, (index) => (index.add(roomKey), index))
|
|
94
96
|
editRelationsInStore(store, ownersOfRooms, (relations) => {
|
|
95
97
|
relations.set({ room: roomKey, user: userKey })
|
|
96
98
|
})
|
|
97
99
|
|
|
98
|
-
|
|
100
|
+
const provideMutableFamily = realtimeMutableFamilyProvider({
|
|
101
|
+
socket: room,
|
|
102
|
+
consumer: roomKey,
|
|
103
|
+
store,
|
|
104
|
+
})
|
|
105
|
+
const provideState = realtimeStateProvider({
|
|
106
|
+
socket: room,
|
|
107
|
+
consumer: roomKey,
|
|
108
|
+
store,
|
|
109
|
+
})
|
|
110
|
+
const unsubFromRoomKey = provideState(myRoomKeyAtom, roomKey)
|
|
111
|
+
|
|
112
|
+
const ownersOfRoomsAtoms = getInternalRelationsFromStore(
|
|
113
|
+
store,
|
|
114
|
+
ownersOfRooms,
|
|
115
|
+
)
|
|
116
|
+
const unsubFromOwnerKeys = provideMutableFamily(ownersOfRoomsAtoms, [
|
|
117
|
+
roomKey,
|
|
118
|
+
])
|
|
119
|
+
const usersInRoomsAtoms = getInternalRelationsFromStore(store, usersInRooms)
|
|
120
|
+
const unsubFromUsersInRooms = provideMutableFamily(
|
|
121
|
+
usersInRoomsAtoms,
|
|
122
|
+
findInStore(store, visibilityFromRoomSelector, roomKey),
|
|
123
|
+
)
|
|
124
|
+
|
|
125
|
+
room.on(`close`, () => {
|
|
126
|
+
unsubFromRoomKey()
|
|
127
|
+
unsubFromOwnerKeys()
|
|
128
|
+
unsubFromUsersInRooms()
|
|
99
129
|
destroyRoom({ store, socket, userKey })(roomKey)
|
|
100
130
|
})
|
|
101
131
|
|
|
102
|
-
return
|
|
132
|
+
return room
|
|
103
133
|
}
|
|
104
134
|
}
|
|
105
135
|
|
|
@@ -115,7 +145,7 @@ export function provideEnterAndExit({
|
|
|
115
145
|
roomSocket,
|
|
116
146
|
userKey,
|
|
117
147
|
}: ProvideEnterAndExitConfig): (roomKey: RoomKey) => void {
|
|
118
|
-
const enterRoom = (roomKey: RoomKey) => {
|
|
148
|
+
const enterRoom = (roomKey: RoomKey): void => {
|
|
119
149
|
store.logger.info(
|
|
120
150
|
`📡`,
|
|
121
151
|
`socket`,
|
|
@@ -123,6 +153,10 @@ export function provideEnterAndExit({
|
|
|
123
153
|
`👤 ${userKey} enters room ${roomKey}`,
|
|
124
154
|
)
|
|
125
155
|
|
|
156
|
+
const dcUserFromRoom = () => {
|
|
157
|
+
toRoom([`user-leaves`])
|
|
158
|
+
}
|
|
159
|
+
|
|
126
160
|
const exitRoom = () => {
|
|
127
161
|
store.logger.info(
|
|
128
162
|
`📡`,
|
|
@@ -131,17 +165,15 @@ export function provideEnterAndExit({
|
|
|
131
165
|
`👤 ${userKey} leaves room ${roomKey}`,
|
|
132
166
|
)
|
|
133
167
|
socket.offAny(forward)
|
|
134
|
-
|
|
168
|
+
dcUserFromRoom()
|
|
135
169
|
editRelationsInStore(store, usersInRooms, (relations) => {
|
|
136
170
|
relations.delete({ room: roomKey, user: userKey })
|
|
137
171
|
})
|
|
172
|
+
|
|
138
173
|
roomSocket.off(`leaveRoom`, exitRoom)
|
|
139
174
|
roomSocket.on(`joinRoom`, enterRoom)
|
|
140
175
|
}
|
|
141
176
|
|
|
142
|
-
roomSocket.on(`leaveRoom`, exitRoom)
|
|
143
|
-
roomSocket.off(`joinRoom`, enterRoom)
|
|
144
|
-
|
|
145
177
|
const roomQueue: [string, ...Json.Array][] = []
|
|
146
178
|
const pushToRoomQueue = (payload: [string, ...Json.Array]): void => {
|
|
147
179
|
roomQueue.push(payload)
|
|
@@ -158,7 +190,7 @@ export function provideEnterAndExit({
|
|
|
158
190
|
const childSocket = ROOMS.get(roomKey)
|
|
159
191
|
if (!childSocket) {
|
|
160
192
|
store.logger.error(`❌`, `unknown`, roomKey, `no room found with this id`)
|
|
161
|
-
return
|
|
193
|
+
return
|
|
162
194
|
}
|
|
163
195
|
childSocket.onAny((...payload) => {
|
|
164
196
|
socket.emit(...payload)
|
|
@@ -172,6 +204,10 @@ export function provideEnterAndExit({
|
|
|
172
204
|
const payload = roomQueue.shift()
|
|
173
205
|
if (payload) toRoom(payload)
|
|
174
206
|
}
|
|
207
|
+
|
|
208
|
+
socket.on(`disconnect`, dcUserFromRoom)
|
|
209
|
+
roomSocket.on(`leaveRoom`, exitRoom)
|
|
210
|
+
roomSocket.off(`joinRoom`, enterRoom)
|
|
175
211
|
}
|
|
176
212
|
roomSocket.on(`joinRoom`, enterRoom)
|
|
177
213
|
return enterRoom
|
|
@@ -229,6 +265,9 @@ export type ProvideRoomsConfig<RoomNames extends string> = {
|
|
|
229
265
|
resolveRoomScript: (path: RoomNames) => [string, string[]]
|
|
230
266
|
roomNames: RoomNames[]
|
|
231
267
|
roomTimeLimit?: number
|
|
268
|
+
userKey: UserKey
|
|
269
|
+
store: RootStore
|
|
270
|
+
socket: Socket
|
|
232
271
|
}
|
|
233
272
|
export function provideRooms<RoomNames extends string>({
|
|
234
273
|
store = IMPLICIT.STORE,
|
|
@@ -236,11 +275,15 @@ export function provideRooms<RoomNames extends string>({
|
|
|
236
275
|
resolveRoomScript,
|
|
237
276
|
roomNames,
|
|
238
277
|
userKey,
|
|
239
|
-
}: ProvideRoomsConfig<RoomNames>
|
|
278
|
+
}: ProvideRoomsConfig<RoomNames>): () => void {
|
|
240
279
|
const roomSocket = castSocket<
|
|
241
280
|
TypedSocket<RoomSocketInterface<RoomNames>, never>
|
|
242
281
|
>(socket, createRoomSocketGuard(roomNames))
|
|
243
|
-
const exposeMutable = realtimeMutableProvider({
|
|
282
|
+
const exposeMutable = realtimeMutableProvider({
|
|
283
|
+
socket,
|
|
284
|
+
store,
|
|
285
|
+
consumer: userKey,
|
|
286
|
+
})
|
|
244
287
|
const unsubFromRoomKeys = exposeMutable(roomKeysAtom)
|
|
245
288
|
const usersInRoomsAtoms = getInternalRelationsFromStore(store, usersInRooms)
|
|
246
289
|
const [, usersInRoomsAtomsUsersOnly] = getInternalRelationsFromStore(
|
|
@@ -257,7 +300,7 @@ export function provideRooms<RoomNames extends string>({
|
|
|
257
300
|
const exposeMutableFamily = realtimeMutableFamilyProvider({
|
|
258
301
|
socket,
|
|
259
302
|
store,
|
|
260
|
-
userKey,
|
|
303
|
+
consumer: userKey,
|
|
261
304
|
})
|
|
262
305
|
const unsubFromUsersInRooms = exposeMutableFamily(
|
|
263
306
|
usersInRoomsAtoms,
|
|
@@ -267,7 +310,12 @@ export function provideRooms<RoomNames extends string>({
|
|
|
267
310
|
ownersOfRoomsAtoms,
|
|
268
311
|
usersWhoseRoomsCanBeSeenSelector,
|
|
269
312
|
)
|
|
270
|
-
const enterRoom = provideEnterAndExit({
|
|
313
|
+
const enterRoom = provideEnterAndExit({
|
|
314
|
+
store,
|
|
315
|
+
socket,
|
|
316
|
+
roomSocket,
|
|
317
|
+
userKey,
|
|
318
|
+
})
|
|
271
319
|
|
|
272
320
|
const userRoomSet = getFromStore(store, usersInRoomsAtomsUsersOnly, userKey)
|
|
273
321
|
for (const userRoomKey of userRoomSet) {
|