From 76213c3e7482d307f5834691eba17f6eb76dd5e3 Mon Sep 17 00:00:00 2001 From: Rinse Date: Wed, 20 May 2026 04:34:02 +0000 Subject: [PATCH 1/2] fix(logs): use userspace polling for -f follow mode MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit fs.watchFile (libuv uv_fs_poll_t) does not reliably emit change events for cross-process file appends on Windows, so `bitsocial logs -f` would silently miss new log lines there. Replace it with a self-rescheduling setTimeout that calls fs.promises.stat() + reads new bytes — the same pattern production tail-f libraries use precisely because OS file watchers aren't cross-platform reliable for this scenario. Closes #40 --- src/cli/commands/logs.ts | 32 +++++++++++++++++++------------- 1 file changed, 19 insertions(+), 13 deletions(-) diff --git a/src/cli/commands/logs.ts b/src/cli/commands/logs.ts index 98b78fb..7637689 100644 --- a/src/cli/commands/logs.ts +++ b/src/cli/commands/logs.ts @@ -254,8 +254,6 @@ export default class Logs extends Command { } } - // Switch watchers - fs.unwatchFile(currentLogFile, readNewData); currentLogFile = newestFile; pendingBuffer = ""; @@ -279,26 +277,34 @@ export default class Logs extends Command { const newStat = await fsPromise.stat(currentLogFile); position = newStat.size; - fs.watchFile(currentLogFile, { interval: 300 }, readNewData); } catch { // Directory listing failed or file disappeared — retry next cycle } }; - fs.watchFile(currentLogFile, { interval: 300 }, readNewData); + // Userspace polling instead of fs.watchFile — libuv's uv_fs_poll_t doesn't + // reliably notify on cross-process appends on Windows (see nodejs/node#36888). + let polling = true; + let pollTimer: NodeJS.Timeout | null = null; + const pollLoop = async () => { + if (!polling) return; + try { + await readNewData(); + } finally { + if (polling) pollTimer = setTimeout(pollLoop, 300); + } + }; + pollTimer = setTimeout(pollLoop, 300); const newFileCheckInterval = setInterval(checkForNewLogFile, 3000); - // Keep the process alive and clean up on exit - process.on("SIGINT", () => { - clearInterval(newFileCheckInterval); - fs.unwatchFile(currentLogFile, readNewData); - process.exit(0); - }); - process.on("SIGTERM", () => { + const shutdown = () => { + polling = false; + if (pollTimer) clearTimeout(pollTimer); clearInterval(newFileCheckInterval); - fs.unwatchFile(currentLogFile, readNewData); process.exit(0); - }); + }; + process.on("SIGINT", shutdown); + process.on("SIGTERM", shutdown); // Keep process alive await new Promise(() => {}); From b01faab13a143e28d3920ec045e8899c2bf113a4 Mon Sep 17 00:00:00 2001 From: Rinse Date: Wed, 20 May 2026 04:56:12 +0000 Subject: [PATCH 2/2] chore(deps): upgrade pkc-js to 0.0.35 --- package-lock.json | 8 ++++---- package.json | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/package-lock.json b/package-lock.json index 1307174..d937cbd 100644 --- a/package-lock.json +++ b/package-lock.json @@ -16,7 +16,7 @@ "@oclif/plugin-help": "6.2.36", "@oclif/plugin-not-found": "3.2.73", "@oclif/table": "0.5.1", - "@pkcprotocol/pkc-js": "0.0.34", + "@pkcprotocol/pkc-js": "0.0.35", "dataobject-parser": "1.2.22", "decompress": "4.2.1", "env-paths": "2.2.1", @@ -5421,9 +5421,9 @@ } }, "node_modules/@pkcprotocol/pkc-js": { - "version": "0.0.34", - "resolved": "https://registry.npmjs.org/@pkcprotocol/pkc-js/-/pkc-js-0.0.34.tgz", - "integrity": "sha512-P2eW+bmiMSK8A0Na2a+zxfQkTK/s5dssX7lYpfWg3Q88v7XWdTugSEZMym1KtciJCipeGFQnRhpZWzTlIttqJw==", + "version": "0.0.35", + "resolved": "https://registry.npmjs.org/@pkcprotocol/pkc-js/-/pkc-js-0.0.35.tgz", + "integrity": "sha512-5E5cqYvM7AKBnzVZlVCgHrkQX0X3dWaasnzKOO+dq1nq9llvm9/sHmxanRAk1JMo2cH18aPTp9q7cJ83NvtfPw==", "license": "GPL-3.0-or-later", "dependencies": { "@enhances/with-resolvers": "0.0.5", diff --git a/package.json b/package.json index af5e540..f859cb3 100644 --- a/package.json +++ b/package.json @@ -119,7 +119,7 @@ "@oclif/plugin-help": "6.2.36", "@oclif/plugin-not-found": "3.2.73", "@oclif/table": "0.5.1", - "@pkcprotocol/pkc-js": "0.0.34", + "@pkcprotocol/pkc-js": "0.0.35", "dataobject-parser": "1.2.22", "decompress": "4.2.1", "env-paths": "2.2.1",