{count.value}
+ +``` + +### Compiler Enhancements + +The LWC compiler will be updated to recognize when a Signal's `.value` is used within a template. Instead of accessing the property directly at runtime, it will generate code to subscribe to the Signal's changes during component's template initialization and unsubscribe upon component's template disposal. + +### Store Protocol + +A store must implement the following protocol to be compatible with the new reactivity model: + +```ts +class Store { + get value(): any { /* return current value */ } + subscribe((newValue: any) => void): () => void { /* subscribe to changes */ } +} +``` + +__NOTE:__ _We can work the details of this protocol. It could be more simple, or hopefully similar to what is out there._ + +### Integration with Components + +Components should treat signals as internal reactive state mechanisms. While a signal can technically be passed down to child components, it's recommended to pass only the necessary data, typically the `.value` of the signal, to keep the child components decoupled from the parent's state management strategy. + +Here’s how a parent component would pass the current value of a signal to a child component, which expects a number: + +```javascript +// ParentComponent.js +import { signal } from 'some/signals'; + +export default class ParentComponent extends LightningElement { + count = signal(0); +} +``` + +```html + + + +{currentRecord.value.Name}
+ +``` + +__Note:__ if the currentRecord's value is not available yet, it might require some additional logic to handle that case. This is similar to what developers have to do today when using `@wire`. + +### LWC Internals + +LWC will NOT provide a built-in store implementation. Instead, it relies on a well defined protocol to interpret data in templates. This will allow developers to bring their own stores and integrate them with LWC components. It is very likely that LDS implements its own flavor of signals to work with LWC but the purpose of this RFC is to define the protocol, not the implementation. + +## Backward Compatibility + +There are two main concerns with backward compatibility: + +1. A component receiving an object from a parent component that contains a `value` getter and a `subscribe` method. If the object is considered a POJO by our current test, then LWC would incorrectly avoid wrapping the object with a read-only reactive process. This is a minor concern, but it is something to consider. +2. A template using `x.value` as part of an interpolation where the value of `x` is not a signal, but contains a `value` getter and a `subscribe` method. In this case, the compiled code would attempt to call `subscribe`, if it fails, we can swallow the error and show a warning. In terms of functionality, everything remains the same, the `.value` is used to render the value into the DOM, and if it is reactive it will be updated automatically by triggering the re-rendering, which would call the `.value` getter again. Technically, this is not a non-backward compabitibility issue since we can swallow the error. But it is something to consider. + +## Drawbacks + +### Increased Complexity for Developers + +* __Explicit Reactivity Management__: The shift from `@track`'s implicit reactivity to explicit signals and stores introduces additional complexity. For thos developers that are still using `@track`, they must now manage subscriptions and updates more directly, which could increase the cognitive load, compared to the simplicity of `@track`. +* __Learning Curve__: There's an inherent learning curve as developers familiarize themselves with the new patterns of Signals and stores, particularly around the nuances of updates to `.value` instead of changing deep properties. + +### Framework Compatibility Concerns + +* __Integration with Existing Libraries__: While the goal is to enable the use of any store that follows the Signal protocol, real-world usage may reveal compatibility issues, necessitating additional wrapper or adapter code. As of today, there are a number of popular Signal-like libraries out there, and we should make sure that we can integrate with them. + +## Alternatives + +### 1. Adoption of Other Reactivity Models + +Other frameworks' reactivity models, such as starbeam, Vue's reactivity system or Svelte's store contracts, could be considered. Each comes with its own set of trade-offs and would require significant adaptation to align with LWC's architecture and principles. + +### Enhanced Compiler Optimizations + +Enhancements to the LWC compiler could potentially abstract away some of the verbosity and complexity of managing reactive states. This solution would still necessitate a shift in developer practices but could minimize the learning curve and migration effort. + +### Framework-Agnostic State Management Libraries + +Leveraging existing state management libraries, like Redux or MobX, could be an option. These libraries offer mature ecosystems and patterns but would require integration work to behave reactively within the LWC component lifecycle. + +## Adoption Strategy + +Most of this section is really about how LDS and others would adopt this new technology. A gradual, phased approach is recommended to transition to the new reactivity model. This allows developers to adopt the changes incrementally and provides the framework maintainers with feedback loops to adjust the strategy as needed. Release comprehensive guides and examples showcasing the new model's benefits and usage. + +## Security Considerations + +Minor security consideration. Changing a property of a value from a store has no implications for other components with access to the same store, because the change is not going to trigger rehydration of templates, e.g.: `{currentRecord.value.x}` in a template, while someone else with access to the same record can do `currentRecord.value.x++`. In this case, LWC would not pick up the change, and update the UI, as described above, but anyone using the currentRecord in another turn, is subject to the incremented value. This is not such a big risk, but it is something to consider. The responsability shifts to the store developer to protect against others trying to make changes to it. LDS is doing some of that already, but the fact that components are accessing the `.value` directly, makes it more difficult to prevent someone from changing the object that eventually someone else would rely on, unless a new value is emitted. Since LWC is not in control, there is no much we can do to help in this area. + +## Open Discussion Topics + +* The signal/store protocol. Except for the `.value`, which seems to be a requirement, the rest of the protocol is open for discussion. +* The test to determine when an object is a signal during runtime is tricky, we should discuss that in details.