Skip to content

Commit 04b30eb

Browse files
committed
rename Entity.findMany to findManyPrivate and add Entity.findManyPublic
1 parent 00e022e commit 04b30eb

16 files changed

+508
-385
lines changed

packages/hypergraph-react/src/internal/convert-relations.ts

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@ import { Constants, Utils } from '@graphprotocol/hypergraph';
22
import * as Option from 'effect/Option';
33
import type * as Schema from 'effect/Schema';
44
import * as SchemaAST from 'effect/SchemaAST';
5-
import { convertPropertyValue } from './convert-property-value.js';
65

76
// A recursive representation of the entity structure returned by the public GraphQL
87
// endpoint. `values` and `relations` are optional because the nested `to` selections
@@ -84,7 +83,7 @@ export const convertRelations = <_S extends Schema.Schema.AnyNoContext>(
8483
if (!value) {
8584
continue;
8685
}
87-
const rawValue = convertPropertyValue(value, nestedProp.type);
86+
const rawValue = Utils.convertPropertyValue(value, nestedProp.type);
8887
if (rawValue) {
8988
nestedRawEntity[String(nestedProp.name)] = rawValue;
9089
}
Lines changed: 5 additions & 262 deletions
Original file line numberDiff line numberDiff line change
@@ -1,250 +1,18 @@
1-
import { Graph } from '@graphprotocol/grc-20';
2-
import { Constants, type Entity, Utils } from '@graphprotocol/hypergraph';
1+
import { Constants, Entity, Utils } from '@graphprotocol/hypergraph';
32
import { useQuery as useQueryTanstack } from '@tanstack/react-query';
4-
import * as Either from 'effect/Either';
53
import * as Option from 'effect/Option';
6-
import * as Schema from 'effect/Schema';
4+
import type * as Schema from 'effect/Schema';
75
import * as SchemaAST from 'effect/SchemaAST';
8-
import { gql, request } from 'graphql-request';
9-
import { useMemo } from 'react';
10-
import { convertPropertyValue } from './convert-property-value.js';
11-
import { convertRelations } from './convert-relations.js';
12-
import { getRelationTypeIds } from './get-relation-type-ids.js';
13-
import { translateFilterToGraphql } from './translate-filter-to-graphql.js';
146
import type { QueryPublicParams } from './types.js';
157
import { useHypergraphSpaceInternal } from './use-hypergraph-space-internal.js';
168

17-
const entitiesQueryDocumentLevel0 = gql`
18-
query entities($spaceId: UUID!, $typeIds: [UUID!]!, $first: Int, $filter: EntityFilter!) {
19-
entities(
20-
filter: { and: [{
21-
relations: {some: {typeId: {is: "8f151ba4-de20-4e3c-9cb4-99ddf96f48f1"}, toEntityId: {in: $typeIds}}},
22-
spaceIds: {in: [$spaceId]},
23-
}, $filter]}
24-
first: $first
25-
) {
26-
id
27-
name
28-
valuesList(filter: {spaceId: {is: $spaceId}}) {
29-
propertyId
30-
string
31-
boolean
32-
number
33-
time
34-
point
35-
}
36-
}
37-
}
38-
`;
39-
40-
const entitiesQueryDocumentLevel1 = gql`
41-
query entities($spaceId: UUID!, $typeIds: [UUID!]!, $relationTypeIdsLevel1: [UUID!]!, $first: Int, $filter: EntityFilter!) {
42-
entities(
43-
first: $first
44-
filter: { and: [{
45-
relations: {some: {typeId: {is: "8f151ba4-de20-4e3c-9cb4-99ddf96f48f1"}, toEntityId: {in: $typeIds}}},
46-
spaceIds: {in: [$spaceId]},
47-
}, $filter]}
48-
) {
49-
id
50-
name
51-
valuesList(filter: {spaceId: {is: $spaceId}}) {
52-
propertyId
53-
string
54-
boolean
55-
number
56-
time
57-
point
58-
}
59-
relationsList(
60-
filter: {spaceId: {is: $spaceId}, typeId:{ in: $relationTypeIdsLevel1}},
61-
) {
62-
id
63-
toEntity {
64-
id
65-
name
66-
valuesList(filter: {spaceId: {is: $spaceId}}) {
67-
propertyId
68-
string
69-
boolean
70-
number
71-
time
72-
point
73-
}
74-
}
75-
typeId
76-
}
77-
}
78-
}
79-
`;
80-
81-
const entitiesQueryDocumentLevel2 = gql`
82-
query entities($spaceId: UUID!, $typeIds: [UUID!]!, $relationTypeIdsLevel1: [UUID!]!, $relationTypeIdsLevel2: [UUID!]!, $first: Int, $filter: EntityFilter!) {
83-
entities(
84-
first: $first
85-
filter: { and: [{
86-
relations: {some: {typeId: {is: "8f151ba4-de20-4e3c-9cb4-99ddf96f48f1"}, toEntityId: {in: $typeIds}}},
87-
spaceIds: {in: [$spaceId]},
88-
}, $filter]}
89-
) {
90-
id
91-
name
92-
valuesList(filter: {spaceId: {is: $spaceId}}) {
93-
propertyId
94-
string
95-
boolean
96-
number
97-
time
98-
point
99-
}
100-
relationsList(
101-
filter: {spaceId: {is: $spaceId}, typeId:{ in: $relationTypeIdsLevel1}},
102-
) {
103-
id
104-
toEntity {
105-
id
106-
name
107-
valuesList(filter: {spaceId: {is: $spaceId}}) {
108-
propertyId
109-
string
110-
boolean
111-
number
112-
time
113-
point
114-
}
115-
relationsList(
116-
filter: {spaceId: {is: $spaceId}, typeId:{ in: $relationTypeIdsLevel2}},
117-
# filter: {spaceId: {is: $spaceId}, toEntity: {relations: {some: {typeId: {is: "8f151ba4-de20-4e3c-9cb4-99ddf96f48f1"}, toEntityId: {in: $relationTypeIdsLevel2}}}}}
118-
) {
119-
id
120-
toEntity {
121-
id
122-
name
123-
valuesList(filter: {spaceId: {is: $spaceId}}) {
124-
propertyId
125-
string
126-
boolean
127-
number
128-
time
129-
point
130-
}
131-
}
132-
typeId
133-
}
134-
}
135-
typeId
136-
}
137-
}
138-
}
139-
`;
140-
141-
type EntityQueryResult = {
142-
entities: {
143-
id: string;
144-
name: string;
145-
valuesList: {
146-
propertyId: string;
147-
string: string;
148-
boolean: boolean;
149-
number: number;
150-
time: string;
151-
point: string;
152-
}[];
153-
relationsList: {
154-
id: string;
155-
toEntity: {
156-
id: string;
157-
name: string;
158-
valuesList: {
159-
propertyId: string;
160-
string: string;
161-
boolean: boolean;
162-
number: number;
163-
time: string;
164-
point: string;
165-
}[];
166-
relationsList: {
167-
id: string;
168-
toEntity: {
169-
id: string;
170-
name: string;
171-
valuesList: {
172-
propertyId: string;
173-
string: string;
174-
boolean: boolean;
175-
number: number;
176-
time: string;
177-
point: string;
178-
}[];
179-
};
180-
typeId: string;
181-
}[];
182-
};
183-
typeId: string;
184-
}[];
185-
}[];
186-
};
187-
188-
export const parseResult = <S extends Schema.Schema.AnyNoContext>(queryData: EntityQueryResult, type: S) => {
189-
const schemaWithId = Utils.addIdSchemaField(type);
190-
const decode = Schema.decodeUnknownEither(schemaWithId);
191-
const data: Entity.Entity<S>[] = [];
192-
const invalidEntities: Record<string, unknown>[] = [];
193-
194-
for (const queryEntity of queryData.entities) {
195-
let rawEntity: Record<string, string | boolean | number | unknown[] | Date> = {
196-
id: queryEntity.id,
197-
};
198-
199-
const ast = type.ast as SchemaAST.TypeLiteral;
200-
201-
for (const prop of ast.propertySignatures) {
202-
const propType =
203-
prop.isOptional && SchemaAST.isUnion(prop.type)
204-
? (prop.type.types.find((member) => !SchemaAST.isUndefinedKeyword(member)) ?? prop.type)
205-
: prop.type;
206-
207-
const result = SchemaAST.getAnnotation<string>(Constants.PropertyIdSymbol)(propType);
208-
209-
if (Option.isSome(result)) {
210-
const value = queryEntity.valuesList.find((a) => a.propertyId === result.value);
211-
if (value) {
212-
const rawValue = convertPropertyValue(value, propType);
213-
if (rawValue) {
214-
rawEntity[String(prop.name)] = rawValue;
215-
}
216-
}
217-
}
218-
}
219-
220-
// @ts-expect-error
221-
rawEntity = {
222-
...rawEntity,
223-
...convertRelations(queryEntity, ast),
224-
};
225-
226-
const decodeResult = decode({
227-
...rawEntity,
228-
__deleted: false,
229-
});
230-
231-
if (Either.isRight(decodeResult)) {
232-
// injecting the schema to the entity to be able to access it in the preparePublish function
233-
data.push({ ...decodeResult.right, __schema: type });
234-
} else {
235-
invalidEntities.push(rawEntity);
236-
}
237-
}
238-
return { data, invalidEntities };
239-
};
240-
2419
export const useEntitiesPublic = <S extends Schema.Schema.AnyNoContext>(type: S, params?: QueryPublicParams<S>) => {
24210
const { enabled = true, filter, include, space: spaceFromParams, first = 100 } = params ?? {};
24311
const { space: spaceFromContext } = useHypergraphSpaceInternal();
24412
const space = spaceFromParams ?? spaceFromContext;
24513

24614
// constructing the relation type ids for the query
247-
const relationTypeIds = getRelationTypeIds(type, include);
15+
const relationTypeIds = Utils.getRelationTypeIds(type, include);
24816

24917
const typeIds = SchemaAST.getAnnotation<string[]>(Constants.TypeIdsSymbol)(type.ast as SchemaAST.TypeLiteral).pipe(
25018
Option.getOrElse(() => []),
@@ -261,35 +29,10 @@ export const useEntitiesPublic = <S extends Schema.Schema.AnyNoContext>(type: S,
26129
first,
26230
],
26331
queryFn: async () => {
264-
let queryDocument = entitiesQueryDocumentLevel0;
265-
if (relationTypeIds.level1.length > 0) {
266-
queryDocument = entitiesQueryDocumentLevel1;
267-
}
268-
if (relationTypeIds.level2.length > 0) {
269-
queryDocument = entitiesQueryDocumentLevel2;
270-
}
271-
272-
const filterParams = filter ? translateFilterToGraphql(filter, type) : {};
273-
274-
const result = await request<EntityQueryResult>(`${Graph.TESTNET_API_ORIGIN}/graphql`, queryDocument, {
275-
spaceId: space,
276-
typeIds,
277-
relationTypeIdsLevel1: relationTypeIds.level1,
278-
relationTypeIdsLevel2: relationTypeIds.level2,
279-
first,
280-
filter: filterParams,
281-
});
282-
return result;
32+
return Entity.findManyPublic(type, { filter, include, space, first });
28333
},
28434
enabled,
28535
});
28636

287-
const { data, invalidEntities } = useMemo(() => {
288-
if (result.data) {
289-
return parseResult(result.data, type);
290-
}
291-
return { data: [], invalidEntities: [] };
292-
}, [result.data, type]);
293-
294-
return { ...result, data, invalidEntities };
37+
return { ...result, data: result.data?.data || [], invalidEntities: result.data?.invalidEntities || [] };
29538
};

packages/hypergraph-react/src/internal/use-entity-public.tsx

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,6 @@ import * as Schema from 'effect/Schema';
77
import * as SchemaAST from 'effect/SchemaAST';
88
import { gql, request } from 'graphql-request';
99
import { useMemo } from 'react';
10-
import { convertPropertyValue } from './convert-property-value.js';
11-
import { convertRelations } from './convert-relations.js';
12-
import { getRelationTypeIds } from './get-relation-type-ids.js';
1310
import { useHypergraphSpaceInternal } from './use-hypergraph-space-internal.js';
1411

1512
const entityQueryDocumentLevel0 = gql`
@@ -195,7 +192,7 @@ export const parseResult = <S extends Schema.Schema.AnyNoContext>(queryData: Ent
195192
if (Option.isSome(result)) {
196193
const value = queryEntity.valuesList.find((a) => a.propertyId === result.value);
197194
if (value) {
198-
const rawValue = convertPropertyValue(value, propType);
195+
const rawValue = Utils.convertPropertyValue(value, propType);
199196
if (rawValue) {
200197
rawEntity[String(prop.name)] = rawValue;
201198
}
@@ -206,7 +203,7 @@ export const parseResult = <S extends Schema.Schema.AnyNoContext>(queryData: Ent
206203
// @ts-expect-error
207204
rawEntity = {
208205
...rawEntity,
209-
...convertRelations(queryEntity, ast),
206+
...Utils.convertRelations(queryEntity, ast),
210207
};
211208

212209
const decodeResult = decode({
@@ -239,7 +236,7 @@ export const useEntityPublic = <S extends Schema.Schema.AnyNoContext>(type: S, p
239236
const space = spaceFromParams ?? spaceFromContext;
240237

241238
// constructing the relation type ids for the query
242-
const relationTypeIds = getRelationTypeIds(type, include);
239+
const relationTypeIds = Utils.getRelationTypeIds(type, include);
243240

244241
const typeIds = SchemaAST.getAnnotation<string[]>(Constants.TypeIdsSymbol)(type.ast as SchemaAST.TypeLiteral).pipe(
245242
Option.getOrElse(() => []),

packages/hypergraph/package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,7 @@
8181
"@xstate/store": "^3.9.2",
8282
"bs58check": "^4.0.0",
8383
"effect": "^3.17.13",
84+
"graphql-request": "^7.2.0",
8485
"open": "^10.2.0",
8586
"permissionless": "^0.2.47",
8687
"siwe": "^3.0.0",

packages/hypergraph/src/entity/findMany.ts renamed to packages/hypergraph/src/entity/find-many-private.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import * as SchemaAST from 'effect/SchemaAST';
55
import { TypeIdsSymbol } from '../constants.js';
66
import { deepMerge } from '../utils/internal/deep-merge.js';
77
import { canonicalize } from '../utils/jsc.js';
8-
import { type DecodedEntitiesCacheEntry, decodedEntitiesCache, type QueryEntry } from './decodedEntitiesCache.js';
8+
import { decodedEntitiesCache, type DecodedEntitiesCacheEntry, type QueryEntry } from './decodedEntitiesCache.js';
99
import { entityRelationParentsMap } from './entityRelationParentsMap.js';
1010
import { getEntityRelations } from './getEntityRelations.js';
1111
import { hasValidTypesProperty } from './hasValidTypesProperty.js';
@@ -240,7 +240,7 @@ const subscribeToDocumentChanges = (handle: DocHandle<DocumentContent>) => {
240240
/**
241241
* Queries for a list of entities of the given type from the repo.
242242
*/
243-
export function findMany<const S extends Schema.Schema.AnyNoContext>(
243+
export function findManyPrivate<const S extends Schema.Schema.AnyNoContext>(
244244
handle: DocHandle<DocumentContent>,
245245
type: S,
246246
filter: EntityFilter<Schema.Schema.Type<S>> | undefined,
@@ -431,7 +431,7 @@ export function subscribeToFindMany<const S extends Schema.Schema.AnyNoContext>(
431431
return query.data;
432432
}
433433

434-
const { entities } = findMany(handle, type, filter, include);
434+
const { entities } = findManyPrivate(handle, type, filter, include);
435435

436436
for (const entity of entities) {
437437
cacheEntry?.entities.set(entity.id, entity);

0 commit comments

Comments
 (0)