@lanonasis/memory-client 1.0.1 → 2.0.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.
@@ -0,0 +1,213 @@
1
+ import * as react from 'react';
2
+ import { ReactNode } from 'react';
3
+ import { CoreMemoryClientConfig, CoreMemoryClient, ApiError } from '../core/client';
4
+ export { ApiError, 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
+ * React Hooks for Memory Client
36
+ *
37
+ * Provides convenient React hooks for working with memories
38
+ */
39
+
40
+ /**
41
+ * Hook to access the Memory Client instance
42
+ *
43
+ * @throws Error if used outside of MemoryProvider
44
+ */
45
+ declare function useMemoryClient(): {};
46
+ /**
47
+ * Result type for list/search hooks
48
+ */
49
+ interface UseMemoriesResult {
50
+ memories: MemoryEntry[];
51
+ loading: boolean;
52
+ error: ApiError | null;
53
+ refresh: () => Promise<void>;
54
+ }
55
+ /**
56
+ * Hook to list memories with optional filtering
57
+ *
58
+ * @example
59
+ * ```tsx
60
+ * function MemoryList() {
61
+ * const { memories, loading, error, refresh } = useMemories({
62
+ * memory_type: 'project',
63
+ * limit: 20
64
+ * });
65
+ *
66
+ * if (loading) return <div>Loading...</div>;
67
+ * if (error) return <div>Error: {error.message}</div>;
68
+ *
69
+ * return (
70
+ * <div>
71
+ * {memories.map(m => <div key={m.id}>{m.title}</div>)}
72
+ * <button onClick={refresh}>Refresh</button>
73
+ * </div>
74
+ * );
75
+ * }
76
+ * ```
77
+ */
78
+ declare function useMemories(options?: {
79
+ page?: number;
80
+ limit?: number;
81
+ memory_type?: string;
82
+ topic_id?: string;
83
+ project_ref?: string;
84
+ status?: string;
85
+ tags?: string[];
86
+ sort?: string;
87
+ order?: 'asc' | 'desc';
88
+ }): UseMemoriesResult;
89
+ /**
90
+ * Result type for single memory hook
91
+ */
92
+ interface UseMemoryResult {
93
+ memory: MemoryEntry | null;
94
+ loading: boolean;
95
+ error: ApiError | null;
96
+ refresh: () => Promise<void>;
97
+ update: (updates: UpdateMemoryRequest) => Promise<void>;
98
+ deleteMemory: () => Promise<void>;
99
+ }
100
+ /**
101
+ * Hook to fetch and manage a single memory by ID
102
+ *
103
+ * @example
104
+ * ```tsx
105
+ * function MemoryDetail({ id }: { id: string }) {
106
+ * const { memory, loading, error, update, deleteMemory } = useMemory(id);
107
+ *
108
+ * if (loading) return <div>Loading...</div>;
109
+ * if (error) return <div>Error: {error.message}</div>;
110
+ * if (!memory) return <div>Memory not found</div>;
111
+ *
112
+ * return (
113
+ * <div>
114
+ * <h1>{memory.title}</h1>
115
+ * <p>{memory.content}</p>
116
+ * <button onClick={() => update({ title: 'Updated Title' })}>Update</button>
117
+ * <button onClick={deleteMemory}>Delete</button>
118
+ * </div>
119
+ * );
120
+ * }
121
+ * ```
122
+ */
123
+ declare function useMemory(id: string): UseMemoryResult;
124
+ /**
125
+ * Result type for create memory hook
126
+ */
127
+ interface UseCreateMemoryResult {
128
+ createMemory: (memory: CreateMemoryRequest) => Promise<MemoryEntry | null>;
129
+ loading: boolean;
130
+ error: ApiError | null;
131
+ }
132
+ /**
133
+ * Hook to create new memories
134
+ *
135
+ * @example
136
+ * ```tsx
137
+ * function CreateMemoryForm() {
138
+ * const { createMemory, loading, error } = useCreateMemory();
139
+ * const [title, setTitle] = useState('');
140
+ * const [content, setContent] = useState('');
141
+ *
142
+ * const handleSubmit = async (e: React.FormEvent) => {
143
+ * e.preventDefault();
144
+ * const memory = await createMemory({ title, content });
145
+ * if (memory) {
146
+ * console.log('Created:', memory.id);
147
+ * setTitle('');
148
+ * setContent('');
149
+ * }
150
+ * };
151
+ *
152
+ * return (
153
+ * <form onSubmit={handleSubmit}>
154
+ * <input value={title} onChange={e => setTitle(e.target.value)} />
155
+ * <textarea value={content} onChange={e => setContent(e.target.value)} />
156
+ * <button type="submit" disabled={loading}>Create</button>
157
+ * {error && <div>Error: {error.message}</div>}
158
+ * </form>
159
+ * );
160
+ * }
161
+ * ```
162
+ */
163
+ declare function useCreateMemory(): UseCreateMemoryResult;
164
+ /**
165
+ * Result type for search memories hook
166
+ */
167
+ interface UseSearchMemoriesResult {
168
+ results: MemorySearchResult[];
169
+ loading: boolean;
170
+ error: ApiError | null;
171
+ search: (query: string, options?: Omit<SearchMemoryRequest, 'query'>) => Promise<void>;
172
+ totalResults: number;
173
+ searchTime: number;
174
+ }
175
+ /**
176
+ * Hook to search memories with debouncing
177
+ *
178
+ * @example
179
+ * ```tsx
180
+ * function MemorySearch() {
181
+ * const { results, loading, error, search } = useSearchMemories();
182
+ * const [query, setQuery] = useState('');
183
+ *
184
+ * useEffect(() => {
185
+ * if (query.length > 2) {
186
+ * search(query, { limit: 10 });
187
+ * }
188
+ * }, [query, search]);
189
+ *
190
+ * return (
191
+ * <div>
192
+ * <input
193
+ * value={query}
194
+ * onChange={e => setQuery(e.target.value)}
195
+ * placeholder="Search memories..."
196
+ * />
197
+ * {loading && <div>Searching...</div>}
198
+ * {error && <div>Error: {error.message}</div>}
199
+ * {results.map(r => (
200
+ * <div key={r.id}>
201
+ * <h3>{r.title}</h3>
202
+ * <span>Score: {r.similarity_score.toFixed(2)}</span>
203
+ * </div>
204
+ * ))}
205
+ * </div>
206
+ * );
207
+ * }
208
+ * ```
209
+ */
210
+ declare function useSearchMemories(debounceMs?: number): UseSearchMemoriesResult;
211
+
212
+ export { MemoryContext, MemoryProvider, useCreateMemory, useMemories, useMemory, useMemoryClient, useSearchMemories };
213
+ export type { MemoryProviderProps, UseCreateMemoryResult, UseMemoriesResult, UseMemoryResult, UseSearchMemoriesResult };
@@ -0,0 +1,348 @@
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({
91
+ message: result.error,
92
+ code: 'API_ERROR'
93
+ });
94
+ setMemories([]);
95
+ }
96
+ else if (result.data) {
97
+ setMemories(result.data.data);
98
+ }
99
+ setLoading(false);
100
+ }, [client, JSON.stringify(options)]);
101
+ useEffect(() => {
102
+ loadMemories();
103
+ }, [loadMemories]);
104
+ return {
105
+ memories,
106
+ loading,
107
+ error,
108
+ refresh: loadMemories
109
+ };
110
+ }
111
+ /**
112
+ * Hook to fetch and manage a single memory by ID
113
+ *
114
+ * @example
115
+ * ```tsx
116
+ * function MemoryDetail({ id }: { id: string }) {
117
+ * const { memory, loading, error, update, deleteMemory } = useMemory(id);
118
+ *
119
+ * if (loading) return <div>Loading...</div>;
120
+ * if (error) return <div>Error: {error.message}</div>;
121
+ * if (!memory) return <div>Memory not found</div>;
122
+ *
123
+ * return (
124
+ * <div>
125
+ * <h1>{memory.title}</h1>
126
+ * <p>{memory.content}</p>
127
+ * <button onClick={() => update({ title: 'Updated Title' })}>Update</button>
128
+ * <button onClick={deleteMemory}>Delete</button>
129
+ * </div>
130
+ * );
131
+ * }
132
+ * ```
133
+ */
134
+ function useMemory(id) {
135
+ const client = useMemoryClient();
136
+ const [memory, setMemory] = useState(null);
137
+ const [loading, setLoading] = useState(true);
138
+ const [error, setError] = useState(null);
139
+ const loadMemory = useCallback(async () => {
140
+ if (!id) {
141
+ setMemory(null);
142
+ setLoading(false);
143
+ return;
144
+ }
145
+ setLoading(true);
146
+ setError(null);
147
+ const result = await client.getMemory(id);
148
+ if (result.error) {
149
+ setError({
150
+ message: result.error,
151
+ code: 'API_ERROR'
152
+ });
153
+ setMemory(null);
154
+ }
155
+ else if (result.data) {
156
+ setMemory(result.data);
157
+ }
158
+ setLoading(false);
159
+ }, [client, id]);
160
+ useEffect(() => {
161
+ loadMemory();
162
+ }, [loadMemory]);
163
+ const update = useCallback(async (updates) => {
164
+ if (!id)
165
+ return;
166
+ const result = await client.updateMemory(id, updates);
167
+ if (result.error) {
168
+ setError({
169
+ message: result.error,
170
+ code: 'API_ERROR'
171
+ });
172
+ }
173
+ else if (result.data) {
174
+ setMemory(result.data);
175
+ }
176
+ }, [client, id]);
177
+ const deleteMemory = useCallback(async () => {
178
+ if (!id)
179
+ return;
180
+ const result = await client.deleteMemory(id);
181
+ if (result.error) {
182
+ setError({
183
+ message: result.error,
184
+ code: 'API_ERROR'
185
+ });
186
+ }
187
+ else {
188
+ setMemory(null);
189
+ }
190
+ }, [client, id]);
191
+ return {
192
+ memory,
193
+ loading,
194
+ error,
195
+ refresh: loadMemory,
196
+ update,
197
+ deleteMemory
198
+ };
199
+ }
200
+ /**
201
+ * Hook to create new memories
202
+ *
203
+ * @example
204
+ * ```tsx
205
+ * function CreateMemoryForm() {
206
+ * const { createMemory, loading, error } = useCreateMemory();
207
+ * const [title, setTitle] = useState('');
208
+ * const [content, setContent] = useState('');
209
+ *
210
+ * const handleSubmit = async (e: React.FormEvent) => {
211
+ * e.preventDefault();
212
+ * const memory = await createMemory({ title, content });
213
+ * if (memory) {
214
+ * console.log('Created:', memory.id);
215
+ * setTitle('');
216
+ * setContent('');
217
+ * }
218
+ * };
219
+ *
220
+ * return (
221
+ * <form onSubmit={handleSubmit}>
222
+ * <input value={title} onChange={e => setTitle(e.target.value)} />
223
+ * <textarea value={content} onChange={e => setContent(e.target.value)} />
224
+ * <button type="submit" disabled={loading}>Create</button>
225
+ * {error && <div>Error: {error.message}</div>}
226
+ * </form>
227
+ * );
228
+ * }
229
+ * ```
230
+ */
231
+ function useCreateMemory() {
232
+ const client = useMemoryClient();
233
+ const [loading, setLoading] = useState(false);
234
+ const [error, setError] = useState(null);
235
+ const createMemory = useCallback(async (memory) => {
236
+ setLoading(true);
237
+ setError(null);
238
+ const result = await client.createMemory(memory);
239
+ if (result.error) {
240
+ setError({
241
+ message: result.error,
242
+ code: 'API_ERROR'
243
+ });
244
+ setLoading(false);
245
+ return null;
246
+ }
247
+ setLoading(false);
248
+ return result.data || null;
249
+ }, [client]);
250
+ return {
251
+ createMemory,
252
+ loading,
253
+ error
254
+ };
255
+ }
256
+ /**
257
+ * Hook to search memories with debouncing
258
+ *
259
+ * @example
260
+ * ```tsx
261
+ * function MemorySearch() {
262
+ * const { results, loading, error, search } = useSearchMemories();
263
+ * const [query, setQuery] = useState('');
264
+ *
265
+ * useEffect(() => {
266
+ * if (query.length > 2) {
267
+ * search(query, { limit: 10 });
268
+ * }
269
+ * }, [query, search]);
270
+ *
271
+ * return (
272
+ * <div>
273
+ * <input
274
+ * value={query}
275
+ * onChange={e => setQuery(e.target.value)}
276
+ * placeholder="Search memories..."
277
+ * />
278
+ * {loading && <div>Searching...</div>}
279
+ * {error && <div>Error: {error.message}</div>}
280
+ * {results.map(r => (
281
+ * <div key={r.id}>
282
+ * <h3>{r.title}</h3>
283
+ * <span>Score: {r.similarity_score.toFixed(2)}</span>
284
+ * </div>
285
+ * ))}
286
+ * </div>
287
+ * );
288
+ * }
289
+ * ```
290
+ */
291
+ function useSearchMemories(debounceMs = 300) {
292
+ const client = useMemoryClient();
293
+ const [results, setResults] = useState([]);
294
+ const [loading, setLoading] = useState(false);
295
+ const [error, setError] = useState(null);
296
+ const [totalResults, setTotalResults] = useState(0);
297
+ const [searchTime, setSearchTime] = useState(0);
298
+ const debounceTimer = useRef(null);
299
+ const search = useCallback(async (query, options) => {
300
+ // Clear existing timer
301
+ if (debounceTimer.current) {
302
+ clearTimeout(debounceTimer.current);
303
+ }
304
+ // Set new timer
305
+ debounceTimer.current = setTimeout(async () => {
306
+ setLoading(true);
307
+ setError(null);
308
+ const result = await client.searchMemories({
309
+ query,
310
+ ...options
311
+ });
312
+ if (result.error) {
313
+ setError({
314
+ message: result.error,
315
+ code: 'API_ERROR'
316
+ });
317
+ setResults([]);
318
+ setTotalResults(0);
319
+ setSearchTime(0);
320
+ }
321
+ else if (result.data) {
322
+ setResults(result.data.results);
323
+ setTotalResults(result.data.total_results);
324
+ setSearchTime(result.data.search_time_ms);
325
+ }
326
+ setLoading(false);
327
+ }, debounceMs);
328
+ }, [client, debounceMs]);
329
+ // Cleanup timer on unmount
330
+ useEffect(() => {
331
+ return () => {
332
+ if (debounceTimer.current) {
333
+ clearTimeout(debounceTimer.current);
334
+ }
335
+ };
336
+ }, []);
337
+ return {
338
+ results,
339
+ loading,
340
+ error,
341
+ search,
342
+ totalResults,
343
+ searchTime
344
+ };
345
+ }
346
+
347
+ export { MemoryContext, MemoryProvider, useCreateMemory, useMemories, useMemory, useMemoryClient, useSearchMemories };
348
+ //# 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 { ApiError } from '../core/client';\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: ApiError | 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<ApiError | 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({\n message: result.error,\n code: 'API_ERROR'\n });\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: ApiError | 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<ApiError | 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({\n message: result.error,\n code: 'API_ERROR'\n });\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({\n message: result.error,\n code: 'API_ERROR'\n });\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({\n message: result.error,\n code: 'API_ERROR'\n });\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: ApiError | 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<ApiError | 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({\n message: result.error,\n code: 'API_ERROR'\n });\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: ApiError | 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<ApiError | null>(null);\n const [totalResults, setTotalResults] = useState(0);\n const [searchTime, setSearchTime] = useState(0);\n const debounceTimer = useRef<NodeJS.Timeout | 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 ...options\n });\n\n if (result.error) {\n setError({\n message: result.error,\n code: 'API_ERROR'\n });\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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"}