diff options
-rw-r--r-- | .gitignore | 1 | ||||
-rw-r--r-- | index.js | 30 |
2 files changed, 29 insertions, 2 deletions
diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..e46e79c --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +.scrollback diff --git a/index.js b/index.js index d91d459..294ad72 100644 --- a/index.js +++ b/index.js @@ -1,5 +1,5 @@ const path = require('node:path') -const {promises: {readFile}, createReadStream} = require('node:fs') +const {promises: {readFile}, readFileSync, createReadStream, createWriteStream} = require('node:fs') const {createServer} = require('node:http') const {createHash, randomBytes} = require('node:crypto') const Readline = require('node:readline'); @@ -12,18 +12,44 @@ const readline = Readline.createInterface({ prompt: '> ', }); - const MAX_EVENTS = 100 +// Event emitter and buffer for late joiners const chatEvents = new EventEmitter() +let bufferDirty = true let eventBuffer = [] chatEvents.on('event', ev => { eventBuffer = [...eventBuffer, ev].slice(0, MAX_EVENTS) + bufferDirty = true readline.clearLine() console.log(JSON.stringify(ev)) readline.prompt() }) +// Populate buffer on startup +const scrollbackFile = path.join(__dirname, '.scrollback') +try { + eventBuffer = readFileSync(scrollbackFile, {encoding: 'utf8'}).split('\n') + .map(line => { + try { + return JSON.parse(line) + } catch { + return null + } + }).filter(event => !!event) + bufferDirty = false +} catch { } + +// Sync buffer to disk every second +setInterval(async () => { + if (!bufferDirty) return + + const fileStream = createWriteStream(scrollbackFile, {flags: 'w', encoding: 'utf8'}) + for (const event of eventBuffer) { + await new Promise(res => fileStream.write(JSON.stringify(event) + '\n', 'utf8', res)) + } +}, 1000) + let currentUsers = {} readline.on('line', (line) => { |