135135 < div class ="lds-dual-ring "> </ div >
136136</ div >
137137
138- </ body >
138+ < script > "use strict" ;
139+
140+ ( function ( ) {
141+
142+ const address = '{{__TRUNK_ADDRESS__}}' ;
143+ const base = '{{__TRUNK_WS_BASE__}}' ;
144+ let protocol = '' ;
145+ protocol =
146+ protocol
147+ ? protocol
148+ : window . location . protocol === 'https:'
149+ ? 'wss'
150+ : 'ws' ;
151+ const url = protocol + '://' + address + base + '.well-known/trunk/ws' ;
152+
153+ class Overlay {
154+ constructor ( ) {
155+ // create an overlay
156+ this . _overlay = document . createElement ( "div" ) ;
157+ const style = this . _overlay . style ;
158+ style . height = "100vh" ;
159+ style . width = "100vw" ;
160+ style . position = "fixed" ;
161+ style . top = "0" ;
162+ style . left = "0" ;
163+ style . backgroundColor = "rgba(222, 222, 222, 0.5)" ;
164+ style . fontFamily = "sans-serif" ;
165+ // not sure that's the right approach
166+ style . zIndex = "1000000" ;
167+ style . backdropFilter = "blur(1rem)" ;
168+
169+ const container = document . createElement ( "div" ) ;
170+ // center it
171+ container . style . position = "absolute" ;
172+ container . style . top = "30%" ;
173+ container . style . left = "15%" ;
174+ container . style . maxWidth = "85%" ;
175+
176+ this . _title = document . createElement ( "div" ) ;
177+ this . _title . innerText = "Build failure" ;
178+ this . _title . style . paddingBottom = "2rem" ;
179+ this . _title . style . fontSize = "2.5rem" ;
180+
181+ this . _message = document . createElement ( "div" ) ;
182+ this . _message . style . whiteSpace = "pre-wrap" ;
183+
184+ const icon = document . createElement ( "div" ) ;
185+ icon . innerHTML = '<svg xmlns="http://www.w3.org/2000/svg" width="64" height="64" fill="#dc3545" viewBox="0 0 16 16"><path d="M8.982 1.566a1.13 1.13 0 0 0-1.96 0L.165 13.233c-.457.778.091 1.767.98 1.767h13.713c.889 0 1.438-.99.98-1.767L8.982 1.566zM8 5c.535 0 .954.462.9.995l-.35 3.507a.552.552 0 0 1-1.1 0L7.1 5.995A.905.905 0 0 1 8 5zm.002 6a1 1 0 1 1 0 2 1 1 0 0 1 0-2z"/></svg>' ;
186+ this . _title . prepend ( icon ) ;
187+
188+ container . append ( this . _title , this . _message ) ;
189+ this . _overlay . append ( container ) ;
190+
191+ this . _inject ( ) ;
192+ window . setInterval ( ( ) => {
193+ this . _inject ( ) ;
194+ } , 250 ) ;
195+ }
196+
197+ set reason ( reason ) {
198+ this . _message . textContent = reason ;
199+ }
200+
201+ _inject ( ) {
202+ if ( ! this . _overlay . isConnected ) {
203+ // prepend it
204+ document . body ?. prepend ( this . _overlay ) ;
205+ }
206+ }
207+
208+ }
209+
210+ class Client {
211+ constructor ( url ) {
212+ this . url = url ;
213+ this . poll_interval = 5000 ;
214+ this . _overlay = null ;
215+ }
216+
217+ start ( ) {
218+ const ws = new WebSocket ( this . url ) ;
219+ ws . onmessage = ( ev ) => {
220+ const msg = JSON . parse ( ev . data ) ;
221+ switch ( msg . type ) {
222+ case "reload" :
223+ this . reload ( ) ;
224+ break ;
225+ case "buildFailure" :
226+ this . buildFailure ( msg . data )
227+ break ;
228+ }
229+ } ;
230+ ws . onclose = ( ) => this . onclose ( ) ;
231+ }
232+
233+ onclose ( ) {
234+ window . setTimeout (
235+ ( ) => {
236+ // when we successfully reconnect, we'll force a
237+ // reload (since we presumably lost connection to
238+ // trunk due to it being killed, so it will have
239+ // rebuilt on restart)
240+ const ws = new WebSocket ( this . url ) ;
241+ ws . onopen = ( ) => window . location . reload ( ) ;
242+ ws . onclose = ( ) => this . onclose ( ) ;
243+ } ,
244+ this . poll_interval ) ;
245+ }
246+
247+ reload ( ) {
248+ window . location . reload ( ) ;
249+ }
250+
251+ buildFailure ( { reason} ) {
252+ // also log the console
253+ console . error ( "Build failed:" , reason ) ;
254+
255+ console . debug ( "Overlay" , this . _overlay ) ;
256+
257+ if ( ! this . _overlay ) {
258+ this . _overlay = new Overlay ( ) ;
259+ }
260+ this . _overlay . reason = reason ;
261+ }
262+ }
263+
264+ new Client ( url ) . start ( ) ;
265+
266+ } ) ( )
267+ </ script > </ body >
139268
140269</ html >
0 commit comments