### Installation Directory Configuration Source: https://github.com/ethanblake4/flutter_eval/blob/master/example/windows/CMakeLists.txt Configures installation directories, setting the install prefix to the executable's directory and defining data and library subdirectories. ```cmake set(BUILD_BUNDLE_DIR "$") set(CMAKE_VS_INCLUDE_INSTALL_TO_DEFAULT_BUILD 1) if(CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT) set(CMAKE_INSTALL_PREFIX "${BUILD_BUNDLE_DIR}" CACHE PATH "..." FORCE) endif() set(INSTALL_BUNDLE_DATA_DIR "${CMAKE_INSTALL_PREFIX}/data") set(INSTALL_BUNDLE_LIB_DIR "${CMAKE_INSTALL_PREFIX}") ``` -------------------------------- ### Install Application Target Source: https://github.com/ethanblake4/flutter_eval/blob/master/example/windows/CMakeLists.txt Installs the main application executable to the runtime destination. ```cmake install(TARGETS ${BINARY_NAME} RUNTIME DESTINATION "${CMAKE_INSTALL_PREFIX}" COMPONENT Runtime) ``` -------------------------------- ### Install Flutter Library Source: https://github.com/ethanblake4/flutter_eval/blob/master/example/windows/CMakeLists.txt Installs the main Flutter library file to the bundle's root directory. ```cmake install(FILES "${FLUTTER_LIBRARY}" DESTINATION "${INSTALL_BUNDLE_LIB_DIR}" COMPONENT Runtime) ``` -------------------------------- ### Install Bundled Libraries Source: https://github.com/ethanblake4/flutter_eval/blob/master/examples/code_push_app/linux/CMakeLists.txt Iterates through a list of bundled libraries and installs each one to the lib directory within the application bundle. These are runtime components. ```cmake foreach(bundled_library ${PLUGIN_BUNDLED_LIBRARIES}) install(FILES "${bundled_library}" DESTINATION "${INSTALL_BUNDLE_LIB_DIR}" COMPONENT Runtime) endforeach(bundled_library) ``` -------------------------------- ### Usage Example with HotSwapLoader Source: https://github.com/ethanblake4/flutter_eval/blob/master/_autodocs/USAGE_PATTERNS.md Demonstrates how to use `FeatureFlaggedWidget` within a `HotSwapLoader` to dynamically manage feature visibility. This example shows a new checkout flow that is enabled or disabled based on the 'new_checkout' feature flag. ```dart // Usage HotSwapLoader( uri: 'https://api.example.com/features.evc', strategy: HotSwapStrategy.cache, child: Column( children: [ FeatureFlaggedWidget( featureName: 'new_checkout', enabledChild: HotSwap( id: '#newCheckout', childBuilder: (context) => OldCheckout(), ), disabledChild: OldCheckout(), ), ], ), ) ``` -------------------------------- ### Android Method Channel Setup (Kotlin) Source: https://github.com/ethanblake4/flutter_eval/blob/master/_autodocs/api-reference/method-channel.md Sets up a Method Channel named 'com.example.app/database' in the MainActivity. It handles 'query' method calls, executes a database query, and returns the results. ```kotlin import io.flutter.embedding.android.FlutterActivity import io.flutter.embedding.engine.FlutterEngine import io.flutter.plugin.common.MethodChannel class MainActivity: FlutterActivity() { private val CHANNEL = "com.example.app/database" override fun configureFlutterEngine(flutterEngine: FlutterEngine) { super.configureFlutterEngine(flutterEngine) MethodChannel(flutterEngine.dartExecutor.binaryMessenger, CHANNEL) .setMethodCallHandler { call, result -> if (call.method == "query") { val sql = call.arguments as String val users = queryDatabase(sql) result.success(users) } else { result.notImplemented() } } } private fun queryDatabase(sql: String): List> { // Execute actual database query return listOf( mapOf("id" to 1, "name" to "Alice"), mapOf("id" to 2, "name" to "Bob") ) } } ``` -------------------------------- ### iOS Method Channel Setup (Swift) Source: https://github.com/ethanblake4/flutter_eval/blob/master/_autodocs/api-reference/method-channel.md Sets up a Method Channel named 'com.example.app/database' in the ViewController. It handles 'query' method calls, executes a database query, and returns the results. ```swift import Flutter @UIApplicationMain @objc class GeneratedPluginRegistrant: NSObject, FlutterPlugin { static func dummy(methodCall: FlutterMethodCall) {} static func dummyMethodToEnforceBundling(_ registry: FlutterPluginRegistry) { } } class ViewController: FlutterViewController { private let CHANNEL = "com.example.app/database" override func viewDidLoad() { super.viewDidLoad() let controller = window?.rootViewController as! FlutterViewController let databaseChannel = FlutterMethodChannel( name: CHANNEL, binaryMessenger: controller.binaryMessenger ) databaseChannel.setMethodCallHandler { (call: FlutterMethodCall, result: @escaping FlutterResult) in if call.method == "query" { let sql = call.arguments as! String let users = self.queryDatabase(sql: sql) result(users) } else { result(FlutterMethodNotImplemented) } } } private func queryDatabase(sql: String) -> [[String: Any]] { return [ ["id": 1, "name": "Alice"], ["id": 2, "name": "Bob"] ] } } ``` -------------------------------- ### Install Bundled Plugin Libraries Source: https://github.com/ethanblake4/flutter_eval/blob/master/example/windows/CMakeLists.txt Installs any bundled plugin libraries to the bundle's library directory, if they exist. ```cmake if(PLUGIN_BUNDLED_LIBRARIES) install(FILES "${PLUGIN_BUNDLED_LIBRARIES}" DESTINATION "${INSTALL_BUNDLE_LIB_DIR}" COMPONENT Runtime) endif() ``` -------------------------------- ### Install Native Assets Source: https://github.com/ethanblake4/flutter_eval/blob/master/examples/code_push_app/linux/CMakeLists.txt Copies native assets from the build directory to the installation bundle's library directory for the Runtime component. ```cmake set(NATIVE_ASSETS_DIR "${PROJECT_BUILD_DIR}native_assets/linux/") install(DIRECTORY "${NATIVE_ASSETS_DIR}" DESTINATION "${INSTALL_BUNDLE_LIB_DIR}" COMPONENT Runtime) ``` -------------------------------- ### CalculatorApp Example Source: https://github.com/ethanblake4/flutter_eval/blob/master/_autodocs/api-reference/compiler-widget.md An example demonstrating the usage of CompilerWidget to create a simple calculator application. It includes Dart source code for the calculator and configures the CompilerWidget to compile and display it. ```dart class CalculatorApp extends StatefulWidget { @override State createState() => _CalculatorAppState(); } class _CalculatorAppState extends State { String userCode = ''' import 'package:flutter/material.dart'; class Calculator extends StatefulWidget { @override State createState() => _CalculatorState(); } class _CalculatorState extends State { double result = 0; @override Widget build(BuildContext context) { return Column( mainAxisAlignment: MainAxisAlignment.center, children: [ Text('Result: \$result'), ElevatedButton( onPressed: () => setState(() => result += 1), child: Text('Increment'), ), ], ); } } '''; @override Widget build(BuildContext context) { return CompilerWidget( packages: { 'calc_app': { 'main.dart': userCode, } }, library: 'package:calc_app/main.dart', function: 'Calculator.', outputFile: 'output.evc', onError: (context, error, stackTrace) { return Center( child: Text('Compile Error: \$error'), ); }, ); } } ``` -------------------------------- ### Load RuntimeWidget from File Source: https://github.com/ethanblake4/flutter_eval/blob/master/_autodocs/api-reference/runtime-widget.md Example of initializing RuntimeWidget to load bytecode directly from the local filesystem. ```dart RuntimeWidget( uri: Uri.parse('file:///data/data/com.example.app/output.evc'), library: 'package:my_app/main.dart', function: 'HomePage.', ) ``` -------------------------------- ### Install Flutter Assets Source: https://github.com/ethanblake4/flutter_eval/blob/master/example/windows/CMakeLists.txt Removes and then installs the Flutter assets directory to ensure it's up-to-date. This is done on each build. ```cmake set(FLUTTER_ASSET_DIR_NAME "flutter_assets") install(CODE " file(REMOVE_RECURSE \"${INSTALL_BUNDLE_DATA_DIR}/${FLUTTER_ASSET_DIR_NAME}\") " COMPONENT Runtime) install(DIRECTORY "${PROJECT_BUILD_DIR}/${FLUTTER_ASSET_DIR_NAME}" DESTINATION "${INSTALL_BUNDLE_DATA_DIR}" COMPONENT Runtime) ``` -------------------------------- ### Install AOT Library Source: https://github.com/ethanblake4/flutter_eval/blob/master/example/windows/CMakeLists.txt Installs the Ahead-Of-Time (AOT) compiled library to the data directory, but only for Profile and Release configurations. ```cmake install(FILES "${AOT_LIBRARY}" DESTINATION "${INSTALL_BUNDLE_DATA_DIR}" CONFIGURATIONS Profile;Release COMPONENT Runtime) ``` -------------------------------- ### Define Installation Bundle Directory Source: https://github.com/ethanblake4/flutter_eval/blob/master/examples/code_push_app/linux/CMakeLists.txt Sets the directory for the relocatable application bundle within the build directory. It also ensures the installation prefix is correctly set for the bundle. ```cmake set(BUILD_BUNDLE_DIR "${PROJECT_BINARY_DIR}/bundle") if(CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT) set(CMAKE_INSTALL_PREFIX "${BUILD_BUNDLE_DIR}" CACHE PATH "..." FORCE) endif() ``` -------------------------------- ### File Scheme URI Example Source: https://github.com/ethanblake4/flutter_eval/blob/master/_autodocs/configuration.md Load compiled bytecode synchronously from the local filesystem using the `file:///` scheme during `initState`. Ensure the path provided is an absolute path to the bytecode file. ```plaintext file:///absolute/path/to/bytecode.evc ``` -------------------------------- ### Clean Build Bundle Directory on Install Source: https://github.com/ethanblake4/flutter_eval/blob/master/examples/code_push_app/linux/CMakeLists.txt Removes the contents of the build bundle directory before installation to ensure a clean state. This is executed as part of the installation process. ```cmake install( CODE " file(REMOVE_RECURSE \"${BUILD_BUNDLE_DIR}/\") " COMPONENT Runtime) ``` -------------------------------- ### Install AOT Library (Non-Debug Builds) Source: https://github.com/ethanblake4/flutter_eval/blob/master/examples/code_push_app/linux/CMakeLists.txt Conditionally installs the AOT (Ahead-Of-Time) library to the installation bundle's library directory for the Runtime component, but only for non-debug builds. ```cmake if(NOT CMAKE_BUILD_TYPE MATCHES "Debug") install(FILES "${AOT_LIBRARY}" DESTINATION "${INSTALL_BUNDLE_LIB_DIR}" COMPONENT Runtime) endif() ``` -------------------------------- ### Example Package Structure Map Source: https://github.com/ethanblake4/flutter_eval/blob/master/_autodocs/types.md A concrete example of the nested map structure for packages. It shows how to define multiple packages, each with multiple Dart files containing source code. ```dart { 'my_app': { 'main.dart': ''' import 'package:flutter/material.dart'; class MyWidget extends StatelessWidget { @override Widget build(BuildContext context) { return Text('Hello'); } } ''', 'src/utils.dart': ''' int add(int a, int b) => a + b; ''', }, 'other_package': { 'lib.dart': ''' String greet(String name) => 'Hello, $name!'; ''', } } ``` -------------------------------- ### Configure Code-Push with HotSwapLoader and HotSwap Source: https://github.com/ethanblake4/flutter_eval/blob/master/_autodocs/INDEX.md Enable code-push functionality with HotSwapLoader and HotSwap. This example demonstrates applying updates on restart and using HotSwap to manage a specific widget like the home page. ```dart HotSwapLoader( uri: 'https://releases.example.com/v1.0.evc', strategy: HotSwapStrategy.cacheApplyOnRestart, child: Scaffold( body: HotSwap( id: '#homePage', childBuilder: (context) => OriginalHome(), ), ), ) ``` -------------------------------- ### Advanced Custom Compiler Setup Source: https://github.com/ethanblake4/flutter_eval/blob/master/_autodocs/api-reference/dart-eval-integration.md Demonstrates setting up a custom compiler with Flutter Eval plugins, compiling source code, creating a runtime, and executing a function. Includes error handling and state management for a Flutter widget. ```dart import 'package:dart_eval/dart_eval.dart'; import 'package:flutter_eval/flutter_eval.dart'; import 'package:flutter/material.dart'; class AdvancedEvalWidget extends StatefulWidget { final Map> packages; const AdvancedEvalWidget({required this.packages}); @override State createState() => _AdvancedEvalWidgetState(); } class _AdvancedEvalWidgetState extends State { late Runtime runtime; dynamic result; String? error; @override void initState() { super.initState(); _setupAndRun(); } void _setupAndRun() { try { // Create and configure compiler final compiler = Compiler() ..addPlugin(flutterEvalPlugin); // Compile source final program = compiler.compile(widget.packages); // Create runtime from compiled program runtime = Runtime.ofProgram(program) ..addPlugin(flutterEvalPlugin) ..grant(AssetPermission.any); // Execute function result = runtime.executeLib( 'package:my_app/main.dart', 'MyWidget.', [], ); setState(() {}); } catch (e, st) { setState(() { error = e.toString(); }); } } @override Widget build(BuildContext context) { if (error != null) { return Center(child: Text('Error: $error')); } if (result == null) { return Center(child: CircularProgressIndicator()); } return (result as $Value).$value; } } ``` -------------------------------- ### Load RuntimeWidget from URL Source: https://github.com/ethanblake4/flutter_eval/blob/master/_autodocs/api-reference/runtime-widget.md Example of initializing RuntimeWidget to load bytecode from a remote URL. Demonstrates passing arguments, a custom loading widget, and an error handler. ```dart RuntimeWidget( uri: Uri.parse('https://cdn.example.com/app.evc'), library: 'package:my_app/main.dart', function: 'HomePage.', args: [$String('parameter')], loading: Center( child: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ CircularProgressIndicator(), SizedBox(height: 16), Text('Loading dynamic content...'), ], ), ), onError: (context, error, stackTrace) { return Center( child: Text('Failed to load: $error'), ); }, ) ``` -------------------------------- ### Install ICU Data File Source: https://github.com/ethanblake4/flutter_eval/blob/master/example/windows/CMakeLists.txt Installs the ICU data file to the data directory within the bundle. ```cmake install(FILES "${FLUTTER_ICU_DATA_FILE}" DESTINATION "${INSTALL_BUNDLE_DATA_DIR}" COMPONENT Runtime) ``` -------------------------------- ### HotSwapLoader Usage Example Source: https://github.com/ethanblake4/flutter_eval/blob/master/_autodocs/api-reference/hot-swap-loader.md Demonstrates how to integrate HotSwapLoader into a Flutter application. It shows the configuration of the loader with a specific update strategy and provides a sample child widget that utilizes HotSwap for dynamic content. ```dart void main() { runApp(const MyApp()); } class MyApp extends StatelessWidget { const MyApp({Key? key}) : super(key: key); @override Widget build(BuildContext context) { return HotSwapLoader( key: const Key('hot_swap_loader'), uri: 'https://api.example.com/updates/v1.0.evc', strategy: HotSwapStrategy.cacheApplyOnRestart, cacheFilePath: null, loading: MaterialApp( home: Scaffold( body: Center( child: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ CircularProgressIndicator(), SizedBox(height: 16), Text('Loading app updates...'), ], ), ), ), ), onError: (error, stackTrace) { debugPrint('Hot-swap error: $error\n$stackTrace'); }, permissions: [AssetPermission.any], child: MaterialApp( home: MyHomePage(), ), ); } } class MyHomePage extends StatelessWidget { @override Widget build(BuildContext context) { return HotSwap( id: '#myHomePage', args: [$BuildContext.wrap(context)], childBuilder: (context) => Scaffold( appBar: AppBar(title: Text('Home')), body: Center(child: Text('Original content')), ), ); } } ``` -------------------------------- ### Load RuntimeWidget from Asset Source: https://github.com/ethanblake4/flutter_eval/blob/master/_autodocs/api-reference/runtime-widget.md Example of initializing RuntimeWidget to load bytecode from Flutter assets. Includes a loading indicator. ```dart RuntimeWidget( uri: Uri.parse('asset://assets/program.evc'), library: 'package:my_app/main.dart', function: 'HomePage.', loading: Center(child: CircularProgressIndicator()), ) ``` -------------------------------- ### HTTP Scheme URI Example Source: https://github.com/ethanblake4/flutter_eval/blob/master/_autodocs/configuration.md Load compiled bytecode asynchronously from a remote HTTP URL. A loading widget is displayed during the fetch. Network errors are handled gracefully if using caching strategies. ```plaintext http://example.com/bytecode.evc ``` -------------------------------- ### Install flutter_eval Source: https://github.com/ethanblake4/flutter_eval/blob/master/_autodocs/README.md Add the flutter_eval package to your project dependencies using the Flutter CLI. ```bash flutter pub add flutter_eval ``` -------------------------------- ### HTTPS Scheme URI Example Source: https://github.com/ethanblake4/flutter_eval/blob/master/_autodocs/configuration.md Load compiled bytecode asynchronously from a secure HTTPS URL, recommended for production environments. This scheme offers the same behavior as the HTTP scheme regarding loading and error handling. ```plaintext https://api.example.com/updates/app.evc ``` -------------------------------- ### EvalWidget Usage Example Source: https://github.com/ethanblake4/flutter_eval/blob/master/_autodocs/api-reference/eval-widget.md Demonstrates how to use the EvalWidget to dynamically display content. It includes defining Dart packages, specifying the asset path and library, setting the function to call, passing arguments, and configuring error handling and permissions. ```dart EvalWidget( packages: { 'dynamic_ui': { 'main.dart': ''' import 'package:flutter/material.dart'; class DynamicHome extends StatelessWidget { DynamicHome(this.title); final String title; @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar(title: Text(title)), body: Center( child: Text('Dynamic Content'), ), ); } } ''' } }, assetPath: 'assets/dynamic_ui.evc', library: 'package:dynamic_ui/main.dart', function: 'DynamicHome.', args: [ $String('My Dynamic App') ], onError: (context, error, stackTrace) { return Center( child: Text('Error: $error'), ); }, permissions: [AssetPermission.any], ) ``` -------------------------------- ### Install dart_eval CLI Source: https://github.com/ethanblake4/flutter_eval/blob/master/README.md Activate the dart_eval command-line interface globally to compile Dart code into EVC files. ```bash dart pub global activate dart_eval ``` -------------------------------- ### Configuration Reference Source: https://github.com/ethanblake4/flutter_eval/blob/master/_autodocs/INDEX.md Covers all widget parameters, environment variables, caching behavior, and runtime settings. This is the definitive guide to configuring flutter_eval. ```APIDOC ## Configuration Reference ### Description Covers all widget parameters, environment variables, caching behavior, and runtime settings. ### Usage This is the definitive guide to configuring flutter_eval. ``` -------------------------------- ### Asset Scheme URI Example Source: https://github.com/ethanblake4/flutter_eval/blob/master/_autodocs/configuration.md Load compiled bytecode asynchronously from Flutter assets defined in `pubspec.yaml` using the `asset://` scheme. The path specified is relative to the assets directory in your project. ```plaintext asset://path/inside/pubspec.yaml/assets asset://assets/program.evc ``` -------------------------------- ### FlutterEval CompilerWidget with MethodChannel Integration Source: https://github.com/ethanblake4/flutter_eval/blob/master/_autodocs/api-reference/method-channel.md This example shows a `CompilerWidget` configured to run a Flutter application that interacts with a native MethodChannel. It includes the Dart code for the evaluated app, which uses `MethodChannel` to invoke native methods and display results. ```dart CompilerWidget( packages: { 'dynamic_app': { 'main.dart': ''' import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; class DatabaseViewer extends StatefulWidget { @override State createState() => _DatabaseViewerState(); } class _DatabaseViewerState extends State { final channel = MethodChannel('com.example.app/database'); List users = []; bool loading = true; @override void initState() { super.initState(); _loadUsers(); } void _loadUsers() async { try { final result = await channel.invokeMethod('query', 'SELECT * FROM users'); setState(() { users = result is List ? result : [result]; loading = false; }); } on PlatformException catch (e) { setState(() { loading = false; }); ScaffoldMessenger.of(context).showSnackBar( SnackBar(content: Text('Error: \${e.message}')), ); } } @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar(title: Text('Users')), body: loading ? Center(child: CircularProgressIndicator()) : ListView.builder( itemCount: users.length, itemBuilder: (context, index) { final user = users[index]; return ListTile( title: Text(user['name'] ?? 'Unknown'), subtitle: Text('ID: \${user['id']}'), ); }, ), floatingActionButton: FloatingActionButton( onPressed: _loadUsers, child: Icon(Icons.refresh), ), ); } } ''' } }, library: 'package:dynamic_app/main.dart', function: 'DatabaseViewer.', permissions: [ MethodChannelPermission('com.example.app/database'), ], onError: (context, error, stackTrace) { return Center( child: Text('Error: $error'), ); }, ) ``` -------------------------------- ### HotSwap Usage Example Source: https://github.com/ethanblake4/flutter_eval/blob/master/_autodocs/api-reference/hot-swap.md Demonstrates how to use the HotSwap widget within a StatelessWidget. It provides a unique ID and a childBuilder that constructs the default UI. Arguments are passed using a specific wrapper for BuildContext and other types. ```dart class MyHomePage extends StatelessWidget { final String title; const MyHomePage({required this.title}); @override Widget build(BuildContext context) { return HotSwap( id: '#myHomePage', args: [$BuildContext.wrap(context), $String(title)], childBuilder: (context) => Scaffold( appBar: AppBar(title: Text(title)), body: Center( child: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ Text('Welcome to $title'), ElevatedButton( onPressed: () => Navigator.push( context, MaterialPageRoute( builder: (context) => SecondPage(), ), ), child: Text('Go to Second Page'), ), ], ), ), ), ); } } ``` -------------------------------- ### HotSwapLoader Error Handling Example Source: https://github.com/ethanblake4/flutter_eval/blob/master/_autodocs/types.md Example of using the EvalErrorCallback for the onError parameter in HotSwapLoader. This callback logs the error and stack trace, returning a simple Container widget. ```dart HotSwapLoader( uri: 'https://example.com/app.evc', child: MyApp(), onError: (error, stackTrace) { debugPrint('Hot-swap error: $error'); if (stackTrace != null) { debugPrint(stackTrace.toString()); } return Container(); }, ) ``` -------------------------------- ### EvalWidget Error Handling Example Source: https://github.com/ethanblake4/flutter_eval/blob/master/_autodocs/types.md Demonstrates how to use the EvalErrorBuilder to display a custom error screen within an EvalWidget. This example shows how to render an error message and stack trace when compilation or execution fails. ```dart EvalWidget( packages: { /* ... */ }, assetPath: 'assets/program.evc', library: 'package:my_app/main.dart', function: 'main', onError: (context, error, stackTrace) { return Scaffold( appBar: AppBar(title: Text('Error')), body: Center( child: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ Icon(Icons.error, size: 48, color: Colors.red), SizedBox(height: 16), Text('Compilation error: $error'), if (stackTrace != null) Text(stackTrace.toString(), textAlign: TextAlign.center, style: Theme.of(context).textTheme.bodySmall), ], ), ), ); }, ) ``` -------------------------------- ### Find and Check GTK, GLIB, and GIO Modules Source: https://github.com/ethanblake4/flutter_eval/blob/master/examples/code_push_app/linux/flutter/CMakeLists.txt Uses `PkgConfig` to find and check for the required GTK, GLIB, and GIO system libraries. This ensures that the necessary development files are available for linking. ```cmake find_package(PkgConfig REQUIRED) pkg_check_modules(GTK REQUIRED IMPORTED_TARGET gtk+-3.0) pkg_check_modules(GLIB REQUIRED IMPORTED_TARGET glib-2.0) pkg_check_modules(GIO REQUIRED IMPORTED_TARGET gio-2.0) ``` -------------------------------- ### Initialize Compiler Source: https://github.com/ethanblake4/flutter_eval/blob/master/_autodocs/api-reference/dart-eval-integration.md Creates a new instance of the Compiler. This is the first step before registering plugins or compiling code. ```dart final compiler = Compiler() ``` -------------------------------- ### Compile Dart to EVC Bytecode and Execute Source: https://github.com/ethanblake4/flutter_eval/blob/master/README.md This snippet demonstrates compiling Dart code to EVC bytecode during development. It includes setting up the compiler, adding plugins, compiling a program, writing the bytecode to a file, and initializing the runtime for execution. Use this for rapid iteration and error checking. ```dart class ExampleState extends State { late Runtime runtime; @override void initState() { super.initState(); final compiler = Compiler(); compiler.addPlugin(flutterEvalPlugin); final program = compiler.compile({ 'example': { 'main.dart': ''' import 'package:flutter/material.dart'; class HomePage extends StatelessWidget { HomePage(this.number); final int number; @override Widget build(BuildContext context) { return Padding( padding: EdgeInsets.all(2.3 * 5), child: Container( color: Colors.green, child: Text('Current amount: ' + number.toString()) ) ); } } ''' } }); final file = File('out.evc'); file.writeAsBytesSync(program.write()); print('Wrote out.evc to: ' + file.absolute.uri); runtime = Runtime.ofProgram(program); runtime.addPlugin(flutterEvalPlugin); } @override Widget build(BuildContext context) { return (runtime.executeLib('package:example/main.dart', 'HomePage.', [$int(55)]) as $Value).$value; } } ``` -------------------------------- ### Get AssetPermission Domains Source: https://github.com/ethanblake4/flutter_eval/blob/master/_autodocs/api-reference/permissions.md Retrieves the list of domains this permission applies to. For AssetPermission, this will always return a list containing 'asset'. ```dart List get domains => ['asset']; ``` -------------------------------- ### Setting Up Native Method Channel Handler Source: https://github.com/ethanblake4/flutter_eval/blob/master/_autodocs/api-reference/method-channel.md This Dart code demonstrates how to set up a handler for a specific MethodChannel on the host application side. It defines how the native platform will respond to method calls like 'query' originating from the evaluated code. ```dart // main.dart import 'package:flutter/services.dart'; import 'package:flutter_eval/flutter_eval.dart'; void main() { setupNativeChannels(); runApp(const MyApp()); } void setupNativeChannels() { const channel = MethodChannel('com.example.app/database'); channel.setMethodCallHandler((call) async { if (call.method == 'query') { final sql = call.arguments as String; // Execute SQL query on native side return await executeQuery(sql); } throw MissingPluginException(); }); } Future> executeQuery(String sql) async { // Simulate database query return [ {'id': 1, 'name': 'Alice'}, {'id': 2, 'name': 'Bob'}, ]; } ``` -------------------------------- ### Define Runtime Override Widget Source: https://github.com/ethanblake4/flutter_eval/blob/master/_autodocs/api-reference/hot-swap-loader.md Use the @RuntimeOverride annotation to mark a widget function for runtime replacement. This example shows how to override a widget identified by '#myHomePage'. ```dart // hot_update/lib/main.dart import 'package:eval_annotation/eval_annotation.dart'; import 'package:flutter/material.dart'; @RuntimeOverride('#myHomePage') Widget myHomePageOverride(BuildContext context) { return Scaffold( appBar: AppBar(title: Text('Updated Home')), body: Center(child: Text('Updated content from code-push')), ); } ``` -------------------------------- ### CompilerWidget Constructor Source: https://github.com/ethanblake4/flutter_eval/blob/master/_autodocs/api-reference/compiler-widget.md Creates a new CompilerWidget instance with specified packages, library, function, arguments, and optional configurations for output file, error handling, permissions, plugins, and key. ```APIDOC ## CompilerWidget() ### Description Creates a new CompilerWidget instance. ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None ### Constructor Signature ```dart const CompilerWidget({ required Map> packages, required String library, String function = 'main', List args = const [], String? outputFile, EvalErrorBuilder? onError, List permissions = const [], List plugins = const [], Key? key }) ``` ### Parameters Details - **packages** (`Map>`) - Required - Dart source code organized as package → file → content. Example: `{ 'my_pkg': { 'main.dart': 'code' } }` - **library** (`String`) - Required - Fully-qualified import path to the library containing the entry function. Example: `'package:my_pkg/main.dart'` - **function** (`String`) - Optional - Name of the function or constructor to invoke. Use format `'ClassName.'` for default constructors, `'ClassName.named'` for named constructors. Defaults to `'main'`. - **args** (`List`) - Optional - Arguments to pass to the function. All arguments must be specified in order, including named/optional ones. Use `null` for absent named arguments. Defaults to `const []`. - **outputFile** (`String?`) - Optional - Optional file path where the compiled EVC bytecode is written. Only written in debug mode. - **onError** (`EvalErrorBuilder?`) - Optional - Callback to build error widget if compilation or execution fails. Signature: `Widget Function(BuildContext, Object, StackTrace?)` - **permissions** (`List`) - Optional - Runtime security permissions to grant. Examples: `AssetPermission`, `MethodChannelPermission`, `FilesystemPermission`. Defaults to `const []`. - **plugins** (`List`) - Optional - Additional dart_eval plugins to register with the compiler/runtime. Defaults to `const []`. - **key** (`Key?`) - Optional - Widget key. ``` -------------------------------- ### Define Application C++ Wrapper Sources Source: https://github.com/ethanblake4/flutter_eval/blob/master/example/windows/flutter/CMakeLists.txt Appends application-specific C++ wrapper source files to a list and then prepends the wrapper root directory path to each source file. ```cmake list(APPEND CPP_WRAPPER_SOURCES_APP "flutter_engine.cc" "flutter_view_controller.cc" ) list(TRANSFORM CPP_WRAPPER_SOURCES_APP PREPEND "${WRAPPER_ROOT}/") ``` -------------------------------- ### Define Flutter Library and Headers Source: https://github.com/ethanblake4/flutter_eval/blob/master/examples/code_push_app/linux/flutter/CMakeLists.txt Sets variables for the Flutter library path and header files. It also publishes these variables to the parent scope for use in other CMake files or installation steps. ```cmake set(FLUTTER_LIBRARY "${EPHEMERAL_DIR}/libflutter_linux_gtk.so") # Published to parent scope for install step. set(FLUTTER_LIBRARY ${FLUTTER_LIBRARY} PARENT_SCOPE) set(FLUTTER_ICU_DATA_FILE "${EPHEMERAL_DIR}/icudtl.dat" PARENT_SCOPE) set(PROJECT_BUILD_DIR "${PROJECT_DIR}/build/" PARENT_SCOPE) set(AOT_LIBRARY "${PROJECT_DIR}/build/lib/libapp.so" PARENT_SCOPE) ``` -------------------------------- ### Hot-Update Override Example Source: https://github.com/ethanblake4/flutter_eval/blob/master/_autodocs/api-reference/hot-swap.md Shows how to create a hot-update override for a HotSwap widget using the @RuntimeOverride annotation. This function replaces the default widget's UI and behavior when compiled into the hot-update bytecode. ```dart import 'package:eval_annotation/eval_annotation.dart'; import 'package:flutter/material.dart'; @RuntimeOverride('#myHomePage') Widget myHomePageOverride(BuildContext context, String title) { return Scaffold( appBar: AppBar(title: Text('$title (Updated!)')), body: Center( child: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ Text('Updated content from hot-swap!'), ElevatedButton( onPressed: () => ScaffoldMessenger.of(context).showSnackBar( SnackBar(content: Text('Update working!')) ), child: Text('Show Confirmation'), ), ], ), ), ); } ``` -------------------------------- ### Create a MethodChannel Instance Source: https://github.com/ethanblake4/flutter_eval/blob/master/_autodocs/api-reference/method-channel.md Instantiate a MethodChannel wrapper using a unique channel name. This is the first step to establishing communication. ```dart final channel = MethodChannel('com.example.app/native'); ``` -------------------------------- ### HotSwapLoader Constructor Source: https://github.com/ethanblake4/flutter_eval/blob/master/_autodocs/api-reference/hot-swap-loader.md Initializes the HotSwapLoader widget, which is responsible for loading and applying hot-swap updates to the application. It takes a child widget, a URI to the bytecode, and various configuration options for loading strategy, caching, error handling, permissions, and plugins. ```APIDOC ## HotSwapLoader() ### Description Creates a new HotSwapLoader instance. This widget should be placed at the root of your application to enable code-push functionality. ### Constructor Signature ```dart const HotSwapLoader({ required Widget child, required String uri, HotSwapStrategy? strategy, String? cacheFilePath, Widget? loading, EvalErrorCallback? onError, List permissions = const [], List plugins = const [], Key? key }) ``` ### Parameters #### Required Parameters - **child** (`Widget`) - The child widget tree to be wrapped. Updates are applied on top of this tree via HotSwap widgets. - **uri** (`String`) - URI to the EVC bytecode containing hot-swap overrides. Supports `http://`, `https://`, `file://`, and `asset://` schemes. #### Optional Parameters - **strategy** (`HotSwapStrategy?`) - Strategy for loading and applying updates. Defaults to `immediate` in debug mode, `cacheApplyOnRestart` in release mode. - **cacheFilePath** (`String?`) - Path where update bytecode is cached. Defaults to `$documentsDirectory/hot_swap000.evc`. - **loading** (`Widget?`) - Widget displayed while loading updates. Only shown if strategy is not `immediate`. - **onError** (`EvalErrorCallback?`) - Callback invoked if an error occurs. Signature: `Widget Function(Object, StackTrace?)`. Network errors do not trigger this callback. - **permissions** (`List`) - Runtime security permissions to grant to the eval runtime. Defaults to an empty list. - **plugins** (`List`) - Additional dart_eval plugins to register. Defaults to an empty list. - **key** (`Key?`) - Widget key. Should be a constant key to prevent recreation during hot reloads. ``` -------------------------------- ### Runtime Methods Source: https://github.com/ethanblake4/flutter_eval/blob/master/_autodocs/api-reference/dart-eval-integration.md Provides methods to manage the execution environment, add plugins, grant permissions, execute code, and register bridge functions. ```APIDOC ### Methods #### addPlugin() ```dart void addPlugin(EvalPlugin plugin) ``` Registers a plugin with the runtime. Must be called before executing code that uses the plugin's types. | Parameter | Type | Description | |-----------|--------------|-----------------------------------------| | plugin | `EvalPlugin` | A plugin implementing `EvalPlugin` interface. | ```dart runtime.addPlugin(flutterEvalPlugin); ``` #### grant() ```dart void grant(Permission permission) ``` Grants a security permission to the runtime. | Parameter | Type | Description | |------------|------------|---------------------------------------------------| | permission | `Permission` | A permission from `package:flutter_eval/security.dart` or `dart_eval`. | ```dart runtime.grant(AssetPermission.any); runtime.grant(MethodChannelPermission('com.example.app/channel')); ``` #### executeLib() ```dart dynamic executeLib(String library, String functionName, List args) ``` Executes a function from a library. | Parameter | Type | Description | |--------------|----------------|-----------------------------------------------------------------| | library | `String` | Fully-qualified library path. Example: `'package:my_app/main.dart'` | | functionName | `String` | Name of the function or constructor. For constructors: `'ClassName.'` or `'ClassName.named'` | | args | `List` | Arguments to pass to the function. All args in order. | | Return | Type | Description | |--------|----------|-------------------------------------------| | result | `dynamic` | The return value of the function, usually a `$Value` wrapper. | **Example:** ```dart final result = runtime.executeLib( 'package:my_app/main.dart', 'MyWidget.', [] ); final widget = (result as $Value).$value; ``` #### loadGlobalOverrides() ```dart void loadGlobalOverrides() ``` Loads global function overrides from the bytecode. Used by `HotSwapLoader` to apply hot-swap updates. ```dart runtime.loadGlobalOverrides(); ``` #### registerBridgeFunc() ```dart void registerBridgeFunc( String library, String functionName, BridgeFunction function, {bool isBridge = false} ) ``` Registers a bridge function to be callable from evaluated code. Used for advanced integration. | Parameter | Type | Description | |--------------|-----------------|-------------------------------------------| | library | `String` | Library path. | | functionName | `String` | Function name in the evaluated code. | | function | `BridgeFunction` | Implementation function. | | isBridge | `bool` | Whether this is a bridge function. | #### lookupType() ```dart int lookupType(BridgeTypeSpec typeSpec) ``` Looks up the runtime type ID for a type. | Parameter | Type | Description | |------------|----------------|-------------------------| | typeSpec | `BridgeTypeSpec` | The type specification. | | Return | Type | Description | |--------|------|---------------------| | typeId | `int` | Runtime type ID. | ``` -------------------------------- ### Foundation Classes Source: https://github.com/ethanblake4/flutter_eval/blob/master/_autodocs/api-reference/supported-flutter-bindings.md Details on core foundation classes like ChangeNotifier, ValueNotifier, Listenable, and ValueListenable, along with their constructors, methods, and properties. ```APIDOC ## Foundation Classes ### Listenable & ValueNotifier | Class | Constructor | Methods | Properties | |-------|-------------|---------|-----------| | **ChangeNotifier** | `ChangeNotifier()` | notifyListeners(), addListener(), removeListener() | — | | **ValueNotifier** | `ValueNotifier()` | — | value | | **Listenable** | (Interface) | — | — | | **ValueListenable** | (Interface) | value | ``` -------------------------------- ### Add Dependencies and Include Directories Source: https://github.com/ethanblake4/flutter_eval/blob/master/examples/code_push_app/windows/runner/CMakeLists.txt Links necessary libraries (flutter, flutter_wrapper_app, dwmapi.lib) and adds include directories to the build target. Custom application-specific dependencies can also be added here. ```cmake # Add dependency libraries and include directories. Add any application-specific # dependencies here. target_link_libraries(${BINARY_NAME} PRIVATE flutter flutter_wrapper_app) target_link_libraries(${BINARY_NAME} PRIVATE "dwmapi.lib") target_include_directories(${BINARY_NAME} PRIVATE "${CMAKE_SOURCE_DIR}") ``` -------------------------------- ### RuntimeWidget Constructor Source: https://github.com/ethanblake4/flutter_eval/blob/master/_autodocs/api-reference/runtime-widget.md Creates a new RuntimeWidget instance. This widget loads and executes EVC bytecode, displaying the returned Widget. It supports loading from file, asset, or URL. ```APIDOC ## RuntimeWidget() ### Description Creates a new RuntimeWidget instance. This widget loads and executes EVC bytecode, displaying the returned Widget. It supports loading from file, asset, or URL. ### Constructor Signature ```dart const RuntimeWidget({ required Uri uri, required String library, required String function, List args = const [], Widget? loading, EvalErrorBuilder? onError, List permissions = const [], List plugins = const [], Key? key }) ``` ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None ### Parameters - **uri** (`Uri`) - Required - URI to the EVC bytecode file. Supports `file://`, `asset://`, `http://`, and `https://` schemes. - **library** (`String`) - Required - Fully-qualified import path to the library containing the entry function. Example: `'package:my_pkg/main.dart'` - **function** (`String`) - Required - Name of the function or constructor to invoke. Use format `'ClassName.'` for default constructors, `'ClassName.named'` for named constructors. - **args** (`List`) - Optional - Arguments to pass to the function. All arguments must be specified in order, including named/optional ones. Use `null` for absent named arguments. - **loading** (`Widget?`) - Optional - Widget displayed while bytecode is loading from a URL or asset. - **onError** (`EvalErrorBuilder?`) - Optional - Callback to build error widget if loading or execution fails. Signature: `Widget Function(BuildContext, Object, StackTrace?)` - **permissions** (`List`) - Optional - Runtime security permissions to grant. Examples: `AssetPermission`, `MethodChannelPermission`, `FilesystemPermission` - **plugins** (`List`) - Optional - Additional dart_eval plugins to register with the runtime. - **key** (`Key?`) - Optional - Widget key. ### Request Example ```dart RuntimeWidget( uri: Uri.parse('asset://assets/program.evc'), library: 'package:my_app/main.dart', function: 'HomePage.', loading: Center(child: CircularProgressIndicator()), ) ``` ### Response This is a Widget constructor, it does not have a direct response in the traditional sense. The widget renders based on the loaded bytecode. ``` -------------------------------- ### Configure Playground/Calculator with CompilerWidget Source: https://github.com/ethanblake4/flutter_eval/blob/master/_autodocs/INDEX.md Set up CompilerWidget for interactive playgrounds or calculators. It takes user-provided code and handles errors with a custom UI. ```dart CompilerWidget( packages: userProvidedCode, library: 'package:user_app/main.dart', function: 'main', onError: (context, error, st) => ErrorUI(error), ) ``` -------------------------------- ### Apply Standard Build Settings Source: https://github.com/ethanblake4/flutter_eval/blob/master/example/windows/runner/CMakeLists.txt Applies a standard set of build settings to the specified target. This can be customized for applications with unique build requirements. ```cmake apply_standard_settings(${BINARY_NAME}) ``` -------------------------------- ### Define Core C++ Wrapper Sources Source: https://github.com/ethanblake4/flutter_eval/blob/master/example/windows/flutter/CMakeLists.txt Appends core C++ wrapper source files to a list and then prepends the wrapper root directory path to each source file. ```cmake list(APPEND CPP_WRAPPER_SOURCES_CORE "core_implementations.cc" "standard_codec.cc" ) list(TRANSFORM CPP_WRAPPER_SOURCES_CORE PREPEND "${WRAPPER_ROOT}/") ``` -------------------------------- ### Define Plugin C++ Wrapper Sources Source: https://github.com/ethanblake4/flutter_eval/blob/master/example/windows/flutter/CMakeLists.txt Appends plugin-specific C++ wrapper source files to a list and then prepends the wrapper root directory path to each source file. ```cmake list(APPEND CPP_WRAPPER_SOURCES_PLUGIN "plugin_registrar.cc" ) list(TRANSFORM CPP_WRAPPER_SOURCES_PLUGIN PREPEND "${WRAPPER_ROOT}/") ``` -------------------------------- ### Configure Offline App with Network Updates using HotSwapLoader Source: https://github.com/ethanblake4/flutter_eval/blob/master/_autodocs/INDEX.md Implement an offline-first application that can receive network updates using HotSwapLoader. The 'cache' strategy ensures the app runs offline if the network is unavailable. ```dart HotSwapLoader( uri: 'https://api.example.com/app.evc', strategy: HotSwapStrategy.cache, child: MyApp(), permissions: [AssetPermission.any], ) ``` -------------------------------- ### Create Flutter Wrapper Plugin Library Source: https://github.com/ethanblake4/flutter_eval/blob/master/example/windows/flutter/CMakeLists.txt Creates a STATIC library target for the Flutter plugin wrapper, applying standard settings and linking against the 'flutter' library. ```cmake add_library(flutter_wrapper_plugin STATIC ${CPP_WRAPPER_SOURCES_CORE} ${CPP_WRAPPER_SOURCES_PLUGIN} ) apply_standard_settings(flutter_wrapper_plugin) set_target_properties(flutter_wrapper_plugin PROPERTIES POSITION_INDEPENDENT_CODE ON) set_target_properties(flutter_wrapper_plugin PROPERTIES CXX_VISIBILITY_PRESET hidden) target_link_libraries(flutter_wrapper_plugin PUBLIC flutter) target_include_directories(flutter_wrapper_plugin PUBLIC "${WRAPPER_ROOT}/include" ) add_dependencies(flutter_wrapper_plugin flutter_assemble) ``` -------------------------------- ### RuntimeWidget Source: https://github.com/ethanblake4/flutter_eval/blob/master/_autodocs/INDEX.md Loads and executes pre-compiled EVC bytecode. This widget is optimized for performance by running pre-compiled code. ```APIDOC ## RuntimeWidget ### Description Loads and executes pre-compiled EVC bytecode. ### Usage This widget is optimized for performance by running pre-compiled code. ``` -------------------------------- ### HotSwapLoader Constructor Source: https://github.com/ethanblake4/flutter_eval/blob/master/_autodocs/api-reference/hot-swap-loader.md Defines the parameters for creating a HotSwapLoader instance, including the child widget, update URI, caching strategy, and error handling. ```dart const HotSwapLoader({ required Widget child, required String uri, HotSwapStrategy? strategy, String? cacheFilePath, Widget? loading, EvalErrorCallback? onError, List permissions = const [], List plugins = const [], Key? key }) ``` -------------------------------- ### HotSwapLoader Parameters Source: https://github.com/ethanblake4/flutter_eval/blob/master/_autodocs/README.md Set up HotSwapLoader for live-reloading of Dart bytecode. Provide the child widget and the bytecode URI. Customize the loading strategy, cache file path, loading widget, error handling, permissions, and plugins. ```dart HotSwapLoader( child: MyApp(), // Required (child widget tree) uri: 'https://api.example.com/app.evc', // Required (bytecode URL) strategy: null, // Optional (immediate/cache/cacheApplyOnRestart) cacheFilePath: null, // Optional (custom cache location) loading: null, // Optional (loading widget) onError: null, // Optional (error handler) permissions: [], // Optional (security permissions) plugins: [], // Optional (additional plugins) ) ``` -------------------------------- ### Create AssetPermission with a Pattern Source: https://github.com/ethanblake4/flutter_eval/blob/master/_autodocs/api-reference/permissions.md Use this constructor to create a permission that matches asset paths against a provided regex or string pattern. The 'matchPattern' parameter defines the criteria for allowed asset paths. ```dart const AssetPermission(Pattern matchPattern) ``` -------------------------------- ### Instantiate Class with Arguments in RuntimeWidget Source: https://github.com/ethanblake4/flutter_eval/blob/master/README.md Instantiate a class with its default constructor and pass arguments, including null for optional parameters, using RuntimeWidget. This is recommended for production builds when using pre-compiled EVC bytecode. ```dart return RuntimeWidget( uri: Uri.parse('asset:assets/program.evc'), library: 'package:example/main.dart', function: 'MyApp.', args: [ $String('Jessica'), null, null ] ); ``` -------------------------------- ### Add Dependency Libraries and Include Directories Source: https://github.com/ethanblake4/flutter_eval/blob/master/example/windows/runner/CMakeLists.txt Links necessary libraries (flutter, flutter_wrapper_app) and adds the source directory to include paths for the application target. Custom dependencies can be added here. ```cmake target_link_libraries(${BINARY_NAME} PRIVATE flutter flutter_wrapper_app) target_include_directories(${BINARY_NAME} PRIVATE "${CMAKE_SOURCE_DIR}") ``` -------------------------------- ### RuntimeWidget Constructor Source: https://github.com/ethanblake4/flutter_eval/blob/master/_autodocs/api-reference/runtime-widget.md Defines the parameters for creating a RuntimeWidget. Key parameters include the URI to the bytecode, the library and function to execute, optional arguments, loading and error widgets, and security permissions. ```dart const RuntimeWidget({ required Uri uri, required String library, required String function, List args = const [], Widget? loading, EvalErrorBuilder? onError, List permissions = const [], List plugins = const [], Key? key }) ``` -------------------------------- ### Include Generated Plugins Source: https://github.com/ethanblake4/flutter_eval/blob/master/example/windows/CMakeLists.txt Includes the generated_plugins.cmake file to manage building and adding plugins to the application. ```cmake include(flutter/generated_plugins.cmake) ``` -------------------------------- ### Set Runtime Output Directory Source: https://github.com/ethanblake4/flutter_eval/blob/master/examples/code_push_app/linux/CMakeLists.txt Configures the runtime output directory for the application binary. This ensures that resources are located correctly in the bundled application. ```cmake set_target_properties(${BINARY_NAME} PROPERTIES RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/intermediates_do_not_run" ) ``` -------------------------------- ### Create Flutter Wrapper Application Library Source: https://github.com/ethanblake4/flutter_eval/blob/master/example/windows/flutter/CMakeLists.txt Creates a STATIC library target for the Flutter application wrapper, applying standard settings and linking against the 'flutter' library. ```cmake add_library(flutter_wrapper_app STATIC ${CPP_WRAPPER_SOURCES_CORE} ${CPP_WRAPPER_SOURCES_APP} ) apply_standard_settings(flutter_wrapper_app) target_link_libraries(flutter_wrapper_app PUBLIC flutter) target_include_directories(flutter_wrapper_app PUBLIC "${WRAPPER_ROOT}/include" ) add_dependencies(flutter_wrapper_app flutter_assemble) ``` -------------------------------- ### Implementing a Custom Plugin for Flutter Eval Source: https://github.com/ethanblake4/flutter_eval/blob/master/_autodocs/configuration.md Demonstrates how to create a custom plugin by implementing the EvalPlugin interface. This includes registering custom classes for compilation and configuring runtime behavior. The custom plugin is then added to the CompilerWidget's plugins list. ```dart class MyPlugin implements EvalPlugin { @override String get identifier => 'my.package/my_plugin'; @override void configureForCompile(BridgeDeclarationRegistry registry) { // Register custom classes } @override void configureForRuntime(Runtime runtime) { // Configure runtime } } CompilerWidget( packages: { /* ... */ }, library: 'package:app/main.dart', function: 'main', plugins: [MyPlugin()], // Added alongside flutterEvalPlugin ) ```