| 14 | import { ActiveLocation, ActiveLocationChangedEvent, DebugSessionChangedEvent, DebugSessionStartedEvent, DebugSessionStoppedEvent, DeviceAddedEvent, DeviceChangedEvent, DeviceRemovedEvent, DeviceSelectedEvent, DtdMessage, DtdNotification, DtdRequest, DtdResponse, DtdResult, EnablePlatformTypeParams, Event, EventKind, GetDebugSessionsResult, GetDevicesResult, GetIDEWorkspaceRootsParams, GetIDEWorkspaceRootsResult, GetVmServicesResult, HotReloadParams, HotRestartParams, NavigateToCodeParams, OpenDevToolsPageParams, ReadFileAsStringParams, ReadFileAsStringResult, RegisterServiceParams, RegisterServiceResult, RegisterVmServiceParams, RegisterVmServiceResult, SelectDeviceParams, Service, ServiceMethod, ServiceRegisteredEventData, ServiceUnregisteredEventData, SetIDEWorkspaceRootsParams, SetIDEWorkspaceRootsResult, Stream, SuccessResult, UnregisterVmServiceParams, UnregisterVmServiceResult } from "./tooling_daemon_services"; |
| 15 | |
| 16 | export class DartToolingDaemon implements IAmDisposable { |
| 17 | protected readonly disposables: IAmDisposable[] = []; |
| 18 | protected readonly logger: CategoryLogger; |
| 19 | |
| 20 | private readonly dtdProcess: DartToolingDaemonProcess; |
| 21 | private connection: ConnectionInfo | undefined; |
| 22 | private nextId = 1; |
| 23 | private completers: Record<string, PromiseCompleter<DtdResult>> = {}; |
| 24 | private serviceHandlers: Record<string, (params?: object) => PromiseOr<DtdResult>> = {}; |
| 25 | |
| 26 | private hasShownTerminatedError = false; |
| 27 | private isShuttingDown = false; |
| 28 | |
| 29 | private connectedCompleter = new PromiseCompleter<ConnectionInfo | undefined>(); |
| 30 | public get connected() { return this.connectedCompleter.promise; } |
| 31 | |
| 32 | private readonly notificationsEmitters: Record<string, EventsEmitter<any>> = {}; |
| 33 | |
| 34 | /// The set of services that have been seen registered over the Services stream |
| 35 | /// but not yet unregistered. |
| 36 | public readonly registeredServiceMethods = new Set<string>(); |
| 37 | |
| 38 | constructor( |
| 39 | logger: Logger, |
| 40 | sdks: DartSdks, |
| 41 | protected readonly dartCapabilities: DartCapabilities, |
| 42 | additionalArgs: string[], |
| 43 | maxLogLineLength: number | undefined, |
| 44 | getToolEnv: () => any, |
| 45 | private readonly promptToReloadExtension: (logger: Logger, options: { prompt?: string; buttonText?: string; offerLog?: boolean; specificLog?: string; useError?: boolean; restartReason: ExtensionRestartReason }) => Promise<void>, |
| 46 | ) { |
| 47 | this.logger = new CategoryLogger(logger, LogCategory.DartToolingDaemon); |
| 48 | this.dtdProcess = new DartToolingDaemonProcess(this.logger, sdks, additionalArgs, maxLogLineLength, getToolEnv); |
| 49 | this.disposables.push(this.dtdProcess); |
| 50 | |
| 51 | void this.dtdProcess.dtdUri.then(() => this.connect()); |
| 52 | void this.dtdProcess.processExit.then((codes) => this.handleProcessExit(codes)); |
| 53 | } |
| 54 | |
| 55 | public get dtdUri(): Promise<string | undefined> { |
| 56 | return this.dtdProcess.dtdUri; |
| 57 | } |
| 58 | |
| 59 | private async connect() { |
| 60 | const dtdUri = await this.dtdProcess.dtdUri; |
| 61 | if (!dtdUri) |
| 62 | return; |
| 63 | const dtdSecret = await this.dtdProcess.dtdSecret; |
| 64 | |
| 65 | this.logger.info(`Connecting to DTD at ${dtdUri}...`); |
| 66 | const socket = new ws.WebSocket(dtdUri, { followRedirects: true }); |
| 67 | attachPing(socket); |
| 68 | socket.on("open", () => this.handleOpen()); |
| 69 | // eslint-disable-next-line @typescript-eslint/no-base-to-string |
| 70 | socket.on("message", (data) => this.handleData(data.toString())); |
| 71 | socket.on("close", () => this.handleWebSocketClose()); |
| 72 | socket.on("error", (e) => this.handleError(e)); |
| 73 |
nothing calls this directly
no outgoing calls
no test coverage detected