@aerostack/sdk-react 0.6.6 → 0.6.7

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 CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@aerostack/sdk-react",
3
- "version": "0.6.6",
3
+ "version": "0.6.7",
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.6"
44
+ "@aerostack/sdk-web": "^0.6.7"
45
45
  },
46
46
  "exports": {
47
47
  ".": {
@@ -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, options);
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
- // Note: We don't automatically disconnect the global client,
60
- // but we could unsubscribe from the channel if needed.
61
- // channel.unsubscribe();
64
+ channel.unsubscribe();
62
65
  };
63
- }, [sdk, topic, JSON.stringify(options)]);
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';