-
Notifications
You must be signed in to change notification settings - Fork 8
fix loading handle #262
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
fix loading handle #262
Changes from 2 commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,8 +1,6 @@ | ||
'use client'; | ||
|
||
import type { AnyDocumentId } from '@automerge/automerge-repo'; | ||
import { useRepo } from '@automerge/automerge-repo-react-hooks'; | ||
import { Entity, Utils, store } from '@graphprotocol/hypergraph'; | ||
import { Entity, store } from '@graphprotocol/hypergraph'; | ||
import { useSelector } from '@xstate/store/react'; | ||
import * as Schema from 'effect/Schema'; | ||
import { | ||
|
@@ -35,12 +33,13 @@ | |
} | ||
|
||
function useSubscribeToSpaceAndGetHandle({ spaceId, enabled }: { spaceId: string; enabled: boolean }) { | ||
const repo = useRepo(); | ||
const handle = useMemo(() => { | ||
const id = Utils.idToAutomergeId(spaceId) as AnyDocumentId; | ||
const result = repo.findWithProgress<Entity.DocumentContent>(id); | ||
return result.handle; | ||
}, [spaceId, repo]); | ||
const handle = useSelector(store, (state) => { | ||
const space = state.context.spaces.find((space) => space.id === spaceId); | ||
if (!space) { | ||
return undefined; | ||
} | ||
return space.automergeDocHandle; | ||
}); | ||
|
||
const { subscribeToSpace, isConnecting } = useHypergraphApp(); | ||
useEffect(() => { | ||
|
@@ -61,43 +60,69 @@ | |
const { space: spaceIdFromParams } = options ?? {}; | ||
const spaceId = spaceIdFromParams ?? spaceIdFromContext; | ||
const handle = useSubscribeToSpaceAndGetHandle({ spaceId, enabled: options.mode === 'private' }); | ||
const ready = options.mode === 'public' ? true : handle.isReady(); | ||
const ready = options.mode === 'public' ? true : handle ? handle.isReady() : false; | ||
const space = useSelector(store, (state) => state.context.spaces.find((space) => space.id === spaceId)); | ||
return { ready, name: space?.name, id: spaceId }; | ||
} | ||
|
||
export function useCreateEntity<const S extends Entity.AnyNoContext>(type: S, options?: { space?: string }) { | ||
const { space } = options ?? {}; | ||
const { space: spaceIdFromParams } = options ?? {}; | ||
const { space: spaceFromContext } = useHypergraphSpaceInternal(); | ||
const handle = useSubscribeToSpaceAndGetHandle({ spaceId: space ?? spaceFromContext, enabled: true }); | ||
const spaceId = spaceIdFromParams ?? spaceFromContext; | ||
const handle = useSubscribeToSpaceAndGetHandle({ spaceId, enabled: true }); | ||
if (!handle) { | ||
return () => { | ||
throw new Error('Space not found or not ready'); | ||
Check failure on line 75 in packages/hypergraph-react/src/HypergraphSpaceContext.tsx
|
||
}; | ||
} | ||
return Entity.create(handle, type); | ||
} | ||
|
||
export function useUpdateEntity<const S extends Entity.AnyNoContext>(type: S, options?: { space?: string }) { | ||
const { space: spaceFromContext } = useHypergraphSpaceInternal(); | ||
const { space } = options ?? {}; | ||
const handle = useSubscribeToSpaceAndGetHandle({ spaceId: space ?? spaceFromContext, enabled: true }); | ||
if (!handle) { | ||
return () => { | ||
throw new Error('Space not found or not ready'); | ||
}; | ||
} | ||
return Entity.update(handle, type); | ||
} | ||
|
||
export function useDeleteEntity(options?: { space?: string }) { | ||
const { space: spaceFromContext } = useHypergraphSpaceInternal(); | ||
const { space } = options ?? {}; | ||
const handle = useSubscribeToSpaceAndGetHandle({ spaceId: space ?? spaceFromContext, enabled: true }); | ||
if (!handle) { | ||
return () => { | ||
throw new Error('Space not found or not ready'); | ||
}; | ||
} | ||
return Entity.markAsDeleted(handle); | ||
} | ||
|
||
export function useRemoveRelation(options?: { space?: string }) { | ||
const { space: spaceFromContext } = useHypergraphSpaceInternal(); | ||
const { space } = options ?? {}; | ||
const handle = useSubscribeToSpaceAndGetHandle({ spaceId: space ?? spaceFromContext, enabled: true }); | ||
if (!handle) { | ||
return () => { | ||
throw new Error('Space not found or not ready'); | ||
}; | ||
} | ||
return Entity.removeRelation(handle); | ||
} | ||
|
||
export function useHardDeleteEntity(options?: { space?: string }) { | ||
const { space: spaceFromContext } = useHypergraphSpaceInternal(); | ||
const { space } = options ?? {}; | ||
const handle = useSubscribeToSpaceAndGetHandle({ spaceId: space ?? spaceFromContext, enabled: true }); | ||
if (!handle) { | ||
return () => { | ||
throw new Error('Space not found or not ready'); | ||
}; | ||
} | ||
return Entity.delete(handle); | ||
} | ||
|
||
|
@@ -117,11 +142,11 @@ | |
}); | ||
const { space: spaceFromContext } = useHypergraphSpaceInternal(); | ||
const handle = useSubscribeToSpaceAndGetHandle({ spaceId: spaceFromParams ?? spaceFromContext, enabled: true }); | ||
const handleIsReady = handle.isReady(); | ||
const handleIsReady = handle ? handle.isReady() : false; | ||
|
||
// biome-ignore lint/correctness/useExhaustiveDependencies: allow to change filter and include | ||
useLayoutEffect(() => { | ||
if (enabled && handleIsReady) { | ||
if (enabled && handle && handleIsReady) { | ||
const subscription = Entity.subscribeToFindMany(handle, type, filter, include); | ||
subscriptionRef.current.subscribe = subscription.subscribe; | ||
subscriptionRef.current.getEntities = subscription.getEntities; | ||
|
@@ -163,6 +188,9 @@ | |
const equals = Schema.equivalence(type); | ||
|
||
const subscribe = (callback: () => void) => { | ||
if (!handle) { | ||
return () => {}; | ||
} | ||
const handleChange = () => { | ||
callback(); | ||
}; | ||
|
@@ -181,6 +209,9 @@ | |
}; | ||
|
||
return useSyncExternalStore(subscribe, () => { | ||
if (!handle) { | ||
return prevEntityRef.current; | ||
} | ||
const doc = handle.doc(); | ||
if (doc === undefined) { | ||
return prevEntityRef.current; | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Commented-out logging can clutter the codebase. Either remove the dead code or re-enable the check with a proper logging strategy and a clear TODO note.
Copilot uses AI. Check for mistakes.