js_interpreter 0.0.1 copy "js_interpreter: ^0.0.1" to clipboard
js_interpreter: ^0.0.1 copied to clipboard

A comprehensive, pure Dart JavaScript interpreter supporting ES6+ features. Perfect for embedding JavaScript execution in Dart/Flutter applications.

js_interpreter #

Pub package License

A comprehensive, pure Dart implementation of a JavaScript interpreter supporting ES6+ features. Perfect for embedding JavaScript execution in Dart/Flutter applications.

✨ Features #

🚀 Core Capabilities #

  • Full JavaScript Parsing - Complete lexer and parser supporting modern JavaScript syntax
  • Async/Await Support - Native async function execution with Promise integration
  • Module System - ES6 modules with import/export
  • Class System - Full ES6+ class support including private fields and static blocks
  • Generators - function* and yield/yield* support
  • Iterators - Full iterator protocol implementation
  • Proxy/Reflect - Complete metaprogramming support
  • TypedArrays - All typed array types (Int8Array, Uint8Array, Float32Array, etc.)
  • RegExp - Full regular expression support with ES2022 features
  • Strict Mode - Automatic and explicit strict mode handling

For detailed feature coverage and use cases, check the test suite for comprehensive examples.

📦 Installation #

Add to your pubspec.yaml:

dependencies:
  js_interpreter: ^0.0.1

Or install via command line:

dart pub add js_interpreter

🔧 Quick Start #

Basic Usage #

import 'package:js_interpreter/js_interpreter.dart';

void main() {
  final interpreter = JSInterpreter();
  
  // Evaluate JavaScript code
  final result = interpreter.eval('''
    const greeting = "Hello";
    const name = "World";
    greeting + ", " + name + "!";
  ''');
  
  print(result); // Hello, World!
}

Async/Await Support #

import 'package:js_interpreter/js_interpreter.dart';

void main() async {
  final interpreter = JSInterpreter();
  
  final result = await interpreter.evalAsync('''
    async function fetchData() {
      const response = await Promise.resolve({ data: "Hello Async!" });
      return response.data;
    }
    
    await fetchData();
  ''');
  
  print(result); // Hello Async!
}

Convert to Dart Types #

import 'package:js_interpreter/js_interpreter.dart';

void main() async {
  final interpreter = JSInterpreter();
  
  // Returns native Dart types (String, int, double, List, Map, etc.)
  final result = await interpreter.evalAsyncToDart('''
    const data = {
      name: "Alice",
      age: 30,
      hobbies: ["reading", "coding"]
    };
    JSON.stringify(data);
  ''');
  
  print(result); // {"name":"Alice","age":30,"hobbies":["reading","coding"]}
  print(result.runtimeType); // String
}

ES6 Modules #

import 'package:js_interpreter/js_interpreter.dart';

void main() async {
  final interpreter = JSInterpreter();
  
  // Register a module
  interpreter.registerModule('math-utils', '''
    export function add(a, b) { return a + b; }
    export function multiply(a, b) { return a * b; }
    export const PI = 3.14159;
  ''');
  
  // Use the module
  final result = await interpreter.evalModuleAsync('''
    import { add, multiply, PI } from 'math-utils';
    
    const sum = add(5, 3);
    const product = multiply(4, PI);
    
    export default { sum, product };
  ''');
  
  print(result); // {sum: 8, product: 12.56636}
}

Dart-JS Interop #

import 'package:js_interpreter/js_interpreter.dart';

void main() {
  final interpreter = JSInterpreter();
  
  // Inject Dart function into JavaScript
  interpreter.setGlobal('dartPrint', (List<JSValue> args) {
    print('From Dart: ${args.first}');
    return JSValueFactory.undefined();
  });
  
  interpreter.eval('''
    dartPrint("Hello from JavaScript!");
  ''');
  // Output: From Dart: Hello from JavaScript!
}

Messaging System: sendMessage & sendMessageAsync #

The interpreter provides a powerful bidirectional messaging system for complex Dart-JavaScript interactions.

sendMessage (Synchronous)

import 'package:js_interpreter/js_interpreter.dart';

void main() {
  final interpreter = JSInterpreter();
  
  // Register a message handler
  interpreter.onMessage('greet', (dynamic message) {
    final name = message as String;
    return 'Hello, $name!';
  });
  
  // Call from JavaScript (synchronous)
  final result = interpreter.eval('''
    const greeting = sendMessage('greet', 'Alice');
    greeting; // "Hello, Alice!"
  ''');
  
  print(result);
}

sendMessageAsync (Asynchronous)

For async operations that require waiting for results:

import 'package:js_interpreter/js_interpreter.dart';

void main() async {
  final interpreter = JSInterpreter();
  
  // Register an async message handler
  interpreter.onMessage('fetchUser', (dynamic message) async {
    final userId = message as int;
    // Simulate async operation
    await Future.delayed(Duration(milliseconds: 100));
    return {
      'id': userId,
      'name': 'Alice',
      'email': 'alice@example.com'
    };
  });
  
  // Call from JavaScript (asynchronous)
  final result = await interpreter.evalAsync('''
    async function loadUser() {
      const user = await sendMessageAsync('fetchUser', 1);
      return user.email;
    }
    
    await loadUser();
  ''');
  
  print(result); // "alice@example.com"
}

Advanced Patterns

Message Handlers with Multiple Arguments:

interpreter.onMessage('calculate', (dynamic message) {
  final args = message as List;
  final operation = args[0] as String;
  final a = args[1] as num;
  final b = args[2] as num;
  
  switch (operation) {
    case 'add': return a + b;
    case 'multiply': return a * b;
    default: return null;
  }
});

// In JavaScript:
final result = interpreter.eval('''
  sendMessage('calculate', 'add', 5, 3); // 8
  sendMessage('calculate', 'multiply', 4, 7); // 28
''');

Async Pipeline with Promise.all:

interpreter.onMessage('fetchData', (dynamic message) async {
  final source = message as String;
  await Future.delayed(Duration(milliseconds: 50));
  return {'source': source, 'data': [1, 2, 3]};
});

final result = await interpreter.evalAsync('''
  const results = await Promise.all([
    sendMessageAsync('fetchData', 'database'),
    sendMessageAsync('fetchData', 'api'),
    sendMessageAsync('fetchData', 'cache')
  ]);
  
  results.map(r => r.source);
''');
// ['database', 'api', 'cache']

Error Handling:

interpreter.onMessage('riskyOperation', (dynamic message) {
  if (message == 'fail') {
    throw Exception('Operation failed');
  }
  return 'Success';
});

// In JavaScript:
final result = await interpreter.evalAsync('''
  try {
    const result1 = await sendMessageAsync('riskyOperation', 'ok');
    const result2 = await sendMessageAsync('riskyOperation', 'fail');
  } catch (error) {
    console.log('Caught:', error.message);
  }
''');

📚 API Reference #

JSInterpreter #

The main class for JavaScript interpretation.

Method Description
eval(String code) Synchronously evaluate JavaScript code
evalAsync(String code) Asynchronously evaluate JavaScript code (returns Future<JSValue>)
evalAsyncToDart(String code) Asynchronously evaluate and convert result to Dart types
evalModule(String code) Evaluate as ES6 module
evalModuleAsync(String code) Asynchronously evaluate as ES6 module
registerModule(String name, String code) Register a module for import
setGlobal(String name, dynamic value) Set a global variable
getGlobal(String name) Get a global variable
onMessage(String channel, dynamic callback) Register a message handler for a specific channel

Global Functions (JavaScript Context) #

Function Description
sendMessage(String channel, [arg1, arg2, ...]) Send a synchronous message to Dart and get a result
sendMessageAsync(String channel, [arg1, arg2, ...]) Send an asynchronous message to Dart (returns Promise)

JSValue Types #

Type Description
JSUndefined JavaScript undefined
JSNull JavaScript null
JSBoolean JavaScript boolean
JSNumber JavaScript number (int or double)
JSString JavaScript string
JSBigInt JavaScript BigInt
JSSymbol JavaScript Symbol
JSObject JavaScript object
JSArray JavaScript array
JSFunction JavaScript function
JSClass JavaScript class
JSGenerator JavaScript generator
JSAsyncGenerator JavaScript async generator
JSPromise JavaScript Promise
JSRegExp JavaScript RegExp
JSDate JavaScript Date
JSError JavaScript Error (and all error types)

📄 License #

This project is licensed under the MIT License - see the LICENSE file for details.


Made with ❤️ in Dart

1
likes
150
points
235
downloads

Publisher

unverified uploader

Weekly Downloads

A comprehensive, pure Dart JavaScript interpreter supporting ES6+ features. Perfect for embedding JavaScript execution in Dart/Flutter applications.

Repository (GitHub)
View/report issues

Topics

#javascript #interpreter #parser #ecmascript #es6

Documentation

Documentation
API reference

License

MIT (license)

Dependencies

intl

More

Packages that depend on js_interpreter