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
|
@@ -7,15 +7,14 @@ import * as React from "react"
|
|
|
7
7
|
|
|
8
8
|
import { useRealtimeService } from "./use-realtime-service"
|
|
9
9
|
|
|
10
|
-
export function usePullSelectorFamilyMember<
|
|
11
|
-
T,
|
|
12
|
-
K
|
|
13
|
-
|
|
14
|
-
>(familyToken: AtomIO.SelectorFamilyToken<T, K>, key: Key): T {
|
|
10
|
+
export function usePullSelectorFamilyMember<T, K extends Canonical>(
|
|
11
|
+
familyToken: AtomIO.SelectorFamilyToken<T, K>,
|
|
12
|
+
key: NoInfer<K>,
|
|
13
|
+
): T {
|
|
15
14
|
const store = React.useContext(StoreContext)
|
|
16
15
|
const token = findInStore(store, familyToken, key)
|
|
17
16
|
useRealtimeService(`pull:${token.key}`, (socket) =>
|
|
18
|
-
RTC.pullSelectorFamilyMember(store, socket,
|
|
17
|
+
RTC.pullSelectorFamilyMember(store, socket, familyToken, key),
|
|
19
18
|
)
|
|
20
19
|
|
|
21
20
|
return useO(token)
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import type * as AtomIO from "atom.io"
|
|
2
2
|
import type { Json } from "atom.io/json"
|
|
3
|
-
import { StoreContext, useI } from "atom.io/react"
|
|
3
|
+
import { StoreContext, useI, useO } from "atom.io/react"
|
|
4
|
+
import * as RT from "atom.io/realtime"
|
|
4
5
|
import * as RTC from "atom.io/realtime-client"
|
|
5
6
|
import * as React from "react"
|
|
6
7
|
|
|
@@ -8,10 +9,13 @@ import { useRealtimeService } from "./use-realtime-service"
|
|
|
8
9
|
|
|
9
10
|
export function usePush<J extends Json.Serializable>(
|
|
10
11
|
token: AtomIO.WritableToken<J>,
|
|
11
|
-
): <New extends J>(next: New | ((old: J) => New)) => void {
|
|
12
|
+
): (<New extends J>(next: New | ((old: J) => New)) => void) | null {
|
|
12
13
|
const store = React.useContext(StoreContext)
|
|
13
14
|
useRealtimeService(`push:${token.key}`, (socket) =>
|
|
14
15
|
RTC.pushState(store, socket, token),
|
|
15
16
|
)
|
|
16
|
-
|
|
17
|
+
const mutex = useO(RT.mutexAtoms, token.key)
|
|
18
|
+
const setter = useI(token)
|
|
19
|
+
|
|
20
|
+
return mutex ? setter : null
|
|
17
21
|
}
|
|
@@ -1,31 +1,31 @@
|
|
|
1
1
|
import * as React from "react"
|
|
2
2
|
import type { Socket } from "socket.io-client"
|
|
3
3
|
|
|
4
|
-
import { onMount } from "./on-mount"
|
|
5
4
|
import { RealtimeContext } from "./realtime-context"
|
|
5
|
+
import { useSingleEffect } from "./use-single-effect"
|
|
6
6
|
|
|
7
7
|
export function useRealtimeService(
|
|
8
8
|
key: string,
|
|
9
|
-
create: (socket: Socket) => (
|
|
9
|
+
create: (socket: Socket) => () => void,
|
|
10
10
|
): void {
|
|
11
11
|
const { socket, services } = React.useContext(RealtimeContext)
|
|
12
|
-
|
|
12
|
+
useSingleEffect(() => {
|
|
13
13
|
let service = services?.get(key)
|
|
14
14
|
if (service) {
|
|
15
|
-
service
|
|
16
|
-
} else {
|
|
17
|
-
const dispose =
|
|
18
|
-
service =
|
|
15
|
+
++service.consumerCount
|
|
16
|
+
} else if (socket) {
|
|
17
|
+
const dispose = create(socket)
|
|
18
|
+
service = { consumerCount: 1, dispose }
|
|
19
19
|
services?.set(key, service)
|
|
20
20
|
}
|
|
21
21
|
return () => {
|
|
22
22
|
if (service) {
|
|
23
|
-
service
|
|
24
|
-
if (service
|
|
25
|
-
service
|
|
23
|
+
--service.consumerCount
|
|
24
|
+
if (service.consumerCount === 0) {
|
|
25
|
+
service.dispose?.()
|
|
26
26
|
services?.delete(key)
|
|
27
27
|
}
|
|
28
28
|
}
|
|
29
29
|
}
|
|
30
|
-
})
|
|
30
|
+
}, [socket, key])
|
|
31
31
|
}
|
|
@@ -1,28 +1,25 @@
|
|
|
1
1
|
/** biome-ignore-all lint/correctness/useHookAtTopLevel: intentional */
|
|
2
2
|
|
|
3
|
+
import { isFn } from "atom.io/internal/is-fn"
|
|
3
4
|
import * as React from "react"
|
|
4
5
|
|
|
5
|
-
// @ts-expect-error this is a safe way to check a property on the global object
|
|
6
|
-
const { NODE_ENV } = globalThis[`env`] ?? {}
|
|
7
|
-
const IN_DEV = NODE_ENV === `development`
|
|
8
|
-
|
|
9
|
-
function noop() {}
|
|
10
|
-
|
|
11
6
|
export function useSingleEffect(
|
|
12
7
|
effect: () => (() => void) | undefined | void,
|
|
13
8
|
deps: unknown[],
|
|
14
9
|
): void {
|
|
15
|
-
|
|
16
|
-
|
|
10
|
+
const globalEnv = (globalThis as unknown as { env: any })[`env`]
|
|
11
|
+
const isInDev = globalEnv?.NODE_ENV === `development`
|
|
12
|
+
if (isInDev) {
|
|
13
|
+
const cleanupRef = React.useRef<boolean | (() => void)>(false)
|
|
17
14
|
React.useEffect(() => {
|
|
18
|
-
let
|
|
19
|
-
if (
|
|
20
|
-
|
|
21
|
-
|
|
15
|
+
let cleanupFn = cleanupRef.current
|
|
16
|
+
if (cleanupFn === false) {
|
|
17
|
+
cleanupFn = effect() ?? true
|
|
18
|
+
cleanupRef.current = cleanupFn
|
|
22
19
|
} else {
|
|
23
20
|
return () => {
|
|
24
|
-
|
|
25
|
-
|
|
21
|
+
if (isFn(cleanupFn)) cleanupFn()
|
|
22
|
+
cleanupRef.current = false
|
|
26
23
|
}
|
|
27
24
|
}
|
|
28
25
|
}, deps)
|
|
@@ -5,7 +5,7 @@ import type {
|
|
|
5
5
|
} from "atom.io"
|
|
6
6
|
import { atomFamily } from "atom.io"
|
|
7
7
|
|
|
8
|
-
import type { UserKey } from "
|
|
8
|
+
import type { UserKey } from "../realtime-server-stores/server-user-store"
|
|
9
9
|
|
|
10
10
|
// export const completeUpdateAtoms = atomFamily<
|
|
11
11
|
// TransactionUpdate<any> | null,
|
|
@@ -10,7 +10,7 @@ import type { ContinuityToken } from "atom.io/realtime"
|
|
|
10
10
|
|
|
11
11
|
import type { ServerConfig, Socket } from ".."
|
|
12
12
|
import { socketAtoms, usersOfSockets } from ".."
|
|
13
|
-
import { userUnacknowledgedQueues } from "
|
|
13
|
+
import { userUnacknowledgedQueues } from "./continuity-store"
|
|
14
14
|
import { prepareToSendInitialPayload } from "./prepare-to-send-initial-payload"
|
|
15
15
|
import { prepareToServeTransactionRequest } from "./prepare-to-serve-transaction-request"
|
|
16
16
|
import { prepareToTrackClientAcknowledgement } from "./prepare-to-track-client-acknowledgement"
|
|
@@ -2,11 +2,9 @@ import type { Store } from "atom.io/internal"
|
|
|
2
2
|
import { setIntoStore } from "atom.io/internal"
|
|
3
3
|
import type { ContinuityToken } from "atom.io/realtime"
|
|
4
4
|
|
|
5
|
-
import type {
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
} from "../realtime-server-stores"
|
|
9
|
-
import { userUnacknowledgedQueues } from "../realtime-server-stores"
|
|
5
|
+
import type { UserKey } from "../realtime-server-stores"
|
|
6
|
+
import type { ContinuitySyncTransactionUpdate } from "./continuity-store"
|
|
7
|
+
import { userUnacknowledgedQueues } from "./continuity-store"
|
|
10
8
|
|
|
11
9
|
export function prepareToTrackClientAcknowledgement(
|
|
12
10
|
store: Store,
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { Events } from "./ipc-sockets"
|
|
2
|
+
import type { Socket } from "./socket-interface"
|
|
3
|
+
|
|
4
|
+
export function employSocket<I extends Events, K extends string & keyof I>(
|
|
5
|
+
socket: Socket,
|
|
6
|
+
event: K,
|
|
7
|
+
handleEvent: (...data: I[K]) => void,
|
|
8
|
+
): () => void {
|
|
9
|
+
socket.on(event, handleEvent)
|
|
10
|
+
const retireSocket = () => {
|
|
11
|
+
socket.off(event, handleEvent)
|
|
12
|
+
}
|
|
13
|
+
return retireSocket
|
|
14
|
+
}
|
|
@@ -1,6 +1,3 @@
|
|
|
1
|
-
import type { RootStore } from "atom.io/internal"
|
|
2
|
-
import type { Json } from "atom.io/json"
|
|
3
|
-
|
|
4
1
|
export * from "./continuity/prepare-to-sync-realtime-continuity"
|
|
5
2
|
export * from "./ipc-sockets"
|
|
6
3
|
export * from "./realtime-action-receiver"
|
|
@@ -10,20 +7,5 @@ export * from "./realtime-mutable-provider"
|
|
|
10
7
|
export * from "./realtime-server-stores"
|
|
11
8
|
export * from "./realtime-state-provider"
|
|
12
9
|
export * from "./realtime-state-receiver"
|
|
13
|
-
|
|
14
|
-
export type
|
|
15
|
-
id: string | undefined
|
|
16
|
-
on: (event: string, listener: (...args: Json.Serializable[]) => void) => void
|
|
17
|
-
onAny: (
|
|
18
|
-
listener: (event: string, ...args: Json.Serializable[]) => void,
|
|
19
|
-
) => void
|
|
20
|
-
off: (event: string, listener: (...args: Json.Serializable[]) => void) => void
|
|
21
|
-
offAny: (
|
|
22
|
-
listener: (event: string, ...args: Json.Serializable[]) => void,
|
|
23
|
-
) => void
|
|
24
|
-
emit: (event: string, ...args: Json.Serializable[]) => void
|
|
25
|
-
}
|
|
26
|
-
export type ServerConfig = {
|
|
27
|
-
socket: Socket
|
|
28
|
-
store?: RootStore
|
|
29
|
-
}
|
|
10
|
+
export type * from "./server-config"
|
|
11
|
+
export type * from "./socket-interface"
|
|
@@ -1,16 +1,26 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { Readable, Writable } from "node:stream"
|
|
2
2
|
|
|
3
|
-
import type { Json } from "atom.io/json"
|
|
3
|
+
import type { Json, stringified } from "atom.io/json"
|
|
4
4
|
import { parseJson } from "atom.io/json"
|
|
5
5
|
|
|
6
|
-
import type { EventBuffer, Events } from "./custom-socket"
|
|
6
|
+
import type { EventBuffer, EventPayload, Events } from "./custom-socket"
|
|
7
7
|
import { CustomSocket } from "./custom-socket"
|
|
8
8
|
|
|
9
9
|
/* eslint-disable no-console */
|
|
10
10
|
|
|
11
|
+
export type ChildProcess = {
|
|
12
|
+
pid?: number | undefined
|
|
13
|
+
stdin: Writable
|
|
14
|
+
stdout: Readable
|
|
15
|
+
stderr: Readable
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export type StderrLog = [`e` | `i` | `w`, ...Json.Array]
|
|
19
|
+
|
|
11
20
|
export class ChildSocket<
|
|
12
21
|
I extends Events,
|
|
13
22
|
O extends Events,
|
|
23
|
+
P extends ChildProcess = ChildProcess,
|
|
14
24
|
> extends CustomSocket<I, O> {
|
|
15
25
|
protected incompleteData = ``
|
|
16
26
|
protected unprocessedEvents: string[] = []
|
|
@@ -19,13 +29,13 @@ export class ChildSocket<
|
|
|
19
29
|
|
|
20
30
|
public id = `#####`
|
|
21
31
|
|
|
22
|
-
public
|
|
32
|
+
public proc: P
|
|
23
33
|
public key: string
|
|
24
34
|
public logger: Pick<Console, `error` | `info` | `warn`>
|
|
25
35
|
|
|
26
|
-
protected handleLog(
|
|
27
|
-
if (Array.isArray(
|
|
28
|
-
const [level, ...rest] =
|
|
36
|
+
protected handleLog(log: StderrLog): void {
|
|
37
|
+
if (Array.isArray(log)) {
|
|
38
|
+
const [level, ...rest] = log
|
|
29
39
|
switch (level) {
|
|
30
40
|
case `i`:
|
|
31
41
|
this.logger.info(...rest)
|
|
@@ -36,14 +46,12 @@ export class ChildSocket<
|
|
|
36
46
|
case `e`:
|
|
37
47
|
this.logger.error(...rest)
|
|
38
48
|
break
|
|
39
|
-
default:
|
|
40
|
-
return
|
|
41
49
|
}
|
|
42
50
|
}
|
|
43
51
|
}
|
|
44
52
|
|
|
45
53
|
public constructor(
|
|
46
|
-
|
|
54
|
+
proc: P,
|
|
47
55
|
key: string,
|
|
48
56
|
logger?: Pick<Console, `error` | `info` | `warn`>,
|
|
49
57
|
) {
|
|
@@ -51,17 +59,17 @@ export class ChildSocket<
|
|
|
51
59
|
const stringifiedEvent = JSON.stringify([event, ...args]) + `\x03`
|
|
52
60
|
const errorHandler = (err: { code: string }) => {
|
|
53
61
|
if (err.code === `EPIPE`) {
|
|
54
|
-
console.error(`EPIPE error during write`, this.
|
|
62
|
+
console.error(`EPIPE error during write`, this.proc.stdin)
|
|
55
63
|
}
|
|
56
|
-
this.
|
|
64
|
+
this.proc.stdin.removeListener(`error`, errorHandler)
|
|
57
65
|
}
|
|
58
66
|
|
|
59
|
-
this.
|
|
60
|
-
this.
|
|
67
|
+
this.proc.stdin.once(`error`, errorHandler)
|
|
68
|
+
this.proc.stdin.write(stringifiedEvent)
|
|
61
69
|
|
|
62
70
|
return this
|
|
63
71
|
})
|
|
64
|
-
this.
|
|
72
|
+
this.proc = proc
|
|
65
73
|
this.key = key
|
|
66
74
|
this.logger = logger ?? {
|
|
67
75
|
info: (...args: unknown[]) => {
|
|
@@ -74,74 +82,125 @@ export class ChildSocket<
|
|
|
74
82
|
console.error(this.id, this.key, ...args)
|
|
75
83
|
},
|
|
76
84
|
}
|
|
77
|
-
this.
|
|
85
|
+
this.proc.stdout.on(
|
|
78
86
|
`data`,
|
|
79
|
-
<
|
|
87
|
+
<K extends string & keyof I>(buffer: EventBuffer<I, K>) => {
|
|
80
88
|
const chunk = buffer.toString()
|
|
81
89
|
|
|
82
90
|
if (chunk === `ALIVE`) {
|
|
83
|
-
|
|
91
|
+
this.logger.info(chunk)
|
|
84
92
|
return
|
|
85
93
|
}
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
console.log(`❗`, this.incompleteData)
|
|
94
|
+
|
|
95
|
+
const pieces = chunk.split(`\x03`)
|
|
96
|
+
const initialMaybeWellFormed = pieces[0]
|
|
97
|
+
pieces[0] = this.incompleteData + initialMaybeWellFormed
|
|
98
|
+
let idx = 0
|
|
99
|
+
for (const piece of pieces) {
|
|
100
|
+
if (piece === ``) {
|
|
101
|
+
continue
|
|
95
102
|
}
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
+
try {
|
|
104
|
+
const jsonPiece = parseJson(piece as stringified<EventPayload<I, K>>)
|
|
105
|
+
this.handleEvent(...jsonPiece)
|
|
106
|
+
this.incompleteData = ``
|
|
107
|
+
} catch (thrown0) {
|
|
108
|
+
if (thrown0 instanceof Error) {
|
|
109
|
+
console.error(
|
|
110
|
+
[
|
|
111
|
+
`❌ Malformed data received from child process`,
|
|
112
|
+
``,
|
|
113
|
+
piece,
|
|
114
|
+
``,
|
|
115
|
+
thrown0.message,
|
|
116
|
+
].join(`\n❌\t`),
|
|
117
|
+
)
|
|
118
|
+
}
|
|
119
|
+
try {
|
|
120
|
+
if (idx === 0) {
|
|
121
|
+
this.incompleteData = piece
|
|
122
|
+
const maybeActualJsonPiece = parseJson(
|
|
123
|
+
initialMaybeWellFormed as stringified<EventPayload<I, K>>,
|
|
124
|
+
)
|
|
125
|
+
this.handleEvent(...maybeActualJsonPiece)
|
|
126
|
+
this.incompleteData = ``
|
|
127
|
+
} else {
|
|
128
|
+
this.incompleteData += piece
|
|
129
|
+
}
|
|
130
|
+
} catch (thrown1) {
|
|
131
|
+
if (thrown1 instanceof Error) {
|
|
132
|
+
console.error(
|
|
133
|
+
[
|
|
134
|
+
`❌ Malformed data received from child process`,
|
|
135
|
+
``,
|
|
136
|
+
initialMaybeWellFormed,
|
|
137
|
+
``,
|
|
138
|
+
thrown1.message,
|
|
139
|
+
].join(`\n❌\t`),
|
|
140
|
+
)
|
|
103
141
|
}
|
|
104
|
-
parsedEvent = parseJson(event)
|
|
105
|
-
this.handleEvent(...(parsedEvent as [string, ...I[keyof I]]))
|
|
106
142
|
}
|
|
107
143
|
}
|
|
108
|
-
|
|
109
|
-
} catch (error) {
|
|
110
|
-
console.warn(`⚠️----------------⚠️`)
|
|
111
|
-
console.warn(this.incompleteData)
|
|
112
|
-
console.warn(`⚠️----------------⚠️`)
|
|
113
|
-
console.error(error)
|
|
144
|
+
++idx
|
|
114
145
|
}
|
|
115
146
|
},
|
|
116
147
|
)
|
|
117
|
-
this.
|
|
118
|
-
const chunk =
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
const
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
this.
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
148
|
+
this.proc.stderr.on(`data`, (buffer: Buffer) => {
|
|
149
|
+
const chunk = buffer.toString()
|
|
150
|
+
const pieces = chunk.split(`\x03`)
|
|
151
|
+
const initialMaybeWellFormed = pieces[0]
|
|
152
|
+
pieces[0] = this.incompleteData + initialMaybeWellFormed
|
|
153
|
+
let idx = 0
|
|
154
|
+
for (const piece of pieces) {
|
|
155
|
+
if (piece === ``) {
|
|
156
|
+
continue
|
|
157
|
+
}
|
|
158
|
+
try {
|
|
159
|
+
const jsonPiece = parseJson(piece as stringified<StderrLog>)
|
|
160
|
+
this.handleLog(jsonPiece)
|
|
161
|
+
this.incompleteData = ``
|
|
162
|
+
} catch (thrown0) {
|
|
163
|
+
if (thrown0 instanceof Error) {
|
|
164
|
+
console.error(
|
|
165
|
+
[
|
|
166
|
+
`❌ Malformed log received from child process`,
|
|
167
|
+
``,
|
|
168
|
+
piece,
|
|
169
|
+
``,
|
|
170
|
+
thrown0.message,
|
|
171
|
+
].join(`\n❌\t`),
|
|
172
|
+
)
|
|
173
|
+
}
|
|
174
|
+
try {
|
|
175
|
+
if (idx === 0) {
|
|
176
|
+
this.incompleteData = piece
|
|
177
|
+
const maybeActualJsonPiece = parseJson(
|
|
178
|
+
initialMaybeWellFormed as stringified<StderrLog>,
|
|
179
|
+
)
|
|
180
|
+
this.handleLog(maybeActualJsonPiece)
|
|
181
|
+
this.incompleteData = ``
|
|
182
|
+
} else {
|
|
183
|
+
this.incompleteData += piece
|
|
184
|
+
}
|
|
185
|
+
} catch (thrown1) {
|
|
186
|
+
if (thrown1 instanceof Error) {
|
|
187
|
+
console.error(
|
|
188
|
+
[
|
|
189
|
+
`❌ Malformed log received from child process...`,
|
|
190
|
+
``,
|
|
191
|
+
initialMaybeWellFormed,
|
|
192
|
+
``,
|
|
193
|
+
thrown1.message,
|
|
194
|
+
].join(`\n❌\t`),
|
|
195
|
+
)
|
|
196
|
+
}
|
|
134
197
|
}
|
|
135
198
|
}
|
|
136
|
-
|
|
137
|
-
console.error(`❌❌❌`)
|
|
138
|
-
console.error(this.incompleteLog)
|
|
139
|
-
console.error(error)
|
|
140
|
-
console.error(`❌❌❌️`)
|
|
199
|
+
++idx
|
|
141
200
|
}
|
|
142
201
|
})
|
|
143
|
-
if (
|
|
144
|
-
this.id =
|
|
202
|
+
if (proc.pid) {
|
|
203
|
+
this.id = proc.pid.toString()
|
|
145
204
|
}
|
|
146
205
|
}
|
|
147
206
|
}
|
|
@@ -1,35 +1,37 @@
|
|
|
1
1
|
import type { Json, stringified } from "atom.io/json"
|
|
2
2
|
|
|
3
|
-
import type { Socket } from "
|
|
3
|
+
import type { Socket } from "../socket-interface"
|
|
4
4
|
|
|
5
5
|
export type Events = Json.Object<string, Json.Serializable[]>
|
|
6
6
|
|
|
7
|
-
export type
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
> =
|
|
7
|
+
export type EventPayload<
|
|
8
|
+
E extends Events,
|
|
9
|
+
K extends string & keyof E = string & keyof E,
|
|
10
|
+
> = [string, ...E[K]]
|
|
11
11
|
|
|
12
12
|
export interface EventBuffer<
|
|
13
|
-
|
|
14
|
-
|
|
13
|
+
E extends Events,
|
|
14
|
+
K extends string & keyof E = string & keyof E,
|
|
15
15
|
> extends Buffer {
|
|
16
|
-
toString():
|
|
16
|
+
toString(): stringified<EventPayload<E, K>>
|
|
17
17
|
}
|
|
18
18
|
|
|
19
|
-
export class CustomSocket<I extends Events, O extends Events>
|
|
19
|
+
export abstract class CustomSocket<I extends Events, O extends Events>
|
|
20
|
+
implements Socket
|
|
21
|
+
{
|
|
20
22
|
protected listeners: Map<keyof O, Set<(...args: Json.Array) => void>>
|
|
21
23
|
protected globalListeners: Set<(event: string, ...args: Json.Array) => void>
|
|
22
|
-
protected handleEvent<
|
|
23
|
-
|
|
24
|
-
...args: I[Event]
|
|
24
|
+
protected handleEvent<K extends string & keyof I>(
|
|
25
|
+
...args: EventPayload<I, K>
|
|
25
26
|
): void {
|
|
27
|
+
const [event, ...rest] = args
|
|
26
28
|
for (const listener of this.globalListeners) {
|
|
27
|
-
listener(event, ...
|
|
29
|
+
listener(event, ...rest)
|
|
28
30
|
}
|
|
29
31
|
const listeners = this.listeners.get(event)
|
|
30
32
|
if (listeners) {
|
|
31
33
|
for (const listener of listeners) {
|
|
32
|
-
listener(...
|
|
34
|
+
listener(...rest)
|
|
33
35
|
}
|
|
34
36
|
}
|
|
35
37
|
}
|