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.
Files changed (38) hide show
  1. package/dist/internal/index.js +8 -8
  2. package/dist/internal/index.js.map +1 -1
  3. package/dist/introspection/index.d.ts.map +1 -1
  4. package/dist/main/index.d.ts +6 -4
  5. package/dist/main/index.d.ts.map +1 -1
  6. package/dist/main/index.js +4 -3
  7. package/dist/main/index.js.map +1 -1
  8. package/dist/realtime/index.d.ts +94 -31
  9. package/dist/realtime/index.d.ts.map +1 -1
  10. package/dist/realtime/index.js +34 -1
  11. package/dist/realtime/index.js.map +1 -1
  12. package/dist/realtime-react/index.d.ts +3 -1
  13. package/dist/realtime-react/index.d.ts.map +1 -1
  14. package/dist/realtime-react/index.js +7 -4
  15. package/dist/realtime-react/index.js.map +1 -1
  16. package/dist/realtime-server/index.d.ts +43 -13
  17. package/dist/realtime-server/index.d.ts.map +1 -1
  18. package/dist/realtime-server/index.js +120 -63
  19. package/dist/realtime-server/index.js.map +1 -1
  20. package/package.json +10 -10
  21. package/src/internal/families/create-readonly-held-selector-family.ts +2 -2
  22. package/src/internal/families/create-readonly-pure-selector-family.ts +2 -2
  23. package/src/internal/families/create-regular-atom-family.ts +2 -2
  24. package/src/internal/families/create-writable-held-selector-family.ts +2 -2
  25. package/src/internal/families/create-writable-pure-selector-family.ts +2 -2
  26. package/src/internal/mutable/create-mutable-atom-family.ts +2 -2
  27. package/src/internal/not-found-error.ts +2 -2
  28. package/src/main/logger.ts +8 -4
  29. package/src/realtime/cast-socket.ts +73 -0
  30. package/src/realtime/index.ts +2 -0
  31. package/src/realtime/socket-interface.ts +1 -1
  32. package/src/realtime/standard-schema.ts +72 -0
  33. package/src/realtime-react/index.ts +1 -0
  34. package/src/realtime-react/realtime-context.tsx +0 -9
  35. package/src/realtime-react/use-realtime-rooms.ts +13 -0
  36. package/src/realtime-server/realtime-server-stores/index.ts +1 -1
  37. package/src/realtime-server/realtime-server-stores/provide-rooms.ts +368 -0
  38. 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
- }