2015-08-28 14:45:39 -04:00
|
|
|
import "dart:isolate";
|
|
|
|
import "dart:async";
|
|
|
|
|
|
|
|
Uri toDartDataUri(String source) {
|
|
|
|
return Uri.parse("data:application/dart;charset=utf-8,"
|
|
|
|
"${Uri.encodeComponent(source)}");
|
|
|
|
}
|
|
|
|
|
|
|
|
createIsolateSource(String moduleSource, List<List<String>> moduleImports) {
|
|
|
|
var moduleSourceParts = [];
|
|
|
|
moduleImports.forEach((sourceImport) {
|
|
|
|
String modName = sourceImport[0];
|
|
|
|
String modAlias = sourceImport[1];
|
|
|
|
moduleSourceParts.add("import 'package:${modName}.dart' as ${modAlias};");
|
|
|
|
});
|
2015-09-11 16:33:24 -04:00
|
|
|
moduleSourceParts.add(moduleSource);
|
2015-08-28 14:45:39 -04:00
|
|
|
|
|
|
|
return """
|
|
|
|
import "dart:isolate";
|
|
|
|
import "${toDartDataUri(moduleSourceParts.join('\n'))}" as mut;
|
|
|
|
|
|
|
|
main(List args, SendPort replyPort) {
|
|
|
|
replyPort.send(mut.run(args));
|
|
|
|
}
|
|
|
|
""";
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2015-09-11 16:33:24 -04:00
|
|
|
var timeStamp = new DateTime.now().millisecondsSinceEpoch;
|
|
|
|
|
2015-08-28 14:45:39 -04:00
|
|
|
dynamic callModule(dynamic data) { return data.map( (a) => a+1); }
|
|
|
|
|
|
|
|
evalModule(String moduleSource, List<List<String>> moduleImports, List args) {
|
|
|
|
String source = createIsolateSource(moduleSource, moduleImports);
|
|
|
|
Completer completer = new Completer();
|
|
|
|
RawReceivePort receivePort;
|
|
|
|
receivePort = new RawReceivePort( (message) {
|
|
|
|
receivePort.close();
|
|
|
|
completer.complete(message);
|
|
|
|
});
|
2015-09-11 16:33:24 -04:00
|
|
|
// Note: we have a special karma plugin that sends files under
|
|
|
|
// urls like /package_1234 as permanently cached.
|
|
|
|
// With this, spawning multiple isolates gets faster as Darts does not
|
|
|
|
// reload the files from the server.
|
|
|
|
var packageRoot = Uri.parse('/packages_${timeStamp}');
|
2015-08-28 14:45:39 -04:00
|
|
|
return Isolate.spawnUri(toDartDataUri(source), args, receivePort.sendPort, packageRoot: packageRoot).then( (isolate) {
|
|
|
|
RawReceivePort errorPort;
|
|
|
|
errorPort = new RawReceivePort( (message) {
|
|
|
|
completer.completeError(message);
|
|
|
|
});
|
|
|
|
isolate.addErrorListener(errorPort.sendPort);
|
|
|
|
return completer.future;
|
|
|
|
});
|
|
|
|
}
|