@aerostack/sdk-react 0.6.6 → 0.6.8
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/package.json +2 -2
- package/src/context.tsx +20 -3
- package/src/hooks/useSubscription.ts +26 -6
- package/src/index.ts +1 -0
- package/test-realtime-import.ts +2 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@aerostack/sdk-react",
|
|
3
|
-
"version": "0.6.
|
|
3
|
+
"version": "0.6.8",
|
|
4
4
|
"author": "Aerostack",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"repository": {
|
|
@@ -41,7 +41,7 @@
|
|
|
41
41
|
"typescript-eslint": "^8.26.0"
|
|
42
42
|
},
|
|
43
43
|
"dependencies": {
|
|
44
|
-
"@aerostack/sdk-web": "^0.6.
|
|
44
|
+
"@aerostack/sdk-web": "^0.6.8"
|
|
45
45
|
},
|
|
46
46
|
"exports": {
|
|
47
47
|
".": {
|
package/src/context.tsx
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import React, { createContext, useContext, useMemo } from 'react';
|
|
2
2
|
import { SDK } from '@aerostack/sdk-web';
|
|
3
|
+
import { RealtimeClient } from '@aerostack/sdk-web/sdk/realtime.js';
|
|
3
4
|
|
|
4
5
|
export interface AerostackContextType {
|
|
5
|
-
sdk: SDK;
|
|
6
|
+
sdk: SDK & { realtime?: RealtimeClient };
|
|
6
7
|
projectId: string;
|
|
7
8
|
}
|
|
8
9
|
|
|
@@ -10,12 +11,14 @@ const AerostackContext = createContext<AerostackContextType | null>(null);
|
|
|
10
11
|
|
|
11
12
|
export interface AerostackProviderProps {
|
|
12
13
|
projectId: string;
|
|
14
|
+
apiKey?: string;
|
|
13
15
|
baseUrl?: string;
|
|
14
16
|
children: React.ReactNode;
|
|
15
17
|
}
|
|
16
18
|
|
|
17
19
|
export const AerostackProvider: React.FC<AerostackProviderProps> = ({
|
|
18
20
|
projectId,
|
|
21
|
+
apiKey,
|
|
19
22
|
baseUrl = 'https://api.aerostack.ai/v1',
|
|
20
23
|
children,
|
|
21
24
|
}) => {
|
|
@@ -26,10 +29,24 @@ export const AerostackProvider: React.FC<AerostackProviderProps> = ({
|
|
|
26
29
|
if (mod.setProjectId) mod.setProjectId(projectId);
|
|
27
30
|
});
|
|
28
31
|
|
|
29
|
-
|
|
32
|
+
const client = new SDK({
|
|
30
33
|
serverURL: baseUrl,
|
|
34
|
+
apiKeyAuth: apiKey,
|
|
31
35
|
});
|
|
32
|
-
|
|
36
|
+
|
|
37
|
+
// Instantiate RealtimeClient and attach it to the SDK instance
|
|
38
|
+
// so that useSubscription and App code can access 'sdk.realtime'
|
|
39
|
+
const realtime = new RealtimeClient({
|
|
40
|
+
baseUrl,
|
|
41
|
+
projectId,
|
|
42
|
+
apiKey,
|
|
43
|
+
});
|
|
44
|
+
|
|
45
|
+
// Expose realtime on the SDK instance
|
|
46
|
+
(client as any).realtime = realtime;
|
|
47
|
+
|
|
48
|
+
return client as SDK & { realtime: RealtimeClient };
|
|
49
|
+
}, [baseUrl, projectId, apiKey]);
|
|
33
50
|
|
|
34
51
|
const value = useMemo(() => ({
|
|
35
52
|
sdk,
|
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
import { useEffect, useState } from 'react';
|
|
1
|
+
import { useEffect, useState, useRef } from 'react';
|
|
2
2
|
import { useAerostack } from '../context.js';
|
|
3
|
+
|
|
3
4
|
export interface RealtimeSubscriptionOptions {
|
|
4
5
|
event?: 'INSERT' | 'UPDATE' | 'DELETE' | '*';
|
|
5
6
|
filter?: Record<string, any>;
|
|
@@ -19,6 +20,9 @@ export function useSubscription<T = any>(
|
|
|
19
20
|
const [data, setData] = useState<T | null>(null);
|
|
20
21
|
const [error, setError] = useState<Error | null>(null);
|
|
21
22
|
const [loading, setLoading] = useState(true);
|
|
23
|
+
// Fix A15: Stable reference for options to prevent re-render loops
|
|
24
|
+
const optionsRef = useRef(options);
|
|
25
|
+
optionsRef.current = options;
|
|
22
26
|
|
|
23
27
|
useEffect(() => {
|
|
24
28
|
let isMounted = true;
|
|
@@ -30,7 +34,7 @@ export function useSubscription<T = any>(
|
|
|
30
34
|
return;
|
|
31
35
|
}
|
|
32
36
|
|
|
33
|
-
const channel = realtime.channel(topic,
|
|
37
|
+
const channel = realtime.channel(topic, optionsRef.current);
|
|
34
38
|
|
|
35
39
|
const setup = async () => {
|
|
36
40
|
try {
|
|
@@ -54,13 +58,29 @@ export function useSubscription<T = any>(
|
|
|
54
58
|
|
|
55
59
|
setup();
|
|
56
60
|
|
|
61
|
+
// Fix 1.5: Properly unsubscribe on cleanup
|
|
57
62
|
return () => {
|
|
58
63
|
isMounted = false;
|
|
59
|
-
|
|
60
|
-
// but we could unsubscribe from the channel if needed.
|
|
61
|
-
// channel.unsubscribe();
|
|
64
|
+
channel.unsubscribe();
|
|
62
65
|
};
|
|
63
|
-
}, [sdk, topic
|
|
66
|
+
}, [sdk, topic]);
|
|
64
67
|
|
|
65
68
|
return { data, error, loading };
|
|
66
69
|
}
|
|
70
|
+
|
|
71
|
+
/**
|
|
72
|
+
* Hook to observe the realtime connection status
|
|
73
|
+
*/
|
|
74
|
+
export function useRealtimeStatus() {
|
|
75
|
+
const { sdk } = useAerostack();
|
|
76
|
+
const realtime = (sdk as any).realtime;
|
|
77
|
+
const [status, setStatus] = useState<string>(realtime?.status ?? 'idle');
|
|
78
|
+
|
|
79
|
+
useEffect(() => {
|
|
80
|
+
if (!realtime || !realtime.onStatusChange) return;
|
|
81
|
+
const unsub = realtime.onStatusChange((s: string) => setStatus(s));
|
|
82
|
+
return unsub;
|
|
83
|
+
}, [realtime]);
|
|
84
|
+
|
|
85
|
+
return status;
|
|
86
|
+
}
|
package/src/index.ts
CHANGED
|
@@ -3,6 +3,7 @@ export * from './hooks/useAuth.js';
|
|
|
3
3
|
export * from './hooks/useDb.js';
|
|
4
4
|
export * from './hooks/useAI.js';
|
|
5
5
|
export * from './hooks/useCache.js';
|
|
6
|
+
export * from './hooks/useSubscription.js';
|
|
6
7
|
|
|
7
8
|
// Re-export core types and client for convenience
|
|
8
9
|
import { SDK, SDKOptions } from '@aerostack/sdk-web';
|