Refactor to use Context API for network status

This commit is contained in:
49lf
2024-04-14 11:12:51 -04:00
parent 39a6d265f2
commit ff08cef9f8
11 changed files with 349 additions and 272 deletions

View File

@ -12,6 +12,8 @@ import SignIn from './routes/SignIn'
import { Auth } from './Auth'
import { isTauri } from './lib/isTauri'
import Home from './routes/Home'
import { NetworkContext } from './hooks/useNetworkContext'
import { useNetworkStatus } from './hooks/useNetworkStatus'
import makeUrlPathRelative from './lib/makeUrlPathRelative'
import DownloadAppBanner from 'components/DownloadAppBanner'
import { WasmErrBanner } from 'components/WasmErrBanner'
@ -155,5 +157,9 @@ const router = createBrowserRouter([
* @returns RouterProvider
*/
export const Router = () => {
return <RouterProvider router={router} />
const networkStatus = useNetworkStatus()
return <NetworkContext.Provider value={networkStatus}>
<RouterProvider router={router} />
</NetworkContext.Provider>
}

View File

@ -3,13 +3,11 @@ import { isCursorInSketchCommandRange } from 'lang/util'
import { engineCommandManager, kclManager } from 'lib/singletons'
import { useModelingContext } from 'hooks/useModelingContext'
import { useCommandsContext } from 'hooks/useCommandsContext'
import { useNetworkContext } from 'hooks/useNetworkContext'
import { NetworkHealthState } from 'hooks/useNetworkStatus'
import { ActionButton } from 'components/ActionButton'
import { isSingleCursorInPipe } from 'lang/queryAst'
import { useKclContext } from 'lang/KclProvider'
import {
NetworkHealthState,
useNetworkStatus,
} from 'components/NetworkHealthIndicator'
import { useStore } from 'useStore'
import { ActionButtonDropdown } from 'components/ActionButtonDropdown'
import { useHotkeys } from 'react-hotkeys-hook'
@ -38,8 +36,7 @@ export function Toolbar({
}, [engineCommandManager.artifactMap, context.selectionRanges])
const toolbarButtonsRef = useRef<HTMLUListElement>(null)
const { overallState } = useNetworkStatus()
const { overallState } = useNetworkContext()
const { isExecuting } = useKclContext()
const { isStreamReady } = useStore((s) => ({
isStreamReady: s.isStreamReady,

View File

@ -1,41 +1,52 @@
import { useEffect, useState } from 'react'
// import {
// ConnectingType,
// ConnectingTypeGroup,
// DisconnectingType,
// EngineCommandManagerEvents,
// EngineConnectionEvents,
// EngineConnectionStateType,
// ErrorType,
// initialConnectingTypeGroupState,
// } from '../lang/std/engineConnection'
// import { engineCommandManager } from '../lib/singletons'
import {
EngineCommandManagerEvents,
EngineConnectionEvents,
ConnectionError,
CONNECTION_ERROR_TEXT,
} from '../lang/std/engineConnection'
// Sorted by severity
enum Error {
Unset = 0,
LongLoadingTime,
BadAuthToken,
TooManyConnections,
}
const errorText: Record<Error, string> = {
[Error.Unset]: "",
[Error.LongLoadingTime]: "Loading is taking longer than expected...",
[Error.BadAuthToken]: "Your authorization token is not valid; please login again.",
[Error.TooManyConnections]: "There are too many connections.",
}
import { engineCommandManager } from '../lib/singletons'
const Loading = ({ children }: React.PropsWithChildren) => {
const [error, setError] = useState<Error>(Error.Unset)
const [error, setError] = useState<ConnectionError>(ConnectionError.Unset)
useEffect(() => {
const onConnectionStateChange = (state: EngineConnectionState) => {
console.log("<Loading/>", state)
}
const onEngineAvailable = ({ detail: engineConnection }: CustomEvent) => {
engineConnection.addEventListener(
EngineConnectionEvents.ConnectionStateChanged,
onConnectionStateChange as EventListener
)
}
engineCommandManager.addEventListener(
EngineCommandManagerEvents.EngineAvailable,
onEngineAvailable as EventListener
)
return () => {
engineCommandManager.removeEventListener(
EngineCommandManagerEvents.EngineAvailable,
onEngineAvailable as EventListener
)
engineCommandManager.engineConnection?.removeEventListener(
EngineConnectionEvents.ConnectionStateChanged,
onConnectionStateChange as EventListener
)
}
}, [])
useEffect(() => {
// Don't set long loading time if there's a more severe error
if (error > Error.LongLoadingTime) return
if (error > ConnectionError.LongLoadingTime) return
const timer = setTimeout(() => {
setError(Error.LongLoadingTime)
setError(ConnectionError.LongLoadingTime)
}, 4000)
return () => clearTimeout(timer)
@ -61,10 +72,10 @@ const Loading = ({ children }: React.PropsWithChildren) => {
<p
className={
'text-sm mt-4 text-primary/60 transition-opacity duration-500' +
(error !== Error.Unset ? ' opacity-100' : ' opacity-0')
(error !== ConnectionError.Unset ? ' opacity-100' : ' opacity-0')
}
>
{ errorText[error] }
{ CONNECTION_ERROR_TEXT[error] }
</p>
</div>
)

View File

@ -33,6 +33,9 @@ import {
syntaxHighlighting,
defaultHighlightStyle,
} from '@codemirror/language'
import { useModelingContext } from 'hooks/useModelingContext'
import { useNetworkContext } from 'hooks/useNetworkContext'
import { NetworkHealthState } from 'hooks/useNetworkStatus'
import interact from '@replit/codemirror-interact'
import { kclManager, editorManager, codeManager } from 'lib/singletons'
import { useHotkeys } from 'react-hotkeys-hook'
@ -63,6 +66,9 @@ export const KclEditorPane = () => {
? getSystemTheme()
: context.app.theme.current
const { copilotLSP, kclLSP } = useLspContext()
const { overallState } = useNetworkContext()
const isNetworkOkay = overallState === NetworkHealthState.Ok
const navigate = useNavigate()
useEffect(() => {
if (typeof window === 'undefined') return

View File

@ -1,24 +1,9 @@
import { Popover } from '@headlessui/react'
import { useEffect, useState } from 'react'
import { ActionIcon, ActionIconProps } from './ActionIcon'
import {
ConnectingType,
ConnectingTypeGroup,
DisconnectingType,
EngineCommandManagerEvents,
EngineConnectionEvents,
EngineConnectionStateType,
ErrorType,
initialConnectingTypeGroupState,
} from '../lang/std/engineConnection'
import { engineCommandManager } from '../lib/singletons'
import Tooltip from './Tooltip'
export enum NetworkHealthState {
Ok,
Issue,
Disconnected,
}
import { ConnectingTypeGroup } from '../lang/std/engineConnection'
import { useNetworkContext } from '../hooks/useNetworkContext'
import { NetworkHealthState } from '../hooks/useNetworkStatus'
export const NETWORK_HEALTH_TEXT: Record<NetworkHealthState, string> = {
[NetworkHealthState.Ok]: 'Connected',
@ -81,198 +66,6 @@ const overallConnectionStateIcon: Record<
[NetworkHealthState.Disconnected]: 'networkCrossedOut',
}
export function useNetworkStatus() {
const [steps, setSteps] = useState(
structuredClone(initialConnectingTypeGroupState)
)
const [internetConnected, setInternetConnected] = useState<boolean>(true)
const [overallState, setOverallState] = useState<NetworkHealthState>(
NetworkHealthState.Disconnected
)
const [pingPongHealth, setPingPongHealth] = useState<'OK' | 'BAD'>('BAD')
const [hasCopied, setHasCopied] = useState<boolean>(false)
const [error, setError] = useState<ErrorType | undefined>(undefined)
const hasIssue = (i: [ConnectingType, boolean | undefined]) =>
i[1] === undefined ? i[1] : !i[1]
const [issues, setIssues] = useState<
Record<ConnectingTypeGroup, boolean | undefined>
>({
[ConnectingTypeGroup.WebSocket]: undefined,
[ConnectingTypeGroup.ICE]: undefined,
[ConnectingTypeGroup.WebRTC]: undefined,
})
const [hasIssues, setHasIssues] = useState<boolean | undefined>(undefined)
useEffect(() => {
setOverallState(
!internetConnected
? NetworkHealthState.Disconnected
: hasIssues || hasIssues === undefined
? NetworkHealthState.Issue
: NetworkHealthState.Ok
)
}, [hasIssues, internetConnected])
useEffect(() => {
const onlineCallback = () => {
setSteps(initialConnectingTypeGroupState)
setInternetConnected(true)
}
const offlineCallback = () => {
setInternetConnected(false)
}
window.addEventListener('online', onlineCallback)
window.addEventListener('offline', offlineCallback)
return () => {
window.removeEventListener('online', onlineCallback)
window.removeEventListener('offline', offlineCallback)
}
}, [])
useEffect(() => {
console.log(pingPongHealth)
}, [pingPongHealth])
useEffect(() => {
const issues = {
[ConnectingTypeGroup.WebSocket]: steps[
ConnectingTypeGroup.WebSocket
].reduce(
(acc: boolean | undefined, a) =>
acc === true || acc === undefined ? acc : hasIssue(a),
false
),
[ConnectingTypeGroup.ICE]: steps[ConnectingTypeGroup.ICE].reduce(
(acc: boolean | undefined, a) =>
acc === true || acc === undefined ? acc : hasIssue(a),
false
),
[ConnectingTypeGroup.WebRTC]: steps[ConnectingTypeGroup.WebRTC].reduce(
(acc: boolean | undefined, a) =>
acc === true || acc === undefined ? acc : hasIssue(a),
false
),
}
setIssues(issues)
}, [steps])
useEffect(() => {
setHasIssues(
issues[ConnectingTypeGroup.WebSocket] ||
issues[ConnectingTypeGroup.ICE] ||
issues[ConnectingTypeGroup.WebRTC]
)
}, [issues])
useEffect(() => {
const onPingPongChange = ({ detail: state }: CustomEvent) => {
setPingPongHealth(state)
}
const onConnectionStateChange = ({
detail: engineConnectionState,
}: CustomEvent) => {
setSteps((steps) => {
let nextSteps = structuredClone(steps)
if (
engineConnectionState.type === EngineConnectionStateType.Connecting
) {
const groups = Object.values(nextSteps)
for (let group of groups) {
for (let step of group) {
if (step[0] !== engineConnectionState.value.type) continue
step[1] = true
}
}
}
if (
engineConnectionState.type === EngineConnectionStateType.Disconnecting
) {
const groups = Object.values(nextSteps)
for (let group of groups) {
for (let step of group) {
if (
engineConnectionState.value.type === DisconnectingType.Error
) {
if (
engineConnectionState.value.value.lastConnectingValue
?.type === step[0]
) {
step[1] = false
}
}
}
if (engineConnectionState.value.type === DisconnectingType.Error) {
setError(engineConnectionState.value.value)
}
}
}
// Reset the state of all steps if we have disconnected.
if (
engineConnectionState.type === EngineConnectionStateType.Disconnected
) {
return structuredClone(initialConnectingTypeGroupState)
}
return nextSteps
})
}
const onEngineAvailable = ({ detail: engineConnection }: CustomEvent) => {
engineConnection.addEventListener(
EngineConnectionEvents.PingPongChanged,
onPingPongChange as EventListener
)
engineConnection.addEventListener(
EngineConnectionEvents.ConnectionStateChanged,
onConnectionStateChange as EventListener
)
}
engineCommandManager.addEventListener(
EngineCommandManagerEvents.EngineAvailable,
onEngineAvailable as EventListener
)
return () => {
engineCommandManager.removeEventListener(
EngineCommandManagerEvents.EngineAvailable,
onEngineAvailable as EventListener
)
// When the component is unmounted these should be assigned, but it's possible
// the component mounts and unmounts before engine is available.
engineCommandManager.engineConnection?.addEventListener(
EngineConnectionEvents.PingPongChanged,
onPingPongChange as EventListener
)
engineCommandManager.engineConnection?.addEventListener(
EngineConnectionEvents.ConnectionStateChanged,
onConnectionStateChange as EventListener
)
}
}, [])
return {
hasIssues,
overallState,
internetConnected,
steps,
issues,
error,
setHasCopied,
hasCopied,
pingPongHealth,
}
}
export const NetworkHealthIndicator = () => {
const {
hasIssues,
@ -283,7 +76,7 @@ export const NetworkHealthIndicator = () => {
error,
setHasCopied,
hasCopied,
} = useNetworkStatus()
} = useNetworkContext()
return (
<Popover className="relative">

View File

@ -4,8 +4,9 @@ import { getNormalisedCoordinates } from '../lib/utils'
import Loading from './Loading'
import { useSettingsAuthContext } from 'hooks/useSettingsAuthContext'
import { useModelingContext } from 'hooks/useModelingContext'
import { useNetworkContext } from 'hooks/useNetworkContext'
import { NetworkHealthState } from 'hooks/useNetworkStatus'
import { ClientSideScene } from 'clientSideScene/ClientSideSceneComp'
import { NetworkHealthState, useNetworkStatus } from './NetworkHealthIndicator'
import { butName } from 'lib/cameraControls'
import { sendSelectEventToEngine } from 'lib/selections'
@ -28,7 +29,7 @@ export const Stream = ({ className = '' }: { className?: string }) => {
}))
const { settings } = useSettingsAuthContext()
const { state } = useModelingContext()
const { overallState } = useNetworkStatus()
const { overallState } = useNetworkContext()
const isNetworkOkay = overallState === NetworkHealthState.Ok

View File

@ -0,0 +1,6 @@
import { createContext, useContext } from 'react'
export const NetworkContext = createContext(null)
export const useNetworkContext = () => {
return useContext(NetworkContext)
}

View File

@ -0,0 +1,214 @@
import { useEffect, useState } from 'react'
import {
ConnectingType,
ConnectingTypeGroup,
DisconnectingType,
EngineCommandManagerEvents,
EngineConnectionEvents,
EngineConnectionStateType,
ErrorType,
initialConnectingTypeGroupState,
} from '../lang/std/engineConnection'
import { engineCommandManager } from '../lib/singletons'
export enum NetworkHealthState {
Ok,
Issue,
Disconnected,
}
// Must be called from one place in the application.
// We've chosen the <Router /> component for this.
export function useNetworkStatus() {
const [steps, setSteps] = useState(
structuredClone(initialConnectingTypeGroupState)
)
const [internetConnected, setInternetConnected] = useState<boolean>(true)
const [overallState, setOverallState] = useState<NetworkHealthState>(
NetworkHealthState.Disconnected
)
const [pingPongHealth, setPingPongHealth] = useState<undefined | 'OK' | 'TIMEOUT'>(undefined)
const [hasCopied, setHasCopied] = useState<boolean>(false)
const [error, setError] = useState<ErrorType | undefined>(undefined)
const hasIssue = (i: [ConnectingType, boolean | undefined]) =>
i[1] === undefined ? i[1] : !i[1]
const [issues, setIssues] = useState<
Record<ConnectingTypeGroup, boolean | undefined>
>({
[ConnectingTypeGroup.WebSocket]: undefined,
[ConnectingTypeGroup.ICE]: undefined,
[ConnectingTypeGroup.WebRTC]: undefined,
})
const [hasIssues, setHasIssues] = useState<boolean | undefined>(undefined)
useEffect(() => {
setOverallState(
!internetConnected
? NetworkHealthState.Disconnected
: hasIssues || hasIssues === undefined
? NetworkHealthState.Issue
: NetworkHealthState.Ok
)
}, [hasIssues, internetConnected])
useEffect(() => {
const onlineCallback = () => {
setSteps(initialConnectingTypeGroupState)
setInternetConnected(true)
}
const offlineCallback = () => {
setInternetConnected(false)
}
window.addEventListener('online', onlineCallback)
window.addEventListener('offline', offlineCallback)
console.log("useNetworkStatus initialized")
return () => {
window.removeEventListener('online', onlineCallback)
window.removeEventListener('offline', offlineCallback)
console.log("useNetworkStatus teardown")
}
}, [])
useEffect(() => {
console.log("pingPongHealth", pingPongHealth)
}, [pingPongHealth])
useEffect(() => {
const issues = {
[ConnectingTypeGroup.WebSocket]: steps[
ConnectingTypeGroup.WebSocket
].reduce(
(acc: boolean | undefined, a) =>
acc === true || acc === undefined ? acc : hasIssue(a),
false
),
[ConnectingTypeGroup.ICE]: steps[ConnectingTypeGroup.ICE].reduce(
(acc: boolean | undefined, a) =>
acc === true || acc === undefined ? acc : hasIssue(a),
false
),
[ConnectingTypeGroup.WebRTC]: steps[ConnectingTypeGroup.WebRTC].reduce(
(acc: boolean | undefined, a) =>
acc === true || acc === undefined ? acc : hasIssue(a),
false
),
}
setIssues(issues)
}, [steps])
useEffect(() => {
setHasIssues(
issues[ConnectingTypeGroup.WebSocket] ||
issues[ConnectingTypeGroup.ICE] ||
issues[ConnectingTypeGroup.WebRTC]
)
}, [issues])
useEffect(() => {
const onPingPongChange = ({ detail: state }: CustomEvent) => {
setPingPongHealth(state)
}
const onConnectionStateChange = ({
detail: engineConnectionState,
}: CustomEvent) => {
setSteps((steps) => {
let nextSteps = structuredClone(steps)
if (
engineConnectionState.type === EngineConnectionStateType.Connecting
) {
const groups = Object.values(nextSteps)
for (let group of groups) {
for (let step of group) {
if (step[0] !== engineConnectionState.value.type) continue
step[1] = true
}
}
}
if (
engineConnectionState.type === EngineConnectionStateType.Disconnecting
) {
const groups = Object.values(nextSteps)
for (let group of groups) {
for (let step of group) {
if (
engineConnectionState.value.type === DisconnectingType.Error
) {
if (
engineConnectionState.value.value.lastConnectingValue
?.type === step[0]
) {
step[1] = false
}
}
}
if (engineConnectionState.value.type === DisconnectingType.Error) {
setError(engineConnectionState.value.value)
}
}
}
// Reset the state of all steps if we have disconnected.
if (
engineConnectionState.type === EngineConnectionStateType.Disconnected
) {
return structuredClone(initialConnectingTypeGroupState)
}
return nextSteps
})
}
const onEngineAvailable = ({ detail: engineConnection }: CustomEvent) => {
engineConnection.addEventListener(
EngineConnectionEvents.PingPongChanged,
onPingPongChange as EventListener
)
engineConnection.addEventListener(
EngineConnectionEvents.ConnectionStateChanged,
onConnectionStateChange as EventListener
)
}
engineCommandManager.addEventListener(
EngineCommandManagerEvents.EngineAvailable,
onEngineAvailable as EventListener
)
return () => {
engineCommandManager.removeEventListener(
EngineCommandManagerEvents.EngineAvailable,
onEngineAvailable as EventListener
)
// When the component is unmounted these should be assigned, but it's possible
// the component mounts and unmounts before engine is available.
engineCommandManager.engineConnection?.addEventListener(
EngineConnectionEvents.PingPongChanged,
onPingPongChange as EventListener
)
engineCommandManager.engineConnection?.addEventListener(
EngineConnectionEvents.ConnectionStateChanged,
onConnectionStateChange as EventListener
)
}
}, [])
return {
hasIssues,
overallState,
internetConnected,
steps,
issues,
error,
setHasCopied,
hasCopied,
pingPongHealth,
}
}

View File

@ -7,12 +7,10 @@ import { authMachine } from 'machines/authMachine'
import { settingsMachine } from 'machines/settingsMachine'
import { homeMachine } from 'machines/homeMachine'
import { Command, CommandSetConfig, CommandSetSchema } from 'lib/commandTypes'
import {
NetworkHealthState,
useNetworkStatus,
} from 'components/NetworkHealthIndicator'
import { useKclContext } from 'lang/KclProvider'
import { useStore } from 'useStore'
import { useNetworkContext } from 'hooks/useNetworkContext'
import { NetworkHealthState } from 'hooks/useNetworkStatus'
// This might not be necessary, AnyStateMachine from xstate is working
export type AllMachines =
@ -47,12 +45,16 @@ export default function useStateMachineCommands<
onCancel,
}: UseStateMachineCommandsArgs<T, S>) {
const { commandBarSend } = useCommandsContext()
const { overallState } = useNetworkStatus()
const { overallState } = useNetworkContext()
const { isExecuting } = useKclContext()
const { isStreamReady } = useStore((s) => ({
isStreamReady: s.isStreamReady,
}))
useEffect(() => {
console.log("useStateMachineCommands initialized")
}, [])
useEffect(() => {
const disableAllButtons =
overallState !== NetworkHealthState.Ok || isExecuting || !isStreamReady

View File

@ -113,9 +113,44 @@ export enum DisconnectingType {
Quit = 'quit',
}
// Sorted by severity
export enum ConnectionError {
Unset = 0,
LongLoadingTime,
ICENegotiate,
DataChannelError,
WebSocketError,
LocalDescriptionInvalid,
// These are more severe than protocol errors because they don't even allow
// the program to do any protocol messages in the first place if they occur.
BadAuthToken,
TooManyConnections,
// An unknown error is the most severe because it has not been classified
// or encountered before.
Unknown,
}
export const CONNECTION_ERROR_TEXT: Record<ConnectionError, string> = {
[ConnectionError.Unset]: "",
[ConnectionError.LongLoadingTime]: "Loading is taking longer than expected...",
[ConnectionError.ICENegotiate]: "ICE negotiation failed.",
[ConnectionError.DataChannelError]: "The data channel signaled an error.",
[ConnectionError.WebSocketError]: "The websocket signaled an error.",
[ConnectionError.LocalDescriptionInvalid]: "The local description is invalid.",
[ConnectionError.BadAuthToken]: "Your authorization token is not valid; please login again.",
[ConnectionError.TooManyConnections]: "There are too many connections.",
[ConnectionError.Unknown]: "An unexpected error occurred. Please report this to us.",
}
export interface ErrorType {
// We may not necessary have an error to assign.
error?: Error
// The error we've encountered.
error: ConnectionError,
// Additional context.
context?: string,
// We assign this in the state setter because we may have not failed at
// a Connecting state, which we check for there.
@ -130,7 +165,7 @@ export type DisconnectingValue =
// These are ordered by the expected sequence.
export enum ConnectingType {
WebSocketConnecting = 'websocket-connecting',
WebSocketEstablished = 'websocket-established',
WebSocketOpen = 'websocket-open',
PeerConnectionCreated = 'peer-connection-created',
ICEServersSet = 'ice-servers-set',
SetLocalDescription = 'set-local-description',
@ -157,7 +192,7 @@ export const initialConnectingTypeGroupState: Record<
> = {
[ConnectingTypeGroup.WebSocket]: [
[ConnectingType.WebSocketConnecting, undefined],
[ConnectingType.WebSocketEstablished, undefined],
[ConnectingType.WebSocketOpen, undefined],
],
[ConnectingTypeGroup.ICE]: [
[ConnectingType.PeerConnectionCreated, undefined],
@ -179,7 +214,7 @@ export const initialConnectingTypeGroupState: Record<
export type ConnectingValue =
| State<ConnectingType.WebSocketConnecting, void>
| State<ConnectingType.WebSocketEstablished, void>
| State<ConnectingType.WebSocketOpen, void>
| State<ConnectingType.PeerConnectionCreated, void>
| State<ConnectingType.ICEServersSet, void>
| State<ConnectingType.SetLocalDescription, void>
@ -200,7 +235,7 @@ export type EngineConnectionState =
| State<EngineConnectionStateType.Disconnecting, DisconnectingValue>
| State<EngineConnectionStateType.Disconnected, void>
export type PingPongState = 'OK' | 'BAD'
export type PingPongState = 'OK' | 'TIMEOUT'
export enum EngineConnectionEvents {
// Fires for each ping-pong success or failure.
@ -404,9 +439,8 @@ class EngineConnection extends EventTarget {
value: {
type: DisconnectingType.Error,
value: {
error: new Error(
'failed to negotiate ice connection; restarting'
),
error: ConnectionError.ICENegotiate,
context: event.toString(),
},
},
}
@ -532,6 +566,8 @@ class EngineConnection extends EventTarget {
})
this.unreliableDataChannel.addEventListener('close', (event) => {
console.log("data channel close")
this.disconnectAll()
this.finalizeIfAllConnectionsClosed()
})
@ -544,7 +580,8 @@ class EngineConnection extends EventTarget {
value: {
type: DisconnectingType.Error,
value: {
error: new Error(event.toString()),
error: ConnectionError.DataChannelError,
context: event.toString(),
},
},
}
@ -589,7 +626,7 @@ class EngineConnection extends EventTarget {
this.state = {
type: EngineConnectionStateType.Connecting,
value: {
type: ConnectingType.WebSocketEstablished,
type: ConnectingType.WebSocketOpen,
},
}
@ -609,6 +646,8 @@ class EngineConnection extends EventTarget {
})
this.websocket.addEventListener('close', (event) => {
console.log("websocket close")
this.disconnectAll()
this.finalizeIfAllConnectionsClosed()
})
@ -621,7 +660,8 @@ class EngineConnection extends EventTarget {
value: {
type: DisconnectingType.Error,
value: {
error: new Error(event.toString()),
error: ConnectionError.WebSocketError,
context: event.toString(),
},
},
}
@ -635,6 +675,8 @@ class EngineConnection extends EventTarget {
// when assuming we're the only consumer or that all messages will
// be carefully formatted here.
console.log("websocket message", event)
if (typeof event.data !== 'string') {
return
}
@ -680,7 +722,7 @@ failed cmd type was ${artifactThatFailed?.commandType}`
) {
this.dispatchEvent(
new CustomEvent(EngineConnectionEvents.PingPongChanged, {
detail: 'BAD',
detail: 'TIMEOUT',
})
)
} else {
@ -773,8 +815,7 @@ failed cmd type was ${artifactThatFailed?.commandType}`
}
})
})
.catch((error: Error) => {
console.error(error)
.catch((err: Error) => {
// The local description is invalid, so there's no point continuing.
this.disconnectAll()
this.state = {
@ -782,7 +823,8 @@ failed cmd type was ${artifactThatFailed?.commandType}`
value: {
type: DisconnectingType.Error,
value: {
error,
error: ConnectionError.LocalDescriptionInvalid,
context: err.toString(),
},
},
}

View File

@ -318,7 +318,6 @@ function resetAndSetEngineEntitySelectionCmds(
selections: SelectionToEngine[]
): Models['WebSocketRequest_type'][] {
if (!engineCommandManager.engineConnection?.isReady()) {
console.log('engine connection is not ready')
return []
}
return [