mirror of
https://github.com/supermemoryai/supermemory.git
synced 2026-10-03 02:21:23 +00:00
Merge 8d3f7ac8d6 into cfa6c7cb17
This commit is contained in:
commit
4585d27081
2 changed files with 359 additions and 90 deletions
|
|
@ -25,11 +25,11 @@ npm install @supermemory/memory-graph
|
|||
'use client'; // For Next.js App Router
|
||||
|
||||
import { MemoryGraph } from '@supermemory/memory-graph';
|
||||
import type { DocumentWithMemories } from '@supermemory/memory-graph';
|
||||
import type { GraphApiDocument } from '@supermemory/memory-graph';
|
||||
import { useEffect, useState } from 'react';
|
||||
|
||||
export default function GraphPage() {
|
||||
const [documents, setDocuments] = useState<DocumentWithMemories[]>([]);
|
||||
const [documents, setDocuments] = useState<GraphApiDocument[]>([]);
|
||||
const [isLoading, setIsLoading] = useState(true);
|
||||
const [error, setError] = useState<Error | null>(null);
|
||||
|
||||
|
|
@ -59,15 +59,97 @@ export default function GraphPage() {
|
|||
}
|
||||
```
|
||||
|
||||
<Note>
|
||||
`documents` must be `GraphApiDocument[]`, the shape the API route below returns, with `documentType` and `memories` fields (not the raw API's `type` and `memoryEntries`).
|
||||
</Note>
|
||||
|
||||
## Backend API Route
|
||||
|
||||
Create an API route to fetch documents from Supermemory:
|
||||
Create an API route to fetch documents from Supermemory. The `/v3/documents/documents` response uses `type` and `memoryEntries`; `<MemoryGraph>` expects `documentType` and `memories`, so the route normalizes the shape before returning it:
|
||||
|
||||
<CodeGroup>
|
||||
|
||||
```typescript Next.js App Router
|
||||
// app/api/graph/route.ts
|
||||
import { NextResponse } from 'next/server';
|
||||
import type { GraphApiDocument, GraphApiMemory } from '@supermemory/memory-graph';
|
||||
|
||||
interface RawMemoryEntry {
|
||||
id: string;
|
||||
memory?: string | null;
|
||||
content?: string | null;
|
||||
spaceId?: string | null;
|
||||
isStatic?: boolean;
|
||||
isLatest?: boolean;
|
||||
isForgotten?: boolean;
|
||||
forgetAfter?: string | null;
|
||||
forgetReason?: string | null;
|
||||
version?: number;
|
||||
parentMemoryId?: string | null;
|
||||
rootMemoryId?: string | null;
|
||||
createdAt: string;
|
||||
updatedAt: string;
|
||||
relation?: 'updates' | 'extends' | 'derives' | null;
|
||||
updatesMemoryId?: string | null;
|
||||
nextVersionId?: string | null;
|
||||
memoryRelations?: Record<string, 'updates' | 'extends' | 'derives'> | null;
|
||||
spaceContainerTag?: string | null;
|
||||
}
|
||||
|
||||
interface RawDocument {
|
||||
id: string;
|
||||
title: string | null;
|
||||
summary?: string | null;
|
||||
type: string;
|
||||
createdAt: string;
|
||||
updatedAt: string;
|
||||
memoryEntries: RawMemoryEntry[];
|
||||
}
|
||||
|
||||
interface RawDocumentsResponse {
|
||||
documents: RawDocument[];
|
||||
pagination: {
|
||||
currentPage: number;
|
||||
limit: number;
|
||||
totalItems: number;
|
||||
totalPages: number;
|
||||
};
|
||||
}
|
||||
|
||||
// Maps the raw API document (`type` / `memoryEntries`) onto the shape
|
||||
// <MemoryGraph> expects (`documentType` / `memories`), filling in the
|
||||
// defaults for fields the API may omit.
|
||||
function toGraphDocument(doc: RawDocument): GraphApiDocument {
|
||||
return {
|
||||
id: doc.id,
|
||||
title: doc.title,
|
||||
summary: doc.summary ?? null,
|
||||
documentType: doc.type,
|
||||
createdAt: doc.createdAt,
|
||||
updatedAt: doc.updatedAt,
|
||||
memories: doc.memoryEntries.map((mem): GraphApiMemory => ({
|
||||
id: mem.id,
|
||||
memory: mem.memory ?? mem.content ?? '',
|
||||
content: mem.content ?? null,
|
||||
isStatic: mem.isStatic ?? false,
|
||||
spaceId: mem.spaceId ?? '',
|
||||
isLatest: mem.isLatest ?? true,
|
||||
isForgotten: mem.isForgotten ?? false,
|
||||
forgetAfter: mem.forgetAfter ?? null,
|
||||
forgetReason: mem.forgetReason ?? null,
|
||||
version: mem.version ?? 1,
|
||||
parentMemoryId: mem.parentMemoryId ?? null,
|
||||
rootMemoryId: mem.rootMemoryId ?? null,
|
||||
createdAt: mem.createdAt,
|
||||
updatedAt: mem.updatedAt,
|
||||
relation: mem.relation ?? null,
|
||||
updatesMemoryId: mem.updatesMemoryId ?? null,
|
||||
nextVersionId: mem.nextVersionId ?? null,
|
||||
memoryRelations: mem.memoryRelations ?? null,
|
||||
spaceContainerTag: mem.spaceContainerTag ?? null,
|
||||
})),
|
||||
};
|
||||
}
|
||||
|
||||
export async function GET() {
|
||||
const response = await fetch('https://api.supermemory.ai/v3/documents/documents', {
|
||||
|
|
@ -84,14 +166,95 @@ export async function GET() {
|
|||
}),
|
||||
});
|
||||
|
||||
const data = await response.json();
|
||||
return NextResponse.json(data);
|
||||
const data: RawDocumentsResponse = await response.json();
|
||||
return NextResponse.json({
|
||||
documents: data.documents.map(toGraphDocument),
|
||||
pagination: data.pagination,
|
||||
});
|
||||
}
|
||||
```
|
||||
|
||||
```typescript Next.js Pages Router
|
||||
// pages/api/graph.ts
|
||||
import type { NextApiRequest, NextApiResponse } from 'next';
|
||||
import type { GraphApiDocument, GraphApiMemory } from '@supermemory/memory-graph';
|
||||
|
||||
interface RawMemoryEntry {
|
||||
id: string;
|
||||
memory?: string | null;
|
||||
content?: string | null;
|
||||
spaceId?: string | null;
|
||||
isStatic?: boolean;
|
||||
isLatest?: boolean;
|
||||
isForgotten?: boolean;
|
||||
forgetAfter?: string | null;
|
||||
forgetReason?: string | null;
|
||||
version?: number;
|
||||
parentMemoryId?: string | null;
|
||||
rootMemoryId?: string | null;
|
||||
createdAt: string;
|
||||
updatedAt: string;
|
||||
relation?: 'updates' | 'extends' | 'derives' | null;
|
||||
updatesMemoryId?: string | null;
|
||||
nextVersionId?: string | null;
|
||||
memoryRelations?: Record<string, 'updates' | 'extends' | 'derives'> | null;
|
||||
spaceContainerTag?: string | null;
|
||||
}
|
||||
|
||||
interface RawDocument {
|
||||
id: string;
|
||||
title: string | null;
|
||||
summary?: string | null;
|
||||
type: string;
|
||||
createdAt: string;
|
||||
updatedAt: string;
|
||||
memoryEntries: RawMemoryEntry[];
|
||||
}
|
||||
|
||||
interface RawDocumentsResponse {
|
||||
documents: RawDocument[];
|
||||
pagination: {
|
||||
currentPage: number;
|
||||
limit: number;
|
||||
totalItems: number;
|
||||
totalPages: number;
|
||||
};
|
||||
}
|
||||
|
||||
// Maps the raw API document (`type` / `memoryEntries`) onto the shape
|
||||
// <MemoryGraph> expects (`documentType` / `memories`), filling in the
|
||||
// defaults for fields the API may omit.
|
||||
function toGraphDocument(doc: RawDocument): GraphApiDocument {
|
||||
return {
|
||||
id: doc.id,
|
||||
title: doc.title,
|
||||
summary: doc.summary ?? null,
|
||||
documentType: doc.type,
|
||||
createdAt: doc.createdAt,
|
||||
updatedAt: doc.updatedAt,
|
||||
memories: doc.memoryEntries.map((mem): GraphApiMemory => ({
|
||||
id: mem.id,
|
||||
memory: mem.memory ?? mem.content ?? '',
|
||||
content: mem.content ?? null,
|
||||
isStatic: mem.isStatic ?? false,
|
||||
spaceId: mem.spaceId ?? '',
|
||||
isLatest: mem.isLatest ?? true,
|
||||
isForgotten: mem.isForgotten ?? false,
|
||||
forgetAfter: mem.forgetAfter ?? null,
|
||||
forgetReason: mem.forgetReason ?? null,
|
||||
version: mem.version ?? 1,
|
||||
parentMemoryId: mem.parentMemoryId ?? null,
|
||||
rootMemoryId: mem.rootMemoryId ?? null,
|
||||
createdAt: mem.createdAt,
|
||||
updatedAt: mem.updatedAt,
|
||||
relation: mem.relation ?? null,
|
||||
updatesMemoryId: mem.updatesMemoryId ?? null,
|
||||
nextVersionId: mem.nextVersionId ?? null,
|
||||
memoryRelations: mem.memoryRelations ?? null,
|
||||
spaceContainerTag: mem.spaceContainerTag ?? null,
|
||||
})),
|
||||
};
|
||||
}
|
||||
|
||||
export default async function handler(req: NextApiRequest, res: NextApiResponse) {
|
||||
const response = await fetch('https://api.supermemory.ai/v3/documents/documents', {
|
||||
|
|
@ -103,8 +266,11 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse)
|
|||
body: JSON.stringify({ page: 1, limit: 500, sort: 'createdAt', order: 'desc' }),
|
||||
});
|
||||
|
||||
const data = await response.json();
|
||||
res.json(data);
|
||||
const data: RawDocumentsResponse = await response.json();
|
||||
res.json({
|
||||
documents: data.documents.map(toGraphDocument),
|
||||
pagination: data.pagination,
|
||||
});
|
||||
}
|
||||
```
|
||||
|
||||
|
|
@ -120,7 +286,41 @@ app.get('/api/graph', async (req, res) => {
|
|||
});
|
||||
|
||||
const data = await response.json();
|
||||
res.json(data);
|
||||
|
||||
// Map the raw API document (`type` / `memoryEntries`) onto the shape
|
||||
// <MemoryGraph> expects (`documentType` / `memories`), filling in the
|
||||
// defaults for fields the API may omit.
|
||||
const documents = data.documents.map((doc) => ({
|
||||
id: doc.id,
|
||||
title: doc.title,
|
||||
summary: doc.summary ?? null,
|
||||
documentType: doc.type,
|
||||
createdAt: doc.createdAt,
|
||||
updatedAt: doc.updatedAt,
|
||||
memories: doc.memoryEntries.map((mem) => ({
|
||||
id: mem.id,
|
||||
memory: mem.memory ?? mem.content ?? '',
|
||||
content: mem.content ?? null,
|
||||
isStatic: mem.isStatic ?? false,
|
||||
spaceId: mem.spaceId ?? '',
|
||||
isLatest: mem.isLatest ?? true,
|
||||
isForgotten: mem.isForgotten ?? false,
|
||||
forgetAfter: mem.forgetAfter ?? null,
|
||||
forgetReason: mem.forgetReason ?? null,
|
||||
version: mem.version ?? 1,
|
||||
parentMemoryId: mem.parentMemoryId ?? null,
|
||||
rootMemoryId: mem.rootMemoryId ?? null,
|
||||
createdAt: mem.createdAt,
|
||||
updatedAt: mem.updatedAt,
|
||||
relation: mem.relation ?? null,
|
||||
updatesMemoryId: mem.updatesMemoryId ?? null,
|
||||
nextVersionId: mem.nextVersionId ?? null,
|
||||
memoryRelations: mem.memoryRelations ?? null,
|
||||
spaceContainerTag: mem.spaceContainerTag ?? null,
|
||||
})),
|
||||
}));
|
||||
|
||||
res.json({ documents, pagination: data.pagination });
|
||||
});
|
||||
```
|
||||
|
||||
|
|
@ -134,13 +334,13 @@ app.get('/api/graph', async (req, res) => {
|
|||
|
||||
## Variants
|
||||
|
||||
**Console Variant** - Full-featured dashboard view (0.8x zoom, space selector visible):
|
||||
**Console Variant** - Full-featured dashboard view (0.8x initial zoom):
|
||||
|
||||
```tsx
|
||||
<MemoryGraph documents={documents} variant="console" />
|
||||
```
|
||||
|
||||
**Consumer Variant** - Embedded widget view (0.5x zoom, space selector hidden):
|
||||
**Consumer Variant** - Embedded widget view (0.5x initial zoom):
|
||||
|
||||
```tsx
|
||||
<MemoryGraph documents={documents} variant="consumer" />
|
||||
|
|
@ -156,10 +356,11 @@ app.get('/api/graph', async (req, res) => {
|
|||
'use client';
|
||||
|
||||
import { MemoryGraph } from '@supermemory/memory-graph';
|
||||
import type { GraphApiDocument } from '@supermemory/memory-graph';
|
||||
import { useCallback, useEffect, useState } from 'react';
|
||||
|
||||
export default function PaginatedGraph() {
|
||||
const [documents, setDocuments] = useState([]);
|
||||
const [documents, setDocuments] = useState<GraphApiDocument[]>([]);
|
||||
const [page, setPage] = useState(1);
|
||||
const [hasMore, setHasMore] = useState(true);
|
||||
const [isLoading, setIsLoading] = useState(true);
|
||||
|
|
@ -193,8 +394,8 @@ export default function PaginatedGraph() {
|
|||
isLoading={isLoading}
|
||||
isLoadingMore={isLoadingMore}
|
||||
hasMore={hasMore}
|
||||
totalLoaded={documents.length}
|
||||
loadMoreDocuments={loadMore}
|
||||
totalCount={documents.length}
|
||||
onLoadMore={loadMore}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
|
@ -210,17 +411,6 @@ export default function PaginatedGraph() {
|
|||
/>
|
||||
```
|
||||
|
||||
### Controlled Space Selection
|
||||
|
||||
```tsx
|
||||
<MemoryGraph
|
||||
documents={documents}
|
||||
selectedSpace={selectedSpace}
|
||||
onSpaceChange={setSelectedSpace}
|
||||
showSpacesSelector={false}
|
||||
/>
|
||||
```
|
||||
|
||||
### Custom Empty State
|
||||
|
||||
```tsx
|
||||
|
|
@ -240,80 +430,131 @@ export default function PaginatedGraph() {
|
|||
|
||||
| Prop | Type | Default | Description |
|
||||
|------|------|---------|-------------|
|
||||
| `documents` | `DocumentWithMemories[]` | required | Array of documents to display |
|
||||
| `isLoading` | `boolean` | `false` | Shows loading indicator |
|
||||
| `error` | `Error \| null` | `null` | Error to display |
|
||||
| `documents` | `GraphApiDocument[]` | `[]` | Documents to display - pass this for direct data mode |
|
||||
| `isLoading` | `boolean` | `false` | Whether data is loading |
|
||||
| `error` | `Error \| null` | `null` | Error from data fetching |
|
||||
| `variant` | `"console" \| "consumer"` | `"console"` | Visual variant |
|
||||
| `children` | `ReactNode` | - | Custom empty state content |
|
||||
| `children` | `ReactNode` | - | Rendered when there are no documents |
|
||||
|
||||
### Pagination Props
|
||||
|
||||
| Prop | Type | Default | Description |
|
||||
|------|------|---------|-------------|
|
||||
| `isLoadingMore` | `boolean` | `false` | Shows indicator when loading more |
|
||||
| `hasMore` | `boolean` | `false` | Whether more documents available |
|
||||
| `totalLoaded` | `number` | - | Total documents currently loaded |
|
||||
| `loadMoreDocuments` | `() => Promise<void>` | - | Callback to load more |
|
||||
| `autoLoadOnViewport` | `boolean` | `true` | Auto-load when 80% visible |
|
||||
| `isLoadingMore` | `boolean` | `false` | Whether more data is being loaded |
|
||||
| `hasMore` | `boolean` | `false` | Whether there are more documents to load |
|
||||
| `onLoadMore` | `() => void` | - | Callback to load more documents |
|
||||
| `totalCount` | `number` | - | Total count, used by the loading indicator |
|
||||
|
||||
### Display Props
|
||||
|
||||
| Prop | Type | Default | Description |
|
||||
|------|------|---------|-------------|
|
||||
| `showSpacesSelector` | `boolean` | variant-based | Show space filter dropdown |
|
||||
| `highlightDocumentIds` | `string[]` | `[]` | Document IDs to highlight |
|
||||
| `highlightsVisible` | `boolean` | `true` | Whether highlights shown |
|
||||
| `occludedRightPx` | `number` | `0` | Pixels occluded on right |
|
||||
| `highlightDocumentIds` | `string[]` | - | Document IDs to highlight |
|
||||
| `highlightsVisible` | `boolean` | - | Whether highlights are visible |
|
||||
| `legendId` | `string` | - | Optional legend element id |
|
||||
| `showFps` | `boolean` | - | Show FPS counter overlay |
|
||||
| `canvasRef` | `RefObject<HTMLCanvasElement \| null>` | - | External ref to the canvas (e.g. for screenshot export) |
|
||||
| `colors` | `Partial<GraphThemeColors>` | - | Custom theme colors, merged with CSS-variable/default values |
|
||||
| `labels` | `MemoryGraphLabels` | - | Custom user-facing labels, merged with defaults |
|
||||
| `layering` | `MemoryGraphLayering` | - | Overlay layering controls (e.g. hover popover z-index) |
|
||||
|
||||
### Controlled State Props
|
||||
### Filtering Props
|
||||
|
||||
| Prop | Type | Description |
|
||||
|------|------|-------------|
|
||||
| `selectedSpace` | `string` | Currently selected space (use `"all"` for all) |
|
||||
| `onSpaceChange` | `(spaceId: string) => void` | Callback when space changes |
|
||||
| `memoryLimit` | `number` | Max memories per document when space selected |
|
||||
| Prop | Type | Default | Description |
|
||||
|------|------|---------|-------------|
|
||||
| `containerTags` | `string[]` | - | Container tags for filtering (used by apps with their own API hooks) |
|
||||
| `documentIds` | `string[]` | - | Specific document IDs to show |
|
||||
| `maxNodes` | `number` | - | Max nodes to display |
|
||||
|
||||
### Slideshow Props
|
||||
|
||||
| Prop | Type | Default | Description |
|
||||
|------|------|---------|-------------|
|
||||
| `isSlideshowActive` | `boolean` | - | Whether slideshow mode is active |
|
||||
| `onSlideshowNodeChange` | `(nodeId: string \| null) => void` | - | Called as the slideshow moves between nodes |
|
||||
| `onSlideshowStop` | `() => void` | - | Called when the slideshow ends |
|
||||
|
||||
### Other
|
||||
|
||||
| Prop | Type | Default | Description |
|
||||
|------|------|---------|-------------|
|
||||
| `onOpenDocument` | `(documentId: string) => void` | - | Called when the user wants to view a document's full content |
|
||||
|
||||
---
|
||||
|
||||
## Data Types
|
||||
|
||||
### DocumentWithMemories
|
||||
### GraphApiDocument / GraphApiMemory
|
||||
|
||||
This is the shape `documents` actually takes: `documentType` and `memories`, matching what the API route in [Backend API Route](#backend-api-route) normalizes into:
|
||||
|
||||
```typescript
|
||||
interface GraphApiDocument {
|
||||
id: string;
|
||||
title: string | null;
|
||||
summary: string | null;
|
||||
documentType: string;
|
||||
createdAt: string;
|
||||
updatedAt: string;
|
||||
memories: GraphApiMemory[];
|
||||
}
|
||||
|
||||
interface GraphApiMemory {
|
||||
id: string;
|
||||
memory: string;
|
||||
content?: string | null;
|
||||
isStatic: boolean;
|
||||
spaceId: string;
|
||||
isLatest: boolean;
|
||||
isForgotten: boolean;
|
||||
forgetAfter: string | null;
|
||||
forgetReason: string | null;
|
||||
version: number;
|
||||
parentMemoryId: string | null;
|
||||
rootMemoryId: string | null;
|
||||
createdAt: string;
|
||||
updatedAt: string;
|
||||
relation?: 'updates' | 'extends' | 'derives' | null;
|
||||
updatesMemoryId?: string | null;
|
||||
nextVersionId?: string | null;
|
||||
memoryRelations?: Record<string, 'updates' | 'extends' | 'derives'> | null;
|
||||
spaceContainerTag?: string | null;
|
||||
}
|
||||
```
|
||||
|
||||
### DocumentWithMemories / MemoryEntry
|
||||
|
||||
Also exported for backward compatibility with older API response shapes. Not what `documents` takes today, but still useful for typing a raw fetch response before mapping it to `GraphApiDocument`:
|
||||
|
||||
```typescript
|
||||
interface DocumentWithMemories {
|
||||
id: string;
|
||||
customId?: string | null;
|
||||
title?: string | null;
|
||||
content?: string | null;
|
||||
title: string | null;
|
||||
url: string | null;
|
||||
documentType: string;
|
||||
createdAt: string;
|
||||
updatedAt: string;
|
||||
summary?: string | null;
|
||||
url?: string | null;
|
||||
source?: string | null;
|
||||
type?: string | null;
|
||||
status: 'pending' | 'processing' | 'done' | 'failed';
|
||||
metadata?: Record<string, string | number | boolean> | null;
|
||||
createdAt: string | Date;
|
||||
updatedAt: string | Date;
|
||||
memoryEntries: MemoryEntry[];
|
||||
memories: MemoryEntry[];
|
||||
}
|
||||
```
|
||||
|
||||
### MemoryEntry
|
||||
|
||||
```typescript
|
||||
interface MemoryEntry {
|
||||
id: string;
|
||||
documentId: string;
|
||||
content: string | null;
|
||||
summary?: string | null;
|
||||
title?: string | null;
|
||||
type?: string | null;
|
||||
metadata?: Record<string, string | number | boolean> | null;
|
||||
createdAt: string | Date;
|
||||
updatedAt: string | Date;
|
||||
spaceContainerTag?: string | null;
|
||||
relation?: 'updates' | 'extends' | 'derives' | null;
|
||||
isLatest?: boolean;
|
||||
memory: string;
|
||||
content?: string | null;
|
||||
createdAt: string;
|
||||
updatedAt: string;
|
||||
spaceId?: string | null;
|
||||
isStatic?: boolean;
|
||||
isForgotten?: boolean;
|
||||
forgetAfter?: string | null;
|
||||
forgetReason?: string | null;
|
||||
version?: number;
|
||||
parentMemoryId?: string | null;
|
||||
rootMemoryId?: string | null;
|
||||
isLatest?: boolean;
|
||||
relation?: 'updates' | 'extends' | 'derives' | null;
|
||||
spaceContainerTag?: string | null;
|
||||
}
|
||||
```
|
||||
|
||||
|
|
@ -324,26 +565,52 @@ interface MemoryEntry {
|
|||
### Components
|
||||
|
||||
```typescript
|
||||
import {
|
||||
MemoryGraph,
|
||||
GraphCanvas,
|
||||
Legend,
|
||||
LoadingIndicator,
|
||||
NodeDetailPanel,
|
||||
SpacesDropdown
|
||||
} from '@supermemory/memory-graph';
|
||||
import { MemoryGraph, GraphCanvas } from '@supermemory/memory-graph';
|
||||
```
|
||||
|
||||
### Hooks
|
||||
|
||||
```typescript
|
||||
import { useGraphData, useGraphInteractions } from '@supermemory/memory-graph';
|
||||
import { useGraphData, useGraphTheme } from '@supermemory/memory-graph';
|
||||
```
|
||||
|
||||
### Engine Classes
|
||||
|
||||
For advanced usage: driving the force simulation, viewport, or hit-testing directly:
|
||||
|
||||
```typescript
|
||||
import {
|
||||
ForceSimulation,
|
||||
ViewportState,
|
||||
SpatialIndex,
|
||||
VersionChainIndex,
|
||||
} from '@supermemory/memory-graph';
|
||||
```
|
||||
|
||||
### Constants
|
||||
|
||||
```typescript
|
||||
import { colors, GRAPH_SETTINGS, LAYOUT_CONSTANTS } from '@supermemory/memory-graph';
|
||||
import {
|
||||
DEFAULT_COLORS,
|
||||
DEFAULT_HOVER_POPOVER_Z_INDEX,
|
||||
DEFAULT_LABELS,
|
||||
FORCE_CONFIG,
|
||||
GRAPH_SETTINGS,
|
||||
} from '@supermemory/memory-graph';
|
||||
```
|
||||
|
||||
### Mock Data
|
||||
|
||||
`@supermemory/memory-graph/mock-data` generates fake `GraphApiDocument[]` data for local development and stress testing, without a live API key:
|
||||
|
||||
```typescript
|
||||
import { generateMockGraphData } from '@supermemory/memory-graph/mock-data';
|
||||
|
||||
const { documents } = generateMockGraphData({
|
||||
documentCount: 100,
|
||||
memoriesPerDoc: [2, 5],
|
||||
seed: 12345,
|
||||
});
|
||||
```
|
||||
|
||||
---
|
||||
|
|
|
|||
|
|
@ -14,10 +14,10 @@ Open [http://localhost:3000](http://localhost:3000) and enter your Supermemory A
|
|||
## Usage Example
|
||||
|
||||
```tsx
|
||||
import { MemoryGraph, type DocumentWithMemories } from '@supermemory/memory-graph'
|
||||
import { MemoryGraph, type GraphApiDocument } from '@supermemory/memory-graph'
|
||||
|
||||
function App() {
|
||||
const [documents, setDocuments] = useState<DocumentWithMemories[]>([])
|
||||
const [documents, setDocuments] = useState<GraphApiDocument[]>([])
|
||||
|
||||
return (
|
||||
<MemoryGraph
|
||||
|
|
@ -26,10 +26,9 @@ function App() {
|
|||
isLoadingMore={false}
|
||||
error={null}
|
||||
hasMore={false}
|
||||
loadMoreDocuments={() => {}}
|
||||
totalLoaded={documents.length}
|
||||
onLoadMore={() => {}}
|
||||
totalCount={documents.length}
|
||||
variant="console"
|
||||
showSpacesSelector={true}
|
||||
>
|
||||
<div>No memories found</div>
|
||||
</MemoryGraph>
|
||||
|
|
@ -37,16 +36,19 @@ function App() {
|
|||
}
|
||||
```
|
||||
|
||||
See [`src/app/page.tsx`](./src/app/page.tsx) for the full working example, including converting a raw API response into `GraphApiDocument[]`.
|
||||
|
||||
## Props
|
||||
|
||||
| Prop | Type | Description |
|
||||
|------|------|-------------|
|
||||
| `documents` | `DocumentWithMemories[]` | Array of documents to display |
|
||||
| `documents` | `GraphApiDocument[]` | Array of documents to display |
|
||||
| `isLoading` | `boolean` | Initial loading state |
|
||||
| `isLoadingMore` | `boolean` | Loading more documents state |
|
||||
| `error` | `Error \| null` | Error to display |
|
||||
| `hasMore` | `boolean` | Whether more documents can be loaded |
|
||||
| `loadMoreDocuments` | `() => void` | Callback to load more documents |
|
||||
| `totalLoaded` | `number` | Total number of loaded documents |
|
||||
| `variant` | `"default" \| "console"` | Visual theme variant |
|
||||
| `showSpacesSelector` | `boolean` | Show space filter dropdown |
|
||||
| `onLoadMore` | `() => void` | Callback to load more documents |
|
||||
| `totalCount` | `number` | Total number of loaded documents |
|
||||
| `variant` | `"console" \| "consumer"` | Visual variant |
|
||||
|
||||
See [`packages/memory-graph`](../../packages/memory-graph/src/types.ts) for the full `MemoryGraphProps` reference.
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue