Skip to content

Commit 84c944e

Browse files
authored
Merge pull request #51 from ethanblake4/v0.6
v0.6
2 parents 3247960 + 8103bb0 commit 84c944e

File tree

200 files changed

+6414
-486
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

200 files changed

+6414
-486
lines changed

CHANGELOG.md

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,15 @@
1+
## 0.6.0
2+
- Upgrade to dart_eval v0.6.0
3+
- Add HotSwap and HotSwapLoader widgets to facilitate easy partial app
4+
updates
5+
- CompilerWidget, EvalWidget, and RuntimeWidget now support an `onError` callback
6+
that is called when an error occurs during compilation or evaluation. You can
7+
use this to display a custom error fallback.
8+
- Add ListView and InkWell
9+
- Add Card, Drawer, and ListTile (thanks to @DevAdalat)
10+
- Add Image, ImageProvider, and NetworkImage (thanks to @DevAdalat)
11+
- Fix BoxDecoration not extending Decoration
12+
- Fix error when constructing a TextStyle without the `inherit` property
113
## 0.5.4
214
- Support for Flutter 3.7
315
- Add Spacer (thanks to @canewsin)

LICENSE

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
Copyright 2022 Ethan Elshyeb
1+
Copyright 2023 Ethan Elshyeb
22

33
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
44

README.md

Lines changed: 119 additions & 70 deletions
Original file line numberDiff line numberDiff line change
@@ -3,24 +3,131 @@
33
[![Web example](https://img.shields.io/badge/web-example-blue.svg)](https://ethanblake.xyz/evalpad)
44

55
`flutter_eval` is a Flutter bridge library for [dart_eval](https://pub.dev/packages/dart_eval),
6-
enabling painless creation of fully dynamic Flutter apps and widgets that can be loaded
7-
from a file or the Internet at runtime. It provides both a set of compile-time descriptors and directives,
8-
as well as runtime bridge classes and wrappers, with a seamless API that makes usage easy.
6+
and a solution enabling both fully dynamic runtime code-push and runtime evaluation of Flutter code.
7+
It can be used to enable hot-swapping parts of your app with an over-the-air update, or for dynamically
8+
evaluating code based on user input such as in a calculator. flutter_eval supports all platforms
9+
including iOS and is built on dart_eval's custom bytecode interpreter, making it very fast.
910

1011
| dart_eval | [![pub package](https://img.shields.io/pub/v/dart_eval.svg?label=dart_eval&color=teal)](https://pub.dev/packages/dart_eval) |
1112
| ------------ | ------------------------------------------------------------------------------------------------------------------------------------ |
1213
| flutter_eval | [![pub package](https://img.shields.io/pub/v/flutter_eval.svg?label=flutter_eval&color=blue)](https://pub.dev/packages/flutter_eval) |
14+
| eval_annotation | [![pub package](https://img.shields.io/pub/v/eval_annotation.svg?label=eval_annotation&color=orange)](https://pub.dev/packages/eval_annotation) |
1315

1416
For a live example, check out [EvalPad](https://ethanblake.xyz/evalpad).
1517

1618
Although flutter_eval is already the best solution for native Dart Flutter code push,
17-
it's still very early for the project and you should not expect existing Flutter/Dart code
18-
to work without modification. Many classes and methods have not yet been implemented.
19+
the project is still in development and you should not expect all existing Flutter/Dart code
20+
to work without modification, as various standard library classes and Dart features
21+
have yet to be implemented.
1922

20-
## Getting started
23+
## Quickstart for code push
2124

2225
Run `flutter pub add flutter_eval` to install the package.
2326

27+
At the root of your app, add a HotSwapLoader widget with a URI
28+
pointing to where you'll host the update file:
29+
30+
```dart
31+
class MyApp extends StatelessWidget {
32+
33+
@override
34+
Widget build(BuildContext context) {
35+
return HotSwapLoader(
36+
uri: 'https://mysite.com/app_update/version_xxx.evc',
37+
child: MaterialApp(
38+
...
39+
```
40+
41+
Then, add HotSwap widgets throughout your app at every location
42+
you'd like to be able to dynamically update:
43+
44+
```dart
45+
class MyHomePage extends StatelessWidget {
46+
47+
@override
48+
Widget build(BuildContext context) {
49+
return HotSwap(
50+
id: '#myHomePage',
51+
args: [$BuildContext.wrap(context)],
52+
childBuilder: (context) => Scaffold(
53+
...
54+
```
55+
56+
Next, create a new Flutter package using `flutter create --template=package`.
57+
This can be nested inside your app's folder or located separately. Name it
58+
something appropriate, such as my_app_hot_update. We'll refer to this
59+
as the "hot update package" from now on.
60+
61+
Head over to the flutter_eval [Releases page](https://github.com/ethanblake4/flutter_eval/releases)
62+
and find the release corresponding to the version of flutter_eval you are using. Under **Assets**,
63+
download `flutter_eval.json`. (Or [click here](https://github.com/ethanblake4/flutter_eval/releases/latest/download/flutter_eval.json) to download the latest version.)
64+
65+
In the root of the hot update package, create a folder called `.dart_eval` and
66+
a subfolder `bindings`. Place the downloaded `flutter_eval.json` file inside of
67+
this folder.
68+
69+
Your project structure should look like this:
70+
```
71+
├── .dart_eval
72+
│ └── bindings
73+
│ └── flutter_eval.json.
74+
├── pubspec.yaml
75+
└── lib
76+
└── hot_update.dart
77+
```
78+
79+
At the root of the hot update package, run `flutter pub add eval_annotation`.
80+
81+
Delete all the code from main.dart, including the main() function.
82+
For every HotSwap widget you'd like to update (you can update all,
83+
or just a few, or just one), create a top-level function with the
84+
@RuntimeOverride annotation referencing its ID:
85+
86+
```dart
87+
@RuntimeOverride('#myHomePage')
88+
Widget myHomePageUpdate(BuildContext context) {
89+
return Scaffold(
90+
...
91+
)
92+
}
93+
```
94+
Finally, we'll need to install the dart_eval CLI:
95+
96+
```bash
97+
dart pub global activate dart_eval
98+
```
99+
100+
After installing, you can run:
101+
```bash
102+
dart_eval compile -o version_xxx.evc
103+
```
104+
105+
If the steps were performed correctly, you should see the following in the console output:
106+
107+
`Found binding file: .dart_eval\bindings\flutter_eval.json`
108+
109+
as well as
110+
111+
`Compiled $x characters Dart to $y bytes EVC in $z ms: version_xxx.evc`
112+
113+
The resulting `version_xxx.evc` file will be in the root of the project and
114+
you can now upload it to the previously referenced server path.
115+
116+
If you run the app, you should see the contents of the HotSwap widgets
117+
replaced with the contents of their corresponding @RuntimeOverride functions.
118+
119+
HotSwap widgets can optionally specify a strategy to use when loading/applying updates,
120+
one of _immediate_, _cache_, or _cacheApplyOnRestart_. By default, HotSwapLoader
121+
uses immediate in debug/profile mode and cacheApplyOnRestart in release mode. You
122+
can also specify a placeholder widget to display when loading from the cache via
123+
the _loading_ parameter.
124+
125+
For a complete example of code push, see
126+
[examples/code_push_app](https://github.com/ethanblake4/flutter_eval/tree/master/examples/code_push_app)
127+
and its subfolder [hot_update](https://github.com/ethanblake4/flutter_eval/tree/master/examples/code_push_app/hot_update).
128+
129+
## Quickstart for dynamic execution and manual updates
130+
24131
To create a simple dynamic stateless widget, add and modify the following inside a
25132
build() method or as a child parameter:
26133

@@ -82,69 +189,8 @@ flutter_eval includes two other helper Widgets for different use cases:
82189
- `RuntimeWidget` will *always* load EVC bytecode and does not provide a
83190
parameter to specify Dart code. This is recommended if you're compiling
84191
with the CLI - see below.
85-
86-
## Compiling with the dart_eval CLI
87-
88-
flutter_eval allows you to compile an existing Flutter project using the dart_eval CLI;
89-
please note, however, that Pub packages are not currently supported.
90-
91-
To get started, first install the dart_eval CLI:
92-
93-
```bash
94-
dart pub global activate dart_eval
95-
```
96-
97-
Next, head over to the flutter_eval [Releases page](https://github.com/ethanblake4/flutter_eval/releases)
98-
and find the release corresponding to the version of flutter_eval you are using. Under **Assets**,
99-
download `flutter_eval.json`.
100-
101-
In the root of the project you wish to compile, create a folder called `.dart_eval` and
102-
a subfolder `bindings`. Place the downloaded `flutter_eval.json` file inside of this folder.
103-
104-
Your project structure should look like this:
105-
```
106-
├── .dart_eval
107-
│ └── bindings
108-
│ └── flutter_eval.json.
109-
├── pubspec.yaml
110-
└── lib
111-
└── main.dart
112-
```
113-
114-
You'll also have to change your entrypoint a bit. flutter_eval does not support
115-
`runApp()` as it runs inside an existing Flutter app, which already calls runApp().
116-
Instead, you can change your main() function to look like this:
117-
118-
```dart
119-
Widget main() {
120-
// do any setup, then
121-
return MyApp();
122-
}
123-
```
124-
125-
Alternatively, you can simply comment out runApp() and reference Widget
126-
constructors directly from RuntimeWidget. This is recommended if your project
127-
has multiple widgets which are displayed at different times or in different
128-
parts of the app.
129-
130-
Finally, in the root of your project, run:
131-
```bash
132-
dart_eval compile -o program.evc
133-
```
134-
135-
If the steps were performed correctly, you should see the following in the console output:
136-
137-
`Found binding file: .dart_eval\bindings\flutter_eval.json`
138-
139-
as well as
140-
141-
`Compiled $x characters Dart to $y bytes EVC in $z ms: program.evc`
142-
143-
The resulting `program.evc` file will be in the root of your project and you can use it
144-
in flutter_eval, as an asset or from a URL. The package name will be automatically inferred
145-
from your pubspec.yaml file.
146-
147-
## Calling functions and passing arguments
192+
193+
### Calling functions and passing arguments
148194

149195
To instantiate a class with its default constructor, append a '.' to the class name.
150196

@@ -193,7 +239,10 @@ Currently supported widgets and classes include:
193239
- `Text`, `TextStyle`, `TextEditingController`, `TextField`;
194240
- `TextDirection`, `VerticalDirection`, `TextBaseline`
195241
- `Scaffold`, `ScaffoldMessenger`, `AppBar`, `SnackBar`, `FloatingActionButton`;
196-
- `TextButton`, `ElevatedButton`, `IconButton`, `Spacer`;
242+
- `InkWell`, `TextButton`, `ElevatedButton`, `IconButton`;
243+
- `Card`, `Drawer`;
244+
- `Image`, `ImageProvider`, `NetworkImage`, `MemoryImage`;
245+
- `ListView`, `ListTile`, `Spacer`;
197246
- `Navigator`, `NavigatorState`, `Builder`;
198247

199248
Note that many of these have only partial support.

example/web/manifest.json

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
11
{
2-
"name": "example",
3-
"short_name": "example",
2+
"name": "flutter_eval example",
3+
"short_name": "flutter_eval example",
44
"start_url": ".",
55
"display": "standalone",
66
"background_color": "#0175C2",
77
"theme_color": "#0175C2",
8-
"description": "A new Flutter project.",
9-
"orientation": "portrait-primary",
8+
"description": "A flutter_eval example project.",
9+
"orientation": "any",
1010
"prefer_related_applications": false,
1111
"icons": [
1212
{

examples/code_push_app/.gitignore

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
# Miscellaneous
2+
*.class
3+
*.log
4+
*.pyc
5+
*.swp
6+
.DS_Store
7+
.atom/
8+
.buildlog/
9+
.history
10+
.svn/
11+
migrate_working_dir/
12+
13+
# IntelliJ related
14+
*.iml
15+
*.ipr
16+
*.iws
17+
.idea/
18+
19+
# The .vscode folder contains launch configuration and tasks you configure in
20+
# VS Code which you may wish to be included in version control, so this line
21+
# is commented out by default.
22+
#.vscode/
23+
24+
# Flutter/Dart/Pub related
25+
**/doc/api/
26+
**/ios/Flutter/.last_build_id
27+
.dart_tool/
28+
.flutter-plugins
29+
.flutter-plugins-dependencies
30+
.packages
31+
.pub-cache/
32+
.pub/
33+
/build/
34+
pubspec_overrides.yaml
35+
36+
# Symbolication related
37+
app.*.symbols
38+
39+
# Obfuscation related
40+
app.*.map.json
41+
42+
# Android Studio will place build artifacts here
43+
/android/app/debug
44+
/android/app/profile
45+
/android/app/release

examples/code_push_app/.metadata

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
# This file tracks properties of this Flutter project.
2+
# Used by Flutter tool to assess capabilities and perform upgrades etc.
3+
#
4+
# This file should be version controlled.
5+
6+
version:
7+
revision: 2ad6cd72c040113b47ee9055e722606a490ef0da
8+
channel: stable
9+
10+
project_type: app
11+
12+
# Tracks metadata for the flutter migrate command
13+
migration:
14+
platforms:
15+
- platform: root
16+
create_revision: 2ad6cd72c040113b47ee9055e722606a490ef0da
17+
base_revision: 2ad6cd72c040113b47ee9055e722606a490ef0da
18+
- platform: android
19+
create_revision: 2ad6cd72c040113b47ee9055e722606a490ef0da
20+
base_revision: 2ad6cd72c040113b47ee9055e722606a490ef0da
21+
- platform: ios
22+
create_revision: 2ad6cd72c040113b47ee9055e722606a490ef0da
23+
base_revision: 2ad6cd72c040113b47ee9055e722606a490ef0da
24+
- platform: linux
25+
create_revision: 2ad6cd72c040113b47ee9055e722606a490ef0da
26+
base_revision: 2ad6cd72c040113b47ee9055e722606a490ef0da
27+
- platform: macos
28+
create_revision: 2ad6cd72c040113b47ee9055e722606a490ef0da
29+
base_revision: 2ad6cd72c040113b47ee9055e722606a490ef0da
30+
- platform: web
31+
create_revision: 2ad6cd72c040113b47ee9055e722606a490ef0da
32+
base_revision: 2ad6cd72c040113b47ee9055e722606a490ef0da
33+
- platform: windows
34+
create_revision: 2ad6cd72c040113b47ee9055e722606a490ef0da
35+
base_revision: 2ad6cd72c040113b47ee9055e722606a490ef0da
36+
37+
# User provided section
38+
39+
# List of Local paths (relative to this file) that should be
40+
# ignored by the migrate tool.
41+
#
42+
# Files that are not part of the templates will be ignored by default.
43+
unmanaged_files:
44+
- 'lib/main.dart'
45+
- 'ios/Runner.xcodeproj/project.pbxproj'

examples/code_push_app/README.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
## flutter_eval code push app sample
2+
3+
This sample app shows a basic setup for code-push via flutter_eval's HotSwap
4+
and HotSwapLoader. The main project is a simple counter app wherein HotSwaps
5+
have been added, and it loads an EVC update file over the network using
6+
HotSwapLoader. The subproject [hot_update](hot_update) is a Flutter package
7+
with dart_eval JSON bindings that we compile using the dart_eval CLI to
8+
produce the EVC update file. See the flutter_eval README for more details.
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
# This file configures the analyzer, which statically analyzes Dart code to
2+
# check for errors, warnings, and lints.
3+
#
4+
# The issues identified by the analyzer are surfaced in the UI of Dart-enabled
5+
# IDEs (https://dart.dev/tools#ides-and-editors). The analyzer can also be
6+
# invoked from the command line by running `flutter analyze`.
7+
8+
# The following line activates a set of recommended lints for Flutter apps,
9+
# packages, and plugins designed to encourage good coding practices.
10+
include: package:flutter_lints/flutter.yaml
11+
12+
linter:
13+
# The lint rules applied to this project can be customized in the
14+
# section below to disable rules from the `package:flutter_lints/flutter.yaml`
15+
# included above or to enable additional rules. A list of all available lints
16+
# and their documentation is published at
17+
# https://dart-lang.github.io/linter/lints/index.html.
18+
#
19+
# Instead of disabling a lint rule for the entire project in the
20+
# section below, it can also be suppressed for a single line of code
21+
# or a specific dart file by using the `// ignore: name_of_lint` and
22+
# `// ignore_for_file: name_of_lint` syntax on the line or in the file
23+
# producing the lint.
24+
rules:
25+
# avoid_print: false # Uncomment to disable the `avoid_print` rule
26+
# prefer_single_quotes: true # Uncomment to enable the `prefer_single_quotes` rule
27+
28+
# Additional information about this file can be found at
29+
# https://dart.dev/guides/language/analysis-options

0 commit comments

Comments
 (0)