-
-
Notifications
You must be signed in to change notification settings - Fork 1.9k
ZERO circular dependency #2429
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
ZERO circular dependency #2429
Conversation
... so that its attributes are added to the schema
free of circular deps.
- no need to have a separate method just for the top-level method.
... by using utilizing component-to-schema logic,
instead of punching the error bar attributes into
the trace declarations.
... so that down the road errorbars could be taken out
or src/core.js, and be its own registrable module.
- export api methods in plot_api/index.js - expose and register them in src/core.js
|
Anything that makes bundling easier, faster, smaller :) |
src/plots/plots.js
Outdated
| var Lib = require('../lib'); | ||
| var _ = Lib._; | ||
| var Color = require('../components/color'); | ||
| var Grid = require('../components/grid'); |
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.
Do you want to go the last inch here and turn Grid.method into Registry.getComponentMethod? Then grid becomes an optional component, right?
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.
done in -> 9246fda
test/jasmine/tests/register_test.js
Outdated
| }, 'degauss')).toEqual([]); | ||
| }); | ||
|
|
||
| it('returns an empty array if none present', function() { |
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.
test case description copied from above
But also, if you leave these un-nested, the descriptions should reference the method being tested.
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.
done in e05f4f0
test/jasmine/tests/register_test.js
Outdated
|
|
||
| beforeAll(function() { | ||
| Registry.register(fakeModule); | ||
| }); |
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.
do we need to remove this in afterAll (here and in the next suite), as we do in the suite above?
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.
Good catch. Fixed in e05f4f0
| */ | ||
| exports.call = function(name, args) { | ||
| return exports.apiMethodRegistry[name].apply(null, args); | ||
| }; |
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.
Can we get rid of the array wrapping the args, like other call methods (d3.select().call and native function.call)? Borrowing from d3 and condensing, seems like it would just be:
return exports.apiMethodRegistry[name].apply(null, [].slice.call(arguments, 1));
or, perhaps marginally faster if we don't care about this being the method name:
return exports.apiMethodRegistry[name].apply([].slice.call(arguments));
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.
That's what I was going to do until I saw this block (called from updatemenus and silders) where the argument list is built as an array.
I think I would prefer keeping this pattern. I could rename Registry.call -> Registry.apply to avoid confusion on the call signature if you prefer.
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.
Ah right, that's the one place you use Registry.call without brackets, and it would be awkward to try and fit that into the call pattern. It's a shame that this one call adds cruft to the hundred other ones though. What about creating both Registry.call and Registry.apply methods? Or, since at least for now that's the only place we'd use Registry.apply, just inlining it there:
return Registry.apiMethodRegistry[method].apply(null, allArgs).catch(...
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.
Done in 705aed6 🚀
tasks/test_syntax.js
Outdated
| if(circularDeps.length) { | ||
| console.log(circularDeps.join('\n')); | ||
| logs.push('some new circular dependencies were added to src/'); | ||
| logs.push('some circular dependencies were found to src/'); |
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.
found in src/
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.
Good 👁️ done in d27b3ba
|
@etpinard this is brilliant. Beautiful. Heroic even. Amazing that even with the extra machinery it's a net decrease in LOC. Just a few comments, the only substantive one being the Love it. End of an era. |
- move all spec under top-level describe(), so that they can easily reuse the 'unregister' wrapper, - fixup spec naming
... everywhere except for plots/command.js where
and fn.apply would work better, for now just
grab api method for registry cache.
... and 'enforce' Registry in components/modebar/
(like for all components really).
|
A couple more things I want to add:
|
|
|
||
| return new Promise(function(resolve, reject) { | ||
| Registry.call('plot', [clonedGd, data, layoutImage, configImage]) | ||
| plotApi.plot(clonedGd, data, layoutImage, configImage) |
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.
just curious, why did you choose not to use Registry here?
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.
Plotly.toImage shouldn't be in a circular dep with the other Plotly methods. Plotly.toImage should call Plotly.plot but never the other way around.
Ideally, I think the api method registry should only be used in components/ and in the subplot modules (for interaction updates). Plotly methods need to call component methods (e.g .draw) and some components need to call Plotly methods (e.g. updatemenus / mode bar button click) - this is circular, hence the need for an api method registry.
|
💃 💃 💃 |
resolves #236 and closes milestone/9.
I started working on this PR when I noticed that the new layout
gridmodule from #2399 has a circular dependency:This went unnoticed because some other PR(s) removed one or two circular dependencies. On master we now have:
whereas our
test-syntaxscript was happy with 16 or less.So after fixing the
gridcircular dep (that's in commit bee37dd), I tried to see what it would take to 🔪 all circular dependencies. In brief, we had:errorbarsas a component and useRegistry.getComponentMethodwhen needed (commit 87275af),Plotly[method]functions) as first proposed in the last serious attempt Eliminate circular dependencies #2032 (comment)and to my surprise this worked as a charm 🍀 🍾 🎉
Looking forward, removing these circular deps isn't just nice, it should allow us to trim our bundle size using
browser-pack-flator eventinyify. Preliminary attempts were positive: I think we'll be able to trim tens of kBs out of our bundles. I'll open up a new PR for this soon. Moreover, there were reports of some dev tools (the new FF ones I think) balking on our source code, this might help.@alexcjohnson @nicolaskruchten hopefully you'll enjoy this. 😛