From 47fa09af4a2a3b34bb90c885d644f453c6f5e852 Mon Sep 17 00:00:00 2001 From: Eyas Date: Wed, 25 Mar 2020 12:44:40 -0400 Subject: [PATCH] chore(gatsby): Update websocket-manager to TS (#22510) * 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 --- packages/gatsby/package.json | 1 + packages/gatsby/src/commands/develop.ts | 5 +- packages/gatsby/src/query/query-compiler.js | 2 +- packages/gatsby/src/query/queue.js | 2 +- packages/gatsby/src/redux/types.ts | 4 +- ...socket-manager.js => websocket-manager.ts} | 178 ++++++++---------- yarn.lock | 7 + 7 files changed, 97 insertions(+), 102 deletions(-) rename packages/gatsby/src/utils/{websocket-manager.js => websocket-manager.ts} (62%) diff --git a/packages/gatsby/package.json b/packages/gatsby/package.json index ff13c0529c972..ba1c6f059157c 100644 --- a/packages/gatsby/package.json +++ b/packages/gatsby/package.json @@ -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", diff --git a/packages/gatsby/src/commands/develop.ts b/packages/gatsby/src/commands/develop.ts index 819cad1ce18d6..a592dbddeee2f 100644 --- a/packages/gatsby/src/commands/develop.ts +++ b/packages/gatsby/src/commands/develop.ts @@ -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" @@ -320,8 +320,7 @@ async function startServer(program: IProgram): Promise { ? 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) diff --git a/packages/gatsby/src/query/query-compiler.js b/packages/gatsby/src/query/query-compiler.js index 2b5c067861f40..5bc5d8a2a1740 100644 --- a/packages/gatsby/src/query/query-compiler.js +++ b/packages/gatsby/src/query/query-compiler.js @@ -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` diff --git a/packages/gatsby/src/query/queue.js b/packages/gatsby/src/query/queue.js index 71bacc5abd518..c690f5645bfc2 100644 --- a/packages/gatsby/src/query/queue.js +++ b/packages/gatsby/src/query/queue.js @@ -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 = () => { diff --git a/packages/gatsby/src/redux/types.ts b/packages/gatsby/src/redux/types.ts index 11cbf7c03e573..dce585b7f6970 100644 --- a/packages/gatsby/src/redux/types.ts +++ b/packages/gatsby/src/redux/types.ts @@ -120,13 +120,13 @@ export interface IGatsbyState { } > staticQueryComponents: Map< - string, + number, { name: string componentPath: SystemPath id: Identifier query: string - hash: number + hash: string } > // @deprecated diff --git a/packages/gatsby/src/utils/websocket-manager.js b/packages/gatsby/src/utils/websocket-manager.ts similarity index 62% rename from packages/gatsby/src/utils/websocket-manager.js rename to packages/gatsby/src/utils/websocket-manager.ts index 552e57423df1b..add7c78c60af5 100644 --- a/packages/gatsby/src/utils/websocket-manager.js +++ b/packages/gatsby/src/utils/websocket-manager.ts @@ -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 +type PageResultsMap = Map +type QueryResultsMap = Map /** * 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 => { const { program, pages } = store.getState() const publicDir = path.join(program.directory, `public`) if (pages.has(denormalizePagePath(pagePath)) || pages.has(pagePath)) { @@ -42,10 +47,13 @@ const getCachedPageData = async ( } } - return undefined + return { + id: pagePath, + result: undefined, + } } -const hashPaths = paths => { +const hashPaths = (paths?: string[]): undefined | Array => { if (!paths) { return undefined } @@ -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 @@ -98,53 +106,35 @@ const getCachedStaticQueryResults = ( const getRoomNameFromPath = (path: string): string => `path-${path}` class WebsocketManager { - pageResults: QueryResultsMap - staticQueryResults: QueryResultsMap - errors: Map - isInitialised: boolean - activePaths: Set - 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 = new Set() + connectedClients = 0 + errors: Map = 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) @@ -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, @@ -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) ] @@ -179,12 +170,12 @@ class WebsocketManager { } } - const getDataForPath = async path => { + const getDataForPath = async (path: string): Promise => { 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) @@ -192,19 +183,18 @@ class WebsocketManager { } } - 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)), }, }, @@ -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)), }, }, @@ -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)), }, }, @@ -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() diff --git a/yarn.lock b/yarn.lock index fb972e863b613..0e9a1010d9ca1 100644 --- a/yarn.lock +++ b/yarn.lock @@ -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"