Streamline the project references context provider (#19387)

GitOrigin-RevId: 9af00459ec121a605b84809b349a0bc258896048
This commit is contained in:
Alf Eaton
2024-07-16 08:04:30 +00:00
committed by Copybot
parent a55d9fcf38
commit 66c55b0647
22 changed files with 55 additions and 144 deletions
@@ -10,64 +10,32 @@ import {
} from 'react'
import { useIdeReactContext } from '@/features/ide-react/context/ide-react-context'
import { useConnectionContext } from '@/features/ide-react/context/connection-context'
import _ from 'lodash'
import { postJSON } from '@/infrastructure/fetch-json'
import { ShareJsDoc } from '@/features/ide-react/editor/share-js-doc'
import useScopeValue from '@/shared/hooks/use-scope-value'
import { ReactScopeValueStore } from '@/features/ide-react/scope-value-store/react-scope-value-store'
import { useFileTreeData } from '@/shared/context/file-tree-data-context'
import { findDocEntityById } from '@/features/ide-react/util/find-doc-entity-by-id'
import { IdeEvents } from '@/features/ide-react/create-ide-event-emitter'
import { debugConsole } from '@/utils/debugging'
type References = {
keys: string[]
}
type ReferencesContextValue = {
indexReferencesIfDocModified: (
doc: ShareJsDoc,
shouldBroadcast: boolean
) => void
indexAllReferences: (shouldBroadcast: boolean) => void
}
type IndexReferencesResponse = References
const ReferencesContext = createContext<ReferencesContextValue | undefined>(
undefined
)
export function populateReferenceScope(store: ReactScopeValueStore) {
store.set('$root._references', { keys: [] })
}
export const ReferencesContext = createContext<
| {
referenceKeys: Set<string>
indexAllReferences: (shouldBroadcast: boolean) => void
}
| undefined
>(undefined)
export const ReferencesProvider: FC = ({ children }) => {
const { fileTreeData } = useFileTreeData()
const { eventEmitter, projectId } = useIdeReactContext()
const { socket } = useConnectionContext()
const [references, setReferences] =
useScopeValue<References>('$root._references')
const [referenceKeys, setReferenceKeys] = useState(new Set<string>())
const [existingIndexHash, setExistingIndexHash] = useState<
Record<string, { hash: string; timestamp: number }>
>({})
const storeReferencesKeys = useCallback(
(newKeys: string[], replaceExistingKeys: boolean) => {
const oldKeys = references.keys
const keys = replaceExistingKeys ? newKeys : _.union(oldKeys, newKeys)
window.dispatchEvent(
new CustomEvent('project:references', {
detail: keys,
})
)
setReferences({ keys })
},
[references.keys, setReferences]
)
const indexAllReferences = useCallback(
(shouldBroadcast: boolean) => {
postJSON(`/project/${projectId}/references/indexAll`, {
@@ -75,15 +43,15 @@ export const ReferencesProvider: FC = ({ children }) => {
shouldBroadcast,
},
})
.then((response: IndexReferencesResponse) => {
storeReferencesKeys(response.keys, true)
.then((response: { keys: string[] }) => {
setReferenceKeys(new Set(response.keys))
})
.catch(error => {
// allow the request to fail
debugConsole.error(error)
})
},
[projectId, storeReferencesKeys]
[projectId]
)
const indexReferencesIfDocModified = useCallback(
@@ -132,25 +100,15 @@ export const ReferencesProvider: FC = ({ children }) => {
}
}, [eventEmitter, fileTreeData, indexReferencesIfDocModified])
useEffect(() => {
const handleShouldReindex = () => {
indexAllReferences(true)
}
eventEmitter.on('references:should-reindex', handleShouldReindex)
return () => {
eventEmitter.off('references:should-reindex', handleShouldReindex)
}
}, [eventEmitter, indexAllReferences])
useEffect(() => {
const handleProjectJoined = () => {
// We only need to grab the references when the editor first loads,
// not on every reconnect
socket.on('references:keys:updated', (keys, allDocs) =>
storeReferencesKeys(keys, allDocs)
)
socket.on('references:keys:updated', (keys, allDocs) => {
setReferenceKeys(oldKeys =>
allDocs ? new Set(keys) : new Set([...oldKeys, ...keys])
)
})
indexAllReferences(false)
}
@@ -159,14 +117,14 @@ export const ReferencesProvider: FC = ({ children }) => {
return () => {
eventEmitter.off('project:joined', handleProjectJoined)
}
}, [eventEmitter, indexAllReferences, socket, storeReferencesKeys])
}, [eventEmitter, indexAllReferences, socket])
const value = useMemo<ReferencesContextValue>(
const value = useMemo(
() => ({
indexReferencesIfDocModified,
referenceKeys,
indexAllReferences,
}),
[indexReferencesIfDocModified, indexAllReferences]
[indexAllReferences, referenceKeys]
)
return (
@@ -176,7 +134,7 @@ export const ReferencesProvider: FC = ({ children }) => {
)
}
export function useReferencesContext(): ReferencesContextValue {
export function useReferencesContext() {
const context = useContext(ReferencesContext)
if (!context) {