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
@@ -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: `roomIndex`,
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
- (RoomKey | UserKey)[],
46
+ [self: UserKey, ...RoomKey[]],
47
47
  UserKey
48
48
  > = selectorFamily({
49
- key: `selfList`,
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: (...args: Json.Serializable[]) => void) => void
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<unknown>[]): void => {
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 "socket.io-client"
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 "socket.io-client"
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 "socket.io-client"
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 "socket.io-client"
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 "socket.io-client"
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 "socket.io-client"
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"
@@ -1,6 +1,6 @@
1
1
  import type * as AtomIO from "atom.io"
2
2
  import type { Store } from "atom.io/internal"
3
- import type { Socket } from "socket.io-client"
3
+ import type { Socket } from "atom.io/realtime"
4
4
 
5
5
  import { pullSelectorRoots } from "./pull-selector-roots"
6
6
 
@@ -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: [storageSync(globalThis.localStorage, JSON, `myUserKey`)],
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 { RoomSocketInterface } from "atom.io/realtime"
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 function useRealtimeRooms<RoomNames extends string>(): Socket<
8
- {},
9
- RoomSocketInterface<RoomNames>
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
- return socket as Socket<{}, RoomSocketInterface<RoomNames>>
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
  }
@@ -82,7 +82,7 @@ export function provideOutcomes(
82
82
 
83
83
  socket.emit(
84
84
  `tx-new:${continuityKey}`,
85
- redactedUpdate as Json.Serializable,
85
+ redactedUpdate as unknown as Json.Serializable,
86
86
  )
87
87
  } catch (thrown) {
88
88
  if (thrown instanceof Error) {
@@ -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 relayServices: ((
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.relayServices = []
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(`👤`, `user`, userKey, `joined`)
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
- `attaching services:`,
183
- `[${[...this.relayServices.keys()].join(`, `)}]`,
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.relayServices.push(attachServices)
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 type { ServerConfig } from "./server-config"
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
- roomSocket.on(`close`, () => {
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 roomSocket
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
- toRoom([`user-leaves`])
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 null
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> & ServerConfig): () => void {
278
+ }: ProvideRoomsConfig<RoomNames>): () => void {
240
279
  const roomSocket = castSocket<
241
280
  TypedSocket<RoomSocketInterface<RoomNames>, never>
242
281
  >(socket, createRoomSocketGuard(roomNames))
243
- const exposeMutable = realtimeMutableProvider({ socket, store, userKey })
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({ store, socket, roomSocket, userKey })
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) {