Skip to content

Commit aa4cac3

Browse files
kachartmm
andauthored
Pass selection options to useRealtme hook (#21)
* feat: added select options to useSubscription * feat: pass type to compare fn * test: added tests to cover new args * docs: update example * ci: update size (#23) * feat: update useRealtime args * feat: add default type * docs: highlight correct row Co-authored-by: Tom Meagher <[email protected]>
1 parent d908b34 commit aa4cac3

File tree

4 files changed

+51
-4
lines changed

4 files changed

+51
-4
lines changed

docs/pages/documentation/realtime/use-realtime.md

+27-1
Original file line numberDiff line numberDiff line change
@@ -18,12 +18,38 @@ You can pass a function for comparing subscription event changes. By default, th
1818

1919
When using your own compare function, you typically want to compare unique values:
2020

21-
```tsx highlight=6
21+
```tsx highlight=7
2222
import { useRealtime } from 'react-supabase'
2323

2424
function Page() {
2525
const [result, reexecute] = useRealtime(
2626
'todos',
27+
{ select: { columns:'id, username' } },
28+
(data, payload) => data.username === payload.username,
29+
)
30+
31+
return ...
32+
}
33+
```
34+
35+
## Initial selection of records
36+
37+
When initializing the component you might need to filter your data appropriately. You can pass the options directly to the `useSelect` hook.
38+
39+
First argument can be either a `string` table name or `useSelect` options with table property.
40+
41+
```tsx highlight=7,8,9,10
42+
import { useRealtime } from 'react-supabase'
43+
44+
function Page() {
45+
const [result, reexecute] = useRealtime(
46+
'todos',
47+
{
48+
select: {
49+
columns: 'id, username, description',
50+
filter: (query) => query.eq('completed', false),
51+
}
52+
},
2753
(data, payload) => data.username === payload.username,
2854
)
2955

src/hooks/realtime/use-realtime.ts

+8-3
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import { useEffect, useReducer } from 'react'
22
import { SupabaseRealtimePayload } from '@supabase/supabase-js'
33

4-
import { UseSelectState, useSelect } from '../data'
4+
import { UseSelectConfig, UseSelectState, useSelect } from '../data'
55
import { useSubscription } from './use-subscription'
66

77
export type UseRealtimeState<Data = any> = Omit<
@@ -23,6 +23,10 @@ export type UseRealtimeAction<Data = any> =
2323
| { type: 'FETCH'; payload: UseSelectState<Data> }
2424
| { type: 'SUBSCRIPTION'; payload: SupabaseRealtimePayload<Data> }
2525

26+
export type UseRealtimeConfig<Data = any> = {
27+
select?: Omit<UseSelectConfig<Data>, 'pause'>
28+
}
29+
2630
export type UseRealtimeCompareFn<Data = any> = (
2731
data: Data,
2832
payload: Data,
@@ -32,6 +36,7 @@ type CompareFnDefaultData<Data> = Data & { id: any }
3236

3337
export function useRealtime<Data = any>(
3438
table: string,
39+
config?: UseRealtimeConfig<Data>,
3540
compareFn: UseRealtimeCompareFn<Data> = (a, b) =>
3641
(<CompareFnDefaultData<Data>>a).id ===
3742
(<CompareFnDefaultData<Data>>b).id,
@@ -41,7 +46,7 @@ export function useRealtime<Data = any>(
4146
'Must specify table or row. Cannot listen for all database changes.',
4247
)
4348

44-
const [result, reexecute] = useSelect<Data>(table)
49+
const [result, reexecute] = useSelect<Data>(table, config?.select)
4550
const [state, dispatch] = useReducer<
4651
React.Reducer<UseRealtimeState<Data>, UseRealtimeAction<Data>>
4752
>(reducer(compareFn), result)
@@ -58,7 +63,7 @@ export function useRealtime<Data = any>(
5863
}
5964

6065
const reducer =
61-
<Data = any>(compareFn: UseRealtimeCompareFn) =>
66+
<Data = any>(compareFn: UseRealtimeCompareFn<Data>) =>
6267
(
6368
state: UseRealtimeState<Data>,
6469
action: UseRealtimeAction<Data>,

test/hooks/realtime/__snapshots__/use-realtime.test.tsx.snap

+2
Original file line numberDiff line numberDiff line change
@@ -3,3 +3,5 @@
33
exports[`useRealtime should throw when not inside Provider 1`] = `"No client has been specified using Provider."`;
44

55
exports[`useRealtime should throw when trying to listen all database changes 1`] = `"Must specify table or row. Cannot listen for all database changes."`;
6+
7+
exports[`useRealtime should throw when trying to listen all database changes via options 1`] = `"Must specify table or row. Cannot listen for all database changes."`;

test/hooks/realtime/use-realtime.test.tsx

+14
Original file line numberDiff line numberDiff line change
@@ -13,4 +13,18 @@ describe('useRealtime', () => {
1313
const { result } = renderHook(() => useRealtime('*'), { wrapper })
1414
expect(() => result.current).toThrowErrorMatchingSnapshot()
1515
})
16+
17+
it('should throw when trying to listen all database changes via options', () => {
18+
const { result } = renderHook(
19+
() =>
20+
useRealtime('*', {
21+
select: {
22+
columns: 'id, username, completed',
23+
filter: (query) => query.eq('completed', false),
24+
},
25+
}),
26+
{ wrapper },
27+
)
28+
expect(() => result.current).toThrowErrorMatchingSnapshot()
29+
})
1630
})

0 commit comments

Comments
 (0)