Skip to content

Releases: buiapp/reaktiv

0.24.2

Choose a tag to compare

@buiapp buiapp released this 06 Jul 12:40

Full Changelog: 0.23.0...0.24.2

Added

  • Introduced lowercase primitive APIs as the recommended style:
    signal, computed, linked, resource, and effect.

Changed

  • Updated documentation and examples to consistently use lowercase primitives.
  • Clarified that uppercase names remain supported as concrete classes or compatibility entry points.

0.24.1

Choose a tag to compare

@buiapp buiapp released this 06 Jul 11:58

Full Changelog: 0.23.0...0.24.1

Added

  • Introduced lowercase primitive APIs as the recommended style:
    signal, computed, linked, resource, and effect.

Changed

  • Updated documentation and examples to consistently use lowercase primitives.
  • Clarified that uppercase names remain supported as concrete classes or compatibility entry points.

0.24.0

Choose a tag to compare

@buiapp buiapp released this 06 Jul 10:50

Full Changelog: 0.23.0...0.24.0

Added

  • Introduced lowercase primitive APIs as the recommended style:
    signal, computed, linked, resource, and effect.

Changed

  • Updated documentation and examples to consistently use lowercase primitives.
  • Clarified that uppercase names remain supported as concrete classes or compatibility entry points.

0.23.0

Choose a tag to compare

@buiapp buiapp released this 22 Jun 10:14

0.23.0

Added

  • Added ReactiveModel for grouping reactive state and behavior in reusable
    Python classes.
  • Added field() for typed, per-instance signals with default values and
    factories.
  • Added model-friendly @computed, @effect, @linked, and @resource
    decorators with support for instance methods.
  • Added automatic ownership and cleanup of model effects and resources through
    ReactiveModel.dispose().
  • Added constructor overrides and mixin guidance for initializing models with
    instance-specific values.
from reaktiv import ReactiveModel, computed, effect, field


class Counter(ReactiveModel):
    count = field(0)

    @computed
    def doubled(self):
        return self.count() * 2

    @effect
    def report(self):
        print(self.count(), self.doubled())


counter = Counter(count=5)
counter.count.update(lambda value: value + 1)
counter.dispose()

Improved

  • Expanded type inference coverage and documentation for the new model API.
  • Added practical ReactiveModel examples for application state, linked values,
    async resources, cleanup, and custom equality.
  • Made documentation examples executable directly in the browser with Pyodide.

API Direction

  • Lowercase callable APIs such as computed(), effect(), linked(), and
    resource() are planned to become the preferred style for future
    instantiation and decorators.

Full Changelog: 0.22.0...0.23.0

0.22.0

Choose a tag to compare

@buiapp buiapp released this 14 Jun 19:08

0.22.0

  • Thread-safety improvements
  • Prevented independent signal graphs from blocking each other across threads.
  • Fixed missed effect executions in threaded graph updates.
  • Improved computed/effect dependency tracking under concurrent updates.
  • Note: single-thread sync graph workloads may have modest overhead from thread-safe coordination.

Full Changelog: 0.21.5...0.22.0

0.21.5

Choose a tag to compare

@buiapp buiapp released this 12 Jun 16:02

Full Changelog: 0.21.4...0.21.5

0.21.4

Choose a tag to compare

@buiapp buiapp released this 02 Jun 10:09

Full Changelog: 0.21.3...0.21.4

0.21.3

Choose a tag to compare

@buiapp buiapp released this 22 Feb 21:16

Fixed

  • Removed undeclared typing_extensions dependency (#30)

Full Changelog: 0.21.2...0.21.3

0.21.2

Choose a tag to compare

@buiapp buiapp released this 19 Feb 10:44

Fixed

  • BREAKING: Restored weakref behavior for Effects that was accidentally removed in the August 2025 rewrite. Effects are now properly garbage collected when not assigned to a variable, as documented.

⚠️ Migration Warning

If you were relying on Effects persisting without storing a reference, your code will break.

Previously buggy behavior:

# Effect stayed alive even without assignment (BUG)
Effect(lambda: print(signal()))
signal.set(1)  # This worked, but shouldn't have

Correct behavior (0.21.2+):

# Effect is immediately GC'd without assignment
Effect(lambda: print(signal()))
signal.set(1)  # Effect won't run - already garbage collected

# Store reference to keep Effect alive
effect = Effect(lambda: print(signal()))
signal.set(1)  # Works correctly

Action required: Search your codebase for Effect( and ensure all Effects are either:

  1. Assigned to a variable: self.effect = Effect(...)
  2. Stored in a collection: self.effects.append(Effect(...))
  3. Properly disposed when done: effect.dispose()

This change prevents memory leaks in patterns like nested Effects and is consistent with the documented behavior.

Added

  • Added __del__ method to Effect class to automatically run cleanup functions when Effects are garbage collected, preventing resource leaks even without explicit dispose() calls.

Full Changelog: 0.21.1...0.21.2

0.21.1

Choose a tag to compare

@buiapp buiapp released this 14 Feb 13:53

Fixed

  • Bug: Effects watching intermediate computed signals in diamond-shaped dependency graphs now trigger correctly (Issue #27)

Full Changelog: 0.21.0...0.21.1