lamnhan066 / isolate_manager

Create multiple long-lived isolates for the Functions, supports Worker on the Web (with the effective generator) and WASM compilation.
https://pub.dev/packages/isolate_manager
MIT License
35 stars 2 forks source link

Uncaught Error: UnimplementedError #35

Open WieFel opened 2 hours ago

WieFel commented 2 hours ago

I have the following code, which I run on an isolate. It has two functions exportAsCsv and exportAsExcel (in a separate dart file), which depend on an external lib respectively.

import 'package:csv/csv.dart';
import 'package:excel/excel.dart';
import 'package:isolate_manager/isolate_manager.dart';

@pragma('vm:entry-point')
@isolateManagerWorker
Future<List<int>> exportAsCsv(List<List<dynamic>> data) async {
  final csv = ListToCsvConverter().convert(data);
  return csv.codeUnits;
}

@pragma('vm:entry-point')
@isolateManagerWorker
Future<List<int>> exportAsExcel(({String fileName, List<List<dynamic>> data}) message) async {
  final excel = Excel.createExcel();
  final sheet = excel['Sheet1'];

  for (final row in message.data) {
    sheet.appendRow(List.of(row.map((cellValue) => TextCellValue(cellValue.toString()))));
  }
  List<int>? bytes = excel.save(fileName: message.fileName);

  if (bytes == null) {
    throw Exception('Failed to save Excel file');
  }

  return bytes;
}

I instantiate the isolate managers like this in my Bloc:

final csvIsolateManager = IsolateManager.create(
  exportAsCsv,
  workerName: 'exportAsCsv',
);
final excelIsolateManager = IsolateManager.create(
  exportAsExcel,
  workerName: 'exportAsExcel',
);

On Android/iOS, the code runs fine. When I run it on web, and trigger e.g. the exportToCsv() function, I get the following error in my browser console:

Uncaught Error: UnimplementedError
    at Object.b (exportAsCsv.js:249:18)
    at Object.bT (exportAsCsv.js:258:15)
    at cm.gb_ (exportAsCsv.js:3965:16)
    at exportAsCsv.js:2029:3
    at fw.a (exportAsCsv.js:1329:64)
    at fw.$2 (exportAsCsv.js:2462:14)
    at Object.h5 (exportAsCsv.js:1315:11)
    at Object.hg (exportAsCsv.js:2032:10)
    at kQ (exportAsCsv.js:2055:8)
    at exportAsCsv.js:4430:66

I suppose that is due to isolate_manager not supporting ANY external packages.. Is that true? Is there any way I can get it to work on web?

lamnhan066 commented 2 hours ago

Hi @WieFel

Have you run the dart run isolate_manager:generate and is it completed?

If the csv and excel support the Dart native then the isolate should work after the generation is complete.

WieFel commented 2 hours ago

Thanks for the quick answer.

Yes, I ran dart run isolate_manager:generate, and it generated two files exportAsCsv.js and exportAsExcel.js.

And yes, the packages actually both support web: https://pub.dev/packages/csv https://pub.dev/packages/excel

When I run them just with the normal dart compute() function, they run fine on the web, but they block the UI of course.

I just don't really understand what the UnimplementedError tells me in this case, as the js code is obfuscated...

lamnhan066 commented 1 hour ago

I think the issue is caused by excel.save, it executes the download dialog which isn’t supported on the Worker.

Is there any other method that does the same without triggering the native UI part like dialog?

WieFel commented 37 minutes ago

True, it is triggering the download directly. But no download dialog.

However, exportAsCsv doesn't do that, and still fails. I also triggered exportAsCsv in the example that failed...

lamnhan066 commented 24 minutes ago

You can try using the List instead of a specific Type like this:

@isolateManagerWorker
Future<List> exportAsCsv(List data) async {
  final csv = ListToCsvConverter().convert(data);
  return csv.codeUnits;
}
WieFel commented 10 minutes ago

I just tried it even without using the external csv lib:

@pragma('vm:entry-point')
@isolateManagerWorker
Future<List> exportAsCsv(List data) async {
  final csv = data.map((d) => d.join(',')).join('\n');
  return csv.codeUnits;
}

But after re-executing dart run isolate_manager:generate and restarting my web application from scratch, I still get the same error:

Uncaught Error: UnimplementedError
    at Object.b (exportAsCsv.js:250:18)
    at Object.bP (exportAsCsv.js:259:15)
    at ci.gb_ (exportAsCsv.js:3881:16)
    at exportAsCsv.js:2005:3
    at fr.a (exportAsCsv.js:1318:64)
    at fr.$2 (exportAsCsv.js:2448:14)
    at Object.h0 (exportAsCsv.js:1304:11)
    at Object.hb (exportAsCsv.js:2008:10)
    at kN (exportAsCsv.js:2041:3)
    at exportAsCsv.js:4348:66

Line 250 in exportAsCsv.js looks like this:

b(a){return A.ih(new Error(),a)},

Line 4348 in exportAsCsv.js is:

if(typeof dartMainRunner==="function"){dartMainRunner(s,[])}else{s([])}})})()