forked from phcode-dev/staging.phcode.dev
-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathpageLoaderWorker.js
More file actions
1 lines (1 loc) · 4.72 KB
/
pageLoaderWorker.js
File metadata and controls
1 lines (1 loc) · 4.72 KB
1
let _livePreviewBroadcastChannel,_livePreviewWebSocket,_livePreviewWebSocketOpen=!1,livePreviewDebugModeEnabled=!1;function _debugLog(...args){livePreviewDebugModeEnabled&&console.log(...args)}function mergeMetadataAndArrayBuffer(metadata,bufferData){if(bufferData instanceof ArrayBuffer&&(metadata.hasBufferData=!0),bufferData=bufferData||new ArrayBuffer(0),"object"!=typeof metadata)throw new Error("metadata should be an object, but was "+typeof metadata);if(!(bufferData instanceof ArrayBuffer))throw new Error("Expected bufferData to be an instance of ArrayBuffer, but was "+typeof bufferData);const metadataString=JSON.stringify(metadata),metadataUint8Array=(new TextEncoder).encode(metadataString),metadataBuffer=metadataUint8Array.buffer,sizePrefixLength=4;if(metadataBuffer.byteLength>4294e6)throw new Error("metadata too large. Should be below 4,294MB, but was "+metadataBuffer.byteLength);const concatenatedBuffer=new ArrayBuffer(4+metadataBuffer.byteLength+bufferData.byteLength),concatenatedUint8Array=new Uint8Array(concatenatedBuffer);return new DataView(concatenatedBuffer).setUint32(0,metadataBuffer.byteLength,!0),concatenatedUint8Array.set(metadataUint8Array,4),bufferData.byteLength>0&&concatenatedUint8Array.set(new Uint8Array(bufferData),4+metadataBuffer.byteLength),concatenatedBuffer}function splitMetadataAndBuffer(concatenatedBuffer){if(!(concatenatedBuffer instanceof ArrayBuffer))throw new Error("Expected ArrayBuffer message from websocket");const sizePrefixLength=4,buffer1Length=new DataView(concatenatedBuffer).getUint32(0,!0),buffer1=concatenatedBuffer.slice(4,4+buffer1Length),metadata=JSON.parse((new TextDecoder).decode(buffer1));let buffer2;return concatenatedBuffer.byteLength>4+buffer1Length&&(buffer2=concatenatedBuffer.slice(4+buffer1Length)),!buffer2&&metadata.hasBufferData&&(buffer2=new ArrayBuffer(0)),{metadata:metadata,bufferData:buffer2}}let messageQueue=[];function _sendMessage(message){_livePreviewWebSocket&&_livePreviewWebSocketOpen?_livePreviewWebSocket.send(mergeMetadataAndArrayBuffer(message)):_livePreviewBroadcastChannel?_livePreviewBroadcastChannel.postMessage(message):(livePreviewDebugModeEnabled&&console.warn("No Channels available for live preview worker messaging, queueing request, waiting for channel.."),messageQueue.push(message))}function flushPendingMessages(){const savedMessageQueue=messageQueue;messageQueue=[];for(let message of savedMessageQueue)_sendMessage(message)}function _setupHearbeatMessenger(clientID){function _sendOnlineHeartbeat(){_sendMessage({type:"TAB_ONLINE",clientID:clientID,URL:location.href})}_sendOnlineHeartbeat(),setInterval(()=>{_sendOnlineHeartbeat()},3e3)}function _setupBroadcastChannel(broadcastChannel,clientID){(_livePreviewBroadcastChannel=new BroadcastChannel(broadcastChannel)).onmessage=(event=>{const type=event.data.type;switch(type){case"TAB_ONLINE":break;default:postMessage(event.data)}}),_setupHearbeatMessenger(clientID)}function _setupWebsocketChannel(wssEndpoint,clientID){_debugLog("live preview worker websocket url: ",wssEndpoint),(_livePreviewWebSocket=new WebSocket(wssEndpoint)).binaryType="arraybuffer",_livePreviewWebSocket.addEventListener("open",()=>{_debugLog("live preview worker websocket opened",wssEndpoint),_livePreviewWebSocketOpen=!0,_sendMessage({type:"CHANNEL_TYPE",channelName:"livePreviewChannel",pageLoaderID:clientID}),flushPendingMessages(),_setupHearbeatMessenger(clientID)}),_livePreviewWebSocket.addEventListener("message",function(event){const message=event.data,{metadata:metadata}=splitMetadataAndBuffer(message);_debugLog("Live Preview worker socket channel: Browser received event from Phoenix: ",metadata);const type=metadata.type;switch(type){case"TAB_ONLINE":break;default:postMessage(metadata)}}),_livePreviewWebSocket.addEventListener("error",function(event){console.error("Live Preview worker socket channel: error event: ",event)}),_livePreviewWebSocket.addEventListener("close",function(){_livePreviewWebSocketOpen=!1,_debugLog("Live Preview worker websocket closed")})}function updateTitleAndFavicon(event){_sendMessage({type:"UPDATE_TITLE_AND_ICON",title:event.data.title,faviconBase64:event.data.faviconBase64,URL:location.href})}onmessage=(event=>{const type=event.data.type;switch(type){case"setupPhoenixComm":livePreviewDebugModeEnabled=event.data.livePreviewDebugModeEnabled,event.data.broadcastChannel?_setupBroadcastChannel(event.data.broadcastChannel,event.data.clientID):event.data.websocketChannelURL?_setupWebsocketChannel(event.data.websocketChannelURL,event.data.clientID):console.error("No live preview worker communication channels! ",event.data);break;case"updateTitleIcon":updateTitleAndFavicon(event);break;case"livePreview":_sendMessage(event.data.message);break;default:console.error("Live Preview page worker: received unknown event:",event)}});