1
-
2
1
import * as react from "react" ;
3
2
import * as reactDOM from "react-dom" ;
4
3
import htm from "htm" ;
@@ -9,13 +8,7 @@ import serializeEvent from "./event-to-object";
9
8
const html = htm . bind ( react . createElement ) ;
10
9
const alreadyImported = { } ;
11
10
12
- export function renderLayout ( mountElement , endpoint ) {
13
- const cmpt = html `< ${ Layout } endpoint =${ endpoint } /> ` ;
14
- return reactDOM . render ( cmpt , mountElement ) ;
15
- }
16
-
17
- export default function Layout ( { endpoint } ) {
18
- // handle relative endpoint URI
11
+ export function mountLayoutWithWebSocket ( mountElement , endpoint ) {
19
12
if ( endpoint . startsWith ( "." ) || endpoint . startsWith ( "/" ) ) {
20
13
let loc = window . location ;
21
14
let protocol ;
@@ -31,36 +24,53 @@ export default function Layout({ endpoint }) {
31
24
endpoint = new_uri + endpoint ;
32
25
}
33
26
34
- const socket = react . useMemo ( ( ) => new WebSocket ( endpoint ) , [ endpoint ] ) ;
35
- const [ state , setState ] = react . useState ( { model : { } } ) ;
36
-
37
- socket . onmessage = ( event ) => {
38
- const [ pathPrefix , patch ] = JSON . parse ( event . data ) ;
39
- setState ( {
40
- model : jsonpatch . applyPatch (
41
- state . model ,
42
- patch . map ( ( op ) => {
43
- op . path = pathPrefix + op . path ;
44
- return op ;
45
- } ) ,
46
- undefined ,
47
- false
48
- ) . newDocument ,
49
- } ) ;
50
- } ;
27
+ const ws = new WebSocket ( endpoint ) ;
51
28
52
- const sendMsg = ( msg ) => {
53
- socket . send ( JSON . stringify ( msg ) ) ;
54
- } ;
55
- const sendEvent = ( event ) => {
56
- sendMsg ( {
57
- header : { } ,
58
- body : { event : event } ,
29
+ function registerUpdateCallback ( update ) {
30
+ ws . onmessage = ( event ) => {
31
+ const [ pathPrefix , patch ] = JSON . parse ( event . data ) ;
32
+ update ( pathPrefix , patch ) ;
33
+ } ;
34
+ }
35
+
36
+ function sendCallback ( event ) {
37
+ ws . send (
38
+ JSON . stringify ( {
39
+ header : { } ,
40
+ body : { event : event } ,
41
+ } )
42
+ ) ;
43
+ }
44
+
45
+ const cmpt = html `< ${ Layout }
46
+ registerUpdateCallback =${ registerUpdateCallback }
47
+ sendCallback=${ sendCallback }
48
+ /> ` ;
49
+
50
+ return reactDOM . render ( cmpt , mountElement ) ;
51
+ }
52
+
53
+ export default function Layout ( { registerUpdateCallback, sendCallback } ) {
54
+ const [ model , setModel ] = react . useState ( { } ) ;
55
+
56
+ react . useEffect ( ( ) => {
57
+ registerUpdateCallback ( ( pathPrefix , patch ) => {
58
+ setModel (
59
+ jsonpatch . applyPatch (
60
+ model ,
61
+ patch . map ( ( op ) => {
62
+ op . path = pathPrefix + op . path ;
63
+ return op ;
64
+ } ) ,
65
+ undefined ,
66
+ false
67
+ ) . newDocument
68
+ ) ;
59
69
} ) ;
60
- } ;
70
+ } , [ model ] ) ;
61
71
62
- if ( state . model . tagName ) {
63
- return html `< ${ Element } sendEvent =${ sendEvent } model=${ state . model } /> ` ;
72
+ if ( model . tagName ) {
73
+ return html `< ${ Element } sendEvent =${ sendCallback } model=${ model } /> ` ;
64
74
} else {
65
75
return html `< div /> ` ;
66
76
}
0 commit comments