11'use client' ;
22
3- import { Entity , store } from '@graphprotocol/hypergraph' ;
3+ import { Entity , type Id , store } from '@graphprotocol/hypergraph' ;
44import { useSelector } from '@xstate/store/react' ;
55import * as Schema from 'effect/Schema' ;
66import {
@@ -14,6 +14,7 @@ import {
1414 useSyncExternalStore ,
1515} from 'react' ;
1616import { useHypergraphApp } from './HypergraphAppContext.js' ;
17+ import { useEntityPublic } from './internal/use-entity-public.js' ;
1718import { usePublicSpace } from './internal/use-public-space.js' ;
1819
1920// TODO space can be undefined
@@ -181,19 +182,28 @@ export function useQueryLocal<const S extends Entity.AnyNoContext>(type: S, para
181182 return { entities, deletedEntities } ;
182183}
183184
184- export function useQueryEntity < const S extends Entity . AnyNoContext > (
185+ function useEntityPrivate < const S extends Entity . AnyNoContext > (
185186 type : S ,
186- id : string ,
187- params ?: { space ?: string ; include ?: { [ K in keyof Schema . Schema . Type < S > ] ?: Record < string , never > } } ,
187+ params : {
188+ id : string | Id ;
189+ enabled ?: boolean ;
190+ space ?: string ;
191+ include ?: { [ K in keyof Schema . Schema . Type < S > ] ?: Record < string , Record < string , never > > } | undefined ;
192+ } ,
188193) {
189194 const { space : spaceFromContext } = useHypergraphSpaceInternal ( ) ;
190- const { space : spaceFromParams , include } = params ?? { } ;
191- const handle = useSubscribeToSpaceAndGetHandle ( { spaceId : spaceFromParams ?? spaceFromContext , enabled : true } ) ;
192- const prevEntityRef = useRef < Entity . Entity < S > | undefined > ( undefined ) ;
195+ const { space : spaceFromParams , include, id, enabled = true } = params ;
196+ const handle = useSubscribeToSpaceAndGetHandle ( { spaceId : spaceFromParams ?? spaceFromContext , enabled } ) ;
197+ const prevEntityRef = useRef < {
198+ data : Entity . Entity < S > | undefined ;
199+ invalidEntity : Record < string , string | boolean | number | Date > | undefined ;
200+ isPending : boolean ;
201+ isError : boolean ;
202+ } > ( { data : undefined , invalidEntity : undefined , isPending : false , isError : false } ) ;
193203 const equals = Schema . equivalence ( type ) ;
194204
195205 const subscribe = ( callback : ( ) => void ) => {
196- if ( ! handle ) {
206+ if ( ! handle || ! enabled ) {
197207 return ( ) => { } ;
198208 }
199209 const handleChange = ( ) => {
@@ -214,7 +224,7 @@ export function useQueryEntity<const S extends Entity.AnyNoContext>(
214224 } ;
215225
216226 return useSyncExternalStore ( subscribe , ( ) => {
217- if ( ! handle ) {
227+ if ( ! handle || ! enabled ) {
218228 return prevEntityRef . current ;
219229 }
220230 const doc = handle . doc ( ) ;
@@ -223,16 +233,39 @@ export function useQueryEntity<const S extends Entity.AnyNoContext>(
223233 }
224234
225235 const found = Entity . findOne ( handle , type , include ) ( id ) ;
226- if ( found === undefined && prevEntityRef . current !== undefined ) {
236+ if ( found === undefined && prevEntityRef . current . data !== undefined ) {
227237 // entity was maybe deleted, delete from the ref
228- prevEntityRef . current = undefined ;
229- } else if ( found !== undefined && prevEntityRef . current === undefined ) {
230- prevEntityRef . current = found ;
231- } else if ( found !== undefined && prevEntityRef . current !== undefined && ! equals ( found , prevEntityRef . current ) ) {
238+ prevEntityRef . current = { data : undefined , invalidEntity : undefined , isPending : false , isError : false } ;
239+ } else if ( found !== undefined && prevEntityRef . current . data === undefined ) {
240+ prevEntityRef . current = { data : found , invalidEntity : undefined , isPending : false , isError : false } ;
241+ } else if (
242+ found !== undefined &&
243+ prevEntityRef . current . data !== undefined &&
244+ ! equals ( found , prevEntityRef . current . data )
245+ ) {
232246 // found and ref have a value, compare for equality, if they are not equal, update the ref and return
233- prevEntityRef . current = found ;
247+ prevEntityRef . current = { data : found , invalidEntity : undefined , isPending : false , isError : false } ;
234248 }
235249
236250 return prevEntityRef . current ;
237251 } ) ;
238252}
253+
254+ export function useEntity < const S extends Entity . AnyNoContext > (
255+ type : S ,
256+ params : {
257+ id : string | Id ;
258+ space ?: string ;
259+ mode : 'private' | 'public' ;
260+ include ?: { [ K in keyof Schema . Schema . Type < S > ] ?: Record < string , Record < string , never > > } | undefined ;
261+ } ,
262+ ) {
263+ const resultPublic = useEntityPublic ( type , { ...params , enabled : params . mode === 'public' } ) ;
264+ const resultPrivate = useEntityPrivate ( type , { ...params , enabled : params . mode === 'private' } ) ;
265+
266+ if ( params . mode === 'public' ) {
267+ return resultPublic ;
268+ }
269+
270+ return resultPrivate ;
271+ }
0 commit comments