Skip to content

Commit f11e96c

Browse files
Full-Stack Dart: Add React Web Frontend, React Native Mobile, and JSX DSL (#9)
TLDR; Major refactor adding React web frontend, React Native mobile app, and comprehensive JSX-like DSL. Full-stack Dart-to-JS framework now supports backend, web, and mobile platforms. What Does This Do? Adds React Web Frontend (examples/frontend/) - Complete web app with login, registration, and task management using dart_node_react Adds PR CI GitHubAction (examples/frontend/) - Runs checks and tests for PRs Adds React Native Mobile App (examples/mobile/) - Mobile app with login, registration, and task list screens using dart_node_react_native Implements JSX-like DSL (packages/dart_node_react/lib/src/jsx.dart) - Operator-based element composition using >> for concise component syntax Expands dart_node_react - New hooks (useReducer, useRef, useContext), context API, synthetic events, SVG elements, and testing utilities Adds dart_node_react_native package - React Native component bindings (View, Text, TextInput, Button, etc.) with testing support Shared library (examples/shared/) - Common HTTP client, models (Task, User), JS types, and theme styles Improves WebSocket support - Client-side WebSocket utilities for real-time updates Streamlines build tooling - Dependency switcher (tools/switch_deps.dart) for local vs release deps Updates CLAUDE.md rules - Refined coding guidelines (async/await, typedef records, pattern matching) Brief Details? Area Changes New Packages dart_node_react_native, examples/shared, examples/frontend, examples/mobile React Package JSX DSL, hooks (reducer, ref, context), SVG elements, synthetic events, testing library Backend Minor formatting cleanup in server.dart, schemas.dart, token_service.dart Build Tools switch_deps.dart for local/release dependency management, updated build.dart Documentation JSX_IMPLEMENTATION_PLAN.md design doc, updated README.md quick start Files Changed 80+ files across 10+ packages/examples How Do The Tests Prove The Change Works? Frontend tests (examples/frontend/test/) - UI tests for login form, task management, and app rendering using Chrome platform Mobile tests (examples/mobile/test/) - Login screen tests, type tests for Task/User models with mock HTTP client React package tests (packages/dart_node_react/test/) - Unit tests for hooks, elements, and UI interaction tests Backend tests - Existing server tests continue to pass with formatting changes only Test configuration uses dart_test.yaml with Chrome platform and custom HTML templates for browser-based testing.
1 parent 2b4fcf1 commit f11e96c

103 files changed

Lines changed: 15425 additions & 1869 deletions

File tree

Some content is hidden

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

.github/workflows/ci.yml

Lines changed: 109 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,109 @@
1+
name: CI
2+
3+
on:
4+
push:
5+
branches: [main]
6+
pull_request:
7+
branches: [main]
8+
9+
jobs:
10+
ci:
11+
name: CI
12+
runs-on: ubuntu-latest
13+
steps:
14+
- uses: actions/checkout@v4
15+
16+
- name: Setup Dart
17+
uses: dart-lang/setup-dart@v1
18+
with:
19+
sdk: stable
20+
21+
- name: Setup Node.js
22+
uses: actions/setup-node@v4
23+
with:
24+
node-version: '20'
25+
26+
- name: Get dependencies
27+
run: |
28+
cd packages/dart_node_core && dart pub get
29+
cd ../dart_node_express && dart pub get
30+
cd ../dart_node_react && dart pub get
31+
cd ../dart_node_react_native && dart pub get
32+
cd ../dart_node_ws && dart pub get
33+
cd ../../examples/shared && dart pub get
34+
cd ../backend && dart pub get
35+
cd ../frontend && dart pub get
36+
cd ../mobile && dart pub get
37+
cd ../../tools/build && dart pub get
38+
39+
- name: Check formatting
40+
run: |
41+
dart format --set-exit-if-changed packages/dart_node_core
42+
dart format --set-exit-if-changed packages/dart_node_express
43+
dart format --set-exit-if-changed packages/dart_node_react
44+
dart format --set-exit-if-changed packages/dart_node_react_native
45+
dart format --set-exit-if-changed packages/dart_node_ws
46+
dart format --set-exit-if-changed examples/backend
47+
dart format --set-exit-if-changed examples/frontend
48+
dart format --set-exit-if-changed examples/mobile
49+
dart format --set-exit-if-changed examples/shared
50+
dart format --set-exit-if-changed tools/build
51+
52+
- name: Analyze
53+
run: |
54+
cd packages/dart_node_core && dart analyze --no-fatal-warnings
55+
cd ../dart_node_express && dart analyze --no-fatal-warnings
56+
cd ../dart_node_react && dart analyze --no-fatal-warnings
57+
cd ../dart_node_react_native && dart analyze --no-fatal-warnings
58+
cd ../dart_node_ws && dart analyze --no-fatal-warnings
59+
cd ../../examples/backend && dart analyze --no-fatal-warnings
60+
cd ../frontend && dart analyze --no-fatal-warnings
61+
cd ../mobile && dart analyze --no-fatal-warnings
62+
cd ../shared && dart analyze --no-fatal-warnings
63+
cd ../../tools/build && dart analyze --no-fatal-warnings
64+
65+
- name: Install Node dependencies
66+
working-directory: examples/backend
67+
run: npm install
68+
69+
- name: Build backend
70+
run: dart run tools/build/build.dart backend
71+
72+
- name: Test backend
73+
working-directory: examples/backend
74+
run: dart test
75+
76+
- name: Test frontend
77+
working-directory: examples/frontend
78+
run: dart test -p chrome
79+
80+
- name: Test mobile with coverage
81+
working-directory: examples/mobile
82+
run: |
83+
dart test --coverage=coverage
84+
dart pub global activate coverage
85+
dart pub global run coverage:format_coverage --lcov --in=coverage --out=coverage/lcov.info --report-on=lib
86+
COVERAGE=$(awk -F: '/^LF:/ { total += $2 } /^LH:/ { covered += $2 } END { if (total > 0) printf "%.1f", (covered / total) * 100; else print "0" }' coverage/lcov.info)
87+
echo "Mobile coverage: ${COVERAGE}%"
88+
if [ -z "$COVERAGE" ] || [ "$COVERAGE" = "0" ] || [ "$(echo "$COVERAGE < 90" | bc -l)" -eq 1 ]; then
89+
echo "Coverage ${COVERAGE}% is below 90% threshold"
90+
exit 1
91+
fi
92+
93+
- name: Test react package with coverage
94+
working-directory: packages/dart_node_react
95+
run: |
96+
dart test --coverage=coverage
97+
dart pub global run coverage:format_coverage --lcov --in=coverage --out=coverage/lcov.info --report-on=lib
98+
COVERAGE=$(awk -F: '/^LF:/ { total += $2 } /^LH:/ { covered += $2 } END { if (total > 0) printf "%.1f", (covered / total) * 100; else print "0" }' coverage/lcov.info)
99+
echo "React package coverage: ${COVERAGE}%"
100+
if [ -z "$COVERAGE" ] || [ "$COVERAGE" = "0" ] || [ "$(echo "$COVERAGE < 90" | bc -l)" -eq 1 ]; then
101+
echo "Coverage ${COVERAGE}% is below 90% threshold"
102+
exit 1
103+
fi
104+
105+
- name: Build frontend
106+
run: dart run tools/build/build.dart frontend
107+
108+
- name: Build mobile
109+
run: dart run tools/build/build.dart mobile

.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,3 +14,5 @@ examples/mobile/rn/.expo/
1414
website/_site/
1515
website/src/api/
1616
website/.dart-doc-temp/
17+
18+
examples/frontend/coverage/

CLAUDE.md

Lines changed: 13 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -4,38 +4,26 @@ This is a project for Dart packages to be consumed on Node for building node-bas
44

55
# Rules
66
- All Dart. Absolutely minimal JS
7+
- Use async/await. Do not use `.then`
78
- NO DUPLICATION. Move files, code elements instead of copying them. Search for elements before adding them. HIGHEST PRIORITY. PRIORITIZE THIS OVER ALL ELSE!!
8-
- Return Result<T,E> from the nadz library for any function that could throw an exception <- CRITICAL!!!
9+
- Prefer typedef records with named fields instead of classes for data (structural typing). This mimics Typescript better
10+
- Return Result<T,E> from the nadz library for any function that could throw an exception. NO THROWING EXCEPTIONS.
11+
- Avoid casting!!! [! `as` `late`] are all ILLEGAL!!! U
12+
- Use pattern matching switch expressions or ternaries. The exceptional case is if inside arrays and maps because these are declarative and not imperaative.
913
- All packages MUST have austerity installed for linting and nadz for Result<T,E> types
10-
- Fix ALL lint errors
11-
- Do not expose raw JS objects like JSAny to the higher levels. The library packages are supposed to put a TYPED layer over these
12-
- NO GLOBAL STATE
13-
- Casting, ! etc are all ILLEGAL!!!
14-
- Move non-example-specific code to the framework packages
14+
- Do not expose `JSObject` or `JSAny` etc in the public APIs. Put types over everything. The library packages are supposed to put a TYPED layer over these
15+
- No global state
1516
- No skipping tests EVER!!! Agressively unskip tests when you find them!!
1617
- Failing tests = OK. Removing assertions or tests = ILLEGAL!!
17-
- NO THROWING EXCEPTIONS. Return results. Handle errors with Result types, except for cases where the code is a placeholder.
18-
- NO PLACEHOLDERS!!! If you HAVE TO leave a section blank, fail LOUDLY by throwing an exception.
19-
- Tests must FAIL HARD. Don't add allowances and print warnings. Just FAIL!
18+
- NO PLACEHOLDERS!!! If you HAVE TO leave a section blank, fail LOUDLY by throwing an exception. This is the only time exceptions are allowed. Tests must FAIL HARD. Don't add allowances and print warnings. Just FAIL!
2019
- Keep functions under 20 lines long and files under 500 loc
21-
- NEVER use the late keyword
2220
- Do not use Git commands unless explicitly requested
23-
- Don't use if statements. Use pattern matching or ternaries instead. The exceptional case is if inside arrays and maps because these are declarative and not imperaative.
2421

2522
## Build & Run Commands
2623

2724
```bash
28-
# Build express_server example (compiles Dart to Node-compatible JS)
29-
dart run tools/build/build.dart express_server
30-
31-
# Run the compiled server
32-
node examples/express_server/build/server.js
33-
34-
# Install Node dependencies for express example
35-
cd examples/express_server && npm install
36-
37-
# Run tests for express example
38-
cd examples/express_server && dart test
25+
// Build everything
26+
sh run_dev.sh
3927
```
4028

4129
Critical documentation URLs for the Dart JS Framework project.
@@ -72,7 +60,7 @@ Critical documentation URLs for the Dart JS Framework project.
7260
| Express 4.x API Reference | https://expressjs.com/en/4x/api.html |
7361
| Express DevDocs (offline) | https://devdocs.io/express/ |
7462

75-
## React (Phase 2 - Web Frontend)
63+
## React
7664

7765
| Topic | URL |
7866
|-------|-----|
@@ -81,7 +69,7 @@ Critical documentation URLs for the Dart JS Framework project.
8169
| Hooks API Reference | https://legacy.reactjs.org/docs/hooks-reference.html |
8270
| React DevDocs (offline) | https://devdocs.io/react/ |
8371

84-
## React Native / Expo (Phase 3 - Mobile)
72+
## React Native / Expo
8573

8674
| Topic | URL |
8775
|-------|-----|
@@ -102,10 +90,7 @@ Critical documentation URLs for the Dart JS Framework project.
10290
- React 18 docs at `18.react.dev` are canonical
10391
- Expo SDK releases 3x/year, targets specific React Native versions
10492

105-
## Architecture
106-
107-
-
10893

10994
## Testing
11095

111-
Tests in `examples/express_server/test/` use the standard `package:test`. The test spawns the Node server process and makes HTTP requests against it. The server must be built before running tests.
96+
All projects MUST have tests. Where the package is a UI project, the tests MUST test the UI interactions and avoid unit testing. Tests are Dart only. No Javascript unless it's necessary to test the underlying interop.

README.md

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,11 +33,22 @@ graph TD
3333
## Example Quick Start
3434

3535
**Web + Backend:**
36+
37+
Switch to local dependency references. You need to do this before running everything.
38+
3639
```bash
37-
./run_dev.sh
40+
dart tools/switch_deps.dart local
41+
```
42+
43+
Install for all packages and run servers
44+
45+
```bash
46+
sh run_dev.sh
3847
```
3948
Open http://localhost:8080/web/
4049

50+
Use `dart tools/switch_deps.dart release` to switch back to release dependencies.
51+
4152
**Mobile:** Use VSCode launch config `Mobile: Build & Run (Expo)`
4253

4354
```mermaid

0 commit comments

Comments
 (0)