# Capability Spec Delta: bitpacker-streaming (bitpacker-stub-completion) **Package**: `@suaveplan/bitpacker-streaming` **Status**: PROPOSED > Every requirement below carries a `**Verified by:**` line at authoring time. ## ADDED Requirements ### Requirement: StreamingBitPacker class The package SHALL export `StreamingBitPacker extends EventEmitter` matching upstream `streaming.ts` (L14-L406). The class SHALL expose `packStream(data, options)` and `unpackStream(packed, options)`, both returning `Promise` (pack) / `Promise>` (unpack). Both methods SHALL emit `progress` events as chunks complete and `chunk` events with the bytes of each completed chunk; chunk size SHALL come from `options.chunkSize` (default 1024). #### Scenario: packStream round-trips through unpackStream - **WHEN** a 100 KiB object is `packStream`-ed and the result is `unpackStream`-ed under the same schema - **THEN** the unpacked value deep-equals the input #### Scenario: progress events fire in chunk order - **WHEN** `packStream` is called on data that produces 8 chunks - **THEN** 8 `progress` events fire with `{ index, total: 8, percent }` in monotonically increasing order; the final event has `percent === 1` #### Scenario: chunk events carry chunk bytes - **WHEN** `packStream` runs with `emitProgress: true` - **THEN** each `chunk` event's payload is a `Uint8Array` whose concatenation equals the final return value byte-for-byte **Verified by:** `packages/bitpacker/bitpacker-streaming/src/streaming-bit-packer/streaming-bit-packer.test.ts::"packStream / unpackStream round-trip preserves the value"` AND `packages/bitpacker/bitpacker-streaming/src/streaming-bit-packer/streaming-bit-packer.test.ts::"emits progress events in monotonic chunk order"` AND `packages/bitpacker/bitpacker-streaming/src/streaming-bit-packer/streaming-bit-packer.test.ts::"chunk events concatenate to the final byte output"` --- ### Requirement: chunkProcessor invoked per chunk If `options.chunkProcessor` is supplied, the streaming bit-packer SHALL invoke it on each chunk before emitting / returning, awaiting the result. If the processor throws, `packStream` / `unpackStream` SHALL throw `BitpackerError` with code `BITPACKER.STREAM_CHUNK_PROCESSOR_FAILED`, chaining the original error. #### Scenario: chunkProcessor mutates chunks before delivery - **WHEN** `chunkProcessor` is `(chunk) => xor(chunk, 0xff)` and the produced bytes are XOR'd back before unpack - **THEN** the round-trip succeeds #### Scenario: chunkProcessor failure surfaces as coded error - **WHEN** `chunkProcessor` throws on chunk 3 - **THEN** `packStream` rejects with `BitpackerError` code `BITPACKER.STREAM_CHUNK_PROCESSOR_FAILED` whose `cause` is the original error and `context.chunkIndex === 3` **Verified by:** `packages/bitpacker/bitpacker-streaming/src/streaming-bit-packer/streaming-bit-packer.spec-conformance.test.ts::"chunkProcessor mutates chunks before delivery"` AND `packages/bitpacker/bitpacker-streaming/src/streaming-bit-packer/streaming-bit-packer.spec-conformance.test.ts::"chunkProcessor failure surfaces as STREAM_CHUNK_PROCESSOR_FAILED"` --- ### Requirement: validateChunks gates pack/unpack on validation When `options.validateChunks` is `true`, the streaming bit-packer SHALL run the underlying `BitPacker.validate` over the input (pack) or unpacked output (unpack) and reject before emitting if validation fails, throwing `BitpackerError` with code `BITPACKER.STREAM_VALIDATION_FAILED`. #### Scenario: validation gate rejects malformed input - **WHEN** `validateChunks: true` and the input violates the schema (e.g. value out of `u8` range) - **THEN** `packStream` rejects with `BitpackerError` code `BITPACKER.STREAM_VALIDATION_FAILED` AND no `chunk` events fire #### Scenario: validation gate disabled by default - **WHEN** `validateChunks` is omitted - **THEN** packing proceeds without validation; encoder errors surface natively **Verified by:** `packages/bitpacker/bitpacker-streaming/src/streaming-bit-packer/streaming-bit-packer.spec-conformance.test.ts::"validateChunks: true rejects malformed input with STREAM_VALIDATION_FAILED"` AND `packages/bitpacker/bitpacker-streaming/src/streaming-bit-packer/streaming-bit-packer.spec-conformance.test.ts::"validateChunks default is false"` --- ### Requirement: AbortSignal propagation `packStream` and `unpackStream` SHALL accept `options.signal: AbortSignal`. When the signal is already aborted at call time, the call SHALL reject immediately with `BitpackerError` code `BITPACKER.STREAM_ABORTED`. When abort fires mid-stream, the in-flight chunk SHALL complete and then the call SHALL reject with the same code; no subsequent chunks SHALL be processed or emitted. #### Scenario: pre-aborted signal rejects immediately - **WHEN** `signal.aborted === true` at call time - **THEN** `packStream` rejects synchronously with `BitpackerError` code `BITPACKER.STREAM_ABORTED` #### Scenario: mid-stream abort halts further chunks - **WHEN** `abort()` fires after the 2nd of 8 chunks completes - **THEN** chunks 3..8 do NOT emit `chunk` events and the promise rejects with `BITPACKER.STREAM_ABORTED` **Verified by:** `packages/bitpacker/bitpacker-streaming/src/streaming-bit-packer/streaming-bit-packer.test.ts::"pre-aborted signal rejects immediately with STREAM_ABORTED"` AND `packages/bitpacker/bitpacker-streaming/src/streaming-bit-packer/streaming-bit-packer.test.ts::"mid-stream abort halts further chunk emission"` ## MODIFIED Requirements ### Requirement: Synchronous chunked helpers delegate to StreamingBitPacker The existing `packToChunks`, `unpackFromChunks`, and `unpackFromChunksAsync` functions SHALL be preserved with their current signatures, but their implementation SHALL delegate to `StreamingBitPacker` so behavior stays synchronized. The async helper SHALL honour `AbortSignal` (already true today; pin behavior in test). #### Scenario: packToChunks output equals StreamingBitPacker.packStream concatenation - **WHEN** the same data + schema is run through `packToChunks` and through `packStream` and the chunks of each are concatenated - **THEN** the byte-arrays are equal **Verified by:** `packages/bitpacker/bitpacker-streaming/src/streaming-bit-packer/streaming-bit-packer.test.ts::"packToChunks delegates to packStream"` AND `packages/bitpacker/bitpacker-streaming/src/streaming-bit-packer/streaming-bit-packer.test.ts::"unpackFromChunksAsync honours AbortSignal"`