@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.
@@ -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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"}