atom.io 0.44.12 → 0.44.13
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/internal/index.js +8 -8
- package/dist/internal/index.js.map +1 -1
- package/dist/introspection/index.d.ts.map +1 -1
- package/dist/main/index.d.ts +6 -4
- package/dist/main/index.d.ts.map +1 -1
- package/dist/main/index.js +4 -3
- package/dist/main/index.js.map +1 -1
- package/dist/realtime/index.d.ts +94 -31
- package/dist/realtime/index.d.ts.map +1 -1
- package/dist/realtime/index.js +34 -1
- package/dist/realtime/index.js.map +1 -1
- package/dist/realtime-react/index.d.ts +3 -1
- package/dist/realtime-react/index.d.ts.map +1 -1
- package/dist/realtime-react/index.js +7 -4
- package/dist/realtime-react/index.js.map +1 -1
- package/dist/realtime-server/index.d.ts +43 -13
- package/dist/realtime-server/index.d.ts.map +1 -1
- package/dist/realtime-server/index.js +120 -63
- package/dist/realtime-server/index.js.map +1 -1
- package/package.json +10 -10
- package/src/internal/families/create-readonly-held-selector-family.ts +2 -2
- package/src/internal/families/create-readonly-pure-selector-family.ts +2 -2
- package/src/internal/families/create-regular-atom-family.ts +2 -2
- package/src/internal/families/create-writable-held-selector-family.ts +2 -2
- package/src/internal/families/create-writable-pure-selector-family.ts +2 -2
- package/src/internal/mutable/create-mutable-atom-family.ts +2 -2
- package/src/internal/not-found-error.ts +2 -2
- package/src/main/logger.ts +8 -4
- package/src/realtime/cast-socket.ts +73 -0
- package/src/realtime/index.ts +2 -0
- package/src/realtime/socket-interface.ts +1 -1
- package/src/realtime/standard-schema.ts +72 -0
- package/src/realtime-react/index.ts +1 -0
- package/src/realtime-react/realtime-context.tsx +0 -9
- package/src/realtime-react/use-realtime-rooms.ts +13 -0
- package/src/realtime-server/realtime-server-stores/index.ts +1 -1
- package/src/realtime-server/realtime-server-stores/provide-rooms.ts +368 -0
- package/src/realtime-server/realtime-server-stores/server-room-external-store.ts +0 -227
|
@@ -1,227 +0,0 @@
|
|
|
1
|
-
import type { ChildProcessWithoutNullStreams } from "node:child_process"
|
|
2
|
-
import { spawn } from "node:child_process"
|
|
3
|
-
|
|
4
|
-
import type { Store } from "atom.io/internal"
|
|
5
|
-
import {
|
|
6
|
-
editRelationsInStore,
|
|
7
|
-
findInStore,
|
|
8
|
-
findRelationsInStore,
|
|
9
|
-
getFromStore,
|
|
10
|
-
getInternalRelationsFromStore,
|
|
11
|
-
IMPLICIT,
|
|
12
|
-
setIntoStore,
|
|
13
|
-
} from "atom.io/internal"
|
|
14
|
-
import type { Json } from "atom.io/json"
|
|
15
|
-
import type {
|
|
16
|
-
AllEventsListener,
|
|
17
|
-
EventsMap,
|
|
18
|
-
RoomKey,
|
|
19
|
-
RoomSocketInterface,
|
|
20
|
-
Socket,
|
|
21
|
-
SocketKey,
|
|
22
|
-
TypedSocket,
|
|
23
|
-
UserKey,
|
|
24
|
-
} from "atom.io/realtime"
|
|
25
|
-
import { ownersOfRooms, roomKeysAtom, usersInRooms } from "atom.io/realtime"
|
|
26
|
-
|
|
27
|
-
import { ChildSocket } from "../ipc-sockets"
|
|
28
|
-
import { realtimeMutableFamilyProvider } from "../realtime-mutable-family-provider"
|
|
29
|
-
import { realtimeMutableProvider } from "../realtime-mutable-provider"
|
|
30
|
-
import type { ServerConfig } from "../server-config"
|
|
31
|
-
import {
|
|
32
|
-
selfListSelectors,
|
|
33
|
-
socketKeysAtom,
|
|
34
|
-
userKeysAtom,
|
|
35
|
-
usersOfSockets,
|
|
36
|
-
} from "./server-user-store"
|
|
37
|
-
|
|
38
|
-
export type RoomMap = Map<
|
|
39
|
-
string,
|
|
40
|
-
ChildSocket<any, any, ChildProcessWithoutNullStreams>
|
|
41
|
-
>
|
|
42
|
-
|
|
43
|
-
declare global {
|
|
44
|
-
var ATOM_IO_REALTIME_SERVER_ROOMS: RoomMap
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
export const ROOMS: RoomMap =
|
|
48
|
-
globalThis.ATOM_IO_REALTIME_SERVER_ROOMS ??
|
|
49
|
-
(globalThis.ATOM_IO_REALTIME_SERVER_ROOMS = new Map())
|
|
50
|
-
|
|
51
|
-
export const roomMeta: { count: number } = { count: 0 }
|
|
52
|
-
|
|
53
|
-
export async function spawnRoom(
|
|
54
|
-
store: Store,
|
|
55
|
-
userKey: UserKey,
|
|
56
|
-
roomKey: RoomKey,
|
|
57
|
-
command: string,
|
|
58
|
-
args: string[],
|
|
59
|
-
): Promise<ChildSocket<any, any>> {
|
|
60
|
-
const child = await new Promise<ChildProcessWithoutNullStreams>((resolve) => {
|
|
61
|
-
const room = spawn(command, args, { env: process.env })
|
|
62
|
-
const resolver = (data: Buffer) => {
|
|
63
|
-
if (data.toString() === `ALIVE`) {
|
|
64
|
-
room.stdout.off(`data`, resolver)
|
|
65
|
-
resolve(room)
|
|
66
|
-
}
|
|
67
|
-
}
|
|
68
|
-
room.stdout.on(`data`, resolver)
|
|
69
|
-
})
|
|
70
|
-
const roomSocket = new ChildSocket(child, roomKey)
|
|
71
|
-
ROOMS.set(roomKey, roomSocket)
|
|
72
|
-
setIntoStore(store, roomKeysAtom, (index) => (index.add(roomKey), index))
|
|
73
|
-
|
|
74
|
-
editRelationsInStore(store, ownersOfRooms, (relations) => {
|
|
75
|
-
relations.set({ room: roomKey, user: userKey })
|
|
76
|
-
})
|
|
77
|
-
|
|
78
|
-
roomSocket.on(`close`, () => {
|
|
79
|
-
destroyRoom(store)(roomKey)
|
|
80
|
-
})
|
|
81
|
-
|
|
82
|
-
return roomSocket
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
export function provideEnterAndExit(
|
|
86
|
-
store: Store,
|
|
87
|
-
userKey: UserKey,
|
|
88
|
-
socket: Socket,
|
|
89
|
-
): {
|
|
90
|
-
enterRoom: (roomKey: RoomKey) => void
|
|
91
|
-
} {
|
|
92
|
-
const enterRoom = (roomKey: RoomKey) => {
|
|
93
|
-
const exitRoom = () => {
|
|
94
|
-
socket.offAny(forward)
|
|
95
|
-
toRoom([`user-leaves`])
|
|
96
|
-
leaveRoom(store, roomKey, userKey)
|
|
97
|
-
socket.off(`leaveRoom`, exitRoom)
|
|
98
|
-
socket.on(`joinRoom`, enterRoom)
|
|
99
|
-
}
|
|
100
|
-
|
|
101
|
-
socket.on(`leaveRoom`, exitRoom)
|
|
102
|
-
socket.off(`joinRoom`, enterRoom)
|
|
103
|
-
|
|
104
|
-
const roomQueue: [string, ...Json.Array][] = []
|
|
105
|
-
const pushToRoomQueue = (payload: [string, ...Json.Array]): void => {
|
|
106
|
-
roomQueue.push(payload)
|
|
107
|
-
}
|
|
108
|
-
let toRoom = pushToRoomQueue
|
|
109
|
-
const forward: AllEventsListener<EventsMap> = (...payload) => {
|
|
110
|
-
toRoom(payload)
|
|
111
|
-
}
|
|
112
|
-
socket.onAny(forward)
|
|
113
|
-
|
|
114
|
-
editRelationsInStore(store, usersInRooms, (relations) => {
|
|
115
|
-
relations.set({ room: roomKey, user: userKey })
|
|
116
|
-
})
|
|
117
|
-
const roomSocket = ROOMS.get(roomKey)
|
|
118
|
-
if (!roomSocket) {
|
|
119
|
-
store.logger.error(`❌`, `unknown`, roomKey, `no room found with this id`)
|
|
120
|
-
return null
|
|
121
|
-
}
|
|
122
|
-
roomSocket.onAny((...payload) => {
|
|
123
|
-
socket.emit(...payload)
|
|
124
|
-
})
|
|
125
|
-
roomSocket.emit(`user-joins`, userKey)
|
|
126
|
-
|
|
127
|
-
toRoom = (payload) => {
|
|
128
|
-
roomSocket.emit(`user::${userKey}`, ...payload)
|
|
129
|
-
}
|
|
130
|
-
while (roomQueue.length > 0) {
|
|
131
|
-
const payload = roomQueue.shift()
|
|
132
|
-
if (payload) toRoom(payload)
|
|
133
|
-
}
|
|
134
|
-
}
|
|
135
|
-
socket.on(`joinRoom`, enterRoom)
|
|
136
|
-
return { enterRoom }
|
|
137
|
-
}
|
|
138
|
-
|
|
139
|
-
export function leaveRoom(
|
|
140
|
-
store: Store,
|
|
141
|
-
roomKey: RoomKey,
|
|
142
|
-
userKey: UserKey,
|
|
143
|
-
): void {
|
|
144
|
-
editRelationsInStore(store, usersInRooms, (relations) => {
|
|
145
|
-
relations.delete({ room: roomKey, user: userKey })
|
|
146
|
-
})
|
|
147
|
-
}
|
|
148
|
-
|
|
149
|
-
export function destroyRoom(store: Store): (roomKey: RoomKey) => void {
|
|
150
|
-
return (roomKey: RoomKey) => {
|
|
151
|
-
// logger.info(`[${shortId}]:${username}`, `deleting room "${roomId}"`)
|
|
152
|
-
setIntoStore(store, roomKeysAtom, (s) => (s.delete(roomKey), s))
|
|
153
|
-
editRelationsInStore(store, usersInRooms, (relations) => {
|
|
154
|
-
relations.delete({ room: roomKey })
|
|
155
|
-
})
|
|
156
|
-
const room = ROOMS.get(roomKey)
|
|
157
|
-
if (room) {
|
|
158
|
-
room.emit(`exit`)
|
|
159
|
-
ROOMS.delete(roomKey)
|
|
160
|
-
}
|
|
161
|
-
}
|
|
162
|
-
}
|
|
163
|
-
|
|
164
|
-
export type ProvideRoomsConfig = {
|
|
165
|
-
resolveRoomScript: (path: string) => [string, string[]]
|
|
166
|
-
roomTimeLimit?: number
|
|
167
|
-
}
|
|
168
|
-
export function provideRooms<RoomNames extends string>({
|
|
169
|
-
store = IMPLICIT.STORE,
|
|
170
|
-
socket,
|
|
171
|
-
resolveRoomScript,
|
|
172
|
-
}: ProvideRoomsConfig & ServerConfig): void {
|
|
173
|
-
const socketKey = `socket::${socket.id}` satisfies SocketKey
|
|
174
|
-
const userKey = getFromStore(
|
|
175
|
-
store,
|
|
176
|
-
findRelationsInStore(store, usersOfSockets, socketKey).userKeyOfSocket,
|
|
177
|
-
)!
|
|
178
|
-
const roomSocket = socket as TypedSocket<RoomSocketInterface<RoomNames>, {}>
|
|
179
|
-
|
|
180
|
-
const exposeMutable = realtimeMutableProvider({ socket, store })
|
|
181
|
-
const exposeMutableFamily = realtimeMutableFamilyProvider({
|
|
182
|
-
socket,
|
|
183
|
-
store,
|
|
184
|
-
})
|
|
185
|
-
|
|
186
|
-
exposeMutable(roomKeysAtom)
|
|
187
|
-
|
|
188
|
-
const [, usersInRoomsAtoms] = getInternalRelationsFromStore(
|
|
189
|
-
store,
|
|
190
|
-
usersInRooms,
|
|
191
|
-
`split`,
|
|
192
|
-
)
|
|
193
|
-
const usersWhoseRoomsCanBeSeenSelector = findInStore(
|
|
194
|
-
store,
|
|
195
|
-
selfListSelectors,
|
|
196
|
-
userKey,
|
|
197
|
-
)
|
|
198
|
-
exposeMutableFamily(usersInRoomsAtoms, usersWhoseRoomsCanBeSeenSelector)
|
|
199
|
-
const usersOfSocketsAtoms = getInternalRelationsFromStore(
|
|
200
|
-
store,
|
|
201
|
-
usersOfSockets,
|
|
202
|
-
)
|
|
203
|
-
exposeMutableFamily(usersOfSocketsAtoms, socketKeysAtom)
|
|
204
|
-
|
|
205
|
-
const createRoom = async (roomName: RoomNames) => {
|
|
206
|
-
// logger.info(`[${shortId}]:${username}`, `creating room "${roomId}"`)
|
|
207
|
-
const roomKey = `room::${roomMeta.count++}` satisfies RoomKey
|
|
208
|
-
await spawnRoom(store, userKey, roomKey, ...resolveRoomScript(roomName))
|
|
209
|
-
}
|
|
210
|
-
|
|
211
|
-
const { enterRoom } = provideEnterAndExit(store, userKey, roomSocket)
|
|
212
|
-
|
|
213
|
-
const userRoomSet = getFromStore(store, usersInRoomsAtoms, userKey)
|
|
214
|
-
for (const userRoomKey of userRoomSet) {
|
|
215
|
-
enterRoom(userRoomKey)
|
|
216
|
-
break
|
|
217
|
-
}
|
|
218
|
-
|
|
219
|
-
roomSocket.on(`createRoom`, createRoom)
|
|
220
|
-
roomSocket.on(`deleteRoom`, destroyRoom(store))
|
|
221
|
-
socket.on(`disconnect`, () => {
|
|
222
|
-
// logger.info(`${socket.id} disconnected`)
|
|
223
|
-
editRelationsInStore(store, usersOfSockets, (rel) => rel.delete(socketKey))
|
|
224
|
-
setIntoStore(store, userKeysAtom, (keys) => (keys.delete(userKey), keys))
|
|
225
|
-
setIntoStore(store, socketKeysAtom, (keys) => (keys.delete(socketKey), keys))
|
|
226
|
-
})
|
|
227
|
-
}
|