Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion apps/events/src/Boot.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { HypergraphAppProvider } from '@graphprotocol/hypergraph-react';
import { RouterProvider, createRouter } from '@tanstack/react-router';
import { mapping } from './mapping.js';
import { routeTree } from './routeTree.gen';

// Create a new router instance
Expand All @@ -14,7 +15,7 @@ declare module '@tanstack/react-router' {

export function Boot() {
return (
<HypergraphAppProvider storage={localStorage} syncServerUri="http://localhost:3030">
<HypergraphAppProvider storage={localStorage} syncServerUri="http://localhost:3030" mapping={mapping}>
<RouterProvider router={router} />
</HypergraphAppProvider>
);
Expand Down
2 changes: 1 addition & 1 deletion apps/events/src/mapping.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { Id } from '@graphprotocol/grc-20';
import type { Mapping } from '@graphprotocol/hypergraph-react';
import type { Mapping } from '@graphprotocol/hypergraph';

export const mapping: Mapping = {
RelationEntry: {
Expand Down
3 changes: 1 addition & 2 deletions apps/events/src/routes/playground.lazy.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import { Playground } from '@/components/playground';
import { mapping } from '@/mapping.js';
import { HypergraphSpaceProvider } from '@graphprotocol/hypergraph-react';
import { createLazyFileRoute } from '@tanstack/react-router';

Expand All @@ -9,7 +8,7 @@ export const Route = createLazyFileRoute('/playground')({

function RouteComponent() {
return (
<HypergraphSpaceProvider space="93952dae-46e3-4682-b290-80028ca95403" mapping={mapping}>
<HypergraphSpaceProvider space="93952dae-46e3-4682-b290-80028ca95403">
<div className="flex flex-col gap-4 max-w-(--breakpoint-sm) mx-auto py-8">
<h1 className="text-2xl font-bold">Playground</h1>
<Playground />
Expand Down
3 changes: 1 addition & 2 deletions apps/events/src/routes/space/$spaceId/chat.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import { SpaceChat } from '@/components/SpaceChat';
import { mapping } from '@/mapping.js';
import { store } from '@graphprotocol/hypergraph';
import { HypergraphSpaceProvider, useHypergraphApp } from '@graphprotocol/hypergraph-react';
import { createFileRoute } from '@tanstack/react-router';
Expand Down Expand Up @@ -32,7 +31,7 @@ function RouteComponent() {

return (
<div className="flex flex-col gap-4 max-w-(--breakpoint-sm) mx-auto py-8">
<HypergraphSpaceProvider space={spaceId} mapping={mapping}>
<HypergraphSpaceProvider space={spaceId}>
<SpaceChat spaceId={spaceId} />
</HypergraphSpaceProvider>
</div>
Expand Down
3 changes: 1 addition & 2 deletions apps/events/src/routes/space/$spaceId/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import { TodosReadOnly } from '@/components/todos-read-only';
import { TodosReadOnlyFilter } from '@/components/todos-read-only-filter';
import { Button } from '@/components/ui/button';
import { Users } from '@/components/users';
import { mapping } from '@/mapping.js';
import { store } from '@graphprotocol/hypergraph';
import { HypergraphSpaceProvider, useHypergraphApp } from '@graphprotocol/hypergraph-react';
import { createFileRoute } from '@tanstack/react-router';
Expand Down Expand Up @@ -38,7 +37,7 @@ function Space() {

return (
<div className="flex flex-col gap-4 max-w-(--breakpoint-sm) mx-auto py-8">
<HypergraphSpaceProvider space={spaceId} mapping={mapping}>
<HypergraphSpaceProvider space={spaceId}>
<Users />
<Todos />
<TodosReadOnlyFilter />
Expand Down
3 changes: 1 addition & 2 deletions apps/events/src/routes/space/$spaceId/playground.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import { TodosPublic } from '@/components/todo/todos-public';
import { mapping } from '@/mapping.js';
import { store } from '@graphprotocol/hypergraph';
import { HypergraphSpaceProvider, useHypergraphApp } from '@graphprotocol/hypergraph-react';
import { createFileRoute } from '@tanstack/react-router';
Expand Down Expand Up @@ -32,7 +31,7 @@ function PlaygroundRouteComponent() {

return (
<div className="flex flex-col gap-4 max-w-(--breakpoint-sm) mx-auto py-8">
<HypergraphSpaceProvider space={spaceId} mapping={mapping}>
<HypergraphSpaceProvider space={spaceId}>
<TodosPublic />
</HypergraphSpaceProvider>
</div>
Expand Down
3 changes: 1 addition & 2 deletions apps/events/src/routes/space/$spaceId/public-integration.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import { CreatePropertiesAndTypes } from '@/components/create-properties-and-types';
import { Todos2 } from '@/components/todos2';
import { mapping } from '@/mapping.js';
import { store } from '@graphprotocol/hypergraph';
import { HypergraphSpaceProvider, useHypergraphApp } from '@graphprotocol/hypergraph-react';
import { createFileRoute } from '@tanstack/react-router';
Expand Down Expand Up @@ -33,7 +32,7 @@ function PublicIntegration() {

return (
<div className="flex flex-col gap-4 max-w-(--breakpoint-sm) mx-auto py-8">
<HypergraphSpaceProvider space={spaceId} mapping={mapping}>
<HypergraphSpaceProvider space={spaceId}>
<CreatePropertiesAndTypes />
<Todos2 />
</HypergraphSpaceProvider>
Expand Down
3 changes: 1 addition & 2 deletions apps/events/src/routes/space/$spaceId/users.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import { UsersMerged } from '@/components/users/users-merged';
import { UsersPublic } from '@/components/users/users-public';
import { mapping } from '@/mapping.js';
import { store } from '@graphprotocol/hypergraph';
import { HypergraphSpaceProvider, useHypergraphApp } from '@graphprotocol/hypergraph-react';
import { createFileRoute } from '@tanstack/react-router';
Expand Down Expand Up @@ -33,7 +32,7 @@ function UsersRouteComponent() {

return (
<div className="flex flex-col gap-4 max-w-(--breakpoint-sm) mx-auto py-8">
<HypergraphSpaceProvider space={spaceId} mapping={mapping}>
<HypergraphSpaceProvider space={spaceId}>
<UsersMerged />
<UsersLocal />
<UsersPublic />
Expand Down
2 changes: 1 addition & 1 deletion apps/next-example/src/components/providers.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ export default function Providers({ children }: { children: React.ReactNode }) {
const storage = typeof window !== 'undefined' ? window.localStorage : (undefined as unknown as Storage);

return (
<HypergraphAppProvider storage={storage} syncServerUri="http://localhost:3030">
<HypergraphAppProvider storage={storage} syncServerUri="http://localhost:3030" mapping={{}}>
{children}
</HypergraphAppProvider>
);
Expand Down
11 changes: 9 additions & 2 deletions packages/hypergraph-react/src/HypergraphAppContext.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import {
type InboxMessageStorageEntry,
Inboxes,
Key,
type Mapping,
Messages,
SpaceEvents,
type SpaceStorageEntry,
Expand Down Expand Up @@ -184,6 +185,7 @@ export type HypergraphAppProviderProps = Readonly<{
syncServerUri?: string;
chainId?: number;
children: ReactNode;
mapping: Mapping;
}>;
// 1) a) Get session token from local storage, or
// b) Auth with the sync server
Expand All @@ -193,8 +195,8 @@ export type HypergraphAppProviderProps = Readonly<{
export function HypergraphAppProvider({
storage,
syncServerUri = 'https://syncserver.hypergraph.thegraph.com',
chainId = 80451,
children,
mapping,
}: HypergraphAppProviderProps) {
const [websocketConnection, setWebsocketConnection] = useState<WebSocket>();
const [isConnecting, setIsConnecting] = useState(true);
Expand Down Expand Up @@ -227,6 +229,11 @@ export function HypergraphAppProvider({
const initialRenderAuthCheckRef = useRef(false);
// using a layout effect to avoid a re-render
useLayoutEffect(() => {
store.send({
type: 'setMapping',
mapping,
});

if (!initialRenderAuthCheckRef.current) {
const identity = Identity.loadIdentity(storage);
if (identity) {
Expand All @@ -238,7 +245,7 @@ export function HypergraphAppProvider({
// set render auth check to true so next potential rerender doesn't proc this
initialRenderAuthCheckRef.current = true;
}
}, [storage]);
}, [storage, mapping]);

useEffect(() => {
if (!identity) {
Expand Down
27 changes: 10 additions & 17 deletions packages/hypergraph-react/src/HypergraphSpaceContext.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,19 +6,17 @@ import { Entity, Utils } from '@graphprotocol/hypergraph';
import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
import * as Schema from 'effect/Schema';
import { type ReactNode, createContext, useContext, useMemo, useRef, useState, useSyncExternalStore } from 'react';
import type { Mapping } from './types.js';

export type HypergraphContext = {
space: string;
repo: Repo;
id: AnyDocumentId;
handle: DocHandle<Entity.DocumentContent>;
mapping?: Mapping | undefined;
};

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

export function useHypergraph() {
function useHypergraphSpaceInternal() {
const context = useContext(HypergraphReactContext);
if (!context) {
throw new Error('useHypergraphSpace must be used within a HypergraphSpaceProvider');
Expand All @@ -29,11 +27,7 @@ export function useHypergraph() {

const queryClient = new QueryClient();

export function HypergraphSpaceProvider({
space,
children,
mapping,
}: { space: string; children: ReactNode; mapping?: Mapping }) {
export function HypergraphSpaceProvider({ space, children }: { space: string; children: ReactNode }) {
const repo = useRepo();
const ref = useRef<HypergraphContext | undefined>(undefined);

Expand All @@ -47,7 +41,6 @@ export function HypergraphSpaceProvider({
repo,
id,
handle: result.handle,
mapping,
};
}

Expand All @@ -59,27 +52,27 @@ export function HypergraphSpaceProvider({
}

export function useCreateEntity<const S extends Entity.AnyNoContext>(type: S) {
const hypergraph = useHypergraph();
const hypergraph = useHypergraphSpaceInternal();
return Entity.create(hypergraph.handle, type);
}

export function useUpdateEntity<const S extends Entity.AnyNoContext>(type: S) {
const hypergraph = useHypergraph();
const hypergraph = useHypergraphSpaceInternal();
return Entity.update(hypergraph.handle, type);
}

export function useDeleteEntity() {
const hypergraph = useHypergraph();
const hypergraph = useHypergraphSpaceInternal();
return Entity.markAsDeleted(hypergraph.handle);
}

export function useRemoveRelation() {
const hypergraph = useHypergraph();
const hypergraph = useHypergraphSpaceInternal();
return Entity.removeRelation(hypergraph.handle);
}

export function useHardDeleteEntity() {
const hypergraph = useHypergraph();
const hypergraph = useHypergraphSpaceInternal();
return Entity.delete(hypergraph.handle);
}

Expand All @@ -93,7 +86,7 @@ export function useQueryLocal<const S extends Entity.AnyNoContext>(type: S, para
const { enabled = true, filter, include } = params ?? {};
const entitiesRef = useRef<Entity.Entity<S>[]>([]);

const hypergraph = useHypergraph();
const hypergraph = useHypergraphSpaceInternal();
const [subscription] = useState(() => {
if (!enabled) {
return {
Expand Down Expand Up @@ -130,7 +123,7 @@ export function useQueryEntity<const S extends Entity.AnyNoContext>(
id: string,
include?: { [K in keyof Schema.Schema.Type<S>]?: Record<string, never> },
) {
const hypergraph = useHypergraph();
const hypergraph = useHypergraphSpaceInternal();
const prevEntityRef = useRef<Entity.Entity<S> | undefined>(undefined);
const equals = Schema.equivalence(type);

Expand Down Expand Up @@ -174,6 +167,6 @@ export function useQueryEntity<const S extends Entity.AnyNoContext>(
}

export const useHypergraphSpace = () => {
const { space } = useHypergraph();
const { space } = useHypergraphSpaceInternal();
return space;
};
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
import type { Entity } from '@graphprotocol/hypergraph';
import { useHypergraph } from '../HypergraphSpaceContext.js';
import { store } from '@graphprotocol/hypergraph';
import { useSelector } from '@xstate/store/react';

export function useGenerateCreateOps<const S extends Entity.AnyNoContext>(type: S, enabled = true) {
const { mapping } = useHypergraph();
const mapping = useSelector(store, (state) => state.context.mapping);

return (properties: Entity.Entity<S>) => {
// @ts-expect-error TODO should use the actual type instead of the name in the mapping
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import type { Op } from '@graphprotocol/grc-20';
import type { Entity } from '@graphprotocol/hypergraph';
import { useHypergraph } from '../HypergraphSpaceContext.js';
import { type Entity, store } from '@graphprotocol/hypergraph';
import { useSelector } from '@xstate/store/react';
import type { DiffEntry } from '../types.js';

export function useGenerateUpdateOps<const S extends Entity.AnyNoContext>(type: S, enabled = true) {
const { mapping } = useHypergraph();
const mapping = useSelector(store, (state) => state.context.mapping);

return ({ id, diff }: { id: string; diff: DiffEntry }) => {
// @ts-expect-error TODO should use the actual type instead of the name in the mapping
Expand Down
10 changes: 6 additions & 4 deletions packages/hypergraph-react/src/internal/use-query-public.tsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
import { type Entity, Type } from '@graphprotocol/hypergraph';
import { type Entity, type Mapping, type MappingEntry, Type, store } from '@graphprotocol/hypergraph';
import { useQuery as useQueryTanstack } from '@tanstack/react-query';
import { useSelector } from '@xstate/store/react';
import * as Either from 'effect/Either';
import * as Schema from 'effect/Schema';
import { gql, request } from 'graphql-request';
import { useMemo } from 'react';
import { useHypergraph } from '../HypergraphSpaceContext.js';
import type { Mapping, MappingEntry } from '../types.js';
import { useHypergraphSpace } from '../HypergraphSpaceContext.js';
import { GEO_API_TESTNET_ENDPOINT } from './constants.js';
import type { QueryPublicParams } from './types.js';

Expand Down Expand Up @@ -161,7 +161,9 @@ export const parseResult = <S extends Entity.AnyNoContext>(

export const useQueryPublic = <S extends Entity.AnyNoContext>(type: S, params?: QueryPublicParams<S>) => {
const { enabled = true, include } = params ?? {};
const { space, mapping } = useHypergraph();
const space = useHypergraphSpace();
const mapping = useSelector(store, (state) => state.context.mapping);
console.log('mapping', mapping);

// @ts-expect-error TODO should use the actual type instead of the name in the mapping
const typeName = type.name;
Expand Down
16 changes: 1 addition & 15 deletions packages/hypergraph-react/src/types.ts
Original file line number Diff line number Diff line change
@@ -1,21 +1,7 @@
import type { Id as Grc20Id, Op } from '@graphprotocol/grc-20';
import type { Op } from '@graphprotocol/grc-20';
import type { Entity } from '@graphprotocol/hypergraph';
import type * as Schema from 'effect/Schema';

export type MappingEntry = {
typeIds: Grc20Id.Id[];
properties?: {
[key: string]: Grc20Id.Id;
};
relations?: {
[key: string]: Grc20Id.Id;
};
};

export type Mapping = {
[key: string]: MappingEntry;
};

export type EntityLike = {
id: string;
[key: string]: unknown;
Expand Down
7 changes: 4 additions & 3 deletions packages/hypergraph-react/src/use-query.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import { type Entity, Type, Utils } from '@graphprotocol/hypergraph';
import { type Entity, Type, Utils, store } from '@graphprotocol/hypergraph';
import { useSelector } from '@xstate/store/react';
import type * as Schema from 'effect/Schema';
import { useMemo } from 'react';
import { useHypergraph, useQueryLocal } from './HypergraphSpaceContext.js';
import { useQueryLocal } from './HypergraphSpaceContext.js';
import { generateDeleteOps } from './internal/generate-delete-ops.js';
import { useGenerateCreateOps } from './internal/use-generate-create-ops.js';
import { useGenerateUpdateOps } from './internal/use-generate-update-ops.js';
Expand Down Expand Up @@ -147,7 +148,7 @@ export function useQuery<const S extends Entity.AnyNoContext>(type: S, params?:
const { mode = 'merged', filter, include } = params ?? {};
const publicResult = useQueryPublic(type, { enabled: mode === 'public' || mode === 'merged', include });
const localResult = useQueryLocal(type, { enabled: mode === 'local' || mode === 'merged', filter, include });
const { mapping } = useHypergraph();
const mapping = useSelector(store, (state) => state.context.mapping);
const generateCreateOps = useGenerateCreateOps(type, mode === 'merged');
const generateUpdateOps = useGenerateUpdateOps(type, mode === 'merged');

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ const storageMock = {
describe('HypergraphAppContext', () => {
it('should render the HypergraphAppProvider and be initially unauthenticated', async () => {
const wrapper = ({ children }: Readonly<{ children: React.ReactNode }>) => (
<HypergraphAppProvider storage={storageMock} syncServerUri="http://localhost:3030">
<HypergraphAppProvider storage={storageMock} syncServerUri="http://localhost:3030" mapping={{}}>
{children}
</HypergraphAppProvider>
);
Expand Down
1 change: 1 addition & 0 deletions packages/hypergraph/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
"@automerge/automerge": "^2.2.9",
"@automerge/automerge-repo": "=2.0.0-beta.5",
"@effect/experimental": "^0.44.20",
"@graphprotocol/grc-20": "^0.20.0",
"@noble/ciphers": "^1.3.0",
"@noble/curves": "^1.9.0",
"@noble/hashes": "^1.8.0",
Expand Down
Loading
Loading