# Changelog

## [Unreleased]

## [0.6.0] - 2026-02-23

### Added

- Expose extra internal source pads in composed transforms
- Handle duplicate pad names in `Compose`

### Changed

- Make `ParallelizeBase` part of the public API
- Make Bottle HTTP control use a random port by default
- Put tag in registry file full path

## [0.5.0] - 2026-01-15

### Added

- Add `Compose` class for composing multiple elements into reusable units
  * Support for `ComposedSourceElement`, `ComposedTransformElement`,
    `ComposedSinkElement` via `.as_source()`, `.as_transform()`, `.as_sink()`
- Add class-level fixed/extra pad configuration for elements via
  `static_sink_pads`, `static_source_pads`, `allow_dynamic_sink_pads`,
  `allow_dynamic_source_pads`
- Add validation decorators for element reuse
- Add `CollectSink` flag to keep frames where `data is None`

### Changed

- Use short pad names as keys in `CollectSink` and `IterSource`
- Expose `pad_name` (short name) from pads, specify full name within base
  `PadLike` class
- Switch to native types for type hints where applicable
- Make buffer logging level DEBUG instead of INFO

### Fixed

- Fix `CollectSink` for TSFrame buffers attribute
- Fix pickling issues on Mac OS for parallelize elements

## [0.4.0] - 2025-11-03

### Added

- Add `pipeline.connect()` for implicit pipeline linking with automatic pad
  matching
- Add `select()` and `group()` for element grouping and pad selection
  * `select_by_source()` / `select_by_sink()` for iterating over pads
- Add partial match strategy for `connect()` with overlapping pad names
- Add `StatsSource` for system/process statistics via psutil
- Add `WorkerContext` for consistent subprocess/parallelize API
- Add error propagation from worker processes in parallelize elements
- Add element entry point registration

### Changed

- Bump minimum Python version to 3.10
- Simplify parallelize and subprocess API
- Define abstract base classes for elements and `PadLike`
- Allow generic frame-like objects for elements
- Migrate logging functionality to separate logger module

### Fixed

- Fix memory profiling when logger is set to NOTSET
- Provide pad context for runtime exceptions

## [0.3.0] - 2025-05-14

### Added

- Add threading mode for parallelize elements (`_use_threading_override`)
- Add `DataSpec` for frame data specification and validation
- Add `sub_process_shutdown()` for graceful worker shutdown

### Changed

- Flatten pad class hierarchy

### Fixed

- Reset received signals in `SignalEOS` on context manager exit
- Make sure input queue is actually empty when cleaning up subprocess
- Improve exception handling in subprocess

## [0.2.0] - 2025-04-17

### Added

- Add `HTTPControl` for REST endpoint monitoring and control
  * GET/POST routes with wildcard key support
  * `exchange_state()` for bidirectional state updates
  * Configurable tag prefix for routes
  * Registry file location control
- Add `CallableTransform.from_callable()` and `from_combinations()` class
  methods
- Add subprocess/parallelize elements for multiprocessing
  * `ParallelizeTransformElement`, `ParallelizeSinkElement`,
    `ParallelizeSourceElement`
  * Shared memory support via `Parallelize.to_shm()`
- Add `SignalEOS` for graceful SIGINT/SIGTERM handling
- Add memory profiling via `SGNLOGLEVEL=pipeline:MEMPROF`
- Add pipeline visualization via `pipeline.visualize()`
- Add Jupyter notebook support (auto-detects running event loop)
- Add `InternalPad` to all elements
- Add element logging support
- Add `NullSink` verbose option
- Add `pipeline.check()` for validating pad connections

### Changed

- Rename `TransformElement.transform()` to `.new()`
- Use abbreviated "snk" instead of "sink" in internal pad names

### Fixed

- Fix `CallableTransform.from_combinations` pad uniqueness
- Fix `NullSink` EOS handling based on `frame.EOS`

## [0.1.0] - 2024-12-13

- Initial release
- Core framework: `SourceElement`, `TransformElement`, `SinkElement`
- `Frame` with `data`, `EOS`, `is_gap`, `spec`, `metadata` attributes
- `SourcePad`, `SinkPad` with linking and graph execution
- `Pipeline` with async event loop and `TopologicalSorter`-based DAG execution
- `NullSource`, `IterSource`, `DequeSource` built-in sources
- `NullSink`, `CollectSink`, `DequeSink` built-in sinks
- `CallableTransform` for wrapping callables as transforms

[unreleased]: https://git.ligo.org/greg/sgn/-/compare/v0.6.0...main
[0.6.0]: https://git.ligo.org/greg/sgn/-/tags/v0.6.0
[0.5.0]: https://git.ligo.org/greg/sgn/-/tags/v0.5.0
[0.4.0]: https://git.ligo.org/greg/sgn/-/tags/v0.4.0
[0.3.0]: https://git.ligo.org/greg/sgn/-/tags/v0.3.0
[0.2.0]: https://git.ligo.org/greg/sgn/-/tags/v0.2.0
[0.1.0]: https://git.ligo.org/greg/sgn/-/tags/v0.1.0
