102 lines
No EOL
8.6 KiB
Markdown
102 lines
No EOL
8.6 KiB
Markdown
# Neon Framework
|
|
|
|
## Overview
|
|
|
|
Neon Framework is a custom Dart-based UI framework for building native mobile apps (Android & iOS) **without any Flutter dependency**. It is a standalone SDK that owns its own runtime, widget system, rendering pipeline, state management, and platform bridges. The framework communicates with native apps via an HTTP-based bridge — the Dart backend runs a local HTTP server that serves a JSON widget tree, and native apps (Android/iOS) fetch this tree, render native UI components, and send user actions back via POST requests.
|
|
|
|
The project has completed 8 development phases: Vision → Core Runtime → Widget System → Rendering Layer → State Management → Platform Layer → Tooling (CLI) → Storage & Networking → Plugins & Extensibility.
|
|
|
|
The main framework code lives in `neon_framework/` and a test app lives in `neon_framework/my_2nd_test_app/` with both Android (Kotlin) and iOS (Swift) native shells.
|
|
|
|
## User Preferences
|
|
|
|
Preferred communication style: Simple, everyday language.
|
|
|
|
## System Architecture
|
|
|
|
### Core Framework (`neon_framework/lib/src/`)
|
|
|
|
The framework follows a layered architecture:
|
|
|
|
1. **Core Runtime** (`core/`): `NeonApp.run()` entry point, lifecycle management (onInit, onPause, onResume, onDispose, onHotReload), environment-aware error handling, and configuration via `NeonConfig`, `NeonBuildFlavor`, and `NeonFeatureFlags`.
|
|
|
|
2. **Widget System** (`widgets/`): Inspired by Flutter's composition model. Includes `NeonWidget`, `StatelessWidget`, `StatefulWidget`, and `NeonState`. Widgets build a tree (`NeonWidgetTree` / `NeonElement`) and serialize to JSON for native rendering. Includes primitives (Text, Button, Container) and layouts (Column, Row, Stack). Material 3 widgets (Switch, Checkbox, Radio, Slider, Chips, Badge, Card, Dialog, BottomSheet, TextField, SearchBar, SearchAnchor, MenuAnchor, MenuBar) are also supported.
|
|
|
|
3. **Rendering Layer** (`rendering/`): Custom layout engine with constraints, render objects, canvas abstractions, and a render pipeline (Layout → Paint → Composite). Includes animation foundations with curves and spring physics.
|
|
|
|
4. **State Management** (`state/`): Reactive primitives — `NeonSignal` (observable values), `NeonComputed` (derived values), `NeonEffect` (side effects), and `NeonAsyncValue` (loading/success/error/cached states). `setState()` triggers widget tree rebuilds and re-serialization.
|
|
|
|
5. **Data Layer** (`storage/`, `networking/`): Key-value store, SQLite database with migrations, HTTP client with interceptors, WebSocket client with auto-reconnect, and a cache policy system (cache-first, network-first, stale-while-revalidate, etc.).
|
|
|
|
6. **Plugin System** (`plugins/`): Dual-mode architecture supporting Dart-only and native plugins. Includes a plugin registry with dependency resolution, capability conflict detection, lifecycle management, and a hook system. Semantic versioning and SDK constraints are enforced.
|
|
|
|
7. **CLI Tooling** (`bin/neon.dart`, `tooling/`): Commands for `create`, `run`, `build`, `doctor`, `clean`. Hot reload engine with file watching, debounce, and three reload tiers (UI-only, state-preserving, full).
|
|
|
|
### Platform Bridge Architecture
|
|
|
|
This is the most important architectural pattern to understand:
|
|
|
|
- **Dart side** runs an HTTP server (typically on `localhost:8080`)
|
|
- **GET /** returns the full widget tree as JSON
|
|
- **POST /action** receives user interactions (widget ID, index, value) and returns the updated widget tree as JSON
|
|
- **Native apps** (Android `MainActivity.kt`, iOS `ViewController.swift`) fetch the JSON tree, recursively render native UI components, and send actions back when users interact
|
|
- **State updates** flow: User taps → native sends POST → Dart finds widget by ID → calls callback → `setState()` → tree rebuilds → new JSON sent back → native re-renders
|
|
|
|
### Key Design Decisions
|
|
|
|
- **No Flutter**: This is intentional. The framework owns its entire stack. Don't add Flutter dependencies.
|
|
- **JSON-based rendering**: Widgets serialize to JSON maps. The native side interprets these maps to create native Android/iOS views. This is the bridge between Dart logic and native UI.
|
|
- **Widget keys**: Interactive widgets must have stable string keys so the native apps can target them for action events. Missing keys was a recurring bug source.
|
|
- **`double.infinity` handling**: JSON doesn't support infinity values. These must be clamped or replaced before serialization.
|
|
- **Microtask timing**: `setState()` is async — the action handler must `await Future.delayed(Duration.zero)` before rebuilding the tree, to let the microtask queue flush.
|
|
|
|
### Test App Structure
|
|
|
|
`my_2nd_test_app/` contains:
|
|
- `lib/` — Dart app code using the Neon Framework (8 screens: Dashboard, Interaction, Controls, Values, Advanced, Containment, Input, Info & Progress)
|
|
- `android/` — Gradle-based Android project with `MainActivity.kt` that renders the JSON widget tree
|
|
- `NeonApp/` — Xcode project with `ViewController.swift` that renders the JSON widget tree on iOS
|
|
|
|
### Recent Changes (Phase 10 - Information & Progress Widgets)
|
|
- Added 8 new Material 3 widget types: ListTile, LinearProgressIndicator, CircularProgressIndicator, Tooltip, SnackBar, SingleChildScrollView, ListView (with builder/separated variants), CustomScrollView with sliver support (SliverList, SliverAppBar)
|
|
- Full JSON serialization, action handling, and HTML/CSS/JS web renderer for all new widgets
|
|
- Native Android (Kotlin) and iOS (Swift) rendering support for all new widgets
|
|
- New Info & Progress showcase screen demonstrating all new widget types
|
|
- Navigation bar expanded to 8 tabs
|
|
- Fixed Radio button generic type crash: added `selectValue()` method to bypass Dart generic type erasure issue with `onChanged` callback
|
|
- Previous phase 9 changes preserved: Card, Dialog, BottomSheet, TextField, SearchBar, MenuAnchor/MenuBar
|
|
- **Fixed web renderer Button click bug**: Container type check was matching before Button check in the JS renderer, preventing buttons (whose `type` is `Container` but `sourceType` is `Button`) from being clickable. Moved `isButton`/Button check before Container check. Native renderers (Android/iOS) already handled this via `isButton` flag.
|
|
- **Fixed nested AppBar/NavigationBar rendering**: When ShowcaseApp is embedded inside AppLauncher, the AppBar and NavigationBar were nested inside Expanded/ShowcaseApp rather than at root level. Added inline rendering for both widget types in `renderWidget()` so they display correctly at any nesting depth. Also added NavigationBar, TabBar, and AppBar to the interactable widget list in widget_tree.dart for proper action routing.
|
|
|
|
### Flutter-to-Neon Transpiler (`tools/transpiler/`)
|
|
- **Purpose**: Source-to-source converter that transforms Flutter widget code into Neon-compatible code
|
|
- **Entry point**: `tools/transpiler/main.dart` — runs before the main app in the workflow
|
|
- **Input**: Place Flutter `.dart` files in `flutter_input/` directory
|
|
- **Output**: Converted files go to `lib/neon_compat/` with a barrel export `neon_compat.dart`
|
|
- **Widget mapping** (`tools/transpiler/widget_mapping.dart`): Maps ~50 Flutter widgets/types to Neon equivalents
|
|
- **Key transformations**:
|
|
- Flutter imports → `package:neon_framework/neon.dart`
|
|
- `StatelessWidget`/`StatefulWidget` → Neon base classes
|
|
- `State<T>` → `NeonState<T>`
|
|
- `Widget build(BuildContext)` → `NeonWidget build(NeonBuildContext)`
|
|
- `ElevatedButton` → `FilledButton`, `TextStyle` → `NeonTextStyle`, `EdgeInsets` → `NeonEdgeInsets`, etc.
|
|
- `Key? key` → `String? key`
|
|
- Removes Flutter-specific imports, handles `Scaffold` removal
|
|
- **Usage**: `dart run tools/transpiler/main.dart [input_dir] [output_dir]`
|
|
- **Uses**: `analyzer` package for Dart AST parsing to find widget classes
|
|
|
|
## External Dependencies
|
|
|
|
### Dart Packages (from pubspec)
|
|
- **analyzer** — Dart AST parsing for the transpiler
|
|
- **args** — CLI argument parsing
|
|
- **path** — File path manipulation
|
|
- **watcher** — File system watching for hot reload
|
|
- **test** (dev) — Unit testing
|
|
|
|
### Native Platform Dependencies
|
|
- **Android**: Standard Android SDK (API 21+), Kotlin, Gradle. Uses `java.net.URL` for HTTP communication with the Dart backend. Native widgets include `android.widget.Switch`, `CheckBox`, `RadioButton`, `SeekBar`, etc.
|
|
- **iOS**: UIKit-based (not SwiftUI). Uses `URLSession` for HTTP communication. Native widgets include `UISwitch`, `UIButton`, `UISlider`, etc. Xcode project targets iOS simulator (arm64).
|
|
|
|
### No Database or External Services
|
|
The framework includes its own storage abstractions (key-value store, SQLite) with in-memory backends for testing. There is no external database dependency like Postgres. The HTTP client and WebSocket client are built-in with mock backends available. |