@@ -3,7 +3,7 @@ import path from "path"
3
3
import { store } from "../redux"
4
4
import { Server as HTTPSServer } from "https"
5
5
import { Server as HTTPServer } from "http"
6
- import fs from "fs"
6
+ import fs from "fs-extra "
7
7
import { readPageData , IPageDataWithQueryResult } from "../utils/page-data"
8
8
import telemetry from "gatsby-telemetry"
9
9
import url from "url"
@@ -25,87 +25,72 @@ type PageResultsMap = Map<string, IPageQueryResult>
25
25
type QueryResultsMap = Map < string , IStaticQueryResult >
26
26
27
27
/**
28
- * Get cached page query result for given page path.
28
+ * Get page query result for given page path.
29
29
* @param {string } pagePath Path to a page.
30
30
*/
31
- const getCachedPageData = async (
32
- pagePath : string
33
- ) : Promise < IPageQueryResult > => {
31
+ async function getPageData ( pagePath : string ) : Promise < IPageQueryResult > {
34
32
const { program, pages } = store . getState ( )
35
33
const publicDir = path . join ( program . directory , `public` )
34
+
35
+ const result : IPageQueryResult = {
36
+ id : pagePath ,
37
+ result : undefined ,
38
+ }
36
39
if ( pages . has ( denormalizePagePath ( pagePath ) ) || pages . has ( pagePath ) ) {
37
40
try {
38
41
const pageData : IPageDataWithQueryResult = await readPageData (
39
42
publicDir ,
40
43
pagePath
41
44
)
42
45
43
- return {
44
- result : pageData ,
45
- id : pagePath ,
46
- }
46
+ result . result = pageData
47
47
} catch ( err ) {
48
48
throw new Error (
49
49
`Error loading a result for the page query in "${ pagePath } ". Query was not run and no cached result was found.`
50
50
)
51
51
}
52
52
}
53
53
54
- return {
55
- id : pagePath ,
56
- result : undefined ,
57
- }
54
+ return result
58
55
}
59
56
60
- const hashPaths = (
61
- paths ?: Array < string >
62
- ) : undefined | Array < string | undefined > => {
63
- if ( ! paths ) {
64
- return undefined
57
+ /**
58
+ * Get page query result for given page path.
59
+ * @param {string } pagePath Path to a page.
60
+ */
61
+ async function getStaticQueryData (
62
+ staticQueryId : string
63
+ ) : Promise < IStaticQueryResult > {
64
+ const { program } = store . getState ( )
65
+ const publicDir = path . join ( program . directory , `public` )
66
+
67
+ const filePath = path . join (
68
+ publicDir ,
69
+ `page-data` ,
70
+ `sq` ,
71
+ `d` ,
72
+ `${ staticQueryId } .json`
73
+ )
74
+
75
+ const result : IStaticQueryResult = {
76
+ id : staticQueryId ,
77
+ result : undefined ,
65
78
}
66
- return paths . map ( path => {
67
- if ( ! path ) {
68
- return undefined
79
+ if ( await fs . pathExists ( filePath ) ) {
80
+ try {
81
+ const fileResult = await fs . readJson ( filePath )
82
+
83
+ result . result = fileResult
84
+ } catch ( err ) {
85
+ // ignore errors
69
86
}
70
- return createHash ( `sha256` ) . update ( path ) . digest ( `hex` )
71
- } )
87
+ }
88
+
89
+ return result
72
90
}
73
91
74
- /**
75
- * Get cached StaticQuery results for components that Gatsby didn't run query yet.
76
- * @param {QueryResultsMap } resultsMap Already stored results for queries that don't need to be read from files.
77
- * @param {string } directory Root directory of current project.
78
- */
79
- const getCachedStaticQueryResults = (
80
- resultsMap : QueryResultsMap ,
81
- directory : string
82
- ) : QueryResultsMap => {
83
- const cachedStaticQueryResults : QueryResultsMap = new Map ( )
84
- const { staticQueryComponents } = store . getState ( )
85
- staticQueryComponents . forEach ( staticQueryComponent => {
86
- // Don't read from file if results were already passed from query runner
87
- if ( resultsMap . has ( staticQueryComponent . hash ) ) return
88
- const filePath = path . join (
89
- directory ,
90
- `public` ,
91
- `page-data` ,
92
- `sq` ,
93
- `d` ,
94
- `${ staticQueryComponent . hash } .json`
95
- )
96
- const fileResult = fs . readFileSync ( filePath , `utf-8` )
97
- if ( fileResult === `undefined` ) {
98
- console . log (
99
- `Error loading a result for the StaticQuery in "${ staticQueryComponent . componentPath } ". Query was not run and no cached result was found.`
100
- )
101
- return
102
- }
103
- cachedStaticQueryResults . set ( staticQueryComponent . hash , {
104
- result : JSON . parse ( fileResult ) ,
105
- id : staticQueryComponent . hash ,
106
- } )
107
- } )
108
- return cachedStaticQueryResults
92
+ function hashPaths ( paths : Array < string > ) : Array < string > {
93
+ return paths . map ( path => createHash ( `sha256` ) . update ( path ) . digest ( `hex` ) )
109
94
}
110
95
111
96
const getRoomNameFromPath = ( path : string ) : string => `path-${ path } `
@@ -119,22 +104,17 @@ export class WebsocketManager {
119
104
websocket : socketIO . Server | undefined
120
105
121
106
init = ( {
122
- directory,
123
107
server,
124
108
} : {
125
109
directory : string
126
110
server : HTTPSServer | HTTPServer
127
111
} ) : socketIO . Server => {
128
- const cachedStaticQueryResults = getCachedStaticQueryResults (
129
- this . staticQueryResults ,
130
- directory
131
- )
132
- this . staticQueryResults = new Map ( [
133
- ...this . staticQueryResults ,
134
- ...cachedStaticQueryResults ,
135
- ] )
136
-
137
- this . websocket = socketIO ( server )
112
+ this . websocket = socketIO ( server , {
113
+ // we see ping-pong timeouts on gatsby-cloud when socket.io is running for a while
114
+ // increasing it should help
115
+ // @see https://github.com/socketio/socket.io/issues/3259#issuecomment-448058937
116
+ pingTimeout : 30000 ,
117
+ } )
138
118
139
119
this . websocket . on ( `connection` , socket => {
140
120
let activePath : string | null = null
@@ -147,13 +127,6 @@ export class WebsocketManager {
147
127
}
148
128
149
129
this . connectedClients += 1
150
- // Send already existing static query results
151
- this . staticQueryResults . forEach ( result => {
152
- socket . send ( {
153
- type : `staticQueryResult` ,
154
- payload : result ,
155
- } )
156
- } )
157
130
this . errors . forEach ( ( message , errorID ) => {
158
131
socket . send ( {
159
132
type : `overlayError` ,
@@ -176,22 +149,39 @@ export class WebsocketManager {
176
149
}
177
150
178
151
const getDataForPath = async ( path : string ) : Promise < void > => {
179
- if ( ! this . pageResults . has ( path ) ) {
152
+ let pageData = this . pageResults . get ( path )
153
+ if ( ! pageData ) {
180
154
try {
181
- const result = await getCachedPageData ( path )
155
+ pageData = await getPageData ( path )
182
156
183
- this . pageResults . set ( path , result )
157
+ this . pageResults . set ( path , pageData )
184
158
} catch ( err ) {
185
159
console . log ( err . message )
186
-
187
160
return
188
161
}
189
162
}
190
163
164
+ const staticQueryHashes = pageData . result ?. staticQueryHashes ?? [ ]
165
+ await Promise . all (
166
+ staticQueryHashes . map ( async queryId => {
167
+ let staticQueryResult = this . staticQueryResults . get ( queryId )
168
+
169
+ if ( ! staticQueryResult ) {
170
+ staticQueryResult = await getStaticQueryData ( queryId )
171
+ this . staticQueryResults . set ( queryId , staticQueryResult )
172
+ }
173
+
174
+ socket . send ( {
175
+ type : `staticQueryResult` ,
176
+ payload : staticQueryResult ,
177
+ } )
178
+ } )
179
+ )
180
+
191
181
socket . send ( {
192
182
type : `pageQueryResult` ,
193
183
why : `getDataForPath` ,
194
- payload : this . pageResults . get ( path ) ,
184
+ payload : pageData ,
195
185
} )
196
186
197
187
if ( this . connectedClients > 0 ) {
@@ -236,6 +226,7 @@ export class WebsocketManager {
236
226
237
227
if ( this . websocket ) {
238
228
this . websocket . send ( { type : `staticQueryResult` , payload : data } )
229
+
239
230
if ( this . connectedClients > 0 ) {
240
231
telemetry . trackCli (
241
232
`WEBSOCKET_EMIT_STATIC_PAGE_DATA_UPDATE` ,
0 commit comments