evaluateJson method

  1. @override
dynamic evaluateJson(
  1. String command, {
  2. String? sourceUrl,
})
override

Evaluate js script and decode the result via a single JSON.stringify round-trip instead of recursive per-element FFI marshaling.

This is dramatically faster for large arrays/objects, but the result must be JSON-serializable: functions, Promises and cyclic references are not supported (they decode to null / are dropped, as with JSON.stringify).

Implementation

@override
dynamic evaluateJson(String command, {String? sourceUrl}) {
  _ensureEngine();
  final ctx = _ctx!;
  final jsval = jsEval(
    ctx,
    command,
    sourceUrl ?? '<eval>',
    JSEvalFlag.GLOBAL,
  );
  if (jsIsException(jsval) != 0) {
    jsFreeValue(ctx, jsval);
    throw _parseJSException(ctx);
  }
  final fnStringify = _jsonStringifyFn ??= jsEval(
    ctx,
    'JSON.stringify',
    '<json>',
    JSEvalFlag.GLOBAL,
  );
  final thisObj = jsUNDEFINED();
  final jsonVal = jsCall(ctx, fnStringify, thisObj, [jsval]);
  jsFreeValue(ctx, thisObj);
  jsFreeValue(ctx, jsval);
  if (jsIsException(jsonVal) != 0) {
    jsFreeValue(ctx, jsonVal);
    throw _parseJSException(ctx);
  }
  if (jsValueGetTag(jsonVal) != JSTag.STRING) {
    jsFreeValue(ctx, jsonVal);
    return null;
  }
  final jsonStr = jsToCString(ctx, jsonVal);
  jsFreeValue(ctx, jsonVal);
  _maybeDrainJobs();
  return jsonDecode(jsonStr);
}