@lanonasis/memory-client 1.0.1 → 2.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/core/index.d.ts +948 -0
- package/dist/core/index.js +1027 -0
- package/dist/core/index.js.map +1 -0
- package/dist/core/tsconfig.tsbuildinfo +1 -0
- package/dist/index.d.ts +703 -352
- package/dist/index.esm.js +1070 -277
- package/dist/index.esm.js.map +1 -1
- package/dist/index.js +1098 -283
- package/dist/index.js.map +1 -1
- package/dist/node/index.d.ts +329 -0
- package/dist/node/index.js +647 -0
- package/dist/node/index.js.map +1 -0
- package/dist/node/tsconfig.tsbuildinfo +1 -0
- package/dist/presets/index.d.ts +146 -0
- package/dist/presets/index.js +234 -0
- package/dist/presets/index.js.map +1 -0
- package/dist/presets/tsconfig.tsbuildinfo +1 -0
- package/dist/react/index.d.ts +235 -0
- package/dist/react/index.js +333 -0
- package/dist/react/index.js.map +1 -0
- package/dist/react/tsconfig.tsbuildinfo +1 -0
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/dist/vue/index.d.ts +316 -0
- package/dist/vue/index.js +341 -0
- package/dist/vue/index.js.map +1 -0
- package/dist/vue/tsconfig.tsbuildinfo +1 -0
- package/package.json +67 -13
|
@@ -0,0 +1,235 @@
|
|
|
1
|
+
import * as react from 'react';
|
|
2
|
+
import { ReactNode } from 'react';
|
|
3
|
+
import { CoreMemoryClientConfig, CoreMemoryClient } from '../core/client';
|
|
4
|
+
export { ApiResponse, CoreMemoryClient, CoreMemoryClientConfig, PaginatedResponse } from '../core/client';
|
|
5
|
+
import { MemoryEntry, UpdateMemoryRequest, CreateMemoryRequest, MemorySearchResult, SearchMemoryRequest } from '../core/types';
|
|
6
|
+
export { CreateMemoryRequest, MemoryEntry, MemorySearchResult, MemoryStatus, MemoryTopic, MemoryType, SearchMemoryRequest, UpdateMemoryRequest, UserMemoryStats } from '../core/types';
|
|
7
|
+
|
|
8
|
+
declare const MemoryContext: react.Context<CoreMemoryClient | null>;
|
|
9
|
+
interface MemoryProviderProps {
|
|
10
|
+
children: ReactNode;
|
|
11
|
+
config?: CoreMemoryClientConfig;
|
|
12
|
+
apiKey?: string;
|
|
13
|
+
apiUrl?: string;
|
|
14
|
+
client?: CoreMemoryClient;
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* Memory Provider Component
|
|
18
|
+
*
|
|
19
|
+
* Wrap your app or component tree with this provider to enable Memory hooks
|
|
20
|
+
*
|
|
21
|
+
* @example
|
|
22
|
+
* ```tsx
|
|
23
|
+
* function App() {
|
|
24
|
+
* return (
|
|
25
|
+
* <MemoryProvider apiKey={process.env.REACT_APP_LANONASIS_KEY}>
|
|
26
|
+
* <YourComponents />
|
|
27
|
+
* </MemoryProvider>
|
|
28
|
+
* );
|
|
29
|
+
* }
|
|
30
|
+
* ```
|
|
31
|
+
*/
|
|
32
|
+
declare function MemoryProvider({ children, config, apiKey, apiUrl, client: providedClient }: MemoryProviderProps): react.FunctionComponentElement<react.ProviderProps<CoreMemoryClient | null>>;
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* Error handling for Memory Client
|
|
36
|
+
* Browser-safe, no Node.js dependencies
|
|
37
|
+
*/
|
|
38
|
+
/**
|
|
39
|
+
* Standardized error codes for programmatic error handling
|
|
40
|
+
*/
|
|
41
|
+
declare const ERROR_CODES: readonly ["API_ERROR", "AUTH_ERROR", "VALIDATION_ERROR", "TIMEOUT_ERROR", "RATE_LIMIT_ERROR", "NOT_FOUND", "NETWORK_ERROR", "FORBIDDEN", "CONFLICT", "SERVER_ERROR"];
|
|
42
|
+
type ErrorCode = typeof ERROR_CODES[number];
|
|
43
|
+
/**
|
|
44
|
+
* Structured API error response - replaces plain string errors
|
|
45
|
+
* Enables programmatic error handling with typed codes
|
|
46
|
+
*/
|
|
47
|
+
interface ApiErrorResponse {
|
|
48
|
+
/** Machine-readable error code for programmatic handling */
|
|
49
|
+
code: ErrorCode;
|
|
50
|
+
/** Human-readable error message */
|
|
51
|
+
message: string;
|
|
52
|
+
/** HTTP status code if from API response */
|
|
53
|
+
statusCode?: number;
|
|
54
|
+
/** Additional error details (validation errors, etc.) */
|
|
55
|
+
details?: unknown;
|
|
56
|
+
/** Request ID for debugging/support */
|
|
57
|
+
requestId?: string;
|
|
58
|
+
/** Timestamp when error occurred */
|
|
59
|
+
timestamp?: string;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
/**
|
|
63
|
+
* Hook to access the Memory Client instance
|
|
64
|
+
*
|
|
65
|
+
* @throws Error if used outside of MemoryProvider
|
|
66
|
+
*/
|
|
67
|
+
declare function useMemoryClient(): CoreMemoryClient;
|
|
68
|
+
/**
|
|
69
|
+
* Result type for list/search hooks
|
|
70
|
+
*/
|
|
71
|
+
interface UseMemoriesResult {
|
|
72
|
+
memories: MemoryEntry[];
|
|
73
|
+
loading: boolean;
|
|
74
|
+
error: ApiErrorResponse | null;
|
|
75
|
+
refresh: () => Promise<void>;
|
|
76
|
+
}
|
|
77
|
+
/**
|
|
78
|
+
* Hook to list memories with optional filtering
|
|
79
|
+
*
|
|
80
|
+
* @example
|
|
81
|
+
* ```tsx
|
|
82
|
+
* function MemoryList() {
|
|
83
|
+
* const { memories, loading, error, refresh } = useMemories({
|
|
84
|
+
* memory_type: 'project',
|
|
85
|
+
* limit: 20
|
|
86
|
+
* });
|
|
87
|
+
*
|
|
88
|
+
* if (loading) return <div>Loading...</div>;
|
|
89
|
+
* if (error) return <div>Error: {error.message}</div>;
|
|
90
|
+
*
|
|
91
|
+
* return (
|
|
92
|
+
* <div>
|
|
93
|
+
* {memories.map(m => <div key={m.id}>{m.title}</div>)}
|
|
94
|
+
* <button onClick={refresh}>Refresh</button>
|
|
95
|
+
* </div>
|
|
96
|
+
* );
|
|
97
|
+
* }
|
|
98
|
+
* ```
|
|
99
|
+
*/
|
|
100
|
+
declare function useMemories(options?: {
|
|
101
|
+
page?: number;
|
|
102
|
+
limit?: number;
|
|
103
|
+
memory_type?: string;
|
|
104
|
+
topic_id?: string;
|
|
105
|
+
project_ref?: string;
|
|
106
|
+
status?: string;
|
|
107
|
+
tags?: string[];
|
|
108
|
+
sort?: string;
|
|
109
|
+
order?: 'asc' | 'desc';
|
|
110
|
+
}): UseMemoriesResult;
|
|
111
|
+
/**
|
|
112
|
+
* Result type for single memory hook
|
|
113
|
+
*/
|
|
114
|
+
interface UseMemoryResult {
|
|
115
|
+
memory: MemoryEntry | null;
|
|
116
|
+
loading: boolean;
|
|
117
|
+
error: ApiErrorResponse | null;
|
|
118
|
+
refresh: () => Promise<void>;
|
|
119
|
+
update: (updates: UpdateMemoryRequest) => Promise<void>;
|
|
120
|
+
deleteMemory: () => Promise<void>;
|
|
121
|
+
}
|
|
122
|
+
/**
|
|
123
|
+
* Hook to fetch and manage a single memory by ID
|
|
124
|
+
*
|
|
125
|
+
* @example
|
|
126
|
+
* ```tsx
|
|
127
|
+
* function MemoryDetail({ id }: { id: string }) {
|
|
128
|
+
* const { memory, loading, error, update, deleteMemory } = useMemory(id);
|
|
129
|
+
*
|
|
130
|
+
* if (loading) return <div>Loading...</div>;
|
|
131
|
+
* if (error) return <div>Error: {error.message}</div>;
|
|
132
|
+
* if (!memory) return <div>Memory not found</div>;
|
|
133
|
+
*
|
|
134
|
+
* return (
|
|
135
|
+
* <div>
|
|
136
|
+
* <h1>{memory.title}</h1>
|
|
137
|
+
* <p>{memory.content}</p>
|
|
138
|
+
* <button onClick={() => update({ title: 'Updated Title' })}>Update</button>
|
|
139
|
+
* <button onClick={deleteMemory}>Delete</button>
|
|
140
|
+
* </div>
|
|
141
|
+
* );
|
|
142
|
+
* }
|
|
143
|
+
* ```
|
|
144
|
+
*/
|
|
145
|
+
declare function useMemory(id: string): UseMemoryResult;
|
|
146
|
+
/**
|
|
147
|
+
* Result type for create memory hook
|
|
148
|
+
*/
|
|
149
|
+
interface UseCreateMemoryResult {
|
|
150
|
+
createMemory: (memory: CreateMemoryRequest) => Promise<MemoryEntry | null>;
|
|
151
|
+
loading: boolean;
|
|
152
|
+
error: ApiErrorResponse | null;
|
|
153
|
+
}
|
|
154
|
+
/**
|
|
155
|
+
* Hook to create new memories
|
|
156
|
+
*
|
|
157
|
+
* @example
|
|
158
|
+
* ```tsx
|
|
159
|
+
* function CreateMemoryForm() {
|
|
160
|
+
* const { createMemory, loading, error } = useCreateMemory();
|
|
161
|
+
* const [title, setTitle] = useState('');
|
|
162
|
+
* const [content, setContent] = useState('');
|
|
163
|
+
*
|
|
164
|
+
* const handleSubmit = async (e: React.FormEvent) => {
|
|
165
|
+
* e.preventDefault();
|
|
166
|
+
* const memory = await createMemory({ title, content });
|
|
167
|
+
* if (memory) {
|
|
168
|
+
* console.log('Created:', memory.id);
|
|
169
|
+
* setTitle('');
|
|
170
|
+
* setContent('');
|
|
171
|
+
* }
|
|
172
|
+
* };
|
|
173
|
+
*
|
|
174
|
+
* return (
|
|
175
|
+
* <form onSubmit={handleSubmit}>
|
|
176
|
+
* <input value={title} onChange={e => setTitle(e.target.value)} />
|
|
177
|
+
* <textarea value={content} onChange={e => setContent(e.target.value)} />
|
|
178
|
+
* <button type="submit" disabled={loading}>Create</button>
|
|
179
|
+
* {error && <div>Error: {error.message}</div>}
|
|
180
|
+
* </form>
|
|
181
|
+
* );
|
|
182
|
+
* }
|
|
183
|
+
* ```
|
|
184
|
+
*/
|
|
185
|
+
declare function useCreateMemory(): UseCreateMemoryResult;
|
|
186
|
+
/**
|
|
187
|
+
* Result type for search memories hook
|
|
188
|
+
*/
|
|
189
|
+
interface UseSearchMemoriesResult {
|
|
190
|
+
results: MemorySearchResult[];
|
|
191
|
+
loading: boolean;
|
|
192
|
+
error: ApiErrorResponse | null;
|
|
193
|
+
search: (query: string, options?: Omit<SearchMemoryRequest, 'query'>) => Promise<void>;
|
|
194
|
+
totalResults: number;
|
|
195
|
+
searchTime: number;
|
|
196
|
+
}
|
|
197
|
+
/**
|
|
198
|
+
* Hook to search memories with debouncing
|
|
199
|
+
*
|
|
200
|
+
* @example
|
|
201
|
+
* ```tsx
|
|
202
|
+
* function MemorySearch() {
|
|
203
|
+
* const { results, loading, error, search } = useSearchMemories();
|
|
204
|
+
* const [query, setQuery] = useState('');
|
|
205
|
+
*
|
|
206
|
+
* useEffect(() => {
|
|
207
|
+
* if (query.length > 2) {
|
|
208
|
+
* search(query, { limit: 10 });
|
|
209
|
+
* }
|
|
210
|
+
* }, [query, search]);
|
|
211
|
+
*
|
|
212
|
+
* return (
|
|
213
|
+
* <div>
|
|
214
|
+
* <input
|
|
215
|
+
* value={query}
|
|
216
|
+
* onChange={e => setQuery(e.target.value)}
|
|
217
|
+
* placeholder="Search memories..."
|
|
218
|
+
* />
|
|
219
|
+
* {loading && <div>Searching...</div>}
|
|
220
|
+
* {error && <div>Error: {error.message}</div>}
|
|
221
|
+
* {results.map(r => (
|
|
222
|
+
* <div key={r.id}>
|
|
223
|
+
* <h3>{r.title}</h3>
|
|
224
|
+
* <span>Score: {r.similarity_score.toFixed(2)}</span>
|
|
225
|
+
* </div>
|
|
226
|
+
* ))}
|
|
227
|
+
* </div>
|
|
228
|
+
* );
|
|
229
|
+
* }
|
|
230
|
+
* ```
|
|
231
|
+
*/
|
|
232
|
+
declare function useSearchMemories(debounceMs?: number): UseSearchMemoriesResult;
|
|
233
|
+
|
|
234
|
+
export { MemoryContext, MemoryProvider, useCreateMemory, useMemories, useMemory, useMemoryClient, useSearchMemories };
|
|
235
|
+
export type { ApiErrorResponse, ErrorCode, MemoryProviderProps, UseCreateMemoryResult, UseMemoriesResult, UseMemoryResult, UseSearchMemoriesResult };
|
|
@@ -0,0 +1,333 @@
|
|
|
1
|
+
import { createContext, useMemo, createElement, useContext, useState, useCallback, useEffect, useRef } from 'react';
|
|
2
|
+
import { createMemoryClient } from '../core/client';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* React Context Provider for Memory Client
|
|
6
|
+
*
|
|
7
|
+
* Provides a Memory Client instance to all child components via React Context
|
|
8
|
+
*/
|
|
9
|
+
const MemoryContext = createContext(null);
|
|
10
|
+
/**
|
|
11
|
+
* Memory Provider Component
|
|
12
|
+
*
|
|
13
|
+
* Wrap your app or component tree with this provider to enable Memory hooks
|
|
14
|
+
*
|
|
15
|
+
* @example
|
|
16
|
+
* ```tsx
|
|
17
|
+
* function App() {
|
|
18
|
+
* return (
|
|
19
|
+
* <MemoryProvider apiKey={process.env.REACT_APP_LANONASIS_KEY}>
|
|
20
|
+
* <YourComponents />
|
|
21
|
+
* </MemoryProvider>
|
|
22
|
+
* );
|
|
23
|
+
* }
|
|
24
|
+
* ```
|
|
25
|
+
*/
|
|
26
|
+
function MemoryProvider({ children, config, apiKey, apiUrl = 'https://api.lanonasis.com', client: providedClient }) {
|
|
27
|
+
const client = useMemo(() => {
|
|
28
|
+
if (providedClient) {
|
|
29
|
+
return providedClient;
|
|
30
|
+
}
|
|
31
|
+
return createMemoryClient({
|
|
32
|
+
apiUrl,
|
|
33
|
+
apiKey,
|
|
34
|
+
...config
|
|
35
|
+
});
|
|
36
|
+
}, [providedClient, apiUrl, apiKey, config]);
|
|
37
|
+
return createElement(MemoryContext.Provider, { value: client }, children);
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* React Hooks for Memory Client
|
|
42
|
+
*
|
|
43
|
+
* Provides convenient React hooks for working with memories
|
|
44
|
+
*/
|
|
45
|
+
/**
|
|
46
|
+
* Hook to access the Memory Client instance
|
|
47
|
+
*
|
|
48
|
+
* @throws Error if used outside of MemoryProvider
|
|
49
|
+
*/
|
|
50
|
+
function useMemoryClient() {
|
|
51
|
+
const client = useContext(MemoryContext);
|
|
52
|
+
if (!client) {
|
|
53
|
+
throw new Error('useMemoryClient must be used within a MemoryProvider');
|
|
54
|
+
}
|
|
55
|
+
return client;
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* Hook to list memories with optional filtering
|
|
59
|
+
*
|
|
60
|
+
* @example
|
|
61
|
+
* ```tsx
|
|
62
|
+
* function MemoryList() {
|
|
63
|
+
* const { memories, loading, error, refresh } = useMemories({
|
|
64
|
+
* memory_type: 'project',
|
|
65
|
+
* limit: 20
|
|
66
|
+
* });
|
|
67
|
+
*
|
|
68
|
+
* if (loading) return <div>Loading...</div>;
|
|
69
|
+
* if (error) return <div>Error: {error.message}</div>;
|
|
70
|
+
*
|
|
71
|
+
* return (
|
|
72
|
+
* <div>
|
|
73
|
+
* {memories.map(m => <div key={m.id}>{m.title}</div>)}
|
|
74
|
+
* <button onClick={refresh}>Refresh</button>
|
|
75
|
+
* </div>
|
|
76
|
+
* );
|
|
77
|
+
* }
|
|
78
|
+
* ```
|
|
79
|
+
*/
|
|
80
|
+
function useMemories(options) {
|
|
81
|
+
const client = useMemoryClient();
|
|
82
|
+
const [memories, setMemories] = useState([]);
|
|
83
|
+
const [loading, setLoading] = useState(true);
|
|
84
|
+
const [error, setError] = useState(null);
|
|
85
|
+
const loadMemories = useCallback(async () => {
|
|
86
|
+
setLoading(true);
|
|
87
|
+
setError(null);
|
|
88
|
+
const result = await client.listMemories(options);
|
|
89
|
+
if (result.error) {
|
|
90
|
+
setError(result.error);
|
|
91
|
+
setMemories([]);
|
|
92
|
+
}
|
|
93
|
+
else if (result.data) {
|
|
94
|
+
setMemories(result.data.data);
|
|
95
|
+
}
|
|
96
|
+
setLoading(false);
|
|
97
|
+
}, [client, JSON.stringify(options)]);
|
|
98
|
+
useEffect(() => {
|
|
99
|
+
loadMemories();
|
|
100
|
+
}, [loadMemories]);
|
|
101
|
+
return {
|
|
102
|
+
memories,
|
|
103
|
+
loading,
|
|
104
|
+
error,
|
|
105
|
+
refresh: loadMemories
|
|
106
|
+
};
|
|
107
|
+
}
|
|
108
|
+
/**
|
|
109
|
+
* Hook to fetch and manage a single memory by ID
|
|
110
|
+
*
|
|
111
|
+
* @example
|
|
112
|
+
* ```tsx
|
|
113
|
+
* function MemoryDetail({ id }: { id: string }) {
|
|
114
|
+
* const { memory, loading, error, update, deleteMemory } = useMemory(id);
|
|
115
|
+
*
|
|
116
|
+
* if (loading) return <div>Loading...</div>;
|
|
117
|
+
* if (error) return <div>Error: {error.message}</div>;
|
|
118
|
+
* if (!memory) return <div>Memory not found</div>;
|
|
119
|
+
*
|
|
120
|
+
* return (
|
|
121
|
+
* <div>
|
|
122
|
+
* <h1>{memory.title}</h1>
|
|
123
|
+
* <p>{memory.content}</p>
|
|
124
|
+
* <button onClick={() => update({ title: 'Updated Title' })}>Update</button>
|
|
125
|
+
* <button onClick={deleteMemory}>Delete</button>
|
|
126
|
+
* </div>
|
|
127
|
+
* );
|
|
128
|
+
* }
|
|
129
|
+
* ```
|
|
130
|
+
*/
|
|
131
|
+
function useMemory(id) {
|
|
132
|
+
const client = useMemoryClient();
|
|
133
|
+
const [memory, setMemory] = useState(null);
|
|
134
|
+
const [loading, setLoading] = useState(true);
|
|
135
|
+
const [error, setError] = useState(null);
|
|
136
|
+
const loadMemory = useCallback(async () => {
|
|
137
|
+
if (!id) {
|
|
138
|
+
setMemory(null);
|
|
139
|
+
setLoading(false);
|
|
140
|
+
return;
|
|
141
|
+
}
|
|
142
|
+
setLoading(true);
|
|
143
|
+
setError(null);
|
|
144
|
+
const result = await client.getMemory(id);
|
|
145
|
+
if (result.error) {
|
|
146
|
+
setError(result.error);
|
|
147
|
+
setMemory(null);
|
|
148
|
+
}
|
|
149
|
+
else if (result.data) {
|
|
150
|
+
setMemory(result.data);
|
|
151
|
+
}
|
|
152
|
+
setLoading(false);
|
|
153
|
+
}, [client, id]);
|
|
154
|
+
useEffect(() => {
|
|
155
|
+
loadMemory();
|
|
156
|
+
}, [loadMemory]);
|
|
157
|
+
const update = useCallback(async (updates) => {
|
|
158
|
+
if (!id)
|
|
159
|
+
return;
|
|
160
|
+
const result = await client.updateMemory(id, updates);
|
|
161
|
+
if (result.error) {
|
|
162
|
+
setError(result.error);
|
|
163
|
+
}
|
|
164
|
+
else if (result.data) {
|
|
165
|
+
setMemory(result.data);
|
|
166
|
+
}
|
|
167
|
+
}, [client, id]);
|
|
168
|
+
const deleteMemory = useCallback(async () => {
|
|
169
|
+
if (!id)
|
|
170
|
+
return;
|
|
171
|
+
const result = await client.deleteMemory(id);
|
|
172
|
+
if (result.error) {
|
|
173
|
+
setError(result.error);
|
|
174
|
+
}
|
|
175
|
+
else {
|
|
176
|
+
setMemory(null);
|
|
177
|
+
}
|
|
178
|
+
}, [client, id]);
|
|
179
|
+
return {
|
|
180
|
+
memory,
|
|
181
|
+
loading,
|
|
182
|
+
error,
|
|
183
|
+
refresh: loadMemory,
|
|
184
|
+
update,
|
|
185
|
+
deleteMemory
|
|
186
|
+
};
|
|
187
|
+
}
|
|
188
|
+
/**
|
|
189
|
+
* Hook to create new memories
|
|
190
|
+
*
|
|
191
|
+
* @example
|
|
192
|
+
* ```tsx
|
|
193
|
+
* function CreateMemoryForm() {
|
|
194
|
+
* const { createMemory, loading, error } = useCreateMemory();
|
|
195
|
+
* const [title, setTitle] = useState('');
|
|
196
|
+
* const [content, setContent] = useState('');
|
|
197
|
+
*
|
|
198
|
+
* const handleSubmit = async (e: React.FormEvent) => {
|
|
199
|
+
* e.preventDefault();
|
|
200
|
+
* const memory = await createMemory({ title, content });
|
|
201
|
+
* if (memory) {
|
|
202
|
+
* console.log('Created:', memory.id);
|
|
203
|
+
* setTitle('');
|
|
204
|
+
* setContent('');
|
|
205
|
+
* }
|
|
206
|
+
* };
|
|
207
|
+
*
|
|
208
|
+
* return (
|
|
209
|
+
* <form onSubmit={handleSubmit}>
|
|
210
|
+
* <input value={title} onChange={e => setTitle(e.target.value)} />
|
|
211
|
+
* <textarea value={content} onChange={e => setContent(e.target.value)} />
|
|
212
|
+
* <button type="submit" disabled={loading}>Create</button>
|
|
213
|
+
* {error && <div>Error: {error.message}</div>}
|
|
214
|
+
* </form>
|
|
215
|
+
* );
|
|
216
|
+
* }
|
|
217
|
+
* ```
|
|
218
|
+
*/
|
|
219
|
+
function useCreateMemory() {
|
|
220
|
+
const client = useMemoryClient();
|
|
221
|
+
const [loading, setLoading] = useState(false);
|
|
222
|
+
const [error, setError] = useState(null);
|
|
223
|
+
const createMemory = useCallback(async (memory) => {
|
|
224
|
+
setLoading(true);
|
|
225
|
+
setError(null);
|
|
226
|
+
const result = await client.createMemory(memory);
|
|
227
|
+
if (result.error) {
|
|
228
|
+
setError(result.error);
|
|
229
|
+
setLoading(false);
|
|
230
|
+
return null;
|
|
231
|
+
}
|
|
232
|
+
setLoading(false);
|
|
233
|
+
return result.data || null;
|
|
234
|
+
}, [client]);
|
|
235
|
+
return {
|
|
236
|
+
createMemory,
|
|
237
|
+
loading,
|
|
238
|
+
error
|
|
239
|
+
};
|
|
240
|
+
}
|
|
241
|
+
/**
|
|
242
|
+
* Hook to search memories with debouncing
|
|
243
|
+
*
|
|
244
|
+
* @example
|
|
245
|
+
* ```tsx
|
|
246
|
+
* function MemorySearch() {
|
|
247
|
+
* const { results, loading, error, search } = useSearchMemories();
|
|
248
|
+
* const [query, setQuery] = useState('');
|
|
249
|
+
*
|
|
250
|
+
* useEffect(() => {
|
|
251
|
+
* if (query.length > 2) {
|
|
252
|
+
* search(query, { limit: 10 });
|
|
253
|
+
* }
|
|
254
|
+
* }, [query, search]);
|
|
255
|
+
*
|
|
256
|
+
* return (
|
|
257
|
+
* <div>
|
|
258
|
+
* <input
|
|
259
|
+
* value={query}
|
|
260
|
+
* onChange={e => setQuery(e.target.value)}
|
|
261
|
+
* placeholder="Search memories..."
|
|
262
|
+
* />
|
|
263
|
+
* {loading && <div>Searching...</div>}
|
|
264
|
+
* {error && <div>Error: {error.message}</div>}
|
|
265
|
+
* {results.map(r => (
|
|
266
|
+
* <div key={r.id}>
|
|
267
|
+
* <h3>{r.title}</h3>
|
|
268
|
+
* <span>Score: {r.similarity_score.toFixed(2)}</span>
|
|
269
|
+
* </div>
|
|
270
|
+
* ))}
|
|
271
|
+
* </div>
|
|
272
|
+
* );
|
|
273
|
+
* }
|
|
274
|
+
* ```
|
|
275
|
+
*/
|
|
276
|
+
function useSearchMemories(debounceMs = 300) {
|
|
277
|
+
const client = useMemoryClient();
|
|
278
|
+
const [results, setResults] = useState([]);
|
|
279
|
+
const [loading, setLoading] = useState(false);
|
|
280
|
+
const [error, setError] = useState(null);
|
|
281
|
+
const [totalResults, setTotalResults] = useState(0);
|
|
282
|
+
const [searchTime, setSearchTime] = useState(0);
|
|
283
|
+
const debounceTimer = useRef(null);
|
|
284
|
+
const search = useCallback(async (query, options) => {
|
|
285
|
+
// Clear existing timer
|
|
286
|
+
if (debounceTimer.current) {
|
|
287
|
+
clearTimeout(debounceTimer.current);
|
|
288
|
+
}
|
|
289
|
+
// Set new timer
|
|
290
|
+
debounceTimer.current = setTimeout(async () => {
|
|
291
|
+
setLoading(true);
|
|
292
|
+
setError(null);
|
|
293
|
+
const result = await client.searchMemories({
|
|
294
|
+
query,
|
|
295
|
+
status: options?.status ?? 'active',
|
|
296
|
+
limit: options?.limit ?? 20,
|
|
297
|
+
threshold: options?.threshold ?? 0.7,
|
|
298
|
+
...options
|
|
299
|
+
});
|
|
300
|
+
if (result.error) {
|
|
301
|
+
setError(result.error);
|
|
302
|
+
setResults([]);
|
|
303
|
+
setTotalResults(0);
|
|
304
|
+
setSearchTime(0);
|
|
305
|
+
}
|
|
306
|
+
else if (result.data) {
|
|
307
|
+
setResults(result.data.results);
|
|
308
|
+
setTotalResults(result.data.total_results);
|
|
309
|
+
setSearchTime(result.data.search_time_ms);
|
|
310
|
+
}
|
|
311
|
+
setLoading(false);
|
|
312
|
+
}, debounceMs);
|
|
313
|
+
}, [client, debounceMs]);
|
|
314
|
+
// Cleanup timer on unmount
|
|
315
|
+
useEffect(() => {
|
|
316
|
+
return () => {
|
|
317
|
+
if (debounceTimer.current) {
|
|
318
|
+
clearTimeout(debounceTimer.current);
|
|
319
|
+
}
|
|
320
|
+
};
|
|
321
|
+
}, []);
|
|
322
|
+
return {
|
|
323
|
+
results,
|
|
324
|
+
loading,
|
|
325
|
+
error,
|
|
326
|
+
search,
|
|
327
|
+
totalResults,
|
|
328
|
+
searchTime
|
|
329
|
+
};
|
|
330
|
+
}
|
|
331
|
+
|
|
332
|
+
export { MemoryContext, MemoryProvider, useCreateMemory, useMemories, useMemory, useMemoryClient, useSearchMemories };
|
|
333
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sources":["../../../src/react/provider.tsx","../../../src/react/hooks.ts"],"sourcesContent":["/**\n * React Context Provider for Memory Client\n *\n * Provides a Memory Client instance to all child components via React Context\n */\n\nimport { createElement, createContext, useMemo, type ReactNode } from 'react';\nimport { createMemoryClient, type CoreMemoryClient, type CoreMemoryClientConfig } from '../core/client';\n\nexport const MemoryContext = createContext<CoreMemoryClient | null>(null);\n\nexport interface MemoryProviderProps {\n children: ReactNode;\n config?: CoreMemoryClientConfig;\n apiKey?: string;\n apiUrl?: string;\n client?: CoreMemoryClient;\n}\n\n/**\n * Memory Provider Component\n *\n * Wrap your app or component tree with this provider to enable Memory hooks\n *\n * @example\n * ```tsx\n * function App() {\n * return (\n * <MemoryProvider apiKey={process.env.REACT_APP_LANONASIS_KEY}>\n * <YourComponents />\n * </MemoryProvider>\n * );\n * }\n * ```\n */\nexport function MemoryProvider({\n children,\n config,\n apiKey,\n apiUrl = 'https://api.lanonasis.com',\n client: providedClient\n}: MemoryProviderProps) {\n const client = useMemo(() => {\n if (providedClient) {\n return providedClient;\n }\n\n return createMemoryClient({\n apiUrl,\n apiKey,\n ...config\n });\n }, [providedClient, apiUrl, apiKey, config]);\n\n return createElement(MemoryContext.Provider, { value: client }, children);\n}\n","/**\n * React Hooks for Memory Client\n *\n * Provides convenient React hooks for working with memories\n */\n\nimport { useContext, useEffect, useState, useCallback, useRef } from 'react';\nimport { MemoryContext } from './provider';\nimport type {\n MemoryEntry,\n CreateMemoryRequest,\n UpdateMemoryRequest,\n SearchMemoryRequest,\n MemorySearchResult\n} from '../core/types';\nimport type { ApiErrorResponse } from '../core/errors';\n\n/**\n * Hook to access the Memory Client instance\n *\n * @throws Error if used outside of MemoryProvider\n */\nexport function useMemoryClient() {\n const client = useContext(MemoryContext);\n\n if (!client) {\n throw new Error('useMemoryClient must be used within a MemoryProvider');\n }\n\n return client;\n}\n\n/**\n * Result type for list/search hooks\n */\nexport interface UseMemoriesResult {\n memories: MemoryEntry[];\n loading: boolean;\n error: ApiErrorResponse | null;\n refresh: () => Promise<void>;\n}\n\n/**\n * Hook to list memories with optional filtering\n *\n * @example\n * ```tsx\n * function MemoryList() {\n * const { memories, loading, error, refresh } = useMemories({\n * memory_type: 'project',\n * limit: 20\n * });\n *\n * if (loading) return <div>Loading...</div>;\n * if (error) return <div>Error: {error.message}</div>;\n *\n * return (\n * <div>\n * {memories.map(m => <div key={m.id}>{m.title}</div>)}\n * <button onClick={refresh}>Refresh</button>\n * </div>\n * );\n * }\n * ```\n */\nexport function useMemories(options?: {\n page?: number;\n limit?: number;\n memory_type?: string;\n topic_id?: string;\n project_ref?: string;\n status?: string;\n tags?: string[];\n sort?: string;\n order?: 'asc' | 'desc';\n}): UseMemoriesResult {\n const client = useMemoryClient();\n const [memories, setMemories] = useState<MemoryEntry[]>([]);\n const [loading, setLoading] = useState(true);\n const [error, setError] = useState<ApiErrorResponse | null>(null);\n\n const loadMemories = useCallback(async () => {\n setLoading(true);\n setError(null);\n\n const result = await client.listMemories(options);\n\n if (result.error) {\n setError(result.error);\n setMemories([]);\n } else if (result.data) {\n setMemories(result.data.data);\n }\n\n setLoading(false);\n }, [client, JSON.stringify(options)]);\n\n useEffect(() => {\n loadMemories();\n }, [loadMemories]);\n\n return {\n memories,\n loading,\n error,\n refresh: loadMemories\n };\n}\n\n/**\n * Result type for single memory hook\n */\nexport interface UseMemoryResult {\n memory: MemoryEntry | null;\n loading: boolean;\n error: ApiErrorResponse | null;\n refresh: () => Promise<void>;\n update: (updates: UpdateMemoryRequest) => Promise<void>;\n deleteMemory: () => Promise<void>;\n}\n\n/**\n * Hook to fetch and manage a single memory by ID\n *\n * @example\n * ```tsx\n * function MemoryDetail({ id }: { id: string }) {\n * const { memory, loading, error, update, deleteMemory } = useMemory(id);\n *\n * if (loading) return <div>Loading...</div>;\n * if (error) return <div>Error: {error.message}</div>;\n * if (!memory) return <div>Memory not found</div>;\n *\n * return (\n * <div>\n * <h1>{memory.title}</h1>\n * <p>{memory.content}</p>\n * <button onClick={() => update({ title: 'Updated Title' })}>Update</button>\n * <button onClick={deleteMemory}>Delete</button>\n * </div>\n * );\n * }\n * ```\n */\nexport function useMemory(id: string): UseMemoryResult {\n const client = useMemoryClient();\n const [memory, setMemory] = useState<MemoryEntry | null>(null);\n const [loading, setLoading] = useState(true);\n const [error, setError] = useState<ApiErrorResponse | null>(null);\n\n const loadMemory = useCallback(async () => {\n if (!id) {\n setMemory(null);\n setLoading(false);\n return;\n }\n\n setLoading(true);\n setError(null);\n\n const result = await client.getMemory(id);\n\n if (result.error) {\n setError(result.error);\n setMemory(null);\n } else if (result.data) {\n setMemory(result.data);\n }\n\n setLoading(false);\n }, [client, id]);\n\n useEffect(() => {\n loadMemory();\n }, [loadMemory]);\n\n const update = useCallback(async (updates: UpdateMemoryRequest) => {\n if (!id) return;\n\n const result = await client.updateMemory(id, updates);\n\n if (result.error) {\n setError(result.error);\n } else if (result.data) {\n setMemory(result.data);\n }\n }, [client, id]);\n\n const deleteMemory = useCallback(async () => {\n if (!id) return;\n\n const result = await client.deleteMemory(id);\n\n if (result.error) {\n setError(result.error);\n } else {\n setMemory(null);\n }\n }, [client, id]);\n\n return {\n memory,\n loading,\n error,\n refresh: loadMemory,\n update,\n deleteMemory\n };\n}\n\n/**\n * Result type for create memory hook\n */\nexport interface UseCreateMemoryResult {\n createMemory: (memory: CreateMemoryRequest) => Promise<MemoryEntry | null>;\n loading: boolean;\n error: ApiErrorResponse | null;\n}\n\n/**\n * Hook to create new memories\n *\n * @example\n * ```tsx\n * function CreateMemoryForm() {\n * const { createMemory, loading, error } = useCreateMemory();\n * const [title, setTitle] = useState('');\n * const [content, setContent] = useState('');\n *\n * const handleSubmit = async (e: React.FormEvent) => {\n * e.preventDefault();\n * const memory = await createMemory({ title, content });\n * if (memory) {\n * console.log('Created:', memory.id);\n * setTitle('');\n * setContent('');\n * }\n * };\n *\n * return (\n * <form onSubmit={handleSubmit}>\n * <input value={title} onChange={e => setTitle(e.target.value)} />\n * <textarea value={content} onChange={e => setContent(e.target.value)} />\n * <button type=\"submit\" disabled={loading}>Create</button>\n * {error && <div>Error: {error.message}</div>}\n * </form>\n * );\n * }\n * ```\n */\nexport function useCreateMemory(): UseCreateMemoryResult {\n const client = useMemoryClient();\n const [loading, setLoading] = useState(false);\n const [error, setError] = useState<ApiErrorResponse | null>(null);\n\n const createMemory = useCallback(async (memory: CreateMemoryRequest): Promise<MemoryEntry | null> => {\n setLoading(true);\n setError(null);\n\n const result = await client.createMemory(memory);\n\n if (result.error) {\n setError(result.error);\n setLoading(false);\n return null;\n }\n\n setLoading(false);\n return result.data || null;\n }, [client]);\n\n return {\n createMemory,\n loading,\n error\n };\n}\n\n/**\n * Result type for search memories hook\n */\nexport interface UseSearchMemoriesResult {\n results: MemorySearchResult[];\n loading: boolean;\n error: ApiErrorResponse | null;\n search: (query: string, options?: Omit<SearchMemoryRequest, 'query'>) => Promise<void>;\n totalResults: number;\n searchTime: number;\n}\n\n/**\n * Hook to search memories with debouncing\n *\n * @example\n * ```tsx\n * function MemorySearch() {\n * const { results, loading, error, search } = useSearchMemories();\n * const [query, setQuery] = useState('');\n *\n * useEffect(() => {\n * if (query.length > 2) {\n * search(query, { limit: 10 });\n * }\n * }, [query, search]);\n *\n * return (\n * <div>\n * <input\n * value={query}\n * onChange={e => setQuery(e.target.value)}\n * placeholder=\"Search memories...\"\n * />\n * {loading && <div>Searching...</div>}\n * {error && <div>Error: {error.message}</div>}\n * {results.map(r => (\n * <div key={r.id}>\n * <h3>{r.title}</h3>\n * <span>Score: {r.similarity_score.toFixed(2)}</span>\n * </div>\n * ))}\n * </div>\n * );\n * }\n * ```\n */\nexport function useSearchMemories(debounceMs: number = 300): UseSearchMemoriesResult {\n const client = useMemoryClient();\n const [results, setResults] = useState<MemorySearchResult[]>([]);\n const [loading, setLoading] = useState(false);\n const [error, setError] = useState<ApiErrorResponse | null>(null);\n const [totalResults, setTotalResults] = useState(0);\n const [searchTime, setSearchTime] = useState(0);\n const debounceTimer = useRef<ReturnType<typeof setTimeout> | null>(null);\n\n const search = useCallback(async (query: string, options?: Omit<SearchMemoryRequest, 'query'>) => {\n // Clear existing timer\n if (debounceTimer.current) {\n clearTimeout(debounceTimer.current);\n }\n\n // Set new timer\n debounceTimer.current = setTimeout(async () => {\n setLoading(true);\n setError(null);\n\n const result = await client.searchMemories({\n query,\n status: options?.status ?? 'active',\n limit: options?.limit ?? 20,\n threshold: options?.threshold ?? 0.7,\n ...options\n });\n\n if (result.error) {\n setError(result.error);\n setResults([]);\n setTotalResults(0);\n setSearchTime(0);\n } else if (result.data) {\n setResults(result.data.results);\n setTotalResults(result.data.total_results);\n setSearchTime(result.data.search_time_ms);\n }\n\n setLoading(false);\n }, debounceMs);\n }, [client, debounceMs]);\n\n // Cleanup timer on unmount\n useEffect(() => {\n return () => {\n if (debounceTimer.current) {\n clearTimeout(debounceTimer.current);\n }\n };\n }, []);\n\n return {\n results,\n loading,\n error,\n search,\n totalResults,\n searchTime\n };\n}\n"],"names":[],"mappings":"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"}
|