flutter_fjs 0.1.5 copy "flutter_fjs: ^0.1.5" to clipboard
flutter_fjs: ^0.1.5 copied to clipboard

JS/TS runtime for Flutter. Embeds QuickJS-ng with direct JSI-style JS<->C++ calls, runs source or bytecode bundles, and renders HTML-like JS tags as Flutter widgets.

example/lib/main.dart

// The smallest Flutter host that runs a JS bundle built by @ufjs/cli.
//
// This is the package's integration example; the full sample app lives in
// examples/hello-fjs. Produce a bundle first (`fjs build` in a JS project,
// which writes dist/app/bundle.fjsbundle and, for code-split apps, a
// pages/ directory), then run this host one of two ways:
//
//   flutter run --dart-define=FJS_DEV=192.168.x.x:38900   # fjs dev, hot reload
//   flutter run                                           # bundle from assets
//
// The release path expects the bundle under assets/fjs/ (declared in the
// host app's pubspec); it is the same layout `fjs build --release` bakes
// into a generated host.
import 'dart:convert' show jsonDecode;

import 'package:flutter/foundation.dart' show defaultTargetPlatform;
import 'package:flutter/material.dart';
import 'package:flutter/services.dart' show rootBundle;
import 'package:flutter_fjs/flutter_fjs.dart';

Future<void> main() async {
  WidgetsFlutterBinding.ensureInitialized();
  final engine = FjsEngine();
  engine.onLog = (level, message) =>
      debugPrint('[js:${FjsLogLevel.of(level).name}] $message');
  // Host modules are the Dart half of JS's synchronous module calls.
  engine.host.register(
    'device',
    (args) => {'platform': defaultTargetPlatform.name, 'args': args},
  );

  const dev = String.fromEnvironment('FJS_DEV');
  if (dev.isEmpty) {
    // Release: assets, no network, no waiting worth showing a spinner for.
    await loadReleaseAssets(engine);
    runApp(_ExampleApp(engine: engine, dev: ''));
    return;
  }
  // Dev: PAINT FIRST, connect after. The first outbound request may raise
  // a LAN permission sheet, and a sheet needs a foregrounded UI to be
  // answered; connectDev's backoff picks the bundle up afterwards.
  runApp(_ExampleApp(engine: engine, dev: dev));
  engine.connectDevString(dev).ignore();
}

extension on FjsEngine {
  Future<void> connectDevString(String value) async {
    final uri = Uri.parse(value.contains('://') ? value : 'http://$value');
    if (uri.host.isEmpty) {
      throw ArgumentError('FJS_DEV must be host:port, got "$value"');
    }
    await connectDev(uri.host, uri.hasPort ? uri.port : 38900);
  }
}

/// The release path: bundle (and, for split apps, page chunks) from
/// Flutter assets — the layout `fjs build --release` bakes into a
/// generated host.
Future<void> loadReleaseAssets(FjsEngine engine) async {
  Map<String, Object?>? pages;
  try {
    final manifest = jsonDecode(
      await rootBundle.loadString('assets/fjs/manifest.json'),
    );
    pages = (manifest['pages'] as Map?)?.cast<String, Object?>();
  } catch (_) {
    pages = null;
  }
  engine.chunkLoader = (chunk) async {
    try {
      final path =
          pages?[chunk]?.toString() ?? 'assets/fjs/pages/$chunk.fjsbundle';
      return (await rootBundle.load(path)).toUint8List();
    } catch (_) {
      return null;
    }
  };
  final bundle = await rootBundle.load('assets/fjs/bundle.fjsbundle');
  engine.runBundle(bundle.toUint8List());
  engine.startEventLoop();
}

class _ExampleApp extends StatelessWidget {
  const _ExampleApp({required this.engine, required this.dev});

  final FjsEngine engine;
  final String dev;

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'flutter_fjs example',
      theme: ThemeData(useMaterial3: true, colorSchemeSeed: Colors.indigo),
      home: Scaffold(
        body: FjsApp(
          engine: engine,
          // Shown while a pushed route waits for its JS chunk to arrive.
          placeholder: Center(
            child: Column(
              mainAxisSize: MainAxisSize.min,
              children: [
                const CircularProgressIndicator(),
                if (dev.isNotEmpty) ...[
                  const SizedBox(height: 16),
                  Text('waiting for fjs dev at $dev', softWrap: false),
                ],
              ],
            ),
          ),
        ),
      ),
    );
  }
}
1
likes
140
points
259
downloads

Documentation

Documentation
API reference

Publisher

verified publisherzhuzhe.dev

Weekly Downloads

JS/TS runtime for Flutter. Embeds QuickJS-ng with direct JSI-style JS<->C++ calls, runs source or bytecode bundles, and renders HTML-like JS tags as Flutter widgets.

Repository (GitHub)
View/report issues

Topics

#javascript #typescript #quickjs #ffi #vue

License

MIT (license)

Dependencies

cached_network_image, ffi, flutter, vector_math

More

Packages that depend on flutter_fjs

Packages that implement flutter_fjs