Skip to content

Commit 8c5632f

Browse files
committed
remove repo and handle from HypergraphSpace context
1 parent 0609380 commit 8c5632f

2 files changed

Lines changed: 39 additions & 53 deletions

File tree

Lines changed: 2 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,6 @@
11
import { SpaceChat } from '@/components/SpaceChat';
2-
import { store } from '@graphprotocol/hypergraph';
3-
import { HypergraphSpaceProvider, useHypergraphApp } from '@graphprotocol/hypergraph-react';
2+
import { useHypergraphApp } from '@graphprotocol/hypergraph-react';
43
import { createFileRoute } from '@tanstack/react-router';
5-
import { useSelector } from '@xstate/store/react';
64
import { useEffect } from 'react';
75

86
export const Route = createFileRoute('/space/$spaceId/chat')({
@@ -11,29 +9,20 @@ export const Route = createFileRoute('/space/$spaceId/chat')({
119

1210
function RouteComponent() {
1311
const { spaceId } = Route.useParams();
14-
const spaces = useSelector(store, (state) => state.context.spaces);
1512
const { subscribeToSpace, isConnecting } = useHypergraphApp();
1613
useEffect(() => {
1714
if (!isConnecting) {
1815
subscribeToSpace({ spaceId });
1916
}
2017
}, [isConnecting, subscribeToSpace, spaceId]);
2118

22-
const space = spaces.find((space) => space.id === spaceId);
23-
2419
if (isConnecting) {
2520
return <div className="flex justify-center items-center h-screen">Loading …</div>;
2621
}
2722

28-
if (!space) {
29-
return <div className="flex justify-center items-center h-screen">Space not found</div>;
30-
}
31-
3223
return (
3324
<div className="flex flex-col gap-4 max-w-(--breakpoint-sm) mx-auto py-8">
34-
<HypergraphSpaceProvider space={spaceId}>
35-
<SpaceChat spaceId={spaceId} />
36-
</HypergraphSpaceProvider>
25+
<SpaceChat spaceId={spaceId} />
3726
</div>
3827
);
3928
}

packages/hypergraph-react/src/HypergraphSpaceContext.tsx

Lines changed: 37 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,12 @@
11
'use client';
22

3-
import type { AnyDocumentId, DocHandle, Repo } from '@automerge/automerge-repo';
3+
import type { AnyDocumentId } from '@automerge/automerge-repo';
44
import { useRepo } from '@automerge/automerge-repo-react-hooks';
55
import { Entity, Utils } from '@graphprotocol/hypergraph';
66
import * as Schema from 'effect/Schema';
77
import { type ReactNode, createContext, useContext, useMemo, useRef, useState, useSyncExternalStore } from 'react';
88

9-
export type HypergraphContext = {
10-
space: string;
11-
repo: Repo;
12-
id: AnyDocumentId;
13-
handle: DocHandle<Entity.DocumentContent>;
14-
};
9+
export type HypergraphContext = { space: string };
1510

1611
export const HypergraphReactContext = createContext<HypergraphContext | undefined>(undefined);
1712

@@ -25,48 +20,48 @@ function useHypergraphSpaceInternal() {
2520
}
2621

2722
export function HypergraphSpaceProvider({ space, children }: { space: string; children: ReactNode }) {
28-
const repo = useRepo();
29-
const ref = useRef<HypergraphContext | undefined>(undefined);
23+
return <HypergraphReactContext.Provider value={{ space }}>{children}</HypergraphReactContext.Provider>;
24+
}
3025

31-
let current = ref.current;
32-
if (current === undefined || space !== current.space || repo !== current.repo) {
33-
const id = Utils.idToAutomergeId(space) as AnyDocumentId;
26+
function useAutomergeHandle({ spaceId }: { spaceId: string }) {
27+
const repo = useRepo();
28+
const handle = useMemo(() => {
29+
const id = Utils.idToAutomergeId(spaceId) as AnyDocumentId;
3430
const result = repo.findWithProgress<Entity.DocumentContent>(id);
31+
return result.handle;
32+
}, [spaceId, repo]);
3533

36-
current = ref.current = {
37-
space,
38-
repo,
39-
id,
40-
handle: result.handle,
41-
};
42-
}
43-
44-
return <HypergraphReactContext.Provider value={current}>{children}</HypergraphReactContext.Provider>;
34+
return handle;
4535
}
4636

4737
export function useCreateEntity<const S extends Entity.AnyNoContext>(type: S) {
48-
const hypergraph = useHypergraphSpaceInternal();
49-
return Entity.create(hypergraph.handle, type);
38+
const { space } = useHypergraphSpaceInternal();
39+
const handle = useAutomergeHandle({ spaceId: space });
40+
return Entity.create(handle, type);
5041
}
5142

5243
export function useUpdateEntity<const S extends Entity.AnyNoContext>(type: S) {
53-
const hypergraph = useHypergraphSpaceInternal();
54-
return Entity.update(hypergraph.handle, type);
44+
const { space } = useHypergraphSpaceInternal();
45+
const handle = useAutomergeHandle({ spaceId: space });
46+
return Entity.update(handle, type);
5547
}
5648

5749
export function useDeleteEntity() {
58-
const hypergraph = useHypergraphSpaceInternal();
59-
return Entity.markAsDeleted(hypergraph.handle);
50+
const { space } = useHypergraphSpaceInternal();
51+
const handle = useAutomergeHandle({ spaceId: space });
52+
return Entity.markAsDeleted(handle);
6053
}
6154

6255
export function useRemoveRelation() {
63-
const hypergraph = useHypergraphSpaceInternal();
64-
return Entity.removeRelation(hypergraph.handle);
56+
const { space } = useHypergraphSpaceInternal();
57+
const handle = useAutomergeHandle({ spaceId: space });
58+
return Entity.removeRelation(handle);
6559
}
6660

6761
export function useHardDeleteEntity() {
68-
const hypergraph = useHypergraphSpaceInternal();
69-
return Entity.delete(hypergraph.handle);
62+
const { space } = useHypergraphSpaceInternal();
63+
const handle = useAutomergeHandle({ spaceId: space });
64+
return Entity.delete(handle);
7065
}
7166

7267
type QueryParams<S extends Entity.AnyNoContext> = {
@@ -78,8 +73,9 @@ type QueryParams<S extends Entity.AnyNoContext> = {
7873
export function useQueryLocal<const S extends Entity.AnyNoContext>(type: S, params?: QueryParams<S>) {
7974
const { enabled = true, filter, include } = params ?? {};
8075
const entitiesRef = useRef<Entity.Entity<S>[]>([]);
76+
const { space } = useHypergraphSpaceInternal();
77+
const handle = useAutomergeHandle({ spaceId: space });
8178

82-
const hypergraph = useHypergraphSpaceInternal();
8379
const [subscription] = useState(() => {
8480
if (!enabled) {
8581
return {
@@ -88,7 +84,7 @@ export function useQueryLocal<const S extends Entity.AnyNoContext>(type: S, para
8884
};
8985
}
9086

91-
return Entity.subscribeToFindMany(hypergraph.handle, type, filter, include);
87+
return Entity.subscribeToFindMany(handle, type, filter, include);
9288
});
9389

9490
// TODO: allow to change the enabled state
@@ -116,7 +112,8 @@ export function useQueryEntity<const S extends Entity.AnyNoContext>(
116112
id: string,
117113
include?: { [K in keyof Schema.Schema.Type<S>]?: Record<string, never> },
118114
) {
119-
const hypergraph = useHypergraphSpaceInternal();
115+
const { space } = useHypergraphSpaceInternal();
116+
const handle = useAutomergeHandle({ spaceId: space });
120117
const prevEntityRef = useRef<Entity.Entity<S> | undefined>(undefined);
121118
const equals = Schema.equivalence(type);
122119

@@ -129,22 +126,22 @@ export function useQueryEntity<const S extends Entity.AnyNoContext>(
129126
callback();
130127
};
131128

132-
hypergraph.handle.on('change', handleChange);
133-
hypergraph.handle.on('delete', handleDelete);
129+
handle.on('change', handleChange);
130+
handle.on('delete', handleDelete);
134131

135132
return () => {
136-
hypergraph.handle.off('change', handleChange);
137-
hypergraph.handle.off('delete', handleDelete);
133+
handle.off('change', handleChange);
134+
handle.off('delete', handleDelete);
138135
};
139136
};
140137

141138
return useSyncExternalStore(subscribe, () => {
142-
const doc = hypergraph.handle.doc();
139+
const doc = handle.doc();
143140
if (doc === undefined) {
144141
return prevEntityRef.current;
145142
}
146143

147-
const found = Entity.findOne(hypergraph.handle, type, include)(id);
144+
const found = Entity.findOne(handle, type, include)(id);
148145
if (found === undefined && prevEntityRef.current !== undefined) {
149146
// entity was maybe deleted, delete from the ref
150147
prevEntityRef.current = undefined;

0 commit comments

Comments
 (0)