NexPy — Transitive Synchronization and Shared-State Fusion for Python
NexPy (distributed on PyPI as nexpylib) is a reactive synchronization framework for Python that provides a universal mechanism for maintaining coherent shared state across independent objects through Nexus fusion and internal Hook synchronization.

🎯 Core Concept: Inter-Object Synchronization via Nexus Fusion
Unlike traditional reactive frameworks that propagate changes through dependency graphs, NexPy creates fusion domains where multiple hooks share a single Nexus—a centralized synchronization core that holds and propagates state.
What is a Nexus?
A Nexus is a shared synchronization core that represents a fusion domain. Each Hook in NexPy references a Nexus, but does not own it—instead, multiple hooks may share the same Nexus, forming a dynamic network of coherence.
What is Nexus Fusion?
When two hooks are joined, their respective Nexuses undergo a fusion process:
- Original Nexuses are destroyed — Both hooks' previous Nexuses cease to exist
- New unified Nexus is created — A single Nexus is created to hold the shared value
- Both hooks join the same fusion domain — They now share synchronized state
This joining is:
- Symmetric —
A.join(B) is equivalent to B.join(A)
- Transitive — Joining creates equivalence chains across all connected hooks
- Non-directional — There's no "master" or "slave"; all hooks are equal participants
Transitive Synchronization Example
import nexpy as nx
A = nx.Hook(1)
B = nx.Hook(2)
C = nx.Hook(3)
D = nx.Hook(4)
A.join(B)
C.join(D)
B.join(C)
print(A.value, B.value, C.value, D.value)
A.value = 42
print(A.value, B.value, C.value, D.value)
Hook Isolation
A hook can later be isolated, which:
- Removes it from its current fusion domain
- Creates a new, independent Nexus initialized with the hook's current value
- Leaves remaining hooks still joined and synchronized
import nexpy as nx
A = nx.Hook(1)
B = nx.Hook(1)
C = nx.Hook(1)
A.join(B)
B.join(C)
B.isolate()
A.value = 10
print(A.value, B.value, C.value)
⚛️ Internal Synchronization: Intra-Object Coherence
In addition to global fusion, NexPy maintains atomic internal synchronization among related hooks within a single object through a transaction-like validation and update protocol.
Example: XDictSelect — Multi-Hook Atomic Synchronization
XDictSelect exposes 5 synchronized hooks: dict, keys, values, key, and value.
import nexpy as nx
select = nx.XDictSelect({"a": 1, "b": 2, "c": 3}, key="a")
print(select.dict_hook.value)
print(select.key_hook.value)
print(select.value_hook.value)
select.key = "b"
print(select.value)
select.value = 20
print(select.dict)
The Internal Synchronization Protocol
When one hook changes (e.g., key), NexPy:
- Determines affected Nexuses — Which related Nexuses must update (e.g.,
value, dict)
- Readiness check (validation pre-step) — Queries each affected Nexus via validation callbacks
- Atomic update — If all Nexuses report readiness, applies all updates in one transaction
- Rejection — Otherwise rejects the change to maintain global validity
This ensures the system is:
- Atomic — All updates occur together or not at all
- Consistent — Constraints are always satisfied
- Isolated — Concurrent modifications are safely locked
- Durable (logical) — Once accepted, coherence persists until the next explicit change
NexPy guarantees continuous validity both within objects (internal sync) and across objects (Nexus fusion).
🚀 Quick Start
Installation
pip install nexpylib
Basic Usage
1. Simple Reactive Value
import nexpy as nx
value = nx.XValue(42)
print(value.value)
value.value = 100
print(value.value)
def on_change():
print(f"Value changed to: {value.value}")
value.value_hook.add_listener(on_change)
value.value = 200
2. Hook Fusion Across Independent Objects
import nexpy as nx
temperature_sensor = nx.XValue(20.0)
display_value = nx.XValue(0.0)
temperature_sensor.value_hook.join(display_value.value_hook)
print(temperature_sensor.value, display_value.value)
temperature_sensor.value = 25.5
print(display_value.value)
3. Reactive Collections
import nexpy as nx
numbers = nx.XList([1, 2, 3])
numbers.list_hook.add_listener(lambda: print(f"List changed: {numbers.list}"))
numbers.append(4)
tags = nx.XSet({"python", "reactive"})
tags.add("framework")
print(tags.set)
config = nx.XDict({"debug": False, "version": "1.0"})
config["debug"] = True
print(config.dict)
4. Selection Objects with Internal Synchronization
import nexpy as nx
options = nx.XDictSelect(
{"low": 1, "medium": 5, "high": 10},
key="medium"
)
print(options.key)
print(options.value)
options.key = "high"
print(options.value)
options.value = 15
print(options.dict)
5. Adapter Objects for Type Bridging
import nexpy as nx
optional_adapter = nx.XOptionalAdapter[int](
hook_t_or_value=42,
hook_optional=None
)
print(optional_adapter.hook_t.value)
print(optional_adapter.hook_optional.value)
optional_adapter.hook_t.value = 100
print(optional_adapter.hook_optional.value)
set_seq_adapter = nx.XSetSequenceAdapter[int](
hook_set_or_value={3, 1, 2},
hook_sequence=None,
sort_callable=lambda s: list(reversed(sorted(s)))
)
print(set_seq_adapter.hook_set.value)
print(set_seq_adapter.hook_sequence.value)
6. Configuring Floating-Point Tolerance
import nexpy as nx
from nexpy import default
default.FLOAT_ACCURACY = 1e-6
temperature = nx.XValue(20.0)
temperature.value = 20.0000001
temperature.value = 20.001
📚 Key Features
🔗 Transitive Hook Fusion
- Join any hooks to create fusion domains
- Transitive synchronization:
A→B + B→C = A→B→C
- Symmetric and non-directional connections
- Isolate hooks to break fusion domains
⚛️ Atomic Internal Synchronization
- ACID-like guarantees for multi-hook objects
- Transaction-style validation and updates
- Automatic constraint maintenance
- Continuous validity enforcement
🔄 Reactive Collections
XList — Reactive lists with element access
XSet — Reactive sets with membership tracking
XDict — Reactive dictionaries with key-value pairs
- Full Python collection protocol support
🎯 Selection Objects
XDictSelect — Select key-value pairs from dicts
XSetSingleSelect — Select single elements from sets
XSetMultiSelect — Multiple selection support
- Optional selection variants (allow
None selection)
🔄 Adapter Objects
XOptionalAdapter — Bridge between T and Optional[T] (blocks None)
XIntFloatAdapter — Bridge between int and float (validates integer-valued floats)
XSetSequenceAdapter — Bridge between AbstractSet and Sequence (validates unique elements)
- Custom sorting control for set-to-sequence conversion
- Type-safe bridging between incompatible hook types
🔒 Thread-Safe by Design
- All operations protected by reentrant locks
- Safe concurrent access from multiple threads
- Reentrancy protection against recursive modifications
- Independent nested submissions allowed
🎭 Multiple Notification Philosophies
- Listeners (Synchronous) — Direct callbacks during updates
- Publish-Subscribe (Asynchronous) — Decoupled async notifications
- Hooks (Bidirectional Validation) — Enforce constraints across objects
🎯 Custom Equality Checks
- Built-in floating-point tolerance (configurable via
default.FLOAT_ACCURACY)
- Standard practice: 1e-9 tolerance to avoid spurious updates
- Cross-type comparison support (e.g.,
float vs int)
- Register custom equality callbacks for specialized types at the NexusManager level
📖 Documentation
🏗️ Architecture Overview
┌─────────────────────────────────────────────────────────────┐
│ User Objects │
│ ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────┐ │
│ │ XValue │ │ XDict │ │ XList │ │ XSet │ │
│ └────┬─────┘ └────┬─────┘ └────┬─────┘ └────┬─────┘ │
└───────┼─────────────┼─────────────┼─────────────┼──────────┘
│ │ │ │
└─────────────┴─────────────┴─────────────┘
│
┌─────────────────┴─────────────────┐
│ Hook Layer │
│ (Owned Hooks + Floating Hooks) │
└─────────────────┬─────────────────┘
│
┌─────────────────┴─────────────────┐
│ Nexus Layer │
│ (Fusion Domains + Shared State) │
└─────────────────┬─────────────────┘
│
┌─────────────────┴─────────────────┐
│ NexusManager │
│ (Coordination + Validation) │
└───────────────────────────────────┘
Key Components:
- Hooks — Connection points that reference Nexuses
- Nexus — Shared synchronization core for fusion domains
- NexusManager — Central coordinator for validation and updates
- X Objects — High-level reactive data structures
🎓 Use Cases
1. GUI Data Binding
import nexpy as nx
user_name = nx.XValue("Alice")
class TextWidget:
def __init__(self, hook):
self.hook = hook
hook.add_listener(self.refresh)
def refresh(self):
print(f"Display: {self.hook.value}")
widget = TextWidget(user_name.value_hook)
user_name.value = "Bob"
2. Configuration Synchronization
import nexpy as nx
app_config = nx.XDict({"theme": "dark", "lang": "en"})
cache_config = nx.XDict({})
cache_config.dict_hook.join(app_config.dict_hook)
app_config["theme"] = "light"
print(cache_config["theme"])
3. State Machines with Atomic Transitions
import nexpy as nx
states = {"idle", "running", "paused", "stopped"}
current = nx.XDictSelect(
{state: state for state in states},
key="idle"
)
def validate_transition(values):
if values["key"] == "running" and some_condition:
return False, "Cannot transition to running"
return True, "Valid"
try:
current.key = "running"
except ValueError as e:
print(f"Transition rejected: {e}")
🤝 Contributing
Contributions are welcome! Please see our Contributing Guide for details.
Development Setup
git clone https://github.com/babrandes/nexpylib.git
cd nexpylib
pip install -e .
python -m pytest tests/
📄 License
This project is licensed under the Apache License 2.0 — see the LICENSE file for details.
🔗 Links
🎯 Changelog
See CHANGELOG.md for a list of changes between versions.
⭐ Star History
If you find NexPy useful, please consider starring the repository on GitHub!
Built with ❤️ by Benedikt Axel Brandes