mirror of
https://github.com/flutter/flutter.git
synced 2025-06-03 00:51:18 +00:00
[ Widget Preview ] Add initial support for communications over the Dart Tooling Daemon (DTD) (#166698)
This will eventually be used as the main communication channel between the widget preview scaffold, the Flutter tool, and other developer tooling (e.g., IDEs). Fixes #166417
This commit is contained in:
parent
9bf18f0971
commit
30e53b0d9c
@ -258,6 +258,8 @@ List<FlutterCommand> generateCommands({required bool verboseHelp, required bool
|
||||
platform: globals.platform,
|
||||
shutdownHooks: globals.shutdownHooks,
|
||||
os: globals.os,
|
||||
processManager: globals.processManager,
|
||||
artifacts: globals.artifacts!,
|
||||
),
|
||||
UpgradeCommand(verboseHelp: verboseHelp),
|
||||
SymbolizeCommand(stdio: globals.stdio, fileSystem: globals.fs),
|
||||
|
@ -5,7 +5,9 @@
|
||||
import 'package:args/args.dart';
|
||||
import 'package:meta/meta.dart';
|
||||
import 'package:package_config/package_config.dart';
|
||||
import 'package:process/process.dart';
|
||||
|
||||
import '../artifacts.dart';
|
||||
import '../base/common.dart';
|
||||
import '../base/deferred_component.dart';
|
||||
import '../base/file_system.dart';
|
||||
@ -24,6 +26,8 @@ import '../linux/build_linux.dart';
|
||||
import '../macos/build_macos.dart';
|
||||
import '../project.dart';
|
||||
import '../runner/flutter_command.dart';
|
||||
import '../runner/flutter_command_runner.dart';
|
||||
import '../widget_preview/dtd_services.dart';
|
||||
import '../widget_preview/preview_code_generator.dart';
|
||||
import '../widget_preview/preview_detector.dart';
|
||||
import '../widget_preview/preview_manifest.dart';
|
||||
@ -41,6 +45,8 @@ class WidgetPreviewCommand extends FlutterCommand {
|
||||
required Platform platform,
|
||||
required ShutdownHooks shutdownHooks,
|
||||
required OperatingSystemUtils os,
|
||||
required ProcessManager processManager,
|
||||
required Artifacts artifacts,
|
||||
}) {
|
||||
addSubcommand(
|
||||
WidgetPreviewStartCommand(
|
||||
@ -52,6 +58,8 @@ class WidgetPreviewCommand extends FlutterCommand {
|
||||
platform: platform,
|
||||
shutdownHooks: shutdownHooks,
|
||||
os: os,
|
||||
processManager: processManager,
|
||||
artifacts: artifacts,
|
||||
),
|
||||
);
|
||||
addSubcommand(
|
||||
@ -118,6 +126,8 @@ final class WidgetPreviewStartCommand extends WidgetPreviewSubCommandBase with C
|
||||
required this.platform,
|
||||
required this.shutdownHooks,
|
||||
required this.os,
|
||||
required this.processManager,
|
||||
required this.artifacts,
|
||||
}) {
|
||||
addPubOptions();
|
||||
argParser
|
||||
@ -152,6 +162,9 @@ final class WidgetPreviewStartCommand extends WidgetPreviewSubCommandBase with C
|
||||
static const String kHeadlessWeb = 'headless-web';
|
||||
static const String kWidgetPreviewScaffoldOutputDir = 'scaffold-output-dir';
|
||||
|
||||
/// Environment variable used to pass the DTD URI to the widget preview scaffold.
|
||||
static const String kWidgetPreviewDtdUriEnvVar = 'WIDGET_PREVIEW_DTD_URI';
|
||||
|
||||
@override
|
||||
Future<Set<DevelopmentArtifact>> get requiredArtifacts async => const <DevelopmentArtifact>{
|
||||
// Ensure the Flutter Web SDK is installed.
|
||||
@ -185,6 +198,10 @@ final class WidgetPreviewStartCommand extends WidgetPreviewSubCommandBase with C
|
||||
|
||||
final OperatingSystemUtils os;
|
||||
|
||||
final ProcessManager processManager;
|
||||
|
||||
final Artifacts artifacts;
|
||||
|
||||
late final FlutterProject rootProject = getRootProject();
|
||||
|
||||
late final PreviewDetector _previewDetector = PreviewDetector(
|
||||
@ -203,6 +220,12 @@ final class WidgetPreviewStartCommand extends WidgetPreviewSubCommandBase with C
|
||||
cache: cache,
|
||||
);
|
||||
|
||||
late final WidgetPreviewDtdServices _dtdService = WidgetPreviewDtdServices(
|
||||
logger: logger,
|
||||
shutdownHooks: shutdownHooks,
|
||||
dtdLauncher: DtdLauncher(logger: logger, artifacts: artifacts, processManager: processManager),
|
||||
);
|
||||
|
||||
/// The currently running instance of the widget preview scaffold.
|
||||
AppInstance? _widgetPreviewApp;
|
||||
|
||||
@ -284,6 +307,7 @@ final class WidgetPreviewStartCommand extends WidgetPreviewSubCommandBase with C
|
||||
shutdownHooks.addShutdownHook(() async {
|
||||
await _widgetPreviewApp?.stop();
|
||||
});
|
||||
await configureDtd();
|
||||
_widgetPreviewApp = await runPreviewEnvironment(
|
||||
widgetPreviewScaffoldProject: rootProject.widgetPreviewScaffoldProject,
|
||||
);
|
||||
@ -309,6 +333,31 @@ final class WidgetPreviewStartCommand extends WidgetPreviewSubCommandBase with C
|
||||
_populatePreviewPubspec(rootProject: rootProject);
|
||||
}
|
||||
|
||||
/// Configures the Dart Tooling Daemon connection.
|
||||
///
|
||||
/// If --dtd-uri is provided, the existing DTD instance will be used. If the tool fails to
|
||||
/// connect to this URI, it will start its own DTD instance.
|
||||
///
|
||||
/// If --dtd-uri is not provided, a DTD instance managed by the tool will be started.
|
||||
Future<void> configureDtd() async {
|
||||
final String? existingDtdUriStr = stringArg(FlutterGlobalOptions.kDtdUrl, global: true);
|
||||
Uri? existingDtdUri;
|
||||
try {
|
||||
if (existingDtdUriStr != null) {
|
||||
existingDtdUri = Uri.parse(existingDtdUriStr);
|
||||
}
|
||||
} on FormatException {
|
||||
logger.printWarning('Failed to parse value of --dtd-uri: $existingDtdUriStr.');
|
||||
}
|
||||
if (existingDtdUri == null) {
|
||||
logger.printTrace('Launching a fresh DTD instance...');
|
||||
await _dtdService.launchAndConnect();
|
||||
} else {
|
||||
logger.printTrace('Connecting to existing DTD instance at: $existingDtdUri...');
|
||||
await _dtdService.connect(dtdWsUri: existingDtdUri);
|
||||
}
|
||||
}
|
||||
|
||||
/// Builds the application binary for the widget preview scaffold the first
|
||||
/// time the widget preview command is run.
|
||||
///
|
||||
@ -457,6 +506,12 @@ final class WidgetPreviewStartCommand extends WidgetPreviewSubCommandBase with C
|
||||
BuildMode.debug,
|
||||
null,
|
||||
treeShakeIcons: false,
|
||||
// Provide the DTD connection information directly to the preview scaffold.
|
||||
// This could, in theory, be provided via a follow up call to a service extension
|
||||
// registered by the preview scaffold, but there's some uncertainty around how service
|
||||
// extensions will work with Flutter web embedded in VSCode without a Chrome debugger
|
||||
// connection.
|
||||
dartDefines: <String>['$kWidgetPreviewDtdUriEnvVar=${_dtdService.dtdUri}'],
|
||||
extraFrontEndOptions:
|
||||
isWeb ? <String>['--dartdevc-canary', '--dartdevc-module-format=ddc'] : null,
|
||||
packageConfigPath: widgetPreviewScaffoldProject.packageConfig.path,
|
||||
@ -599,6 +654,7 @@ final class WidgetPreviewStartCommand extends WidgetPreviewSubCommandBase with C
|
||||
if (offline) '--offline',
|
||||
'--directory',
|
||||
widgetPreviewScaffoldProject.directory.path,
|
||||
'dtd',
|
||||
'flutter_lints',
|
||||
'stack_trace',
|
||||
],
|
||||
|
@ -36,6 +36,7 @@ abstract final class FlutterGlobalOptions {
|
||||
static const String kMachineFlag = 'machine';
|
||||
static const String kPackagesOption = 'packages';
|
||||
static const String kPrefixedErrorsFlag = 'prefixed-errors';
|
||||
static const String kDtdUrl = 'dtd-url';
|
||||
static const String kPrintDtd = 'print-dtd';
|
||||
static const String kQuietFlag = 'quiet';
|
||||
static const String kShowTestDeviceFlag = 'show-test-device';
|
||||
@ -151,6 +152,12 @@ class FlutterCommandRunner extends CommandRunner<void> {
|
||||
hide: !verboseHelp,
|
||||
help: 'Path to your "package_config.json" file.',
|
||||
);
|
||||
argParser.addOption(
|
||||
FlutterGlobalOptions.kDtdUrl,
|
||||
help:
|
||||
'The address of an existing Dart Tooling Daemon instance to be used by the Flutter CLI.',
|
||||
hide: !verboseHelp,
|
||||
);
|
||||
argParser.addFlag(
|
||||
FlutterGlobalOptions.kPrintDtd,
|
||||
negatable: false,
|
||||
|
101
packages/flutter_tools/lib/src/widget_preview/dtd_services.dart
Normal file
101
packages/flutter_tools/lib/src/widget_preview/dtd_services.dart
Normal file
@ -0,0 +1,101 @@
|
||||
// Copyright 2014 The Flutter Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
import 'dart:async';
|
||||
|
||||
import 'package:dtd/dtd.dart';
|
||||
import 'package:process/process.dart';
|
||||
|
||||
import '../artifacts.dart';
|
||||
import '../base/common.dart';
|
||||
import '../base/io.dart';
|
||||
import '../base/logger.dart';
|
||||
import '../base/process.dart';
|
||||
import '../convert.dart';
|
||||
|
||||
/// Provides services, streams, and RPC invocations to interact with the Widget Preview Scaffold.
|
||||
class WidgetPreviewDtdServices {
|
||||
WidgetPreviewDtdServices({
|
||||
required this.logger,
|
||||
required this.shutdownHooks,
|
||||
required this.dtdLauncher,
|
||||
}) {
|
||||
shutdownHooks.addShutdownHook(() async {
|
||||
await _dtd?.close();
|
||||
await dtdLauncher.dispose();
|
||||
});
|
||||
}
|
||||
|
||||
final Logger logger;
|
||||
final ShutdownHooks shutdownHooks;
|
||||
final DtdLauncher dtdLauncher;
|
||||
|
||||
DartToolingDaemon? _dtd;
|
||||
|
||||
/// The [Uri] pointing to the currently connected DTD instance.
|
||||
///
|
||||
/// Returns `null` if there is no DTD connection.
|
||||
Uri? get dtdUri => _dtdUri;
|
||||
Uri? _dtdUri;
|
||||
|
||||
/// Starts DTD in a child process before invoking [connect] with a [Uri] pointing to the new
|
||||
/// DTD instance.
|
||||
Future<void> launchAndConnect() async {
|
||||
// Connect to the new DTD instance.
|
||||
await connect(dtdWsUri: await dtdLauncher.launch());
|
||||
}
|
||||
|
||||
/// Connects to an existing DTD instance and registers any relevant services.
|
||||
Future<void> connect({required Uri dtdWsUri}) async {
|
||||
_dtdUri = dtdWsUri;
|
||||
_dtd = await DartToolingDaemon.connect(dtdWsUri);
|
||||
// TODO(bkonyi): register services.
|
||||
logger.printTrace('Connected to DTD and registered services.');
|
||||
}
|
||||
}
|
||||
|
||||
/// Manages the lifecycle of a Dart Tooling Daemon (DTD) instance.
|
||||
class DtdLauncher {
|
||||
DtdLauncher({required this.logger, required this.artifacts, required this.processManager});
|
||||
|
||||
/// Starts a new DTD instance and returns the web socket URI it's available on.
|
||||
Future<Uri> launch() async {
|
||||
if (_dtdProcess != null) {
|
||||
throw StateError('Attempted to launch DTD twice.');
|
||||
}
|
||||
|
||||
// Start DTD.
|
||||
_dtdProcess = await processManager.start(<Object>[
|
||||
artifacts.getArtifactPath(Artifact.engineDartBinary),
|
||||
'tooling-daemon',
|
||||
'--machine',
|
||||
]);
|
||||
|
||||
// Wait for the DTD connection information.
|
||||
final Completer<Uri> dtdUri = Completer<Uri>();
|
||||
late final StreamSubscription<String> sub;
|
||||
sub = _dtdProcess!.stdout.transform(const Utf8Decoder()).listen((String data) async {
|
||||
await sub.cancel();
|
||||
final Map<String, Object?> jsonData = json.decode(data) as Map<String, Object?>;
|
||||
if (jsonData case {'tooling_daemon_details': {'uri': final String dtdUriString}}) {
|
||||
dtdUri.complete(Uri.parse(dtdUriString));
|
||||
} else {
|
||||
throwToolExit('Unable to start the Dart Tooling Daemon.');
|
||||
}
|
||||
});
|
||||
return dtdUri.future;
|
||||
}
|
||||
|
||||
/// Kills the spawned DTD instance.
|
||||
Future<void> dispose() async {
|
||||
_dtdProcess?.kill();
|
||||
_dtdProcess = null;
|
||||
}
|
||||
|
||||
final Logger logger;
|
||||
final Artifacts artifacts;
|
||||
final ProcessManager processManager;
|
||||
|
||||
Process? _dtdProcess;
|
||||
}
|
@ -356,6 +356,7 @@
|
||||
"templates/widget_preview_scaffold/lib/src/widget_preview.dart.tmpl",
|
||||
"templates/widget_preview_scaffold/lib/src/widget_preview_rendering.dart.tmpl",
|
||||
"templates/widget_preview_scaffold/lib/src/controls.dart.tmpl",
|
||||
"templates/widget_preview_scaffold/lib/src/dtd_services.dart.tmpl",
|
||||
"templates/widget_preview_scaffold/lib/src/generated_preview.dart.tmpl",
|
||||
"templates/widget_preview_scaffold/lib/src/utils.dart.tmpl",
|
||||
"templates/widget_preview_scaffold/pubspec.yaml.tmpl",
|
||||
|
@ -0,0 +1,33 @@
|
||||
// Copyright 2014 The Flutter Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
import 'dart:async';
|
||||
|
||||
import 'package:dtd/dtd.dart';
|
||||
|
||||
/// Provides services, streams, and RPC invocations to interact with Flutter developer tooling.
|
||||
class WidgetPreviewScaffoldDtdServices {
|
||||
/// Environment variable for the DTD URI.
|
||||
static const String kWidgetPreviewDtdUriEnvVar = 'WIDGET_PREVIEW_DTD_URI';
|
||||
|
||||
/// Connects to the Dart Tooling Daemon (DTD) specified by the Flutter tool.
|
||||
///
|
||||
/// If the connection is successful, the Widget Preview Scaffold will register services and
|
||||
/// subscribe to various streams to interact directly with other tooling (e.g., IDEs).
|
||||
Future<void> connect() async {
|
||||
final Uri dtdWsUri = Uri.parse(
|
||||
const String.fromEnvironment(kWidgetPreviewDtdUriEnvVar),
|
||||
);
|
||||
_dtd = await DartToolingDaemon.connect(dtdWsUri);
|
||||
unawaited(
|
||||
_dtd.postEvent(
|
||||
'WidgetPreviewScaffold',
|
||||
'Connected',
|
||||
const <String, Object?>{},
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
late final DartToolingDaemon _dtd;
|
||||
}
|
@ -13,6 +13,7 @@ import 'package:flutter/services.dart';
|
||||
import 'package:stack_trace/stack_trace.dart';
|
||||
|
||||
import 'controls.dart';
|
||||
import 'dtd_services.dart';
|
||||
import 'generated_preview.dart';
|
||||
import 'utils.dart';
|
||||
import 'widget_preview.dart';
|
||||
@ -410,6 +411,8 @@ class PreviewAssetBundle extends PlatformAssetBundle {
|
||||
/// the preview scaffold project which prevents us from being able to use hot
|
||||
/// restart to iterate on this file.
|
||||
Future<void> mainImpl() async {
|
||||
// TODO(bkonyi): store somewhere.
|
||||
await WidgetPreviewScaffoldDtdServices().connect();
|
||||
runApp(_WidgetPreviewScaffold());
|
||||
}
|
||||
|
||||
|
@ -12,6 +12,7 @@ dependencies:
|
||||
flutter_test:
|
||||
sdk: flutter
|
||||
# These will be replaced with proper constraints after the template is hydrated.
|
||||
dtd: any
|
||||
flutter_lints: any
|
||||
stack_trace: any
|
||||
|
||||
|
@ -3,6 +3,7 @@
|
||||
// found in the LICENSE file.
|
||||
|
||||
import 'package:file/memory.dart';
|
||||
import 'package:flutter_tools/src/artifacts.dart';
|
||||
import 'package:flutter_tools/src/base/file_system.dart';
|
||||
import 'package:flutter_tools/src/base/logger.dart';
|
||||
import 'package:flutter_tools/src/base/os.dart';
|
||||
@ -47,6 +48,8 @@ void main() {
|
||||
platform: platform,
|
||||
processManager: processManager,
|
||||
),
|
||||
processManager: FakeProcessManager.any(),
|
||||
artifacts: Artifacts.test(fileSystem: fileSystem),
|
||||
);
|
||||
rootProject = FakeFlutterProject(
|
||||
projectRoot: 'some_project',
|
||||
|
@ -6,6 +6,7 @@ import 'dart:io' as io show IOOverrides;
|
||||
|
||||
import 'package:args/command_runner.dart';
|
||||
import 'package:file_testing/file_testing.dart';
|
||||
import 'package:flutter_tools/src/artifacts.dart';
|
||||
import 'package:flutter_tools/src/base/bot_detector.dart';
|
||||
import 'package:flutter_tools/src/base/common.dart';
|
||||
import 'package:flutter_tools/src/base/file_system.dart';
|
||||
@ -80,6 +81,8 @@ void main() {
|
||||
logger: logger,
|
||||
platform: platform,
|
||||
),
|
||||
artifacts: Artifacts.test(),
|
||||
processManager: FakeProcessManager.any(),
|
||||
),
|
||||
);
|
||||
await runner.run(<String>['widget-preview', ...arguments]);
|
||||
|
@ -5,12 +5,18 @@
|
||||
import 'dart:async';
|
||||
import 'dart:convert';
|
||||
|
||||
import 'package:dtd/dtd.dart';
|
||||
import 'package:file/file.dart';
|
||||
import 'package:flutter_tools/src/base/io.dart';
|
||||
import 'package:flutter_tools/src/base/logger.dart';
|
||||
import 'package:flutter_tools/src/commands/widget_preview.dart';
|
||||
import 'package:flutter_tools/src/globals.dart' as globals;
|
||||
import 'package:flutter_tools/src/runner/flutter_command_runner.dart';
|
||||
import 'package:flutter_tools/src/widget_preview/dtd_services.dart';
|
||||
import 'package:process/process.dart';
|
||||
|
||||
import '../src/common.dart';
|
||||
import '../src/context.dart';
|
||||
import 'test_data/basic_project.dart';
|
||||
import 'test_utils.dart';
|
||||
|
||||
@ -43,10 +49,13 @@ const List<String> subsequentLaunchMessagesWeb = <String>[
|
||||
void main() {
|
||||
late Directory tempDir;
|
||||
Process? process;
|
||||
Logger? logger;
|
||||
DtdLauncher? dtdLauncher;
|
||||
final BasicProject project = BasicProject();
|
||||
const ProcessManager processManager = LocalProcessManager();
|
||||
|
||||
setUp(() async {
|
||||
logger = BufferLogger.test();
|
||||
tempDir = createResolvedTempDirectorySync('widget_preview_test.');
|
||||
await project.setUpIn(tempDir);
|
||||
});
|
||||
@ -54,12 +63,15 @@ void main() {
|
||||
tearDown(() async {
|
||||
process?.kill();
|
||||
process = null;
|
||||
await dtdLauncher?.dispose();
|
||||
dtdLauncher = null;
|
||||
tryToDelete(tempDir);
|
||||
});
|
||||
|
||||
Future<void> runWidgetPreview({
|
||||
required List<String> expectedMessages,
|
||||
bool useWeb = false,
|
||||
Uri? dtdUri,
|
||||
}) async {
|
||||
expect(expectedMessages, isNotEmpty);
|
||||
int i = 0;
|
||||
@ -72,6 +84,7 @@ void main() {
|
||||
'--${WidgetPreviewStartCommand.kHeadlessWeb}'
|
||||
else
|
||||
'--${WidgetPreviewStartCommand.kUseFlutterDesktop}',
|
||||
if (dtdUri != null) '--${FlutterGlobalOptions.kDtdUrl}=$dtdUri',
|
||||
], workingDirectory: tempDir.path);
|
||||
|
||||
final Completer<void> completer = Completer<void>();
|
||||
@ -103,8 +116,6 @@ void main() {
|
||||
}),
|
||||
);
|
||||
await completer.future;
|
||||
process!.kill();
|
||||
process = null;
|
||||
}
|
||||
|
||||
group('flutter widget-preview start', () {
|
||||
@ -132,5 +143,38 @@ void main() {
|
||||
// We shouldn't regenerate the scaffold after the initial run.
|
||||
await runWidgetPreview(expectedMessages: subsequentLaunchMessagesWeb, useWeb: true);
|
||||
});
|
||||
|
||||
testUsingContext('can connect to an existing DTD instance', () async {
|
||||
dtdLauncher = DtdLauncher(
|
||||
logger: logger!,
|
||||
artifacts: globals.artifacts!,
|
||||
processManager: globals.processManager,
|
||||
);
|
||||
|
||||
// Start a DTD instance.
|
||||
final Uri dtdUri = await dtdLauncher!.launch();
|
||||
|
||||
// Connect to it and listen to the WidgetPreviewScaffold stream.
|
||||
//
|
||||
// The preview scaffold will send a 'Connected' event on this stream once it has initialized
|
||||
// and is ready.
|
||||
final DartToolingDaemon dtdConnection = await DartToolingDaemon.connect(dtdUri);
|
||||
const String kWidgetPreviewScaffoldStream = 'WidgetPreviewScaffold';
|
||||
final Completer<void> completer = Completer<void>();
|
||||
dtdConnection.onEvent(kWidgetPreviewScaffoldStream).listen((DTDEvent event) {
|
||||
expect(event.stream, kWidgetPreviewScaffoldStream);
|
||||
expect(event.kind, 'Connected');
|
||||
completer.complete();
|
||||
});
|
||||
await dtdConnection.streamListen(kWidgetPreviewScaffoldStream);
|
||||
|
||||
// Start the widget preview and wait for the 'Connected' event.
|
||||
await runWidgetPreview(
|
||||
expectedMessages: firstLaunchMessagesWeb,
|
||||
useWeb: true,
|
||||
dtdUri: dtdUri,
|
||||
);
|
||||
await completer.future;
|
||||
});
|
||||
});
|
||||
}
|
||||
|
@ -0,0 +1,33 @@
|
||||
// Copyright 2014 The Flutter Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
import 'dart:async';
|
||||
|
||||
import 'package:dtd/dtd.dart';
|
||||
|
||||
/// Provides services, streams, and RPC invocations to interact with Flutter developer tooling.
|
||||
class WidgetPreviewScaffoldDtdServices {
|
||||
/// Environment variable for the DTD URI.
|
||||
static const String kWidgetPreviewDtdUriEnvVar = 'WIDGET_PREVIEW_DTD_URI';
|
||||
|
||||
/// Connects to the Dart Tooling Daemon (DTD) specified by the Flutter tool.
|
||||
///
|
||||
/// If the connection is successful, the Widget Preview Scaffold will register services and
|
||||
/// subscribe to various streams to interact directly with other tooling (e.g., IDEs).
|
||||
Future<void> connect() async {
|
||||
final Uri dtdWsUri = Uri.parse(
|
||||
const String.fromEnvironment(kWidgetPreviewDtdUriEnvVar),
|
||||
);
|
||||
_dtd = await DartToolingDaemon.connect(dtdWsUri);
|
||||
unawaited(
|
||||
_dtd.postEvent(
|
||||
'WidgetPreviewScaffold',
|
||||
'Connected',
|
||||
const <String, Object?>{},
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
late final DartToolingDaemon _dtd;
|
||||
}
|
@ -13,6 +13,7 @@ import 'package:flutter/services.dart';
|
||||
import 'package:stack_trace/stack_trace.dart';
|
||||
|
||||
import 'controls.dart';
|
||||
import 'dtd_services.dart';
|
||||
import 'generated_preview.dart';
|
||||
import 'utils.dart';
|
||||
import 'widget_preview.dart';
|
||||
@ -410,6 +411,8 @@ class PreviewAssetBundle extends PlatformAssetBundle {
|
||||
/// the preview scaffold project which prevents us from being able to use hot
|
||||
/// restart to iterate on this file.
|
||||
Future<void> mainImpl() async {
|
||||
// TODO(bkonyi): store somewhere.
|
||||
await WidgetPreviewScaffoldDtdServices().connect();
|
||||
runApp(_WidgetPreviewScaffold());
|
||||
}
|
||||
|
||||
|
@ -12,6 +12,7 @@ dependencies:
|
||||
flutter_test:
|
||||
sdk: flutter
|
||||
# These will be replaced with proper constraints after the template is hydrated.
|
||||
dtd: 2.5.0
|
||||
flutter_lints: 5.0.0
|
||||
stack_trace: 1.12.1
|
||||
|
||||
@ -20,7 +21,13 @@ dependencies:
|
||||
characters: 1.4.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
|
||||
clock: 1.1.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
|
||||
collection: 1.19.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
|
||||
convert: 3.1.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
|
||||
crypto: 3.0.6 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
|
||||
fake_async: 1.3.3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
|
||||
file: 7.0.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
|
||||
http: 1.3.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
|
||||
http_parser: 4.1.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
|
||||
json_rpc_2: 3.0.3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
|
||||
leak_tracker: 10.0.9 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
|
||||
leak_tracker_flutter_testing: 3.0.9 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
|
||||
leak_tracker_testing: 3.0.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
|
||||
@ -34,10 +41,15 @@ dependencies:
|
||||
string_scanner: 1.4.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
|
||||
term_glyph: 1.2.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
|
||||
test_api: 0.7.4 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
|
||||
typed_data: 1.4.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
|
||||
unified_analytics: 7.0.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
|
||||
vector_math: 2.1.4 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
|
||||
vm_service: 15.0.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
|
||||
web: 1.1.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
|
||||
web_socket: 0.1.6 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
|
||||
web_socket_channel: 3.0.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
|
||||
|
||||
flutter:
|
||||
uses-material-design: true
|
||||
|
||||
# PUBSPEC CHECKSUM: 367e
|
||||
# PUBSPEC CHECKSUM: 4b12
|
||||
|
Loading…
Reference in New Issue
Block a user