atom.io 0.40.6 → 0.40.7
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/README.md +1 -1
- package/dist/data/index.d.ts +1 -1
- package/dist/employ-socket-D6wgByWh.js +12 -0
- package/dist/employ-socket-D6wgByWh.js.map +1 -0
- package/dist/has-role-hv4-hJMw.js +1149 -0
- package/dist/has-role-hv4-hJMw.js.map +1 -0
- package/dist/internal/index.d.ts +248 -248
- package/dist/internal/index.d.ts.map +1 -1
- package/dist/internal/index.js +570 -1712
- package/dist/internal/index.js.map +1 -1
- package/dist/introspection/index.d.ts +1 -1
- package/dist/is-fn-DY1wZ-md.js +10 -0
- package/dist/is-fn-DY1wZ-md.js.map +1 -0
- package/dist/main/index.d.ts +33 -33
- package/dist/main/index.d.ts.map +1 -1
- package/dist/main/index.js +2 -2
- package/dist/main/index.js.map +1 -1
- package/dist/mutex-store-CSvxY9i3.js +11 -0
- package/dist/mutex-store-CSvxY9i3.js.map +1 -0
- package/dist/react/index.d.ts +5 -5
- package/dist/react/index.d.ts.map +1 -1
- package/dist/react/index.js.map +1 -1
- package/dist/react-devtools/index.js +7 -7
- package/dist/react-devtools/index.js.map +1 -1
- package/dist/realtime/index.d.ts +7 -15
- package/dist/realtime/index.d.ts.map +1 -1
- package/dist/realtime/index.js +3 -33
- package/dist/realtime/index.js.map +1 -1
- package/dist/realtime-client/index.d.ts +5 -5
- package/dist/realtime-client/index.d.ts.map +1 -1
- package/dist/realtime-client/index.js +92 -69
- package/dist/realtime-client/index.js.map +1 -1
- package/dist/realtime-react/index.d.ts +17 -10
- package/dist/realtime-react/index.d.ts.map +1 -1
- package/dist/realtime-react/index.js +41 -41
- package/dist/realtime-react/index.js.map +1 -1
- package/dist/realtime-server/index.d.ts +60 -53
- package/dist/realtime-server/index.d.ts.map +1 -1
- package/dist/realtime-server/index.js +592 -485
- package/dist/realtime-server/index.js.map +1 -1
- package/dist/realtime-testing/index.d.ts +1 -2
- package/dist/realtime-testing/index.d.ts.map +1 -1
- package/dist/realtime-testing/index.js +25 -18
- package/dist/realtime-testing/index.js.map +1 -1
- package/dist/shared-room-store-COGGKqes.js +32 -0
- package/dist/shared-room-store-COGGKqes.js.map +1 -0
- package/dist/shared-room-store-D2o4ZLjC.d.ts +15 -0
- package/dist/shared-room-store-D2o4ZLjC.d.ts.map +1 -0
- package/dist/web/index.d.ts +3 -3
- package/dist/web/index.d.ts.map +1 -1
- package/dist/web/index.js +4 -3
- package/dist/web/index.js.map +1 -1
- package/package.json +12 -12
- package/src/internal/atom/create-regular-atom.ts +5 -4
- package/src/internal/atom/dispose-atom.ts +7 -2
- package/src/internal/atom/has-role.ts +3 -3
- package/src/internal/caching.ts +4 -2
- package/src/internal/families/create-readonly-held-selector-family.ts +2 -1
- package/src/internal/families/create-readonly-pure-selector-family.ts +5 -2
- package/src/internal/families/create-regular-atom-family.ts +2 -1
- package/src/internal/families/create-writable-held-selector-family.ts +2 -1
- package/src/internal/families/create-writable-pure-selector-family.ts +5 -2
- package/src/internal/families/dispose-from-store.ts +4 -4
- package/src/internal/families/find-in-store.ts +10 -10
- package/src/internal/families/get-family-of-token.ts +2 -2
- package/src/internal/families/index.ts +1 -0
- package/src/internal/families/mint-in-store.ts +54 -19
- package/src/internal/families/seek-in-store.ts +1 -1
- package/src/internal/get-state/get-fallback.ts +2 -2
- package/src/internal/get-state/get-from-store.ts +5 -5
- package/src/internal/get-state/read-or-compute-value.ts +1 -1
- package/src/internal/get-state/reduce-reference.ts +8 -6
- package/src/internal/index.ts +2 -220
- package/src/internal/molecule.ts +1 -2
- package/src/internal/mutable/create-mutable-atom-family.ts +3 -2
- package/src/internal/mutable/create-mutable-atom.ts +4 -2
- package/src/internal/mutable/get-json-family.ts +1 -1
- package/src/internal/mutable/get-update-family.ts +1 -1
- package/src/internal/mutable/tracker-family.ts +2 -1
- package/src/internal/mutable/tracker.ts +5 -8
- package/src/internal/safe-compute.ts +1 -1
- package/src/internal/selector/create-readonly-held-selector.ts +2 -1
- package/src/internal/selector/create-readonly-pure-selector.ts +2 -1
- package/src/internal/selector/create-writable-held-selector.ts +2 -1
- package/src/internal/selector/create-writable-pure-selector.ts +2 -1
- package/src/internal/selector/dispose-selector.ts +3 -2
- package/src/internal/selector/register-selector.ts +8 -5
- package/src/internal/selector/trace-selector-atoms.ts +2 -1
- package/src/internal/set-state/dispatch-state-update.ts +3 -2
- package/src/internal/set-state/evict-downstream.ts +1 -1
- package/src/internal/set-state/operate-on-store.ts +16 -22
- package/src/internal/set-state/reset-atom-or-selector.ts +5 -3
- package/src/internal/set-state/reset-in-store.ts +5 -5
- package/src/internal/set-state/set-atom-or-selector.ts +2 -2
- package/src/internal/set-state/set-atom.ts +4 -2
- package/src/internal/set-state/set-into-store.ts +21 -39
- package/src/internal/set-state/set-selector.ts +3 -2
- package/src/internal/state-types.ts +228 -0
- package/src/internal/store/deposit.ts +4 -4
- package/src/internal/store/index.ts +0 -1
- package/src/internal/store/store.ts +9 -9
- package/src/internal/store/withdraw.ts +4 -4
- package/src/internal/subscribe/recall-state.ts +1 -1
- package/src/internal/subscribe/subscribe-to-root-atoms.ts +1 -12
- package/src/internal/subscribe/subscribe-to-transaction.ts +3 -2
- package/src/internal/transaction/build-transaction.ts +3 -2
- package/src/internal/transaction/index.ts +1 -23
- package/src/internal/transaction/is-root-store.ts +4 -1
- package/src/internal/transaction/transaction-meta-progress.ts +22 -0
- package/src/main/atom.ts +1 -2
- package/src/main/find-state.ts +5 -5
- package/src/main/get-state.ts +4 -4
- package/src/main/realm.ts +2 -2
- package/src/main/set-state.ts +10 -10
- package/src/react/parse-state-overloads.ts +3 -3
- package/src/react/use-i.ts +6 -4
- package/src/react/use-loadable.ts +4 -10
- package/src/react/use-o.ts +6 -4
- package/src/react-devtools/store.ts +6 -6
- package/src/realtime/index.ts +1 -0
- package/src/realtime/mutex-store.ts +11 -0
- package/src/realtime/realtime-continuity.ts +1 -5
- package/src/realtime-client/pull-atom-family-member.ts +14 -17
- package/src/realtime-client/pull-atom.ts +1 -1
- package/src/realtime-client/pull-mutable-atom-family-member.ts +16 -12
- package/src/realtime-client/pull-selector-family-member.ts +8 -35
- package/src/realtime-client/pull-selector-roots.ts +90 -0
- package/src/realtime-client/pull-selector.ts +2 -27
- package/src/realtime-client/push-state.ts +33 -5
- package/src/realtime-client/realtime-client-stores/client-main-store.ts +2 -5
- package/src/realtime-react/index.ts +2 -1
- package/src/realtime-react/realtime-context.tsx +9 -5
- package/src/realtime-react/use-pull-atom-family-member.ts +2 -3
- package/src/realtime-react/use-pull-mutable-family-member.ts +2 -3
- package/src/realtime-react/use-pull-selector-family-member.ts +5 -6
- package/src/realtime-react/use-push.ts +7 -3
- package/src/realtime-react/use-realtime-service.ts +11 -11
- package/src/realtime-react/use-single-effect.ts +11 -14
- package/src/realtime-server/{realtime-server-stores/server-sync-store.ts → continuity/continuity-store.ts} +1 -1
- package/src/realtime-server/continuity/prepare-to-sync-realtime-continuity.ts +1 -1
- package/src/realtime-server/continuity/prepare-to-track-client-acknowledgement.ts +3 -5
- package/src/realtime-server/continuity/subscribe-to-continuity-actions.ts +1 -1
- package/src/realtime-server/employ-socket.ts +14 -0
- package/src/realtime-server/index.ts +2 -20
- package/src/realtime-server/ipc-sockets/child-socket.ts +125 -66
- package/src/realtime-server/ipc-sockets/custom-socket.ts +16 -14
- package/src/realtime-server/ipc-sockets/parent-socket.ts +81 -58
- package/src/realtime-server/realtime-family-provider.ts +78 -29
- package/src/realtime-server/realtime-mutable-family-provider.ts +80 -31
- package/src/realtime-server/realtime-mutable-provider.ts +30 -22
- package/src/realtime-server/realtime-server-stores/index.ts +0 -2
- package/src/realtime-server/realtime-server-stores/server-room-external-store.ts +77 -36
- package/src/realtime-server/realtime-server-stores/server-user-store.ts +12 -1
- package/src/realtime-server/realtime-state-provider.ts +30 -29
- package/src/realtime-server/realtime-state-receiver.ts +62 -16
- package/src/realtime-server/server-config.ts +9 -0
- package/src/realtime-server/socket-interface.ts +14 -0
- package/src/realtime-testing/setup-realtime-test.tsx +56 -23
- package/src/web/index.ts +1 -1
- package/src/web/{persist-sync.ts → storage-sync.ts} +5 -2
- package/src/internal/store/mint-or-counterfeit.ts +0 -108
- package/src/realtime-react/on-mount.ts +0 -5
- package/src/realtime-server/realtime-server-stores/server-room-external-actions.ts +0 -79
|
@@ -1,48 +1,89 @@
|
|
|
1
1
|
import type { ChildProcessWithoutNullStreams } from "node:child_process"
|
|
2
2
|
import { spawn } from "node:child_process"
|
|
3
3
|
|
|
4
|
-
import type {
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
} from "atom.io"
|
|
9
|
-
import { atomFamily, selectorFamily } from "atom.io"
|
|
4
|
+
import type { TransactionIO, TransactionToken } from "atom.io"
|
|
5
|
+
import { transaction } from "atom.io"
|
|
6
|
+
import { editRelationsInStore } from "atom.io/internal"
|
|
7
|
+
import type { UserInRoomMeta } from "atom.io/realtime/shared-room-store"
|
|
8
|
+
import { roomIndex, usersInRooms } from "atom.io/realtime/shared-room-store"
|
|
10
9
|
|
|
11
10
|
import { ChildSocket } from "../ipc-sockets"
|
|
11
|
+
import type { RoomKey } from "./server-user-store"
|
|
12
12
|
|
|
13
|
-
export
|
|
14
|
-
|
|
15
|
-
|
|
13
|
+
export const ROOMS: Map<
|
|
14
|
+
string,
|
|
15
|
+
ChildSocket<any, any, ChildProcessWithoutNullStreams>
|
|
16
|
+
> = new Map()
|
|
16
17
|
|
|
17
|
-
export
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
18
|
+
export async function spawnRoom(
|
|
19
|
+
roomId: string,
|
|
20
|
+
script: string,
|
|
21
|
+
options: string[],
|
|
22
|
+
): Promise<ChildSocket<any, any>> {
|
|
23
|
+
const child = await new Promise<ChildProcessWithoutNullStreams>((resolve) => {
|
|
24
|
+
const room = spawn(script, options, { env: process.env })
|
|
25
|
+
const resolver = (data: Buffer) => {
|
|
26
|
+
if (data.toString() === `ALIVE`) {
|
|
27
|
+
room.stdout.off(`data`, resolver)
|
|
28
|
+
resolve(room)
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
room.stdout.on(`data`, resolver)
|
|
21
32
|
})
|
|
33
|
+
ROOMS.set(roomId, new ChildSocket(child, roomId))
|
|
34
|
+
return new ChildSocket(child, roomId)
|
|
35
|
+
}
|
|
22
36
|
|
|
23
|
-
export const
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
(
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
37
|
+
export const joinRoomTX: TransactionToken<
|
|
38
|
+
(roomId: string, userId: string, enteredAtEpoch: number) => UserInRoomMeta
|
|
39
|
+
> = transaction({
|
|
40
|
+
key: `joinRoom`,
|
|
41
|
+
do: (tools, roomId, userId, enteredAtEpoch) => {
|
|
42
|
+
const meta = { enteredAtEpoch }
|
|
43
|
+
editRelationsInStore(
|
|
44
|
+
usersInRooms,
|
|
45
|
+
(relations) => {
|
|
46
|
+
relations.set({ room: roomId, user: userId }, meta)
|
|
47
|
+
},
|
|
48
|
+
tools.env().store,
|
|
49
|
+
)
|
|
50
|
+
return meta
|
|
51
|
+
},
|
|
52
|
+
})
|
|
53
|
+
export type JoinRoomIO = TransactionIO<typeof joinRoomTX>
|
|
54
|
+
|
|
55
|
+
export const leaveRoomTX: TransactionToken<
|
|
56
|
+
(roomId: string, userId: string) => void
|
|
57
|
+
> = transaction({
|
|
58
|
+
key: `leaveRoom`,
|
|
59
|
+
do: ({ env }, roomId, userId) => {
|
|
60
|
+
editRelationsInStore(
|
|
61
|
+
usersInRooms,
|
|
62
|
+
(relations) => {
|
|
63
|
+
relations.delete({ room: roomId, user: userId })
|
|
64
|
+
},
|
|
65
|
+
env().store,
|
|
66
|
+
)
|
|
67
|
+
},
|
|
68
|
+
})
|
|
69
|
+
export type LeaveRoomIO = TransactionIO<typeof leaveRoomTX>
|
|
70
|
+
|
|
71
|
+
export const destroyRoomTX: TransactionToken<(roomKey: RoomKey) => void> =
|
|
72
|
+
transaction({
|
|
73
|
+
key: `destroyRoom`,
|
|
74
|
+
do: ({ set, env }, roomId) => {
|
|
75
|
+
editRelationsInStore(
|
|
76
|
+
usersInRooms,
|
|
77
|
+
(relations) => {
|
|
78
|
+
relations.delete({ room: roomId })
|
|
44
79
|
},
|
|
80
|
+
env().store,
|
|
45
81
|
)
|
|
46
|
-
|
|
82
|
+
set(roomIndex, (s) => (s.delete(roomId), s))
|
|
83
|
+
const room = ROOMS.get(roomId)
|
|
84
|
+
if (room) {
|
|
85
|
+
room.emit(`exit`)
|
|
86
|
+
ROOMS.delete(roomId)
|
|
87
|
+
}
|
|
47
88
|
},
|
|
48
|
-
})
|
|
89
|
+
})
|
|
@@ -2,9 +2,10 @@ import type {
|
|
|
2
2
|
Hierarchy,
|
|
3
3
|
JoinToken,
|
|
4
4
|
MutableAtomToken,
|
|
5
|
+
PureSelectorFamilyToken,
|
|
5
6
|
RegularAtomFamilyToken,
|
|
6
7
|
} from "atom.io"
|
|
7
|
-
import { atomFamily, join, mutableAtom } from "atom.io"
|
|
8
|
+
import { atomFamily, join, mutableAtom, selectorFamily } from "atom.io"
|
|
8
9
|
import { SetRTX } from "atom.io/transceivers/set-rtx"
|
|
9
10
|
|
|
10
11
|
import type { Socket } from ".."
|
|
@@ -53,3 +54,13 @@ export const usersOfSockets: JoinToken<
|
|
|
53
54
|
isAType: (s): s is UserKey => s.startsWith(`user::`),
|
|
54
55
|
isBType: (s): s is SocketKey => s.startsWith(`socket::`),
|
|
55
56
|
})
|
|
57
|
+
|
|
58
|
+
export const userMutualSituationalAwarenessIndexes: PureSelectorFamilyToken<
|
|
59
|
+
UserKey[],
|
|
60
|
+
UserKey
|
|
61
|
+
> = selectorFamily<UserKey[], UserKey>({
|
|
62
|
+
key: `userMutualSituationalAwarenessIndexes`,
|
|
63
|
+
get: (userId) => () => {
|
|
64
|
+
return [userId]
|
|
65
|
+
},
|
|
66
|
+
})
|
|
@@ -3,6 +3,7 @@ import { getFromStore, IMPLICIT, subscribeToState } from "atom.io/internal"
|
|
|
3
3
|
import type { Json } from "atom.io/json"
|
|
4
4
|
|
|
5
5
|
import type { ServerConfig } from "."
|
|
6
|
+
import { employSocket } from "./employ-socket"
|
|
6
7
|
|
|
7
8
|
export type StateProvider = ReturnType<typeof realtimeStateProvider>
|
|
8
9
|
export function realtimeStateProvider({
|
|
@@ -12,39 +13,39 @@ export function realtimeStateProvider({
|
|
|
12
13
|
return function stateProvider<J extends Json.Serializable>(
|
|
13
14
|
token: AtomIO.WritableToken<J>,
|
|
14
15
|
): () => void {
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
16
|
+
const subscriptions = new Set<() => void>()
|
|
17
|
+
const clearSubscriptions = () => {
|
|
18
|
+
for (const unsub of subscriptions) unsub()
|
|
19
|
+
subscriptions.clear()
|
|
20
|
+
}
|
|
19
21
|
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
token
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
22
|
+
const start = () => {
|
|
23
|
+
subscriptions.add(
|
|
24
|
+
employSocket(socket, `sub:${token.key}`, () => {
|
|
25
|
+
clearSubscriptions()
|
|
26
|
+
socket.emit(`serve:${token.key}`, getFromStore(store, token))
|
|
27
|
+
subscriptions.add(
|
|
28
|
+
subscribeToState(
|
|
29
|
+
store,
|
|
30
|
+
token,
|
|
31
|
+
`expose-single:${socket.id}`,
|
|
32
|
+
({ newValue }) => {
|
|
33
|
+
socket.emit(`serve:${token.key}`, newValue)
|
|
34
|
+
},
|
|
35
|
+
),
|
|
36
|
+
)
|
|
37
|
+
subscriptions.add(
|
|
38
|
+
employSocket(socket, `unsub:${token.key}`, () => {
|
|
39
|
+
clearSubscriptions()
|
|
40
|
+
start()
|
|
41
|
+
}),
|
|
42
|
+
)
|
|
43
|
+
}),
|
|
27
44
|
)
|
|
28
|
-
|
|
29
|
-
const fillUnsubRequest = () => {
|
|
30
|
-
socket.off(`unsub:${token.key}`, fillUnsubRequest)
|
|
31
|
-
if (unsubscribeFromStateUpdates) {
|
|
32
|
-
unsubscribeFromStateUpdates()
|
|
33
|
-
unsubscribeFromStateUpdates = undefined
|
|
34
|
-
}
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
socket.on(`unsub:${token.key}`, fillUnsubRequest)
|
|
38
45
|
}
|
|
39
46
|
|
|
40
|
-
|
|
47
|
+
start()
|
|
41
48
|
|
|
42
|
-
return
|
|
43
|
-
socket.off(`sub:${token.key}`, fillSubRequest)
|
|
44
|
-
if (unsubscribeFromStateUpdates) {
|
|
45
|
-
unsubscribeFromStateUpdates()
|
|
46
|
-
unsubscribeFromStateUpdates = undefined
|
|
47
|
-
}
|
|
48
|
-
}
|
|
49
|
+
return clearSubscriptions
|
|
49
50
|
}
|
|
50
51
|
}
|
|
@@ -1,35 +1,81 @@
|
|
|
1
1
|
import type { WritableToken } from "atom.io"
|
|
2
|
-
import {
|
|
2
|
+
import {
|
|
3
|
+
findInStore,
|
|
4
|
+
getFromStore,
|
|
5
|
+
IMPLICIT,
|
|
6
|
+
setIntoStore,
|
|
7
|
+
subscribeToState,
|
|
8
|
+
} from "atom.io/internal"
|
|
9
|
+
import {
|
|
10
|
+
operateOnStore,
|
|
11
|
+
OWN_OP,
|
|
12
|
+
} from "atom.io/internal/set-state/operate-on-store"
|
|
3
13
|
import type { Json } from "atom.io/json"
|
|
14
|
+
import { mutexAtoms } from "atom.io/realtime/mutex-store"
|
|
4
15
|
|
|
5
16
|
import type { ServerConfig } from "."
|
|
17
|
+
import { employSocket } from "./employ-socket"
|
|
6
18
|
|
|
7
19
|
export type StateReceiver = ReturnType<typeof realtimeStateReceiver>
|
|
8
20
|
export function realtimeStateReceiver({
|
|
9
21
|
socket,
|
|
10
22
|
store = IMPLICIT.STORE,
|
|
11
23
|
}: ServerConfig) {
|
|
12
|
-
return function stateReceiver<
|
|
13
|
-
|
|
24
|
+
return function stateReceiver<S extends Json.Serializable, C extends S>(
|
|
25
|
+
clientToken: WritableToken<C>,
|
|
26
|
+
serverToken: WritableToken<S> = clientToken,
|
|
14
27
|
): () => void {
|
|
15
|
-
const
|
|
16
|
-
|
|
28
|
+
const mutexAtom = findInStore(store, mutexAtoms, serverToken.key)
|
|
29
|
+
|
|
30
|
+
const subscriptions = new Set<() => void>()
|
|
31
|
+
const clearSubscriptions = () => {
|
|
32
|
+
for (const unsub of subscriptions) unsub()
|
|
33
|
+
subscriptions.clear()
|
|
17
34
|
}
|
|
18
35
|
|
|
19
|
-
const
|
|
20
|
-
|
|
21
|
-
|
|
36
|
+
const permitPublish = () => {
|
|
37
|
+
clearSubscriptions()
|
|
38
|
+
subscriptions.add(
|
|
39
|
+
employSocket(socket, `pub:${clientToken.key}`, (newValue) => {
|
|
40
|
+
setIntoStore(store, serverToken, newValue as C)
|
|
41
|
+
}),
|
|
42
|
+
)
|
|
43
|
+
subscriptions.add(
|
|
44
|
+
employSocket(socket, `unclaim:${clientToken.key}`, () => {
|
|
45
|
+
setIntoStore(store, mutexAtom, false)
|
|
46
|
+
clearSubscriptions()
|
|
47
|
+
start()
|
|
48
|
+
}),
|
|
49
|
+
)
|
|
22
50
|
}
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
51
|
+
|
|
52
|
+
const start = () => {
|
|
53
|
+
subscriptions.add(
|
|
54
|
+
employSocket(socket, `claim:${clientToken.key}`, () => {
|
|
55
|
+
if (getFromStore(store, mutexAtom)) {
|
|
56
|
+
clearSubscriptions()
|
|
57
|
+
subscriptions.add(
|
|
58
|
+
subscribeToState(store, mutexAtom, socket.id!, () => {
|
|
59
|
+
const currentValue = getFromStore(store, mutexAtom)
|
|
60
|
+
if (currentValue === false) {
|
|
61
|
+
operateOnStore(OWN_OP, store, mutexAtom, true)
|
|
62
|
+
permitPublish()
|
|
63
|
+
socket.emit(`claim-result:${clientToken.key}`, true)
|
|
64
|
+
}
|
|
65
|
+
}),
|
|
66
|
+
)
|
|
67
|
+
socket.emit(`claim-result:${clientToken.key}`, false)
|
|
68
|
+
return
|
|
69
|
+
}
|
|
70
|
+
setIntoStore(store, mutexAtom, true)
|
|
71
|
+
permitPublish()
|
|
72
|
+
socket.emit(`claim-result:${clientToken.key}`, true)
|
|
73
|
+
}),
|
|
74
|
+
)
|
|
26
75
|
}
|
|
27
76
|
|
|
28
|
-
|
|
77
|
+
start()
|
|
29
78
|
|
|
30
|
-
return
|
|
31
|
-
socket.off(`claim:${token.key}`, fillPubClaim)
|
|
32
|
-
socket.off(`pub:${token.key}`, publish)
|
|
33
|
-
}
|
|
79
|
+
return clearSubscriptions
|
|
34
80
|
}
|
|
35
81
|
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { Json } from "atom.io/json"
|
|
2
|
+
|
|
3
|
+
export type Socket = {
|
|
4
|
+
id: string | undefined
|
|
5
|
+
on: (event: string, listener: (...args: Json.Serializable[]) => void) => void
|
|
6
|
+
onAny: (
|
|
7
|
+
listener: (event: string, ...args: Json.Serializable[]) => void,
|
|
8
|
+
) => void
|
|
9
|
+
off: (event: string, listener: (...args: Json.Serializable[]) => void) => void
|
|
10
|
+
offAny: (
|
|
11
|
+
listener: (event: string, ...args: Json.Serializable[]) => void,
|
|
12
|
+
) => void
|
|
13
|
+
emit: (event: string, ...args: Json.Serializable[]) => void
|
|
14
|
+
}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { ChildProcess } from "node:child_process"
|
|
1
2
|
import * as http from "node:http"
|
|
2
3
|
|
|
3
4
|
import type { RenderResult } from "@testing-library/react"
|
|
@@ -15,10 +16,10 @@ import {
|
|
|
15
16
|
} from "atom.io/internal"
|
|
16
17
|
import { toEntries } from "atom.io/json"
|
|
17
18
|
import * as AR from "atom.io/react"
|
|
18
|
-
import * as RT from "atom.io/realtime"
|
|
19
19
|
import * as RTC from "atom.io/realtime-client"
|
|
20
20
|
import * as RTR from "atom.io/realtime-react"
|
|
21
21
|
import * as RTS from "atom.io/realtime-server"
|
|
22
|
+
import { SetRTX } from "atom.io/transceivers/set-rtx"
|
|
22
23
|
import * as Happy from "happy-dom"
|
|
23
24
|
import * as React from "react"
|
|
24
25
|
import * as SocketIO from "socket.io"
|
|
@@ -30,27 +31,49 @@ let testNumber = 0
|
|
|
30
31
|
/* eslint-disable no-console */
|
|
31
32
|
|
|
32
33
|
function prefixLogger(store: Store, prefix: string) {
|
|
33
|
-
store.loggers[0] = new AtomIO.AtomIOLogger(
|
|
34
|
-
info
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
34
|
+
store.loggers[0] = new AtomIO.AtomIOLogger(
|
|
35
|
+
`info`,
|
|
36
|
+
(...params) => {
|
|
37
|
+
let idx = 0
|
|
38
|
+
for (const param of params) {
|
|
39
|
+
if (param instanceof SocketIO.Socket) {
|
|
40
|
+
params[idx] = `Socket:${param.id}`
|
|
41
|
+
}
|
|
42
|
+
if (param instanceof RTS.ChildSocket) {
|
|
43
|
+
params[idx] = `ChildSocket:${param.id}`
|
|
44
|
+
}
|
|
45
|
+
if (param instanceof ChildProcess) {
|
|
46
|
+
params[idx] = `ChildProcess:${param.pid}`
|
|
47
|
+
}
|
|
48
|
+
if (param instanceof SetRTX) {
|
|
49
|
+
params[idx] =
|
|
50
|
+
`SetRTX(${param.size}) {${[...param].join(`, `)}} at ${param.cacheIdx}`
|
|
51
|
+
}
|
|
52
|
+
idx++
|
|
53
|
+
}
|
|
54
|
+
return params
|
|
39
55
|
},
|
|
40
|
-
|
|
41
|
-
|
|
56
|
+
{
|
|
57
|
+
info: (...params) => {
|
|
58
|
+
console.info(prefix, ...params)
|
|
59
|
+
},
|
|
60
|
+
warn: (...params) => {
|
|
61
|
+
console.warn(prefix, ...params)
|
|
62
|
+
},
|
|
63
|
+
error: (...params) => {
|
|
64
|
+
console.error(prefix, ...params)
|
|
65
|
+
},
|
|
42
66
|
},
|
|
43
|
-
|
|
67
|
+
)
|
|
44
68
|
}
|
|
45
69
|
|
|
46
70
|
export type TestSetupOptions = {
|
|
47
|
-
port: number
|
|
48
71
|
immortal?: { server?: boolean }
|
|
49
72
|
server: (tools: {
|
|
50
73
|
socket: SocketIO.Socket
|
|
51
74
|
silo: AtomIO.Silo
|
|
52
75
|
enableLogging: () => void
|
|
53
|
-
}) => void
|
|
76
|
+
}) => (() => void) | void
|
|
54
77
|
}
|
|
55
78
|
export type TestSetupOptions__SingleClient = TestSetupOptions & {
|
|
56
79
|
client: React.FC
|
|
@@ -105,10 +128,11 @@ export const setupRealtimeTestServer = (
|
|
|
105
128
|
},
|
|
106
129
|
IMPLICIT.STORE,
|
|
107
130
|
)
|
|
131
|
+
// prefixLogger(silo.store, `server`)
|
|
108
132
|
const socketRealm = new AtomIO.Realm<RTS.SocketSystemHierarchy>(silo.store)
|
|
109
133
|
|
|
110
134
|
const httpServer = http.createServer((_, res) => res.end(`Hello World!`))
|
|
111
|
-
const address = httpServer.listen(
|
|
135
|
+
const address = httpServer.listen().address()
|
|
112
136
|
const port =
|
|
113
137
|
typeof address === `string` ? null : address === null ? null : address.port
|
|
114
138
|
if (port === null) throw new Error(`Could not determine port for test server`)
|
|
@@ -138,6 +162,8 @@ export const setupRealtimeTestServer = (
|
|
|
138
162
|
}
|
|
139
163
|
})
|
|
140
164
|
|
|
165
|
+
const serviceDisposalFunctions: Array<() => void> = []
|
|
166
|
+
|
|
141
167
|
server.on(`connection`, (socket: SocketIO.Socket) => {
|
|
142
168
|
let userKey: string | null = null
|
|
143
169
|
function enableLogging() {
|
|
@@ -158,19 +184,26 @@ export const setupRealtimeTestServer = (
|
|
|
158
184
|
console.log(`${userKey} disconnected`)
|
|
159
185
|
})
|
|
160
186
|
}
|
|
161
|
-
options.server({ socket, enableLogging, silo })
|
|
187
|
+
const disposeServices = options.server({ socket, enableLogging, silo })
|
|
188
|
+
if (disposeServices) {
|
|
189
|
+
serviceDisposalFunctions.push(disposeServices)
|
|
190
|
+
}
|
|
162
191
|
})
|
|
163
192
|
|
|
164
193
|
const dispose = async () => {
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
for (const roomKey of roomKeys) {
|
|
168
|
-
const roomState = findInStore(silo.store, RTS.roomSelectors, roomKey)
|
|
169
|
-
const room = getFromStore(silo.store, roomState)
|
|
170
|
-
if (room && !(room instanceof Promise)) {
|
|
171
|
-
room.process.kill()
|
|
172
|
-
}
|
|
194
|
+
for (const disposeSocketServices of serviceDisposalFunctions) {
|
|
195
|
+
disposeSocketServices()
|
|
173
196
|
}
|
|
197
|
+
await server.close()
|
|
198
|
+
|
|
199
|
+
// const roomKeys = getFromStore(silo.store, RT.roomIndex)
|
|
200
|
+
// for (const roomKey of roomKeys) {
|
|
201
|
+
// const roomState = findInStore(silo.store, RTS.roomSelectors, roomKey)
|
|
202
|
+
// const room = getFromStore(silo.store, roomState)
|
|
203
|
+
// if (room && !(room instanceof Promise)) {
|
|
204
|
+
// room.process.kill()
|
|
205
|
+
// }
|
|
206
|
+
// } // ❗ POSSIBLY STILL NEEDED
|
|
174
207
|
silo.store.valueMap.clear()
|
|
175
208
|
}
|
|
176
209
|
|
|
@@ -212,7 +245,7 @@ export const setupRealtimeTestClient = (
|
|
|
212
245
|
}
|
|
213
246
|
|
|
214
247
|
const enableLogging = () => {
|
|
215
|
-
prefixLogger(silo.store, name)
|
|
248
|
+
// prefixLogger(silo.store, name)
|
|
216
249
|
socket.onAny((event, ...args) => {
|
|
217
250
|
console.log(`📡 `, name, event, ...args)
|
|
218
251
|
})
|
package/src/web/index.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export * from "./
|
|
1
|
+
export * from "./storage-sync"
|
|
@@ -5,13 +5,16 @@ export type StringInterface<T> = {
|
|
|
5
5
|
parse: (s: string) => T
|
|
6
6
|
}
|
|
7
7
|
|
|
8
|
-
export const
|
|
8
|
+
export const storageSync =
|
|
9
9
|
<T>(
|
|
10
|
-
storage: Storage,
|
|
10
|
+
storage: Storage | undefined,
|
|
11
11
|
{ stringify, parse }: StringInterface<T>,
|
|
12
12
|
key: string,
|
|
13
13
|
): AtomEffect<T> =>
|
|
14
14
|
({ setSelf, onSet }) => {
|
|
15
|
+
if (!storage) {
|
|
16
|
+
return
|
|
17
|
+
}
|
|
15
18
|
const savedValue = storage.getItem(key)
|
|
16
19
|
if (savedValue != null) setSelf(parse(savedValue))
|
|
17
20
|
|
|
@@ -1,108 +0,0 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
AtomFamilyToken,
|
|
3
|
-
AtomToken,
|
|
4
|
-
MutableAtomFamilyToken,
|
|
5
|
-
MutableAtomToken,
|
|
6
|
-
ReadableFamilyToken,
|
|
7
|
-
ReadableToken,
|
|
8
|
-
ReadonlyPureSelectorFamilyToken,
|
|
9
|
-
ReadonlyPureSelectorToken,
|
|
10
|
-
RegularAtomFamilyToken,
|
|
11
|
-
RegularAtomToken,
|
|
12
|
-
SelectorFamilyToken,
|
|
13
|
-
SelectorToken,
|
|
14
|
-
WritableFamilyToken,
|
|
15
|
-
WritablePureSelectorFamilyToken,
|
|
16
|
-
WritablePureSelectorToken,
|
|
17
|
-
WritableToken,
|
|
18
|
-
} from "atom.io"
|
|
19
|
-
import type { Canonical } from "atom.io/json"
|
|
20
|
-
import { stringifyJson } from "atom.io/json"
|
|
21
|
-
|
|
22
|
-
import type { Transceiver } from "../mutable"
|
|
23
|
-
|
|
24
|
-
export const COUNTERFEIT: unique symbol = Symbol(`counterfeit`)
|
|
25
|
-
|
|
26
|
-
export const FAMILY_MEMBER_TOKEN_TYPES = {
|
|
27
|
-
atom_family: `atom`,
|
|
28
|
-
molecule_family: `molecule`,
|
|
29
|
-
mutable_atom_family: `mutable_atom`,
|
|
30
|
-
readonly_held_selector_family: `readonly_held_selector`,
|
|
31
|
-
readonly_pure_selector_family: `readonly_pure_selector`,
|
|
32
|
-
writable_held_selector_family: `writable_held_selector`,
|
|
33
|
-
writable_pure_selector_family: `writable_pure_selector`,
|
|
34
|
-
} as const
|
|
35
|
-
|
|
36
|
-
export function mint<
|
|
37
|
-
T extends Transceiver<any, any, any>,
|
|
38
|
-
K extends Canonical,
|
|
39
|
-
Key extends K,
|
|
40
|
-
>(token: MutableAtomFamilyToken<T, K>, key: Key): MutableAtomToken<T>
|
|
41
|
-
|
|
42
|
-
export function mint<T, K extends Canonical, Key extends K, E>(
|
|
43
|
-
token: RegularAtomFamilyToken<T, K, E>,
|
|
44
|
-
key: Key,
|
|
45
|
-
counterfeit?: typeof COUNTERFEIT,
|
|
46
|
-
): RegularAtomToken<T, Key, E>
|
|
47
|
-
|
|
48
|
-
export function mint<T, K extends Canonical, Key extends K, E>(
|
|
49
|
-
token: AtomFamilyToken<T, K, E>,
|
|
50
|
-
key: Key,
|
|
51
|
-
counterfeit?: typeof COUNTERFEIT,
|
|
52
|
-
): AtomToken<T, Key, E>
|
|
53
|
-
|
|
54
|
-
export function mint<T, K extends Canonical, Key extends K, E>(
|
|
55
|
-
token: WritablePureSelectorFamilyToken<T, K, E>,
|
|
56
|
-
key: Key,
|
|
57
|
-
counterfeit?: typeof COUNTERFEIT,
|
|
58
|
-
): WritablePureSelectorToken<T, Key, E>
|
|
59
|
-
|
|
60
|
-
export function mint<T, K extends Canonical, Key extends K, E>(
|
|
61
|
-
token: ReadonlyPureSelectorFamilyToken<T, K, E>,
|
|
62
|
-
key: Key,
|
|
63
|
-
counterfeit?: typeof COUNTERFEIT,
|
|
64
|
-
): ReadonlyPureSelectorToken<T, Key, E>
|
|
65
|
-
|
|
66
|
-
export function mint<T, K extends Canonical, Key extends K, E>(
|
|
67
|
-
token: SelectorFamilyToken<T, K, E>,
|
|
68
|
-
key: Key,
|
|
69
|
-
counterfeit?: typeof COUNTERFEIT,
|
|
70
|
-
): SelectorToken<T, Key, E>
|
|
71
|
-
|
|
72
|
-
export function mint<T, K extends Canonical, Key extends K, E>(
|
|
73
|
-
token: WritableFamilyToken<T, K, E>,
|
|
74
|
-
key: Key,
|
|
75
|
-
counterfeit?: typeof COUNTERFEIT,
|
|
76
|
-
): WritableToken<T, Key, E>
|
|
77
|
-
|
|
78
|
-
export function mint<T, K extends Canonical, Key extends K, E>(
|
|
79
|
-
token: ReadableFamilyToken<T, K, E>,
|
|
80
|
-
key: Key,
|
|
81
|
-
counterfeit?: typeof COUNTERFEIT,
|
|
82
|
-
): ReadableToken<T, Key, E>
|
|
83
|
-
|
|
84
|
-
export function mint(
|
|
85
|
-
token: ReadableFamilyToken<any, any, any>,
|
|
86
|
-
key: Canonical,
|
|
87
|
-
counterfeit?: typeof COUNTERFEIT,
|
|
88
|
-
): ReadableToken<any, any, any> {
|
|
89
|
-
const subKey = stringifyJson(key)
|
|
90
|
-
const fullKey = `${token.key}(${subKey})`
|
|
91
|
-
const type = FAMILY_MEMBER_TOKEN_TYPES[token.type]
|
|
92
|
-
const stateToken: ReadableToken<any> & {
|
|
93
|
-
counterfeit?: boolean
|
|
94
|
-
} = {
|
|
95
|
-
key: fullKey,
|
|
96
|
-
type,
|
|
97
|
-
family: {
|
|
98
|
-
key: token.key,
|
|
99
|
-
subKey,
|
|
100
|
-
},
|
|
101
|
-
}
|
|
102
|
-
|
|
103
|
-
if (counterfeit) {
|
|
104
|
-
stateToken.counterfeit = true
|
|
105
|
-
}
|
|
106
|
-
|
|
107
|
-
return stateToken
|
|
108
|
-
}
|