Skip to content

Commit 6edadfb

Browse files
committed
fix loading handle
1 parent 81dbd36 commit 6edadfb

File tree

2 files changed

+46
-15
lines changed

2 files changed

+46
-15
lines changed

apps/events/src/components/users.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ import { UserEntry } from './user-entry.js';
88
export const Users = () => {
99
const { data: users } = useQuery(User, { mode: 'private' });
1010
const { ready: spaceReady } = useSpace({ mode: 'private' });
11-
const createEntity = useCreateEntity(User, { space: '1c954768-7e14-4f0f-9396-0fe9dcd55fe8' });
11+
const createEntity = useCreateEntity(User);
1212
const [newUserName, setNewUserName] = useState('');
1313

1414
if (!spaceReady) {

packages/hypergraph-react/src/HypergraphSpaceContext.tsx

Lines changed: 45 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,6 @@
11
'use client';
22

3-
import type { AnyDocumentId } from '@automerge/automerge-repo';
4-
import { useRepo } from '@automerge/automerge-repo-react-hooks';
5-
import { Entity, Utils, store } from '@graphprotocol/hypergraph';
3+
import { Entity, store } from '@graphprotocol/hypergraph';
64
import { useSelector } from '@xstate/store/react';
75
import * as Schema from 'effect/Schema';
86
import {
@@ -35,12 +33,13 @@ export function HypergraphSpaceProvider({ space, children }: { space: string; ch
3533
}
3634

3735
function useSubscribeToSpaceAndGetHandle({ spaceId, enabled }: { spaceId: string; enabled: boolean }) {
38-
const repo = useRepo();
39-
const handle = useMemo(() => {
40-
const id = Utils.idToAutomergeId(spaceId) as AnyDocumentId;
41-
const result = repo.findWithProgress<Entity.DocumentContent>(id);
42-
return result.handle;
43-
}, [spaceId, repo]);
36+
const handle = useSelector(store, (state) => {
37+
const space = state.context.spaces.find((space) => space.id === spaceId);
38+
if (!space) {
39+
return undefined;
40+
}
41+
return space.automergeDocHandle;
42+
});
4443

4544
const { subscribeToSpace, isConnecting } = useHypergraphApp();
4645
useEffect(() => {
@@ -61,43 +60,69 @@ export function useSpace(options: { space?: string; mode: 'private' | 'public' }
6160
const { space: spaceIdFromParams } = options ?? {};
6261
const spaceId = spaceIdFromParams ?? spaceIdFromContext;
6362
const handle = useSubscribeToSpaceAndGetHandle({ spaceId, enabled: options.mode === 'private' });
64-
const ready = options.mode === 'public' ? true : handle.isReady();
63+
const ready = options.mode === 'public' ? true : handle ? handle.isReady() : false;
6564
const space = useSelector(store, (state) => state.context.spaces.find((space) => space.id === spaceId));
6665
return { ready, name: space?.name, id: spaceId };
6766
}
6867

6968
export function useCreateEntity<const S extends Entity.AnyNoContext>(type: S, options?: { space?: string }) {
70-
const { space } = options ?? {};
69+
const { space: spaceIdFromParams } = options ?? {};
7170
const { space: spaceFromContext } = useHypergraphSpaceInternal();
72-
const handle = useSubscribeToSpaceAndGetHandle({ spaceId: space ?? spaceFromContext, enabled: true });
71+
const spaceId = spaceIdFromParams ?? spaceFromContext;
72+
const handle = useSubscribeToSpaceAndGetHandle({ spaceId, enabled: true });
73+
if (!handle) {
74+
return () => {
75+
throw new Error('Space not found or not ready');
76+
};
77+
}
7378
return Entity.create(handle, type);
7479
}
7580

7681
export function useUpdateEntity<const S extends Entity.AnyNoContext>(type: S, options?: { space?: string }) {
7782
const { space: spaceFromContext } = useHypergraphSpaceInternal();
7883
const { space } = options ?? {};
7984
const handle = useSubscribeToSpaceAndGetHandle({ spaceId: space ?? spaceFromContext, enabled: true });
85+
if (!handle) {
86+
return () => {
87+
throw new Error('Space not found or not ready');
88+
};
89+
}
8090
return Entity.update(handle, type);
8191
}
8292

8393
export function useDeleteEntity(options?: { space?: string }) {
8494
const { space: spaceFromContext } = useHypergraphSpaceInternal();
8595
const { space } = options ?? {};
8696
const handle = useSubscribeToSpaceAndGetHandle({ spaceId: space ?? spaceFromContext, enabled: true });
97+
if (!handle) {
98+
return () => {
99+
throw new Error('Space not found or not ready');
100+
};
101+
}
87102
return Entity.markAsDeleted(handle);
88103
}
89104

90105
export function useRemoveRelation(options?: { space?: string }) {
91106
const { space: spaceFromContext } = useHypergraphSpaceInternal();
92107
const { space } = options ?? {};
93108
const handle = useSubscribeToSpaceAndGetHandle({ spaceId: space ?? spaceFromContext, enabled: true });
109+
if (!handle) {
110+
return () => {
111+
throw new Error('Space not found or not ready');
112+
};
113+
}
94114
return Entity.removeRelation(handle);
95115
}
96116

97117
export function useHardDeleteEntity(options?: { space?: string }) {
98118
const { space: spaceFromContext } = useHypergraphSpaceInternal();
99119
const { space } = options ?? {};
100120
const handle = useSubscribeToSpaceAndGetHandle({ spaceId: space ?? spaceFromContext, enabled: true });
121+
if (!handle) {
122+
return () => {
123+
throw new Error('Space not found or not ready');
124+
};
125+
}
101126
return Entity.delete(handle);
102127
}
103128

@@ -117,11 +142,11 @@ export function useQueryLocal<const S extends Entity.AnyNoContext>(type: S, para
117142
});
118143
const { space: spaceFromContext } = useHypergraphSpaceInternal();
119144
const handle = useSubscribeToSpaceAndGetHandle({ spaceId: spaceFromParams ?? spaceFromContext, enabled: true });
120-
const handleIsReady = handle.isReady();
145+
const handleIsReady = handle ? handle.isReady() : false;
121146

122147
// biome-ignore lint/correctness/useExhaustiveDependencies: allow to change filter and include
123148
useLayoutEffect(() => {
124-
if (enabled && handleIsReady) {
149+
if (enabled && handle && handleIsReady) {
125150
const subscription = Entity.subscribeToFindMany(handle, type, filter, include);
126151
subscriptionRef.current.subscribe = subscription.subscribe;
127152
subscriptionRef.current.getEntities = subscription.getEntities;
@@ -163,6 +188,9 @@ export function useQueryEntity<const S extends Entity.AnyNoContext>(
163188
const equals = Schema.equivalence(type);
164189

165190
const subscribe = (callback: () => void) => {
191+
if (!handle) {
192+
return () => {};
193+
}
166194
const handleChange = () => {
167195
callback();
168196
};
@@ -181,6 +209,9 @@ export function useQueryEntity<const S extends Entity.AnyNoContext>(
181209
};
182210

183211
return useSyncExternalStore(subscribe, () => {
212+
if (!handle) {
213+
return prevEntityRef.current;
214+
}
184215
const doc = handle.doc();
185216
if (doc === undefined) {
186217
return prevEntityRef.current;

0 commit comments

Comments
 (0)