- refactor: replace
if isinstance(action, ...)chains with Pythonmatchstatement in all reducers across demos, tests, and README - feat: add
poe test-binarytask to run tests against compiled Cython extensions - ci: add
test-binaryjob to GitHub Actions workflow to verify compiled extensions pass all tests
- fix: add missing
redux_pytestpackages to binary wheels in github actions
- chore: provide project information in
pyproject_binary.toml - chore: create binary wheels for a wider range of operating systems and architectures, use dedicated runners for each build to avoid emulation and get faster results
- fix: add missing
redux_pytestpackages to binary wheels in github actions
- fix: handle weakref event handlers in
SideEffectRunner - test: add more performance tests
- chore: update ruff to the latest version 0.15.0
- refactor: use custom value
NOT_SET = object()instead ofNoneto signal the absence of a value for thedefault_valueparameter inAutorunOptionsand internally inAutorunclass for properties storing last selector result and last call result - build: switch versioning source to
version.py, support Python 3.14 - refactor: improve weakref handling in store listeners and event handlers, remove manual
weakrefhandling inSideEffectRunner, optimizeAutorunchecks and subscription logic - test: add tests for subscription lifecycle
- ci: add code coverage check to
integration_deliveryworkflow
- chore: add badges in
README.mdand classifiers inpyproject.toml - refactor: move the common code for manipulating the signature of the wrapped functions in
WithStoreandAutorunto a utility function - feat: support
with_stateto be applied to methods of classes, not just functions - feat: support
viewto be applied to methods of classes, not just functions, it works forautoruntoo, but only when it is being called directly like a view - refactor: rename
_idfield of combine reducer state tocombine_reducers_id - feat: allow customizing the async task creator of the
Autoruninstance by overriding its_create_taskmethod
- refactor: remove
WithStateas it wasn't doing anything beyondfunctools.wraps - refactor: autorun doesn't inform subscribers when the output value is not changed
- refactor: add
autorun_classandside_effect_runner_classto improve extensibility - refactor: setting
auto_awaitfor async autorun functions will make them returnNone, setting it toFalsewill make them return the awaitable, the awaitable can beawaited multiple times, as it cashes the result if comparator is not changed, it can't be set for sync functions - refactor: housekeeping, remove unused callback of task creators, remove unused
_task_callbackof autoruns, clean up type hints, etc
- fix: add
__qualname__,__annotations__,__module__,__defaults__and__kwdefaults__toAutorunandWithStoreinstances so that they play nice when passed as a function to something assuming they are normal function having these properties.
- fix: add
__name__toWithStoreinstances so that they play nice when passed as a function to something assuming they are functions and have a__name__attribute - test: add/modify tests to bring back coverage to 100%
- test: make sure pytest exits completely after running async tests
- refactor: in
_wait_for_store_to_finish, instead of waiting withasyncio.sleep, run the store event loop when conditions are not satisfied - refactor: directly run
_handle_finish_eventin the store event loop whenFinishEventis dispatched, previously it used to be a normalsubscribe_event, events registered insubscribe_eventrun inSideEffectRunnerThreadand it runs them with thetask_runner, and there is no guaranteetask_runnerruns tasks afterFinishEventis dispatched
- refactor: add
WithStateclass to be the return value of thestore.with_stateso that it can report correct signature of its__call__method - chore(docs): add documentation strings for elements defined in
autorun.py
- chore(lint): update
ruffto0.10.0and fix linting issues, makestore.subscribeprivate
- fix: avoid using
asdictin combine-reducers's reducer as it can get too costly for large dataclasses and may even run into errors
- feat: add
memoizationoption toautorun, default isTrue, compatible with old behavior, if set toFalse, calling the function explicitly will always run it regardless of the selector's value - feat: add
with_selector, as a decorator to run functions with the result of a selector.
- refactor: provide correct signature for the autorun instance based on the function it decorates
- refactor: side effect runners always run the side effect in the event loop provided to them regardless of the return value of the side effect being a coroutine or not, this is because even if the side effect is not a coroutine, it might still use async features internally
- refactor(combine_reducers): add custom payload to
CombineReducerInitActionandCombineReducerRegisterActionto allow custom initialization of sub-reducers
- chore(pytest): add
project.entry-points.pytest11section topyproject.tomlso that it can be used as a pytest plugin
- chore: migrate from poetry to uv for the sake of improving performance and dealing with conflicting sub-dependencies
- refactor(core): avoid passing events to
dispatch, to enforce using them as side-effects only
- feat(autorun): add
auto_awaittoAutorunOptionsso that one can define an autorun/view as a decorator of a function without automatically awaiting its result, whenauto_awaitis set toFalse, which activates the new behavior, the decorated function passesasyncio.iscoroutinefunctiontest, useful for certain libraries like quart
- refactor(core): allow
Nonetype for state, action and event types inReducerResultandCompleteReducerResult
- refactor(autorun): remove
auto_calloption as it was addressing such a rare use case that it was not worth the complexity
- feat(core): add
_typefield to the serialized immutable instances
- feat(core): add blocking
wait_for_event_handlersmethod toStoreto wait for all event handlers to finish
- feat(test): add arguments for
wait_for'scheck
- refactor(core): use
str_to_boolofpython-strtoboolinstead ofstrtoboolofdistutils - feat(test-snapshot): add prefix to snapshot fixture
- feat(test-snapshot): the
selectorfunction can signal themonitorit should ignore a particular snapshot of the state by returningNone
- refactor(test-snapshot): make it aligned with
pyfakefsby usingtry/exceptinstead of checkingPath().exists()aspyfakefsdoesn't seem to respectskip_namesforPath().exists()
- feat(test-snapshot): while still taking snapshots of the whole state of the store, one can narrow this down by providing a selector to the
snapshotmethod (used to be a property) - feat(test-snapshot): new
monitormethod to let a test automatically take snapshots of the store whenever it is changed. Takes an optional selector to narrow down the snapshot.
- build(pypi): add metadata
- docs: add an introduction of
viewtoREADME.md
- refactor(autorun): improve type-hints so that its final return value has the correct type, regardless
default_valueis provided or not - refactor(view): improve type-hints so that its final return value has the correct type, regardless
default_valueis provided or not - refactor(combine_reducers): use
make_immutableinstead ofmake_dataclass - test(view): write tests for
store.view
- feat(core): add
viewmethod toStoreto allow computing a derived value from the state only when it is accessed and caching the result until the relevant parts of the state change - feat(test): add performance tests to check it doesn't timeout in edge cases
- refactor(autorun)!: setting
initial_runoption of autorun toFalseused to make the autorun simply not call the function on initialization, now it makes sure the function is not called until the selector's value actually changes - feat(autorun): add
auto_callandreactiveoptions to autorun to control whether the autorun should call the function automatically when the comparator's value changes and whether it shouldn't automatically call it but yet register a change so that when it is manually called the next time, it will call the function.
- test(middleware): add middleware tests
- refactor(test): add the counter id of the failed snapshot to the error message
- fix: add
unsubscribemethod toAutorunReturnTypeprotocol
- refactor: middleware functions can now return
Noneto cancel an action or event
- feat: introduce
grace_time_in_secondsparameter toStoreto allow a grace period for the store to finish its work before callingcleanupandon_finish
- refactor:
Storeno longer aggregates changes, it now calls listeners with every change - refactor:
SideEffectRunnerThreadnow runs async side effects in the event loop of the thread in which it was instantiated in (it used to create its own event loop) - refactor(test):
event_loopfixture now sets the global event loop on setup and restores it on teardown
- fix: initial snapshot cleanup which used to mistakenly remove files with store:... filenames now removes files with store-... filenames
- chore: changed the format of snapshot filenames from store:... to store-...
- chore(test): move fixtures and testing utilities to
redux-pytestpackage - feat(test): add
wait_for,store_monitor,event_loopandneeds_finishfixtures - test: add tests for scheduler and fixtures
- refactor:
SideEffectRunnerThreadnow runs async side effects in its own event-loop - refactor: removed
immediate_runfrom event subscriptions - refactor: removed
EventSubscriptionOptionsas the only option left waskeep_ref, it's now a parameter ofsubscribe_event - feat: new
on_finishcallback for the store, it runs when all worker threads are joined and resources are freed
- fix: automatically unsubscribe autoruns when the weakref is dead
- fix: use weakref of event handlers in
event_handlers_queue
- refactor: drop logging fixture and use standard pytest logger in tests
- refactor: add cleanup to
FinishEventhandler to clean workers, listeners, subscriptions, autoruns, etc - refactor:
TaskCreatoraddTaskCreatorCallbackprotocols - refactor:
Store._create_tasknow has a callback parameter to report the created task - refactor: move serialization methods and side_effect_runner class to separate files
- fix: serialization class methods of
Storeuseclsinstead ofStorefor the sake of extensibility via inheritance - refactor:
pytest_addoptionmoved totest.pyto make reusable
- test: write tests for different features of the api
- refactor: rename certain names in the api to better reflect their job
- refactor: store_snapshot now puts snapshot files in a hierarchical directory structure based on the test module and test name
- fix: sort JSON keys in
snapshot_store'sjson_snapshot - test: cover most features with tests
- docs: update path of demos migrated to tests in
README.md - refactor: remove
set_customer_serializerin favor of overridableserialize_value
- refactor: move store serializer from test framework to code
Storeclass - feat: add ability to set custom serializer for store snapshots
- refactor: improve creating new state classes in
combine_reducersupon registering/unregistering sub-reducers - feat: add test fixture for snapshot testing the store
- chore(test): add test infrastructure for snapshot testing the store
- test: move demo files to test files and update the to use snapshot fixture
- feat: add
keep_refparameter to subscriptions and autoruns, defaulting toTrue, if set toFalse, the subscription/autorun will not keep a reference to the callback - refacotr: general housekeeping
- fix: autorun now correctly updates its value when the store is updated
- feat: add
__repr__toAutorunclass
- chore: improve github workflow caching
- fix:
self_workersinStore.__init__-> local variableworkers
- chore: GitHub workflow to publish pushes on
mainbranch to PyPI - chore: create GitHub release for main branch in GitHub workflows
- refactor: fix lint issues and typing issues
- refactor: remove
create_storeclosure in favor ofStoreclass with identical api
- feat: all subscriptions/listeners with
keep_ref, now useWeakMethodfor methods
- refactor: no error if an unsubscription function is called multiple times
- feat(combine_reducers): initialization of sub-reducers is done with
CombineReducerInitActioncontaining_idinstead of normalInitAction
- fix:
CombineReducerRegisterActionshould take care ofCompleteReducerResultreturned by the sub-reducer on its initialization.
- feat: new option for all subscriptions to hint them keep a weakref of the callback
- refactor: encapsulate autorun options previously provided as multiple keyword arguments, in a single
AutorunOptionsimmutable class - refactor: rename
immediatetoimmediate_runin autorun subscribers - feat: default value of
immediate_runcan be set for all subscribers of an autorun instance by settingssubscribers_immediate_runoption for the autorun
- feat: add
immediateparameter tosubscribemethod ofautorun's returned value
- feat:
autorundecorator accepts a default value for when store is not initialized - feat:
autorundecorator takes its options in its keyword arguments
- refactor: make
dispatchaccept awith_state(store)function as parameter, if provided it will dispatch return value of this function
- refactor: improve typing of
SideEffectRunnerThread
- feat: allow
subscribe_eventcallback parameter take zero arguments
- feat: make
subscribemethod ofautorun's return value, call its callback with the latest value immediately
- feat: add the latest value of
autorunto thevaluefield of its returned value
- feat: the provided
scheduler, if any, should have aintervalparameter, if set toFalse, it should schedule only once, otherwise it should periodically call thecallback
- feat:
InitializationActionErrorshows the incorrect passed action - refactor: improve typing of autorun's
Comparator
- refactor: improve typehints and allow dispatch to get multiple actions/events via
*args
- feat: autorun now recovers from selector attribute errors = uninitialized store
- docs: explain events in more details in
README.md
- docs: add
README.md
- refactor: remove
payloadand...Payloadclasses fromcombine_reducers
- refactor: actions and events are queued solely via
dispatchfunction, even internally - feat: add
action_middlewareandevent_middlewarefields toCreateStoreOptions
- refactor: add
subscribeproperty to the type of the return value of an autorun decorator
- refactor: use
Immutablefrom python-immutable package (extracted and created based onImmutableclass of this package)
- refactor: propagate new
FinishEventwhenFinishActionis dispatched
- feat: add
scheduleroption to schedule running actions in the main loop of frameworks - feat: add
threadsoption to run event handlers asynchronous inthreadsnumber of threads - refacotr: allow
Anyreturn type for event handler and subscriber functions - feat: add
subscribeproperty to the returned function ofautorun
- feat: allow dispatching events with
dispatchfunction
- refactor: postpone nested dispatches
- feat: drop
typefield in actions and events altogether, recognition is done byisinstance
- fix: loosen
subscribe_eventtyping constraints as python doesn't have enough type narrowing mechanism at the moment
- fix: add
event_typetocombine_reducers
- feat: replace side effects with events, events being immutable passive data structures
- fix: let input reducers of
combine_reducershave arbitrary state types
- fix: let input reducers of
combine_reducershave arbitrary action types irrelevant to each other
- fix: let input reducers of
combine_reducershave arbitrary action types
- chore: split the project into multiple files
- feat: let reducers return actions and side effects along new state
- fix: import
dataclass_transformfromtyping_extensionsinstead oftyping
- feat: introduce
immutabledecorator as a shortcut ofdataclass(kw_only=True, frozen=True) - feat: introduce
Immutableclass, its subclasses automatically becomeimmutable - refactor:
BaseActionnow inherits fromImmutable - refactor: Removed
BaseState, state classes, payload classes, etc should now inheritImmutable
- refactor: make all dataclasses
kw_only=True
- refactor: support previous_result argument, improve typings
- refactor: improve typings
- fix: autorun should re-compute the value if it is expired
- fix: last_comparator_result wasn't being updated
- feat: add cached return value to autorun
- feat: improve typing
- feat: make states and action immutable dataclasses
- feat: implement demo covering autorun, subscription and combining reducers
- feat: implement combine_reducers
- feat: implement autorun
- feat: initial implementation