1-
21import * as react from "react" ;
32import * as reactDOM from "react-dom" ;
43import htm from "htm" ;
@@ -9,13 +8,7 @@ import serializeEvent from "./event-to-object";
98const html = htm . bind ( react . createElement ) ;
109const alreadyImported = { } ;
1110
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 ) {
1912 if ( endpoint . startsWith ( "." ) || endpoint . startsWith ( "/" ) ) {
2013 let loc = window . location ;
2114 let protocol ;
@@ -31,36 +24,53 @@ export default function Layout({ endpoint }) {
3124 endpoint = new_uri + endpoint ;
3225 }
3326
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 ) ;
5128
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+ ) ;
5969 } ) ;
60- } ;
70+ } , [ model ] ) ;
6171
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 } /> ` ;
6474 } else {
6575 return html `< div /> ` ;
6676 }
0 commit comments