Two typecheck regressions surfaced after pulling duckietm PR #126 onto
this branch:
- NotificationBadgeReceivedBubbleView lost its `useEffectEvent` wrapper
during conflict resolution. The PR rewrote the effect to use a plain
`useEffect(..., [activeBadgeCodes.length])`; reintroduce the
`requestBadgesIfEmpty = useEffectEvent(...)` shape that the rest of
this branch uses, applied to the renamed activeBadgeCodes selector.
- `src/bootstrap.ts` was importing `GetConfiguration` from the package
alias `@nitrots/configuration`, which Vite resolves via filesystem
alias but tsgo does not. Swap to the monolithic
`@nitrots/nitro-renderer` re-export, matching how App.tsx already
imports the same symbol.
Both fixes get `yarn typecheck` green again and all 113 Vitest cases
still pass.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Restoring `yarn start` from "takes forever" back to seconds.
A previous session had symlinked `public/nitro-assets` and `public/swf`
to a sibling `Nitro-Files/` tree (~177k files) so Vite could serve them
through `publicDir`. The cost was massive: chokidar tried to install a
watcher on every file at startup and the dev server hung for minutes
on Windows. Upstream `duckietm/Nitro-V3` never does this — assets live
on a separate HTTP server referenced by URL in the JSON configs.
Changes:
- Remove the two symlinks under `public/` and add a .gitignore entry
with a note explaining why they must not come back.
- Add a small Vite plugin (`nitroAssetsServer`) that mounts `sirv` on
`/nitro-assets/*` and `/swf/*`, reading from
`../Nitro-Files/{nitro-assets,swf}`. sirv is a connect-style
middleware that bypasses chokidar entirely, so 177k files no longer
cost anything at startup. The plugin also wires the same handler
into `configurePreviewServer` so `yarn preview` keeps working.
- Drop the matching `/nitro-assets` and `/swf` entries from
`server.proxy` — they had been pointed at the auth proxy on :2096
which does not expose those paths.
- Disable `login.turnstile.enabled` in `renderer-config.json`. The
configured sitekey is Cloudflare's "always-passes" test key but the
widget still requires user interaction and blocks the login flow
in local dev.
Login flow fixes that fell out of debugging:
- `prepare()` in App.tsx ran twice under React Strict Mode (mount →
cleanup → mount). The first pass set `setShowLogin(true)`, the
second raced ahead and fell through to `onSessionExpired()`,
clobbering the login UI. Guard the effect with
`lastPrepareTriggerRef` so duplicate runs at the same trigger value
are skipped while intentional re-runs (after a successful login,
which bumps `prepareTrigger`) still go through.
- Call `GetConfiguration().init()` from `bootstrap.ts` before
importing `./index`. The renderer's ConfigurationManager logs
"Missing configuration key" the first time any key is read against
an uninitialised store, and components mounted in the first paint
(login screen, hooks, the renderer warmup) were all hitting that
path before prepare()'s deferred init landed. Pre-loading the
config means the store is already populated when React mounts.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Run eslint --fix across src/ to clear ~1900 mechanical lint errors
surfaced by the @typescript-eslint v8 + react-hooks v7 + react-compiler
upgrade in the React 19 modernization PR.
Issues fixed automatically:
- brace-style (Allman): try/catch one-liners reformatted to multi-line
- indent: tab-vs-space and depth corrections
- semi: missing trailing semicolons
- no-trailing-spaces
No semantic changes. Remaining 701 errors are real-code issues
(set-state-in-effect, rules-of-hooks, no-unsafe-* type checks) that
need manual per-file review.
https://claude.ai/code/session_01GrR87LAqnAEyKG2ZbmQt5Q