-
Notifications
You must be signed in to change notification settings - Fork 15
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 x-element mixins. #23
Conversation
d684e63
to
b27d5b3
Compare
Great summary; might be nice to actually roll this into an artifact in the repository like |
@klebba @charricknflx @codeStryke , I would love to get some feedback from you guys when you have a chance. This is a pretty big change to how |
Caught something while fiddling -- we should probably throw a warning if you declare an observer that points to a non-existent function |
I believe we do this... no? It should dispatch an error event. I was just following that pattern we've had which is throw an event so that integrators can choose to do something with it or not. Otherwise, we set ourselves up to just be console spammers. |
Note: reflection should happen before observation. |
Should we resolve functions at runtime? Then we can compute a class-level function which can be cached for each class? |
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.
How about the case where:
const el = document.createElement('x-foo');
el.propA = 'value';
console.log(el.propB);
Where propB
is computed with propA
as input
etc/topological-sort.js
Outdated
@@ -0,0 +1,68 @@ | |||
function makeGraphLoop(vertex, mapping, edges, vertices) { |
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.
Nit: can we organize this file into a collection of static methods on a class and then export that class
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.
sure, i'm indifferent, but I'll update this file according to the comments here.
@klebba , I don't think we'll easily be able to support this use-case and support the guidelines provided to us by WHATWG. It clearly states that you are not allowed to inspect attributes or children during construction. That means that we cannot fully initialize our properties since they may be coming from attributes. And, if we cannot initialize our properties, we cannot perform computations. Now, the following will just work:
I.e., you can do initialization of properties this way, but you cannot find computed results yet. |
I did some corner case testing of the topological sort implementation and found that
will return
The vertex Just putting it here for information, it may not be a real world problem. |
Also an idea for the topological sort, can we mention/describe the algorithm we are using, for example https://en.wikipedia.org/wiki/Topological_sorting#Algorithms |
Good point. This may convolute the design, but I do think we can compute properties in the constructor as long as we later apply the attribute values on attachment. |
I found an issue (I think) where a computed property is called several more times than I would expect. The offending calls all have the same inputs; any idea what would cause this? |
Ah, thanks @codeStryke! I hadn't thought of that case. I think that won't happen, but we may as well guard against it 👍. EDIT: on second thought, this shouldn't happen, so instead of checking for a condition that should never occur, I'm just going to leave a comment. |
How would you handle computing something if you cannot initialize the value though? I.e., if we should not introspect attributes, we cannot be sure that our values have been initialized and our computations are correct. Right? |
@codeStryke , I based my algorithm off of an implementation in another language. I think I'll re-write with language closer to Kahn's algorithm to improve grok-ability for reviewers. Thanks for the nudge! I was implementing DFS, but I think implementing Kahn's algorithm might end up being easier to follow now that I'm revisiting. |
b27d5b3
to
79e1554
Compare
@klebba I'll look into this next time I have a moment to spend on this PR 👍 |
79e1554
to
78e4b3d
Compare
## Properties | ||
|
||
The properties block allows you to define the following: | ||
|
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.
Clarify which properties do / don't work with each other?
can i have a "computed" property with a "value" property?
@klebba I added a very specific test for this and am not seeing this behavior, let's sync up when I get this next revision through and see if we can get a reproducible test case. |
78e4b3d
to
ea3993f
Compare
ea3993f
to
19a1def
Compare
// schedule microtask, which runs before requestAnimationFrame | ||
// https://jakearchibald.com/2015/tasks-microtasks-queues-and-schedules/ | ||
this[symbol] = await false; | ||
this.render(); | ||
if ((await true) && this[DIRTY]) { |
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.
This might warrant additional comment. In particular, we use this because we synchronously call render
in the initialization phase and want to prevent unnecessary, duplicate rendering on initialization.
Changes:
Non-changes:
*functionally this is the case, I've uncovered some previously-silenced errors though.
†note that reflection happens before observation as a result of this change.
Notes:
Mixin hierarchy
element-mixin
: Provides base functionality.properties-mixin
: Allows you to declare theproperties
block.property-effects-mixin
: Allows you to declare effects that should happen when a property changes.lit-html-mixin
: Chooseslit-html
as our templating engine.It's currently the case that you can omit mixins from the tail, but things will break down if you choose to omit something from the middle/head. I.e., you cannot have
property-effects-mixin
withoutproperties-mixin
, but the other way around is OK.Custom element conformance
Whatwg has a nice list of things which a custom element should conform to.
Polymer 3.0 behavior
We loosely conform to the behavior of Polymer since there is considerable road time on that interface. In general, we aim to provide some minimum subset of the behaviors found in that project. Here are a couple places where we still diverge:
type
is just used for serialization/deserialization)Importantly, the following order of operations for initialization is meant to match:
Then, for each subsequent property change:
Handling dependency graphs
Consider the following properties:
The graph looks like this:
Previously, we were recursively walking the dependencies until some terminal condition was met. This change solves the graph up front so that future property-set operations are more deterministic.
Because our dependencies are really a directed, acyclic graph (DAG), the topological sorting algorithm will provide us with one (of many!) possible orders in which to traverse the edges of the graph. This allows us to move the burden of computed properties from set-time to setup-time.
For completeness, the solution to this graph is
[a, b, c]
. That means that ifa
changes, you need to then updateb
and then updatec
, in that order.Vernacular
The following terms are thrown around in the code:
setup
: This is construction-time work.initialization
: This happens during the firstconnectedCallback
.analysis
: This is property-centric and is a static analysis done as prerequisite for property initialization