1 | import { reportError, clearError } from "./error-overlay-handler"
|
2 | import normalizePagePath from "./normalize-page-path"
|
3 |
|
4 | let socket = null
|
5 |
|
6 | let staticQueryData = {}
|
7 | let pageQueryData = {}
|
8 | let isInitialized = false
|
9 |
|
10 | export const getStaticQueryData = () => staticQueryData
|
11 | export const getPageQueryData = () => pageQueryData
|
12 | export const getIsInitialized = () => isInitialized
|
13 |
|
14 | export default function socketIo() {
|
15 | if (process.env.NODE_ENV !== `production`) {
|
16 | if (!socket) {
|
17 |
|
18 | try {
|
19 |
|
20 | socket = io()
|
21 |
|
22 | const didDataChange = (msg, queryData) => {
|
23 | const id =
|
24 | msg.type === `staticQueryResult`
|
25 | ? msg.payload.id
|
26 | : normalizePagePath(msg.payload.id)
|
27 | return (
|
28 | !(id in queryData) ||
|
29 | JSON.stringify(msg.payload.result) !== JSON.stringify(queryData[id])
|
30 | )
|
31 | }
|
32 |
|
33 | socket.on(`message`, msg => {
|
34 | if (msg.type === `staticQueryResult`) {
|
35 | if (didDataChange(msg, staticQueryData)) {
|
36 | staticQueryData = {
|
37 | ...staticQueryData,
|
38 | [msg.payload.id]: msg.payload.result,
|
39 | }
|
40 | }
|
41 | } else if (msg.type === `pageQueryResult`) {
|
42 | if (didDataChange(msg, pageQueryData)) {
|
43 | pageQueryData = {
|
44 | ...pageQueryData,
|
45 | [normalizePagePath(msg.payload.id)]: msg.payload.result,
|
46 | }
|
47 | }
|
48 | } else if (msg.type === `overlayError`) {
|
49 | if (msg.payload.message) {
|
50 | reportError(msg.payload.id, msg.payload.message)
|
51 | } else {
|
52 | clearError(msg.payload.id)
|
53 | }
|
54 | }
|
55 | if (msg.type && msg.payload) {
|
56 | ___emitter.emit(msg.type, msg.payload)
|
57 | }
|
58 | })
|
59 | } catch (err) {
|
60 | console.error(`Could not connect to socket.io on dev server.`)
|
61 | }
|
62 | }
|
63 | return socket
|
64 | } else {
|
65 | return null
|
66 | }
|
67 | }
|
68 |
|
69 | const inFlightGetPageDataPromiseCache = {}
|
70 | function getPageData(pathname) {
|
71 | pathname = normalizePagePath(pathname)
|
72 | if (inFlightGetPageDataPromiseCache[pathname]) {
|
73 | return inFlightGetPageDataPromiseCache[pathname]
|
74 | } else {
|
75 | inFlightGetPageDataPromiseCache[pathname] = new Promise(resolve => {
|
76 | if (pageQueryData[pathname]) {
|
77 | delete inFlightGetPageDataPromiseCache[pathname]
|
78 | resolve(pageQueryData[pathname])
|
79 | } else {
|
80 | const onPageDataCallback = msg => {
|
81 | if (
|
82 | msg.type === `pageQueryResult` &&
|
83 | normalizePagePath(msg.payload.id) === pathname
|
84 | ) {
|
85 | socket.off(`message`, onPageDataCallback)
|
86 | delete inFlightGetPageDataPromiseCache[pathname]
|
87 | resolve(pageQueryData[pathname])
|
88 | }
|
89 | }
|
90 | socket.on(`message`, onPageDataCallback)
|
91 |
|
92 | socket.emit(`getDataForPath`, pathname)
|
93 | }
|
94 | })
|
95 | }
|
96 | return inFlightGetPageDataPromiseCache[pathname]
|
97 | }
|
98 |
|
99 |
|
100 |
|
101 |
|
102 | function registerPath(path) {
|
103 | socket.emit(`registerPath`, path)
|
104 | }
|
105 |
|
106 |
|
107 | function unregisterPath(path) {
|
108 | socket.emit(`unregisterPath`, path)
|
109 | }
|
110 |
|
111 | export { getPageData, registerPath, unregisterPath }
|