Skip to main content

yet_another_json_isolate 3.0.0-dev.3 copy "yet_another_json_isolate: ^3.0.0-dev.3" to clipboard
yet_another_json_isolate: ^3.0.0-dev.3 copied to clipboard

JSON parsing off the main isolate, processing small payloads inline and large payloads on short lived isolates without copying results. Runs inline on web.


Supabase Logo

yet_another_json_isolate

JSON processing that never blocks the main isolate for long: small payloads are decoded inline, large payloads on short lived isolates that hand their result back without copying, and a large list is encoded on the main isolate in slices that yield to the event loop. On web, which has no isolates, every payload is decoded inline on the main thread.

pub package pub test

Usage #

import 'dart:typed_data';

import 'package:http/http.dart' as http;
import 'package:yet_another_json_isolate/yet_another_json_isolate.dart';

Future<void> main() async {
  final isolate = YAJsonIsolate();
  try {
    // Serialize to a JSON string.
    final String json = await isolate.encode({'title': 'Dune'});

    // Serialize to UTF-8 encoded JSON bytes, such as an HTTP request body,
    // without materializing the intermediate string.
    final Uint8List requestBody = await isolate.encodeBytes([
      {'title': 'Dune'},
      {'title': 'Emma'},
    ]);

    // Deserialize a JSON string.
    final Object? book = await isolate.decode('{"title": "Dune"}');

    // Deserialize UTF-8 encoded JSON bytes, such as an HTTP response body,
    // without materializing the intermediate string on the calling isolate.
    final response = await http.get(Uri.parse('https://example.com/books'));
    final Object? data = await isolate.decodeBytes(response.bodyBytes);
  } finally {
    // Dispose when no longer needed, even when an operation throws.
    await isolate.dispose();
  }
}

AsyncJsonCodec #

YAJsonIsolate implements AsyncJsonCodec, the interface the Supabase clients accept through their jsonCodec parameter. Implement it to process their JSON some other way, for example with a native parser, or to wrap the default implementation and measure it.

import 'dart:typed_data';

import 'package:yet_another_json_isolate/yet_another_json_isolate.dart';

class TimedJsonCodec implements AsyncJsonCodec {
  TimedJsonCodec(this._inner);

  final AsyncJsonCodec _inner;

  @override
  Future<dynamic> decode(String json) => _time(() => _inner.decode(json));

  @override
  Future<dynamic> decodeBytes(Uint8List encodedJson) =>
      _time(() => _inner.decodeBytes(encodedJson));

  @override
  Future<String> encode(Object? json) => _time(() => _inner.encode(json));

  @override
  Future<Uint8List> encodeBytes(Object? json) =>
      _time(() => _inner.encodeBytes(json));

  @override
  Future<void> dispose() => _inner.dispose();

  Future<T> _time<T>(Future<T> Function() operation) async {
    final stopwatch = Stopwatch()..start();
    try {
      return await operation();
    } finally {
      print('JSON took ${stopwatch.elapsedMicroseconds} µs');
    }
  }
}

License #

This repo is licensed under MIT.

15
likes
160
points
1.25M
downloads

Documentation

API reference

Publisher

verified publishersupabase.io

Weekly Downloads

JSON parsing off the main isolate, processing small payloads inline and large payloads on short lived isolates without copying results. Runs inline on web.

Homepage
Repository (GitHub)
View/report issues

Topics

#json #isolate #parsing #async

License

MIT (license)

Dependencies

meta

More

Packages that depend on yet_another_json_isolate