-
Notifications
You must be signed in to change notification settings - Fork 1.8k
Support Iterators/Iterables, Immutable, other inspector improvements #459
Conversation
Flow is failing, could you fix that? |
Yes, forgot to run typecheck. Most of this is fixed in the latest commits, however I'm getting a peculiar failure now:
Running node
|
Running with node |
} | ||
if (typeof obj[Symbol.iterator] === 'function') { | ||
// Convert iterable to array and return array[index] | ||
return [...obj][attr]; |
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.
- Won't there be n^2 complexity? getIn seems to be called in a loop, and we traversing the container every time it's called.
- Will line 25 work with key-value maps, such as decorated records creating properties accessors for its members (so check in line Components displayed as <Unknown ... /> when declaring js variables at the top. #20 will fail)?
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.
-
getIn
was duplicated code moved fro Bridge.js#441 and Agent.js#401 and updated to support iterators. The complexity of the previous implementation hasn't changed (with the exception of spreading the iterable on line 25). -
This does work with key-value maps (if they are iterable) with one caveat, in order to support maps where the key is not a primitive the tool must treat the
[key, value]
entry as an iterable as well resulting in something like this:
myMap: Map(..)
0: [
0: <complex key A>
1: "some value"
]
1: [
0: "string key B"
1: "some other value"
]
...
see Improvement of Keyed iterables/iterators in this comment
I hope I'm making sense here.
Can you use |
Can you rebase please? Sorry for the trouble. I'd like to give this a review. |
Thanks for the Will update and add tests (this may take a day or two for me to get around to it) |
Thanks. Excited about this PR! |
Ping, do you think you'll have time to finish this? |
Yeah, pretty confident I'll have this updated by the end of this weekend! |
Awesome. |
Fixed the conflicts. Looking into using |
objMap: new Map([
[{ a: 'a'}, true],
[{ a: 'a'}, false],
[{ b: 'b'}, [1, 2, 3]],
[{ c: 'c'}, { k1: 'v1', k2: 'v2' }],
]) This looks ok I suppose, but not necessarily the most helpful for dev/debugging since you cannot directly identify the key. However if you are using Objects as keys then presumably you would typically be using other/additional debugging techniques.. |
How does Chrome display this? |
Nice! If you could just add the |
Cool, have this working now, but I'm just investigating/fixing a bug for nested iterables. Will update once I've fix it. |
Hmm.. So nesting keyed entries under I.e. getIn is expected to traverse the 'natural' path, but since we are adding I think either the initial implementation (without |
OK, let's display it in tuples, like you did originally. |
This reverts commit f3c5fe4.
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 is really well written! Thanks for putting this together. I'm really glad it's able to accommodate e.g. Immutable without adding special cases for it.
I'd like to see us limit array & iterable expansion, but it's not a showstopper
if (val && typeof val[Symbol.iterator] === 'function') { | ||
var iterVal = Object.create({}); // flow throws "object literal incompatible with object type" | ||
var count = 0; | ||
for (const entry of val) { |
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 will get fairly unhappy for long lists. Can we bail after ~100 and indicate that there's more we're not showing?
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 can probably be done as a separate diff, I just would rather an extension update not make people's apps suddenly really slow under debugging
agent/dehydrate.js
Outdated
return 'array_buffer'; | ||
} | ||
|
||
var type = typeof data; |
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.
I think I have a slight preference for doing this first, as all of the above checks are only if typeof -> 'object'
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.
Yeah, that's a good point, easily refactored. Will do
if (level > 2) { | ||
return createDehydrated(type, data, cleaned, path); | ||
} | ||
return data.map((item, i) => dehydrate(item, cleaned, path.concat([i]), level + 1)); |
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 would also be nice to limit to e.g. 100, but I'm fine w/ just putting a TODO
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.
Adding a fixed limit seems like a reasonable (but temporary) compromise.
I think the more ideal solution would be to add an optional breadth
argument (defaulting to some small number (20-30) and then adding a show more...
link/button in the interface which would increase the breadth
and inspect+render the next 'page' of items (regardless of whether the inspected object is a iterable, array, map, etc).
I'm happy to update the PR with a hardcoded limit and add a TODO
Sounds good. Will get this done and updated tonight |
Took me a lot longer to get around to this than I would have liked!
Unfortunately I didn't find any simple mechanism to add |
Could you fix lint please? Something minor:
|
Just a heads up: I'm in the middle of some other work but I'll get back to this as soon as I can. Likely within one or two weeks. |
One potentially confusing thing I noticed is it still lets you edit stuff inside the entries (but this won’t work since they’re not real arrays). |
Not going to hold this any longer. 😄 I’ll create a new issue for the followup work. |
Please see #608 for followup items. Let me know if you’d like to work on these! I’d be happy to give you contributor permissions if that would help you move faster. |
Thanks for the merge! I'm definitely up for looking into some of the remaining issues and will follow up on #608. |
Features / Improvements:
<constructor name>(…)
Addresses much of Issue #52 and was inspired by PR #149, particularly @gaearon's comment
Code Change Summary:
getIn(base, path)
to separate file/agent/getIn.js
/agent/dehydrated.js
to improve readability (in addition to enhancements)readOnly
anduninspectable
propteries tometa
for dehydrated values where appropriate/fronted/DataView/DataView.js
DataItem
Component check foruninspectable
when renderingtyped_array, array_buffer, data_view, iterator
cases toPropval.js
andpreviewCoplex.js
in addition to some refactoring for readbilitytest/example
to demonstrate changes.Caveats / For future Improvement
Typed Arrays are set read only in the inspector with these changes - Editing them (in the current released version) would cause them to be converted to objects, but it should be possible to handle this.
Iterators/Iterators are read only for fairly obvious reasons, however it might be reasonable to implement a live-edit feature for built-in iterables (i.e.
Map
,Set
,TypedArray
).Improvement of Keyed iterables/iterators
With these changes the inspector /
DataView
renders entries of iterators as Arrays of[key, value]
arrays i.e.0: Array[2], 1: Array[2], ...
rather thankeyA: <value>, keyB: <value>, ...
.Determining if an iterable is a keyed iterable is tricky because an iterator entry can be of any value. Simply checking that entries are arrays of length
2
is insufficient because a Set of arrays (seetuplesSet
inexample/test/target.js
) would 'break' this approach. In addition ES6Map
andImmutable.Map
allow complex keys and use Same-value-zero equality to determine uniqueness. This means the keys/attribute strings in the inspectorspath
cannot easily be converted to strings through eithertoString
orJSON.stringify
without breaking correctness in some cases.Requesting Feedback & Help for:
Iterables
,Typed Arrays
, etc?Finally
Substantial unit test coverage is on it's way, I just wanted to get some eyeballs on this first!