-
-
Notifications
You must be signed in to change notification settings - Fork 23
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Refactor javascript statesystem #4530
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good in general, a fewer smaller nitpicks here and there.
I have two (larger) questions:
- (This is also a comment somewhere) Do we need the legacy decorator mode, or could we switch to TypeScript 5, which should implement the modern decorators.
- A double take to ensure we have not copied any code from
LitState
(https://www.npmjs.com/package/lit-element-state), as that library is LGPL3, which is annoying at best.
app/assets/javascripts/components/annotations/annotations_cell.ts
Outdated
Show resolved
Hide resolved
On Typescript: The cause of the decorator issue is ts-jest. See kulshekhar/ts-jest#1155
I think the solution here would using only jest (not ts-jest), with babel compilation. Moving to typescript 5 is also not possible. Because of ts-jest/lit. The types provided by lit still match the old typescript decorator types, which do not match with the new typescript definition. This causes ts-jest to throw errors... |
|
On copying code from litState: I think right now we have deviated enough of the original implementation to avoid any copyright infringements. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nice job! I prefer this style over the previous one. It is much clearer that you are calling state functions now in the component classes.
This pull request refactors the javascript state system.
After reviewing multiple existing state systems in #4456, I decided litState and @lit-app/state where the most promising.
But while working with it, I found the typescript support of
litState
to be lacking, while@lit-app/state
has great typescript support but lacks the concept of aStateRecorder
thatlitState
has which helps avoiding a lot of boilerplate code.Thus I decided to write a custom system that combines both of the above. It consists of the following components:
State
a class that inherits fromEventTarget
. It can be subscribed to and will dispatch an event to all subscribers when any of its properties change. It also record every read of it's properties to the stateRecorder. All credits to @lit-app/state for the idea to useEventTarget
to avoid reinventing an event system.stateProperty
a decorator used for properties in theState
class. This decorator overwrites the get and set methods to make sure events get dispatched. Thanks tolit
for giving me examples of decorators that support both the babel and the typescript definition.stateRecorder
instance. A global instance that records every property of a state that gets read between it's start and finish. Credits to litState.StateController
a ReactiveController that uses thestateRecorder
to track all stateProperties that are read during a render cycle. It then subscribes to the relevant states to trigger an update of its host every time one of those stateProperties changes. Thanks to @lit-app/state for introducing me to controllers for this usecase Reactive controllersStateEvent
a custom event that signifies state changes. Credits @lit-app/stateStateMap
extendsState
and implementMap
. It notifies subscribers of key changes as if it where stateProperties.I used this new system to refactor all state systems that I introduced over the past year. This includes the combination of PubSub and the statemixin, SearchQuery and SorrQuery, which all had their own kind of subscription system.
Closes #4456.