Overview
NativeSpanFeed is a zero-copy wrapper over native Zig memory for efficient streaming of terminal output. It manages chunks of data in native memory and provides spans (slices) to TypeScript without copying.
This is not a full stream interface - it’s optimized for zero-copy access to native memory buffers.
Creating a Stream
Attach to an existing native stream by pointer
Native pointer to existing stream
Options
Event Handlers
Register a handler for data availabilityReturns: Cleanup function to unregister the handler
Callback invoked when data is available. Receives a zero-copy view into native memory.
The
Uint8Array provided to your handler is a view into native memory. Do not retain references to it after the handler returns. If you need the data later, copy it.Register an error handlerReturns: Cleanup function to unregister the handler
Callback invoked on error with error code
Stream Control
Manually drain all available dataCalls registered data handlers for all pending spans. Usually not needed as data is drained automatically when handlers are registered.
Close the stream and free resources
Properties
Native pointer to the underlying stream
Types
DataHandler
GrowthPolicy
Controls how memory chunks grow:"linear"- Add fixed amount each time"exponential"- Double size each time"fibonacci"- Use Fibonacci sequence
NativeSpanFeedStats
Example: Basic Usage
Example: Async Handler
Example: Copy Data for Later Use
Memory Management
The native span feed uses a sophisticated memory management system:- Chunks: Data is allocated in chunks in native memory
- Spans: Each data callback receives a span (slice) of a chunk
- Reference Counting: Chunks are reference counted and freed when no longer needed
- Zero-Copy: Data is never copied from native memory to JavaScript unless you explicitly copy it
Lifecycle
- Data is written to a chunk in native memory
- When data is available, the stream emits a “data available” event
- Your handler receives a
Uint8Arrayview into the chunk - After your handler returns (or async handler resolves), the reference count is decremented
- When a chunk’s reference count reaches zero, it’s freed
Performance Tips
- Use synchronous handlers when possible (async handlers keep chunks pinned longer)
- Process data immediately in the handler rather than queuing it
- If you must store data, copy only what you need
- Consider using
drainAll()if you want to batch process multiple spans - Unregister handlers when no longer needed to avoid memory leaks