Skip to content

Commit

Permalink
chore(gatsby): Update websocket-manager to TS (#22510)
Browse files Browse the repository at this point in the history
* chose(gatsby): Update websocket-manager to TS

* cleanup: Removed unused param in websocket-manager

* Update redux staticQueryComponents

* Update yarn.lock

* chose(gatsby): Update websocket-manager to TS

* cleanup: Removed unused param in websocket-manager

* Update redux staticQueryComponents

* Update yarn.lock

* Additional type improvements and code clean ups

* fix lint

Co-authored-by: Blaine Kasten <[email protected]>
  • Loading branch information
Eyas and blainekasten authored Mar 25, 2020
1 parent 27cb456 commit 47fa09a
Show file tree
Hide file tree
Showing 7 changed files with 97 additions and 102 deletions.
1 change: 1 addition & 0 deletions packages/gatsby/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,7 @@
"devDependencies": {
"@babel/cli": "^7.8.4",
"@babel/runtime": "^7.8.7",
"@types/socket.io": "^2.1.4",
"babel-preset-gatsby-package": "^0.3.1",
"cross-env": "^5.2.1",
"documentation": "^12.1.4",
Expand Down
5 changes: 2 additions & 3 deletions packages/gatsby/src/commands/develop.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ import { developStatic } from "./develop-static"
import withResolverContext from "../schema/context"
import sourceNodes from "../utils/source-nodes"
import { createSchemaCustomization } from "../utils/create-schema-customization"
import websocketManager from "../utils/websocket-manager"
import { websocketManager } from "../utils/websocket-manager"
import getSslCert from "../utils/get-ssl-cert"
import { slash } from "gatsby-core-utils"
import { initTracer } from "../utils/tracer"
Expand Down Expand Up @@ -320,8 +320,7 @@ async function startServer(program: IProgram): Promise<IServer> {
? https.createServer(program.ssl, app)
: new http.Server(app)

websocketManager.init({ server, directory: program.directory })
const socket = websocketManager.getSocket()
const socket = websocketManager.init({ server, directory: program.directory })

const listener = server.listen(program.port, program.host)

Expand Down
2 changes: 1 addition & 1 deletion packages/gatsby/src/query/query-compiler.js
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ const {
default: errorParser,
locInGraphQlToLocInFile,
} = require(`./error-parser`)
const websocketManager = require(`../utils/websocket-manager`)
const { websocketManager } = require(`../utils/websocket-manager`)

const overlayErrorID = `graphql-compiler`

Expand Down
2 changes: 1 addition & 1 deletion packages/gatsby/src/query/queue.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ const Queue = require(`better-queue`)
const { store } = require(`../redux`)
const FastMemoryStore = require(`../query/better-queue-custom-store`)
const queryRunner = require(`../query/query-runner`)
const websocketManager = require(`../utils/websocket-manager`)
const { websocketManager } = require(`../utils/websocket-manager`)
const GraphQLRunner = require(`./graphql-runner`).default

const createBaseOptions = () => {
Expand Down
4 changes: 2 additions & 2 deletions packages/gatsby/src/redux/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -120,13 +120,13 @@ export interface IGatsbyState {
}
>
staticQueryComponents: Map<
string,
number,
{
name: string
componentPath: SystemPath
id: Identifier
query: string
hash: number
hash: string
}
>
// @deprecated
Expand Down
Original file line number Diff line number Diff line change
@@ -1,30 +1,35 @@
// @flow

const path = require(`path`)
const { store } = require(`../redux`)
const fs = require(`fs`)
const pageDataUtil = require(`../utils/page-data`)
import path from "path"
import { store } from "../redux"
import { Server as HTTPSServer } from "https"
import { Server as HTTPServer } from "http"
import fs from "fs"
import pageDataUtil from "../utils/page-data"
import telemetry from "gatsby-telemetry"
import url from "url"
import { createHash } from "crypto"
import { normalizePagePath, denormalizePagePath } from "./normalize-page-path"
const telemetry = require(`gatsby-telemetry`)
const url = require(`url`)
const { createHash } = require(`crypto`)
import socketIO from "socket.io"

interface IPageQueryResult {
id: string
result: any // TODO: Improve this once we understand what the type is
}

type QueryResult = {
id: string,
result: object,
interface IStaticQueryResult {
id: number
result: any // TODO: Improve this once we understand what the type is
}

type QueryResultsMap = Map<string, QueryResult>
type PageResultsMap = Map<string, IPageQueryResult>
type QueryResultsMap = Map<number, IStaticQueryResult>

/**
* Get cached page query result for given page path.
* @param {string} pagePath Path to a page.
* @param {string} directory Root directory of current project.
*/
const getCachedPageData = async (
pagePath: string,
directory: string
): QueryResult => {
pagePath: string
): Promise<IPageQueryResult> => {
const { program, pages } = store.getState()
const publicDir = path.join(program.directory, `public`)
if (pages.has(denormalizePagePath(pagePath)) || pages.has(pagePath)) {
Expand All @@ -42,10 +47,13 @@ const getCachedPageData = async (
}
}

return undefined
return {
id: pagePath,
result: undefined,
}
}

const hashPaths = paths => {
const hashPaths = (paths?: string[]): undefined | Array<string | undefined> => {
if (!paths) {
return undefined
}
Expand All @@ -68,7 +76,7 @@ const getCachedStaticQueryResults = (
resultsMap: QueryResultsMap,
directory: string
): QueryResultsMap => {
const cachedStaticQueryResults = new Map()
const cachedStaticQueryResults: QueryResultsMap = new Map()
const { staticQueryComponents } = store.getState()
staticQueryComponents.forEach(staticQueryComponent => {
// Don't read from file if results were already passed from query runner
Expand Down Expand Up @@ -98,53 +106,35 @@ const getCachedStaticQueryResults = (
const getRoomNameFromPath = (path: string): string => `path-${path}`

class WebsocketManager {
pageResults: QueryResultsMap
staticQueryResults: QueryResultsMap
errors: Map<string, QueryResult>
isInitialised: boolean
activePaths: Set<string>
programDir: string

constructor() {
this.isInitialised = false
this.activePaths = new Set()
this.pageResults = new Map()
this.staticQueryResults = new Map()
this.errors = new Map()
// this.websocket
// this.programDir

this.init = this.init.bind(this)
this.getSocket = this.getSocket.bind(this)
this.emitPageData = this.emitPageData.bind(this)
this.emitStaticQueryData = this.emitStaticQueryData.bind(this)
this.emitError = this.emitError.bind(this)
this.connectedClients = 0
}

init({ server, directory }) {
this.programDir = directory

activePaths: Set<string> = new Set()
connectedClients = 0
errors: Map<string, string> = new Map()
pageResults: PageResultsMap = new Map()
staticQueryResults: QueryResultsMap = new Map()
websocket: socketIO.Server | undefined

init = ({
directory,
server,
}: {
directory: string
server: HTTPSServer | HTTPServer
}): socketIO.Server => {
const cachedStaticQueryResults = getCachedStaticQueryResults(
this.staticQueryResults,
this.programDir
directory
)
this.staticQueryResults = new Map([
...this.staticQueryResults,
...cachedStaticQueryResults,
])

this.websocket = require(`socket.io`)(server)

this.websocket.on(`connection`, s => {
let activePath = null
if (
s &&
s.handshake &&
s.handshake.headers &&
s.handshake.headers.referer
) {
const path = url.parse(s.handshake.headers.referer).path
this.websocket = socketIO(server)

this.websocket.on(`connection`, socket => {
let activePath: string | null = null
if (socket?.handshake?.headers?.referer) {
const path = url.parse(socket.handshake.headers.referer).path
if (path) {
activePath = path
this.activePaths.add(path)
Expand All @@ -154,13 +144,13 @@ class WebsocketManager {
this.connectedClients += 1
// Send already existing static query results
this.staticQueryResults.forEach(result => {
this.websocket.send({
socket.send({
type: `staticQueryResult`,
payload: result,
})
})
this.errors.forEach((message, errorID) => {
this.websocket.send({
socket.send({
type: `overlayError`,
payload: {
id: errorID,
Expand All @@ -169,8 +159,9 @@ class WebsocketManager {
})
})

const leaveRoom = path => {
s.leave(getRoomNameFromPath(path))
const leaveRoom = (path: string): void => {
socket.leave(getRoomNameFromPath(path))
if (!this.websocket) return
const leftRoom = this.websocket.sockets.adapter.rooms[
getRoomNameFromPath(path)
]
Expand All @@ -179,32 +170,31 @@ class WebsocketManager {
}
}

const getDataForPath = async path => {
const getDataForPath = async (path: string): Promise<void> => {
if (!this.pageResults.has(path)) {
try {
const result = await getCachedPageData(path, this.programDir)
const result = await getCachedPageData(path)

this.pageResults.set(path, result || { id: path })
this.pageResults.set(path, result)
} catch (err) {
console.log(err.message)

return
}
}

this.websocket.send({
socket.send({
type: `pageQueryResult`,
why: `getDataForPath`,
payload: this.pageResults.get(path),
})

const clientsCount = this.connectedClients
if (clientsCount && clientsCount > 0) {
if (this.connectedClients > 0) {
telemetry.trackCli(
`WEBSOCKET_PAGE_DATA_UPDATE`,
{
siteMeasurements: {
clientsCount,
clientsCount: this.connectedClients,
paths: hashPaths(Array.from(this.activePaths)),
},
},
Expand All @@ -213,42 +203,40 @@ class WebsocketManager {
}
}

s.on(`getDataForPath`, getDataForPath)
socket.on(`getDataForPath`, getDataForPath)

s.on(`registerPath`, path => {
s.join(getRoomNameFromPath(path))
socket.on(`registerPath`, (path: string): void => {
socket.join(getRoomNameFromPath(path))
activePath = path
this.activePaths.add(path)
})

s.on(`disconnect`, s => {
leaveRoom(activePath)
socket.on(`disconnect`, (): void => {
if (activePath) leaveRoom(activePath)
this.connectedClients -= 1
})

s.on(`unregisterPath`, path => {
socket.on(`unregisterPath`, (path: string): void => {
leaveRoom(path)
})
})

this.isInitialised = true
return this.websocket
}

getSocket() {
return this.isInitialised && this.websocket
}
getSocket = (): socketIO.Server | undefined => this.websocket

emitStaticQueryData(data: QueryResult) {
emitStaticQueryData = (data: IStaticQueryResult): void => {
this.staticQueryResults.set(data.id, data)
if (this.isInitialised) {

if (this.websocket) {
this.websocket.send({ type: `staticQueryResult`, payload: data })
const clientsCount = this.connectedClients
if (clientsCount && clientsCount > 0) {
if (this.connectedClients > 0) {
telemetry.trackCli(
`WEBSOCKET_EMIT_STATIC_PAGE_DATA_UPDATE`,
{
siteMeasurements: {
clientsCount,
clientsCount: this.connectedClients,
paths: hashPaths(Array.from(this.activePaths)),
},
},
Expand All @@ -258,18 +246,19 @@ class WebsocketManager {
}
}

emitPageData(data: QueryResult) {
emitPageData = (data: IPageQueryResult): void => {
data.id = normalizePagePath(data.id)
this.pageResults.set(data.id, data)
if (this.isInitialised) {

if (this.websocket) {
this.websocket.send({ type: `pageQueryResult`, payload: data })
const clientsCount = this.connectedClients
if (clientsCount && clientsCount > 0) {

if (this.connectedClients > 0) {
telemetry.trackCli(
`WEBSOCKET_EMIT_PAGE_DATA_UPDATE`,
{
siteMeasurements: {
clientsCount,
clientsCount: this.connectedClients,
paths: hashPaths(Array.from(this.activePaths)),
},
},
Expand All @@ -278,19 +267,18 @@ class WebsocketManager {
}
}
}
emitError(id: string, message?: string) {

emitError = (id: string, message?: string): void => {
if (message) {
this.errors.set(id, message)
} else {
this.errors.delete(id)
}

if (this.isInitialised) {
if (this.websocket) {
this.websocket.send({ type: `overlayError`, payload: { id, message } })
}
}
}

const manager = new WebsocketManager()

module.exports = manager
export const websocketManager: WebsocketManager = new WebsocketManager()
7 changes: 7 additions & 0 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -4093,6 +4093,13 @@
"@types/express-serve-static-core" "*"
"@types/mime" "*"

"@types/socket.io@^2.1.4":
version "2.1.4"
resolved "https://registry.yarnpkg.com/@types/socket.io/-/socket.io-2.1.4.tgz#674e7bc193c5ccdadd4433f79f3660d31759e9ac"
integrity sha512-cI98INy7tYnweTsUlp8ocveVdAxENUThO0JsLSCs51cjOP2yV5Mqo5QszMDPckyRRA+PO6+wBgKvGvHUCc23TQ==
dependencies:
"@types/node" "*"

"@types/source-list-map@*":
version "0.1.2"
resolved "https://registry.yarnpkg.com/@types/source-list-map/-/source-list-map-0.1.2.tgz#0078836063ffaf17412349bba364087e0ac02ec9"
Expand Down

0 comments on commit 47fa09a

Please sign in to comment.