This PR addresses several key issues and improvements in the propagation and isolation of state across contexts, ensuring correct behavior with shared and isolated data. Additionally, it refines the handling of native classes, improves event firing consistency, and strengthens the test cases.
TL;DR;
Fix propagation of state across deep child contexts
Disallow proxying Maps, Sets, and other native classes
Add more robust isolation mechanism for isolated state and shared state
Ensure only one event is fired per context per change (there was a bug that would cause all context dispatches to flow up to the parent context, leading to a single change causing multiple events to fire on the parent context)
Improve tests, add new test cases, etc...
Ensure shared state can be properly modified and deleted (it better matches expectations, but can cause issues so I'd love your opinions on this, unintentionally fixes #50)
High-Level Changes:
Fix state propagation across deep child contexts: Ensures proper propagation and isolation of state across multiple levels of contexts.
Disallow proxying of Map and Set objects: Avoids potential issues by directly handling native collections without unnecessary proxy interference.
Refine isolation mechanism for state: Improves the system for isolating properties within child contexts, preventing unintended changes to parent or sibling contexts.
Ensure only one event is fired per context change: Fixes a bug that caused multiple event dispatches for a single change, particularly when state bubbled up to parent contexts.
Enhance and add tests: Expands test coverage to include various edge cases and improves the accuracy of existing tests.
Behavioral Changes:
Bidirectional data flow: Shared properties are now accurately propagated between parent and child contexts, but isolated properties are restricted to the context in which they were defined.
Improved event dispatch: Only one event is now fired per context per change, ensuring consistency and reducing unintended side effects.
More predictable state management: Isolated and shared data now behave as expected across deep context hierarchies, preventing cross-context pollution.
Why These Changes Are Necessary:
Without these changes, context propagation across deep hierarchies could fail, leading to inconsistent data between parent and child contexts. For example, modifying shared data in a child context could fail to propagate back to the parent, causing bugs in applications that rely on context sharing. Additionally, the old implementation could trigger multiple events per change, leading to performance issues and unintended behaviors.
Examples of failing use cases before this fix:
Scenario 1: Child context inherits shared data but fails to update it in the parent context.
const parent = new Context({ sharedData: "initial" });
const child = parent.with({});
child.target.sharedData = "updated";
// Before: parent.target.sharedData remains "initial"
// After: parent.target.sharedData is now "updated"
Or
const parent = new Context({ sharedData: "initial" });
const child = parent.with({});
delete child.target.sharedData;
// Before: parent.target.sharedData remains "initial"
// After: parent.target.sharedData is still "initial"
Scenario 2: Multiple event dispatches for a single change.
const context = new Context({ data: "initial" });
context.addEventListener("change", (event) => console.log(event.detail));
context.target.data = "updated";
// Before: Multiple "change" events could fire
// After: Only one "change" event fires
Logic and Details of Changes:
State Propagation and Isolation: The state propagation mechanism has been improved to distinguish between isolated and shared properties. Properties added or modified in child contexts are isolated by default, preventing changes from propagating to parent contexts unless explicitly shared.
Event Dispatch Fix: The event system now ensures only a single event is fired per change, preventing duplicate notifications when state changes bubble up through the context hierarchy.
Example:
context.target.prop = "new value"; // Only one "change" event is dispatched
Proxy Handling for Map, Set, etc.: Direct handling of native collections such as Map and Set has been introduced to avoid proxy-related issues. This ensures that operations on these objects behave as expected without unintended side effects.
Example:
const context = new Context({ mySet: new Set() });
context.target.mySet.add("value"); // No proxy interference
Test Improvements: The test suite has been expanded to cover edge cases related to deep context hierarchies, shared and isolated state, event dispatching, and native class handling. New tests verify the correct propagation of state and ensure that events are dispatched only once per change.
Let me know if you need further details or adjustments!
This PR addresses several key issues and improvements in the propagation and isolation of state across contexts, ensuring correct behavior with shared and isolated data. Additionally, it refines the handling of native classes, improves event firing consistency, and strengthens the test cases.
TL;DR;
High-Level Changes:
Map
andSet
objects: Avoids potential issues by directly handling native collections without unnecessary proxy interference.Behavioral Changes:
Why These Changes Are Necessary:
Without these changes, context propagation across deep hierarchies could fail, leading to inconsistent data between parent and child contexts. For example, modifying shared data in a child context could fail to propagate back to the parent, causing bugs in applications that rely on context sharing. Additionally, the old implementation could trigger multiple events per change, leading to performance issues and unintended behaviors.
Examples of failing use cases before this fix:
Scenario 1: Child context inherits shared data but fails to update it in the parent context.
Or
Scenario 2: Multiple event dispatches for a single change.
Logic and Details of Changes:
State Propagation and Isolation: The state propagation mechanism has been improved to distinguish between isolated and shared properties. Properties added or modified in child contexts are isolated by default, preventing changes from propagating to parent contexts unless explicitly shared.
Event Dispatch Fix: The event system now ensures only a single event is fired per change, preventing duplicate notifications when state changes bubble up through the context hierarchy.
Proxy Handling for
Map
,Set
, etc.: Direct handling of native collections such asMap
andSet
has been introduced to avoid proxy-related issues. This ensures that operations on these objects behave as expected without unintended side effects.Test Improvements: The test suite has been expanded to cover edge cases related to deep context hierarchies, shared and isolated state, event dispatching, and native class handling. New tests verify the correct propagation of state and ensure that events are dispatched only once per change.
Let me know if you need further details or adjustments!