@vaiftech/sdk-expo 1.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.
- package/LICENSE +21 -0
- package/README.md +238 -0
- package/dist/index.d.mts +696 -0
- package/dist/index.d.ts +696 -0
- package/dist/index.js +1 -0
- package/dist/index.mjs +1 -0
- package/package.json +67 -0
package/dist/index.d.mts
ADDED
|
@@ -0,0 +1,696 @@
|
|
|
1
|
+
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
2
|
+
import { ReactNode } from 'react';
|
|
3
|
+
import { VaifClientConfig, User, VaifClient, AuthResponse, QueryOptions, WhereFilter, OrderByClause, DbOperation, SubscriptionFilter, DbChangeEvent, ConnectionState, PresenceState, PresenceEntry, UploadResult, FileMetadata, RetryConfig, VaifFunction } from '@vaif/client';
|
|
4
|
+
export { AuthResponse, ConnectionState, DbChangeEvent, DbOperation, FileMetadata, InvokeResult, OrderByClause, PresenceState, QueryOptions, UploadResult, User, VaifClient, VaifClientConfig, VaifFunction, WhereFilter } from '@vaif/client';
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Storage interface for React Native (AsyncStorage compatible)
|
|
8
|
+
*/
|
|
9
|
+
interface AsyncStorageInterface {
|
|
10
|
+
getItem(key: string): Promise<string | null>;
|
|
11
|
+
setItem(key: string, value: string): Promise<void>;
|
|
12
|
+
removeItem(key: string): Promise<void>;
|
|
13
|
+
}
|
|
14
|
+
interface VaifContextValue {
|
|
15
|
+
/** The VAIF client instance */
|
|
16
|
+
client: VaifClient;
|
|
17
|
+
/** Current authenticated user (null if not authenticated) */
|
|
18
|
+
user: User | null;
|
|
19
|
+
/** Current access token */
|
|
20
|
+
token: string | null;
|
|
21
|
+
/** Whether authentication is being checked */
|
|
22
|
+
isLoading: boolean;
|
|
23
|
+
/** Whether user is authenticated */
|
|
24
|
+
isAuthenticated: boolean;
|
|
25
|
+
/** Sign in with email/password */
|
|
26
|
+
signIn: (email: string, password: string) => Promise<AuthResponse>;
|
|
27
|
+
/** Sign up with email/password */
|
|
28
|
+
signUp: (email: string, password: string, metadata?: Record<string, unknown>) => Promise<AuthResponse>;
|
|
29
|
+
/** Sign out the current user */
|
|
30
|
+
signOut: () => Promise<void>;
|
|
31
|
+
/** Refresh the session */
|
|
32
|
+
refreshSession: () => Promise<void>;
|
|
33
|
+
/** Update the current user in state */
|
|
34
|
+
updateUser: (updates: Partial<User>) => void;
|
|
35
|
+
}
|
|
36
|
+
interface VaifProviderProps {
|
|
37
|
+
/** VAIF client configuration */
|
|
38
|
+
config: VaifClientConfig;
|
|
39
|
+
/** Child components */
|
|
40
|
+
children: ReactNode;
|
|
41
|
+
/** AsyncStorage instance (from @react-native-async-storage/async-storage) */
|
|
42
|
+
storage?: AsyncStorageInterface;
|
|
43
|
+
/** Callback when auth state changes */
|
|
44
|
+
onAuthStateChange?: (user: User | null) => void;
|
|
45
|
+
/** Auto refresh session before expiry (default: true) */
|
|
46
|
+
autoRefreshSession?: boolean;
|
|
47
|
+
/** Storage key for session persistence (default: 'vaif-auth') */
|
|
48
|
+
storageKey?: string;
|
|
49
|
+
}
|
|
50
|
+
declare function VaifProvider({ config, children, storage, onAuthStateChange, autoRefreshSession, storageKey, }: VaifProviderProps): react_jsx_runtime.JSX.Element;
|
|
51
|
+
/**
|
|
52
|
+
* Access the VAIF context
|
|
53
|
+
*
|
|
54
|
+
* @throws Error if used outside VaifProvider
|
|
55
|
+
*/
|
|
56
|
+
declare function useVaif(): VaifContextValue;
|
|
57
|
+
/**
|
|
58
|
+
* Access only the VAIF client (lightweight alternative to useVaif)
|
|
59
|
+
*/
|
|
60
|
+
declare function useVaifClient(): VaifClient;
|
|
61
|
+
|
|
62
|
+
interface UseAuthReturn {
|
|
63
|
+
user: User | null;
|
|
64
|
+
isLoading: boolean;
|
|
65
|
+
isAuthenticated: boolean;
|
|
66
|
+
token: string | null;
|
|
67
|
+
signIn: (email: string, password: string) => Promise<AuthResponse>;
|
|
68
|
+
signUp: (email: string, password: string, metadata?: Record<string, unknown>) => Promise<AuthResponse>;
|
|
69
|
+
signOut: () => Promise<void>;
|
|
70
|
+
refreshSession: () => Promise<void>;
|
|
71
|
+
updateProfile: (updates: Record<string, unknown>) => Promise<User>;
|
|
72
|
+
changePassword: (currentPassword: string, newPassword: string) => Promise<void>;
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* Hook for authentication
|
|
76
|
+
*
|
|
77
|
+
* @example
|
|
78
|
+
* ```tsx
|
|
79
|
+
* function LoginScreen() {
|
|
80
|
+
* const { signIn, isLoading, user } = useAuth();
|
|
81
|
+
*
|
|
82
|
+
* const handleLogin = async () => {
|
|
83
|
+
* await signIn('user@example.com', 'password');
|
|
84
|
+
* };
|
|
85
|
+
*
|
|
86
|
+
* if (user) {
|
|
87
|
+
* return <Text>Welcome, {user.email}!</Text>;
|
|
88
|
+
* }
|
|
89
|
+
*
|
|
90
|
+
* return (
|
|
91
|
+
* <Button onPress={handleLogin} disabled={isLoading}>
|
|
92
|
+
* {isLoading ? 'Signing in...' : 'Sign In'}
|
|
93
|
+
* </Button>
|
|
94
|
+
* );
|
|
95
|
+
* }
|
|
96
|
+
* ```
|
|
97
|
+
*/
|
|
98
|
+
declare function useAuth(): UseAuthReturn;
|
|
99
|
+
/**
|
|
100
|
+
* Hook to get just the current user
|
|
101
|
+
*/
|
|
102
|
+
declare function useUser(): User | null;
|
|
103
|
+
|
|
104
|
+
type QueryStatus = "idle" | "loading" | "success" | "error";
|
|
105
|
+
interface UseQueryOptions extends Omit<QueryOptions, "where" | "orderBy"> {
|
|
106
|
+
/** Where conditions */
|
|
107
|
+
where?: WhereFilter | WhereFilter[];
|
|
108
|
+
/** Order by clauses */
|
|
109
|
+
orderBy?: OrderByClause | OrderByClause[];
|
|
110
|
+
/** Skip fetching */
|
|
111
|
+
enabled?: boolean;
|
|
112
|
+
/** Refetch interval in ms */
|
|
113
|
+
refetchInterval?: number;
|
|
114
|
+
}
|
|
115
|
+
interface UseQueryReturn<T> {
|
|
116
|
+
data: T[];
|
|
117
|
+
status: QueryStatus;
|
|
118
|
+
isLoading: boolean;
|
|
119
|
+
isError: boolean;
|
|
120
|
+
isSuccess: boolean;
|
|
121
|
+
error: Error | null;
|
|
122
|
+
refetch: () => Promise<void>;
|
|
123
|
+
}
|
|
124
|
+
interface UsePaginatedQueryOptions extends UseQueryOptions {
|
|
125
|
+
pageSize?: number;
|
|
126
|
+
initialPage?: number;
|
|
127
|
+
}
|
|
128
|
+
interface UsePaginatedQueryReturn<T> extends UseQueryReturn<T> {
|
|
129
|
+
page: number;
|
|
130
|
+
pageSize: number;
|
|
131
|
+
totalPages: number;
|
|
132
|
+
totalCount: number;
|
|
133
|
+
hasNextPage: boolean;
|
|
134
|
+
hasPreviousPage: boolean;
|
|
135
|
+
nextPage: () => void;
|
|
136
|
+
previousPage: () => void;
|
|
137
|
+
goToPage: (page: number) => void;
|
|
138
|
+
}
|
|
139
|
+
/**
|
|
140
|
+
* Hook for querying data from a table
|
|
141
|
+
*
|
|
142
|
+
* @example
|
|
143
|
+
* ```tsx
|
|
144
|
+
* function TaskList() {
|
|
145
|
+
* const { data: tasks, isLoading, error, refetch } = useQuery<Task>('tasks', {
|
|
146
|
+
* where: { status: 'active' },
|
|
147
|
+
* orderBy: { column: 'created_at', direction: 'desc' },
|
|
148
|
+
* limit: 20,
|
|
149
|
+
* });
|
|
150
|
+
*
|
|
151
|
+
* if (isLoading) return <ActivityIndicator />;
|
|
152
|
+
* if (error) return <Text>Error: {error.message}</Text>;
|
|
153
|
+
*
|
|
154
|
+
* return (
|
|
155
|
+
* <FlatList
|
|
156
|
+
* data={tasks}
|
|
157
|
+
* keyExtractor={(item) => item.id}
|
|
158
|
+
* renderItem={({ item }) => <TaskItem task={item} />}
|
|
159
|
+
* onRefresh={refetch}
|
|
160
|
+
* />
|
|
161
|
+
* );
|
|
162
|
+
* }
|
|
163
|
+
* ```
|
|
164
|
+
*/
|
|
165
|
+
declare function useQuery<T extends Record<string, unknown> = Record<string, unknown>>(table: string, options?: UseQueryOptions): UseQueryReturn<T>;
|
|
166
|
+
/**
|
|
167
|
+
* Hook for fetching a single record by ID
|
|
168
|
+
*/
|
|
169
|
+
declare function useQueryById<T extends Record<string, unknown> = Record<string, unknown>>(table: string, id: string | undefined, options?: {
|
|
170
|
+
enabled?: boolean;
|
|
171
|
+
}): {
|
|
172
|
+
data: T | null;
|
|
173
|
+
isLoading: boolean;
|
|
174
|
+
isError: boolean;
|
|
175
|
+
error: Error | null;
|
|
176
|
+
refetch: () => Promise<void>;
|
|
177
|
+
};
|
|
178
|
+
/**
|
|
179
|
+
* Hook for paginated queries
|
|
180
|
+
*/
|
|
181
|
+
declare function usePaginatedQuery<T extends Record<string, unknown> = Record<string, unknown>>(table: string, options?: UsePaginatedQueryOptions): UsePaginatedQueryReturn<T>;
|
|
182
|
+
|
|
183
|
+
type MutationStatus = "idle" | "loading" | "success" | "error";
|
|
184
|
+
interface UseMutationReturn<T, TInput = Partial<T>> {
|
|
185
|
+
mutate: (input: TInput) => Promise<T | null>;
|
|
186
|
+
data: T | null;
|
|
187
|
+
status: MutationStatus;
|
|
188
|
+
isLoading: boolean;
|
|
189
|
+
isError: boolean;
|
|
190
|
+
isSuccess: boolean;
|
|
191
|
+
error: Error | null;
|
|
192
|
+
reset: () => void;
|
|
193
|
+
}
|
|
194
|
+
interface UseCreateReturn<T> extends UseMutationReturn<T, Partial<T>> {
|
|
195
|
+
create: (data: Partial<T>) => Promise<T | null>;
|
|
196
|
+
}
|
|
197
|
+
interface UseUpdateReturn<T> {
|
|
198
|
+
update: (id: string, data: Partial<T>) => Promise<T | null>;
|
|
199
|
+
data: T | null;
|
|
200
|
+
status: MutationStatus;
|
|
201
|
+
isLoading: boolean;
|
|
202
|
+
isError: boolean;
|
|
203
|
+
error: Error | null;
|
|
204
|
+
reset: () => void;
|
|
205
|
+
}
|
|
206
|
+
interface UseDeleteReturn {
|
|
207
|
+
remove: (id: string) => Promise<boolean>;
|
|
208
|
+
status: MutationStatus;
|
|
209
|
+
isLoading: boolean;
|
|
210
|
+
isError: boolean;
|
|
211
|
+
error: Error | null;
|
|
212
|
+
reset: () => void;
|
|
213
|
+
}
|
|
214
|
+
interface UseUpsertReturn<T> {
|
|
215
|
+
upsert: (data: Partial<T>, conflictFields: string[]) => Promise<T | null>;
|
|
216
|
+
data: T | null;
|
|
217
|
+
status: MutationStatus;
|
|
218
|
+
isLoading: boolean;
|
|
219
|
+
isError: boolean;
|
|
220
|
+
error: Error | null;
|
|
221
|
+
reset: () => void;
|
|
222
|
+
}
|
|
223
|
+
/**
|
|
224
|
+
* Hook for creating records
|
|
225
|
+
*
|
|
226
|
+
* @example
|
|
227
|
+
* ```tsx
|
|
228
|
+
* function CreateTask() {
|
|
229
|
+
* const { create, isLoading, error } = useCreate<Task>('tasks');
|
|
230
|
+
*
|
|
231
|
+
* const handleCreate = async () => {
|
|
232
|
+
* const task = await create({ title: 'New Task', status: 'pending' });
|
|
233
|
+
* if (task) {
|
|
234
|
+
* console.log('Created:', task.id);
|
|
235
|
+
* }
|
|
236
|
+
* };
|
|
237
|
+
*
|
|
238
|
+
* return (
|
|
239
|
+
* <Button onPress={handleCreate} disabled={isLoading}>
|
|
240
|
+
* Create Task
|
|
241
|
+
* </Button>
|
|
242
|
+
* );
|
|
243
|
+
* }
|
|
244
|
+
* ```
|
|
245
|
+
*/
|
|
246
|
+
declare function useCreate<T extends Record<string, unknown> = Record<string, unknown>>(table: string): UseCreateReturn<T>;
|
|
247
|
+
/**
|
|
248
|
+
* Hook for updating records
|
|
249
|
+
*
|
|
250
|
+
* @example
|
|
251
|
+
* ```tsx
|
|
252
|
+
* function UpdateTask({ taskId }: { taskId: string }) {
|
|
253
|
+
* const { update, isLoading } = useUpdate<Task>('tasks');
|
|
254
|
+
*
|
|
255
|
+
* const handleComplete = async () => {
|
|
256
|
+
* await update(taskId, { status: 'completed' });
|
|
257
|
+
* };
|
|
258
|
+
*
|
|
259
|
+
* return (
|
|
260
|
+
* <Button onPress={handleComplete} disabled={isLoading}>
|
|
261
|
+
* Mark Complete
|
|
262
|
+
* </Button>
|
|
263
|
+
* );
|
|
264
|
+
* }
|
|
265
|
+
* ```
|
|
266
|
+
*/
|
|
267
|
+
declare function useUpdate<T extends Record<string, unknown> = Record<string, unknown>>(table: string): UseUpdateReturn<T>;
|
|
268
|
+
/**
|
|
269
|
+
* Hook for deleting records
|
|
270
|
+
*
|
|
271
|
+
* @example
|
|
272
|
+
* ```tsx
|
|
273
|
+
* function DeleteTask({ taskId }: { taskId: string }) {
|
|
274
|
+
* const { remove, isLoading } = useDelete('tasks');
|
|
275
|
+
*
|
|
276
|
+
* const handleDelete = async () => {
|
|
277
|
+
* const success = await remove(taskId);
|
|
278
|
+
* if (success) {
|
|
279
|
+
* console.log('Deleted!');
|
|
280
|
+
* }
|
|
281
|
+
* };
|
|
282
|
+
*
|
|
283
|
+
* return (
|
|
284
|
+
* <Button onPress={handleDelete} disabled={isLoading}>
|
|
285
|
+
* Delete
|
|
286
|
+
* </Button>
|
|
287
|
+
* );
|
|
288
|
+
* }
|
|
289
|
+
* ```
|
|
290
|
+
*/
|
|
291
|
+
declare function useDelete(table: string): UseDeleteReturn;
|
|
292
|
+
/**
|
|
293
|
+
* Hook for upserting records
|
|
294
|
+
*
|
|
295
|
+
* @example
|
|
296
|
+
* ```tsx
|
|
297
|
+
* function UpsertUser({ userId }: { userId: string }) {
|
|
298
|
+
* const { upsert, isLoading } = useUpsert<User>('users');
|
|
299
|
+
*
|
|
300
|
+
* const handleUpsert = async () => {
|
|
301
|
+
* await upsert(
|
|
302
|
+
* { id: userId, name: 'John', email: 'john@example.com' },
|
|
303
|
+
* ['id']
|
|
304
|
+
* );
|
|
305
|
+
* };
|
|
306
|
+
*
|
|
307
|
+
* return (
|
|
308
|
+
* <Button onPress={handleUpsert} disabled={isLoading}>
|
|
309
|
+
* Save
|
|
310
|
+
* </Button>
|
|
311
|
+
* );
|
|
312
|
+
* }
|
|
313
|
+
* ```
|
|
314
|
+
*/
|
|
315
|
+
declare function useUpsert<T extends Record<string, unknown> = Record<string, unknown>>(table: string): UseUpsertReturn<T>;
|
|
316
|
+
/**
|
|
317
|
+
* Hook for batch creating records
|
|
318
|
+
*/
|
|
319
|
+
declare function useBatchCreate<T extends Record<string, unknown> = Record<string, unknown>>(table: string): {
|
|
320
|
+
createMany: (items: Partial<T>[]) => Promise<T[]>;
|
|
321
|
+
data: T[];
|
|
322
|
+
isLoading: boolean;
|
|
323
|
+
isError: boolean;
|
|
324
|
+
error: Error | null;
|
|
325
|
+
};
|
|
326
|
+
|
|
327
|
+
interface UseSubscriptionOptions<T> {
|
|
328
|
+
/** Filter by operation type */
|
|
329
|
+
event?: DbOperation | DbOperation[];
|
|
330
|
+
/** Filter condition */
|
|
331
|
+
filter?: SubscriptionFilter | SubscriptionFilter[];
|
|
332
|
+
/** Callback when record is inserted */
|
|
333
|
+
onInsert?: (record: T) => void;
|
|
334
|
+
/** Callback when record is updated */
|
|
335
|
+
onUpdate?: (record: T, old: T | null) => void;
|
|
336
|
+
/** Callback when record is deleted */
|
|
337
|
+
onDelete?: (old: T) => void;
|
|
338
|
+
/** Callback for any change */
|
|
339
|
+
onChange?: (event: DbChangeEvent<T>) => void;
|
|
340
|
+
/** Skip subscription */
|
|
341
|
+
enabled?: boolean;
|
|
342
|
+
}
|
|
343
|
+
interface UseSubscriptionReturn {
|
|
344
|
+
isConnected: boolean;
|
|
345
|
+
connectionState: ConnectionState;
|
|
346
|
+
unsubscribe: () => void;
|
|
347
|
+
}
|
|
348
|
+
interface UsePresenceOptions<T extends PresenceState> {
|
|
349
|
+
/** Initial presence state */
|
|
350
|
+
initialState?: T;
|
|
351
|
+
}
|
|
352
|
+
interface UsePresenceReturn<T extends PresenceState> {
|
|
353
|
+
/** Current presence state for all users */
|
|
354
|
+
presences: PresenceEntry<T>[];
|
|
355
|
+
/** Track your own presence */
|
|
356
|
+
track: (state: T) => void;
|
|
357
|
+
/** Update your presence */
|
|
358
|
+
update: (state: Partial<T>) => void;
|
|
359
|
+
/** Untrack your presence */
|
|
360
|
+
untrack: () => void;
|
|
361
|
+
/** Connection state */
|
|
362
|
+
isConnected: boolean;
|
|
363
|
+
}
|
|
364
|
+
interface UseBroadcastReturn<T> {
|
|
365
|
+
/** Send a broadcast message */
|
|
366
|
+
broadcast: (event: string, payload: T) => void;
|
|
367
|
+
/** Last received message */
|
|
368
|
+
lastMessage: {
|
|
369
|
+
event: string;
|
|
370
|
+
payload: T;
|
|
371
|
+
} | null;
|
|
372
|
+
/** Subscribe to specific event */
|
|
373
|
+
subscribe: (event: string, handler: (payload: T) => void) => () => void;
|
|
374
|
+
/** Connection state */
|
|
375
|
+
isConnected: boolean;
|
|
376
|
+
}
|
|
377
|
+
/**
|
|
378
|
+
* Hook for realtime database subscriptions
|
|
379
|
+
*
|
|
380
|
+
* @example
|
|
381
|
+
* ```tsx
|
|
382
|
+
* function TaskList() {
|
|
383
|
+
* const [tasks, setTasks] = useState<Task[]>([]);
|
|
384
|
+
*
|
|
385
|
+
* useSubscription<Task>('tasks', {
|
|
386
|
+
* onInsert: (task) => setTasks(prev => [...prev, task]),
|
|
387
|
+
* onUpdate: (task) => setTasks(prev =>
|
|
388
|
+
* prev.map(t => t.id === task.id ? task : t)
|
|
389
|
+
* ),
|
|
390
|
+
* onDelete: (task) => setTasks(prev =>
|
|
391
|
+
* prev.filter(t => t.id !== task.id)
|
|
392
|
+
* ),
|
|
393
|
+
* });
|
|
394
|
+
*
|
|
395
|
+
* return <FlatList data={tasks} ... />;
|
|
396
|
+
* }
|
|
397
|
+
* ```
|
|
398
|
+
*/
|
|
399
|
+
declare function useSubscription<T = unknown>(table: string, options?: UseSubscriptionOptions<T>): UseSubscriptionReturn;
|
|
400
|
+
/**
|
|
401
|
+
* Hook for presence tracking
|
|
402
|
+
*
|
|
403
|
+
* @example
|
|
404
|
+
* ```tsx
|
|
405
|
+
* function OnlineUsers() {
|
|
406
|
+
* const { presences, track } = usePresence<{ name: string; status: string }>('room-1');
|
|
407
|
+
*
|
|
408
|
+
* useEffect(() => {
|
|
409
|
+
* track({ name: 'John', status: 'online' });
|
|
410
|
+
* }, []);
|
|
411
|
+
*
|
|
412
|
+
* return (
|
|
413
|
+
* <View>
|
|
414
|
+
* {presences.map((p) => (
|
|
415
|
+
* <Text key={p.connectionId}>{p.state.name}: {p.state.status}</Text>
|
|
416
|
+
* ))}
|
|
417
|
+
* </View>
|
|
418
|
+
* );
|
|
419
|
+
* }
|
|
420
|
+
* ```
|
|
421
|
+
*/
|
|
422
|
+
declare function usePresence<T extends PresenceState = PresenceState>(channelName: string, options?: UsePresenceOptions<T>): UsePresenceReturn<T>;
|
|
423
|
+
/**
|
|
424
|
+
* Hook for broadcast messaging
|
|
425
|
+
*
|
|
426
|
+
* @example
|
|
427
|
+
* ```tsx
|
|
428
|
+
* function Chat() {
|
|
429
|
+
* const { broadcast, subscribe } = useBroadcast<{ text: string }>('chat-room');
|
|
430
|
+
* const [messages, setMessages] = useState<string[]>([]);
|
|
431
|
+
*
|
|
432
|
+
* useEffect(() => {
|
|
433
|
+
* const unsubscribe = subscribe('message', (payload) => {
|
|
434
|
+
* setMessages(prev => [...prev, payload.text]);
|
|
435
|
+
* });
|
|
436
|
+
* return unsubscribe;
|
|
437
|
+
* }, [subscribe]);
|
|
438
|
+
*
|
|
439
|
+
* const sendMessage = (text: string) => {
|
|
440
|
+
* broadcast('message', { text });
|
|
441
|
+
* };
|
|
442
|
+
*
|
|
443
|
+
* return <ChatUI messages={messages} onSend={sendMessage} />;
|
|
444
|
+
* }
|
|
445
|
+
* ```
|
|
446
|
+
*/
|
|
447
|
+
declare function useBroadcast<T = unknown>(channelName: string): UseBroadcastReturn<T>;
|
|
448
|
+
/**
|
|
449
|
+
* Hook for realtime connection state
|
|
450
|
+
*/
|
|
451
|
+
declare function useRealtimeConnection(): {
|
|
452
|
+
connectionState: ConnectionState;
|
|
453
|
+
isConnected: boolean;
|
|
454
|
+
reconnect: () => void;
|
|
455
|
+
disconnect: () => void;
|
|
456
|
+
};
|
|
457
|
+
|
|
458
|
+
interface UseUploadReturn {
|
|
459
|
+
upload: (file: Blob | ArrayBuffer, path: string, options?: UploadOptions) => Promise<UploadResult | null>;
|
|
460
|
+
uploadUri: (uri: string, path: string, options?: UploadOptions) => Promise<UploadResult | null>;
|
|
461
|
+
progress: number;
|
|
462
|
+
isUploading: boolean;
|
|
463
|
+
isError: boolean;
|
|
464
|
+
error: Error | null;
|
|
465
|
+
result: UploadResult | null;
|
|
466
|
+
reset: () => void;
|
|
467
|
+
}
|
|
468
|
+
interface UploadOptions {
|
|
469
|
+
bucket?: string;
|
|
470
|
+
contentType?: string;
|
|
471
|
+
metadata?: Record<string, string>;
|
|
472
|
+
isPublic?: boolean;
|
|
473
|
+
}
|
|
474
|
+
interface UseDownloadReturn {
|
|
475
|
+
download: (path: string) => Promise<Blob | null>;
|
|
476
|
+
isDownloading: boolean;
|
|
477
|
+
isError: boolean;
|
|
478
|
+
error: Error | null;
|
|
479
|
+
progress: number;
|
|
480
|
+
}
|
|
481
|
+
interface UseFileReturn {
|
|
482
|
+
file: FileMetadata | null;
|
|
483
|
+
isLoading: boolean;
|
|
484
|
+
isError: boolean;
|
|
485
|
+
error: Error | null;
|
|
486
|
+
refetch: () => Promise<void>;
|
|
487
|
+
remove: () => Promise<boolean>;
|
|
488
|
+
}
|
|
489
|
+
interface UseFilesReturn {
|
|
490
|
+
files: FileMetadata[];
|
|
491
|
+
isLoading: boolean;
|
|
492
|
+
isError: boolean;
|
|
493
|
+
error: Error | null;
|
|
494
|
+
refetch: () => Promise<void>;
|
|
495
|
+
}
|
|
496
|
+
/**
|
|
497
|
+
* Hook for file uploads
|
|
498
|
+
*
|
|
499
|
+
* @example
|
|
500
|
+
* ```tsx
|
|
501
|
+
* import * as ImagePicker from 'expo-image-picker';
|
|
502
|
+
*
|
|
503
|
+
* function ImageUpload() {
|
|
504
|
+
* const { uploadUri, isUploading, progress } = useUpload();
|
|
505
|
+
*
|
|
506
|
+
* const pickAndUpload = async () => {
|
|
507
|
+
* const result = await ImagePicker.launchImageLibraryAsync();
|
|
508
|
+
* if (!result.canceled) {
|
|
509
|
+
* const { uri } = result.assets[0];
|
|
510
|
+
* await uploadUri(uri, `photos/${Date.now()}.jpg`);
|
|
511
|
+
* }
|
|
512
|
+
* };
|
|
513
|
+
*
|
|
514
|
+
* return (
|
|
515
|
+
* <View>
|
|
516
|
+
* <Button onPress={pickAndUpload} disabled={isUploading}>
|
|
517
|
+
* {isUploading ? `Uploading ${progress}%` : 'Select Image'}
|
|
518
|
+
* </Button>
|
|
519
|
+
* </View>
|
|
520
|
+
* );
|
|
521
|
+
* }
|
|
522
|
+
* ```
|
|
523
|
+
*/
|
|
524
|
+
declare function useUpload(defaultBucket?: string): UseUploadReturn;
|
|
525
|
+
/**
|
|
526
|
+
* Hook for file downloads
|
|
527
|
+
*
|
|
528
|
+
* @example
|
|
529
|
+
* ```tsx
|
|
530
|
+
* function FileDownload({ path }: { path: string }) {
|
|
531
|
+
* const { download, isDownloading, progress } = useDownload();
|
|
532
|
+
*
|
|
533
|
+
* const handleDownload = async () => {
|
|
534
|
+
* const blob = await download(path);
|
|
535
|
+
* if (blob) {
|
|
536
|
+
* // Handle the blob (e.g., save or display)
|
|
537
|
+
* }
|
|
538
|
+
* };
|
|
539
|
+
*
|
|
540
|
+
* return (
|
|
541
|
+
* <Button onPress={handleDownload} disabled={isDownloading}>
|
|
542
|
+
* {isDownloading ? `${progress}%` : 'Download'}
|
|
543
|
+
* </Button>
|
|
544
|
+
* );
|
|
545
|
+
* }
|
|
546
|
+
* ```
|
|
547
|
+
*/
|
|
548
|
+
declare function useDownload(defaultBucket?: string): UseDownloadReturn;
|
|
549
|
+
/**
|
|
550
|
+
* Hook for fetching file metadata
|
|
551
|
+
*/
|
|
552
|
+
declare function useFile(path: string | undefined, options?: {
|
|
553
|
+
bucket?: string;
|
|
554
|
+
}): UseFileReturn;
|
|
555
|
+
/**
|
|
556
|
+
* Hook for listing files
|
|
557
|
+
*/
|
|
558
|
+
declare function useFiles(options?: {
|
|
559
|
+
bucket?: string;
|
|
560
|
+
prefix?: string;
|
|
561
|
+
limit?: number;
|
|
562
|
+
}): UseFilesReturn;
|
|
563
|
+
/**
|
|
564
|
+
* Hook for getting public URL
|
|
565
|
+
*/
|
|
566
|
+
declare function usePublicUrl(path: string | undefined, options?: {
|
|
567
|
+
bucket?: string;
|
|
568
|
+
}): string | null;
|
|
569
|
+
|
|
570
|
+
interface UseFunctionOptions {
|
|
571
|
+
/** Retry configuration */
|
|
572
|
+
retry?: RetryConfig;
|
|
573
|
+
/** Timeout in ms */
|
|
574
|
+
timeout?: number;
|
|
575
|
+
/** Skip invoking */
|
|
576
|
+
enabled?: boolean;
|
|
577
|
+
}
|
|
578
|
+
interface UseFunctionReturn<TOutput, TInput = unknown> {
|
|
579
|
+
invoke: (input?: TInput) => Promise<TOutput | null>;
|
|
580
|
+
data: TOutput | null;
|
|
581
|
+
isLoading: boolean;
|
|
582
|
+
isError: boolean;
|
|
583
|
+
isSuccess: boolean;
|
|
584
|
+
error: Error | null;
|
|
585
|
+
reset: () => void;
|
|
586
|
+
/** Execution metadata */
|
|
587
|
+
meta: {
|
|
588
|
+
status?: number;
|
|
589
|
+
durationMs?: number;
|
|
590
|
+
requestId?: string;
|
|
591
|
+
logs?: string[];
|
|
592
|
+
} | null;
|
|
593
|
+
}
|
|
594
|
+
interface UseRpcReturn<TOutput, TInput = unknown> extends UseFunctionReturn<TOutput, TInput> {
|
|
595
|
+
call: (input?: TInput) => Promise<TOutput | null>;
|
|
596
|
+
}
|
|
597
|
+
interface UseFunctionListReturn {
|
|
598
|
+
functions: VaifFunction[];
|
|
599
|
+
isLoading: boolean;
|
|
600
|
+
isError: boolean;
|
|
601
|
+
error: Error | null;
|
|
602
|
+
refetch: () => Promise<void>;
|
|
603
|
+
}
|
|
604
|
+
/**
|
|
605
|
+
* Hook for invoking serverless functions
|
|
606
|
+
*
|
|
607
|
+
* @example
|
|
608
|
+
* ```tsx
|
|
609
|
+
* function SendEmail() {
|
|
610
|
+
* const { invoke, isLoading, error } = useFunction<{ success: boolean }, { to: string; subject: string }>('send-email');
|
|
611
|
+
*
|
|
612
|
+
* const handleSend = async () => {
|
|
613
|
+
* const result = await invoke({
|
|
614
|
+
* to: 'user@example.com',
|
|
615
|
+
* subject: 'Hello!',
|
|
616
|
+
* });
|
|
617
|
+
* if (result?.success) {
|
|
618
|
+
* Alert.alert('Email sent!');
|
|
619
|
+
* }
|
|
620
|
+
* };
|
|
621
|
+
*
|
|
622
|
+
* return (
|
|
623
|
+
* <Button onPress={handleSend} disabled={isLoading}>
|
|
624
|
+
* {isLoading ? 'Sending...' : 'Send Email'}
|
|
625
|
+
* </Button>
|
|
626
|
+
* );
|
|
627
|
+
* }
|
|
628
|
+
* ```
|
|
629
|
+
*/
|
|
630
|
+
declare function useFunction<TOutput = unknown, TInput = unknown>(functionId: string, options?: UseFunctionOptions): UseFunctionReturn<TOutput, TInput>;
|
|
631
|
+
/**
|
|
632
|
+
* Hook for RPC-style function calls (alias for useFunction)
|
|
633
|
+
*
|
|
634
|
+
* @example
|
|
635
|
+
* ```tsx
|
|
636
|
+
* function Calculator() {
|
|
637
|
+
* const { call, data, isLoading } = useRpc<{ result: number }, { a: number; b: number }>('add-numbers');
|
|
638
|
+
*
|
|
639
|
+
* const handleAdd = async () => {
|
|
640
|
+
* const result = await call({ a: 5, b: 3 });
|
|
641
|
+
* console.log('Sum:', result?.result); // 8
|
|
642
|
+
* };
|
|
643
|
+
*
|
|
644
|
+
* return (
|
|
645
|
+
* <View>
|
|
646
|
+
* <Text>Result: {data?.result ?? '-'}</Text>
|
|
647
|
+
* <Button onPress={handleAdd} disabled={isLoading}>Add</Button>
|
|
648
|
+
* </View>
|
|
649
|
+
* );
|
|
650
|
+
* }
|
|
651
|
+
* ```
|
|
652
|
+
*/
|
|
653
|
+
declare function useRpc<TOutput = unknown, TInput = unknown>(functionId: string, options?: UseFunctionOptions): UseRpcReturn<TOutput, TInput>;
|
|
654
|
+
/**
|
|
655
|
+
* Hook for auto-invoking a function on mount
|
|
656
|
+
*
|
|
657
|
+
* @example
|
|
658
|
+
* ```tsx
|
|
659
|
+
* function UserStats() {
|
|
660
|
+
* const { data, isLoading, refetch } = useFunctionQuery<Stats>('get-user-stats');
|
|
661
|
+
*
|
|
662
|
+
* if (isLoading) return <ActivityIndicator />;
|
|
663
|
+
*
|
|
664
|
+
* return (
|
|
665
|
+
* <View>
|
|
666
|
+
* <Text>Posts: {data?.posts}</Text>
|
|
667
|
+
* <Text>Followers: {data?.followers}</Text>
|
|
668
|
+
* <Button onPress={refetch}>Refresh</Button>
|
|
669
|
+
* </View>
|
|
670
|
+
* );
|
|
671
|
+
* }
|
|
672
|
+
* ```
|
|
673
|
+
*/
|
|
674
|
+
declare function useFunctionQuery<TOutput = unknown, TInput = unknown>(functionId: string, input?: TInput, options?: UseFunctionOptions & {
|
|
675
|
+
refetchInterval?: number;
|
|
676
|
+
}): UseFunctionReturn<TOutput, TInput> & {
|
|
677
|
+
refetch: () => Promise<void>;
|
|
678
|
+
};
|
|
679
|
+
/**
|
|
680
|
+
* Hook for listing available functions
|
|
681
|
+
*/
|
|
682
|
+
declare function useFunctionList(projectId: string, options?: {
|
|
683
|
+
envId?: string;
|
|
684
|
+
enabled?: boolean;
|
|
685
|
+
}): UseFunctionListReturn;
|
|
686
|
+
/**
|
|
687
|
+
* Hook for batch invoking multiple functions
|
|
688
|
+
*/
|
|
689
|
+
declare function useBatchInvoke<TOutput = unknown>(): {
|
|
690
|
+
invoke: (functionIds: string[], inputs?: unknown[]) => Promise<(TOutput | null)[]>;
|
|
691
|
+
results: (TOutput | null)[];
|
|
692
|
+
isLoading: boolean;
|
|
693
|
+
errors: (Error | null)[];
|
|
694
|
+
};
|
|
695
|
+
|
|
696
|
+
export { type AsyncStorageInterface, type MutationStatus, type QueryStatus, type UploadOptions, type UseAuthReturn, type UseBroadcastReturn, type UseCreateReturn, type UseDeleteReturn, type UseDownloadReturn, type UseFileReturn, type UseFilesReturn, type UseFunctionListReturn, type UseFunctionOptions, type UseFunctionReturn, type UseMutationReturn, type UsePaginatedQueryOptions, type UsePaginatedQueryReturn, type UsePresenceOptions, type UsePresenceReturn, type UseQueryOptions, type UseQueryReturn, type UseRpcReturn, type UseSubscriptionOptions, type UseSubscriptionReturn, type UseUpdateReturn, type UseUploadReturn, type UseUpsertReturn, type VaifContextValue, VaifProvider, type VaifProviderProps, useAuth, useBatchCreate, useBatchInvoke, useBroadcast, useCreate, useDelete, useDownload, useFile, useFiles, useFunction, useFunctionList, useFunctionQuery, usePaginatedQuery, usePresence, usePublicUrl, useQuery, useQueryById, useRealtimeConnection, useRpc, useSubscription, useUpdate, useUpload, useUpsert, useUser, useVaif, useVaifClient };
|