-
-
Notifications
You must be signed in to change notification settings - Fork 2.1k
Issue 1010 - Non-rendered async components using asyncDecorator
lock renderer callbacks
#1027
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
Changes from 1 commit
f5e577e
6e9f11b
2ead779
11b8877
340aa26
324d8d6
bd02bff
50f3e58
0e2c54a
796db0c
c0aaab2
73ce153
7a68d13
39a6915
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,87 +1,43 @@ | ||
import {filter} from 'ramda'; | ||
import {createAction} from 'redux-actions'; | ||
import { path } from 'ramda'; | ||
import { createAction } from 'redux-actions'; | ||
|
||
import isSimpleComponent from '../isSimpleComponent'; | ||
import Registry from './../registry'; | ||
import {getAction} from './constants'; | ||
import {isReady} from '@plotly/dash-component-plugins'; | ||
import { getAction } from './constants'; | ||
import { isReady } from '@plotly/dash-component-plugins'; | ||
|
||
const isAppReady = layout => { | ||
const queue = [layout]; | ||
|
||
const components = {}; | ||
const ids = {}; | ||
|
||
/* Would be much simpler if the Registry was aware of what it contained... */ | ||
while (queue.length) { | ||
const elementLayout = queue.shift(); | ||
if (!elementLayout) { | ||
continue; | ||
} | ||
|
||
const id = elementLayout.props && elementLayout.props.id; | ||
const children = elementLayout.props && elementLayout.props.children; | ||
const namespace = elementLayout.namespace; | ||
const type = elementLayout.type; | ||
|
||
components[namespace] = components[namespace] || {}; | ||
components[namespace][type] = type; | ||
const isAppReady = (layout, paths) => targets => { | ||
if (!layout || !paths || !Array.isArray(targets)) { | ||
return true; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Is there a use case for this? Feels like an error rather than a silent success. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Relates to the comment below. Refactoring to take |
||
} | ||
|
||
if (id) { | ||
ids[id] = {namespace, type}; | ||
const promises = []; | ||
targets.forEach(id => { | ||
const pathOfId = paths[id]; | ||
if (!pathOfId) { | ||
return; | ||
} | ||
|
||
if (children) { | ||
const filteredChildren = filter( | ||
child => !isSimpleComponent(child), | ||
Array.isArray(children) ? children : [children] | ||
); | ||
|
||
queue.push(...filteredChildren); | ||
const target = path(pathOfId, layout); | ||
if (!target) { | ||
return; | ||
} | ||
} | ||
|
||
return targets => { | ||
const promises = []; | ||
|
||
if (Array.isArray(targets)) { | ||
targets.forEach(id => { | ||
const target = ids[id]; | ||
if (target) { | ||
const component = Registry.resolve(target); | ||
|
||
const ready = isReady(component); | ||
|
||
if (ready && typeof ready.then === 'function') { | ||
promises.push(ready); | ||
} | ||
} | ||
}); | ||
} else { | ||
Object.entries(components).forEach(([namespace, item]) => { | ||
Object.entries(item).forEach(([type]) => { | ||
const component = Registry.resolve({ | ||
namespace, | ||
type, | ||
}); | ||
|
||
const ready = isReady(component); | ||
const component = Registry.resolve(target); | ||
const ready = isReady(component); | ||
|
||
if (ready && typeof ready.then === 'function') { | ||
promises.push(ready); | ||
} | ||
}); | ||
}); | ||
if (ready && typeof ready.then === 'function') { | ||
promises.push(ready); | ||
} | ||
}); | ||
|
||
return promises.length ? Promise.all(promises) : true; | ||
}; | ||
return promises.length ? Promise.all(promises) : true; | ||
}; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Change |
||
|
||
const setAction = createAction(getAction('SET_APP_READY')); | ||
|
||
export default () => async (dispatch, getState) => { | ||
const ready = isAppReady(getState().layout); | ||
const { layout, paths } = getState(); | ||
const ready = isAppReady(layout, paths); | ||
|
||
dispatch(setAction(ready)); | ||
}; |
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.
As long as we get the order of operations right (ie always updating
isAppReady
after any update tolayout
orpaths
) this should be fine, but it would be more robust and simpler - without any cost anymore - to not put this in the state at all.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.
ie to just make it a function
(layout, paths, targets) => {...}
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.
exactly the problem making the tests fail, the store evals
IS_APP_READY
beforeCOMPUTE_PATH
and the first calls ends up not blocking