Skip to content

Commit

Permalink
Add async support
Browse files Browse the repository at this point in the history
  • Loading branch information
Marc-Andre-Rivet committed Oct 21, 2019
1 parent e959481 commit b31c447
Show file tree
Hide file tree
Showing 32 changed files with 670 additions and 114 deletions.
4 changes: 2 additions & 2 deletions .circleci/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,7 @@ jobs:
command: |
. venv/bin/activate && pip install --no-cache-dir --upgrade -e . --progress-bar off && mkdir packages
cd dash-renderer && renderer build && python setup.py sdist && mv dist/* ../packages/ && cd ..
git clone --depth 1 https://github.com/plotly/dash-core-components.git
git clone --depth 1 -b exp-dynamic-2 https://github.com/plotly/dash-core-components.git
cd dash-core-components && npm install --ignore-scripts && npm run build && python setup.py sdist && mv dist/* ../packages/ && cd ..
git clone --depth 1 https://github.com/plotly/dash-renderer-test-components
cd dash-renderer-test-components && npm install --ignore-scripts && npm run build:all && python setup.py sdist && mv dist/* ../packages/ && cd ..
Expand Down Expand Up @@ -159,7 +159,7 @@ jobs:
name: ️️🏗️ build misc
command: |
. venv/bin/activate && pip install --no-cache-dir --upgrade -e . --progress-bar off && mkdir packages
git clone --depth 1 https://github.com/plotly/dash-table.git
git clone --depth 1 -b exp-dynamic https://github.com/plotly/dash-table.git
cd dash-table && npm install --ignore-scripts && npm run build && python setup.py sdist && mv dist/* ../packages/ && cd ..
git clone --depth 1 https://github.com/plotly/dash-html-components.git
cd dash-html-components && npm install --ignore-scripts && npm run build && python setup.py sdist && mv dist/* ../packages/ && cd ..
Expand Down
21 changes: 21 additions & 0 deletions @plotly/dash-component-plugins/LICENSE
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
MIT License

Copyright (c) 2019 Plotly

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
16 changes: 16 additions & 0 deletions @plotly/dash-component-plugins/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
{
"name": "@plotly/dash-component-plugins",
"version": "1.0.1",
"description": "Plugins for Dash Components",
"repository": {
"type": "git",
"url": "git@github.com:plotly/dash.git"
},
"bugs": {
"url": "https://github.com/plotly/dash/issues"
},
"homepage": "https://github.com/plotly/dash",
"main": "src/index.js",
"author": "Marc-André Rivet",
"license": "MIT"
}
31 changes: 31 additions & 0 deletions @plotly/dash-component-plugins/src/asyncImport.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import { lazy } from 'react';

export const asyncDecorator = (target, promise) => {
let resolve;
const isReady = new Promise(r => {
resolve = r;
});

const state = {
isReady,
get: lazy(() => {
return Promise.resolve(promise()).then(res => {
setTimeout(async () => {
await resolve(true);
state.isReady = true;
}, 0);

return res;
});
}),
};

Object.defineProperty(target, '_dashprivate_isLazyComponentReady', {
get: () => state.isReady,
});

return state.get;
};

export const isReady = target => target &&
target._dashprivate_isLazyComponentReady;
3 changes: 3 additions & 0 deletions @plotly/dash-component-plugins/src/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import { asyncDecorator, isReady } from './dynamicImport';

export { asyncDecorator, isReady };
21 changes: 21 additions & 0 deletions @plotly/webpack-dash-dynamic-import/LICENSE
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
MIT License

Copyright (c) 2019 Plotly

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
16 changes: 16 additions & 0 deletions @plotly/webpack-dash-dynamic-import/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
{
"name": "@plotly/webpack-dash-dynamic-import",
"version": "1.0.0",
"description": "Webpack Plugin for Dynamic Import in Dash",
"repository": {
"type": "git",
"url": "git@github.com:plotly/dash.git"
},
"bugs": {
"url": "https://github.com/plotly/dash/issues"
},
"homepage": "https://github.com/plotly/dash",
"main": "src/index.js",
"author": "Marc-André Rivet",
"license": "MIT"
}
33 changes: 33 additions & 0 deletions @plotly/webpack-dash-dynamic-import/src/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
const resolveImportSource = `\
Object.defineProperty(__webpack_require__, 'p', {
get: (function () {
let script = document.currentScript;
if (!script) {
/* Shim for IE11 and below */
/* Do not take into account async scripts and inline scripts */
const scripts = Array.from(document.getElementsByTagName('script')).filter(function(s) { return !s.async && !s.text && !s.textContent; });
script = scripts.slice(-1)[0];
}
var url = script.src.split('/').slice(0, -1).join('/') + '/';
return function() {
return url;
};
})()
});`

class WebpackDashDynamicImport {
apply(compiler) {
compiler.hooks.compilation.tap('WebpackDashDynamicImport', compilation => {
compilation.mainTemplate.hooks.requireExtensions.tap('WebpackDashDynamicImport > RequireExtensions', (source, chunk, hash) => {
return [
source,
resolveImportSource
]
});
});
}
}

module.exports = WebpackDashDynamicImport;
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ updates in clientside functions.
- Three new `dash.testing` methods: `clear_local_storage`, `clear_session_storage`, and `clear_storage` (to clear both together)
- [#937](https://github.com/plotly/dash/pull/937) `dash.testing` adds two APIs `zoom_in_graph_by_ratio` and `click_at_coord_fractions` about advanced interactions using mouse `ActionChain`
- [#938](https://github.com/plotly/dash/issues/938) Add debugging traces to dash backend about serving component suites, to verify the installed packages whenever in doubt.
- [#899](https://github.com/plotly/dash/pull/899) Add support for async dependencies and components

### Fixed
- [#944](https://github.com/plotly/dash/pull/944) Fix a bug with persistence being toggled on/off on an existing component.
Expand Down
6 changes: 0 additions & 6 deletions dash-renderer/.babelrc

This file was deleted.

13 changes: 13 additions & 0 deletions dash-renderer/babel.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
module.exports = {
presets: [['@babel/preset-env', {
useBuiltIns: 'usage',
corejs: 3
}], '@babel/preset-react'],
env: {
test: {
plugins: [
'@babel/plugin-transform-modules-commonjs'
]
}
}
};
6 changes: 3 additions & 3 deletions dash-renderer/jest.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -163,9 +163,9 @@ module.exports = {
// transform: null,

// An array of regexp pattern strings that are matched against all source file paths, matched files will skip transformation
// transformIgnorePatterns: [
// "/node_modules/"
// ],
transformIgnorePatterns: [
"/node_modules/(?!@plotly).+\\.js"
],

// An array of regexp pattern strings that are matched against all modules before the module loader will automatically return a mock for them
// unmockedModulePathPatterns: undefined,
Expand Down
6 changes: 6 additions & 0 deletions dash-renderer/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 3 additions & 1 deletion dash-renderer/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,10 @@
},
"devDependencies": {
"@babel/core": "^7.6.0",
"@babel/plugin-transform-modules-commonjs": "^7.6.0",
"@babel/preset-env": "^7.6.0",
"@babel/preset-react": "^7.0.0",
"@plotly/dash-component-plugins": "^1.0.1",
"@svgr/webpack": "^4.1.0",
"babel-eslint": "^10.0.3",
"babel-loader": "^8.0.6",
Expand All @@ -57,9 +59,9 @@
"prettier-stylelint": "^0.4.2",
"raw-loader": "^3.1.0",
"style-loader": "^1.0.0",
"webpack-dev-server": "^3.1.11",
"webpack": "^4.39.3",
"webpack-cli": "^3.3.8",
"webpack-dev-server": "^3.1.11",
"webpack-serve": "^3.1.1",
"whatwg-fetch": "^2.0.2"
}
Expand Down
2 changes: 2 additions & 0 deletions dash-renderer/src/APIController.react.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import {
computePaths,
hydrateInitialOutputs,
setLayout,
setAppIsReady,
} from './actions/index';
import {applyPersistence} from './persistence';
import apiThunk from './actions/api';
Expand Down Expand Up @@ -54,6 +55,7 @@ class UnconnectedContainer extends Component {
dispatch
);
dispatch(setLayout(finalLayout));
dispatch(setAppIsReady());
} else if (isNil(paths)) {
dispatch(computePaths({subTree: layout, startingPath: []}));
}
Expand Down
5 changes: 1 addition & 4 deletions dash-renderer/src/TreeContainer.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,14 +22,11 @@ import {
type,
} from 'ramda';
import {notifyObservers, updateProps} from './actions';
import isSimpleComponent from './isSimpleComponent';
import {recordUiEdit} from './persistence';
import ComponentErrorBoundary from './components/error/ComponentErrorBoundary.react';
import checkPropTypes from 'check-prop-types';

const SIMPLE_COMPONENT_TYPES = ['String', 'Number', 'Null', 'Boolean'];
const isSimpleComponent = component =>
includes(type(component), SIMPLE_COMPONENT_TYPES);

function validateComponent(componentDefinition) {
if (type(componentDefinition) === 'Array') {
throw new Error(
Expand Down
1 change: 1 addition & 0 deletions dash-renderer/src/actions/constants.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ const actionList = {
SET_CONFIG: 'SET_CONFIG',
ON_ERROR: 'ON_ERROR',
SET_HOOKS: 'SET_HOOKS',
SET_APP_READY: 'SET_APP_READY',
};

export const getAction = action => {
Expand Down
20 changes: 15 additions & 5 deletions dash-renderer/src/actions/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -33,17 +33,20 @@ import cookie from 'cookie';
import {uid, urlBase, isMultiOutputProp, parseMultipleOutputs} from '../utils';
import {STATUS} from '../constants/constants';
import {applyPersistence, prunePersistence} from '../persistence';
import setAppIsReady from './setAppReadyState';

export const updateProps = createAction(getAction('ON_PROP_CHANGE'));
export const setRequestQueue = createAction(getAction('SET_REQUEST_QUEUE'));
export const computeGraphs = createAction(getAction('COMPUTE_GRAPHS'));
export const computePaths = createAction(getAction('COMPUTE_PATHS'));
export const setLayout = createAction(getAction('SET_LAYOUT'));
export const setAppLifecycle = createAction(getAction('SET_APP_LIFECYCLE'));
export const setConfig = createAction(getAction('SET_CONFIG'));
export const setHooks = createAction(getAction('SET_HOOKS'));
export const setLayout = createAction(getAction('SET_LAYOUT'));
export const onError = createAction(getAction('ON_ERROR'));

export {setAppIsReady};

export function hydrateInitialOutputs() {
return function(dispatch, getState) {
triggerDefaultState(dispatch, getState);
Expand Down Expand Up @@ -175,7 +178,7 @@ function reduceInputIds(nodeIds, InputGraph) {
/*
* Create input-output(s) pairs,
* sort by number of outputs,
* and remove redudant inputs (inputs that update the same output)
* and remove redundant inputs (inputs that update the same output)
*/
const inputOutputPairs = nodeIds.map(nodeId => ({
input: nodeId,
Expand All @@ -194,7 +197,7 @@ function reduceInputIds(nodeIds, InputGraph) {
* trigger components to update multiple times.
*
* For example, [A, B] => C and [A, D] => E
* The unique inputs might be [A, B, D] but that is redudant.
* The unique inputs might be [A, B, D] but that is redundant.
* We only need to update B and D or just A.
*
* In these cases, we'll supply an additional list of outputs
Expand All @@ -215,10 +218,15 @@ function reduceInputIds(nodeIds, InputGraph) {
}

export function notifyObservers(payload) {
return function(dispatch, getState) {
return async function(dispatch, getState) {
const {id, props, excludedOutputs} = payload;

const {graphs, requestQueue} = getState();
const {graphs, isAppReady, requestQueue} = getState();

if (isAppReady !== true) {
await isAppReady;
}

const {InputGraph} = graphs;
/*
* Figure out all of the output id's that depend on this input.
Expand Down Expand Up @@ -942,6 +950,8 @@ function updateOutput(
);
});
}

dispatch(setAppIsReady());
}
};
if (multi) {
Expand Down
Loading

0 comments on commit b31c447

Please sign in to comment.