From d8e47ccd033914cd8db0e6d2491edcd489c852dd Mon Sep 17 00:00:00 2001 From: stephenwf Date: Wed, 23 Jan 2019 23:09:32 +0000 Subject: [PATCH 1/4] Added connect abstraction to cookbook --- .../src/components/CanvasList/CanvasList.js | 9 +++------ .../src/components/ManifestSimple/ManifestSimple.js | 9 +++------ packages/iiif-redux-cookbook/src/hoc/connect.js | 12 ++++++++++++ 3 files changed, 18 insertions(+), 12 deletions(-) create mode 100644 packages/iiif-redux-cookbook/src/hoc/connect.js diff --git a/packages/iiif-redux-cookbook/src/components/CanvasList/CanvasList.js b/packages/iiif-redux-cookbook/src/components/CanvasList/CanvasList.js index c3f37193..7bd3fdfb 100644 --- a/packages/iiif-redux-cookbook/src/components/CanvasList/CanvasList.js +++ b/packages/iiif-redux-cookbook/src/components/CanvasList/CanvasList.js @@ -1,9 +1,7 @@ import React, { Component } from 'react'; -import { connect } from 'react-redux'; +import connect from '../../hoc/connect'; import { manifestByIdSelector } from 'iiif-redux/es/api/manifest'; import { canvases } from 'iiif-redux/es/api/canvas'; -import { iiifResourceRequestUnknown } from 'iiif-redux/es/spaces/iiif-resource'; -import withLoadingState from '../../hoc/withLoadingState'; import t from '../../utils/t'; class CanvasList extends Component { @@ -30,6 +28,5 @@ export default connect( canvasList: canvases(currentManifest.getCanvases, canvas => ({ label: canvas.getLabel, })), - })), - { iiifResourceRequestUnknown } -)(withLoadingState(CanvasList)); + })) +)(CanvasList); diff --git a/packages/iiif-redux-cookbook/src/components/ManifestSimple/ManifestSimple.js b/packages/iiif-redux-cookbook/src/components/ManifestSimple/ManifestSimple.js index 0e6e9aa5..91394507 100644 --- a/packages/iiif-redux-cookbook/src/components/ManifestSimple/ManifestSimple.js +++ b/packages/iiif-redux-cookbook/src/components/ManifestSimple/ManifestSimple.js @@ -1,8 +1,6 @@ import React, { Component } from 'react'; -import { connect } from 'react-redux'; import { manifestByIdSelector } from 'iiif-redux/es/api/manifest'; -import { iiifResourceRequestUnknown } from 'iiif-redux/es/spaces/iiif-resource'; -import withLoadingState from '../../hoc/withLoadingState'; +import connect from '../../hoc/connect'; import t from '../../utils/t'; class ManifestSimple extends Component { @@ -51,6 +49,5 @@ export default connect( license: currentManifest.getLicense, logo: currentManifest.getLogo, metadata: currentManifest.getMetadata, - })), - { iiifResourceRequestUnknown } -)(withLoadingState(ManifestSimple)); + })) +)(ManifestSimple); diff --git a/packages/iiif-redux-cookbook/src/hoc/connect.js b/packages/iiif-redux-cookbook/src/hoc/connect.js new file mode 100644 index 00000000..2c5f242e --- /dev/null +++ b/packages/iiif-redux-cookbook/src/hoc/connect.js @@ -0,0 +1,12 @@ +import { connect } from 'react-redux'; +import withLoadingState from './withLoadingState'; +import { iiifResourceRequestUnknown } from 'iiif-redux/es/spaces/iiif-resource'; + +const customConnect = (selector, actions) => WrappedComponent => { + return connect( + selector, + { iiifResourceRequestUnknown, ...actions } + )(withLoadingState(WrappedComponent)); +}; + +export default customConnect; From b93a3a5c6888963fa19209ad9f5ff3f7e6981cf2 Mon Sep 17 00:00:00 2001 From: stephenwf Date: Wed, 23 Jan 2019 23:10:21 +0000 Subject: [PATCH 2/4] Husky deprecation notice --- package.json | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/package.json b/package.json index b4bca29b..52a74724 100644 --- a/package.json +++ b/package.json @@ -28,7 +28,6 @@ "start": "lerna run start --stream --parallel --concurrency 100", "build": "NODE_ENV=production lerna run build && lerna link", "build-all": "lerna run build", - "precommit": "lint-staged", "release": "fesk-release", "merge": "fesk-merge", "link": "lerna link", @@ -55,5 +54,10 @@ "packages/iiif-redux/__tests__/fixtures", "packages/iiif-redux/__tests__/api/3\\.x/[A-Za-z\\-]+/fixtures" ] + }, + "husky": { + "hooks": { + "pre-commit": "lint-staged" + } } } From ea1abe8be7f186bbb50035f9cedd14d2c3e77099 Mon Sep 17 00:00:00 2001 From: stephenwf Date: Thu, 24 Jan 2019 00:19:55 +0000 Subject: [PATCH 3/4] Added React 16 context example --- .../src/components/App/App.js | 18 ++++++- .../ManifestWithContext.js | 19 +++++++ .../src/context/manifest.js | 50 +++++++++++++++++++ 3 files changed, 86 insertions(+), 1 deletion(-) create mode 100644 packages/iiif-redux-cookbook/src/components/ManifestWithContext/ManifestWithContext.js create mode 100644 packages/iiif-redux-cookbook/src/context/manifest.js diff --git a/packages/iiif-redux-cookbook/src/components/App/App.js b/packages/iiif-redux-cookbook/src/components/App/App.js index 124ae1c6..14a7363b 100644 --- a/packages/iiif-redux-cookbook/src/components/App/App.js +++ b/packages/iiif-redux-cookbook/src/components/App/App.js @@ -1,10 +1,13 @@ -import React, { Component } from 'react'; +import React, { Component, PureComponent } from 'react'; import { Provider } from 'react-redux'; import { Link, Router } from '@reach/router'; import { createStore } from 'iiif-redux'; import './App.css'; import ManifestSimple from '../ManifestSimple/ManifestSimple'; import CanvasList from '../CanvasList/CanvasList'; +import { Manifest, ManifestContext } from '../../context/manifest'; +import t from '../../utils/t'; +import TestManifestContext from '../ManifestWithContext/ManifestWithContext'; const store = createStore(); @@ -23,10 +26,22 @@ const Home = () => (
  • Canvases simple (Presentation 3)
  • +

    React 16 Context

    +
  • + Manifest context (p2) +
  • ); +const ContextTest = () => ( +
    + + + +
    +); + class App extends Component { render() { return ( @@ -51,6 +66,7 @@ class App extends Component { path="/canvases-simple-p3" id="https://raw.githubusercontent.com/digirati-co-uk/prezi2to3-js/master/tests/spec/fixtures/out/manifests.britishart.yale.edu__manifest__1474.json" /> + diff --git a/packages/iiif-redux-cookbook/src/components/ManifestWithContext/ManifestWithContext.js b/packages/iiif-redux-cookbook/src/components/ManifestWithContext/ManifestWithContext.js new file mode 100644 index 00000000..bc03a863 --- /dev/null +++ b/packages/iiif-redux-cookbook/src/components/ManifestWithContext/ManifestWithContext.js @@ -0,0 +1,19 @@ +import React, { Component } from 'react'; +import t from '../../utils/t'; +import { ManifestContext } from '../../context/manifest'; + +class TestManifestContext extends Component { + static contextType = ManifestContext; + + render() { + const { manifest } = this.context; + + if (manifest.fetched === false) { + return
    Loading...
    ; + } + + return
    Manifest label: {t(manifest.label)}
    ; + } +} + +export default TestManifestContext; diff --git a/packages/iiif-redux-cookbook/src/context/manifest.js b/packages/iiif-redux-cookbook/src/context/manifest.js new file mode 100644 index 00000000..9eb4703b --- /dev/null +++ b/packages/iiif-redux-cookbook/src/context/manifest.js @@ -0,0 +1,50 @@ +import React, { Component } from 'react'; +import { ReactReduxContext } from 'react-redux'; +import connect from '../hoc/connect'; +import manifest from 'iiif-redux/es/api/manifest'; +import { getAllManifests } from 'iiif-redux/es/api/all'; +import { createSelector } from 'reselect'; +import memoize from 'lodash.memoize'; + +const defaultContext = { + id: null, + manifest: null, +}; + +export const ManifestContext = React.createContext(defaultContext); + +const manifestSelector = memoize(id => + createSelector( + getAllManifests, + manifests => { + return manifests[id]; + } + ) +); + +class ManifestProvider extends Component { + static defaultProps = Object.assign({}, defaultContext); + + static contextType = ReactReduxContext; + + render() { + const { id, children } = this.props; + return ( + ({ + label: api.getLabel, + license: api.getLicense, + logo: api.getLogo, + metadata: api.getMetadata, + }))(this.context.storeState), + }} + > + {children} + + ); + } +} + +export const Manifest = connect()(ManifestProvider); From 580f22e403f67d4c1f0995cf238e895fcddacb9e Mon Sep 17 00:00:00 2001 From: stephenwf Date: Thu, 31 Jan 2019 22:34:04 +0000 Subject: [PATCH 4/4] React hooks examples --- packages/iiif-redux-cookbook/package.json | 5 +- .../src/components/App/App.js | 30 ++++- .../src/components/HookViewer/HookViewer.js | 98 ++++++++++++++++ .../components/HooksExample/HooksExample.js | 107 ++++++++++++++++++ .../src/context/manifest.js | 47 +++++++- yarn.lock | 57 ++++++++-- 6 files changed, 333 insertions(+), 11 deletions(-) create mode 100644 packages/iiif-redux-cookbook/src/components/HookViewer/HookViewer.js create mode 100644 packages/iiif-redux-cookbook/src/components/HooksExample/HooksExample.js diff --git a/packages/iiif-redux-cookbook/package.json b/packages/iiif-redux-cookbook/package.json index ee62e514..a86535ac 100644 --- a/packages/iiif-redux-cookbook/package.json +++ b/packages/iiif-redux-cookbook/package.json @@ -13,9 +13,10 @@ }, "dependencies": { "@reach/router": "1.2.1", + "@types/react": "^16.8.0", "iiif-redux": "1.0.0", - "react": "16.7.0", - "react-dom": "16.7.0", + "react": "16.8.0-alpha.1", + "react-dom": "16.8.0-alpha.1", "react-redux": "6.0.0", "redux": "4.0.1" }, diff --git a/packages/iiif-redux-cookbook/src/components/App/App.js b/packages/iiif-redux-cookbook/src/components/App/App.js index 14a7363b..710a2440 100644 --- a/packages/iiif-redux-cookbook/src/components/App/App.js +++ b/packages/iiif-redux-cookbook/src/components/App/App.js @@ -8,6 +8,8 @@ import CanvasList from '../CanvasList/CanvasList'; import { Manifest, ManifestContext } from '../../context/manifest'; import t from '../../utils/t'; import TestManifestContext from '../ManifestWithContext/ManifestWithContext'; +import HooksExample from '../HooksExample/HooksExample'; +import HookViewer from '../HookViewer/HookViewer'; const store = createStore(); @@ -30,6 +32,12 @@ const Home = () => (
  • Manifest context (p2)
  • +
  • + Hooks example 1 +
  • +
  • + Hooks example 2 +
  • ); @@ -42,12 +50,30 @@ const ContextTest = () => ( ); +const HooksTest = () => ( +
    + + + +
    +); + +const HooksViewerTest = () => ( +
    + + + +
    +); + class App extends Component { render() { return (
    -

    IIIF Redux demos

    + +

    IIIF Redux demos

    + + +
    diff --git a/packages/iiif-redux-cookbook/src/components/HookViewer/HookViewer.js b/packages/iiif-redux-cookbook/src/components/HookViewer/HookViewer.js new file mode 100644 index 00000000..9be9ca5f --- /dev/null +++ b/packages/iiif-redux-cookbook/src/components/HookViewer/HookViewer.js @@ -0,0 +1,98 @@ +import React, { useContext, useState } from 'react'; +import { + Canvas, + ManifestContext, + useCanvas, + useManifest, +} from '../../context/manifest'; +import t from '../../utils/t'; +import { canvases } from 'iiif-redux/src/api/canvas'; + +// This is all the bits we need for the canvas listing page. +const manifestSelector = manifest => ({ + label: manifest.getLabel, + canvasList: canvases(manifest.getCanvases, canvas => ({ + id: canvas.getId, + label: canvas.getLabel, + })), +}); + +// This is our image viewer, very very simple. +function ImageViewer() { + const { id, label, thumbnailId } = useCanvas(); + + return ( +
    +
    + {t(label)} ({id}) +
    + {t(label)} +
    + ); +} + +// This is an abstraction to get the manifest loading state. +function useManifestLoaded() { + const { manifest } = useContext(ManifestContext); + return manifest.fetched; +} + +const styles = { + container: { display: 'flex' }, + left: { width: 300, margin: 20 }, + right: { flex: '1 0 0%', margin: 20 }, + link: { cursor: 'pointer', margin: 4, background: '#eee', listStyle: 'none' }, + list: { margin: 0, padding: 0, textAlign: 'center' }, +}; + +// This is our viewer. +function HookViewer() { + // Get the fetched status of our manifest + const fetched = useManifestLoaded(); + // Grab the label and list + const { label, canvasList } = useManifest(manifestSelector); + // Create some state to manage the current manifest + const [currentCanvas, setCurrentCanvas] = useState(); + + // If we're fetching, return early. + if (fetched === false) { + return
    Loading...
    ; + } + + // Render our viewer. + return ( +
    +
    +

    {t(label)}

    +
      + {canvasList.map(canvas => ( + // Here we are setting the canvas id for our viewer. +
    • setCurrentCanvas(canvas.id)} + > + {t(canvas.label)} +
    • + ))} +
    +
    +
    + {/* + Here we are creating a new "Context" for the select canvas. + This will be available to ALL children no matter how deep + using `useCanvas` hook. + */} + {currentCanvas ? ( + + + + ) : ( +
    Please Select a canvas
    + )} +
    +
    + ); +} + +export default HookViewer; diff --git a/packages/iiif-redux-cookbook/src/components/HooksExample/HooksExample.js b/packages/iiif-redux-cookbook/src/components/HooksExample/HooksExample.js new file mode 100644 index 00000000..52311f40 --- /dev/null +++ b/packages/iiif-redux-cookbook/src/components/HooksExample/HooksExample.js @@ -0,0 +1,107 @@ +import React, { useContext } from 'react'; +import { ManifestContext, useManifest } from '../../context/manifest'; +import t from '../../utils/t'; +import { externalResources } from 'iiif-redux/src/api/external-resource'; + +function Example1() { + // Default selector. + const { label } = useManifest(); + + return ( +
    +

    Example 1

    + Label: {t(label)} +
    + ); +} + +function Example2() { + // Single field, custom selector. + const license = useManifest(api => api.getLicense); + + return ( +
    +

    Example 2

    + License: {license} +
    + ); +} + +function Example3() { + // You can call useManifest more than once. + const label = useManifest(api => api.getLabel); + const license = useManifest(api => api.getLicense); + + return ( +
    +

    Example 3

    + Label: {t(label)}
    + License: {license} +
    + ); +} + +function Example4() { + // Bigger example, 2 fields selected at once. + const { label, metadata } = useManifest(api => ({ + label: api.getLabel, + metadata: api.getMetadata, + })); + + // Also selecting the see also links (note you will be able to leave second) + // argument blank to get sensible default selector. + const seeAlso = useManifest(manifest => + // This could also have been combined into the selector above, but is + // split out for clarity. + externalResources(manifest.getSeeAlso, resource => ({ + id: resource.getId, + format: resource.getFormat, + })) + ); + + const linkStyle = { margin: 5, padding: 5, border: '2px solid #000' }; + + return ( +
    +

    Example 4

    + Label: {t(label)} + {metadata.map((pair, n) => ( +
    + {t(pair.label)}:{' '} + +
    + ))} +
    +

    See also

    + {seeAlso.map(link => ( +
    + Id: {link.id}
    + format: {link.format} +
    + ))} +
    +
    + ); +} + +function HooksExample() { + // Pure hooks example. + const { manifest } = useContext(ManifestContext); + + if (manifest.fetched === false) { + return
    Loading...
    ; + } + + return ( +
    + + + + +
    + ); + + return
    Hooks example {t(manifest.label)}
    ; +} + +export default HooksExample; diff --git a/packages/iiif-redux-cookbook/src/context/manifest.js b/packages/iiif-redux-cookbook/src/context/manifest.js index 9eb4703b..7b2007f1 100644 --- a/packages/iiif-redux-cookbook/src/context/manifest.js +++ b/packages/iiif-redux-cookbook/src/context/manifest.js @@ -1,10 +1,12 @@ -import React, { Component } from 'react'; +import React, { Component, useContext, useMemo } from 'react'; import { ReactReduxContext } from 'react-redux'; import connect from '../hoc/connect'; import manifest from 'iiif-redux/es/api/manifest'; +import canvas from 'iiif-redux/es/api/canvas'; import { getAllManifests } from 'iiif-redux/es/api/all'; import { createSelector } from 'reselect'; import memoize from 'lodash.memoize'; +import { getAllCanvases } from 'iiif-redux/src/api/all'; const defaultContext = { id: null, @@ -12,6 +14,7 @@ const defaultContext = { }; export const ManifestContext = React.createContext(defaultContext); +export const CanvasContext = React.createContext({ id: null }); const manifestSelector = memoize(id => createSelector( @@ -22,6 +25,48 @@ const manifestSelector = memoize(id => ) ); +const canvasSelector = memoize(id => + createSelector( + getAllCanvases, + canvases => { + return canvases[id]; + } + ) +); + +export function useManifest(customApi = null) { + const { id } = useContext(ManifestContext); + const { storeState } = useContext(ReactReduxContext); + const selector = useMemo(() => manifestSelector(id), [id]); + + return manifest( + selector, + customApi || (api => ({ id: api.getId, label: api.getLabel })) + )(storeState); +} + +export function useCanvas(customApi = null) { + const { id } = useContext(CanvasContext); + const { storeState } = useContext(ReactReduxContext); + const selector = useMemo(() => canvasSelector(id), [id]); + + return canvas( + selector, + customApi || + (api => ({ + id: api.getId, + label: api.getLabel, + thumbnailId: api.getThumbnailId, + })) + )(storeState); +} + +export function Canvas({ id, children }) { + return ( + {children} + ); +} + class ManifestProvider extends Component { static defaultProps = Object.assign({}, defaultContext); diff --git a/yarn.lock b/yarn.lock index 23bdb7f2..0505840f 100644 --- a/yarn.lock +++ b/yarn.lock @@ -761,14 +761,27 @@ version "2.2.25" resolved "https://registry.yarnpkg.com/@stephenwf-forks/manifesto.js/-/manifesto.js-2.2.25.tgz#69a7251479648c4078dc439c33dcbb2384916567" dependencies: - exjs "github:BSick7/exjs#0.5.0" - http-status-codes "github:edsilv/http-status-codes#v0.0.7" + exjs BSick7/exjs#0.5.0 + http-status-codes edsilv/http-status-codes#v0.0.7 request "^2.83.0" "@types/jquery@^2.0.40": version "2.0.49" resolved "https://registry.yarnpkg.com/@types/jquery/-/jquery-2.0.49.tgz#95bd7064caebf65bde10429dff491a1aea05b67d" +"@types/prop-types@*": + version "15.5.8" + resolved "https://registry.yarnpkg.com/@types/prop-types/-/prop-types-15.5.8.tgz#8ae4e0ea205fe95c3901a5a1df7f66495e3a56ce" + integrity sha512-3AQoUxQcQtLHsK25wtTWIoIpgYjH3vSDroZOUr7PpCHw/jLY1RB9z9E8dBT/OSmwStVgkRNvdh+ZHNiomRieaw== + +"@types/react@^16.8.0": + version "16.8.0" + resolved "https://registry.yarnpkg.com/@types/react/-/react-16.8.0.tgz#0933e105ea21739948b1525920e0536312d54c58" + integrity sha512-phBajeyF9ZIYGWUHJV1+X5GHOtdUO0+qHamY4PXFPf6ntoDfW+VqOG8oyruD2K4rqApfOB1QKuQiNYUX8ejEpQ== + dependencies: + "@types/prop-types" "*" + csstype "^2.2.0" + "@webassemblyjs/ast@1.5.13": version "1.5.13" resolved "https://registry.yarnpkg.com/@webassemblyjs/ast/-/ast-1.5.13.tgz#81155a570bd5803a30ec31436bc2c9c0ede38f25" @@ -4008,6 +4021,11 @@ cssom@0.3.x, "cssom@>= 0.3.2 < 0.4.0": dependencies: cssom "0.3.x" +csstype@^2.2.0: + version "2.6.2" + resolved "https://registry.yarnpkg.com/csstype/-/csstype-2.6.2.tgz#3043d5e065454579afc7478a18de41909c8a2f01" + integrity sha512-Rl7PvTae0pflc1YtxtKbiSqq20Ts6vpIYOD5WBafl4y123DyHUeLrRdQP66sQW8/6gmX8jrYJLXwNeMqYVJcow== + currently-unhandled@^0.4.1: version "0.4.1" resolved "https://registry.yarnpkg.com/currently-unhandled/-/currently-unhandled-0.4.1.tgz#988df33feab191ef799a61369dd76c17adf957ea" @@ -5031,9 +5049,8 @@ exit@^0.1.2: version "0.1.2" resolved "https://registry.yarnpkg.com/exit/-/exit-0.1.2.tgz#0632638f8d877cc82107d30a0fff1a17cba1cd0c" -"exjs@github:BSick7/exjs#0.5.0": +exjs@BSick7/exjs#0.5.0: version "0.5.0" - uid "98195810790c0e61cb5beb510da4b756528f92f2" resolved "https://codeload.github.com/BSick7/exjs/tar.gz/98195810790c0e61cb5beb510da4b756528f92f2" expand-braces@^0.1.1: @@ -6380,9 +6397,8 @@ http-signature@~1.2.0: jsprim "^1.2.2" sshpk "^1.7.0" -"http-status-codes@github:edsilv/http-status-codes#v0.0.7": +http-status-codes@edsilv/http-status-codes#v0.0.7: version "0.0.7" - uid af3a8ab9970b1f291a79b03c7382dc16aebee749 resolved "https://codeload.github.com/edsilv/http-status-codes/tar.gz/af3a8ab9970b1f291a79b03c7382dc16aebee749" httpntlm@1.6.1: @@ -8123,7 +8139,6 @@ listr-silent-renderer@^1.1.1: listr-update-renderer@^0.4.0: version "0.4.0" - uid "06073fa93166277607a7814f4e1f83960081414c" resolved "https://github.com/okonet/listr-update-renderer/tarball/upgrade-log-update#06073fa93166277607a7814f4e1f83960081414c" dependencies: chalk "^1.1.3" @@ -11393,6 +11408,16 @@ react-dom@16.7.0: prop-types "^15.6.2" scheduler "^0.12.0" +react-dom@16.8.0-alpha.1: + version "16.8.0-alpha.1" + resolved "https://registry.yarnpkg.com/react-dom/-/react-dom-16.8.0-alpha.1.tgz#dab73b8354ba2e498e3127d18e29d4546cea889e" + integrity sha512-tZCUM8BpnwUHJmLnUWP9c3vVZxnCqYotj7s4tx7umojG6BKv745KIBtuPTzt0EI0q50GMLEpmT/CPQ8iA61TwQ== + dependencies: + loose-envify "^1.1.0" + object-assign "^4.1.1" + prop-types "^15.6.2" + scheduler "^0.13.0-alpha.1" + react-dom@^16.3.2: version "16.4.0" resolved "https://registry.yarnpkg.com/react-dom/-/react-dom-16.4.0.tgz#099f067dd5827ce36a29eaf9a6cdc7cbf6216b1e" @@ -11535,6 +11560,16 @@ react@16.7.0: prop-types "^15.6.2" scheduler "^0.12.0" +react@16.8.0-alpha.1: + version "16.8.0-alpha.1" + resolved "https://registry.yarnpkg.com/react/-/react-16.8.0-alpha.1.tgz#c2b32689f3b466d3ce85a634dd9035f789d2cd97" + integrity sha512-vLwwnhM2dXrCsiQmcSxF2UdZVV5xsiXjK5Yetmy8dVqngJhQ3aw3YJhZN/YmyonxwdimH40wVqFQfsl4gSu2RA== + dependencies: + loose-envify "^1.1.0" + object-assign "^4.1.1" + prop-types "^15.6.2" + scheduler "^0.13.0-alpha.1" + react@^16.3.2: version "16.4.0" resolved "https://registry.yarnpkg.com/react/-/react-16.4.0.tgz#402c2db83335336fba1962c08b98c6272617d585" @@ -12273,6 +12308,14 @@ scheduler@^0.12.0: loose-envify "^1.1.0" object-assign "^4.1.1" +scheduler@^0.13.0-alpha.1: + version "0.13.0-alpha.1" + resolved "https://registry.yarnpkg.com/scheduler/-/scheduler-0.13.0-alpha.1.tgz#753977fb4fb35d8cdd559868a11e46b640955556" + integrity sha512-W0sH0848sVuPKg+I18vTYQyzVtA4X1lrVgSeXK6KnOPUltFdJcY5nkbTkjGUeS/E0x+eBsNYfSdhJtGjT95njw== + dependencies: + loose-envify "^1.1.0" + object-assign "^4.1.1" + schema-utils@^0.3.0: version "0.3.0" resolved "https://registry.yarnpkg.com/schema-utils/-/schema-utils-0.3.0.tgz#f5877222ce3e931edae039f17eb3716e7137f8cf"