Open redDwarf03 opened 2 months ago
Summary: The user is requesting extensions for JSBigInt and BigInt in js-interop
to enable seamless conversion between these types. They are encountering errors related to the use of BigInt in the external
extension members, which is not allowed in dart:js_interop
.
@redDwarf03 have you tried using js- like js: ^0.6.4
and creating an interop?
import 'package:js/js.dart';
@JS('BigInt')
class JSBigInt {
external JSBigInt(String value);
external JSBigInt add(JSBigInt other);
external JSBigInt multiply(JSBigInt other);
}
class MyBigInt extends JSBigInt {
MyBigInt(String value) : super(value);
MyBigInt addWithDart(MyBigInt other) {
return this.add(other);
}
MyBigInt multiplyWithDart(MyBigInt other) {
return this.multiply(other);
}
}
void main() {
var a = MyBigInt('123456789123456789');
var b = MyBigInt('987654321987654321');
var resultAdd = a.addWithDart(b);
var resultMultiply = a.multiplyWithDart(b);
print('Addition Result: ${resultAdd.toString()}');
print('Multiplication Result: ${resultMultiply.toString()}');
}
@redDwarf03 have you tried using js- like
js: ^0.6.4
and creating an interop?import 'package:js/js.dart'; @JS('BigInt') class JSBigInt { external JSBigInt(String value); external JSBigInt add(JSBigInt other); external JSBigInt multiply(JSBigInt other); } class MyBigInt extends JSBigInt { MyBigInt(String value) : super(value); MyBigInt addWithDart(MyBigInt other) { return this.add(other); } MyBigInt multiplyWithDart(MyBigInt other) { return this.multiply(other); } } void main() { var a = MyBigInt('123456789123456789'); var b = MyBigInt('987654321987654321'); var resultAdd = a.addWithDart(b); var resultMultiply = a.multiplyWithDart(b); print('Addition Result: ${resultAdd.toString()}'); print('Multiplication Result: ${resultMultiply.toString()}'); }
No because js
is not supported with new JS Interoperability and WASM
https://dart.dev/interop/js-interop
So i don't want to use js
. Sorry
I create this dart class based on dart test classes but i think dart core team should expose a method to manipulate Bigint and JSBigInt
import 'dart:js_interop';
@JS()
external JSBigInt bigInt;
@JS('BigInt')
external JSBigInt createBigInt(String value);
extension on JSBigInt {
@JS('toString')
external String toStringExternal();
}
Great request, @redDwarf03.
@kevmoo The same with JSFunction if possible :)
The toDart
case is fairly straightforward:
JSBigInt b = ...;
BigInt b2 = BigInt.parse(b.toString()); // toString calls the external toString
The toJS
case requires a few more lines but is also straightforward:
@JS('BigInt')
external JSBigInt bigInt(String s);
...
BigInt b = ...;
bigInt(b.toString());
Of course, it'd be useful to add functions that do this for you and have them in dart:js_interop
, so we can track this request.
The same with JSFunction if possible :)
Can you elaborate a bit more here? We have Function.toJS
and JSExportedDartFunction.toDart
today. JSExportedDartFunction
is a separate type since not all JSFunction
s were converted Dart functions. If you want to call arbitrary JSFunction
s, one solution is using JSFunction.callAsFunction
.
thx. i will explore your comment on JSFunction
@srujzs about JSBigint and JSArray:
I have an JSArray
2 cases:
@JS()
extension type WriteContractParameters._(JSObject _) implements JSObject {
external WriteContractParameters({
JSArray? args,
});
external JSArray? args;
}
@JS()
external JSBigInt bigInt;
@JS('BigInt')
external JSBigInt createBigInt(String value);
extension on JSBigInt {
@JS('toString')
external String toStringExternal();
}
final writeContractParameters = WriteContractParameters(
args: [
'0x08Bfc8BA9fD137Fb632F79548B150FE0Be493254'.toJS,
createBigInt('498500000000000'),
].toJS,
);
When i debug javascript, i have my bigint correctly managed
args: Array(2)
0: "0x08Bfc8BA9fD137Fb632F79548B150FE0Be493254"
1: 498500000000000n
class WriteContractParameters {
WriteContractParameters({
this.args,
});
List<dynamic>? args;
JSWriteContractParameters get toJS => JSWriteContractParameters(
args: args?.jsify() as JSArray<JSObject>?,
);
}
final writeContractParameters = wagmi.WriteContractParameters(
args: [
'0x08Bfc8BA9fD137Fb632F79548B150FE0Be493254',
BigInt.from(498500000000000),
],
);
When i debug javascript, i have my bigint NOT correctly managed
args:
Array(2)
0: "0x08Bfc8BA9fD137Fb632F79548B150FE0Be493254"
1: core._BigIntImpl.__ {Symbol(_used): 4, Symbol(_digits): Uint16Array(4), Symbol(_isNegative): false}
length: 2
Symbol(dartx.arrayRti): (...)
Symbol(dartx.first): (...)
Symbol(dartx.hashCode): (...)
Symbol(dartx.isEmpty): (...)
Symbol(dartx.isNotEmpty): (...)
Symbol(dartx.iterator): (...)
Symbol(dartx.last): (...)
Symbol(dartx.length): (...)
Symbol(dartx.reversed): (...)
Symbol(dartx.runtimeType): (...)
Symbol(dartx.single): (...)
[[Prototype]]: Array(0)
So i would like to fix my case 2
Yeah, we currently don't treat BigInt
s specially in jsify
and treat them as other Dart members, so it'll be a bit more of a manual process. There's a blanket bug here: https://github.com/dart-lang/sdk/issues/55222 to be clear about what jsify
/dartify
can and can't do (right now we only technically support whatever's in the doc comment) as well as make it consistent. One of the options there is allow users to expose the low-level conversion methods they need so they can write their own variants that convert types as they need.
@srujzs i tried something like that but the add method seems to add nothing...
JSArray<JSObject>? _convertArgs(List<dynamic>? args) {
if (args == null) {
return null;
}
final jsArgs = JSArray<JSObject>();
for (final arg in args) {
if (arg is String) {
jsArgs.add(arg.toJS);
} else if (arg is int) {
jsArgs.add(arg.toJS);
} else if (arg is bool) {
jsArgs.add(arg.toJS);
}
}
return jsArgs;
}
@srujzs i tried something like that but the add method seems to add nothing...
JSArray<JSObject>? _convertArgs(List<dynamic>? args) { if (args == null) { return null; } final jsArgs = JSArray<JSObject>(); for (final arg in args) { if (arg is String) { jsArgs.add(arg.toJS); } else if (arg is int) { jsArgs.add(arg.toJS); } else if (arg is bool) { jsArgs.add(arg.toJS); } } return jsArgs; }
@srujzs is it possible to add BigInt in the condition https://github.com/dart-lang/sdk/blob/ee0b971dbd6ff51d8ec740294fb0a2730df6bb2b/sdk/lib/_internal/wasm/lib/js_util_patch.dart#L32
i tried something like that but the add method seems to add nothing...
There's no add
method on a JSArray
. You may want push
e.g.
extension JSArrayExtension<T extends JSAny?> on JSArray<T> {
external void push(T _);
}
Besides that, the approach seems fine, but it is a bit of reinventing jsify
alas.
is it possible to add BigInt in the condition
One of the things we want to do for jsify
/dartify
is expose it in such a way that users can define their own conversions if needed. Maybe a callback would be useful here for types that aren't supported by default, but it'd be nice to customize jsify
/dartify
as needed at any rate.
Why JSBigint and Bigint have no extension in
js-interop
likeI try to create in my project these extensions but i have this error: