1
1
import { useEffect , useState } from "react" ;
2
- import has from "lodash/has " ;
3
- import { PagedCollection } from "../types/Collection " ;
2
+ import { PagedCollection , isPagedCollection } from "../types/collection " ;
3
+ import { isItem } from "../types/item " ;
4
4
import { normalize } from "./dataAccess" ;
5
5
6
- const mercureSubscribe = ( hubURL : string , data : unknown | PagedCollection < unknown > , setData : ( data : unknown ) => void ) => {
6
+ const mercureSubscribe = < T > ( hubURL : string , data : T | PagedCollection < T > , setData : ( data : T ) => void ) => {
7
7
const url = new URL ( hubURL , window . origin ) ;
8
8
url . searchParams . append ( "topic" , ( new URL ( data [ "@id" ] , window . origin ) ) . toString ( ) ) ;
9
9
const eventSource = new EventSource ( url . toString ( ) ) ;
@@ -12,34 +12,44 @@ const mercureSubscribe = (hubURL: string, data: unknown | PagedCollection<unknow
12
12
return eventSource ;
13
13
}
14
14
15
- export const useMercure = ( deps : unknown | PagedCollection < unknown > , hubURL : string | null ) => {
15
+ export const useMercure = < T > ( deps : T | PagedCollection < T > , hubURL : string | null ) => {
16
16
const [ data , setData ] = useState ( deps ) ;
17
17
18
18
useEffect ( ( ) => {
19
19
setData ( deps ) ;
20
20
} , [ deps ] ) ;
21
21
22
22
useEffect ( ( ) => {
23
- if ( ! has ( data , "{{{hydraPrefix}}}member" ) && ! has ( data , "@id" ) ) {
23
+ if ( ! hubURL || ! data ) {
24
+ return ;
25
+ }
26
+
27
+ if ( ! isPagedCollection ( data ) && ! isItem ( data ) ) {
24
28
console . error ( "Object sent is not in JSON-LD format." ) ;
25
29
30
+ return ;
26
31
}
27
32
28
- if ( hubURL && has ( data , "{{{hydraPrefix}}}member" ) && Array . isArray ( data [ "{{{hydraPrefix}}}member" ] ) && data [ "{{{hydraPrefix}}}member" ] . length !== 0 ) {
33
+ if ( isPagedCollection ( data ) && data [ "{{{hydraPrefix}}}member" ] . length !== 0 ) {
34
+ const eventSources : EventSource [ ] = [ ] ;
29
35
// It's a PagedCollection
30
- data [ "{{{hydraPrefix}}}member" ] . forEach ( ( obj , pos ) => mercureSubscribe ( hubURL , obj , ( datum ) => {
31
- data [ "{{{hydraPrefix}}}member" ] [ pos ] = datum ;
32
- setData ( data ) ;
33
- } ) ) ;
34
-
36
+ data [ "{{{hydraPrefix}}}member" ] . forEach ( ( obj , pos ) => {
37
+ eventSources . push ( mercureSubscribe ( hubURL , obj , ( datum : T ) => {
38
+ data [ "{{{hydraPrefix}}}member" ] [ pos ] = datum ;
39
+ setData ( { ...data } ) ;
40
+ } ) ) ;
41
+ } ) ;
42
+
43
+ return ( ) => {
44
+ eventSources . forEach ( ( eventSource ) => eventSource . close ( ) ) ;
45
+ } ;
35
46
}
36
47
37
48
// It's a single object
38
49
const eventSource = mercureSubscribe ( hubURL , data , setData ) ;
39
50
40
51
return ( ) => {
41
- eventSource . removeEventListener ( "message" , ( event ) => setData ( normalize ( JSON . parse ( event . data ) ) ) ) ;
42
-
52
+ eventSource . close ( ) ;
43
53
} ;
44
54
} , [ data ] ) ;
45
55
0 commit comments