112 lines
3.3 KiB
JavaScript
112 lines
3.3 KiB
JavaScript
|
import { reportError, clearError } from "./error-overlay-handler"
|
||
|
import normalizePagePath from "./normalize-page-path"
|
||
|
|
||
|
let socket = null
|
||
|
|
||
|
let staticQueryData = {}
|
||
|
let pageQueryData = {}
|
||
|
let isInitialized = false
|
||
|
|
||
|
export const getStaticQueryData = () => staticQueryData
|
||
|
export const getPageQueryData = () => pageQueryData
|
||
|
export const getIsInitialized = () => isInitialized
|
||
|
|
||
|
export default function socketIo() {
|
||
|
if (process.env.NODE_ENV !== `production`) {
|
||
|
if (!socket) {
|
||
|
// Try to initialize web socket if we didn't do it already
|
||
|
try {
|
||
|
// eslint-disable-next-line no-undef
|
||
|
socket = io()
|
||
|
|
||
|
const didDataChange = (msg, queryData) => {
|
||
|
const id =
|
||
|
msg.type === `staticQueryResult`
|
||
|
? msg.payload.id
|
||
|
: normalizePagePath(msg.payload.id)
|
||
|
return (
|
||
|
!(id in queryData) ||
|
||
|
JSON.stringify(msg.payload.result) !== JSON.stringify(queryData[id])
|
||
|
)
|
||
|
}
|
||
|
|
||
|
socket.on(`message`, msg => {
|
||
|
if (msg.type === `staticQueryResult`) {
|
||
|
if (didDataChange(msg, staticQueryData)) {
|
||
|
staticQueryData = {
|
||
|
...staticQueryData,
|
||
|
[msg.payload.id]: msg.payload.result,
|
||
|
}
|
||
|
}
|
||
|
} else if (msg.type === `pageQueryResult`) {
|
||
|
if (didDataChange(msg, pageQueryData)) {
|
||
|
pageQueryData = {
|
||
|
...pageQueryData,
|
||
|
[normalizePagePath(msg.payload.id)]: msg.payload.result,
|
||
|
}
|
||
|
}
|
||
|
} else if (msg.type === `overlayError`) {
|
||
|
if (msg.payload.message) {
|
||
|
reportError(msg.payload.id, msg.payload.message)
|
||
|
} else {
|
||
|
clearError(msg.payload.id)
|
||
|
}
|
||
|
}
|
||
|
if (msg.type && msg.payload) {
|
||
|
___emitter.emit(msg.type, msg.payload)
|
||
|
}
|
||
|
})
|
||
|
} catch (err) {
|
||
|
console.error(`Could not connect to socket.io on dev server.`)
|
||
|
}
|
||
|
}
|
||
|
return socket
|
||
|
} else {
|
||
|
return null
|
||
|
}
|
||
|
}
|
||
|
|
||
|
const inFlightGetPageDataPromiseCache = {}
|
||
|
function getPageData(pathname) {
|
||
|
pathname = normalizePagePath(pathname)
|
||
|
if (inFlightGetPageDataPromiseCache[pathname]) {
|
||
|
return inFlightGetPageDataPromiseCache[pathname]
|
||
|
} else {
|
||
|
inFlightGetPageDataPromiseCache[pathname] = new Promise(resolve => {
|
||
|
if (pageQueryData[pathname]) {
|
||
|
delete inFlightGetPageDataPromiseCache[pathname]
|
||
|
resolve(pageQueryData[pathname])
|
||
|
} else {
|
||
|
const onPageDataCallback = msg => {
|
||
|
if (
|
||
|
msg.type === `pageQueryResult` &&
|
||
|
normalizePagePath(msg.payload.id) === pathname
|
||
|
) {
|
||
|
socket.off(`message`, onPageDataCallback)
|
||
|
delete inFlightGetPageDataPromiseCache[pathname]
|
||
|
resolve(pageQueryData[pathname])
|
||
|
}
|
||
|
}
|
||
|
socket.on(`message`, onPageDataCallback)
|
||
|
|
||
|
socket.emit(`getDataForPath`, pathname)
|
||
|
}
|
||
|
})
|
||
|
}
|
||
|
return inFlightGetPageDataPromiseCache[pathname]
|
||
|
}
|
||
|
|
||
|
// Tell websocket-manager.js the new path we're on.
|
||
|
// This will help the backend prioritize queries for this
|
||
|
// path.
|
||
|
function registerPath(path) {
|
||
|
socket.emit(`registerPath`, path)
|
||
|
}
|
||
|
|
||
|
// Unregister the former path
|
||
|
function unregisterPath(path) {
|
||
|
socket.emit(`unregisterPath`, path)
|
||
|
}
|
||
|
|
||
|
export { getPageData, registerPath, unregisterPath }
|