@edgebasejs/react-native 0.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/client-core/src/auth/auth-manager.d.ts +73 -0
- package/dist/client-core/src/auth/auth-manager.d.ts.map +1 -0
- package/dist/client-core/src/auth/auth-manager.js +226 -0
- package/dist/client-core/src/auth/auth-manager.js.map +1 -0
- package/dist/client-core/src/auth/index.d.ts +2 -0
- package/dist/client-core/src/auth/index.d.ts.map +1 -0
- package/dist/client-core/src/auth/index.js +2 -0
- package/dist/client-core/src/auth/index.js.map +1 -0
- package/dist/client-core/src/conflict/conflict-resolver.d.ts +62 -0
- package/dist/client-core/src/conflict/conflict-resolver.d.ts.map +1 -0
- package/dist/client-core/src/conflict/conflict-resolver.js +102 -0
- package/dist/client-core/src/conflict/conflict-resolver.js.map +1 -0
- package/dist/client-core/src/conflict/index.d.ts +2 -0
- package/dist/client-core/src/conflict/index.d.ts.map +1 -0
- package/dist/client-core/src/conflict/index.js +2 -0
- package/dist/client-core/src/conflict/index.js.map +1 -0
- package/dist/client-core/src/index.d.ts +6 -0
- package/dist/client-core/src/index.d.ts.map +1 -0
- package/dist/client-core/src/index.js +6 -0
- package/dist/client-core/src/index.js.map +1 -0
- package/dist/client-core/src/outbox/index.d.ts +2 -0
- package/dist/client-core/src/outbox/index.d.ts.map +1 -0
- package/dist/client-core/src/outbox/index.js +2 -0
- package/dist/client-core/src/outbox/index.js.map +1 -0
- package/dist/client-core/src/outbox/outbox-manager.d.ts +82 -0
- package/dist/client-core/src/outbox/outbox-manager.d.ts.map +1 -0
- package/dist/client-core/src/outbox/outbox-manager.js +143 -0
- package/dist/client-core/src/outbox/outbox-manager.js.map +1 -0
- package/dist/client-core/src/storage/index.d.ts +2 -0
- package/dist/client-core/src/storage/index.d.ts.map +1 -0
- package/dist/client-core/src/storage/index.js +2 -0
- package/dist/client-core/src/storage/index.js.map +1 -0
- package/dist/client-core/src/storage/storage-adapter.d.ts +54 -0
- package/dist/client-core/src/storage/storage-adapter.d.ts.map +1 -0
- package/dist/client-core/src/storage/storage-adapter.js +38 -0
- package/dist/client-core/src/storage/storage-adapter.js.map +1 -0
- package/dist/client-core/src/sync/index.d.ts +2 -0
- package/dist/client-core/src/sync/index.d.ts.map +1 -0
- package/dist/client-core/src/sync/index.js +2 -0
- package/dist/client-core/src/sync/index.js.map +1 -0
- package/dist/client-core/src/sync/sync-engine.d.ts +65 -0
- package/dist/client-core/src/sync/sync-engine.d.ts.map +1 -0
- package/dist/client-core/src/sync/sync-engine.js +190 -0
- package/dist/client-core/src/sync/sync-engine.js.map +1 -0
- package/dist/client-react-native/src/hooks/index.d.ts +5 -0
- package/dist/client-react-native/src/hooks/index.d.ts.map +1 -0
- package/dist/client-react-native/src/hooks/index.js +5 -0
- package/dist/client-react-native/src/hooks/index.js.map +1 -0
- package/dist/client-react-native/src/hooks/use-auth.d.ts +17 -0
- package/dist/client-react-native/src/hooks/use-auth.d.ts.map +1 -0
- package/dist/client-react-native/src/hooks/use-auth.js +78 -0
- package/dist/client-react-native/src/hooks/use-auth.js.map +1 -0
- package/dist/client-react-native/src/hooks/use-mutation.d.ts +14 -0
- package/dist/client-react-native/src/hooks/use-mutation.d.ts.map +1 -0
- package/dist/client-react-native/src/hooks/use-mutation.js +95 -0
- package/dist/client-react-native/src/hooks/use-mutation.js.map +1 -0
- package/dist/client-react-native/src/hooks/use-query.d.ts +14 -0
- package/dist/client-react-native/src/hooks/use-query.d.ts.map +1 -0
- package/dist/client-react-native/src/hooks/use-query.js +77 -0
- package/dist/client-react-native/src/hooks/use-query.js.map +1 -0
- package/dist/client-react-native/src/hooks/use-sync.d.ts +14 -0
- package/dist/client-react-native/src/hooks/use-sync.d.ts.map +1 -0
- package/dist/client-react-native/src/hooks/use-sync.js +67 -0
- package/dist/client-react-native/src/hooks/use-sync.js.map +1 -0
- package/dist/client-react-native/src/index.d.ts +9 -0
- package/dist/client-react-native/src/index.d.ts.map +1 -0
- package/dist/client-react-native/src/index.js +9 -0
- package/dist/client-react-native/src/index.js.map +1 -0
- package/dist/client-react-native/src/provider.d.ts +21 -0
- package/dist/client-react-native/src/provider.d.ts.map +1 -0
- package/dist/client-react-native/src/provider.js +92 -0
- package/dist/client-react-native/src/provider.js.map +1 -0
- package/dist/client-react-native/src/storage/async-storage-adapter.d.ts +16 -0
- package/dist/client-react-native/src/storage/async-storage-adapter.d.ts.map +1 -0
- package/dist/client-react-native/src/storage/async-storage-adapter.js +78 -0
- package/dist/client-react-native/src/storage/async-storage-adapter.js.map +1 -0
- package/dist/client-react-native/src/storage/index.d.ts +2 -0
- package/dist/client-react-native/src/storage/index.d.ts.map +1 -0
- package/dist/client-react-native/src/storage/index.js +2 -0
- package/dist/client-react-native/src/storage/index.js.map +1 -0
- package/dist/shared-types/src/admin.d.ts +101 -0
- package/dist/shared-types/src/admin.d.ts.map +1 -0
- package/dist/shared-types/src/admin.js +3 -0
- package/dist/shared-types/src/admin.js.map +1 -0
- package/dist/shared-types/src/auth.d.ts +27 -0
- package/dist/shared-types/src/auth.d.ts.map +1 -0
- package/dist/shared-types/src/auth.js +2 -0
- package/dist/shared-types/src/auth.js.map +1 -0
- package/dist/shared-types/src/index.d.ts +5 -0
- package/dist/shared-types/src/index.d.ts.map +1 -0
- package/dist/shared-types/src/index.js +5 -0
- package/dist/shared-types/src/index.js.map +1 -0
- package/dist/shared-types/src/schema.d.ts +34 -0
- package/dist/shared-types/src/schema.d.ts.map +1 -0
- package/dist/shared-types/src/schema.js +2 -0
- package/dist/shared-types/src/schema.js.map +1 -0
- package/dist/shared-types/src/sync.d.ts +37 -0
- package/dist/shared-types/src/sync.d.ts.map +1 -0
- package/dist/shared-types/src/sync.js +2 -0
- package/dist/shared-types/src/sync.js.map +1 -0
- package/package.json +36 -0
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
// useAuth hook for authentication
|
|
2
|
+
import { useCallback, useContext, useEffect, useState } from 'react';
|
|
3
|
+
import { EdgeBaseContext } from '../provider';
|
|
4
|
+
/**
|
|
5
|
+
* Hook to access authentication state and functions
|
|
6
|
+
*/
|
|
7
|
+
export function useAuth() {
|
|
8
|
+
const context = useContext(EdgeBaseContext);
|
|
9
|
+
if (!context) {
|
|
10
|
+
throw new Error('useAuth must be used within EdgeBaseProvider');
|
|
11
|
+
}
|
|
12
|
+
const { authManager } = context;
|
|
13
|
+
const [error, setError] = useState(null);
|
|
14
|
+
const [authState, setAuthState] = useState(authManager.getState());
|
|
15
|
+
useEffect(() => {
|
|
16
|
+
// Subscribe to auth state changes
|
|
17
|
+
const unsubscribe = authManager.subscribe((state) => {
|
|
18
|
+
setAuthState(state);
|
|
19
|
+
});
|
|
20
|
+
return unsubscribe;
|
|
21
|
+
}, [authManager]);
|
|
22
|
+
const login = useCallback(async (email, password) => {
|
|
23
|
+
setError(null);
|
|
24
|
+
try {
|
|
25
|
+
await authManager.login({ email, password });
|
|
26
|
+
}
|
|
27
|
+
catch (err) {
|
|
28
|
+
const error = err instanceof Error ? err : new Error('Login failed');
|
|
29
|
+
setError(error);
|
|
30
|
+
throw error;
|
|
31
|
+
}
|
|
32
|
+
}, [authManager]);
|
|
33
|
+
const register = useCallback(async (email, password) => {
|
|
34
|
+
setError(null);
|
|
35
|
+
try {
|
|
36
|
+
await authManager.register({ email, password });
|
|
37
|
+
}
|
|
38
|
+
catch (err) {
|
|
39
|
+
const error = err instanceof Error ? err : new Error('Registration failed');
|
|
40
|
+
setError(error);
|
|
41
|
+
throw error;
|
|
42
|
+
}
|
|
43
|
+
}, [authManager]);
|
|
44
|
+
const logout = useCallback(async () => {
|
|
45
|
+
setError(null);
|
|
46
|
+
try {
|
|
47
|
+
await authManager.logout();
|
|
48
|
+
}
|
|
49
|
+
catch (err) {
|
|
50
|
+
const error = err instanceof Error ? err : new Error('Logout failed');
|
|
51
|
+
setError(error);
|
|
52
|
+
throw error;
|
|
53
|
+
}
|
|
54
|
+
}, [authManager]);
|
|
55
|
+
const refreshToken = useCallback(async () => {
|
|
56
|
+
setError(null);
|
|
57
|
+
try {
|
|
58
|
+
await authManager.refreshAccessToken();
|
|
59
|
+
}
|
|
60
|
+
catch (err) {
|
|
61
|
+
const error = err instanceof Error ? err : new Error('Token refresh failed');
|
|
62
|
+
setError(error);
|
|
63
|
+
throw error;
|
|
64
|
+
}
|
|
65
|
+
}, [authManager]);
|
|
66
|
+
return {
|
|
67
|
+
user: authState.user,
|
|
68
|
+
isAuthenticated: authState.isAuthenticated,
|
|
69
|
+
isLoading: authState.isLoading,
|
|
70
|
+
error,
|
|
71
|
+
login,
|
|
72
|
+
register,
|
|
73
|
+
logout,
|
|
74
|
+
refreshToken,
|
|
75
|
+
};
|
|
76
|
+
}
|
|
77
|
+
export default useAuth;
|
|
78
|
+
//# sourceMappingURL=use-auth.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"use-auth.js","sourceRoot":"","sources":["../../../../src/hooks/use-auth.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
export interface UseMutationResult<T> {
|
|
2
|
+
isLoading: boolean;
|
|
3
|
+
error: Error | null;
|
|
4
|
+
create: (entity: string, data: Record<string, any>) => Promise<T>;
|
|
5
|
+
update: (entity: string, id: string, data: Record<string, any>) => Promise<T>;
|
|
6
|
+
delete: (entity: string, id: string) => Promise<void>;
|
|
7
|
+
reset: () => void;
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* Hook to perform mutations (create, update, delete)
|
|
11
|
+
*/
|
|
12
|
+
export declare function useMutation<T = any>(): UseMutationResult<T>;
|
|
13
|
+
export default useMutation;
|
|
14
|
+
//# sourceMappingURL=use-mutation.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"use-mutation.d.ts","sourceRoot":"","sources":["../../../../src/hooks/use-mutation.ts"],"names":[],"mappings":"AAKA,MAAM,WAAW,iBAAiB,CAAC,CAAC;IAClC,SAAS,EAAE,OAAO,CAAC;IACnB,KAAK,EAAE,KAAK,GAAG,IAAI,CAAC;IACpB,MAAM,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,KAAK,OAAO,CAAC,CAAC,CAAC,CAAC;IAClE,MAAM,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,KAAK,OAAO,CAAC,CAAC,CAAC,CAAC;IAC9E,MAAM,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IACtD,KAAK,EAAE,MAAM,IAAI,CAAC;CACnB;AAED;;GAEG;AACH,wBAAgB,WAAW,CAAC,CAAC,GAAG,GAAG,KAAK,iBAAiB,CAAC,CAAC,CAAC,CA0G3D;AAED,eAAe,WAAW,CAAC"}
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
// useMutation hook for mutations (create, update, delete)
|
|
2
|
+
import { useContext, useCallback, useState } from 'react';
|
|
3
|
+
import { EdgeBaseContext } from '../provider';
|
|
4
|
+
/**
|
|
5
|
+
* Hook to perform mutations (create, update, delete)
|
|
6
|
+
*/
|
|
7
|
+
export function useMutation() {
|
|
8
|
+
const context = useContext(EdgeBaseContext);
|
|
9
|
+
if (!context) {
|
|
10
|
+
throw new Error('useMutation must be used within EdgeBaseProvider');
|
|
11
|
+
}
|
|
12
|
+
const { storage, syncEngine } = context;
|
|
13
|
+
const [isLoading, setIsLoading] = useState(false);
|
|
14
|
+
const [error, setError] = useState(null);
|
|
15
|
+
const create = useCallback(async (entity, data) => {
|
|
16
|
+
setIsLoading(true);
|
|
17
|
+
setError(null);
|
|
18
|
+
try {
|
|
19
|
+
// Generate ID
|
|
20
|
+
const id = `${entity}_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`;
|
|
21
|
+
// Optimistic update - save to local storage immediately
|
|
22
|
+
const record = { id, ...data };
|
|
23
|
+
const storageKey = `entity:${entity}:${id}`;
|
|
24
|
+
await storage.setItem(storageKey, JSON.stringify(record));
|
|
25
|
+
// Add to outbox for sync
|
|
26
|
+
await syncEngine?.addChange(entity, 'create', id, record);
|
|
27
|
+
return record;
|
|
28
|
+
}
|
|
29
|
+
catch (err) {
|
|
30
|
+
const error = err instanceof Error ? err : new Error('Create failed');
|
|
31
|
+
setError(error);
|
|
32
|
+
throw error;
|
|
33
|
+
}
|
|
34
|
+
finally {
|
|
35
|
+
setIsLoading(false);
|
|
36
|
+
}
|
|
37
|
+
}, [storage, syncEngine]);
|
|
38
|
+
const update = useCallback(async (entity, id, data) => {
|
|
39
|
+
setIsLoading(true);
|
|
40
|
+
setError(null);
|
|
41
|
+
try {
|
|
42
|
+
// Get existing record
|
|
43
|
+
const storageKey = `entity:${entity}:${id}`;
|
|
44
|
+
const existingData = await storage.getItem(storageKey);
|
|
45
|
+
const existing = existingData ? JSON.parse(existingData) : {};
|
|
46
|
+
// Merge data
|
|
47
|
+
const updated = { ...existing, ...data, id };
|
|
48
|
+
// Optimistic update
|
|
49
|
+
await storage.setItem(storageKey, JSON.stringify(updated));
|
|
50
|
+
// Add to outbox for sync
|
|
51
|
+
await syncEngine?.addChange(entity, 'update', id, data);
|
|
52
|
+
return updated;
|
|
53
|
+
}
|
|
54
|
+
catch (err) {
|
|
55
|
+
const error = err instanceof Error ? err : new Error('Update failed');
|
|
56
|
+
setError(error);
|
|
57
|
+
throw error;
|
|
58
|
+
}
|
|
59
|
+
finally {
|
|
60
|
+
setIsLoading(false);
|
|
61
|
+
}
|
|
62
|
+
}, [storage, syncEngine]);
|
|
63
|
+
const deleteRecord = useCallback(async (entity, id) => {
|
|
64
|
+
setIsLoading(true);
|
|
65
|
+
setError(null);
|
|
66
|
+
try {
|
|
67
|
+
// Remove from local storage
|
|
68
|
+
const storageKey = `entity:${entity}:${id}`;
|
|
69
|
+
await storage.removeItem(storageKey);
|
|
70
|
+
// Add to outbox for sync
|
|
71
|
+
await syncEngine?.addChange(entity, 'delete', id, {});
|
|
72
|
+
}
|
|
73
|
+
catch (err) {
|
|
74
|
+
const error = err instanceof Error ? err : new Error('Delete failed');
|
|
75
|
+
setError(error);
|
|
76
|
+
throw error;
|
|
77
|
+
}
|
|
78
|
+
finally {
|
|
79
|
+
setIsLoading(false);
|
|
80
|
+
}
|
|
81
|
+
}, [storage, syncEngine]);
|
|
82
|
+
const reset = useCallback(() => {
|
|
83
|
+
setError(null);
|
|
84
|
+
}, []);
|
|
85
|
+
return {
|
|
86
|
+
isLoading,
|
|
87
|
+
error,
|
|
88
|
+
create,
|
|
89
|
+
update,
|
|
90
|
+
delete: deleteRecord,
|
|
91
|
+
reset,
|
|
92
|
+
};
|
|
93
|
+
}
|
|
94
|
+
export default useMutation;
|
|
95
|
+
//# sourceMappingURL=use-mutation.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"use-mutation.js","sourceRoot":"","sources":["../../../../src/hooks/use-mutation.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
export interface UseQueryResult<T> {
|
|
2
|
+
data: T[] | null;
|
|
3
|
+
isLoading: boolean;
|
|
4
|
+
error: Error | null;
|
|
5
|
+
refetch: () => Promise<void>;
|
|
6
|
+
}
|
|
7
|
+
/**
|
|
8
|
+
* Hook to query data from an entity
|
|
9
|
+
*/
|
|
10
|
+
export declare function useQuery<T = any>(entity: string, filters?: Record<string, any>, options?: {
|
|
11
|
+
autoSync?: boolean;
|
|
12
|
+
}): UseQueryResult<T>;
|
|
13
|
+
export default useQuery;
|
|
14
|
+
//# sourceMappingURL=use-query.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"use-query.d.ts","sourceRoot":"","sources":["../../../../src/hooks/use-query.ts"],"names":[],"mappings":"AAKA,MAAM,WAAW,cAAc,CAAC,CAAC;IAC/B,IAAI,EAAE,CAAC,EAAE,GAAG,IAAI,CAAC;IACjB,SAAS,EAAE,OAAO,CAAC;IACnB,KAAK,EAAE,KAAK,GAAG,IAAI,CAAC;IACpB,OAAO,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;CAC9B;AAED;;GAEG;AACH,wBAAgB,QAAQ,CAAC,CAAC,GAAG,GAAG,EAC9B,MAAM,EAAE,MAAM,EACd,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EAC7B,OAAO,CAAC,EAAE;IAAE,QAAQ,CAAC,EAAE,OAAO,CAAA;CAAE,GAC/B,cAAc,CAAC,CAAC,CAAC,CA2EnB;AAED,eAAe,QAAQ,CAAC"}
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
// useQuery hook for fetching data
|
|
2
|
+
import { useContext, useCallback, useState, useEffect } from 'react';
|
|
3
|
+
import { EdgeBaseContext } from '../provider';
|
|
4
|
+
/**
|
|
5
|
+
* Hook to query data from an entity
|
|
6
|
+
*/
|
|
7
|
+
export function useQuery(entity, filters, options) {
|
|
8
|
+
const context = useContext(EdgeBaseContext);
|
|
9
|
+
if (!context) {
|
|
10
|
+
throw new Error('useQuery must be used within EdgeBaseProvider');
|
|
11
|
+
}
|
|
12
|
+
const { storage } = context;
|
|
13
|
+
const [data, setData] = useState(null);
|
|
14
|
+
const [isLoading, setIsLoading] = useState(true);
|
|
15
|
+
const [error, setError] = useState(null);
|
|
16
|
+
const fetchData = useCallback(async () => {
|
|
17
|
+
setIsLoading(true);
|
|
18
|
+
setError(null);
|
|
19
|
+
try {
|
|
20
|
+
// Get all keys matching entity pattern
|
|
21
|
+
const allKeys = await storage.getAllKeys();
|
|
22
|
+
const entityKeys = allKeys.filter((key) => key.startsWith(`entity:${entity}:`));
|
|
23
|
+
// Fetch all records for entity
|
|
24
|
+
const records = [];
|
|
25
|
+
for (const key of entityKeys) {
|
|
26
|
+
const data = await storage.getItem(key);
|
|
27
|
+
if (data) {
|
|
28
|
+
const record = JSON.parse(data);
|
|
29
|
+
// Apply filters if provided
|
|
30
|
+
if (filters) {
|
|
31
|
+
let matches = true;
|
|
32
|
+
for (const [filterKey, filterValue] of Object.entries(filters)) {
|
|
33
|
+
if (record[filterKey] !== filterValue) {
|
|
34
|
+
matches = false;
|
|
35
|
+
break;
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
if (matches) {
|
|
39
|
+
records.push(record);
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
else {
|
|
43
|
+
records.push(record);
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
setData(records);
|
|
48
|
+
}
|
|
49
|
+
catch (err) {
|
|
50
|
+
const error = err instanceof Error ? err : new Error('Query failed');
|
|
51
|
+
setError(error);
|
|
52
|
+
}
|
|
53
|
+
finally {
|
|
54
|
+
setIsLoading(false);
|
|
55
|
+
}
|
|
56
|
+
}, [entity, filters, storage]);
|
|
57
|
+
useEffect(() => {
|
|
58
|
+
fetchData();
|
|
59
|
+
// Auto-sync if enabled
|
|
60
|
+
if (options?.autoSync) {
|
|
61
|
+
const interval = setInterval(() => {
|
|
62
|
+
context.syncEngine?.sync().catch((err) => {
|
|
63
|
+
console.error('Auto-sync error:', err);
|
|
64
|
+
});
|
|
65
|
+
}, 30000); // Sync every 30 seconds
|
|
66
|
+
return () => clearInterval(interval);
|
|
67
|
+
}
|
|
68
|
+
}, [fetchData, context, options?.autoSync]);
|
|
69
|
+
return {
|
|
70
|
+
data,
|
|
71
|
+
isLoading,
|
|
72
|
+
error,
|
|
73
|
+
refetch: fetchData,
|
|
74
|
+
};
|
|
75
|
+
}
|
|
76
|
+
export default useQuery;
|
|
77
|
+
//# sourceMappingURL=use-query.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"use-query.js","sourceRoot":"","sources":["../../../../src/hooks/use-query.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
export interface UseSyncResult {
|
|
2
|
+
isSyncing: boolean;
|
|
3
|
+
lastSyncTimestamp: number | null;
|
|
4
|
+
pendingChanges: number;
|
|
5
|
+
error: Error | null;
|
|
6
|
+
sync: () => Promise<void>;
|
|
7
|
+
reset: () => void;
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* Hook to control client-server synchronization
|
|
11
|
+
*/
|
|
12
|
+
export declare function useSync(): UseSyncResult;
|
|
13
|
+
export default useSync;
|
|
14
|
+
//# sourceMappingURL=use-sync.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"use-sync.d.ts","sourceRoot":"","sources":["../../../../src/hooks/use-sync.ts"],"names":[],"mappings":"AAKA,MAAM,WAAW,aAAa;IAC5B,SAAS,EAAE,OAAO,CAAC;IACnB,iBAAiB,EAAE,MAAM,GAAG,IAAI,CAAC;IACjC,cAAc,EAAE,MAAM,CAAC;IACvB,KAAK,EAAE,KAAK,GAAG,IAAI,CAAC;IACpB,IAAI,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;IAC1B,KAAK,EAAE,MAAM,IAAI,CAAC;CACnB;AAED;;GAEG;AACH,wBAAgB,OAAO,IAAI,aAAa,CAiEvC;AAED,eAAe,OAAO,CAAC"}
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
// useSync hook for controlling synchronization
|
|
2
|
+
import { useContext, useCallback, useState, useEffect } from 'react';
|
|
3
|
+
import { EdgeBaseContext } from '../provider';
|
|
4
|
+
/**
|
|
5
|
+
* Hook to control client-server synchronization
|
|
6
|
+
*/
|
|
7
|
+
export function useSync() {
|
|
8
|
+
const context = useContext(EdgeBaseContext);
|
|
9
|
+
if (!context) {
|
|
10
|
+
throw new Error('useSync must be used within EdgeBaseProvider');
|
|
11
|
+
}
|
|
12
|
+
const { syncEngine } = context;
|
|
13
|
+
const [isSyncing, setIsSyncing] = useState(false);
|
|
14
|
+
const [lastSyncTimestamp, setLastSyncTimestamp] = useState(null);
|
|
15
|
+
const [pendingChanges, setPendingChanges] = useState(0);
|
|
16
|
+
const [error, setError] = useState(null);
|
|
17
|
+
// Update sync status from engine
|
|
18
|
+
useEffect(() => {
|
|
19
|
+
const updateStatus = async () => {
|
|
20
|
+
if (!syncEngine)
|
|
21
|
+
return;
|
|
22
|
+
const status = await syncEngine.getStatus();
|
|
23
|
+
setIsSyncing(status.isSyncing);
|
|
24
|
+
setLastSyncTimestamp(status.lastSyncTimestamp);
|
|
25
|
+
setPendingChanges(status.pendingChanges);
|
|
26
|
+
};
|
|
27
|
+
// Initial update
|
|
28
|
+
updateStatus();
|
|
29
|
+
// Poll for updates
|
|
30
|
+
const interval = setInterval(updateStatus, 2000);
|
|
31
|
+
return () => clearInterval(interval);
|
|
32
|
+
}, [syncEngine]);
|
|
33
|
+
const sync = useCallback(async () => {
|
|
34
|
+
if (!syncEngine) {
|
|
35
|
+
throw new Error('Sync engine not available');
|
|
36
|
+
}
|
|
37
|
+
setIsSyncing(true);
|
|
38
|
+
setError(null);
|
|
39
|
+
try {
|
|
40
|
+
await syncEngine.sync();
|
|
41
|
+
const status = await syncEngine.getStatus();
|
|
42
|
+
setLastSyncTimestamp(status.lastSyncTimestamp);
|
|
43
|
+
setPendingChanges(status.pendingChanges);
|
|
44
|
+
}
|
|
45
|
+
catch (err) {
|
|
46
|
+
const error = err instanceof Error ? err : new Error('Sync failed');
|
|
47
|
+
setError(error);
|
|
48
|
+
throw error;
|
|
49
|
+
}
|
|
50
|
+
finally {
|
|
51
|
+
setIsSyncing(false);
|
|
52
|
+
}
|
|
53
|
+
}, [syncEngine]);
|
|
54
|
+
const reset = useCallback(() => {
|
|
55
|
+
setError(null);
|
|
56
|
+
}, []);
|
|
57
|
+
return {
|
|
58
|
+
isSyncing,
|
|
59
|
+
lastSyncTimestamp,
|
|
60
|
+
pendingChanges,
|
|
61
|
+
error,
|
|
62
|
+
sync,
|
|
63
|
+
reset,
|
|
64
|
+
};
|
|
65
|
+
}
|
|
66
|
+
export default useSync;
|
|
67
|
+
//# sourceMappingURL=use-sync.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"use-sync.js","sourceRoot":"","sources":["../../../../src/hooks/use-sync.ts"],"names":[],"mappings":"AAAA,+CAA+C;AAE/C,OAAO,EAAE,UAAU,EAAE,WAAW,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AACrE,OAAO,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAW9C;;GAEG;AACH,MAAM,UAAU,OAAO;IACrB,MAAM,OAAO,GAAG,UAAU,CAAC,eAAe,CAAC,CAAC;IAC5C,IAAI,CAAC,OAAO,EAAE,CAAC;QACb,MAAM,IAAI,KAAK,CAAC,8CAA8C,CAAC,CAAC;IAClE,CAAC;IAED,MAAM,EAAE,UAAU,EAAE,GAAG,OAAO,CAAC;IAC/B,MAAM,CAAC,SAAS,EAAE,YAAY,CAAC,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC;IAClD,MAAM,CAAC,iBAAiB,EAAE,oBAAoB,CAAC,GAAG,QAAQ,CAAgB,IAAI,CAAC,CAAC;IAChF,MAAM,CAAC,cAAc,EAAE,iBAAiB,CAAC,GAAG,QAAQ,CAAC,CAAC,CAAC,CAAC;IACxD,MAAM,CAAC,KAAK,EAAE,QAAQ,CAAC,GAAG,QAAQ,CAAe,IAAI,CAAC,CAAC;IAEvD,iCAAiC;IACjC,SAAS,CAAC,GAAG,EAAE;QACb,MAAM,YAAY,GAAG,KAAK,IAAI,EAAE;YAC9B,IAAI,CAAC,UAAU;gBAAE,OAAO;YAExB,MAAM,MAAM,GAAG,MAAM,UAAU,CAAC,SAAS,EAAE,CAAC;YAC5C,YAAY,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC;YAC/B,oBAAoB,CAAC,MAAM,CAAC,iBAAiB,CAAC,CAAC;YAC/C,iBAAiB,CAAC,MAAM,CAAC,cAAc,CAAC,CAAC;QAC3C,CAAC,CAAC;QAEF,iBAAiB;QACjB,YAAY,EAAE,CAAC;QAEf,mBAAmB;QACnB,MAAM,QAAQ,GAAG,WAAW,CAAC,YAAY,EAAE,IAAI,CAAC,CAAC;QACjD,OAAO,GAAG,EAAE,CAAC,aAAa,CAAC,QAAQ,CAAC,CAAC;IACvC,CAAC,EAAE,CAAC,UAAU,CAAC,CAAC,CAAC;IAEjB,MAAM,IAAI,GAAG,WAAW,CAAC,KAAK,IAAI,EAAE;QAClC,IAAI,CAAC,UAAU,EAAE,CAAC;YAChB,MAAM,IAAI,KAAK,CAAC,2BAA2B,CAAC,CAAC;QAC/C,CAAC;QAED,YAAY,CAAC,IAAI,CAAC,CAAC;QACnB,QAAQ,CAAC,IAAI,CAAC,CAAC;QAEf,IAAI,CAAC;YACH,MAAM,UAAU,CAAC,IAAI,EAAE,CAAC;YACxB,MAAM,MAAM,GAAG,MAAM,UAAU,CAAC,SAAS,EAAE,CAAC;YAC5C,oBAAoB,CAAC,MAAM,CAAC,iBAAiB,CAAC,CAAC;YAC/C,iBAAiB,CAAC,MAAM,CAAC,cAAc,CAAC,CAAC;QAC3C,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,MAAM,KAAK,GAAG,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,KAAK,CAAC,aAAa,CAAC,CAAC;YACpE,QAAQ,CAAC,KAAK,CAAC,CAAC;YAChB,MAAM,KAAK,CAAC;QACd,CAAC;gBAAS,CAAC;YACT,YAAY,CAAC,KAAK,CAAC,CAAC;QACtB,CAAC;IACH,CAAC,EAAE,CAAC,UAAU,CAAC,CAAC,CAAC;IAEjB,MAAM,KAAK,GAAG,WAAW,CAAC,GAAG,EAAE;QAC7B,QAAQ,CAAC,IAAI,CAAC,CAAC;IACjB,CAAC,EAAE,EAAE,CAAC,CAAC;IAEP,OAAO;QACL,SAAS;QACT,iBAAiB;QACjB,cAAc;QACd,KAAK;QACL,IAAI;QACJ,KAAK;KACN,CAAC;AACJ,CAAC;AAED,eAAe,OAAO,CAAC"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
export * from './storage';
|
|
2
|
+
export * from './hooks';
|
|
3
|
+
export * from './provider';
|
|
4
|
+
export { useAuth } from './hooks/use-auth';
|
|
5
|
+
export { useQuery } from './hooks/use-query';
|
|
6
|
+
export { useMutation } from './hooks/use-mutation';
|
|
7
|
+
export { useSync } from './hooks/use-sync';
|
|
8
|
+
export { EdgeBaseProvider, EdgeBaseContext } from './provider';
|
|
9
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,WAAW,CAAC;AAC1B,cAAc,SAAS,CAAC;AACxB,cAAc,YAAY,CAAC;AAC3B,OAAO,EAAE,OAAO,EAAE,MAAM,kBAAkB,CAAC;AAC3C,OAAO,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAC;AAC7C,OAAO,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAC;AACnD,OAAO,EAAE,OAAO,EAAE,MAAM,kBAAkB,CAAC;AAC3C,OAAO,EAAE,gBAAgB,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
export * from './storage';
|
|
2
|
+
export * from './hooks';
|
|
3
|
+
export * from './provider';
|
|
4
|
+
export { useAuth } from './hooks/use-auth';
|
|
5
|
+
export { useQuery } from './hooks/use-query';
|
|
6
|
+
export { useMutation } from './hooks/use-mutation';
|
|
7
|
+
export { useSync } from './hooks/use-sync';
|
|
8
|
+
export { EdgeBaseProvider, EdgeBaseContext } from './provider';
|
|
9
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,WAAW,CAAC;AAC1B,cAAc,SAAS,CAAC;AACxB,cAAc,YAAY,CAAC;AAC3B,OAAO,EAAE,OAAO,EAAE,MAAM,kBAAkB,CAAC;AAC3C,OAAO,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAC;AAC7C,OAAO,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAC;AACnD,OAAO,EAAE,OAAO,EAAE,MAAM,kBAAkB,CAAC;AAC3C,OAAO,EAAE,gBAAgB,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { AuthManager, ClientSyncEngine, OutboxManager, type IStorageAdapter } from '@edgebasejs/client-core';
|
|
3
|
+
export interface EdgeBaseContextValue {
|
|
4
|
+
storage: IStorageAdapter;
|
|
5
|
+
authManager: AuthManager;
|
|
6
|
+
syncEngine: ClientSyncEngine;
|
|
7
|
+
outboxManager: OutboxManager;
|
|
8
|
+
isInitialized: boolean;
|
|
9
|
+
}
|
|
10
|
+
export declare const EdgeBaseContext: React.Context<EdgeBaseContextValue | null>;
|
|
11
|
+
export interface EdgeBaseProviderProps {
|
|
12
|
+
apiUrl: string;
|
|
13
|
+
children: React.ReactNode;
|
|
14
|
+
useMemoryStorage?: boolean;
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* EdgeBase provider component
|
|
18
|
+
* Wraps the app to provide EdgeBase functionality via context
|
|
19
|
+
*/
|
|
20
|
+
export declare function EdgeBaseProvider({ apiUrl, children, useMemoryStorage, }: EdgeBaseProviderProps): import("react/jsx-runtime").JSX.Element;
|
|
21
|
+
//# sourceMappingURL=provider.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"provider.d.ts","sourceRoot":"","sources":["../../../src/provider.tsx"],"names":[],"mappings":"AAAA,OAAO,KAA8B,MAAM,OAAO,CAAC;AAEnD,OAAO,EACL,WAAW,EACX,gBAAgB,EAChB,aAAa,EAEb,KAAK,eAAe,EACrB,MAAM,yBAAyB,CAAC;AAGjC,MAAM,WAAW,oBAAoB;IACnC,OAAO,EAAE,eAAe,CAAC;IACzB,WAAW,EAAE,WAAW,CAAC;IACzB,UAAU,EAAE,gBAAgB,CAAC;IAC7B,aAAa,EAAE,aAAa,CAAC;IAC7B,aAAa,EAAE,OAAO,CAAC;CACxB;AAED,eAAO,MAAM,eAAe,4CAAyD,CAAC;AAEtF,MAAM,WAAW,qBAAqB;IACpC,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAC;IAC1B,gBAAgB,CAAC,EAAE,OAAO,CAAC;CAC5B;AAED;;;GAGG;AACH,wBAAgB,gBAAgB,CAAC,EAC/B,MAAM,EACN,QAAQ,EACR,gBAAwB,GACzB,EAAE,qBAAqB,2CA2GvB"}
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import React, { useEffect, useState } from 'react';
|
|
3
|
+
import { View, Text, ActivityIndicator } from 'react-native';
|
|
4
|
+
import { AuthManager, ClientSyncEngine, OutboxManager, MemoryStorageAdapter, } from '@edgebasejs/client-core';
|
|
5
|
+
import AsyncStorageAdapter from './storage/async-storage-adapter';
|
|
6
|
+
export const EdgeBaseContext = React.createContext(null);
|
|
7
|
+
/**
|
|
8
|
+
* EdgeBase provider component
|
|
9
|
+
* Wraps the app to provide EdgeBase functionality via context
|
|
10
|
+
*/
|
|
11
|
+
export function EdgeBaseProvider({ apiUrl, children, useMemoryStorage = false, }) {
|
|
12
|
+
const [value, setValue] = useState(null);
|
|
13
|
+
const [isInitializing, setIsInitializing] = useState(true);
|
|
14
|
+
const [initError, setInitError] = useState(null);
|
|
15
|
+
useEffect(() => {
|
|
16
|
+
(async () => {
|
|
17
|
+
try {
|
|
18
|
+
// Set up storage
|
|
19
|
+
const storage = useMemoryStorage ? new MemoryStorageAdapter() : new AsyncStorageAdapter();
|
|
20
|
+
// Create auth manager
|
|
21
|
+
const authManager = new AuthManager({
|
|
22
|
+
apiUrl,
|
|
23
|
+
storage,
|
|
24
|
+
});
|
|
25
|
+
await authManager.init();
|
|
26
|
+
// Create outbox manager
|
|
27
|
+
const outboxManager = new OutboxManager(storage);
|
|
28
|
+
await outboxManager.init();
|
|
29
|
+
// Create sync engine
|
|
30
|
+
const accessToken = authManager.getAccessToken();
|
|
31
|
+
const syncEngine = new ClientSyncEngine({
|
|
32
|
+
apiUrl,
|
|
33
|
+
accessToken: accessToken || '',
|
|
34
|
+
storage,
|
|
35
|
+
outboxManager,
|
|
36
|
+
onConflict: (entity, recordId, serverData) => {
|
|
37
|
+
console.log(`Conflict on ${entity}:${recordId}, accepting server version`);
|
|
38
|
+
},
|
|
39
|
+
onError: (error) => {
|
|
40
|
+
console.error('Sync error:', error);
|
|
41
|
+
},
|
|
42
|
+
});
|
|
43
|
+
await syncEngine.init();
|
|
44
|
+
// Subscribe to auth state changes to update sync engine token
|
|
45
|
+
authManager.subscribe((state) => {
|
|
46
|
+
if (state.accessToken) {
|
|
47
|
+
syncEngine.setAccessToken(state.accessToken);
|
|
48
|
+
}
|
|
49
|
+
});
|
|
50
|
+
setValue({
|
|
51
|
+
storage,
|
|
52
|
+
authManager,
|
|
53
|
+
syncEngine,
|
|
54
|
+
outboxManager,
|
|
55
|
+
isInitialized: true,
|
|
56
|
+
});
|
|
57
|
+
}
|
|
58
|
+
catch (error) {
|
|
59
|
+
const err = error instanceof Error ? error : new Error('Initialization failed');
|
|
60
|
+
console.error('EdgeBase initialization error:', err);
|
|
61
|
+
setInitError(err);
|
|
62
|
+
}
|
|
63
|
+
finally {
|
|
64
|
+
setIsInitializing(false);
|
|
65
|
+
}
|
|
66
|
+
})();
|
|
67
|
+
}, [apiUrl, useMemoryStorage]);
|
|
68
|
+
if (isInitializing) {
|
|
69
|
+
return (_jsxs(View, { style: {
|
|
70
|
+
flex: 1,
|
|
71
|
+
justifyContent: 'center',
|
|
72
|
+
alignItems: 'center',
|
|
73
|
+
backgroundColor: '#f5f5f5',
|
|
74
|
+
}, children: [_jsx(ActivityIndicator, { size: "large", color: "#007AFF" }), _jsx(Text, { style: { marginTop: 12, fontSize: 14, color: '#666' }, children: "Initializing EdgeBase..." })] }));
|
|
75
|
+
}
|
|
76
|
+
if (initError) {
|
|
77
|
+
return (_jsxs(View, { style: {
|
|
78
|
+
flex: 1,
|
|
79
|
+
justifyContent: 'center',
|
|
80
|
+
alignItems: 'center',
|
|
81
|
+
backgroundColor: '#f5f5f5',
|
|
82
|
+
}, children: [_jsx(Text, { style: { fontSize: 16, color: '#ff6b6b', fontWeight: 'bold' }, children: "Initialization Error" }), _jsx(Text, { style: {
|
|
83
|
+
marginTop: 8,
|
|
84
|
+
fontSize: 12,
|
|
85
|
+
color: '#666',
|
|
86
|
+
paddingHorizontal: 20,
|
|
87
|
+
textAlign: 'center',
|
|
88
|
+
}, children: initError.message })] }));
|
|
89
|
+
}
|
|
90
|
+
return _jsx(EdgeBaseContext.Provider, { value: value, children: children });
|
|
91
|
+
}
|
|
92
|
+
//# sourceMappingURL=provider.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"provider.js","sourceRoot":"","sources":["../../../src/provider.tsx"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import type { IStorageAdapter } from '@edgebasejs/client-core';
|
|
2
|
+
/**
|
|
3
|
+
* AsyncStorage adapter for React Native
|
|
4
|
+
*/
|
|
5
|
+
export declare class AsyncStorageAdapter implements IStorageAdapter {
|
|
6
|
+
getItem(key: string): Promise<string | null>;
|
|
7
|
+
setItem(key: string, value: string): Promise<void>;
|
|
8
|
+
removeItem(key: string): Promise<void>;
|
|
9
|
+
clear(): Promise<void>;
|
|
10
|
+
getAllKeys(): Promise<string[]>;
|
|
11
|
+
multiGet(keys: string[]): Promise<Array<[string, string | null]>>;
|
|
12
|
+
multiSet(items: Array<[string, string]>): Promise<void>;
|
|
13
|
+
multiRemove(keys: string[]): Promise<void>;
|
|
14
|
+
}
|
|
15
|
+
export default AsyncStorageAdapter;
|
|
16
|
+
//# sourceMappingURL=async-storage-adapter.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"async-storage-adapter.d.ts","sourceRoot":"","sources":["../../../../src/storage/async-storage-adapter.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,yBAAyB,CAAC;AAE/D;;GAEG;AACH,qBAAa,mBAAoB,YAAW,eAAe;IACnD,OAAO,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC;IAS5C,OAAO,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAQlD,UAAU,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAQtC,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAQtB,UAAU,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC;IAU/B,QAAQ,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,KAAK,CAAC,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC,CAAC,CAAC;IAUjE,QAAQ,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC;IAQvD,WAAW,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC;CAOjD;AAED,eAAe,mBAAmB,CAAC"}
|