Skip to content

Commit

Permalink
Replace ws with server sent events
Browse files Browse the repository at this point in the history
  • Loading branch information
thetarnav committed Jan 8, 2025
1 parent baf1dea commit 8504b3b
Show file tree
Hide file tree
Showing 5 changed files with 35 additions and 81 deletions.
4 changes: 1 addition & 3 deletions config.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ export const IS_DEV = /** @type {boolean} */ (false)
export const IS_PROD = /** @type {boolean} */ (!IS_DEV)

export const HTTP_PORT = 3000
export const WEB_SOCKET_PORT = 8080
export const RELOAD_URL = "/_reload"

export const PLAYGROUND_DIRNAME = "example"
export const DIST_DIRNAME = "dist"
Expand All @@ -19,5 +19,3 @@ export const CONFIG_OUT_FILENAME = "_" + CONFIG_FILENAME

export const WASM_FILENAME = "_main.wasm"
export const WASM_PATH = PLAYGROUND_DIRNAME + "/" + PUBLIC_DIRNAME + "/" + WASM_FILENAME

export const MESSAGE_RELOAD = "reload"
10 changes: 5 additions & 5 deletions example/setup.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import * as wasm from "../wasm/runtime.js"

import {IS_DEV, WEB_SOCKET_PORT, MESSAGE_RELOAD, WASM_FILENAME} from "./_config.js"
import {IS_DEV, RELOAD_URL, WASM_FILENAME} from "./_config.js"

/*
Development server
Expand All @@ -10,10 +10,10 @@ if (IS_DEV) {
wasm.enableConsole()

/* Hot Reload */
new WebSocket("ws://localhost:" + WEB_SOCKET_PORT).addEventListener(
"message",
event => event.data === MESSAGE_RELOAD && location.reload(),
)
const events = new EventSource(RELOAD_URL)
events.onmessage = _ => {
location.reload()
}

/* To test dispatching custom events */
document.body.addEventListener("lol", () => {
Expand Down
48 changes: 27 additions & 21 deletions main.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,11 @@ import url from "node:url"
import http from "node:http"

Check failure on line 10 in main.js

View workflow job for this annotation

GitHub Actions / build_test

Cannot find module 'node:http' or its corresponding type declarations.
import process from "node:process"

Check failure on line 11 in main.js

View workflow job for this annotation

GitHub Actions / build_test

Cannot find module 'node:process' or its corresponding type declarations.
import child_process from "node:child_process"

Check failure on line 12 in main.js

View workflow job for this annotation

GitHub Actions / build_test

Cannot find module 'node:child_process' or its corresponding type declarations.
import * as ws from "ws"
import * as esbuild from "esbuild"

import {
DIST_DIRNAME, CONFIG_FILENAME, HTTP_PORT, MESSAGE_RELOAD, PACKAGE_DIRNAME, PLAYGROUND_DIRNAME,
WASM_PATH, WEB_SOCKET_PORT, CONFIG_OUT_FILENAME, WASM_FILENAME, PUBLIC_DIRNAME,
DIST_DIRNAME, CONFIG_FILENAME, HTTP_PORT, PACKAGE_DIRNAME, PLAYGROUND_DIRNAME,
WASM_PATH, RELOAD_URL, CONFIG_OUT_FILENAME, WASM_FILENAME, PUBLIC_DIRNAME,
} from "./config.js"

const dirname = path.dirname(url.fileURLToPath(import.meta.url))
Expand Down Expand Up @@ -104,7 +103,9 @@ const command_handlers = {
void fs.mkdirSync(dist_path, {recursive: true})

const server = makeHttpServer(requestListener)
const wss = new ws.WebSocketServer({port: WEB_SOCKET_PORT})

/** @type {Set<http.ServerResponse>} */
const reload_clients_set = new Set()

/** @type {Promise<number> | null} */ let build_wasm_promise = null
/** @type {Promise<number> | null} */ let build_shader_utils_promise = null
Expand Down Expand Up @@ -187,17 +188,16 @@ const command_handlers = {
}

info(`${filename} ${e}, reloading page...`)
sendToAllClients(wss, MESSAGE_RELOAD)
for (const client of reload_clients_set) {
client.write(`data: reload\n\n`)
}
})
}

function exit() {
void server.close()
void wss.close()
for (let watcher of watchers) {
watcher.close()
}
sendToAllClients(wss, MESSAGE_RELOAD)
for (let w of watchers) w.close()
for (let c of reload_clients_set) c.end()
void process.exit(0)
}
void process.on("SIGINT", exit)
Expand All @@ -211,10 +211,25 @@ const command_handlers = {
const req_time = performance.now()
if (!req.url || req.method !== "GET") return end404(req, res, req_time)

if (req.url === "/" + CONFIG_OUT_FILENAME) {
switch (req.url) {
// Handle SSE endpoint
case RELOAD_URL: {
res.writeHead(200, {
"Content-Type": "text/event-stream",
"Cache-Control": "no-cache",
"Connection": "keep-alive",
})
res.write("\n")
reload_clients_set.add(res)
req.on("close", () => reload_clients_set.delete(res))
return
}
case "/" + CONFIG_OUT_FILENAME:
await config_promise
} else if (req.url === "/" + WASM_FILENAME) {
break
case "/" + WASM_FILENAME:
await build_wasm_promise
break
}

/* Static files */
Expand Down Expand Up @@ -558,15 +573,6 @@ function log_request(req, res, req_time) {
console.log(txt)
}

/** @typedef {Parameters<ws.WebSocket["send"]>[0]} BufferLike */

/** @returns {void} */
function sendToAllClients(/** @type {ws.WebSocketServer} */ wss, /** @type {BufferLike} */ data) {
for (const client of wss.clients) {
client.send(data)
}
}

/** @returns {string} */
function mimeType(/** @type {string} */ ext) {
switch (ext) {
Expand Down
34 changes: 1 addition & 33 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

20 changes: 1 addition & 19 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,22 +4,6 @@
"license": "MIT",
"private": true,
"type": "module",
"files": [
"types",
"wasm",
"!**/*.test.*"
],
"exports": {
"./package.json": "./package.json",
".": {
"types": "./types/runtime.d.ts",
"import": "./wasm/runtime.js"
},
"./*": {
"types": "./types/*.d.ts",
"import": "./wasm/*.js"
}
},
"scripts": {
"dev": "node --watch main.js server",
"server": "node main.js server",
Expand All @@ -33,10 +17,8 @@
},
"devDependencies": {
"@types/node": "^20.12.10",
"@types/ws": "^8.5.10",
"esbuild": "^0.21.5",
"typescript": "^5.4.5",
"ws": "^8.17.0"
"typescript": "^5.4.5"
},
"engines": {
"node": ">=20"
Expand Down

0 comments on commit 8504b3b

Please sign in to comment.