Support @provide with experimental decorators on a property#4200
Conversation
It might feel like this is working at cross purposes to our standard decorators work, because those all require accessors, but I don't think so. With standard decorators we can use the type system to error out if they're used on a property instead of an accessor. With experimental decorators, they sorta work with properties, in that they do provide values and update them, but reading the value back off the field would always give undefined because we were defining it without a getter.
🦋 Changeset detectedLatest commit: 545e76c The changes in this PR will be included in the next version bump. This PR includes changesets to release 1 package
Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
📊 Tachometer Benchmark ResultsSummarynop-update
render
update
update-reflect
Resultsthis-change
render
update
update-reflect
this-change, tip-of-tree, previous-release
render
update
nop-update
this-change, tip-of-tree, previous-release
render
update
this-change, tip-of-tree, previous-release
render
update
update-reflect
|
|
The size of lit-html.js and lit-core.min.js are as expected. |
| assert.strictEqual(consumer.value, 500); | ||
| assert.strictEqual(consumer2.value, 1000); // one-time consumer still has old value | ||
| }); | ||
|
|
There was a problem hiding this comment.
I'm getting pretty confused where the tests go in the package these days. This suite didn't previously use any of the context decorators, and the thing you're testing isn't that providers and consumers work, but that the decorator works. This came up for me when I made the std-decorators tests too.
Could we make a decorators-specific test folder?
| }; | ||
| let newDescriptor; | ||
| if (descriptor === undefined) { | ||
| const symbol = Symbol(); |
There was a problem hiding this comment.
Use a more descriptive name like storage or key? Also, Russell added a nice dev-mode switch to @query() where there was a string description for the Symbol like @provide() storage key for ${nameOrContext} for debugging.
There was a problem hiding this comment.
Switched to a WeakMap for consistency in this file
| if (oldSetter) { | ||
| oldSetter.call(this, value); | ||
| } |
There was a problem hiding this comment.
| if (oldSetter) { | |
| oldSetter.call(this, value); | |
| } | |
| oldSetter?.call(this, value); |
| this: ReactiveElement & {[symbol]: ValueType}, | ||
| value: ValueType | ||
| ) { | ||
| controllerMap.get(this)?.setValue(value); |
There was a problem hiding this comment.
This element will always be in the map by this point, so I don't think we need to optional chaining.
There was a problem hiding this comment.
Switched to not-null assertion
It might feel like this is working at cross purposes to our standard decorators work, because those all require accessors, but I don't think so. With standard decorators we can use the type system to error out if they're used on a property instead of an accessor. With experimental decorators, they sorta work with properties, in that they do provide values and update them, but reading the value back off the field would always give undefined because we were defining it without a getter.