betto_zstd 0.1.0-dev.1
betto_zstd: ^0.1.0-dev.1 copied to clipboard
Zstd compression
betto_zstd #
A Zstandard (Zstd) compression library for Dart. Supports native platforms via
FFI and the web platform via an Emscripten-compiled WASM module. Both paths
compile the same C source (third_party/zstd/src/zstd.c) so frame format
compatibility is guaranteed by construction.
Platforms #
| Platform | Implementation | Status |
|---|---|---|
| macOS, Linux, Windows | Native FFI (native_toolchain_c) |
Compress + decompress |
| iOS, Android | Native FFI (native_toolchain_c) |
Compress + decompress |
| Web (Flutter Web) | Emscripten WASM (dart:js_interop) |
Compress + decompress |
Getting started #
Add betto_zstd to your pubspec.yaml:
dependencies:
betto_zstd: ^0.1.0
Or run:
dart pub add betto_zstd
Native platforms require a C compiler available at build time (e.g. clang
on macOS/iOS, gcc on Linux/Android, MSVC on Windows). The
native_toolchain_c build hook compiles zstd.c automatically during
dart build / flutter build.
Flutter Web requires lib/assets/zstd.wasm to be declared as a Flutter
asset (already done in pubspec.yaml) and ZstdSimple.init() to be awaited
before first use (see usage below).
Usage #
Native platforms #
import 'dart:typed_data';
import 'package:betto_zstd/betto_zstd.dart';
void main() async {
await ZstdSimple.init(); // no-op on native; safe to always call
final zstd = ZstdSimple(level: 3);
final data = Uint8List.fromList([1, 2, 3, 4, 5, 1, 2, 3, 4, 5]);
final compressed = zstd.compress(data);
final decompressed = zstd.decompress(compressed);
assert(decompressed.length == data.length);
}
Flutter Web #
Call ZstdSimple.init() once during app startup — for example in main() —
before creating any ZstdSimple instance:
import 'package:betto_zstd/betto_zstd.dart';
import 'package:flutter/material.dart';
Future<void> main() async {
WidgetsFlutterBinding.ensureInitialized();
await ZstdSimple.init(); // loads lib/assets/zstd.wasm
runApp(const MyApp());
}
ZstdSimple.compress and ZstdSimple.decompress are then synchronous and
safe to call from any context.
Frames produced by the web path are byte-compatible with the native FFI path
and vice versa — both compile the same third_party/zstd/src/zstd.c source, so
the Zstd frame format is identical by construction. This is verified by
test/frame_compat_test.dart, which runs a golden-file cross-platform check on
every CI run.
Compression levels #
print('min level: ${minCLevel()}'); // −131072
print('max level: ${maxCLevel()}'); // 22
final zstd = ZstdSimple(level: maxCLevel()); // maximum compression
CLI tool #
The package includes bin/dartz.dart for compressing and decompressing files:
dart run bin/dartz.dart myfile.txt # compress
dart run bin/dartz.dart -d myfile.txt.zst out # decompress
Vendored C source #
The Zstd C library is vendored as a single-file amalgamation at
third_party/zstd/src/zstd.c, produced by Zstd's
create_single_file_library.sh script. The current vendored version is
recorded in VERSION_ZSTD at the repository root.
Bumping the Zstd version #
- Download the desired Zstd release tarball from https://github.com/facebook/zstd/releases.
- Run
create_single_file_library.shfrom the Zstd source tree. - Copy the output (
zstd.h,zstd.c,zdict.h,zstd_errors.h) tothird_party/zstd/. - Update
VERSION_ZSTDto the new version string (e.g.1.5.8). - Run
dart run ffigento regeneratelib/src/third_party/zstd.dart. - Run
make wasmto rebuildlib/assets/zstd.wasm(requires Emscripten). - Commit all changed files including the new
zstd.wasm.
The build hook (hook/build.dart) verifies at build time that VERSION_ZSTD
matches the version encoded in third_party/zstd/zstd.h and fails the build
on a mismatch.
Rebuilding the WASM module #
The pinned Emscripten version is recorded in EMSCRIPTEN_VERSION at the
repository root (analogous to VERSION_ZSTD for the C library). Always use
that exact version so the rebuilt binary is bit-for-bit identical to the
committed one and the CI verify-wasm job passes.
Using the Containerfile (recommended)
The Containerfile at the repository root installs the pinned Emscripten
version automatically. This is the easiest way to build without polluting your
host environment:
podman build -t betto-zstd-wasm .
podman run --rm -v "$(pwd)":/work -w /work betto-zstd-wasm make wasm
Commit lib/assets/zstd.wasm after building.
Using a local Emscripten install
Install the exact version from EMSCRIPTEN_VERSION via
emsdk, activate
it so emcc is on PATH, then run:
make wasm
Output: lib/assets/zstd.wasm (~317 KB). Commit this file after building.
Upgrading the pinned Emscripten version
- Update
EMSCRIPTEN_VERSIONto the new tagged release (e.g.6.1.0). - Rebuild the WASM module using the container or local workflow above.
- Commit both
EMSCRIPTEN_VERSIONand the newlib/assets/zstd.wasm.
Development #
dart test # native tests
dart test --platform chrome # web/WASM tests (requires committed zstd.wasm)
dart analyze
dart format lib/ test/ example/
make all # license_check + format + analyze + test + coverage + doc
make pre_commit # license_check + test
make wasm # rebuild lib/assets/zstd.wasm (needs emcc)
Acknowledgements #
This package uses the Zstandard C library under the BSD Licence. See also third_party/zstd/README.md.