nomos_flutter 0.16.1
nomos_flutter: ^0.16.1 copied to clipboard
Drive the real Nomos GitHolon from a Flutter app. A local-first domain runtime over a hidden, secure WebView host — write TypeScript domains, get a typesafe Dart client, build Flutter widgets.
nomos_flutter #
Drive the real Nomos GitHolon from a Flutter app. You write a powerful, polymorphic TypeScript domain,
run nomos compile, and get a typesafe Dart client. This package is the runtime that client runs on: it
boots the byte-identical wasm32-wasip1 GitHolon inside a hidden, secure WebView host and hands you a
connected bridge. TS domains in, Flutter widgets out — the webview embedding, the secure loopback origin,
the runner bundle, the wasm, and sync are all hidden in here.
Local-first: every read, write, and merge happens on-device against the local holon; the cloud is custody + sync. One binary on web/iOS/Android/macOS.
Use it #
# pubspec.yaml
dependencies:
nomos_flutter: ^0.1.0
import 'package:flutter/material.dart';
import 'package:nomos_flutter/nomos_flutter.dart';
import 'nomos/todo.client.dart'; // generated by `nomos compile` (copy build/dart/ into your app)
void main() => runApp(const MaterialApp(home: Home()));
class Home extends StatelessWidget {
const Home({super.key});
@override
Widget build(BuildContext context) => NomosScope(
cloud: 'https://nomos.captainapp.co.uk',
workspace: 'my-workspace',
builder: (context, nomos) {
final app = TodoClient(nomos.bridge); // your generated typed client
return TodoPage(app); // app.addTodo(...), app.watchTodosByList(...)
},
);
}
That's the whole integration. NomosScope boots the holon, connects to the workspace, and rebuilds with a
connected NomosClient; everything platform-specific is inside the package.
The typed client #
nomos compile emits build/dart/<name>.client.dart (+ <name>.dart) — a <Domain>Client over a
NomosBridge with typed dispatch, reactive watch… queries parsed into read models, by-id reads, and O(1)
count/sum. You wrap it over nomos.bridge:
final app = TodoClient(nomos.bridge);
final head = await app.addTodo(AddTodoPayload(listId: id, text: 'milk')); // offline-first write
app.watchTodosByList(listId: id).listen((rows) => setState(() => _todos = rows)); // reactive read
await nomos.bridge.sync(); // push session branch → cloud admission → pull main
Platform setup #
Almost nothing — but Apple's sandbox needs one line that a package cannot set for you:
- macOS: add to
macos/Runner/DebugProfile.entitlementsandRelease.entitlements:
(The sandbox blocks even the loopback host without it.)<key>com.apple.security.network.client</key> <true/> - iOS / Android / Web: nothing. (iOS loopback is exempt from Local Network privacy; web uses the page origin.)
How it works (so you don't have to think about it) #
The holon is JavaScript+wasm; Flutter can't run it directly. NomosScope mounts a 1×1 flutter_inappwebview
and serves the bundled runner over a loopback http://127.0.0.1 origin — a secure context, so
crypto.subtle + storage + WebAssembly all work (an about:blank/file: origin silently breaks them). The
runner boots @githolon/client, which pulls the byte-identical holon wasm + the workspace ledger from the
cloud and replays it locally. A small JSON bridge connects Dart ↔ the runner. flutter_inappwebview is used
(not the official webview_flutter) because its WKWebView embedding is the robust one across macOS/iOS.