Commit Graph

10 Commits

Author SHA1 Message Date
simoleo89 23fc302b24 Extract Variables tab JSX into WiredVariablesTabView component
Proposal #5 from docs/ARCHITECTURE.md, first slice: split one of the
three remaining inline tab bodies of WiredCreatorToolsView out into
its own file. Same approach the Settings tab has had for a while
(see WiredToolsSettingsTabView).

What moved
- 113 lines of inline JSX (the `{ activeTab === 'variables' && <div>
  ... </div> }` block) → src/components/wired-tools/WiredVariablesTabView.tsx
- The new component is a pure presentation function: 12 typed props,
  no useState, no useEffect, no event subscriptions. It receives:
    * state to render: variablesType, variablePickerDefinitions,
      selectedVariableDefinition, canVariableHighlight,
      isVariableHighlightActive, variableManageCanOpen,
      selectedVariableProperties, selectedVariableTextValues
    * actions to call: onVariablesTypeChange, onPickVariable,
      onToggleVariableHighlight, onOpenManagePanel
- The parent supplies all of them inline at the call site. The
  manage-panel open sequence (request fresh user vars + reset page +
  clear selection + show modal) is closed over into a single
  onOpenManagePanel callback, so the sub-component doesn't need to
  know about its three internal setters.

Impact
- WiredCreatorToolsView.tsx: 3901 → 3809 lines (−92 net). The file
  is still large, but one of the three big inline blocks is gone.
  Monitor (~176 lines) and Inspection (~138 lines) remain inline as
  follow-up PRs.
- The React Compiler now has a smaller file boundary for the
  Variables panel; once the other two blocks come out the parent
  module should stop being skipped for memoization.

Conscious non-goals
- No state was moved. The shared state (selectedVariableKeys,
  isVariableHighlightActive, variableManagePage, etc.) still lives
  in the parent's useState. Hoisting them to a Zustand slice would
  be a separate PR — premature here.
- No behavior change. Same renders, same handlers, same DOM.

Verification
- yarn eslint on the two touched files: 34 problems baseline,
  34 problems after the split (identical: same FC<{}>, same
  pre-existing set-state-in-effect, same react-compiler skip
  warnings on the parent module).
- yarn test: 49/49 passing.
- yarn tsc on the two files: clean.
2026-05-11 16:46:48 +00:00
simoleo89 6793de2106 Set up Vitest + 22 smoke tests on pure modules (proposal #6)
Phase 3 of the refactor plan in docs/ARCHITECTURE.md — the foundation
that unblocks every safe refactor below.

Install
- yarn add -D vitest@3 jsdom @testing-library/dom @testing-library/react
  @testing-library/jest-dom

Note: pinned to vitest@3 (not the latest 4.x) because yarn 1's peer
resolution breaks on vitest@4's peer link to vite. With vitest@3 the
existing Vite 8 install resolves cleanly.

Configuration
- vitest.config.mts (new): separate from vite.config.mjs because the
  dev/build config wires up renderer SDK aliases that point at sibling
  working trees (../renderer, ../Nitro_Render_V3). Tests are written
  against pure modules that don't pull in the renderer, so the test
  runner uses a smaller alias set.
- tests/setup.ts (new): imports @testing-library/jest-dom/vitest so
  custom matchers (toBeInTheDocument, etc.) are available without
  per-file imports.
- tsconfig.json: include "tests" so eslint stops complaining about
  unparseable files; also makes the IDE see the test files.
- package.json scripts: "test" (one-shot) and "test:watch".

Tests
- tests/WiredCreatorTools.helpers.test.ts (18 cases): covers the pure
  helpers extracted in 3c68d97 — createEmptyMonitorSnapshot,
  formatMonitorLatestOccurrence (5 time-bucket branches),
  formatMonitorHistoryOccurrence, formatVariableTimestamp,
  formatMonitorSource (4 branches), normalizeMonitorReason. These are
  the most boring-but-easy-to-break functions; locking them down first
  is high value, near-zero risk.
- tests/navigatorRoomCreatorStore.test.ts (4 cases): exercises the
  Zustand store added in the previous commit — initial state, latch
  semantics, 5s auto-reset (with fake timers), and the
  "second beginCreate restarts the lockout" invariant. Validates that
  the store-based replacement of the let-singleton has the same
  observable behavior, plus the new invariant that wasn't possible
  before (timer composition under StrictMode double-mount).

Side effect: two non-test source files were converted to `import type`
to keep the test bundle from accidentally pulling in the renderer SDK
transitively:
- src/components/wired-tools/WiredCreatorTools.types.ts
  (`import type { AvatarInfoFurni }`)
- src/components/wired-tools/WiredCreatorTools.helpers.ts
  (`import type { HotelDateTimeParts, MonitorSnapshot }`)
This is harmless — TypeScript already treated them as type-only —
and improves tree-shaking on build as a side benefit.

Verification
- yarn test -> 2 files, 22 tests passing in ~1.0s.
- yarn eslint on tests/ + the two type-only-import files: 0 errors,
  0 warnings.

Migration path
- Next adoption targets: cover useDoorbellState reducer (data hook
  split), the new useNitroQuery adapter (timeout/cleanup behavior),
  and the smaller pure formatters under src/api/.
- React component tests (via @testing-library/react) deferred until
  there's a small mock layer for the renderer SDK. The
  @testing-library/* deps are already installed so that PR is
  unblocked.

https://claude.ai/code/session_01GrR87LAqnAEyKG2ZbmQt5Q
2026-05-11 16:31:53 +00:00
simoleo89 5d8717dedb Split WiredCreatorToolsView: extract types/constants/helpers into 3 sibling files
The single-file WiredCreatorToolsView.tsx was 4493 lines, which is one
of the main reasons the React Compiler reports
"Compilation Skipped: Existing memoization could not be preserved" on
this module. Split is conservative — only the pure leading sections
move out, the component itself is untouched (state, effects, JSX all
stay in place).

New files (sibling to the view):
- WiredCreatorTools.types.ts (~233 lines): every interface and type
  alias declared at the top of the original file.
- WiredCreatorTools.constants.ts (~225 lines): TABS, MONITOR_LOG_ORDER,
  poll constants, MONITOR_ERROR_INFO, INSPECTION_ELEMENTS,
  VARIABLES_ELEMENTS, EDITABLE_*, VARIABLE_DEFINITIONS,
  WIRED_FREEZE_EFFECT_IDS, TEAM_COLOR_NAMES, WEEKDAY/MONTH/DIRECTION
  names. The createVariableDefinition factory is kept as a local helper
  in this file (only used to build VARIABLE_DEFINITIONS).
- WiredCreatorTools.helpers.ts (~147 lines): createEmptyMonitorSnapshot,
  getHotelTimeFormatter (with its module-private cache map),
  getHotelDateTimeParts, formatMonitorLatestOccurrence,
  formatMonitorHistoryOccurrence, formatVariableTimestamp,
  formatMonitorSource, normalizeMonitorReason. All pure (or
  cache-stable), no closure on component state.

WiredCreatorToolsView.tsx changes:
- 4493 -> 3901 lines (-592, ~13% reduction).
- The four inspection-icon asset imports (furni/global/user/context)
  move to the constants file alongside the only consumers
  (INSPECTION_ELEMENTS / VARIABLES_ELEMENTS).
- AvatarInfoFurni was only referenced by the extracted
  InspectionFurniSelection interface and is removed from the main
  file's api import.
- New import block at the top pulls back the symbols actually used by
  the component body.

Verification:
- yarn eslint on the three new files: 0 errors / 0 warnings.
- yarn eslint on WiredCreatorToolsView.tsx: 26 errors before split,
  26 errors after split (identical pre-existing set; nothing new
  introduced).
- yarn tsc --noEmit on the four files: clean (only the project-wide
  pre-existing TS2307 about @nitrots/nitro-renderer not being
  installed locally remains, same as before).

This unblocks future per-tab splits (Monitor / Inspection / Variables
JSX panels are still inline in the view and represent the next ~1600
lines that could move out, but require introducing a shared state
context first since the current setState chain is intertwined).

https://claude.ai/code/session_01GrR87LAqnAEyKG2ZbmQt5Q
2026-05-11 16:31:52 +00:00
simoleo89 535fa71020 ESLint --fix: auto-fix brace-style, indent, semi, no-trailing-spaces
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
2026-05-11 16:31:50 +00:00
Lorenzune 9b36513def WIP preserve local changes before duckie merge 2026-04-21 11:13:32 +02:00
Lorenzune d271264b87 feat: add custom wired show message bubble styles 2026-04-04 15:57:43 +02:00
Lorenzune 36c0221a54 chore: checkpoint current work 2026-04-03 05:22:26 +02:00
Lorenzune 83540ff329 feat: add advanced wired variable tools UI 2026-04-02 04:44:04 +02:00
Lorenzune 31e51297e7 Add wired creator tools monitor and inspection UI
- add the new :wired inspection/monitor panel with furni, user and global tabs

- add live variables, previews, inline editing and keep-selected behavior

- add global room diagnostics placeholders, monitor artwork and server/client timezone display

- add editor support for wf_xtra_text_output_furni_name and related UI texts/assets
2026-03-27 09:37:13 +01:00
Lorenzune 1e00b919e7 feat(ui): add wired creator tools shell 2026-03-19 15:24:18 +01:00