diff --git a/.sse/README.md b/.sse/README.md index a41790c3c5..4276f748a5 100644 --- a/.sse/README.md +++ b/.sse/README.md @@ -19,19 +19,22 @@ https://developer.mozilla.org/en-US/docs/Web/API/Server-sent_events/Using_server 1. If `serverconfig.debugmode == true`, then a. set `serverconfig.sse` to `abs/path/proteinpaint/.sse`. - This is done in `server/src/serverconfig.js`. + This is done in `server/src/serverconfig.js`, except when manually disabled (opt-out) + using serverconfig.sse: false. b. set optional routes that include `server/src/test/routes/sse.js`. -2. In `server/src/test/routes/sse.js`, the `app.get('/sse')` route handler is set up. +2. `client/dev.sh` will create `proteinpaint/.sse/messages` dir to enable sse routes and notification setup. + +3. In `server/src/test/routes/sse.js`, the `app.get('/sse')` route handler is set up. Within the handler, `fs.watch()` is used to detect file changes in `serverconfig.sse/messages`. -3. On detecting `messages/${file}` changes, a notification is triggered in the route handler. +4. On detecting `messages/${file}` changes, a notification is triggered in the route handler. -4. In `client/src/nofify.js`, an event subcription/listener to the `/sse` route is created. +5. In `client/src/nofify.js`, an event subcription/listener to the `/sse` route is created. This creates notification divs to render messages as they are streamed by the server. -5. Some message may trigger browser refresh (must prevent accidental infinite reload loop). +6. Some message may trigger browser refresh (must prevent accidental infinite reload loop). ### Creating a new message by filename diff --git a/release.txt b/release.txt index 8b13789179..7a6e8c8ed9 100644 --- a/release.txt +++ b/release.txt @@ -1 +1,2 @@ - +Features: +- enable hot module replacement in dev diff --git a/server/src/serverconfig.js b/server/src/serverconfig.js index 49d5cc3399..bc813f1b9a 100644 --- a/server/src/serverconfig.js +++ b/server/src/serverconfig.js @@ -121,7 +121,8 @@ if (serverconfig.debugmode && !serverconfig.binpath.includes('sjcrh/')) { const routeSetters = [] const defaultDir = path.join(serverconfig.binpath, 'src/test/routes') // will add testing routes as needed and if found, such as in dev environment - const testRouteSetters = ['gdc.js', 'specs.js', 'readme.js', 'sse.js'] + const testRouteSetters = ['gdc.js', 'specs.js', 'readme.js'] + if (serverconfig.sse !== false) testRouteSetters.push('sse.js') if (serverconfig.routeSetters) { for (const f of serverconfig.routeSetters) { @@ -147,9 +148,6 @@ if (serverconfig.debugmode && !serverconfig.binpath.includes('sjcrh/')) { // since the serverconfig.binpath prefix may // have been applied to locate optional routeSetter files serverconfig.routeSetters = routeSetters - // server-sent events dir, can manually set sseDir to false - // to prevent the default SSE setup in dev - if (serverconfig.sseDir !== false) serverconfig.sseDir = path.join(serverconfig.binpath, '../.sse') } if (serverconfig.allow_env_overrides) { diff --git a/server/src/test/routes/sse.js b/server/src/test/routes/sse.js index 85aaf43ed0..ab76b3a1ab 100644 --- a/server/src/test/routes/sse.js +++ b/server/src/test/routes/sse.js @@ -8,15 +8,18 @@ import serverconfig from '../../serverconfig.js' import notifier from 'node-notifier' const __dirname = import.meta.dirname - notifier.notify({ title: 'PP server', message: 'restarted' }) -// notifier.notify({ title: 'server stopped', message: msg }) + +const sse = serverconfig.sse !== false && path.join(serverconfig.binpath, '.sse') export default function setRoutes(app, basepath) { // when validating server ds and routes init, no need to watch file // that would cause the validation to hang, should exit with no error - if (process.argv.includes('validate')) return - if (!serverconfig.sseDir) return + if (process.argv.includes('validate') || !serverconfig.debugmode) return + // dev or test script will create .sse/messages as needed in non-prod environments, + // sse routes, notification is disabled if this msgDir is not present + const msgDir = path.join(serverconfig.binpath, '../.sse/messages') + if (!fs.existsSync(msgDir)) return // will track only one active sse connection per origin // - key: req.header('host') @@ -56,7 +59,6 @@ export default function setRoutes(app, basepath) { // - key: message filename or source, value: message text // - notify() will clear this store once all connections have been notified const messages = new Map() - const msgDir = path.join(serverconfig.sseDir, 'messages') // initiliaze message detection setTimeout(async () => { @@ -88,8 +90,7 @@ export default function setRoutes(app, basepath) { res.write(`event: message\n`) res.write(text) } - // delay clearing messages to allow re-connections to receive recent messages; - // cannot directly use messages.clear as callback, use a wrapper function to clear + // delay clearing messages to allow re-connections to receive recent messages setTimeout(clearMessages, 3000) } @@ -126,10 +127,6 @@ export default function setRoutes(app, basepath) { messages.clear() } - function logErr(e) { - if (e) console.log(e) - } - // deprecated since messages cannot be posted when the server is rebundling/restarting // app.post('/notifications', async (req, res) => { // for (const res of connections) { @@ -140,3 +137,7 @@ export default function setRoutes(app, basepath) { // } // }) } + +function logErr(e) { + if (e) console.log(e) +}