roku-debug 0.22.5 → 0.22.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.
Files changed (44) hide show
  1. package/CHANGELOG.md +24 -0
  2. package/dist/CompileErrorProcessor.d.ts +6 -0
  3. package/dist/CompileErrorProcessor.js +41 -0
  4. package/dist/CompileErrorProcessor.js.map +1 -1
  5. package/dist/LaunchConfiguration.d.ts +23 -0
  6. package/dist/PerfettoManager.d.ts +108 -0
  7. package/dist/PerfettoManager.js +394 -0
  8. package/dist/PerfettoManager.js.map +1 -0
  9. package/dist/RendezvousTracker.d.ts +1 -1
  10. package/dist/RokuECP.d.ts +27 -2
  11. package/dist/RokuECP.js +33 -0
  12. package/dist/RokuECP.js.map +1 -1
  13. package/dist/SceneGraphDebugCommandController.js.map +1 -1
  14. package/dist/adapters/DebugProtocolAdapter.d.ts +1 -0
  15. package/dist/adapters/DebugProtocolAdapter.js +5 -0
  16. package/dist/adapters/DebugProtocolAdapter.js.map +1 -1
  17. package/dist/adapters/TelnetAdapter.d.ts +1 -0
  18. package/dist/adapters/TelnetAdapter.js +3 -0
  19. package/dist/adapters/TelnetAdapter.js.map +1 -1
  20. package/dist/adapters/customVariables/ifDateTime.js +1 -9
  21. package/dist/adapters/customVariables/ifDateTime.js.map +1 -1
  22. package/dist/bsc/threading/ThreadMessageHandler.d.ts +2 -2
  23. package/dist/debugProtocol/PluginInterface.d.ts +1 -1
  24. package/dist/debugProtocol/client/DebugProtocolClientPlugin.d.ts +2 -2
  25. package/dist/debugProtocol/events/ProtocolEvent.d.ts +3 -3
  26. package/dist/debugProtocol/server/DebugProtocolServerPlugin.d.ts +2 -2
  27. package/dist/debugSession/BrightScriptDebugSession.d.ts +26 -1
  28. package/dist/debugSession/BrightScriptDebugSession.js +187 -18
  29. package/dist/debugSession/BrightScriptDebugSession.js.map +1 -1
  30. package/dist/debugSession/Events.d.ts +53 -2
  31. package/dist/debugSession/Events.js +57 -1
  32. package/dist/debugSession/Events.js.map +1 -1
  33. package/dist/index.d.ts +1 -0
  34. package/dist/index.js +1 -0
  35. package/dist/index.js.map +1 -1
  36. package/dist/interfaces.d.ts +4 -4
  37. package/dist/logging.d.ts +1 -1
  38. package/dist/managers/BreakpointManager.d.ts +2 -2
  39. package/dist/managers/ProjectManager.js +1 -1
  40. package/dist/managers/ProjectManager.js.map +1 -1
  41. package/dist/util.d.ts +6 -0
  42. package/dist/util.js +15 -2
  43. package/dist/util.js.map +1 -1
  44. package/package.json +7 -4
@@ -4,6 +4,7 @@ exports.BrightScriptDebugSession = void 0;
4
4
  const fsExtra = require("fs-extra");
5
5
  const natural_orderby_1 = require("natural-orderby");
6
6
  const path = require("path");
7
+ const semver = require("semver");
7
8
  const roku_deploy_1 = require("roku-deploy");
8
9
  const debugadapter_1 = require("@vscode/debugadapter");
9
10
  const SceneGraphDebugCommandController_1 = require("../SceneGraphDebugCommandController");
@@ -19,6 +20,7 @@ const FileManager_1 = require("../managers/FileManager");
19
20
  const SourceMapManager_1 = require("../managers/SourceMapManager");
20
21
  const LocationManager_1 = require("../managers/LocationManager");
21
22
  const BreakpointManager_1 = require("../managers/BreakpointManager");
23
+ const PerfettoManager_1 = require("../PerfettoManager");
22
24
  const logging_1 = require("../logging");
23
25
  const VariablesResponse_1 = require("../debugProtocol/events/responses/VariablesResponse");
24
26
  const brighterscript_1 = require("brighterscript");
@@ -106,6 +108,14 @@ class BrightScriptDebugSession extends debugadapter_1.DebugSession {
106
108
  get enableDebugProtocol() {
107
109
  return this.launchConfiguration.enableDebugProtocol;
108
110
  }
111
+ /**
112
+ * Check if the Roku firmware supports Perfetto tracing (requires OS 15.2 or higher)
113
+ */
114
+ get supportsPerfettoTracing() {
115
+ var _a, _b;
116
+ this.logger.log('Checking if device supports Perfetto tracing', this.deviceInfo.softwareVersion);
117
+ return semver.satisfies((_b = (_a = this.deviceInfo) === null || _a === void 0 ? void 0 : _a.softwareVersion) !== null && _b !== void 0 ? _b : '0.0', '>= 15.2');
118
+ }
109
119
  /**
110
120
  * Get a promise that resolves when the roku adapter is ready to be used
111
121
  */
@@ -121,7 +131,7 @@ class BrightScriptDebugSession extends debugadapter_1.DebugSession {
121
131
  initializeRequest(response, args) {
122
132
  this.initRequestArgs = args;
123
133
  this.logger.log('initializeRequest');
124
- response.body = response.body || {};
134
+ response.body || (response.body = {});
125
135
  // This debug adapter implements the configurationDoneRequest.
126
136
  response.body.supportsConfigurationDoneRequest = true;
127
137
  // The debug adapter supports the 'restart' request. In this case a client should not implement 'restart' by terminating and relaunching the adapter but by calling the RestartRequest.
@@ -258,7 +268,8 @@ class BrightScriptDebugSession extends debugadapter_1.DebugSession {
258
268
  * @returns
259
269
  */
260
270
  normalizeLaunchConfig(config) {
261
- var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r;
271
+ var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s, _t, _u, _v;
272
+ var _w, _x;
262
273
  (_a = config.cwd) !== null && _a !== void 0 ? _a : (config.cwd = process.cwd());
263
274
  (_b = config.outDir) !== null && _b !== void 0 ? _b : (config.outDir = (0, FileUtils_1.standardizePath) `${config.cwd}/out`);
264
275
  (_c = config.stagingDir) !== null && _c !== void 0 ? _c : (config.stagingDir = (0, FileUtils_1.standardizePath) `${config.outDir}/.roku-deploy-staging`);
@@ -274,11 +285,16 @@ class BrightScriptDebugSession extends debugadapter_1.DebugSession {
274
285
  (_o = config.autoResolveVirtualVariables) !== null && _o !== void 0 ? _o : (config.autoResolveVirtualVariables = false);
275
286
  (_p = config.enhanceREPLCompletions) !== null && _p !== void 0 ? _p : (config.enhanceREPLCompletions = true);
276
287
  (_q = config.username) !== null && _q !== void 0 ? _q : (config.username = 'rokudev');
288
+ if ((_s = (_r = config.profiling) === null || _r === void 0 ? void 0 : _r.tracing) === null || _s === void 0 ? void 0 : _s.enable) {
289
+ (_t = (_w = config.profiling.tracing).dir) !== null && _t !== void 0 ? _t : (_w.dir = (0, FileUtils_1.standardizePath) `${config.cwd}/traces/`);
290
+ // eslint-disable-next-line no-template-curly-in-string
291
+ (_u = (_x = config.profiling.tracing).filename) !== null && _u !== void 0 ? _u : (_x.filename = '${appTitle}_${timestamp}.perfetto-trace');
292
+ }
277
293
  // migrate the old `enableVariablesPanel` setting to the new `deferScopeLoading` setting
278
294
  if (typeof config.enableVariablesPanel !== 'boolean') {
279
295
  config.enableVariablesPanel = true;
280
296
  }
281
- (_r = config.deferScopeLoading) !== null && _r !== void 0 ? _r : (config.deferScopeLoading = config.enableVariablesPanel === false);
297
+ (_v = config.deferScopeLoading) !== null && _v !== void 0 ? _v : (config.deferScopeLoading = config.enableVariablesPanel === false);
282
298
  return config;
283
299
  }
284
300
  async launchRequest(response, config) {
@@ -304,13 +320,20 @@ class BrightScriptDebugSession extends debugadapter_1.DebugSession {
304
320
  // fetches the device info and parses the xml data to JSON object
305
321
  try {
306
322
  this.deviceInfo = await roku_deploy_1.rokuDeploy.getDeviceInfo({ host: this.launchConfiguration.host, remotePort: this.launchConfiguration.remotePort, enhance: true, timeout: 4000 });
323
+ if (this.deviceInfo.ecpSettingMode === 'limited') {
324
+ return await this.shutdown(`ECP access is limited on this Roku. Please change it to 'permissive' or 'enabled' and try again. (device: ${this.launchConfiguration.host})`);
325
+ }
307
326
  }
308
327
  catch (e) {
328
+ if (e instanceof roku_deploy_1.EcpNetworkAccessModeDisabledError) {
329
+ return this.shutdown(`ECP access is disabled on this Roku. Please change it to 'permissive' or 'enabled' and try again. (device: ${this.launchConfiguration.host})`);
330
+ }
309
331
  return this.shutdown(`Unable to connect to roku at '${this.launchConfiguration.host}'. Verify the IP address is correct and that the device is powered on and connected to same network as this computer.`);
310
332
  }
311
333
  if (this.deviceInfo && !this.deviceInfo.developerEnabled) {
312
334
  return this.shutdown(`Developer mode is not enabled for host '${this.launchConfiguration.host}'.`);
313
335
  }
336
+ await this.initializeProfiling();
314
337
  //initialize all file logging (rokuDevice, debugger, etc)
315
338
  this.fileLoggingManager.activate((_d = this.launchConfiguration) === null || _d === void 0 ? void 0 : _d.fileLogging, this.cwd);
316
339
  this.projectManager.launchConfiguration = this.launchConfiguration;
@@ -320,6 +343,7 @@ class BrightScriptDebugSession extends debugadapter_1.DebugSession {
320
343
  this.logger.log('[launchRequest] Packaging and deploying to roku');
321
344
  try {
322
345
  const packageEnd = this.logger.timeStart('log', 'Packaging');
346
+ this.sendLaunchProgress('start', 'Packaging');
323
347
  //build the main project and all component libraries at the same time
324
348
  await Promise.all([
325
349
  this.prepareMainProject(),
@@ -353,12 +377,12 @@ class BrightScriptDebugSession extends debugadapter_1.DebugSession {
353
377
  //pass along the console output
354
378
  if (this.launchConfiguration.consoleOutput === 'full') {
355
379
  this.rokuAdapter.on('console-output', (data) => {
356
- void this.sendLogOutput(data);
380
+ this.sendLogOutput(data).catch(e => this.logger.error('Failed to send log output', e));
357
381
  });
358
382
  }
359
383
  else {
360
384
  this.rokuAdapter.on('unhandled-console-output', (data) => {
361
- void this.sendLogOutput(data);
385
+ this.sendLogOutput(data).catch(e => this.logger.error('Failed to send log output', e));
362
386
  });
363
387
  }
364
388
  this.rokuAdapter.on('device-unresponsive', async (data) => {
@@ -386,7 +410,7 @@ class BrightScriptDebugSession extends debugadapter_1.DebugSession {
386
410
  });
387
411
  // handle any compile errors
388
412
  this.rokuAdapter.on('diagnostics', (diagnostics) => {
389
- void this.handleDiagnostics(diagnostics);
413
+ this.handleDiagnostics(diagnostics).catch(e => this.logger.error('Failed to handle diagnostics', e));
390
414
  });
391
415
  // close disconnect if required when the app is exited
392
416
  // eslint-disable-next-line @typescript-eslint/no-misused-promises
@@ -403,17 +427,21 @@ class BrightScriptDebugSession extends debugadapter_1.DebugSession {
403
427
  const message = 'App exit detected; but launchConfiguration.stopDebuggerOnAppExit is set to false, so keeping debug session running.';
404
428
  this.logger.log('[launchRequest]', message);
405
429
  this.sendEvent(new Events_1.LogOutputEvent(message));
406
- void this.rokuAdapter.once('connected').then(async () => {
430
+ this.rokuAdapter.once('connected').then(async () => {
407
431
  await this.rokuAdapter.setExceptionBreakpoints(this.exceptionBreakpoints);
408
- });
432
+ }).catch(e => this.logger.error('Failed to set exception breakpoints after reconnect', e));
409
433
  }
410
434
  });
435
+ //profiling supports connecting to the socket BEFORE a channel is published, so go ahead and connect now
436
+ await this.tryProfilingConnectOnStart();
437
+ this.sendLaunchProgress('update', 'Uploading to Roku');
411
438
  await this.publish();
412
439
  //hack for certain roku devices that lock up when this event is emitted (no idea why!).
413
440
  if (this.launchConfiguration.emitChannelPublishedEvent) {
414
441
  this.sendEvent(new Events_1.ChannelPublishedEvent(this.launchConfiguration));
415
442
  }
416
443
  //tell the adapter adapter that the channel has been launched.
444
+ this.sendLaunchProgress('update', 'Waiting on application');
417
445
  await this.rokuAdapter.activate();
418
446
  if (this.rokuAdapter.isDestroyed) {
419
447
  throw new Error('Debug session encountered an error');
@@ -436,7 +464,7 @@ class BrightScriptDebugSession extends debugadapter_1.DebugSession {
436
464
  throw error;
437
465
  }
438
466
  //at this point, the project has been deployed. If we need to use a deep link, launch it now.
439
- if (this.launchConfiguration.deepLinkUrl) {
467
+ if (this.launchConfiguration.deepLinkUrl && !this.enableDebugProtocol) {
440
468
  //wait until the first entry breakpoint has been hit
441
469
  await this.firstRunDeferred.promise;
442
470
  //if we are at a breakpoint, continue
@@ -459,9 +487,80 @@ class BrightScriptDebugSession extends debugadapter_1.DebugSession {
459
487
  const message = (e instanceof Exceptions_1.SocketConnectionInUseError) ? e.message : ((_f = e === null || e === void 0 ? void 0 : e.stack) !== null && _f !== void 0 ? _f : e);
460
488
  await this.shutdown(message, true);
461
489
  }
490
+ else {
491
+ this.sendLaunchProgress('end', 'Aborted (compile error)');
492
+ }
462
493
  }
463
494
  logEnd();
464
495
  }
496
+ /**
497
+ * Activate all required functionality for profiling
498
+ */
499
+ async initializeProfiling() {
500
+ var _a, _b, _c, _d, _e;
501
+ // Initialize PerfettoManager
502
+ this.perfettoManager = new PerfettoManager_1.PerfettoManager({
503
+ host: this.launchConfiguration.host,
504
+ rootDir: this.launchConfiguration.rootDir,
505
+ remotePort: this.launchConfiguration.remotePort,
506
+ ...(_a = this.launchConfiguration.profiling) === null || _a === void 0 ? void 0 : _a.tracing
507
+ });
508
+ //send certain profiling events back to the client
509
+ this.perfettoManager.on('enable', (event) => {
510
+ this.sendEvent(new Events_1.ProfilingEnabledEvent({
511
+ types: event.types
512
+ }));
513
+ });
514
+ this.perfettoManager.on('start', (event) => {
515
+ this.sendEvent(new Events_1.ProfilingStartEvent({
516
+ type: event.type
517
+ }));
518
+ });
519
+ this.perfettoManager.on('stop', (event) => {
520
+ this.sendEvent(new Events_1.ProfilingStopEvent({
521
+ type: event.type,
522
+ result: event.result
523
+ }));
524
+ });
525
+ this.perfettoManager.on('error', (event) => {
526
+ this.sendEvent(new Events_1.ProfilingErrorEvent({
527
+ error: event.error
528
+ }));
529
+ });
530
+ //tracing is explicitly enabled. Turn it on
531
+ if (((_c = (_b = this.launchConfiguration.profiling) === null || _b === void 0 ? void 0 : _b.tracing) === null || _c === void 0 ? void 0 : _c.enable) && this.supportsPerfettoTracing) {
532
+ this.logger.info('Enabling perfetto tracing because it is supported by the device and enabled in the launch configuration');
533
+ try {
534
+ await this.perfettoManager.enableTracing();
535
+ }
536
+ catch (e) {
537
+ this.logger.error('Failed to enable perfetto tracing', e);
538
+ }
539
+ //tracing is expicitly DISabled. turn it off
540
+ }
541
+ else if (((_e = (_d = this.launchConfiguration.profiling) === null || _d === void 0 ? void 0 : _d.tracing) === null || _e === void 0 ? void 0 : _e.enable) === false && this.supportsPerfettoTracing) {
542
+ this.logger.info('Disabling perfetto tracing because it is disabled in the launch configuration');
543
+ //TODO implement a way to disable perfetto tracing on the device
544
+ //profiling.tracing.enabled is set to `undefined`, which means we should do nothing
545
+ }
546
+ else {
547
+ this.logger.info('Skipping perfetto initalization because `profiling.tracing.enable` is not defined in the launch configuration');
548
+ }
549
+ }
550
+ /**
551
+ * If profiling was marked "connectOnStart", try connecting right away
552
+ */
553
+ async tryProfilingConnectOnStart() {
554
+ var _a, _b;
555
+ if (((_b = (_a = this.launchConfiguration.profiling) === null || _a === void 0 ? void 0 : _a.tracing) === null || _b === void 0 ? void 0 : _b.connectOnStart) && this.supportsPerfettoTracing) {
556
+ try {
557
+ await this.perfettoManager.startTracing();
558
+ }
559
+ catch (e) {
560
+ this.logger.error('Failed to start perfetto tracing on start', e);
561
+ }
562
+ }
563
+ }
465
564
  /**
466
565
  * Clear certain properties that need reset whenever a debug session is restarted (via vscode or launched from the Roku home screen)
467
566
  */
@@ -528,6 +627,7 @@ class BrightScriptDebugSession extends debugadapter_1.DebugSession {
528
627
  //find the first compile error (i.e. first DiagnosticSeverity.Error) if there is one
529
628
  this.compileError = diagnostics.find(x => x.severity === brighterscript_1.DiagnosticSeverity.Error);
530
629
  if (this.compileError) {
630
+ this.sendLaunchProgress('end', 'Aborted (compile error)');
531
631
  this.sendEvent(new debugadapter_1.StoppedEvent(Events_1.StoppedEventReason.exception, this.COMPILE_ERROR_THREAD_ID, `CompileError: ${this.compileError.message}`));
532
632
  }
533
633
  this.sendEvent(new Events_1.DiagnosticsEvent(diagnostics));
@@ -832,7 +932,7 @@ class BrightScriptDebugSession extends debugadapter_1.DebugSession {
832
932
  * Accepts custom events and requests from the extension
833
933
  * @param command name of the command to execute
834
934
  */
835
- customRequest(command, response, args) {
935
+ async customRequest(command, response, args) {
836
936
  if (command === 'rendezvous.clearHistory') {
837
937
  this.rokuAdapter.clearRendezvousHistory();
838
938
  }
@@ -845,6 +945,27 @@ class BrightScriptDebugSession extends debugadapter_1.DebugSession {
845
945
  else if (command === 'popupMessageEventResponse') {
846
946
  this.emit('popupMessageEventResponse', args);
847
947
  }
948
+ else if (command === 'captureHeapSnapshot') {
949
+ this.perfettoManager.captureHeapSnapshot().catch((e) => this.logger.error('Failed to capture heap snapshot', e));
950
+ }
951
+ else if (command === 'startPerfettoTracing') {
952
+ try {
953
+ await this.perfettoManager.startTracing();
954
+ }
955
+ catch (e) {
956
+ response.success = false;
957
+ response.body = { message: (e === null || e === void 0 ? void 0 : e.message) || String(e) };
958
+ }
959
+ }
960
+ else if (command === 'stopPerfettoTracing') {
961
+ try {
962
+ await this.perfettoManager.stopTracing();
963
+ }
964
+ catch (e) {
965
+ response.success = false;
966
+ response.body = { message: (e === null || e === void 0 ? void 0 : e.message) || String(e) };
967
+ }
968
+ }
848
969
  this.sendResponse(response);
849
970
  }
850
971
  /**
@@ -1931,10 +2052,14 @@ class BrightScriptDebugSession extends debugadapter_1.DebugSession {
1931
2052
  */
1932
2053
  async connectRokuAdapter() {
1933
2054
  this.rokuAdapter.on('start', () => {
2055
+ this.sendLaunchProgress('end', 'Complete');
1934
2056
  if (!this.firstRunDeferred.isCompleted) {
1935
2057
  this.firstRunDeferred.resolve();
1936
2058
  }
1937
2059
  });
2060
+ this.rokuAdapter.on('launch-status', (message) => {
2061
+ this.sendLaunchProgress('update', message);
2062
+ });
1938
2063
  //when the debugger suspends (pauses for debugger input)
1939
2064
  // eslint-disable-next-line @typescript-eslint/no-misused-promises
1940
2065
  this.rokuAdapter.on('suspend', async () => {
@@ -1951,7 +2076,7 @@ class BrightScriptDebugSession extends debugadapter_1.DebugSession {
1951
2076
  });
1952
2077
  // If the roku says it can't continue, we are no longer able to debug, so kill the debug session
1953
2078
  this.rokuAdapter.on('cannot-continue', () => {
1954
- void this.shutdown();
2079
+ this.shutdown().catch(e => this.logger.error(e));
1955
2080
  });
1956
2081
  //make the connection
1957
2082
  await this.rokuAdapter.connect();
@@ -2191,6 +2316,35 @@ class BrightScriptDebugSession extends debugadapter_1.DebugSession {
2191
2316
  //erase all cached variables
2192
2317
  this.variables = {};
2193
2318
  }
2319
+ /**
2320
+ * Sends a launch progress event to the client if the client supports progress reporting.
2321
+ * - `'start'`: begins a new progress bar with the given message. Assigns a new progressId.
2322
+ * - `'update'`: updates the message on the active progress bar.
2323
+ * - `'end'`: dismisses the active progress bar with an optional final message.
2324
+ */
2325
+ sendLaunchProgress(type, message) {
2326
+ var _a;
2327
+ if (!((_a = this.initRequestArgs) === null || _a === void 0 ? void 0 : _a.supportsProgressReporting)) {
2328
+ return;
2329
+ }
2330
+ if (type === 'start') {
2331
+ this.launchProgressId = `rokudebug-launch-${this.idCounter++}`;
2332
+ this.sendEvent(new debugadapter_1.ProgressStartEvent(this.launchProgressId, 'Launching', `${message}...`));
2333
+ }
2334
+ else if (this.launchProgressId) {
2335
+ if (type === 'update') {
2336
+ this.sendEvent(new debugadapter_1.ProgressUpdateEvent(this.launchProgressId, `${message}...`));
2337
+ }
2338
+ else {
2339
+ const lastId = this.launchProgressId;
2340
+ this.sendEvent(new debugadapter_1.ProgressUpdateEvent(lastId, message));
2341
+ setTimeout(() => {
2342
+ this.sendEvent(new debugadapter_1.ProgressEndEvent(lastId, message));
2343
+ }, 1000); // add a slight delay before ending the progress to improve UX
2344
+ this.launchProgressId = undefined;
2345
+ }
2346
+ }
2347
+ }
2194
2348
  /**
2195
2349
  * Tells the client to re-request all variables because we've invalidated them
2196
2350
  * @param threadId
@@ -2274,7 +2428,9 @@ class BrightScriptDebugSession extends debugadapter_1.DebugSession {
2274
2428
  return this.shutdownPromise;
2275
2429
  }
2276
2430
  async _shutdown(errorMessage, modal = false) {
2277
- var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l;
2431
+ var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o;
2432
+ // Ensure any active launch progress bar is dismissed before showing error messages or the terminated event.
2433
+ this.sendLaunchProgress('end', 'Complete');
2278
2434
  //send the message FIRST before anything else. This improves the chances that the message will be displayed to the user
2279
2435
  try {
2280
2436
  if (errorMessage) {
@@ -2287,10 +2443,23 @@ class BrightScriptDebugSession extends debugadapter_1.DebugSession {
2287
2443
  catch (e) {
2288
2444
  this.logger.error(e);
2289
2445
  }
2446
+ // stop perfetto tracing if it's running
2447
+ try {
2448
+ await this.perfettoManager.stopTracing();
2449
+ }
2450
+ catch (e) {
2451
+ this.logger.error('Error stopping perfetto tracing', e);
2452
+ }
2453
+ try {
2454
+ await ((_b = (_a = this.perfettoManager) === null || _a === void 0 ? void 0 : _a.dispose) === null || _b === void 0 ? void 0 : _b.call(_a));
2455
+ }
2456
+ catch (e) {
2457
+ this.logger.error('Error disposing perfetto manager', e);
2458
+ }
2290
2459
  //close the debugger connection
2291
2460
  try {
2292
2461
  this.logger.log('Destroy rokuAdapter');
2293
- await ((_b = (_a = this.rokuAdapter) === null || _a === void 0 ? void 0 : _a.destroy) === null || _b === void 0 ? void 0 : _b.call(_a));
2462
+ await ((_d = (_c = this.rokuAdapter) === null || _c === void 0 ? void 0 : _c.destroy) === null || _d === void 0 ? void 0 : _d.call(_c));
2294
2463
  //press the home button to return to the home screen
2295
2464
  try {
2296
2465
  this.logger.log('Press home button');
@@ -2304,25 +2473,25 @@ class BrightScriptDebugSession extends debugadapter_1.DebugSession {
2304
2473
  this.logger.error(e);
2305
2474
  }
2306
2475
  try {
2307
- (_d = (_c = this.projectManager) === null || _c === void 0 ? void 0 : _c.dispose) === null || _d === void 0 ? void 0 : _d.call(_c);
2476
+ (_f = (_e = this.projectManager) === null || _e === void 0 ? void 0 : _e.dispose) === null || _f === void 0 ? void 0 : _f.call(_e);
2308
2477
  }
2309
2478
  catch (e) {
2310
2479
  this.logger.error(e);
2311
2480
  }
2312
2481
  try {
2313
- (_e = this.componentLibraryServer) === null || _e === void 0 ? void 0 : _e.stop();
2482
+ (_g = this.componentLibraryServer) === null || _g === void 0 ? void 0 : _g.stop();
2314
2483
  }
2315
2484
  catch (e) {
2316
2485
  this.logger.error(e);
2317
2486
  }
2318
2487
  try {
2319
- await ((_g = (_f = this.rendezvousTracker) === null || _f === void 0 ? void 0 : _f.destroy) === null || _g === void 0 ? void 0 : _g.call(_f));
2488
+ await ((_j = (_h = this.rendezvousTracker) === null || _h === void 0 ? void 0 : _h.destroy) === null || _j === void 0 ? void 0 : _j.call(_h));
2320
2489
  }
2321
2490
  catch (e) {
2322
2491
  this.logger.error(e);
2323
2492
  }
2324
2493
  try {
2325
- await ((_j = (_h = this.sourceMapManager) === null || _h === void 0 ? void 0 : _h.destroy) === null || _j === void 0 ? void 0 : _j.call(_h));
2494
+ await ((_l = (_k = this.sourceMapManager) === null || _k === void 0 ? void 0 : _k.destroy) === null || _l === void 0 ? void 0 : _l.call(_k));
2326
2495
  }
2327
2496
  catch (e) {
2328
2497
  this.logger.error(e);
@@ -2330,7 +2499,7 @@ class BrightScriptDebugSession extends debugadapter_1.DebugSession {
2330
2499
  try {
2331
2500
  //if configured, delete the staging directory
2332
2501
  if (!this.launchConfiguration.retainStagingFolder) {
2333
- const stagingDirs = (_l = (_k = this.projectManager) === null || _k === void 0 ? void 0 : _k.getStagingDirs()) !== null && _l !== void 0 ? _l : [];
2502
+ const stagingDirs = (_o = (_m = this.projectManager) === null || _m === void 0 ? void 0 : _m.getStagingDirs()) !== null && _o !== void 0 ? _o : [];
2334
2503
  this.logger.info('deleting staging folders', stagingDirs);
2335
2504
  for (let stagingDir of stagingDirs) {
2336
2505
  try {