mirror of
https://github.com/gurnec/removeddit.git
synced 2026-03-11 08:54:27 +00:00
Switched redux to unstated
This commit is contained in:
parent
2f40c15c7f
commit
43d5a1979c
14 changed files with 127 additions and 221 deletions
|
|
@ -29,10 +29,9 @@
|
|||
"babel-polyfill": "^6.26.0",
|
||||
"react": "^16.4.1",
|
||||
"react-dom": "^16.4.1",
|
||||
"react-redux": "^5.0.7",
|
||||
"react-router-dom": "^4.3.1",
|
||||
"redux": "^4.0.0",
|
||||
"snuownd": "git+https://github.com/JordanMilne/snuownd.git",
|
||||
"unstated": "^2.1.1",
|
||||
"whatwg-fetch": "^2.0.4"
|
||||
},
|
||||
"devDependencies": {
|
||||
|
|
|
|||
|
|
@ -1,18 +1,17 @@
|
|||
import 'babel-polyfill'
|
||||
import React from 'react'
|
||||
import ReactDOM from 'react-dom'
|
||||
import { Provider } from 'react-redux'
|
||||
import { BrowserRouter, Switch, Route } from 'react-router-dom'
|
||||
|
||||
import { store } from './state'
|
||||
import { Provider } from 'unstated'
|
||||
|
||||
import Header from './pages/common/Header'
|
||||
import About from './pages/about'
|
||||
import Subreddit from './pages/subreddit'
|
||||
import Thread from './pages/thread'
|
||||
import NotFound from './pages/notFound'
|
||||
|
||||
ReactDOM.render(
|
||||
<Provider store={store}>
|
||||
<Provider>
|
||||
<BrowserRouter basename={__dirname}>
|
||||
<React.Fragment>
|
||||
<Header />
|
||||
|
|
@ -23,6 +22,7 @@ ReactDOM.render(
|
|||
<Route path='/r/:subreddit/comments/:threadID/:junk/:commentID' component={Thread} />
|
||||
<Route path='/r/:subreddit/comments/:threadID' component={Thread} />
|
||||
<Route path='/r/:subreddit' component={Subreddit} />
|
||||
<Route component={NotFound} />
|
||||
</Switch>
|
||||
</div>
|
||||
</React.Fragment>
|
||||
|
|
|
|||
|
|
@ -1,18 +1,13 @@
|
|||
import React from 'react'
|
||||
import { connect } from 'react-redux'
|
||||
import {connect} from '../../state'
|
||||
|
||||
const StatusBox = props => (
|
||||
<div id='status'>
|
||||
{props.text &&
|
||||
<p id='status-text'>{props.text}</p>}
|
||||
<p id='status-text'>{props.gloabl.state.statusText}</p>}
|
||||
{props.image &&
|
||||
<img id='status-image' src={props.image} alt='status' />}
|
||||
<img id='status-image' src={props.gloabl.state.statusImage} alt='status' />}
|
||||
</div>
|
||||
)
|
||||
|
||||
const mapStateToProps = state => ({
|
||||
text: state.status.text,
|
||||
image: state.status.image
|
||||
})
|
||||
|
||||
export default connect(mapStateToProps)(StatusBox)
|
||||
export default connect(StatusBox)
|
||||
|
|
|
|||
5
src/pages/notFound/index.js
Normal file
5
src/pages/notFound/index.js
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
import React from 'react'
|
||||
|
||||
export default () => (
|
||||
<h2>404 - Not found</h2>
|
||||
)
|
||||
|
|
@ -1,7 +1,7 @@
|
|||
import React from 'react'
|
||||
import { Link } from 'react-router-dom'
|
||||
import { getRemovedThreadIDs } from 'api/removeddit'
|
||||
import { getThreads } from 'api/reddit'
|
||||
import { getRemovedThreadIDs } from '../../api/removeddit'
|
||||
import { getThreads } from '../../api/reddit'
|
||||
import Post from '../common/Post'
|
||||
|
||||
const getSubredditForAPI = props => {
|
||||
|
|
@ -21,19 +21,20 @@ export default class Subreddit extends React.Component {
|
|||
subreddit: ''
|
||||
}
|
||||
}
|
||||
|
||||
componentDidMount () {
|
||||
this.updateThreads(this.props)
|
||||
this.getRemovedThreads(this.props)
|
||||
}
|
||||
|
||||
componentWillReceiveProps (nextProps) {
|
||||
const newSubreddit = getSubredditForAPI(nextProps)
|
||||
|
||||
if (this.state.subreddit !== newSubreddit) {
|
||||
this.updateThreads(nextProps)
|
||||
this.getRemovedThreads(nextProps)
|
||||
}
|
||||
}
|
||||
|
||||
updateThreads (props) {
|
||||
getRemovedThreads (props) {
|
||||
const subreddit = getSubredditForAPI(props)
|
||||
getRemovedThreadIDs(subreddit)
|
||||
.then(threadIDs => getThreads(threadIDs))
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
import React from 'react'
|
||||
import { prettyScore, prettyDate, parse } from 'utils'
|
||||
import { prettyScore, prettyDate, parse } from '../../utils'
|
||||
|
||||
const Comment = (props) => {
|
||||
let commentStyle = 'comment '
|
||||
|
|
|
|||
|
|
@ -2,11 +2,7 @@ import React from 'react'
|
|||
import Comment from './Comment'
|
||||
import CommentInfo from './CommentInfo'
|
||||
import SortBy from './SortBy'
|
||||
import { connect } from 'react-redux'
|
||||
import {
|
||||
SORT_TOP, SORT_BOTTOM, SORT_NEW, SORT_OLD,
|
||||
SHOW_ALL, SHOW_REMOVED_DELETED, SHOW_REMOVED, SHOW_DELETED
|
||||
} from 'state'
|
||||
import {connect, sort, filter} from '../../state'
|
||||
import {
|
||||
topSort, bottomSort, newSort, oldSort,
|
||||
showRemovedAndDeleted, showRemoved, showDeleted
|
||||
|
|
@ -94,22 +90,23 @@ const filterCommentTree = (comments, filterFunction) => {
|
|||
const commentSection = (props) => {
|
||||
console.time('render comment section')
|
||||
const commentTree = unflatten(props.comments, props.root, props.removed, props.deleted)
|
||||
const {commentFilter, commentSort} = props.global.state
|
||||
|
||||
if (props.show === SHOW_REMOVED_DELETED) {
|
||||
if (commentFilter === filter.removedDeleted) {
|
||||
filterCommentTree(commentTree, showRemovedAndDeleted)
|
||||
} else if (props.show === SHOW_REMOVED) {
|
||||
} else if (commentFilter === filter.removed) {
|
||||
filterCommentTree(commentTree, showRemoved)
|
||||
} else if (props.show === SHOW_DELETED) {
|
||||
} else if (commentFilter === filter.deleted) {
|
||||
filterCommentTree(commentTree, showDeleted)
|
||||
}
|
||||
|
||||
if (props.sort === SORT_TOP) {
|
||||
if (commentSort === sort.top) {
|
||||
sortCommentTree(commentTree, topSort)
|
||||
} else if (props.sort === SORT_BOTTOM) {
|
||||
} else if (commentSort === sort.bottom) {
|
||||
sortCommentTree(commentTree, bottomSort)
|
||||
} else if (props.sort === SORT_NEW) {
|
||||
} else if (commentSort === sort.new) {
|
||||
sortCommentTree(commentTree, newSort)
|
||||
} else if (props.sort === SORT_OLD) {
|
||||
} else if (commentSort === sort.old) {
|
||||
sortCommentTree(commentTree, oldSort)
|
||||
}
|
||||
console.timeEnd('render comment section')
|
||||
|
|
@ -132,9 +129,4 @@ const commentSection = (props) => {
|
|||
)
|
||||
}
|
||||
|
||||
const mapStateToProps = state => ({
|
||||
sort: state.commentSection.sort,
|
||||
show: state.commentSection.show
|
||||
})
|
||||
|
||||
export default connect(mapStateToProps)(commentSection)
|
||||
export default connect(commentSection)
|
||||
|
|
|
|||
|
|
@ -1,45 +1,26 @@
|
|||
import React from 'react'
|
||||
import {
|
||||
setCommentSort,
|
||||
setCommentShow,
|
||||
SORT_TOP, SORT_BOTTOM, SORT_NEW, SORT_OLD,
|
||||
SHOW_ALL, SHOW_REMOVED_DELETED, SHOW_REMOVED, SHOW_DELETED
|
||||
} from 'state'
|
||||
import { connect } from 'react-redux'
|
||||
import {connect, sort, filter} from '../../state'
|
||||
|
||||
const sortBy = props => (
|
||||
<div id='comment-sort'>
|
||||
sorted by:
|
||||
<span className='space' />
|
||||
<select onChange={e => props.setSort(e.target.value)} defaultValue={props.sort}>
|
||||
<option value={SORT_TOP}>top</option>
|
||||
<option value={SORT_BOTTOM}>bottom</option>
|
||||
<option value={SORT_NEW}>new</option>
|
||||
<option value={SORT_OLD}>old</option>
|
||||
<select onChange={e => props.global.setCommentSort(e.target.value)} defaultValue={props.global.state.commentSort}>
|
||||
<option value={sort.top}>top</option>
|
||||
<option value={sort.bottom}>bottom</option>
|
||||
<option value={sort.new}>new</option>
|
||||
<option value={sort.old}>old</option>
|
||||
</select>
|
||||
<span className='space' />
|
||||
show:
|
||||
<span className='space' />
|
||||
<select onChange={e => props.setShow(e.target.value)} defaultValue={props.show}>
|
||||
<option value={SHOW_ALL}>All comments</option>
|
||||
<option value={SHOW_REMOVED_DELETED}>Removed and deleted</option>
|
||||
<option value={SHOW_REMOVED}>Removed</option>
|
||||
<option value={SHOW_DELETED}>Deleted</option>
|
||||
<select onChange={e => props.global.setCommentFilter(e.target.value)} defaultValue={props.global.state.commentFilter}>
|
||||
<option value={filter.all}>All comments</option>
|
||||
<option value={filter.removedDeleted}>Removed and deleted</option>
|
||||
<option value={filter.removed}>Removed</option>
|
||||
<option value={filter.deleted}>Deleted</option>
|
||||
</select>
|
||||
</div>
|
||||
)
|
||||
|
||||
const mapStateToProps = state => ({
|
||||
sort: state.commentSection.sort,
|
||||
show: state.commentSection.show
|
||||
})
|
||||
|
||||
const mapDispatchToProps = dispatch => ({
|
||||
setSort: sortString => dispatch(setCommentSort(sortString)),
|
||||
setShow: showString => dispatch(setCommentShow(showString))
|
||||
})
|
||||
|
||||
export default connect(
|
||||
mapStateToProps,
|
||||
mapDispatchToProps
|
||||
)(sortBy)
|
||||
export default connect(sortBy)
|
||||
|
|
|
|||
|
|
@ -1,11 +0,0 @@
|
|||
import React from 'react'
|
||||
|
||||
export default (props) => (
|
||||
<React.Fragment>
|
||||
<div id='comment-info'>
|
||||
removed comments: {props.removedComments}/${props.totalComments}
|
||||
({ ((100 * props.removedComments) / props.totalComments).toFixed(1) }%)
|
||||
</div>
|
||||
<div id='comment-sort'>sorted by: top</div>
|
||||
</React.Fragment>
|
||||
)
|
||||
|
|
@ -1,49 +0,0 @@
|
|||
import { get, put } from 'utils'
|
||||
|
||||
// Sort types
|
||||
export const SORT_TOP = 'SORT_TOP'
|
||||
export const SORT_BOTTOM = 'SORT_BOTTOM'
|
||||
export const SORT_NEW = 'SORT_NEW'
|
||||
export const SORT_OLD = 'SORT_OLD'
|
||||
|
||||
// Filter types
|
||||
export const SHOW_ALL = 'SHOW_ALL'
|
||||
export const SHOW_REMOVED_DELETED = 'SHOW_REMOVED_DELETED'
|
||||
export const SHOW_REMOVED = 'SHOW_REMOVED'
|
||||
export const SHOW_DELETED = 'SHOW_DELETED'
|
||||
|
||||
// Action types
|
||||
export const COMMENT_SORT = 'COMMENT_SORT'
|
||||
export const COMMENT_SHOW = 'COMMENT_SHOW'
|
||||
|
||||
// Action creators
|
||||
export const setCommentSort = payload => ({ type: COMMENT_SORT, payload })
|
||||
export const setCommentShow = payload => ({ type: COMMENT_SHOW, payload })
|
||||
|
||||
const sortKey = 'commentSort'
|
||||
const filterKey = 'commentFilter'
|
||||
|
||||
// Init state
|
||||
const initialStatusState = {
|
||||
sort: get(sortKey, SORT_TOP),
|
||||
show: get(filterKey, SHOW_REMOVED_DELETED)
|
||||
}
|
||||
|
||||
export const commentSectionReducer = (state = initialStatusState, action) => {
|
||||
switch (action.type) {
|
||||
case COMMENT_SORT:
|
||||
put(sortKey, action.payload)
|
||||
return {
|
||||
...state,
|
||||
sort: action.payload
|
||||
}
|
||||
case COMMENT_SHOW:
|
||||
put(filterKey, action.payload)
|
||||
return {
|
||||
...state,
|
||||
show: action.payload
|
||||
}
|
||||
default:
|
||||
return state
|
||||
}
|
||||
}
|
||||
|
|
@ -1,14 +1,71 @@
|
|||
import { createStore, combineReducers, applyMiddleware } from 'redux'
|
||||
import logger from 'redux-logger'
|
||||
import { statusReducer } from './status'
|
||||
import { commentSectionReducer } from './commentSection'
|
||||
import React from 'react'
|
||||
import { Subscribe, Container } from 'unstated'
|
||||
import { get, put } from 'utils'
|
||||
|
||||
export { setStatusLoading, setStatusSuccess, setStatusError } from './status'
|
||||
export * from './commentSection'
|
||||
// Sort types for comments
|
||||
export const sort = {
|
||||
top: 'SORT_TOP',
|
||||
bottom: 'SORT_BOTTOM',
|
||||
new: 'SORT_NEW',
|
||||
old: 'SORT_OLD'
|
||||
}
|
||||
|
||||
const reducer = combineReducers({
|
||||
status: statusReducer,
|
||||
commentSection: commentSectionReducer
|
||||
})
|
||||
// Filter types for comments
|
||||
export const filter = {
|
||||
all: 'SHOW_ALL',
|
||||
removedDeleted: 'SHOW_REMOVED_DELETED',
|
||||
removed: 'SHOW_REMOVED',
|
||||
deleted: 'SHOW_DELETED'
|
||||
}
|
||||
|
||||
export const store = createStore(reducer, applyMiddleware(logger))
|
||||
// Keys for localStorage
|
||||
const sortKey = 'commentSort'
|
||||
const filterKey = 'commentFilter'
|
||||
|
||||
class GlobalState extends Container {
|
||||
constructor () {
|
||||
super()
|
||||
|
||||
this.state = {
|
||||
commentSort: get(sortKey, sort.top),
|
||||
commentFilter: get(filterKey, filter.removedDeleted),
|
||||
statusText: '',
|
||||
statusImage: undefined
|
||||
}
|
||||
}
|
||||
|
||||
setCommentSort (sortType) {
|
||||
put(sortKey, sortType)
|
||||
this.setState({commentSort: sortType})
|
||||
}
|
||||
|
||||
setCommentFilter (filterType) {
|
||||
put(filterKey, filterType)
|
||||
this.setState({commentFilter: filterType})
|
||||
}
|
||||
|
||||
setErrorText (text) {
|
||||
this.setState({statusText: text, statusImage: '/images/error.png'})
|
||||
}
|
||||
|
||||
setSuccessText (text) {
|
||||
this.setState({statusText: text, statusImage: '/images/done.png'})
|
||||
}
|
||||
|
||||
setLoadingText (text) {
|
||||
this.setState({statusText: text, statusImage: '/images/loading.gif'})
|
||||
}
|
||||
|
||||
clearStatusText () {
|
||||
this.setState({statusText: '', statusImage: undefined})
|
||||
}
|
||||
}
|
||||
|
||||
// A redux-like connect function for Unstated
|
||||
export const connect = Component => {
|
||||
return props => (
|
||||
<Subscribe to={[GlobalState]}>
|
||||
{gloablState => <Component {...props} global={gloablState} />}
|
||||
</Subscribe>
|
||||
)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,46 +0,0 @@
|
|||
const images = {
|
||||
loading: '/images/loading.gif',
|
||||
error: '/images/error.png',
|
||||
success: '/images/done.png'
|
||||
}
|
||||
|
||||
// Action types
|
||||
const STATUS_SET_LOADING = 'STATUS_SET_LOADING'
|
||||
const STATUS_SET_SUCCESS = 'STATUS_SET_SUCCESS'
|
||||
const STATUS_SET_ERROR = 'STATUS_SET_ERROR'
|
||||
|
||||
// Action creators
|
||||
export const setStatusLoading = (payload = '') => ({ type: STATUS_SET_LOADING, payload })
|
||||
export const setStatusSuccess = (payload = '') => ({ type: STATUS_SET_SUCCESS, payload })
|
||||
export const setStatusError = (payload = '') => ({ type: STATUS_SET_ERROR, payload })
|
||||
|
||||
// Init state
|
||||
const initialStatusState = {
|
||||
text: null,
|
||||
image: null
|
||||
}
|
||||
|
||||
export const statusReducer = (state = initialStatusState, action) => {
|
||||
switch (action.type) {
|
||||
case STATUS_SET_SUCCESS:
|
||||
return {
|
||||
...state,
|
||||
text: action.payload,
|
||||
image: images.success
|
||||
}
|
||||
case STATUS_SET_LOADING:
|
||||
return {
|
||||
...state,
|
||||
text: action.payload,
|
||||
image: images.loading
|
||||
}
|
||||
case STATUS_SET_ERROR:
|
||||
return {
|
||||
...state,
|
||||
text: action.payload,
|
||||
image: images.error
|
||||
}
|
||||
default:
|
||||
return state
|
||||
}
|
||||
}
|
||||
|
|
@ -23,9 +23,6 @@ export const chunk = (arr, size) => {
|
|||
return chunks
|
||||
}
|
||||
|
||||
// JSON parsing for fetch
|
||||
export const json = x => x.json()
|
||||
|
||||
// Make multiple requests to the same url, with an array of data (usually comment IDs)
|
||||
// This is needed since there is a limit on how long a url can be
|
||||
export const fetchMultiple = (url, arr, header, size = 100) => {
|
||||
|
|
@ -34,7 +31,7 @@ export const fetchMultiple = (url, arr, header, size = 100) => {
|
|||
return Promise.all(subArrays.map(subArr => window.fetch(url + subArr.join(), header)))
|
||||
}
|
||||
|
||||
export const jsonMultiple = responses => Promise.all(responses.map(json))
|
||||
export const jsonMultiple = responses => Promise.all(responses.map(response => response.json()))
|
||||
|
||||
// Change bases
|
||||
export const toBase36 = number => parseInt(number, 10).toString(36)
|
||||
|
|
@ -85,9 +82,10 @@ export const prettyScore = score => {
|
|||
}
|
||||
|
||||
// Retrieve, store and delete stuff in the local storage
|
||||
export const get = (key, defaultValue) => (
|
||||
window.localStorage.getItem(key) !== null ? JSON.parse(window.localStorage.getItem(key)) : defaultValue
|
||||
)
|
||||
export const get = (key, defaultValue) => {
|
||||
const value = window.localStorage.getItem(key)
|
||||
return value !== null ? JSON.parse(value) : defaultValue
|
||||
}
|
||||
|
||||
export const put = (key, value) => window.localStorage.setItem(key, JSON.stringify(value))
|
||||
|
||||
|
|
|
|||
38
yarn.lock
38
yarn.lock
|
|
@ -1532,6 +1532,10 @@ create-hmac@^1.1.0, create-hmac@^1.1.2, create-hmac@^1.1.4:
|
|||
safe-buffer "^5.0.1"
|
||||
sha.js "^2.4.8"
|
||||
|
||||
create-react-context@^0.1.5:
|
||||
version "0.1.6"
|
||||
resolved "https://registry.yarnpkg.com/create-react-context/-/create-react-context-0.1.6.tgz#0f425931d907741127acc6e31acb4f9015dd9fdc"
|
||||
|
||||
cross-spawn@^3.0.0:
|
||||
version "3.0.1"
|
||||
resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-3.0.1.tgz#1256037ecb9f0c5f79e3d6ef135e30770184b982"
|
||||
|
|
@ -2915,7 +2919,7 @@ interpret@^1.1.0:
|
|||
version "1.1.0"
|
||||
resolved "https://registry.yarnpkg.com/interpret/-/interpret-1.1.0.tgz#7ed1b1410c6a0e0f78cf95d3b8440c63f78b8614"
|
||||
|
||||
invariant@^2.0.0, invariant@^2.2.1, invariant@^2.2.2, invariant@^2.2.4:
|
||||
invariant@^2.2.1, invariant@^2.2.2, invariant@^2.2.4:
|
||||
version "2.2.4"
|
||||
resolved "https://registry.yarnpkg.com/invariant/-/invariant-2.2.4.tgz#610f3c92c9359ce1db616e538008d23ff35158e6"
|
||||
dependencies:
|
||||
|
|
@ -3352,10 +3356,6 @@ locate-path@^2.0.0:
|
|||
p-locate "^2.0.0"
|
||||
path-exists "^3.0.0"
|
||||
|
||||
lodash-es@^4.17.5:
|
||||
version "4.17.10"
|
||||
resolved "https://registry.yarnpkg.com/lodash-es/-/lodash-es-4.17.10.tgz#62cd7104cdf5dd87f235a837f0ede0e8e5117e05"
|
||||
|
||||
lodash.assign@^4.2.0:
|
||||
version "4.2.0"
|
||||
resolved "https://registry.yarnpkg.com/lodash.assign/-/lodash.assign-4.2.0.tgz#0d99f3ccd7a6d261d19bdaeb9245005d285808e7"
|
||||
|
|
@ -4379,17 +4379,6 @@ react-dom@^16.4.1:
|
|||
object-assign "^4.1.1"
|
||||
prop-types "^15.6.0"
|
||||
|
||||
react-redux@^5.0.7:
|
||||
version "5.0.7"
|
||||
resolved "https://registry.yarnpkg.com/react-redux/-/react-redux-5.0.7.tgz#0dc1076d9afb4670f993ffaef44b8f8c1155a4c8"
|
||||
dependencies:
|
||||
hoist-non-react-statics "^2.5.0"
|
||||
invariant "^2.0.0"
|
||||
lodash "^4.17.5"
|
||||
lodash-es "^4.17.5"
|
||||
loose-envify "^1.1.0"
|
||||
prop-types "^15.6.0"
|
||||
|
||||
react-router-dom@^4.3.1:
|
||||
version "4.3.1"
|
||||
resolved "https://registry.yarnpkg.com/react-router-dom/-/react-router-dom-4.3.1.tgz#4c2619fc24c4fa87c9fd18f4fb4a43fe63fbd5c6"
|
||||
|
|
@ -4486,13 +4475,6 @@ redux-logger@^3.0.6:
|
|||
dependencies:
|
||||
deep-diff "^0.3.5"
|
||||
|
||||
redux@^4.0.0:
|
||||
version "4.0.0"
|
||||
resolved "https://registry.yarnpkg.com/redux/-/redux-4.0.0.tgz#aa698a92b729315d22b34a0553d7e6533555cc03"
|
||||
dependencies:
|
||||
loose-envify "^1.1.0"
|
||||
symbol-observable "^1.2.0"
|
||||
|
||||
regenerate@^1.2.1:
|
||||
version "1.4.0"
|
||||
resolved "https://registry.yarnpkg.com/regenerate/-/regenerate-1.4.0.tgz#4a856ec4b56e4077c557589cae85e7a4c8869a11"
|
||||
|
|
@ -5204,10 +5186,6 @@ supports-color@^5.1.0, supports-color@^5.3.0, supports-color@^5.4.0:
|
|||
dependencies:
|
||||
has-flag "^3.0.0"
|
||||
|
||||
symbol-observable@^1.2.0:
|
||||
version "1.2.0"
|
||||
resolved "https://registry.yarnpkg.com/symbol-observable/-/symbol-observable-1.2.0.tgz#c22688aed4eab3cdc2dfeacbb561660560a00804"
|
||||
|
||||
table@4.0.2:
|
||||
version "4.0.2"
|
||||
resolved "https://registry.yarnpkg.com/table/-/table-4.0.2.tgz#a33447375391e766ad34d3486e6e2aedc84d2e36"
|
||||
|
|
@ -5419,6 +5397,12 @@ unset-value@^1.0.0:
|
|||
has-value "^0.3.1"
|
||||
isobject "^3.0.0"
|
||||
|
||||
unstated@^2.1.1:
|
||||
version "2.1.1"
|
||||
resolved "https://registry.yarnpkg.com/unstated/-/unstated-2.1.1.tgz#36b124dfb2e7a12d39d0bb9c46dfb6e51276e3a2"
|
||||
dependencies:
|
||||
create-react-context "^0.1.5"
|
||||
|
||||
upath@^1.0.5:
|
||||
version "1.1.0"
|
||||
resolved "https://registry.yarnpkg.com/upath/-/upath-1.1.0.tgz#35256597e46a581db4793d0ce47fa9aebfc9fabd"
|
||||
|
|
|
|||
Loading…
Reference in a new issue