Skip to content

Commit e965c6d

Browse files
committed
implement prepare publish
1 parent 6267464 commit e965c6d

File tree

1 file changed

+51
-88
lines changed

1 file changed

+51
-88
lines changed

packages/hypergraph-react/src/prepare-publish.ts

Lines changed: 51 additions & 88 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,8 @@
1-
import {
2-
type EntityRelationParams,
3-
Graph,
4-
type Id,
5-
type Op,
6-
type PropertiesParam,
7-
type RelationsParam,
8-
} from '@graphprotocol/grc-20';
9-
import type { Entity } from '@graphprotocol/hypergraph';
10-
import { store } from '@graphprotocol/hypergraph';
1+
import { Graph, type Id, type Op, type PropertiesParam, type RelationsParam } from '@graphprotocol/grc-20';
2+
import { Constants, type Entity, Utils } from '@graphprotocol/hypergraph';
3+
import * as Option from 'effect/Option';
114
import type * as Schema from 'effect/Schema';
5+
import * as SchemaAST from 'effect/SchemaAST';
126
import request, { gql } from 'graphql-request';
137

148
export type PreparePublishParams<S extends Schema.Schema.AnyNoContext> = {
@@ -63,101 +57,70 @@ export const preparePublish = async <S extends Schema.Schema.AnyNoContext>({
6357
},
6458
);
6559

66-
const mapping = store.getSnapshot().context.mapping;
67-
const typeName = entity.type;
68-
const mappingEntry = mapping[typeName];
69-
if (!mappingEntry) {
70-
throw new Error(`Mapping entry for ${typeName} not found`);
71-
}
72-
7360
const ops: Op[] = [];
7461
const values: PropertiesParam = [];
7562
const relations: RelationsParam = {};
76-
const fields = entity.__schema.fields;
63+
const type = entity.__schema;
7764

7865
if (data?.entity === null) {
79-
for (const [key, propertyId] of Object.entries(mappingEntry.properties || {})) {
80-
if (entity[key] === undefined) {
81-
if (TypeUtils.isOptional(fields[key])) {
82-
continue;
83-
}
84-
throw new Error(`Value for ${key} is undefined`);
85-
}
86-
let serializedValue: string = entity[key];
87-
if (TypeUtils.isBooleanOrOptionalBooleanType(fields[key])) {
88-
serializedValue = Graph.serializeBoolean(entity[key]);
89-
} else if (TypeUtils.isDateOrOptionalDateType(fields[key])) {
90-
serializedValue = Graph.serializeDate(entity[key]);
91-
} else if (TypeUtils.isPointOrOptionalPointType(fields[key])) {
92-
serializedValue = Graph.serializePoint(entity[key]);
93-
} else if (TypeUtils.isNumberOrOptionalNumberType(fields[key])) {
94-
serializedValue = Graph.serializeNumber(entity[key]);
95-
}
96-
values.push({ property: propertyId, value: serializedValue });
97-
}
98-
for (const [key, relationId] of Object.entries(mappingEntry.relations || {})) {
99-
// @ts-expect-error - TODO: fix the types error
100-
relations[relationId] = entity[key].map((relationEntity) => {
101-
const newRelation: EntityRelationParams = { toEntity: relationEntity.id };
102-
if (relationEntity._relation.id) {
103-
newRelation.id = relationEntity._relation.id;
66+
const ast = type.ast as SchemaAST.TypeLiteral;
67+
68+
const typeIds = SchemaAST.getAnnotation<string[]>(Constants.TypeIdsSymbol)(ast).pipe(Option.getOrElse(() => []));
69+
70+
for (const prop of ast.propertySignatures) {
71+
const propertyId = SchemaAST.getAnnotation<string>(Constants.PropertyIdSymbol)(prop.type);
72+
const propertyType = SchemaAST.getAnnotation<string>(Constants.PropertyTypeSymbol)(prop.type);
73+
if (!Option.isSome(propertyId) || !Option.isSome(propertyType)) continue;
74+
75+
if (Utils.isRelation(prop.type)) {
76+
// @ts-expect-error any is ok here
77+
relations[propertyId.value] = entity[prop.name].map((relationEntity) => {
78+
const newRelation: Record<string, string> = { toEntity: relationEntity.id };
79+
if (relationEntity._relation.id) {
80+
newRelation.id = relationEntity._relation.id;
81+
}
82+
if (relationEntity._relation.position) {
83+
newRelation.position = relationEntity._relation.position;
84+
}
85+
return newRelation;
86+
});
87+
} else {
88+
if (entity[prop.name] === undefined) {
89+
if (prop.isOptional) {
90+
continue;
91+
}
92+
throw new Error(`Value for ${String(prop.name)} is undefined`);
10493
}
105-
if (relationEntity._relation.position) {
106-
newRelation.position = relationEntity._relation.position;
94+
let serializedValue: string = entity[prop.name];
95+
if (propertyType.value === 'boolean') {
96+
serializedValue = Graph.serializeBoolean(entity[prop.name]);
97+
} else if (propertyType.value === 'date') {
98+
serializedValue = Graph.serializeDate(entity[prop.name]);
99+
} else if (propertyType.value === 'point') {
100+
serializedValue = Graph.serializePoint(entity[prop.name]);
101+
} else if (propertyType.value === 'number') {
102+
serializedValue = Graph.serializeNumber(entity[prop.name]);
107103
}
108-
return newRelation;
109-
});
104+
values.push({ property: propertyId.value, value: serializedValue });
105+
}
110106
}
107+
111108
const { ops: createOps } = Graph.createEntity({
112109
id: entity.id,
113-
types: mappingEntry.typeIds,
110+
types: typeIds,
114111
values,
115112
relations,
116113
});
117114
ops.push(...createOps);
118115
return { ops };
119116
}
120117

121-
if (data?.entity) {
122-
for (const [key, propertyId] of Object.entries(mappingEntry.properties || {})) {
123-
if (entity[key] === undefined) {
124-
if (TypeUtils.isOptional(fields[key])) {
125-
continue;
126-
}
127-
throw new Error(`Value for ${key} is undefined`);
128-
}
129-
130-
const existingValueEntry = data.entity.valuesList.find((value) => value.propertyId === propertyId);
131-
let existingValue = existingValueEntry?.string;
132-
let serializedValue: string = entity[key];
133-
if (TypeUtils.isBooleanOrOptionalBooleanType(fields[key])) {
134-
existingValue =
135-
existingValueEntry?.boolean !== undefined ? Graph.serializeBoolean(existingValueEntry.boolean) : undefined;
136-
serializedValue = Graph.serializeBoolean(entity[key]);
137-
} else if (TypeUtils.isDateOrOptionalDateType(fields[key])) {
138-
existingValue = existingValueEntry?.time;
139-
serializedValue = Graph.serializeDate(entity[key]);
140-
} else if (TypeUtils.isPointOrOptionalPointType(fields[key])) {
141-
existingValue = existingValueEntry?.point;
142-
serializedValue = Graph.serializePoint(entity[key]);
143-
} else if (TypeUtils.isNumberOrOptionalNumberType(fields[key])) {
144-
existingValue =
145-
existingValueEntry?.number !== undefined ? Graph.serializeNumber(existingValueEntry.number) : undefined;
146-
serializedValue = Graph.serializeNumber(entity[key]);
147-
}
148-
149-
if (serializedValue !== existingValue) {
150-
values.push({ property: propertyId, value: serializedValue });
151-
}
152-
}
153-
154-
// TODO: handle added or removed relations
155-
// TODO: handle updated relations
156-
// TODO: handle added or removed types
157-
if (values.length > 0) {
158-
const { ops: updateEntityOps } = Graph.updateEntity({ id: entity.id, values });
159-
ops.push(...updateEntityOps);
160-
}
118+
// TODO: handle added or removed relations
119+
// TODO: handle updated relations
120+
// TODO: handle added or removed types
121+
if (values.length > 0) {
122+
const { ops: updateEntityOps } = Graph.updateEntity({ id: entity.id, values });
123+
ops.push(...updateEntityOps);
161124
}
162125

163126
return { ops };

0 commit comments

Comments
 (0)