wappsto-blanket
Advanced tools
Comparing version 1.0.0 to 1.1.0
@@ -0,13 +1,20 @@ | ||
export { default as useEntitySelector } from './useAlwaysSubscribe'; | ||
export { default as useEntitySelector } from './useEntitiesSelector'; | ||
export { default as useEntitySelector } from './useEntitySelector'; | ||
export { default as useIds } from './useIds'; | ||
export { default as useList } from './useList'; | ||
export { default as useLogs } from './useLogs'; | ||
export { default as useMetrics } from './useMetrics'; | ||
export { default as usePrevious } from './usePrevious'; | ||
export { default as useRefresh } from './useRefresh'; | ||
export { default as useRefreshTimestamp } from './useRefreshTimestamp'; | ||
export { default as useRequest } from './useRequest'; | ||
export { default as useSubscribe } from './useSubscribe'; | ||
export { default as useVisible } from './useVisible'; | ||
export { default as useFetchItems } from './useFetchItems'; | ||
export { default as usePagination } from './usePagination'; | ||
export { default as useEntitySelector } from './useFetchItems'; | ||
export { default as useEntitySelector } from './useIds'; | ||
export { default as useEntitySelector } from './useItemSelector'; | ||
export { default as useEntitySelector } from './useList'; | ||
export { default as useEntitySelector } from './useLogs'; | ||
export { default as useEntitySelector } from './useMetrics'; | ||
export { default as useEntitySelector } from './useMountedRef'; | ||
export { default as useEntitySelector } from './usePagination'; | ||
export { default as useEntitySelector } from './usePathSubscribe'; | ||
export { default as useEntitySelector } from './usePrevious'; | ||
export { default as useEntitySelector } from './useRefresh'; | ||
export { default as useEntitySelector } from './useRefreshTimestamp'; | ||
export { default as useEntitySelector } from './useRequest'; | ||
export { default as useEntitySelector } from './useStoreItem'; | ||
export { default as useEntitySelector } from './useStorePagination'; | ||
export { default as useEntitySelector } from './useSubscribe'; | ||
export { default as useEntitySelector } from './useVisible'; |
@@ -1,11 +0,12 @@ | ||
import { useState, useEffect } from 'react'; | ||
import { useState, useEffect, useMemo } from 'react'; | ||
import { useStore } from 'react-redux'; | ||
import { findRequest, startRequest } from 'wappsto-redux/actions/request'; | ||
import { startRequest } from 'wappsto-redux/actions/request'; | ||
import { addEntities } from 'wappsto-redux/actions/entities'; | ||
import { getSession } from 'wappsto-redux/selectors/session'; | ||
import { ITEMS_PER_SLICE } from '../util'; | ||
import querystring from 'query-string'; | ||
const ITEMS_PER_SLICE = 100; | ||
const CHILDREN = { 'network': 'device', 'device': 'value', 'value': 'state' } | ||
const fetch = async (ids, type, store, lvl = 0) => { | ||
const fetch = async (ids, type, store, query, lvl = 0, useCache) => { | ||
const state = store.getState(); | ||
@@ -15,3 +16,3 @@ const uniqIds = [...new Set(ids)]; | ||
let missingIds; | ||
if (state.entities[type+'s']) { | ||
if (useCache && state.entities[type+'s']) { | ||
missingIds = uniqIds.filter(id => !state.entities[type+'s'][id]); | ||
@@ -30,12 +31,6 @@ } else { | ||
const promises = slices.map((e) => { | ||
const url = `/${type}?expand=0&id=[${e.join(',')}]&from_last=true`; | ||
const existingRequest = findRequest(state, url, 'GET'); | ||
if (existingRequest) { | ||
const promise = state.request[existingRequest].promise; | ||
return promise; | ||
} else { | ||
const session = getSession(state); | ||
const { promise } = startRequest(store.dispatch, url, 'GET', null, {}, session); | ||
return promise; | ||
} | ||
const url = `/${type}?expand=0&id=[${e.join(',')}]&${querystring.stringify(query)}`; | ||
const session = getSession(state); | ||
const promise = startRequest(store.dispatch, { url, method: 'GET' }, session); | ||
return promise; | ||
}); | ||
@@ -56,10 +51,10 @@ | ||
const cachedResults = state.entities[type+'s']; | ||
if (cachedResults) { | ||
if (useCache && cachedResults) { | ||
const cachedIds = uniqIds.filter(id => state.entities[type+'s'][id]); | ||
cachedIds.forEach((e) => { | ||
const item = cachedResults[e]; | ||
if (item) { | ||
itemList = [...itemList, item]; | ||
if (item && !itemList.find(i => i.meta.id === e)) { | ||
itemList.push(item); | ||
} | ||
}) | ||
}); | ||
} | ||
@@ -69,3 +64,3 @@ | ||
const itemListIds = itemList.reduce((arr, e) => [...arr, ...(e[CHILDREN[type]] || [])], []); | ||
const result = await fetch(itemListIds, CHILDREN[type], store, lvl-1); | ||
const result = await fetch(itemListIds, CHILDREN[type], store, query, lvl-1, useCache); | ||
return { [type]: itemList, ...result }; | ||
@@ -77,5 +72,19 @@ } else { | ||
const useFetchItems = (objIds, expand) => { | ||
const useFetchItems = (objIds, query, useCache=true) => { | ||
const store = useStore(); | ||
const [[status, items], setState] = useState(['pending', {}]); | ||
const [queryClone, lvl] = useMemo(() => { | ||
if(query && query.constructor === Object){ | ||
const queryClone = {...query}; | ||
const lvl = queryClone.expand; | ||
if(queryClone.hasOwnProperty('expand')){ | ||
delete queryClone.expand; | ||
} | ||
if(!queryClone.hasOwnProperty('from_last')){ | ||
queryClone.from_last = true; | ||
} | ||
return [queryClone, lvl]; | ||
} | ||
return [null, query]; | ||
}, [query]); | ||
@@ -93,7 +102,7 @@ useEffect(() => { | ||
if (CHILDREN[type] || type === 'state') { | ||
const response = await fetch(ids, type, store, expand); | ||
const response = await fetch(ids, type, store, queryClone, lvl, useCache); | ||
items[type] = response; | ||
} else { | ||
const response = await fetch(ids, type, store, 0); | ||
items = response[type]; | ||
const response = await fetch(ids, type, store, queryClone, 0, useCache); | ||
Object.assign(items, response); | ||
} | ||
@@ -114,3 +123,3 @@ } | ||
// eslint-disable-next-line react-hooks/exhaustive-deps | ||
}, [objIds, expand]); | ||
}, [objIds, query]); | ||
@@ -117,0 +126,0 @@ return { status, items }; |
@@ -1,3 +0,3 @@ | ||
import { useState, useEffect, useRef, useCallback, useMemo } from 'react'; | ||
import { useSelector, useDispatch } from 'react-redux'; | ||
import { useState, useRef, useCallback, useMemo } from 'react'; | ||
import { useSelector, useDispatch, useStore } from 'react-redux'; | ||
@@ -7,5 +7,7 @@ import { setItem } from 'wappsto-redux/actions/items'; | ||
import { makeItemSelector } from 'wappsto-redux/selectors/items'; | ||
import { getSession } from 'wappsto-redux/selectors/session'; | ||
import { startRequest } from 'wappsto-redux/actions/request'; | ||
import usePrevious from '../hooks/usePrevious'; | ||
import useRequest from '../hooks/useRequest'; | ||
import { matchArray, matchObject } from '../util'; | ||
import { ITEMS_PER_SLICE } from '../util'; | ||
import equal from 'deep-equal'; | ||
@@ -20,3 +22,30 @@ const itemName = 'useIds_status'; | ||
function useIds(service, ids, query){ | ||
const sendGetIds = (store, ids, service, query, sliceLength) => { | ||
const res = []; | ||
const slices = Math.ceil(ids.length / sliceLength); | ||
for(let i = 0; i < slices; i++){ | ||
res.push(ids.slice(i * sliceLength, (i + 1) * sliceLength)); | ||
} | ||
const state = store.getState(); | ||
const session = getSession(state); | ||
res.forEach(arr => { | ||
const options = { | ||
url: '/' + service, | ||
method: 'GET', | ||
query: { | ||
...query, | ||
id: arr | ||
} | ||
} | ||
const promise = startRequest(store.dispatch, options, session); | ||
promise.then(result => { | ||
setCacheStatus(store.dispatch, arr, result.ok ? 'success' : 'error', query); | ||
}).catch(() => { | ||
setCacheStatus(store.dispatch, arr, 'error', query); | ||
}); | ||
}); | ||
} | ||
function useIds(service, ids, query={}, sliceLength=ITEMS_PER_SLICE){ | ||
const store = useStore(); | ||
const [ status, setStatus ] = useState('idle'); | ||
@@ -30,7 +59,7 @@ const prevStatus = usePrevious(status); | ||
const getItem = useMemo(makeItemSelector, []); | ||
const cacheItems = useSelector(state => getEntities(state, service, { filter: ids.map(id => ({ meta: { id: id } }))})); | ||
const cacheItems = useSelector(state => getEntities(state, service, ids)); | ||
const idsStatus = useSelector(state => getItem(state, itemName)); | ||
const updateMissingIds = useCallback(() => { | ||
if(matchArray(ids, prevIds)){ | ||
if(equal(ids, prevIds)){ | ||
return; | ||
@@ -45,3 +74,3 @@ } | ||
const cQ = {...query, expand: null}; | ||
if(!matchObject(cidQ, cQ) || cid.query.expand < query.expand || cid.status === 'error' || cid.status === 'idle'){ | ||
if(!equal(cidQ, cQ) || cid.query.expand < query.expand || cid.status === 'error' || cid.status === 'idle'){ | ||
arr.push(id); | ||
@@ -69,36 +98,15 @@ } | ||
const { request, send, removeRequest } = useRequest(); | ||
const getMissingIds = (checkIds = true) => { | ||
if(checkIds && matchArray(ids, prevIds)){ | ||
if(checkIds && equal(ids, prevIds)){ | ||
return; | ||
} | ||
const prevMissingIds = updateMissingIds(); | ||
updateMissingIds(); | ||
if(missingIds.current.length > 0){ | ||
if(request && request.status === 'pending' && prevMissingIds.length > 0){ | ||
setCacheStatus(dispatch, prevMissingIds, '', query); | ||
} | ||
removeRequest(); | ||
setCacheStatus(dispatch, missingIds.current, 'pending', query); | ||
send({ | ||
method: 'GET', | ||
url: '/' + service, | ||
query: { | ||
...query, | ||
id: missingIds.current | ||
} | ||
}); | ||
sendGetIds(store, missingIds.current, service, query, sliceLength); | ||
} | ||
} | ||
// Update cache when request is over | ||
useEffect(() => { | ||
if(request){ | ||
setCacheStatus(dispatch, missingIds.current, request.status, query); | ||
} | ||
// eslint-disable-next-line react-hooks/exhaustive-deps | ||
}, [request]); | ||
// Make request to get the ids | ||
useEffect(() => { | ||
useMemo(() => { | ||
getMissingIds(); | ||
@@ -109,3 +117,3 @@ // eslint-disable-next-line react-hooks/exhaustive-deps | ||
// Update status | ||
useEffect(() => { | ||
useMemo(() => { | ||
if(status !== 'success' || prevIds !== ids){ | ||
@@ -130,3 +138,3 @@ for(let i = 0; i < ids.length; i++){ | ||
useEffect(() => { | ||
useMemo(() => { | ||
if(status === 'success'){ | ||
@@ -133,0 +141,0 @@ setItems(cacheItems); |
@@ -59,4 +59,4 @@ import { useState, useEffect, useCallback, useRef, useMemo } from 'react'; | ||
} | ||
} else { | ||
url = '/' + type; | ||
} else if(type){ | ||
url = '/' + type; | ||
if(id){ | ||
@@ -98,3 +98,3 @@ if(id.startsWith('?')){ | ||
const [ customRequest, setCustomRequest ] = useState({ status: 'pending', options: { query: props.query } }); | ||
const [ customRequest, setCustomRequest ] = useState({ status: propsData.url ? 'pending' : 'success', options: { query: props.query } }); | ||
const name = props.name || (propsData.url + JSON.stringify(propsData.query)); | ||
@@ -105,8 +105,5 @@ const idsItemName = name + '_ids'; | ||
const savedIds = useSelector(state => getSavedIdsItem(state, idsItemName)) || empty; | ||
const cachedRequestId = requestIdCache[requestIdName]; | ||
const { request, requestId, setRequestId, send } = useRequest(); | ||
const { request, send } = useRequest(requestIdName, true); | ||
if(cachedRequestId && requestId !== cachedRequestId){ | ||
setRequestId(cachedRequestId); | ||
} if(!cachedRequestId && customRequest.status !== 'pending'){ | ||
if(propsData.url && !request && customRequest.status !== 'pending'){ | ||
setCustomRequest({ status: 'pending', options: { query: props.query } }); | ||
@@ -117,3 +114,3 @@ } | ||
const options = { filter: savedIds, limit: savedIds.length }; | ||
const options = { ids: savedIds, limit: savedIds.length }; | ||
@@ -150,3 +147,3 @@ const getEntities = useMemo(makeEntitiesSelector, []); | ||
setCustomRequest({ status: 'pending', options: options }); | ||
const crid = send({ | ||
send({ | ||
method: 'GET', | ||
@@ -156,5 +153,4 @@ url: propsData.url, | ||
}); | ||
requestIdCache[requestIdName] = crid; | ||
} | ||
}, [propsData.url, requestIdName, send]); | ||
}, [propsData.url, send]); | ||
@@ -174,7 +170,5 @@ const refresh = useCallback((reset) => { | ||
useEffect(() => { | ||
if(props.useCache === false || !cachedRequestId || (savedIds === empty && !request) || (request && request.status === 'error')){ | ||
if(props.useCache === false || !request || (savedIds === empty && !request) || (request && request.status === 'error')){ | ||
refresh(props.reset); | ||
} else if(cachedRequestId !== requestId){ | ||
setRequestId(cachedRequestId); | ||
} | ||
} | ||
// eslint-disable-next-line react-hooks/exhaustive-deps | ||
@@ -192,3 +186,3 @@ }, [propsData.query, props.id, propsData.url, refresh, props.useCache]); | ||
if(request.json.constructor === Array){ | ||
ids = [...(ids || []), ...request.json.map(item => item.constructor === Object ? ({ meta: { id: item.meta.id }}) : ({ meta: { id: item }}))]; | ||
ids = [...(ids || []), ...request.json.map(item => item.constructor === Object ? item.meta.id : item)]; | ||
} else if(request.json.meta.type === 'attributelist'){ | ||
@@ -252,19 +246,23 @@ ids = [propsData.id]; | ||
const addItem = useCallback((id, position = 'start') => { | ||
const found = savedIds.find(obj => obj.meta.id === id); | ||
const found = savedIds.find(existingId => existingId === id); | ||
if(!found){ | ||
dispatch(setItem(idsItemName, (ids = []) => { | ||
if(position === 'start'){ | ||
return [{ meta: { id }}, ...ids]; | ||
return [id, ...ids]; | ||
} else { | ||
return [...ids, { meta: { id }}]; | ||
return [...ids, id]; | ||
} | ||
})); | ||
return true; | ||
} | ||
return false; | ||
}, [dispatch, idsItemName, savedIds]); | ||
const removeItem = useCallback((id) => { | ||
const index = savedIds.findIndex(obj => obj.meta.id === id); | ||
const index = savedIds.findIndex(existingId => existingId === id); | ||
if(index !== -1){ | ||
dispatch(setItem(idsItemName, (ids = []) => [...ids.slice(0, index), ...ids.slice(index + 1)])); | ||
return true; | ||
} | ||
return false; | ||
}, [dispatch, idsItemName, savedIds]); | ||
@@ -271,0 +269,0 @@ |
@@ -7,2 +7,3 @@ import { useState, useRef, useCallback, useEffect } from 'react'; | ||
import axios from 'axios'; | ||
import equal from 'deep-equal'; | ||
@@ -19,3 +20,5 @@ const CancelToken = axios.CancelToken; | ||
function useLogs(stateId, sessionId){ | ||
const cache = {}; | ||
function useLogs(stateId, sessionId, cacheId){ | ||
const [ data, setData ] = useState([]); | ||
@@ -43,2 +46,7 @@ const cachedData = useRef([]); | ||
} | ||
if(cacheId && cache[cacheId] && equal(cache[cacheId].options, options)){ | ||
setData(cache[cacheId].data); | ||
setCurrentStatus(cache[cacheId].status); | ||
return true; | ||
} | ||
if(cOptions.start.constructor === Date){ | ||
@@ -57,3 +65,3 @@ cOptions.start = cOptions.start.toISOString(); | ||
try{ | ||
while(more && !isCanceled.current && !unmounted.current){ | ||
while(more && !isCanceled.current && (cacheId || (!cacheId && !unmounted.current))){ | ||
if(cachedData.current.length > 0){ | ||
@@ -76,2 +84,9 @@ const last = cachedData.current[cachedData.current.length - 1]; | ||
} | ||
if(cacheId){ | ||
cache[cacheId] = { | ||
data: cachedData.current, | ||
options: options, | ||
status: STATUS.SUCCESS | ||
}; | ||
} | ||
if(unmounted.current){ | ||
@@ -85,2 +100,9 @@ return; | ||
} catch(e){ | ||
if(cacheId){ | ||
cache[cacheId] = { | ||
data: cachedData.current, | ||
options: options, | ||
status: STATUS.ERROR | ||
}; | ||
} | ||
if(unmounted.current){ | ||
@@ -114,6 +136,9 @@ return; | ||
const reset = useCallback(() => { | ||
const reset = useCallback((resetCache = true) => { | ||
if(cancelFunc.current){ | ||
cancelFunc.current('Operation canceled'); | ||
} | ||
if(cacheId && resetCache){ | ||
delete cache[cacheId]; | ||
} | ||
setData([]); | ||
@@ -123,3 +148,3 @@ setCurrentStatus(STATUS.IDLE); | ||
cachedData.current = []; | ||
}, []); | ||
}, [cacheId]); | ||
@@ -126,0 +151,0 @@ return { data, status, getLogs, reset, cancel }; |
import { useState, useEffect, useRef } from 'react'; | ||
import { useStore } from 'react-redux'; | ||
import useRequest from './useRequest'; | ||
import { findRequest, startRequest, STATUS } from 'wappsto-redux/actions/request'; | ||
import { startRequest, STATUS } from 'wappsto-redux/actions/request'; | ||
import { getSession } from 'wappsto-redux/selectors/session'; | ||
@@ -20,3 +20,7 @@ | ||
const v = query[k]; | ||
urlInstance.searchParams.set(k, v); | ||
if(v !== null){ | ||
urlInstance.searchParams.set(k, v); | ||
} else{ | ||
urlInstance.searchParams.delete(k); | ||
} | ||
} | ||
@@ -46,12 +50,4 @@ urlInstance.searchParams.set('limit', pageSize); | ||
const fireRequest = (state, url, store, session, requestsRef, key) => { | ||
let id, promise; | ||
id = findRequest(state, url, 'GET'); | ||
if(id){ | ||
promise = state.request[id].promise; | ||
} else { | ||
const req = startRequest(store.dispatch, url, 'GET', null, { reset: false }, session); | ||
promise = req.promise; | ||
id = req.id; | ||
} | ||
requestsRef.current[key] = { promise, id, status: STATUS.pending }; | ||
const promise = startRequest(store.dispatch, { url, method: 'GET' }, session); | ||
requestsRef.current[key] = { promise, status: STATUS.pending }; | ||
return promise; | ||
@@ -104,3 +100,3 @@ } | ||
const usePagination = ({ url, query={}, page: pageNo=1, pageSize=MAX_PER_PAGE, useCache=true }) => { | ||
const usePagination = ({ url, query, page: pageNo=1, pageSize=MAX_PER_PAGE, useCache=true }) => { | ||
const store = useStore(); | ||
@@ -112,5 +108,6 @@ const [status, setStatus] = useState(); | ||
const mounted = useRef(true); | ||
const skipPageChange = useRef(false); | ||
const requestsRef = useRef({ items: null, count: null }); | ||
const start = (resetCache) => { | ||
const start = (currentPage=page, resetCache) => { | ||
requestsRef.current = { items: { status: STATUS.pending }, count: { status: STATUS.pending } }; | ||
@@ -121,3 +118,3 @@ mounted.current = true; | ||
const promise1 = getPageCount({ store, url, requestsRef, resetCache, useCache }); | ||
const { promise: promise2, cacheUrl } = getItems({ store, url, query, pageSize, page, requestsRef, resetCache, useCache }); | ||
const { promise: promise2, cacheUrl } = getItems({ store, url, query, pageSize, page: currentPage, requestsRef, resetCache, useCache }); | ||
@@ -159,8 +156,12 @@ Promise.all([promise1, promise2]).then(([resCount, resItems]) => { | ||
} | ||
cache.pageRequests[cacheUrl].pages[page] = itemsRes; | ||
if (page > 1 && !itemsRes.length) { | ||
setPage(page-1); | ||
cache.pageRequests[cacheUrl].pages[currentPage] = itemsRes; | ||
if (currentPage > 1 && !itemsRes.length) { | ||
setPage(1); | ||
return; | ||
} | ||
if (mounted.current) { | ||
if(currentPage !== page){ | ||
skipPageChange.current = true; | ||
setPage(currentPage); | ||
} | ||
setCount(countRes.count); | ||
@@ -180,3 +181,3 @@ setStatus(STATUS.success); | ||
const refresh = () => { | ||
start(true); | ||
start(null, true); | ||
} | ||
@@ -209,7 +210,9 @@ | ||
} | ||
Object.keys(pagesCache).forEach(pageNumber => { | ||
if(pageNumber > currentPage){ | ||
pagesCache[pageNumber].invalid = true | ||
} | ||
}); | ||
if(currentPage * pageSize < cache.countRequests[url].count){ | ||
Object.keys(pagesCache).forEach(pageNumber => { | ||
if(pageNumber > currentPage){ | ||
pagesCache[pageNumber].invalid = true | ||
} | ||
}); | ||
} | ||
setCount(cache.countRequests[url].count); | ||
@@ -237,7 +240,9 @@ const pageItems = cache.pageRequests[cacheUrl].pages[page]; | ||
Object.keys(pagesCache).forEach(pageNumber => { | ||
if(pageNumber >= currentPage){ | ||
pagesCache[pageNumber].invalid = true; | ||
} | ||
}); | ||
if(currentPage * pageSize < cache.countRequests[url].count){ | ||
Object.keys(pagesCache).forEach(pageNumber => { | ||
if(pageNumber >= currentPage){ | ||
pagesCache[pageNumber].invalid = true; | ||
} | ||
}); | ||
} | ||
} | ||
@@ -280,7 +285,16 @@ | ||
useEffect(() => { | ||
if(skipPageChange.current){ | ||
skipPageChange.current = false; | ||
return; | ||
} | ||
start(); | ||
return () => mounted.current = false; | ||
// eslint-disable-next-line react-hooks/exhaustive-deps | ||
}, [url, page, store, pageSize]); | ||
}, [page, store, pageSize]); | ||
useEffect(() => { | ||
start(1); | ||
// eslint-disable-next-line react-hooks/exhaustive-deps | ||
}, [url, query]); | ||
return { items, count, page, setPage, refresh, status, requests: requestsRef.current, addItem, removeItem }; | ||
@@ -287,0 +301,0 @@ } |
@@ -5,6 +5,9 @@ import { useMemo, useState, useCallback, useEffect } from 'react'; | ||
import { makeRequest, removeRequest as removeStoreRequest } from 'wappsto-redux/actions/request'; | ||
import uuidv4 from 'uuid/v4'; | ||
const useRequestSelector = (removeOldRequest=true) => { | ||
const useRequest = (id, removeOldRequest) => { | ||
const dispatch = useDispatch(); | ||
const [ requestId, setRequestId ] = useState(); | ||
const [ requestId, setRequestId ] = useState(() => { | ||
return id || uuidv4(); | ||
}); | ||
const getRequest = useMemo(makeRequestSelector, []); | ||
@@ -17,13 +20,11 @@ const request = useSelector(state => getRequest(state, requestId)); | ||
const send = useCallback((...args) => { | ||
const newId = dispatch(makeRequest(...args)); | ||
setRequestId(newId); | ||
return newId; | ||
}, [dispatch]); | ||
const send = useCallback((obj) => { | ||
return dispatch(makeRequest({...obj, id: requestId})); | ||
}, [dispatch, requestId]); | ||
useEffect(() => () => { | ||
if(removeOldRequest && requestId){ | ||
if((removeOldRequest && requestId) || (!id && removeOldRequest !== false)){ | ||
removeRequest(); | ||
} | ||
}, [removeOldRequest, requestId, removeRequest]); | ||
}, [removeOldRequest, requestId, removeRequest, id]); | ||
@@ -33,2 +34,2 @@ return { request, requestId, setRequestId, send, removeRequest }; | ||
export default useRequestSelector; | ||
export default useRequest; |
{ | ||
"name": "wappsto-blanket", | ||
"version": "1.0.0", | ||
"version": "1.1.0", | ||
"description": "", | ||
@@ -17,3 +17,6 @@ "scripts": { | ||
}, | ||
"homepage": "https://github.com/Wappsto/wappsto-blanket#readme" | ||
"homepage": "https://github.com/Wappsto/wappsto-blanket#readme", | ||
"dependencies": { | ||
"uuid": "^8.3.1" | ||
} | ||
} |
@@ -5,2 +5,4 @@ import { getServiceVersion } from 'wappsto-redux/util/helpers'; | ||
export const ITEMS_PER_SLICE = 100; | ||
export function getLastKey(data){ | ||
@@ -7,0 +9,0 @@ if(!data){ |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
49215
25
1436
1
+ Addeduuid@^8.3.1
+ Addeduuid@8.3.2(transitive)