Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions docs/notes/ideas.md
Original file line number Diff line number Diff line change
Expand Up @@ -74,4 +74,15 @@ Potential use cases:
- Start a countdown timer subscription only during a specific game phase
- Switch from animationFrame to a slower timer when entity count exceeds a threshold

- Switch from animationFrame to a slower timer when entity count exceeds a threshold

The dispatcher already handles subscription diffing (`diffSubscriptions`) — adding/removing subscriptions between commits is fully supported. This just needs a real consumer to exercise it.

## Zero Console Policy

This repository implements a strict zero-console policy for all source code.

- All `console.log`, `console.info`, and `console.error` calls are prohibited in `packages/*/src`.
- This ensures that production logs are clean and prevents side-channel information leaks.
- Error handling must be managed via the MVU pattern (dispatching error messages) or silent failures where appropriate, rather than simple console output.
- Enforcement is handled via ESLint (`no-console: "error"`) and a pre-push regex check.
8 changes: 6 additions & 2 deletions eslint.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -64,11 +64,15 @@ export default tseslint.config(
"@typescript-eslint/no-explicit-any": "error",
"@typescript-eslint/no-unused-vars": [
"error",
{ argsIgnorePattern: "^_" },
{
argsIgnorePattern: "^_",
varsIgnorePattern: "^_",
caughtErrorsIgnorePattern: "^_",
},
],
"@typescript-eslint/no-floating-promises": "error",
"@typescript-eslint/switch-exhaustiveness-check": "error",
"no-console": ["warn", { allow: ["warn", "error", "info"] }],
"no-console": "error",
"boundaries/element-types": [
"error",
{
Expand Down
8 changes: 4 additions & 4 deletions packages/app-web/src/features/devtools/devtools.ts
Original file line number Diff line number Diff line change
Expand Up @@ -197,8 +197,8 @@ export function view<M extends Model>(
try {
const log = JSON.parse(content);
onReplay(log, currentModel);
} catch (err) {
console.error("Failed to parse log", err);
} catch (_err) {
void _err;
}
};
reader.readAsText(file);
Expand Down Expand Up @@ -229,8 +229,8 @@ export function view<M extends Model>(
try {
const log = JSON.parse(saved);
onReplay(log, currentModel);
} catch (e) {
console.error("Failed to restore", e);
} catch (_e) {
void _e;
}
}
},
Expand Down
7 changes: 0 additions & 7 deletions packages/app-web/src/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -167,9 +167,6 @@ try {
try {
const log = JSON.parse(savedLogStr);
if (!Array.isArray(log)) throw new Error("Log is not an array");
console.info(
`[STORAGE] Found saved session with ${log.length} messages.`,
);

restoredModel = replay({
initialModel,
Expand Down Expand Up @@ -201,9 +198,7 @@ try {
}

initialLog = log;
console.info("[STORAGE] Session restored successfully.");
} catch (e) {
console.error("[STORAGE] Failed to restore session:", e);
restoreError = e instanceof Error ? e.message : String(e);
localStorage.removeItem("causaloop_log_v1");
}
Expand Down Expand Up @@ -240,7 +235,6 @@ try {
}
}

console.info("[REPLAY] Result:", isMatched ? "MATCH" : "MISMATCH");
dispatcher.dispatch({
kind: "devtools",
msg: {
Expand Down Expand Up @@ -320,7 +314,6 @@ try {
dispatcher.dispatch(msg as AppMsg),
);
} catch (e) {
console.error("[FATAL] Application failed to initialize:", e);
showRecoveryScreen(
e instanceof Error
? `Initialization error: ${e.message}. This is likely caused by corrupted saved state.`
Expand Down
4 changes: 2 additions & 2 deletions packages/platform-browser/src/runners/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -68,8 +68,8 @@ export class BrowserRunner<TMsg extends Msg = Msg> {
this.runWrapper(effect, dispatch);
break;
}
} catch (err) {
console.error("Critical error in effect runner:", err);
} catch (_err) {
void _err;
}
}
private runWrapper(
Expand Down
11 changes: 10 additions & 1 deletion scripts/check-forbidden.sh
Original file line number Diff line number Diff line change
@@ -1,7 +1,16 @@
#!/bin/bash

# Check for eslint-disable
if grep -r "eslint-disable" packages/*/src; then
echo "Error: eslint-disable comments are forbidden in src directories."
exit 1
fi
echo "No forbidden comments found."

# Check for console usage
if grep -r "console\." packages/*/src; then
echo "Error: Use of console is forbidden in src directories."
exit 1
fi

echo "No forbidden patterns found."
exit 0