Skip to content

Commit dded603

Browse files
authored
add useEntitiesPublicInfinite hook (#552)
1 parent f51992d commit dded603

8 files changed

Lines changed: 128 additions & 3 deletions

File tree

.changeset/beige-lemons-beg.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
---
2+
"@graphprotocol/hypergraph-react": patch
3+
---
4+
5+
add useEntitiesPublicInfinite hook]
6+

apps/events/src/routeTree.gen.ts

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,10 +23,18 @@ import { Route as SpaceSpaceIdPlaygroundRouteImport } from './routes/space/$spac
2323
import { Route as SpaceSpaceIdEventsRouteImport } from './routes/space/$spaceId/events'
2424
import { Route as SpaceSpaceIdChatRouteImport } from './routes/space/$spaceId/chat'
2525

26+
const PodcastsInfiniteLazyRouteImport = createFileRoute('/podcasts-infinite')()
2627
const PodcastsLazyRouteImport = createFileRoute('/podcasts')()
2728
const PlaygroundLazyRouteImport = createFileRoute('/playground')()
2829
const LoginLazyRouteImport = createFileRoute('/login')()
2930

31+
const PodcastsInfiniteLazyRoute = PodcastsInfiniteLazyRouteImport.update({
32+
id: '/podcasts-infinite',
33+
path: '/podcasts-infinite',
34+
getParentRoute: () => rootRouteImport,
35+
} as any).lazy(() =>
36+
import('./routes/podcasts-infinite.lazy').then((d) => d.Route),
37+
)
3038
const PodcastsLazyRoute = PodcastsLazyRouteImport.update({
3139
id: '/podcasts',
3240
path: '/podcasts',
@@ -105,6 +113,7 @@ export interface FileRoutesByFullPath {
105113
'/login': typeof LoginLazyRoute
106114
'/playground': typeof PlaygroundLazyRoute
107115
'/podcasts': typeof PodcastsLazyRoute
116+
'/podcasts-infinite': typeof PodcastsInfiniteLazyRoute
108117
'/account-inbox/$inboxId': typeof AccountInboxInboxIdRoute
109118
'/friends/$accountAddress': typeof FriendsAccountAddressRoute
110119
'/space/$spaceId': typeof SpaceSpaceIdRouteWithChildren
@@ -121,6 +130,7 @@ export interface FileRoutesByTo {
121130
'/login': typeof LoginLazyRoute
122131
'/playground': typeof PlaygroundLazyRoute
123132
'/podcasts': typeof PodcastsLazyRoute
133+
'/podcasts-infinite': typeof PodcastsInfiniteLazyRoute
124134
'/account-inbox/$inboxId': typeof AccountInboxInboxIdRoute
125135
'/friends/$accountAddress': typeof FriendsAccountAddressRoute
126136
'/space/$spaceId/chat': typeof SpaceSpaceIdChatRoute
@@ -137,6 +147,7 @@ export interface FileRoutesById {
137147
'/login': typeof LoginLazyRoute
138148
'/playground': typeof PlaygroundLazyRoute
139149
'/podcasts': typeof PodcastsLazyRoute
150+
'/podcasts-infinite': typeof PodcastsInfiniteLazyRoute
140151
'/account-inbox/$inboxId': typeof AccountInboxInboxIdRoute
141152
'/friends/$accountAddress': typeof FriendsAccountAddressRoute
142153
'/space/$spaceId': typeof SpaceSpaceIdRouteWithChildren
@@ -155,6 +166,7 @@ export interface FileRouteTypes {
155166
| '/login'
156167
| '/playground'
157168
| '/podcasts'
169+
| '/podcasts-infinite'
158170
| '/account-inbox/$inboxId'
159171
| '/friends/$accountAddress'
160172
| '/space/$spaceId'
@@ -171,6 +183,7 @@ export interface FileRouteTypes {
171183
| '/login'
172184
| '/playground'
173185
| '/podcasts'
186+
| '/podcasts-infinite'
174187
| '/account-inbox/$inboxId'
175188
| '/friends/$accountAddress'
176189
| '/space/$spaceId/chat'
@@ -186,6 +199,7 @@ export interface FileRouteTypes {
186199
| '/login'
187200
| '/playground'
188201
| '/podcasts'
202+
| '/podcasts-infinite'
189203
| '/account-inbox/$inboxId'
190204
| '/friends/$accountAddress'
191205
| '/space/$spaceId'
@@ -203,13 +217,21 @@ export interface RootRouteChildren {
203217
LoginLazyRoute: typeof LoginLazyRoute
204218
PlaygroundLazyRoute: typeof PlaygroundLazyRoute
205219
PodcastsLazyRoute: typeof PodcastsLazyRoute
220+
PodcastsInfiniteLazyRoute: typeof PodcastsInfiniteLazyRoute
206221
AccountInboxInboxIdRoute: typeof AccountInboxInboxIdRoute
207222
FriendsAccountAddressRoute: typeof FriendsAccountAddressRoute
208223
SpaceSpaceIdRoute: typeof SpaceSpaceIdRouteWithChildren
209224
}
210225

211226
declare module '@tanstack/react-router' {
212227
interface FileRoutesByPath {
228+
'/podcasts-infinite': {
229+
id: '/podcasts-infinite'
230+
path: '/podcasts-infinite'
231+
fullPath: '/podcasts-infinite'
232+
preLoaderRoute: typeof PodcastsInfiniteLazyRouteImport
233+
parentRoute: typeof rootRouteImport
234+
}
213235
'/podcasts': {
214236
id: '/podcasts'
215237
path: '/podcasts'
@@ -339,6 +361,7 @@ const rootRouteChildren: RootRouteChildren = {
339361
LoginLazyRoute: LoginLazyRoute,
340362
PlaygroundLazyRoute: PlaygroundLazyRoute,
341363
PodcastsLazyRoute: PodcastsLazyRoute,
364+
PodcastsInfiniteLazyRoute: PodcastsInfiniteLazyRoute,
342365
AccountInboxInboxIdRoute: AccountInboxInboxIdRoute,
343366
FriendsAccountAddressRoute: FriendsAccountAddressRoute,
344367
SpaceSpaceIdRoute: SpaceSpaceIdRouteWithChildren,

apps/events/src/routes/__root.tsx

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,9 @@ export const Route = createRootRoute({
3636
<Link className="text-xs" to="/podcasts">
3737
Podcasts
3838
</Link>
39+
<Link className="text-xs" to="/podcasts-infinite">
40+
Podcasts Infinite Query
41+
</Link>
3942
<Link className="text-xs" to="/playground">
4043
Playground
4144
</Link>
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
import { useEntitiesPublicInfinite } from '@graphprotocol/hypergraph-react';
2+
import { createLazyFileRoute } from '@tanstack/react-router';
3+
import { useEffect } from 'react';
4+
import { Podcast } from '@/schema';
5+
6+
export const Route = createLazyFileRoute('/podcasts-infinite')({
7+
component: RouteComponent,
8+
});
9+
10+
function RouteComponent() {
11+
const space = 'e252f9e1-d3ad-4460-8bf1-54f93b02f220';
12+
13+
const { data, isLoading, isError, fetchNextPage } = useEntitiesPublicInfinite(Podcast, {
14+
first: 2,
15+
offset: 0,
16+
space: space,
17+
include: {
18+
projects: {},
19+
},
20+
});
21+
22+
useEffect(() => {
23+
setTimeout(() => {
24+
fetchNextPage();
25+
setTimeout(() => {
26+
fetchNextPage();
27+
}, 1000);
28+
}, 1000);
29+
}, [fetchNextPage]);
30+
console.log({ data, isLoading, isError });
31+
32+
return (
33+
<>
34+
<h1>Podcasts</h1>
35+
{isLoading && <div>Loading...</div>}
36+
{isError && <div>Error</div>}
37+
{data?.pages.map((page) => {
38+
return page.data.map((podcast) => (
39+
<div key={podcast.id}>
40+
<h2>{podcast.name}</h2>
41+
<hr />
42+
</div>
43+
));
44+
})}
45+
{/* <pre className="text-xs">{JSON.stringify(data, null, 2)}</pre> */}
46+
</>
47+
);
48+
}

apps/events/src/routes/podcasts.lazy.tsx

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,7 @@ function RouteComponent() {
1111

1212
const { data, isLoading, isError } = useEntities(Podcast, {
1313
mode: 'public',
14-
first: 6,
15-
offset: 0,
14+
first: 100,
1615
space: space,
1716
include: {
1817
projects: {},
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
import { Constants, Entity, Utils } from '@graphprotocol/hypergraph';
2+
import { useInfiniteQuery as useInfiniteQueryTanstack } from '@tanstack/react-query';
3+
import * as Option from 'effect/Option';
4+
import type * as Schema from 'effect/Schema';
5+
import * as SchemaAST from 'effect/SchemaAST';
6+
import type { QueryPublicParams } from '../internal/types.js';
7+
import { useHypergraphSpaceInternal } from '../internal/use-hypergraph-space-internal.js';
8+
9+
export const useEntitiesPublicInfinite = <S extends Schema.Schema.AnyNoContext>(
10+
type: S,
11+
params?: QueryPublicParams<S>,
12+
) => {
13+
const { enabled = true, filter, include, space: spaceFromParams, first = 2, offset = 0 } = params ?? {};
14+
const { space: spaceFromContext } = useHypergraphSpaceInternal();
15+
const space = spaceFromParams ?? spaceFromContext;
16+
17+
// constructing the relation type ids for the query
18+
const relationTypeIds = Utils.getRelationTypeIds(type, include);
19+
20+
const typeIds = SchemaAST.getAnnotation<string[]>(Constants.TypeIdsSymbol)(type.ast as SchemaAST.TypeLiteral).pipe(
21+
Option.getOrElse(() => []),
22+
);
23+
24+
const result = useInfiniteQueryTanstack({
25+
queryKey: [
26+
'hypergraph-public-entities',
27+
space,
28+
typeIds,
29+
relationTypeIds.level1,
30+
relationTypeIds.level2,
31+
filter,
32+
'infinite',
33+
],
34+
queryFn: async ({ pageParam }) => {
35+
return Entity.findManyPublic(type, { filter, include, space, first, offset: pageParam });
36+
},
37+
getNextPageParam: (_lastPage, pages) => {
38+
return offset + pages.length * first;
39+
},
40+
initialPageParam: offset,
41+
enabled,
42+
});
43+
44+
return result;
45+
};

packages/hypergraph-react/src/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ export { HypergraphSpaceProvider } from './HypergraphSpaceContext.js';
88
export { useCreateEntity } from './hooks/use-create-entity.js';
99
export { useDeleteEntity } from './hooks/use-delete-entity.js';
1010
export { useEntities } from './hooks/use-entities.js';
11+
export { useEntitiesPublicInfinite } from './hooks/use-entities-public-infinite.js';
1112
export { useEntity } from './hooks/use-entity.js';
1213
export { useHardDeleteEntity } from './hooks/use-hard-delete-entity.js';
1314
export { usePrivyAuthCreatePrivateSpace as _usePrivyAuthCreatePrivateSpace } from './hooks/use-privy-auth-create-private-space.js';

packages/hypergraph-react/src/internal/types.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import type { Entity } from '@graphprotocol/hypergraph';
22
import type * as Schema from 'effect/Schema';
33

44
export type QueryPublicParams<S extends Schema.Schema.AnyNoContext> = {
5-
enabled: boolean;
5+
enabled?: boolean | undefined;
66
filter?: Entity.EntityFilter<Schema.Schema.Type<S>> | undefined;
77
// TODO: for multi-level nesting it should only allow the allowed properties instead of Record<string, Record<string, never>>
88
include?: { [K in keyof Schema.Schema.Type<S>]?: Record<string, Record<string, never>> } | undefined;

0 commit comments

Comments
 (0)