Skip to content

Commit

Permalink
fix: support atom scope outside core (#589)
Browse files Browse the repository at this point in the history
  • Loading branch information
dai-shi committed Jul 15, 2021
1 parent 868f120 commit b6a7240
Show file tree
Hide file tree
Showing 17 changed files with 108 additions and 59 deletions.
50 changes: 25 additions & 25 deletions .size-snapshot.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,9 @@
}
},
"utils.js": {
"bundled": 13479,
"minified": 6775,
"gzipped": 2544,
"bundled": 13716,
"minified": 6895,
"gzipped": 2574,
"treeshaked": {
"rollup": {
"code": 28,
Expand Down Expand Up @@ -70,23 +70,23 @@
}
},
"query.js": {
"bundled": 5321,
"minified": 2315,
"gzipped": 721,
"bundled": 5444,
"minified": 2279,
"gzipped": 710,
"treeshaked": {
"rollup": {
"code": 105,
"code": 80,
"import_statements": 71
},
"webpack": {
"code": 1131
"code": 1093
}
}
},
"xstate.js": {
"bundled": 2977,
"minified": 1314,
"gzipped": 653,
"bundled": 3565,
"minified": 1470,
"gzipped": 684,
"treeshaked": {
"rollup": {
"code": 29,
Expand All @@ -98,9 +98,9 @@
}
},
"valtio.js": {
"bundled": 1235,
"minified": 598,
"gzipped": 335,
"bundled": 1333,
"minified": 642,
"gzipped": 350,
"treeshaked": {
"rollup": {
"code": 37,
Expand All @@ -112,9 +112,9 @@
}
},
"zustand.js": {
"bundled": 549,
"minified": 262,
"gzipped": 188,
"bundled": 647,
"minified": 306,
"gzipped": 204,
"treeshaked": {
"rollup": {
"code": 14,
Expand All @@ -126,9 +126,9 @@
}
},
"redux.js": {
"bundled": 458,
"minified": 220,
"gzipped": 167,
"bundled": 516,
"minified": 248,
"gzipped": 180,
"treeshaked": {
"rollup": {
"code": 14,
Expand All @@ -140,16 +140,16 @@
}
},
"urql.js": {
"bundled": 4312,
"minified": 2311,
"gzipped": 852,
"bundled": 4539,
"minified": 2369,
"gzipped": 856,
"treeshaked": {
"rollup": {
"code": 199,
"code": 170,
"import_statements": 85
},
"webpack": {
"code": 1387
"code": 1355
}
}
}
Expand Down
2 changes: 1 addition & 1 deletion src/query.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
export { queryClientAtom, getQueryClientAtom } from './query/queryClientAtom'
export { queryClientAtom } from './query/queryClientAtom'
export { atomWithQuery } from './query/atomWithQuery'
export { atomWithInfiniteQuery } from './query/atomWithInfiniteQuery'
export type {
Expand Down
16 changes: 12 additions & 4 deletions src/query/atomWithInfiniteQuery.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import {
QueryClient,
QueryKey,
InfiniteQueryObserver,
InfiniteQueryObserverOptions,
Expand All @@ -9,7 +10,7 @@ import {
} from 'react-query'
import { atom } from 'jotai'
import type { WritableAtom, Getter } from 'jotai'
import { getQueryClientAtom } from './queryClientAtom'
import { queryClientAtom } from './queryClientAtom'

export type AtomWithInfiniteQueryAction = {
type: 'refetch' | 'fetchNextPage' | 'fetchPreviousPage'
Expand Down Expand Up @@ -39,11 +40,12 @@ export function atomWithInfiniteQuery<
TError,
TData,
TQueryData
>)
>),
getQueryClient: (get: Getter) => QueryClient = (get) => get(queryClientAtom)
): WritableAtom<InfiniteData<TData | TQueryData>, AtomWithInfiniteQueryAction> {
const queryDataAtom = atom(
(get) => {
const queryClient = get(getQueryClientAtom)
const queryClient = getQueryClient(get)
const options =
typeof createQuery === 'function' ? createQuery(get) : createQuery
let settlePromise:
Expand Down Expand Up @@ -75,6 +77,7 @@ export function atomWithInfiniteQuery<
}
})
)
dataAtom.scope = queryAtom.scope
let setData: (
data: InfiniteData<TData> | Promise<InfiniteData<TData>>
) => void = () => {
Expand Down Expand Up @@ -128,6 +131,7 @@ export function atomWithInfiniteQuery<
return { dataAtom, observer, options }
},
(get, _set, action: AtomWithInfiniteQueryAction) => {
queryDataAtom.scope = queryAtom.scope
const { observer } = get(queryDataAtom)
switch (action.type) {
case 'refetch': {
Expand All @@ -151,10 +155,14 @@ export function atomWithInfiniteQuery<
AtomWithInfiniteQueryAction
>(
(get) => {
queryDataAtom.scope = queryAtom.scope
const { dataAtom } = get(queryDataAtom)
return get(dataAtom)
},
(_get, set, action) => set(queryDataAtom, action) // delegate action
(_get, set, action) => {
queryDataAtom.scope = queryAtom.scope
set(queryDataAtom, action) // delegate action
}
)
return queryAtom
}
16 changes: 12 additions & 4 deletions src/query/atomWithQuery.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import {
QueryClient,
QueryKey,
QueryObserver,
QueryObserverOptions,
Expand All @@ -7,7 +8,7 @@ import {
} from 'react-query'
import { atom } from 'jotai'
import type { WritableAtom, PrimitiveAtom, Getter } from 'jotai'
import { getQueryClientAtom } from './queryClientAtom'
import { queryClientAtom } from './queryClientAtom'

export type AtomWithQueryAction = { type: 'refetch' }

Expand All @@ -26,7 +27,8 @@ export function atomWithQuery<
| AtomWithQueryOptions<TQueryFnData, TError, TData, TQueryData>
| ((
get: Getter
) => AtomWithQueryOptions<TQueryFnData, TError, TData, TQueryData>)
) => AtomWithQueryOptions<TQueryFnData, TError, TData, TQueryData>),
getQueryClient: (get: Getter) => QueryClient = (get) => get(queryClientAtom)
): WritableAtom<TData | TQueryData, AtomWithQueryAction> {
const queryDataAtom: WritableAtom<
{
Expand All @@ -36,7 +38,7 @@ export function atomWithQuery<
AtomWithQueryAction
> = atom(
(get) => {
const queryClient = get(getQueryClientAtom)
const queryClient = getQueryClient(get)
const options =
typeof createQuery === 'function' ? createQuery(get) : createQuery
let settlePromise: ((data: TData | null, err?: TError) => void) | null =
Expand All @@ -60,6 +62,7 @@ export function atomWithQuery<
}
})
)
dataAtom.scope = queryAtom.scope
let setData: (data: TData | Promise<TData>) => void = () => {
throw new Error('atomWithQuery: setting data without mount')
}
Expand Down Expand Up @@ -108,6 +111,7 @@ export function atomWithQuery<
(get, set, action: AtomWithQueryAction) => {
switch (action.type) {
case 'refetch': {
queryDataAtom.scope = queryAtom.scope
const { dataAtom, observer } = get(queryDataAtom)
set(dataAtom, new Promise<TData>(() => {})) // infinite pending
const p = observer.refetch({ cancelRefetch: true }).then(() => {})
Expand All @@ -118,10 +122,14 @@ export function atomWithQuery<
)
const queryAtom = atom<TData | TQueryData, AtomWithQueryAction>(
(get) => {
queryDataAtom.scope = queryAtom.scope
const { dataAtom } = get(queryDataAtom)
return get(dataAtom)
},
(_get, set, action) => set(queryDataAtom, action) // delegate action
(_get, set, action) => {
queryDataAtom.scope = queryAtom.scope
set(queryDataAtom, action) // delegate action
}
)
return queryAtom
}
6 changes: 1 addition & 5 deletions src/query/queryClientAtom.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,4 @@
import { atom } from 'jotai'
import { QueryClient } from 'react-query'

export const queryClientAtom = atom<QueryClient | null>(null)

export const getQueryClientAtom = atom(
(get) => get(queryClientAtom) || new QueryClient()
)
export const queryClientAtom = atom(new QueryClient())
5 changes: 4 additions & 1 deletion src/redux/atomWithStore.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,10 @@ export function atomWithStore<State, A extends Action = AnyAction>(
return unsub
}
const derivedAtom = atom(
(get) => get(baseAtom),
(get) => {
baseAtom.scope = derivedAtom.scope
return get(baseAtom)
},
(_get, _set, action: A) => {
store.dispatch(action)
}
Expand Down
10 changes: 7 additions & 3 deletions src/urql/atomWithMutation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import {
} from '@urql/core'
import { atom } from 'jotai'
import type { Getter } from 'jotai'
import { getClientAtom } from './clientAtom'
import { clientAtom } from './clientAtom'

type MutationAction<Data, Variables extends object> = {
variables?: Variables
Expand All @@ -16,16 +16,20 @@ type MutationAction<Data, Variables extends object> = {

export function atomWithMutation<Data, Variables extends object>(
createQuery: (get: Getter) => TypedDocumentNode<Data, Variables> | string,
getClient: (get: Getter) => Client = (get) => get(getClientAtom)
getClient: (get: Getter) => Client = (get) => get(clientAtom)
) {
const operationResultAtom = atom<
OperationResult<Data, Variables> | Promise<OperationResult<Data, Variables>>
>(
new Promise<OperationResult<Data, Variables>>(() => {}) // infinite pending
)
const queryResultAtom = atom(
(get) => get(operationResultAtom),
(get) => {
operationResultAtom.scope = queryResultAtom.scope
return get(operationResultAtom)
},
(get, set, action: MutationAction<Data, Variables>) => {
operationResultAtom.scope = queryResultAtom.scope
set(
operationResultAtom,
new Promise<OperationResult<Data, Variables>>(() => {}) // new fetch
Expand Down
6 changes: 4 additions & 2 deletions src/urql/atomWithQuery.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import {
} from '@urql/core'
import { atom } from 'jotai'
import type { Getter } from 'jotai'
import { getClientAtom } from './clientAtom'
import { clientAtom } from './clientAtom'

type QueryArgs<Data, Variables extends object> = {
query: TypedDocumentNode<Data, Variables> | string
Expand All @@ -19,7 +19,7 @@ type QueryArgs<Data, Variables extends object> = {

export function atomWithQuery<Data, Variables extends object>(
createQueryArgs: (get: Getter) => QueryArgs<Data, Variables>,
getClient: (get: Getter) => Client = (get) => get(getClientAtom)
getClient: (get: Getter) => Client = (get) => get(clientAtom)
) {
const queryResultAtom = atom((get) => {
const client = getClient(get)
Expand All @@ -34,6 +34,7 @@ export function atomWithQuery<Data, Variables extends object>(
resolve = r
})
)
resultAtom.scope = queryAtom.scope
let setResult: (result: OperationResult<Data, Variables>) => void = () => {
throw new Error('setting result without mount')
}
Expand Down Expand Up @@ -69,6 +70,7 @@ export function atomWithQuery<Data, Variables extends object>(
return { resultAtom, args }
})
const queryAtom = atom((get) => {
queryResultAtom.scope = queryAtom.scope
const { resultAtom } = get(queryResultAtom)
return get(resultAtom)
})
Expand Down
6 changes: 4 additions & 2 deletions src/urql/atomWithSubscription.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import {
} from '@urql/core'
import { atom } from 'jotai'
import type { Getter } from 'jotai'
import { getClientAtom } from './clientAtom'
import { clientAtom } from './clientAtom'

type SubscriptionArgs<Data, Variables extends object> = {
query: TypedDocumentNode<Data, Variables> | string
Expand All @@ -17,7 +17,7 @@ type SubscriptionArgs<Data, Variables extends object> = {

export function atomWithSubscription<Data, Variables extends object>(
createSubscriptionArgs: (get: Getter) => SubscriptionArgs<Data, Variables>,
getClient: (get: Getter) => Client = (get) => get(getClientAtom)
getClient: (get: Getter) => Client = (get) => get(clientAtom)
) {
const queryResultAtom = atom((get) => {
const client = getClient(get)
Expand All @@ -32,6 +32,7 @@ export function atomWithSubscription<Data, Variables extends object>(
resolve = r
})
)
resultAtom.scope = queryAtom.scope
let setResult: (result: OperationResult<Data, Variables>) => void = () => {
throw new Error('setting result without mount')
}
Expand Down Expand Up @@ -68,6 +69,7 @@ export function atomWithSubscription<Data, Variables extends object>(
return { resultAtom, args }
})
const queryAtom = atom((get) => {
queryResultAtom.scope = queryAtom.scope
const { resultAtom } = get(queryResultAtom)
return get(resultAtom)
})
Expand Down
8 changes: 2 additions & 6 deletions src/urql/clientAtom.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,8 @@
import { atom } from 'jotai'
import { Client, createClient } from '@urql/core'
import { createClient } from '@urql/core'

const DEFAULT_URL =
(typeof process === 'object' && process.env.JOTAI_URQL_DEFAULT_URL) ||
'/graphql'

export const clientAtom = atom<Client | null>(null)

export const getClientAtom = atom(
(get) => get(clientAtom) || createClient({ url: DEFAULT_URL })
)
export const clientAtom = atom(createClient({ url: DEFAULT_URL }))
2 changes: 2 additions & 0 deletions src/utils/atomWithDefault.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,15 @@ export function atomWithDefault<Value>(getDefault: Read<Value>) {
const overwrittenAtom = atom<Value | typeof EMPTY>(EMPTY)
const anAtom: WritableAtom<Value, Update> = atom(
(get) => {
overwrittenAtom.scope = anAtom.scope
const overwritten = get(overwrittenAtom)
if (overwritten !== EMPTY) {
return overwritten
}
return getDefault(get)
},
(get, set, update) => {
overwrittenAtom.scope = anAtom.scope
if (update === RESET) {
set(overwrittenAtom, EMPTY)
} else {
Expand Down
Loading

1 comment on commit b6a7240

@vercel
Copy link

@vercel vercel bot commented on b6a7240 Jul 15, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please sign in to comment.