Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[wasm] TypeError #40

Closed
sabin26 opened this issue Aug 28, 2024 · 16 comments
Closed

[wasm] TypeError #40

sabin26 opened this issue Aug 28, 2024 · 16 comments
Assignees

Comments

@sabin26
Copy link

sabin26 commented Aug 28, 2024

import 'package:squadron/squadron.dart';

import 'codec_service.activator.g.dart';
import 'dart:convert';

part 'codec_service.worker.g.dart';

@SquadronService(baseUrl: '/services/codec')
class CodecService {
  CodecService();

  @SquadronMethod()
  Future<Map<String, Object?>> decode(final List<int> bytes) async =>
      const Utf8Decoder().fuse(const JsonDecoder()).convert(bytes) as Map<String, Object?>? ?? <String, Object?>{};
}

The same code works as expected when my flutter app is compiled to javascript but when I compile it to wasm, I get the following error:

$Error._throw	@	main.dart.wasm:0x3c1991
$_TypeError._throwAsCheckError	@	errors_patch.dart:74
$<obj> as Class(Object)	@	main.dart.wasm:0x427d0b
$openChannel closure at file:///C:/Users/Dell/AppData/Local/Pub/Cache/git/squadron-fad409c841390c2ed1987d937d7d79c5a776c7f9/lib/src/_impl/web/_channel.dart:62:22	@	_channel.dart:68
$closure wrapper at file:///C:/Users/Dell/AppData/Local/Pub/Cache/git/squadron-fad409c841390c2ed1987d937d7d79c5a776c7f9/lib/src/_impl/web/_channel.dart:62:22 trampoline	@	main.dart.wasm:0x4e7a4b
$_1828	@	main.dart.wasm:0x3bf91e
(anonymous)	@	main.dart.mjs:627
error		
_4694	@	main.dart.mjs:957
$Worker|set#onerror	@	main.dart.wasm:0x4e7a5b
$openChannel inner	@	_channel.dart:62
$openChannel	@	_channel.dart:32
$Channel.open	@	channel.dart:69
$Worker.start inner	@	worker.dart:244
$Worker.start	@	worker.dart:240
$WorkerPool._provisionWorkers	@	worker_pool.dart:152
$WorkerPool._schedule	@	worker_pool.dart:328
$WorkerPool._enqueue	@	worker_pool.dart:268
$WorkerPool.scheduleValueTask	@	worker_pool.dart:288
$WorkerPool.execute	@	worker_pool.dart:276
$CodecServiceWorkerPool.decode	@	codec_service.worker.g.dart:54
$login inner	@	auth_provider.dart:166
$_awaitHelper closure at org-dartlang-sdk:///dart-sdk/lib/_internal/wasm/lib/async_patch.dart:83:16	@	async_patch.dart:84
$closure wrapper at org-dartlang-sdk:///dart-sdk/lib/_internal/wasm/lib/async_patch.dart:83:16 trampoline	@	main.dart.wasm:0xac05fe
$_rootRunUnary	@	zone.dart:1407
$_rootRunUnary tear-off trampoline	@	main.dart.wasm:0x4c85df
$_CustomZone.runUnary	@	zone.dart:1308
$_FutureListener.handleValue	@	future_impl.dart:163
$_Future._propagateToListeners closure handleValueCallback at org-dartlang-sdk:///dart-sdk/lib/async/future_impl.dart:859:33	@	future_impl.dart:861
$_Future._propagateToListeners	@	future_impl.dart:890
$_Future._completeWithValue	@	future_impl.dart:666
$_Future._asyncCompleteWithValue closure at org-dartlang-sdk:///dart-sdk/lib/async/future_impl.dart:735:29	@	future_impl.dart:736
$closure wrapper at org-dartlang-sdk:///dart-sdk/lib/async/future_impl.dart:735:29 trampoline	@	main.dart.wasm:0x428529
$_rootRun	@	zone.dart:1399
$_rootRun tear-off trampoline	@	main.dart.wasm:0x4c8647
$_CustomZone.run	@	zone.dart:1301
$_CustomZone.runGuarded	@	zone.dart:1209
$_CustomZone.bindCallbackGuarded closure at org-dartlang-sdk:///dart-sdk/lib/async/zone.dart:1249:12	@	zone.dart:1249
$closure wrapper at org-dartlang-sdk:///dart-sdk/lib/async/zone.dart:1249:12 trampoline	@	main.dart.wasm:0x4c8769
$_microtaskLoop	@	schedule_microtask.dart:40
$_startMicrotaskLoop	@	schedule_microtask.dart:49
$_startMicrotaskLoop tear-off trampoline	@	main.dart.wasm:0x41c69c
$_invokeCallback	@	internal_patch.dart:96
(anonymous)	@	main.dart.mjs:647

Pubspec.yaml

dependencies:
  squadron:
    git:
      url: https://github.com/d-markey/squadron
      ref: main
dependency_overrides:
  squadron:
    git:
      url: https://github.com/d-markey/squadron
      ref: main
dev_dependencies:
  squadron_builder:
    git:
      url: https://github.com/d-markey/squadron_builder
      ref: main
@d-markey d-markey self-assigned this Aug 28, 2024
@d-markey d-markey transferred this issue from d-markey/squadron_builder Aug 28, 2024
@d-markey
Copy link
Owner

I've committed 7e951e7 to tentatively fix your issue... according to the stack trace, it happens on line 68 in lib/src/_impl/web/_channel.dart, where something like $<obj> as Class(Object) is happening since err is dynamic. So it will probably uncover another issue and the connection will likely raise a SquadronErrorExt.create('Unexpected error').

Could you post the generated code from codec_service.worker.g.dart? (avoid posting the full code in a comment, just attach the file instead please)

@d-markey
Copy link
Owner

Also, I understand you compiled your Flutter app to Web Assembly, but did you also compile workers to Web Assembly?

@d-markey
Copy link
Owner

At least, this fix made test "- Squadron Worker - initialization error - not found" pass again :-) Thanks!

@sabin26
Copy link
Author

sabin26 commented Aug 29, 2024

Also, I understand you compiled your Flutter app to Web Assembly, but did you also compile workers to Web Assembly?

Scenario 1: CodecService

@SquadronService(baseUrl: '/services/codec', wasm: false) // Raises runtime exception TypeError (this issue)
@SquadronService(baseUrl: '/services/codec', wasm: true) // No error but I would get on to scenario 2

Scenario 2: WebSocketService

@SquadronService(baseUrl: '/services/websocket', wasm: true) // Another issue but no exception

For wasm: false (default):

dart compile js codec_service.web.g.dart -o codec_service.web.g.dart.js

For wasm: true:

dart compile wasm codec_service.web.g.dart -o codec_service.web.g.dart.wasm

I don't know how to explain scenario 2 because there is no exception, but I don't receive WebSocket messages in a Stream. I will open another issue if this issue resolves first.

@sabin26
Copy link
Author

sabin26 commented Aug 29, 2024

Flutter app does runtime check to see if the browser supports wasm. How will squadron manage to do the same ? For js app, load js worker and for wasm app, load wasm worker ?

Do I have to dual compile ?

dart compile js codec_service.web.g.dart -o codec_service.web.g.dart.js
dart compile wasm codec_service.web.g.dart -o codec_service.web.g.dart.wasm

@sabin26
Copy link
Author

sabin26 commented Aug 29, 2024

Could you post the generated code from codec_service.worker.g.dart? (avoid posting the full code in a comment, just attach the file instead please)

I had to change the extension to .txt to upload it here.

codec_service.worker.g.txt

@d-markey
Copy link
Owner

Thanks for the file, I don't think the error comes from the generated code.

What output do you have in your browser's console logs?

@sabin26
Copy link
Author

sabin26 commented Aug 29, 2024

The logs I shared on the first post is from the browser console when the app is launched and some action is performed. The app compiles to wasm sucessfully. So, no compilation error.

@d-markey
Copy link
Owner

Flutter app does runtime check to see if the browser supports wasm. How will squadron manage to do the same ? For js app, load js worker and for wasm app, load wasm worker ?

Do I have to dual compile ?

Yes, you'd have to dual compile AND implement any logic you need to serve JS or wasm. I believe you'd also have to copy the files generated by squadron_builder, because the entry point URI is either js or wasm. Also the worker code is hard-wired on that URI, so the generated worker code will also need some adaptations.

It's an interesting feature, I'll keep that in mind once everything wasm is sorted out.

@d-markey
Copy link
Owner

Version 6 is available, please refer to Squadron's changelog for breaking changes.

Provided you dual-compile, this enables choosing Js or Wasm workers. Eg if your service is called MyService, squadron_builder generates MyServiceWorker and MyServiceWorkerPool with named constructors "js()" and "wasm()". There is still an unnamed constructor which will run the Js or Wasm version that matches your deployment (eg Flutter app compiled to Wasm will use Wasm workers).

@d-markey
Copy link
Owner

Btw did you manage to solve the initial problem you reported? If so, can you close this issue?

@sabin26
Copy link
Author

sabin26 commented Sep 23, 2024

I am migrating to v6.0.1 from pub.dev with squadron builder v6.0.0

But I am getting "Missing import of squadron library" errors when using build_runner build command

It seems the compiler is complaining every other non-squadron releated files to be generated like riverpod providers and freezed data models to also have squadron imported. The errors are "Missing Dart types: FutureOr, Future, Stream" and "Missing import of squadron library"

@d-markey
Copy link
Owner

d-markey commented Sep 23, 2024

The build_runner issue should be fixed now, please upgrade squadron_builder to 6.0.2 6.0.1.

@d-markey d-markey reopened this Sep 23, 2024
@sabin26
Copy link
Author

sabin26 commented Sep 23, 2024

"Missing import of squadron library" - Fixed

"Missing Dart types: FutureOr, Future, Stream" - Not fixed (Still getting error even though the squadron method returns a Future or Stream)

Looking at the examples of squadron builder, is using prefix necessary for Future and Streams ? Some use prefix from dart:async and some from dart:core. Why is that ?

@d-markey
Copy link
Owner

No prefix required, these are tests related to issue d-markey/squadron_builder#14

As a workaround, could you try to change (at least one of) your methods to return FutureOr instead of Future? It may be related to dart:core exporting Future and Stream from dart:async, but not FutureOr. So I believe this would work for the meantime, until I find a fix (which may take a little time...)

@sabin26
Copy link
Author

sabin26 commented Sep 24, 2024

As a workaround, could you try to change (at least one of) your methods to return FutureOr instead of Future?

It worked. Thanks! The build runner issue is gone.

About the original issue, I believe it is resolved because I modified my code to use type casting. Previously it used to work in js environment, so I assumed it as squadron bug. I do not get any logs on console which I reported on this original thread.

I don't know how to explain scenario 2 because there is no exception, but I don't receive WebSocket messages in a Stream. I will open another issue if this issue resolves first.

I will open an issue for this.
Update: It was bug in the websocket client library.

@sabin26 sabin26 closed this as completed Sep 24, 2024
d-markey added a commit to d-markey/squadron_builder that referenced this issue Sep 24, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants