bare_flutter 0.1.0
bare_flutter: ^0.1.0 copied to clipboard
A thin Android and iOS Flutter binding to Holepunch Bare Kit worklets and raw IPC byte streams.
example/lib/main.dart
import 'dart:async';
import 'dart:io';
import 'package:bare_flutter/bare_flutter.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
void main() => runApp(const BareFlutterExample());
class BareFlutterExample extends StatefulWidget {
const BareFlutterExample({super.key});
@override
State<BareFlutterExample> createState() => _BareFlutterExampleState();
}
class _BareFlutterExampleState extends State<BareFlutterExample> {
BareWorklet? _worklet;
StreamSubscription<Uint8List>? _incoming;
String _status = 'Not started';
Future<void> _start() async {
final asset = Platform.isAndroid
? 'assets/echo-android.bundle'
: 'assets/echo-ios.bundle';
final data = await rootBundle.load(asset);
final worklet = await BareWorklet.start(
filename: '/echo.bundle',
source: data.buffer.asUint8List(data.offsetInBytes, data.lengthInBytes),
);
await _incoming?.cancel();
_incoming = worklet.ipc.incoming.listen((bytes) {
if (mounted) setState(() => _status = 'Echoed ${bytes.length} bytes');
});
setState(() {
_worklet = worklet;
_status = worklet.reattached
? 'Reattached generation ${worklet.generation}'
: 'Running generation ${worklet.generation}';
});
}
Future<void> _echo() async {
await _worklet?.ipc.write(Uint8List.fromList([1, 2, 3, 4]));
}
Future<void> _push() async {
final reply = await _worklet?.push(Uint8List.fromList([5, 6, 7]));
if (mounted) {
setState(() => _status = 'Push replied ${reply?.length ?? 0} bytes');
}
}
Future<void> _toggleSuspended() async {
final worklet = _worklet;
if (worklet == null) return;
if (worklet.state == BareWorkletState.suspended) {
await worklet.resume();
} else {
await worklet.suspend();
}
if (mounted) setState(() => _status = worklet.state.name);
}
Future<void> _terminate() async {
await _worklet?.terminate();
if (mounted) setState(() => _status = 'Terminated');
}
@override
void dispose() {
unawaited(_incoming?.cancel());
super.dispose();
}
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(title: const Text('bare_flutter')),
body: Padding(
padding: const EdgeInsets.all(24),
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
Text(_status, key: const Key('status')),
const SizedBox(height: 16),
FilledButton(onPressed: _start, child: const Text('Start')),
FilledButton(onPressed: _echo, child: const Text('Echo bytes')),
FilledButton(onPressed: _push, child: const Text('Push')),
FilledButton(
onPressed: _toggleSuspended,
child: const Text('Suspend / resume'),
),
FilledButton(
onPressed: _terminate,
child: const Text('Terminate'),
),
],
),
),
),
);
}
}