connect static method

Future<LiveApp> connect(
  1. Uri uri, {
  2. required String device,
  3. required String package,
  4. Duration timeout = const Duration(seconds: 3),
  5. String? workspaceRoot,
  6. String? ideName,
  7. String? projectRoot,
  8. bool trusted = false,
})

Connects to the VM service at uri and finds the Nylo isolate.

When projectRoot is given, the app's entrypoint is resolved to a file and must live inside projectRoot; an app built elsewhere throws a LiveProjectMismatchException. If the entrypoint can't be resolved, the app is only accepted when trusted (its daemon was started for this project).

Throws a LiveCommandException when the app can't be reached or doesn't expose Nylo Live (a release build, or Nylo Live disabled).

Implementation

static Future<LiveApp> connect(
  Uri uri, {
  required String device,
  required String package,
  Duration timeout = const Duration(seconds: 3),
  String? workspaceRoot,
  String? ideName,
  String? projectRoot,
  bool trusted = false,
}) async {
  final JsonRpcClient client;
  try {
    client = await JsonRpcClient.connect(uri, timeout: timeout);
  } catch (e) {
    throw LiveCommandException('Couldn\'t connect to $uri ($e)');
  }

  try {
    final ({String id, String? rootLib})? nylo = await _findNylo(
      client,
      timeout: timeout,
    );
    if (nylo == null) {
      throw LiveCommandException(
        'The app at $uri doesn\'t expose Nylo Live. It needs to be a debug '
        'build on a Nylo version with live commands.',
      );
    }
    final String isolateId = nylo.id;

    if (projectRoot != null) {
      final String? entrypoint = await resolveEntrypoint(
        client,
        isolateId,
        nylo.rootLib,
        timeout: timeout,
      );
      if (entrypoint != null && !isInside(entrypoint, projectRoot)) {
        throw LiveProjectMismatchException(entrypoint);
      }
      if (entrypoint == null && !trusted) {
        throw LiveCommandException(
          'Couldn\'t confirm the app at $uri was built from this project. '
          'Pass --uri to target it directly.',
        );
      }
    }

    final Object? status = _unwrap(
      await client.call(statusExtension, {'isolateId': isolateId}, timeout),
    );
    return LiveApp(
      device: device,
      package: package,
      uri: uri,
      client: client,
      isolateId: isolateId,
      status: status is Map ? Map<String, Object?>.from(status) : {},
      workspaceRoot: workspaceRoot,
      ideName: ideName,
    );
  } on LiveCommandException {
    await client.close();
    rethrow;
  } on TimeoutException {
    await client.close();
    throw LiveCommandException(
      'The app at $uri didn\'t respond within ${timeout.inSeconds}s. '
      'It may be paused in a debugger or in the background.',
    );
  } catch (e) {
    await client.close();
    throw LiveCommandException('Couldn\'t talk to the app at $uri ($e)');
  }
}