publishLiveWindows method

void Function() publishLiveWindows(
  1. String path, {
  2. required String app,
})

Writes what is open to path now and on every change, with app and the time, for dartvel inspect windows to read while it is fresh. Returns what stops it.

Implementation

void Function() publishLiveWindows(String path, {required String app}) {
  void write() {
    final List<DVWindow> windows = _all.value;
    final String json = const JsonEncoder.withIndent('  ').convert(<String, Object?>{
      'app': app,
      'at': DateTime.now().toUtc().toIso8601String(),
      'windows': <Map<String, Object?>>[
        for (final DVWindow w in windows)
          <String, Object?>{
            'route': w.route.path,
            'kind': w.kind.name,
            'presentation': w.presentation.name,
            if (w.nativeId != null) 'nativeId': w.nativeId,
            'external': w.external,
          },
      ],
      'performance': performance.toJson(),
      // What startup took, phase by phase. A kiosk that takes eleven
      // seconds to show its first screen is a fault somebody has to
      // answer for, and this is where the answer is.
      'startup': DVStartupProfile.current.toJson(),
    });
    try {
      final File file = File(path);
      file.parent.createSync(recursive: true);
      file.writeAsStringSync(json, flush: true);
    } on FileSystemException {
      // A runtime directory that vanished is not the app's problem.
    }
  }

  write();
  _all.addListener(write);
  // And on every startup phase. The first frame is marked after the
  // application is up, which is after this has already written what it
  // had; without this the published profile stops one phase short of the
  // only one whoever was waiting actually saw.
  DVStartupProfile.current.addListener(write);
  return () {
    _all.removeListener(write);
    DVStartupProfile.current.removeListener(write);
  };
}