Skip to content

Commit

Permalink
breaking: useAtom scope instead of atom scope (#640)
Browse files Browse the repository at this point in the history
* breaking: useAtom scope instead of atom scope

* Update src/core/atom.ts

Co-authored-by: Mathis Møller <mmm@cryosinternational.com>

* some more missing fixes

Co-authored-by: Mathis Møller <mmm@cryosinternational.com>
  • Loading branch information
dai-shi and Mathis Møller authored Aug 10, 2021
1 parent 7a04867 commit 59d2613
Show file tree
Hide file tree
Showing 37 changed files with 94 additions and 246 deletions.
3 changes: 3 additions & 0 deletions src/core/atom.ts
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,9 @@ type OnMount<Update> = <S extends SetAtom<Update>>(
export type Atom<Value> = {
toString: () => string
debugLabel?: string
/**
* @deprecated Instead use `useAtom(atom, scope)`
*/
scope?: Scope
read: Read<Value>
}
Expand Down
33 changes: 24 additions & 9 deletions src/core/useAtom.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { useCallback, useContext, useDebugValue, useEffect } from 'react'
import type { Atom, SetAtom, WritableAtom } from './atom'
import type { Atom, Scope, SetAtom, WritableAtom } from './atom'
import { getStoreContext } from './contexts'
import { useMutableSource } from './useMutableSource'
import { readAtom, subscribeAtom } from './vanilla'
Expand All @@ -11,27 +11,35 @@ const isWritable = <Value, Update>(
!!(atom as WritableAtom<Value, Update>).write

export function useAtom<Value, Update>(
atom: WritableAtom<Value | Promise<Value>, Update>
atom: WritableAtom<Value | Promise<Value>, Update>,
scope?: Scope
): [Value, SetAtom<Update>]

export function useAtom<Value, Update>(
atom: WritableAtom<Promise<Value>, Update>
atom: WritableAtom<Promise<Value>, Update>,
scope?: Scope
): [Value, SetAtom<Update>]

export function useAtom<Value, Update>(
atom: WritableAtom<Value, Update>
atom: WritableAtom<Value, Update>,
scope?: Scope
): [Value, SetAtom<Update>]

export function useAtom<Value>(
atom: Atom<Value | Promise<Value>>
atom: Atom<Value | Promise<Value>>,
scope?: Scope
): [Value, never]

export function useAtom<Value>(atom: Atom<Promise<Value>>): [Value, never]
export function useAtom<Value>(
atom: Atom<Promise<Value>>,
scope?: Scope
): [Value, never]

export function useAtom<Value>(atom: Atom<Value>): [Value, never]
export function useAtom<Value>(atom: Atom<Value>, scope?: Scope): [Value, never]

export function useAtom<Value, Update>(
atom: Atom<Value> | WritableAtom<Value, Update>
atom: Atom<Value> | WritableAtom<Value, Update>,
scope?: Scope
) {
const getAtomValue = useCallback(
(state: State) => {
Expand Down Expand Up @@ -59,7 +67,14 @@ export function useAtom<Value, Update>(
[atom]
)

const StoreContext = getStoreContext(atom.scope)
if ('scope' in atom) {
console.warn(
'atom.scope is deprecated. Please do useAtom(atom, scope) instead.'
)
scope = atom.scope
}

const StoreContext = getStoreContext(scope)
const [mutableSource, updateAtom, commitCallback] = useContext(StoreContext)
const value = useMutableSource(mutableSource, getAtomValue, subscribe)
useEffect(() => {
Expand Down
6 changes: 4 additions & 2 deletions src/devtools/useAtomDevtools.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { useEffect, useRef } from 'react'
import { useAtom } from 'jotai'
import type { WritableAtom } from 'jotai'
import type { Scope } from '../core/atom'

type Config = {
instanceID?: number
Expand Down Expand Up @@ -32,7 +33,8 @@ type Extension = {

export function useAtomDevtools<Value>(
anAtom: WritableAtom<Value, Value>,
name?: string
name?: string,
scope?: Scope
) {
let extension: Extension | undefined
try {
Expand All @@ -48,7 +50,7 @@ export function useAtomDevtools<Value>(
}
}

const [value, setValue] = useAtom(anAtom)
const [value, setValue] = useAtom(anAtom, scope)
const lastValue = useRef(value)
const isTimeTraveling = useRef(false)
const devtools = useRef<ConnectionResult & { shouldInit?: boolean }>()
Expand Down
7 changes: 1 addition & 6 deletions src/devtools/useGotoAtomsSnapshot.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,13 +14,8 @@ export function useGotoAtomsSnapshot(scope?: Scope) {
const restore = store[4]
return useCallback(
(values: Parameters<typeof restore>[0]) => {
for (const [atom] of values) {
if (atom.scope !== scope) {
throw new Error('atom scope mismatch to restore')
}
}
restore(values)
},
[restore, scope]
[restore]
)
}
12 changes: 8 additions & 4 deletions src/immer/useImmerAtom.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,19 +4,23 @@ import { produce } from 'immer'
import type { Draft } from 'immer'
import { useAtom } from 'jotai'
import type { WritableAtom } from 'jotai'
import type { Scope } from '../core/atom'

export function useImmerAtom<Value>(
anAtom: WritableAtom<Value, (draft: Draft<Value>) => void>
anAtom: WritableAtom<Value, (draft: Draft<Value>) => void>,
scope?: Scope
): [Value, (fn: (draft: Draft<Value>) => void) => void]

export function useImmerAtom<Value>(
anAtom: WritableAtom<Value, (value: Value) => Value>
anAtom: WritableAtom<Value, (value: Value) => Value>,
scope?: Scope
): [Value, (fn: (draft: Draft<Value>) => void) => void]

export function useImmerAtom<Value>(
anAtom: WritableAtom<Value, (value: Value) => Value>
anAtom: WritableAtom<Value, (value: Value) => Value>,
scope?: Scope
) {
const [state, setState] = useAtom(anAtom)
const [state, setState] = useAtom(anAtom, scope)
const setStateWithImmer = useCallback(
(fn) => {
setState(produce((draft) => fn(draft)) as (value: Value) => Value)
Expand Down
1 change: 0 additions & 1 deletion src/immer/withImmer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,6 @@ export function withImmer<Value>(anAtom: WritableAtom<Value, Value>) {
)
)
)
derivedAtom.scope = anAtom.scope
setWeakCacheItem(withImmerCache, deps, derivedAtom)
return derivedAtom
}
1 change: 0 additions & 1 deletion src/optics/focusAtom.ts
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,6 @@ export function focusAtom<S, A>(
set(baseAtom, newValueProducer(get(baseAtom)) as NonFunction<S>)
}
)
derivedAtom.scope = baseAtom.scope
setWeakCacheItem(focusAtomCache, deps, derivedAtom)
return derivedAtom
}
Expand Down
4 changes: 0 additions & 4 deletions src/query/atomWithInfiniteQuery.ts
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,6 @@ export function atomWithInfiniteQuery<
}
})
)
dataAtom.scope = queryAtom.scope
let setData: (
data: InfiniteData<TData> | Promise<InfiniteData<TData>>
) => void = () => {
Expand Down Expand Up @@ -130,7 +129,6 @@ 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 @@ -154,12 +152,10 @@ export function atomWithInfiniteQuery<
AtomWithInfiniteQueryAction
>(
(get) => {
queryDataAtom.scope = queryAtom.scope
const { dataAtom } = get(queryDataAtom)
return get(dataAtom)
},
(_get, set, action) => {
queryDataAtom.scope = queryAtom.scope
set(queryDataAtom, action) // delegate action
}
)
Expand Down
4 changes: 0 additions & 4 deletions src/query/atomWithQuery.ts
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,6 @@ 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 @@ -111,7 +110,6 @@ 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 @@ -122,12 +120,10 @@ export function atomWithQuery<
)
const queryAtom = atom<TData | TQueryData, AtomWithQueryAction>(
(get) => {
queryDataAtom.scope = queryAtom.scope
const { dataAtom } = get(queryDataAtom)
return get(dataAtom)
},
(_get, set, action) => {
queryDataAtom.scope = queryAtom.scope
set(queryDataAtom, action) // delegate action
}
)
Expand Down
5 changes: 1 addition & 4 deletions src/redux/atomWithStore.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,7 @@ export function atomWithStore<State, A extends Action = AnyAction>(
return unsub
}
const derivedAtom = atom(
(get) => {
baseAtom.scope = derivedAtom.scope
return get(baseAtom)
},
(get) => get(baseAtom),
(_get, _set, action: A) => {
store.dispatch(action)
}
Expand Down
6 changes: 1 addition & 5 deletions src/urql/atomWithMutation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,12 +24,8 @@ export function atomWithMutation<Data, Variables extends object>(
new Promise<OperationResult<Data, Variables>>(() => {}) // infinite pending
)
const queryResultAtom = atom(
(get) => {
operationResultAtom.scope = queryResultAtom.scope
return get(operationResultAtom)
},
(get) => get(operationResultAtom),
(get, set, action: MutationAction<Data, Variables>) => {
operationResultAtom.scope = queryResultAtom.scope
set(
operationResultAtom,
new Promise<OperationResult<Data, Variables>>(() => {}) // new fetch
Expand Down
2 changes: 0 additions & 2 deletions src/urql/atomWithQuery.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,6 @@ 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 @@ -70,7 +69,6 @@ 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
2 changes: 0 additions & 2 deletions src/urql/atomWithSubscription.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,6 @@ 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 @@ -69,7 +68,6 @@ 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
2 changes: 0 additions & 2 deletions src/utils/atomWithDefault.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,15 +10,13 @@ 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
3 changes: 0 additions & 3 deletions src/utils/atomWithObservable.ts
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,6 @@ export function atomWithObservable<TData>(
}
})
)
dataAtom.scope = observableAtom.scope
let setData: (data: TData | Promise<TData>) => void = () => {
throw new Error('setting data without mount')
}
Expand Down Expand Up @@ -104,12 +103,10 @@ export function atomWithObservable<TData>(
})
const observableAtom = atom(
(get) => {
observableResultAtom.scope = observableAtom.scope
const { dataAtom } = get(observableResultAtom)
return get(dataAtom)
},
(get, _set, data: TData) => {
observableResultAtom.scope = observableAtom.scope
const { observable } = get(observableResultAtom)
if ('next' in observable) {
observable.next(data)
Expand Down
6 changes: 1 addition & 5 deletions src/utils/atomWithStorage.ts
Original file line number Diff line number Diff line change
Expand Up @@ -68,12 +68,8 @@ export function atomWithStorage<Value>(
}

const anAtom = atom(
(get) => {
baseAtom.scope = anAtom.scope
return get(baseAtom)
},
(get) => get(baseAtom),
(get, set, update: SetStateAction<Value>) => {
baseAtom.scope = anAtom.scope
const newValue =
typeof update === 'function'
? (update as (prev: Value) => Value)(get(baseAtom))
Expand Down
1 change: 0 additions & 1 deletion src/utils/freezeAtom.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,6 @@ export function freezeAtom<AtomType extends Atom<any>>(
(get) => deepFreeze(get(anAtom)),
(_get, set, arg) => set(anAtom as any, arg)
)
frozenAtom.scope = anAtom.scope
setWeakCacheItem(freezeAtomCache, deps, frozenAtom)
return frozenAtom
}
Expand Down
2 changes: 0 additions & 2 deletions src/utils/selectAtom.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@ export function selectAtom<Value, Slice>(
return cachedAtom as Atom<Slice>
}
const refAtom = atom(() => ({} as { prev?: Slice }))
refAtom.scope = anAtom.scope
const derivedAtom = atom((get) => {
const slice = selector(get(anAtom))
const ref = get(refAtom)
Expand All @@ -25,7 +24,6 @@ export function selectAtom<Value, Slice>(
ref.prev = slice
return slice
})
derivedAtom.scope = anAtom.scope
setWeakCacheItem(selectAtomCache, deps, derivedAtom)
return derivedAtom
}
3 changes: 0 additions & 3 deletions src/utils/splitAtom.ts
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,6 @@ export function splitAtom<Item, Key>(
keyList?: Key[]
})
)
refAtom.scope = arrAtom.scope
const read = (get: Getter) => {
const ref = get(refAtom)
let nextAtomList: Atom<Item>[] = []
Expand Down Expand Up @@ -90,7 +89,6 @@ export function splitAtom<Item, Key>(
])
}
const itemAtom = isWritable(arrAtom) ? atom(read, write) : atom(read)
itemAtom.scope = arrAtom.scope
nextAtomList[index] = itemAtom
})
ref.keyList = nextKeyList
Expand All @@ -114,7 +112,6 @@ export function splitAtom<Item, Key>(
}
}
const splittedAtom = isWritable(arrAtom) ? atom(read, write) : atom(read)
splittedAtom.scope = arrAtom.scope
setWeakCacheItem(splitAtomCache, deps, splittedAtom)
return splittedAtom
}
3 changes: 1 addition & 2 deletions src/utils/useAtomCallback.ts
Original file line number Diff line number Diff line change
Expand Up @@ -45,8 +45,7 @@ export function useAtomCallback<Result, Arg>(
),
[callback]
)
anAtom.scope = scope
const [, invoke] = useAtom(anAtom)
const [, invoke] = useAtom(anAtom, scope)
return useCallback(
(arg: Arg) =>
new Promise<Result>((resolve, reject) => {
Expand Down
5 changes: 3 additions & 2 deletions src/utils/useAtomValue.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { useAtom } from 'jotai'
import type { Atom } from 'jotai'
import type { Scope } from '../core/atom'

export function useAtomValue<Value>(anAtom: Atom<Value>) {
return useAtom(anAtom)[0]
export function useAtomValue<Value>(anAtom: Atom<Value>, scope?: Scope) {
return useAtom(anAtom, scope)[0]
}
Loading

1 comment on commit 59d2613

@vercel
Copy link

@vercel vercel bot commented on 59d2613 Aug 10, 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.