Skip to content

Commit 596e1c9

Browse files
authored
implement base types (#191)
1 parent ff74686 commit 596e1c9

File tree

15 files changed

+198
-26
lines changed

15 files changed

+198
-26
lines changed

apps/events/src/components/create-properties-and-types.tsx

Lines changed: 57 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -28,9 +28,40 @@ const createPropertiesAndTypes = async ({
2828
});
2929
ops.push(...createAssigneesRelationTypeOps);
3030

31+
const { id: duePropertyId, ops: createDuePropertyOps } = Graph.createProperty({
32+
type: 'TIME',
33+
name: 'Due',
34+
});
35+
ops.push(...createDuePropertyOps);
36+
37+
const { id: pointPropertyId, ops: createPointPropertyOps } = Graph.createProperty({
38+
type: 'POINT',
39+
name: 'Point',
40+
});
41+
ops.push(...createPointPropertyOps);
42+
43+
const { id: amountPropertyId, ops: createAmountPropertyOps } = Graph.createProperty({
44+
type: 'NUMBER',
45+
name: 'Amount',
46+
});
47+
ops.push(...createAmountPropertyOps);
48+
49+
const { id: websitePropertyId, ops: createWebsitePropertyOps } = Graph.createProperty({
50+
type: 'URL',
51+
name: 'Website',
52+
});
53+
ops.push(...createWebsitePropertyOps);
54+
3155
const { id: todoTypeId, ops: createTodoTypeOps } = Graph.createType({
3256
name: 'Todo',
33-
properties: [checkedPropertyId, assigneesRelationTypeId],
57+
properties: [
58+
checkedPropertyId,
59+
assigneesRelationTypeId,
60+
duePropertyId,
61+
pointPropertyId,
62+
websitePropertyId,
63+
amountPropertyId,
64+
],
3465
});
3566
ops.push(...createTodoTypeOps);
3667

@@ -40,7 +71,17 @@ const createPropertiesAndTypes = async ({
4071
space,
4172
name: 'Create properties and types',
4273
});
43-
return { result, todoTypeId, checkedPropertyId, userId, assigneesRelationTypeId };
74+
return {
75+
result,
76+
todoTypeId,
77+
checkedPropertyId,
78+
userId,
79+
assigneesRelationTypeId,
80+
duePropertyId,
81+
pointPropertyId,
82+
websitePropertyId,
83+
amountPropertyId,
84+
};
4485
};
4586

4687
export const CreatePropertiesAndTypes = () => {
@@ -62,7 +103,16 @@ export const CreatePropertiesAndTypes = () => {
62103
if (!smartAccountWalletClient) {
63104
throw new Error('Missing smartAccountWalletClient');
64105
}
65-
const { todoTypeId, checkedPropertyId, userId, assigneesRelationTypeId } = await createPropertiesAndTypes({
106+
const {
107+
todoTypeId,
108+
checkedPropertyId,
109+
userId,
110+
assigneesRelationTypeId,
111+
duePropertyId,
112+
pointPropertyId,
113+
websitePropertyId,
114+
amountPropertyId,
115+
} = await createPropertiesAndTypes({
66116
smartAccountWalletClient,
67117
space,
68118
});
@@ -72,6 +122,10 @@ export const CreatePropertiesAndTypes = () => {
72122
properties: {
73123
name: Id.Id('LuBWqZAu6pz54eiJS5mLv8'),
74124
checked: Id.Id('${checkedPropertyId}'),
125+
due: Id.Id('${duePropertyId}'),
126+
point: Id.Id('${pointPropertyId}'),
127+
website: Id.Id('${websitePropertyId}'),
128+
amount: Id.Id('${amountPropertyId}'),
75129
},
76130
relations: {
77131
assignees: Id.Id('${assigneesRelationTypeId}'),

apps/events/src/components/todo/todos-local.tsx

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,10 @@ export const TodosLocal = () => {
1414
<div key={todo.id} className="flex flex-row items-center gap-2">
1515
<h2>{todo.name}</h2>
1616
<div className="text-xs">{todo.id}</div>
17+
<div className="text-xs">{todo.due.toLocaleDateString()}</div>
18+
<div className="text-xs">{todo.amount}</div>
19+
{todo.point && <div className="text-xs">{todo.point.join(', ')}</div>}
20+
{todo.website && <div className="text-xs">{todo.website.toString()}</div>}
1721
{todo.assignees.map((assignee) => (
1822
<span key={assignee.id} className="border rounded-sm mr-1 p-1">
1923
{assignee.name}

apps/events/src/components/todo/todos-public-geo.tsx

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,10 @@ export const TodosPublicGeo = () => {
3737
<div key={todo.id} className="flex flex-row items-center gap-2">
3838
<h2>{todo.name}</h2>
3939
<div className="text-xs">{todo.id}</div>
40+
<div className="text-xs">{todo.due.toLocaleDateString()}</div>
41+
<div className="text-xs">{todo.amount}</div>
42+
{todo.point && <div className="text-xs">{todo.point.join(', ')}</div>}
43+
{todo.website && <div className="text-xs">{todo.website.toString()}</div>}
4044
<input type="checkbox" checked={todo.checked} readOnly />
4145
{todo.assignees.map((assignee) => (
4246
<span key={assignee.id} className="border rounded-sm mr-1 p-1">
@@ -71,7 +75,15 @@ export const TodosPublicGeo = () => {
7175
throw new Error('Missing smartAccountWalletClient');
7276
}
7377
const userId = Id.Id('8zPJjTGLBDPtUcj6q2tghg');
74-
const todo = createTodo({ name: 'New Todo 22', checked: false, assignees: [userId] });
78+
const todo = createTodo({
79+
name: 'New Todo 22',
80+
checked: false,
81+
assignees: [userId],
82+
due: new Date('2025-08-20'),
83+
amount: 200,
84+
point: [12.34, 56.78],
85+
website: new URL('https://example.com'),
86+
});
7587
console.log('todo', todo);
7688
const { ops } = generateCreateOps(todo);
7789
console.log('ops', ops);

apps/events/src/components/todo/todos-public-kg.tsx

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,10 @@ export const TodosPublicKg = () => {
2424
<div key={todo.id} className="flex flex-row items-center gap-2">
2525
<h2>{todo.name}</h2>
2626
<div className="text-xs">{todo.id}</div>
27+
<div className="text-xs">{todo.due.toLocaleDateString()}</div>
28+
<div className="text-xs">{todo.amount}</div>
29+
{todo.point && <div className="text-xs">{todo.point.join(', ')}</div>}
30+
{todo.website && <div className="text-xs">{todo.website.toString()}</div>}
2731
<input type="checkbox" checked={todo.checked} readOnly />
2832
<Button
2933
onClick={async () => {

apps/events/src/components/todos2.tsx

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,10 @@ export const Todos2 = () => {
110110
checked={todo.checked}
111111
onChange={(e) => updateTodo(todo.id, { checked: e.target.checked })}
112112
/>
113+
<div className="text-xs">{todo.due.toLocaleDateString()}</div>
114+
<div className="text-xs">{todo.amount}</div>
115+
{todo.point && <div className="text-xs">{todo.point.join(', ')}</div>}
116+
{todo.website && <div className="text-xs">{todo.website.toString()}</div>}
113117
{todo.assignees.length > 0 && (
114118
<span className="text-xs text-gray-500">
115119
Assigned to:{' '}
@@ -155,7 +159,15 @@ export const Todos2 = () => {
155159
alert('Todo text is required');
156160
return;
157161
}
158-
createTodo({ name: newTodoName, checked: false, assignees: newTodoAssignees.map(({ value }) => value) });
162+
createTodo({
163+
name: newTodoName,
164+
checked: false,
165+
assignees: newTodoAssignees.map(({ value }) => value),
166+
due: new Date('2025-08-20'),
167+
amount: 100,
168+
point: [12.34, 56.78],
169+
website: new URL('https://example.com'),
170+
});
159171
setNewTodoName('');
160172
}}
161173
>

apps/events/src/mapping.ts

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11,17 +11,21 @@ export const mapping: Mapping = {
1111
},
1212
},
1313
Todo2: {
14-
typeIds: [Id.Id('4ewpH1mPW9f2tLhaHdKKyn')],
14+
typeIds: [Id.Id('LJuM8ju67mCv78FhAiK9k9')],
1515
properties: {
1616
name: Id.Id('LuBWqZAu6pz54eiJS5mLv8'),
17-
checked: Id.Id('7zyFtwuuf9evFNZqcLSytU'),
17+
checked: Id.Id('Ud9kn9gAUsCr1pxvxcgDj8'),
18+
due: Id.Id('CFisPgjjWVdnaMtSWJDBqA'),
19+
point: Id.Id('BkcVo7JZHF5LsWw7XZJwwe'),
20+
website: Id.Id('XZmLQ8XyaUHnNWgSSbzaHU'),
21+
amount: Id.Id('LfzKTfgy5Qg3PxAfKB2BL7'),
1822
},
1923
relations: {
20-
assignees: Id.Id('GeLe54zpz1MiMWAF8LFCCt'),
24+
assignees: Id.Id('HCdFcTRyMyZMXScKox738i'),
2125
},
2226
},
2327
User: {
24-
typeIds: [Id.Id('KYCunro75we8KbjpsDKbm7')],
28+
typeIds: [Id.Id('Fk5qzwdpKsD35gm5ts4SZA')],
2529
properties: {
2630
name: Id.Id('LuBWqZAu6pz54eiJS5mLv8'),
2731
},

apps/events/src/schema.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,10 @@ export class Todo2 extends Entity.Class<Todo2>('Todo2')({
1414
name: Entity.Text,
1515
checked: Entity.Checkbox,
1616
assignees: Entity.Relation(User),
17+
due: Entity.Date,
18+
amount: Entity.Number,
19+
point: Entity.Point,
20+
website: Entity.Url,
1721
}) {}
1822

1923
export class NewsStory extends Entity.Class<NewsStory>('NewsStory')({

packages/hypergraph-react/src/components/publish-diff/entity-card.tsx

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,8 @@ export const EntityCard = ({ entity, type }: EntityCardProps) => {
7777
{key.charAt(0).toUpperCase() + key.slice(1)}
7878
</td>
7979
<td className="py-1.5">
80-
{Array.isArray(value) ? (
80+
{/* check for number to exclude Point fields */}
81+
{Array.isArray(value) && !value.every((v) => typeof v === 'number') ? (
8182
<ul>
8283
{value.map(({ id, name }) => (
8384
<li key={id}>

packages/hypergraph-react/src/internal/use-generate-create-ops.tsx

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,18 @@ export function useGenerateCreateOps<const S extends Entity.AnyNoContext>(type:
2424
if (fields[key] === Entity.Checkbox) {
2525
valueType = 'CHECKBOX';
2626
serializedValue = properties[key] ? '1' : '0';
27+
} else if (fields[key] === Entity.Date) {
28+
valueType = 'TIME';
29+
serializedValue = properties[key].toISOString();
30+
} else if (fields[key] === Entity.Point) {
31+
valueType = 'POINT';
32+
serializedValue = properties[key].join(',');
33+
} else if (fields[key] === Entity.Url) {
34+
valueType = 'URL';
35+
serializedValue = properties[key].toString();
36+
} else if (fields[key] === Entity.Number) {
37+
valueType = 'NUMBER';
38+
serializedValue = properties[key].toString();
2739
}
2840

2941
grcProperties[value] = {

packages/hypergraph-react/src/internal/use-generate-update-ops.tsx

Lines changed: 30 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { Id, type Op, Relation, Triple, type Value } from '@graphprotocol/grc-20';
2-
import type { Entity } from '@graphprotocol/hypergraph';
2+
import { Entity } from '@graphprotocol/hypergraph';
33
import { useHypergraph } from '../HypergraphSpaceContext.js';
44
import type { DiffEntry } from '../types.js';
55

@@ -31,18 +31,41 @@ export function useGenerateUpdateOps<const S extends Entity.AnyNoContext>(type:
3131
const rawValue = propertyDiff.new;
3232

3333
let value: Value;
34-
if (typeof rawValue === 'boolean') {
34+
if (type.fields[key] === Entity.Checkbox) {
3535
value = {
3636
type: 'CHECKBOX',
3737
value: rawValue ? '1' : '0',
3838
};
39+
} else if (type.fields[key] === Entity.Point) {
40+
value = {
41+
type: 'POINT',
42+
// @ts-expect-error: must be an array of numbers
43+
value: rawValue.join(','),
44+
};
45+
} else if (type.fields[key] === Entity.Url) {
46+
value = {
47+
type: 'URL',
48+
// @ts-expect-error: must be a URL
49+
value: rawValue.toString(),
50+
};
51+
} else if (type.fields[key] === Entity.Date) {
52+
value = {
53+
type: 'TIME',
54+
// @ts-expect-error: must be a Date
55+
value: rawValue.toISOString(),
56+
};
57+
} else if (type.fields[key] === Entity.Number) {
58+
value = {
59+
type: 'NUMBER',
60+
// @ts-expect-error: must be a number
61+
value: rawValue.toString(),
62+
};
3963
} else {
4064
value = {
4165
type: 'TEXT',
4266
value: rawValue as string,
4367
};
4468
}
45-
4669
const op = Triple.make({
4770
attributeId: propertyId,
4871
entityId: id,
@@ -53,7 +76,10 @@ export function useGenerateUpdateOps<const S extends Entity.AnyNoContext>(type:
5376

5477
for (const [key, relationId] of Object.entries(mappingEntry.relations || {})) {
5578
const relationDiff = diff[key];
56-
if (relationDiff === undefined || relationDiff.type === 'property') {
79+
if (!relationDiff) {
80+
continue;
81+
}
82+
if (relationDiff.type === 'property') {
5783
throw new Error(`Invalid diff or mapping for generating update Ops on the relation \`${key}\``);
5884
}
5985
for (const toId of relationDiff.addedIds) {

0 commit comments

Comments
 (0)