mirror of
https://github.com/Ark0N/Codeman.git
synced 2026-10-07 16:09:43 +02:00
fix(remote): stop the wake handlers shadowing each other; enforce the input cap
Two findings from a final review pass over the wake-on-LAN feature. `_onRemoteHostWaking` / `_onRemoteHostWakeFailed` were defined in BOTH `panels-ui.js` (toasts) and `host-wake-ui.js` (banner). Both files mix into `CodemanApp.prototype` and `host-wake-ui.js` loads later, so the panels-ui copies were silently shadowed: the toast never fired, and a wake started for a BACKGROUND session (input on a non-active tab) produced no notification at all, since the banner handler only acts on the active session. The handlers now live only in `host-wake-ui.js`, show the toast unconditionally, and update the banner when the woken session is the active one. `appendBoundedPending` dropped only WHOLE chunks, so a single input value over the cap (one large paste is one `input` value, up to the 100 KB input schema) was kept in full: "bounded at 4 KB" held per chunk, not per session, and nothing was logged. The surviving chunk's head is now trimmed too, code-point aware so a multi-byte character is never split into a replacement char. Adds the guard that would have caught the first one: every SSE dispatch handler must be defined in exactly ONE frontend module. The existing test only asserts a handler EXISTS somewhere, which two modules both satisfy while one is shadowed.
This commit is contained in:
@@ -57,4 +57,22 @@ describe('SSE dispatch table', () => {
|
||||
.filter((handler) => !new RegExp(`(^|\\s)${handler}\\s*\\(`, 'm').test(allModules));
|
||||
expect(missing).toEqual([]);
|
||||
});
|
||||
|
||||
it('defines every handler in exactly ONE module (a second copy is shadowed)', () => {
|
||||
// Modules mix into `CodemanApp.prototype` and run in script order, so two
|
||||
// definitions of the same handler name silently shadow each other: the later file
|
||||
// wins and the earlier one never runs. The existence check above cannot see that
|
||||
// (both names resolve), which is how a duplicate banner handler can leave a toast
|
||||
// dead with no error anywhere.
|
||||
const byModule = readdirSync(PUBLIC_DIR)
|
||||
.filter((name) => name.endsWith('.js'))
|
||||
.map((name) => ({ name, source: readFileSync(join(PUBLIC_DIR, name), 'utf-8') }));
|
||||
const shadowed = dispatchEntries()
|
||||
.map((entry) => entry.handler)
|
||||
.filter((handler) => {
|
||||
const re = new RegExp(`(^|\\s)${handler}\\s*\\(`, 'm');
|
||||
return byModule.filter((mod) => re.test(mod.source)).length > 1;
|
||||
});
|
||||
expect(shadowed).toEqual([]);
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user