import { createElement, useEffect, useRef, useState } from 'react'import type { PropsWithChildren } from 'react'import type { Atom, Scope } from './atom'import { createScopeContainer, getScopeContext } from './contexts'import type { ScopeContainer } from './contexts'import { COMMIT_ATOM, createStoreForExport } from './store'import type { VersionObject } from './store'import { useDebugState } from './useDebugState'
export const Provider = ({ children, initialValues, scope, unstable_createStore, unstable_enableVersionedWrite,}: PropsWithChildren<{ initialValues?: Iterable<readonly [Atom<unknown>, unknown]> scope?: Scope unstable_createStore?: typeof createStoreForExport unstable_enableVersionedWrite?: boolean}>) => { const [version, setVersion] = useState<VersionObject>() useEffect(() => { if (version) { ;(scopeContainerRef.current as ScopeContainer).s[COMMIT_ATOM]( null, version ) delete version.p } }, [version])
const scopeContainerRef = useRef<ScopeContainer>() if (!scopeContainerRef.current) { scopeContainerRef.current = createScopeContainer( initialValues, unstable_createStore ) if (unstable_enableVersionedWrite) { scopeContainerRef.current.w = (write) => { setVersion((parentVersion) => { const nextVersion = parentVersion ? { p: parentVersion } : {} write(nextVersion) return nextVersion }) } } }
if (__DEV__ && !unstable_enableVersionedWrite) { useDebugState(scopeContainerRef.current) }
const ScopeContainerContext = getScopeContext(scope) return createElement( ScopeContainerContext.Provider, { value: scopeContainerRef.current, }, children )}