Group-scoped DEFLATE: a stream of self-delimited frames sharing one compression window.
A sequence of frame payloads is compressed into a single raw DEFLATE (RFC 1951) stream,
sync-flushed at each frame boundary. Every frame is therefore self-delimited (byte-aligned, the
window retained) while later frames reuse the earlier ones as context, so a stream of similar
payloads (a snapshot followed by deltas, repeated records, log lines) compresses far better than
each payload alone. The [Encoder]/[Decoder] hold that shared window; create a fresh pair per
independent stream (in moq-net terms, per group).
This is plain raw DEFLATE with a Z_SYNC_FLUSH after each frame, so any peer using the same
primitive (zlib's sync flush, the browser's deflate-raw) interoperates on the wire. There is no
length prefix: the caller is expected to frame each slice (moq-net already does). A small slice
can still inflate to far more than its own size, so [Decoder::frame] bounds each frame's output.
A sync flush always ends in the 4-byte empty-block marker 00 00 ff ff. That marker is fixed, so
[Encoder::frame] drops it from each slice and [Decoder::frame] re-appends it before inflating,
saving 4 bytes per frame. This is the same trick RFC 7692 (permessage-deflate) uses for
WebSocket messages.
let mut encoder = moq_flate::Encoder::new();
let a = encoder.frame(b"the quick brown fox");
let b = encoder.frame(b"the quick brown dog"); // smaller: reuses the window
let mut decoder = moq_flate::Decoder::new();
assert_eq!(decoder.frame(&a)?, &b"the quick brown fox"[..]);
assert_eq!(decoder.frame(&b)?, &b"the quick brown dog"[..]);