Skip to content

Commit

Permalink
chore: Reorganize code to core + react
Browse files Browse the repository at this point in the history
  • Loading branch information
tannerlinsley committed Jun 26, 2020
1 parent bcecb54 commit 2de8528
Show file tree
Hide file tree
Showing 33 changed files with 311 additions and 292 deletions.
10 changes: 6 additions & 4 deletions rollup.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,11 @@ const globals = {
react: 'React',
}

const inputSrc = 'src/react/index.js'

export default [
{
input: 'src/index.js',
input: inputSrc,
output: {
file: 'dist/react-query.mjs',
format: 'es',
Expand All @@ -25,7 +27,7 @@ export default [
plugins: [resolve(), babel(), commonJS(), externalDeps()],
},
{
input: 'src/index.js',
input: inputSrc,
output: {
file: 'dist/react-query.min.mjs',
format: 'es',
Expand All @@ -35,7 +37,7 @@ export default [
plugins: [resolve(), babel(), commonJS(), externalDeps(), terser()],
},
{
input: 'src/index.js',
input: inputSrc,
output: {
name: 'ReactQuery',
file: 'dist/react-query.development.js',
Expand All @@ -47,7 +49,7 @@ export default [
plugins: [resolve(), babel(), commonJS(), externalDeps()],
},
{
input: 'src/index.js',
input: inputSrc,
output: {
name: 'ReactQuery',
file: 'dist/react-query.production.min.js',
Expand Down
62 changes: 5 additions & 57 deletions src/config.js → src/core/config.js
Original file line number Diff line number Diff line change
@@ -1,9 +1,6 @@
import React from 'react'
import { noop, stableStringify, identity, deepEqual } from './utils'

export const configContext = React.createContext()

const DEFAULT_CONFIG = {
export const DEFAULT_CONFIG = {
shared: {
suspense: false,
},
Expand Down Expand Up @@ -40,59 +37,6 @@ export const defaultConfigRef = {
current: DEFAULT_CONFIG,
}

export function useConfigContext() {
return React.useContext(configContext) || defaultConfigRef.current
}

export function ReactQueryConfigProvider({ config, children }) {
let configContextValue = useConfigContext()

const newConfig = React.useMemo(() => {
const { shared = {}, queries = {}, mutations = {} } = config
const {
shared: contextShared = {},
queries: contextQueries = {},
mutations: contextMutations = {},
} = configContextValue

return {
shared: {
...contextShared,
...shared,
},
queries: {
...contextQueries,
...queries,
},
mutations: {
...contextMutations,
...mutations,
},
}
}, [config, configContextValue])

React.useEffect(() => {
// restore previous config on unmount
return () => {
defaultConfigRef.current = { ...(configContextValue || DEFAULTS) }
}
}, [configContextValue])

if (!configContextValue) {
defaultConfigRef.current = newConfig
}

return (
<configContext.Provider value={newConfig}>
{children}
</configContext.Provider>
)
}

function invalidQueryKey() {
throw new Error('A valid query key is required!')
}

export function defaultQueryKeySerializerFn(queryKey) {
if (!queryKey) {
invalidQueryKey()
Expand All @@ -115,3 +59,7 @@ export function defaultQueryKeySerializerFn(queryKey) {

return [queryHash, queryKey]
}

function invalidQueryKey() {
throw new Error('A valid query key is required!')
}
11 changes: 11 additions & 0 deletions src/core/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
export { queryCache, queryCaches, makeQueryCache } from './queryCache'
export { setFocusHandler } from './setFocusHandler'
export {
statusIdle,
statusLoading,
statusSuccess,
statusError,
stableStringify,
setConsole,
deepIncludes,
} from './utils'
36 changes: 2 additions & 34 deletions src/queryCache.js → src/core/queryCache.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import React from 'react'
import {
isServer,
functionalUpdate,
Expand All @@ -15,45 +14,13 @@ import {
Console,
isObject,
} from './utils'

import { defaultConfigRef } from './config'

export const queryCache = makeQueryCache()

export const queryCacheContext = React.createContext(queryCache)

export const queryCaches = [queryCache]

export const useQueryCache = () => React.useContext(queryCacheContext)

export function ReactQueryCacheProvider({ queryCache, children }) {
const resolvedQueryCache = React.useMemo(
() => queryCache || makeQueryCache(),
[queryCache]
)

React.useEffect(() => {
queryCaches.push(resolvedQueryCache)

return () => {
// remove the cache from the active list
const i = queryCaches.indexOf(resolvedQueryCache)
if (i > -1) {
queryCaches.splice(i, 1)
}
// if the resolvedQueryCache was created by us, we need to tear it down
if (queryCache == null) {
resolvedQueryCache.clear()
}
}
}, [resolvedQueryCache, queryCache])

return (
<queryCacheContext.Provider value={resolvedQueryCache}>
{children}
</queryCacheContext.Provider>
)
}

const actionInit = 'Init'
const actionFailed = 'Failed'
const actionMarkStale = 'MarkStale'
Expand Down Expand Up @@ -248,6 +215,7 @@ export function makeQueryCache({ frozen = isServer, defaultConfig } = {}) {
if (throwOnError) {
throw err
}
Console.error(err)
}
}

Expand Down
File renamed without changes.
File renamed without changes.
File renamed without changes.
44 changes: 44 additions & 0 deletions src/core/tests/utils.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
import { setConsole, queryCache, queryCaches } from '../'
import { deepEqual } from '../utils'

describe('core/utils', () => {
afterEach(() => {
queryCaches.forEach(cache => cache.clear())
})

it('setConsole should override Console object', async () => {
const mockConsole = {
error: jest.fn(),
}

setConsole(mockConsole)

await queryCache.prefetchQuery(
'key',
async () => {
throw new Error('Test')
},
{
retry: 0,
}
)

expect(mockConsole.error).toHaveBeenCalled()

setConsole(console)
})

it('deepequal should return `false` for different dates', () => {
const date1 = new Date(2020, 3, 1)
const date2 = new Date(2020, 3, 2)

expect(deepEqual(date1, date2)).toEqual(false)
})

it('should return `true` for equal dates', () => {
const date1 = new Date(2020, 3, 1)
const date2 = new Date(2020, 3, 1)

expect(deepEqual(date1, date2)).toEqual(true)
})
})
70 changes: 0 additions & 70 deletions src/utils.js → src/core/utils.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,3 @@
import React from 'react'
import { useConfigContext } from './config'

//

export const statusIdle = 'idle'
export const statusLoading = 'loading'
export const statusError = 'error'
Expand All @@ -21,27 +16,10 @@ export function identity(d) {
}
export let Console = console || { error: noop, warn: noop, log: noop }

export function useUid() {
const ref = React.useRef(null)

if (ref.current === null) {
ref.current = uid()
}

return ref.current
}

export function setConsole(c) {
Console = c
}

export function useGetLatest(obj) {
const ref = React.useRef()
ref.current = obj

return React.useCallback(() => ref.current, [])
}

export function functionalUpdate(updater, old) {
return typeof updater === 'function' ? updater(old) : updater
}
Expand Down Expand Up @@ -112,54 +90,6 @@ export function getQueryArgs(args) {
return [queryKey, queryFn ? { ...config, queryFn } : config, ...rest]
}

export function useQueryArgs(args) {
const configContext = useConfigContext()

let [queryKey, config, ...rest] = getQueryArgs(args)

// Build the final config
config = {
...configContext.shared,
...configContext.queries,
...config,
}

return [queryKey, config, ...rest]
}

export function useMountedCallback(callback) {
const mounted = React.useRef(false)

React[isServer ? 'useEffect' : 'useLayoutEffect'](() => {
mounted.current = true
return () => (mounted.current = false)
}, [])

return React.useCallback(
(...args) => (mounted.current ? callback(...args) : void 0),
[callback]
)
}

export function handleSuspense(queryInfo) {
if (
queryInfo.query.config.suspense ||
queryInfo.query.config.useErrorBoundary
) {
if (
queryInfo.query.state.status === statusError &&
queryInfo.query.state.throwInErrorBoundary
) {
throw queryInfo.error
}

if (queryInfo.query.config.suspense && queryInfo.status !== statusSuccess) {
queryInfo.query.wasSuspended = true
throw queryInfo.query.fetch()
}
}
}

// This deep-equal is directly based on https://github.com/epoberezkin/fast-deep-equal.
// The parts for comparing any non-JSON-supported values has been removed
export function deepEqual(a, b) {
Expand Down
23 changes: 0 additions & 23 deletions src/index.js

This file was deleted.

37 changes: 37 additions & 0 deletions src/react/ReactQueryCacheProvider.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
import React from 'react'
import { queryCache, makeQueryCache } from '../core'

export const queryCacheContext = React.createContext(queryCache)

export const queryCaches = [queryCache]

export const useQueryCache = () => React.useContext(queryCacheContext)

export function ReactQueryCacheProvider({ queryCache, children }) {
const resolvedQueryCache = React.useMemo(
() => queryCache || makeQueryCache(),
[queryCache]
)

React.useEffect(() => {
queryCaches.push(resolvedQueryCache)

return () => {
// remove the cache from the active list
const i = queryCaches.indexOf(resolvedQueryCache)
if (i > -1) {
queryCaches.splice(i, 1)
}
// if the resolvedQueryCache was created by us, we need to tear it down
if (queryCache == null) {
resolvedQueryCache.clear()
}
}
}, [resolvedQueryCache, queryCache])

return (
<queryCacheContext.Provider value={resolvedQueryCache}>
{children}
</queryCacheContext.Provider>
)
}
Loading

0 comments on commit 2de8528

Please sign in to comment.