Skip to content

Conversation

@thkruz
Copy link
Owner

@thkruz thkruz commented Nov 10, 2025

No description provided.

thkruz added 30 commits October 30, 2025 19:18
…uipment

- introduce Equipment base class and shared equipment.css
- implement full SpectrumAnalyzer (canvas rendering, signal processing, RF/IF handling, responsive resize) with dedicated CSS and bezel.png asset
- add student-equipment module that instantiates 4 SpectrumAnalyzers and update student-page import path
- remove legacy SpectrumAnalyzer.ts and StudentEquipment.ts
…Analyzer tests

- Update package.json: add jest dependency and @types/jest to devDependencies.
- Add client Babel config (client/babel.config.cjs) to support TS/JS transformation for tests.
- Add comprehensive migration documentation (client/docs/MIGRATION.md) describing the Spectrum Analyzer class-based architecture, patterns, and migration checklist.
- Add Jest configuration for the client (client/jest.config.js) with jsdom environment, transforms, mocks, coverage settings and canvas mock setup.
- Add empty jest.setup.js (client/jest.setup.js) placeholder for future test environment setup.
- Add test asset mocks:
  - client/test/mock/styleMock.js (CSS import mock)
  - client/test/mock/fileMock.js (file import mock)
- Add extensive unit/integration tests for the new class-based SpectrumAnalyzer (client/test/spectrum-analyzer.test.ts). Tests cover initialization, UI controls, frequency/band handling, mode/pause behavior, signal processing hooks, event-bus integration, canvas operations, cleanup, and multi-instance scenarios. Also includes scaffolding for StudentEquipment integration tests.

This commit lays the groundwork for running unit tests against the migrated TypeScript equipment classes and documents the migration approach for the Spectrum Analyzer.
… Component import; update App & router

- add pages/abstract-page.ts (AbstractPage) providing common page lifecycle, helpers, and form utilities
- migrate login-page.ts -> LoginPage extends AbstractPage (init/render/handleLogin/performLogin)
- migrate student-page.ts -> StudentPage extends AbstractPage and use container-based rendering
- add components/component.ts and update imports (Header/Body/Footer) to use './component' (normalize filename)
- update App to instantiate LoginPage/StudentPage, use init() lifecycle and public router/property types
- improve router.showPage to alert when a page id is missing
…to unified lifecycle

- Add BaseElement core with template-based render() and lifecycle init()/setupEventListeners()
- Make Component and AbstractPage extend BaseElement; adopt protected html template pattern
- Migrate Header, Footer, Body to template-driven render and remove imperative DOM helpers
- Refactor App to extend BaseElement, manage root element internally, use pagesConstructors to instantiate/init pages, and initialize router
- Expose Router.init() (remove auto-constructor init) and adjust app/router initialization flow
- Simplify Equipment base and downstream classes (SpectrumAnalyzer, StudentEquipment): extend BaseElement, align render() signature, remove duplicated helpers/cleanup stubs
- Update pages (LoginPage, StudentPage) to return HTMLElement, call super.init(), use new lifecycle and adjust navigation
- Update index.ts to instantiate App() without passing root element
…unify antenna events; wire StudentEquipment

- Add Antenna component + antenna.css
  - Full UI (loopback switch, HPA, power, auto-track, band/offset/target controls)
  - Emits ANTENNA_CONFIG_CHANGED, ANTENNA_LOOPBACK_CHANGED, ANTENNA_HPA_CHANGED, ANTENNA_TRACK_CHANGED, ANTENNA_POWER_CHANGED, ANTENNA_ERROR, ANTENNA_LOCKED
  - Simulated lock acquisition, validation when non-operational

- Add Transmitter component + transmitter.css
  - 4-modem case, modem config UI, transmit toggle and power meter
  - Power calculation/validation against powerBudget
  - Emits TX_CONFIG_CHANGED, TX_TRANSMIT_CHANGED, TX_ERROR

- Add Receiver component + receiver.css
  - 4-modem case, modem config UI, signal status & monitor placeholder
  - Emits RX_CONFIG_CHANGED, RX_SIGNAL_FOUND, RX_SIGNAL_LOST

- Add loopback switch assets (baseball_switch_1.png, baseball_switch_2.png)

- Consolidate & rename events in event-bus
  - Replace granular antenna/tx/rx frequency/power events with unified CONFIG/TRANSMIT/ERROR/LOCK events (ANTENNA_CONFIG_CHANGED, TX_CONFIG_CHANGED, RX_CONFIG_CHANGED, etc.)
  - Align event names used across components

- Update SpectrumAnalyzer to listen for ANTENNA_CONFIG_CHANGED instead of old event

- Update StudentEquipment
  - Import and instantiate SpectrumAnalyzer, Antenna, Transmitter, Receiver
  - Initialize multiple analyzers/antennas/tx/rx cases and corresponding containers
  - Extend updateEquipment to propagate updates to antennas, transmitters, receivers and to forward signal data to analyzers
  - getAllConfigs now returns configs for all equipment

Notes:
- New components follow Equipment lifecycle (render/addListeners/initialize/update/getConfig)
- Kept event-driven architecture for cross-component coordination
…tBus.getInstance()

Move common event name constants out of the event-bus module into a dedicated events/Events.ts file.
Remove the exported eventBus singleton usage and update callers (equipment modules and router) to call EventBus.getInstance()
and import the new Events map. Keeps concerns separated and standardizes event usage across the app.
refactor: 🔧 add events/events.ts and update imports to use new events module
fix: adjust SpectrumAnalyzer config (make mutable) and handle antenna config updates by unit; wire openConfig to open the new control panel
chore: add AnalyzerControl CSS/TS files; mark StudentEquipment collections readonly and move global debug export
…faultSignalData; implement antenna signal matching and hook antenna events into SpectrumAnalyzer; align receiver types
…ignal types

- SpectrumAnalyzer now receives an Antenna instance (instead of antenna id) and reads signals/config from antenna
- Standardize and use typed RfSignal / IfSignal / Hertz types; update draw/processing to use frequency/power/bandwidth fields and SATELLITES offsets, loopback and HPA logic
- Move trace/marker state onto SpectrumAnalyzer and update AnalyzerControl to toggle those flags directly
- Make config fields public where needed, tighten readonly constants, simplify update() behavior (signals handled in animation loop)
- Improve deterministic color generation for signals
- Adjust StudentEquipment initialization order to create antennas before analyzers and update callsites
…and integrate antennas with receivers/spectrum

- Introduce Events enum and EventMap typing; replace stringly EventBus with typed on<T>/emit<T> API (keep logging)
- Update Equipment.emit/on to use Events/EventMap; remove unused loadCSS
- Add MHz type; migrate modem/antenna fields to camelCase (modemNumber, antenna, frequency/bandwidth as MHz/Hertz)
- Pass Antenna instances into Receivers; subscribe receivers to antenna events and implement signal matching (getVisibleSignals) and status logic
- Update Antenna to clear signals when not operational/unlocked and filter defaultSignalData by lock + downlink frequency
- Extract/centralize antenna event subscription for SpectrumAnalyzer; move resize handler into render/subscription; default analyzer frequency adjusted
- Add TX/RX event interfaces and small transmitter refactor
- Enable default signals (set isActive true) in constants
- add client/src/storage.ts: AppState, getStore/updateStore, persist to localStorage, sync helpers and EventBus logging
- integrate store into StudentEquipment: expose equipment arrays, persist initial equipment, and hydrate SpectrumAnalyzer configs on hot-reload
- call syncStoreWithEquipment from StudentPage after equipment init
- add @types/webpack-env to devDependencies (package.json / package-lock.json)
- tweak devServer config (disable liveReload) in client webpack.config.js
…migrate storage to new sync module

- Add sync layer: StorageProvider interface, SyncManager, providers (LocalStorage, WebSocket, D1), factory and public sync index
- Replace legacy client storage.ts with async sync/storage.ts that uses SyncManager and StorageProviderFactory
- Emit storage errors via EventBus (Events.STORAGE_ERROR)
- Wire app to new API: swap old sync calls -> syncEquipmentWithStore; make StudentPage.init async and remove direct store logic from StudentEquipment
- Refactor SpectrumAnalyzer config and internals:
  - config now uses centerFrequency/span in Hz and new flags (isPaused, isTraceOn, isMarkerOn)
  - normalize drawing/animation to use Hertz types and computed min/max freq
  - move UI/button updates to helper methods and use config for toggles
- Update AnalyzerControl to use Hertz types and new config fields; fix conversions and display logic
- Add storage-related sync plumbing (debounced saves, provider swapping, HMR support)
…dling

- normalize defaultSignalData feed names (use hyphenated filenames)
- switch equipment grids (spec-a, antenna, tx, rx) to flexible/wrapping layout and add consistent container sizing
- add spacer stylesheet and import it in StudentEquipment; reorder DOM and add isFullEquipmentSuite flag to conditionally initialize/hide extra gear
- reduce initialized spectrum/tx/rx counts when not full suite
- receiver.css: make receiver box auto-size, add box-sizing/overflow rules, enlarge monitor, style video feed, and add responsive small-screen tweaks
- receiver.ts:
  - add syncInputToConfig()
  - use optional chaining / guards to avoid runtime errors when modem/antenna data is missing
  - getActiveModem may return undefined; guard update/apply flows
  - render now uses a <video> element for acquired feeds
  - enhance getVisibleSignals() with frequency-based filtering and 'degraded-' feed prefixing based on offset tolerances
  - expose updateDisplay to ensure UI refresh after changes
- student-page: ensure receivers call syncInputToConfig() after storage sync
- minor transmitter.css cleanup (removed unused flex-grow)
…t styles & defaults

- Remove equipment-section wrappers/spacers in StudentEquipment and use direct grids
- Introduce .receiver-main-content / .rx-modem-config layout; move video monitor side-by-side and add FEC selector; rename receiver inputs to input-rx-*
- Update receiver CSS for tighter spacing, fixed panel widths, adjusted grid columns and responsive behaviors
- Introduce .transmitter-main-content / .tx-modem-config / .transmitter-power-content; rename TX inputs to input-tx-* and move power UI into its own column
- Update transmitter CSS to match RX layout conventions and tweak grid sizing
- Lower default transmitter power from -50 dBm to -97 dBm and compute power % from active modem values
- Constrain SpectrumAnalyzer canvas and internal width/height for consistent rendering
- Minor responsive tweaks and class consolidations across equipment styles
- Replace hard-coded colors with CSS variables across header/footer/body and add unified :root variables in index.css
- Update footer legal/attribution text to new wording
- Rename and adjust equipment grid classes (spec-a-grid -> antenna-spec-a-grid), tweak container IDs and layout in StudentEquipment, and update visibility logic
- Update antenna satellite select labels to named satellites
- Adjust spectrum analyzer canvas height to 280px for consistent sizing
- Fix unit conversions in AnalyzerControl (correct GHz/MHz/kHz scaling) and expose convertToHz method
… logo

- Replace header logo/button with new logo image and add logo asset (client/public/logo.png)
- Rename app title/subtitle from "IRIS" to "SignalRange" and update header copy
- Tidy header styles: reduce main title size, remove negative margins, adjust logo spacing
- Simplify footer copyright/license text and emphasize trademark/license link
- Convert TX/RX equipment layouts from flex to 2-column CSS grid and clean up container rules
- Minor CSS cleanup and spacing adjustments for layout consistency
…fy SpectrumAnalyzer

- Move canvas, animation, signal/noise generation and drawing logic into a new SpectrumScreen class (new file).
- SpectrumAnalyzer now delegates rendering and lifecycle (start/pause/resume, frequency range, mode/trace/marker, reset hold) to SpectrumScreen and removes in-class canvas/rendering code.
- Clean up imports, resize handling and lifecycle/dispose logic; add updateScreenState to sync config with the screen.
…with SpectrumScreen

- standardize Equipment API: replace update(data) signature with update() and add sync(data)
- rename/update implementations: Transmitter, Receiver, Antenna now expose sync(data) and no-op periodic update() where appropriate
- StudentEquipment:
  - start game loop on init; call updateEquipment() each frame
  - call specA.screen.draw() from game loop
  - use sync/update semantics when initializing and updating equipment
- SpectrumAnalyzer:
  - rename rf -> isRfMode and add isShowSignals, refreshRate to config
  - pass SpectrumAnalyzer instance into SpectrumScreen instead of separate config object
  - split sync() and update(): sync updates display, update drives screen.update() when not paused
  - update emitted payloads to use isRfMode
- SpectrumScreen:
  - accept SpectrumAnalyzer reference (specA) and read config from it
  - rely on specA.config for mode, trace, marker, refreshRate, noise/floor/decibel ranges
  - simplify lifecycle (running flag, update/draw separation) and visual tweaks (font size, label offsets)
- AnalyzerControl: rename internal spectrumAnalyzer -> specA and update all usages
- SyncManager: apply sync() to equipment when restoring state (spectrum analyzers, antennas, transmitters, receivers)
- constants: lower default signal power from -100 to -110
- receiver.css: fix selector typo (.input-rx-antennac -> .input-rx-antenna)

This refactor centralizes spectrum config access in SpectrumAnalyzer and harmonizes update/sync flows across equipment.
…with initializeDom(), and unify equipment state & sync/events

- Replace render/init patterns with initializeDom() across BaseElement, Component, pages and analyzer control
- Convert equipment (Antenna, Receiver, Transmitter, SpectrumAnalyzer) to use protected state_ + public state getter
- Update SpectrumScreen and AnalyzerControl to read from state, add FrequencyBand enum and centralized bandInformation
- Standardize event payloads and EventBus/Event definitions (SPEC_A/ANTENNA/RX events) to use typed State objects
- Update SyncManager, storage hooks and StudentEquipment to persist/restore new state shapes
- Misc: DOM caching, listener signatures (addListeners(parentDom)), and UI sync helpers to minimize full re-renders
…omponents

- Move DOM initialization, isInitialized flag and domCache into Equipment
- Remove BaseElement dependency and per-component element/isInitialized fields
- Change initializeDom to accept parentId and return parentDom; update build to pass parentId
- Update addListeners signature to require parentDom
- Replace shallow copies with structuredClone for inputState/lastRenderState
- Update Antenna, Receiver, Transmitter, SpectrumAnalyzer to:
  - use parentDom.innerHTML and domCache entries instead of a local element
  - accept parentDom in addListeners and cache commonly used nodes
  - avoid re-attaching listeners after render; introduce syncDomWithState in Receiver
  - initialize screens/canvas from domCache
- General cleanup: simplify update/render flows and reduce duplicated DOM handling
…-driven lifecycle

- replace protected/private state_ getters with a public `state` on Equipment subclasses
- update Antenna, Receiver, Transmitter, SpectrumAnalyzer to operate directly on `state`
- adopt state-driven DOM sync (syncDomWithState), cache DOM in Transmitter, and use build/initialize lifecycle
- Transmitter: add lastRenderState, improved DOM caching, emit TX_ACTIVE_MODEM_CHANGED on modem switch
- add TxActiveModem event type and wire EventBus + storage listener for TX_ACTIVE_MODEM_CHANGED
- StudentEquipment.getAllConfigs now serializes .state for transmitters/receivers; student-page calls syncDomWithState after restore
thkruz and others added 29 commits November 13, 2025 21:28
- add SignalPathManager to encapsulate noise-floor and cumulative gain calculations across RF front-end
- expose antennaNoiseFloor(frequency, bandwidth) on Antenna and refactor systemTempK_/gOverT_ signatures to typed Hertz/Degrees
- refactor RealTimeSpectrumAnalyzer to add Tap A/B UI, toggles and use SignalPathManager in getInputSignals; introduce getSignalsAtTapPoint helper
- instantiate SignalPathManager from CouplerModule
- extend types: add dB and dBi aliases and add noiseFloor + gainInPath to BaseSignal; update LNB, OMT, Transmitter and scenario fixtures accordingly
- remove antenna.state.noiseFloor and legacy isSignalAboveNoiseFloor_ filtering; update CSS for RTSA buttons
Introduce SignalPathManager and delegate noise/gain logic from RFFrontEnd and callers
- Instantiate SignalPathManager on RFFrontEnd and expose externalNoise / noise-floor helpers
- Replace direct getTotalRxGain / ad-hoc noise calculations across RTSA, spectral & waterfall displays, Receiver, and filter UI with SignalPathManager APIs (getTotalRxGain, getExternalNoise, getNoiseFloorIfRx, getTotalGainTo)
- Update RealTimeSpectrumAnalyzer to aggregate max noise-floor across tap points and respect shouldApplyGain flag
- Make SpectralDensityPlot and WaterfallDisplay apply total RX gain via SignalPathManager
- Tighten gain/noise handling in SignalPathManager: handle unpowered components, consolidate FRISS/internal vs external comparisons, and return consistent noiseFloorNoGain / shouldApplyGain semantics
- Type refinements: use dB/dBm typed aliases and update BUC/HPA state/value assignments; compute HPA/BUC output/gain with typed values and update HPA.state.gain from processed inputs

This centralizes signal-path responsibilities, reduces duplicated calculations, and makes noise/gain behavior consistent across visualizations and modules
Add per-module help support and long-form help content for antenna, RTSA, BUC, IF filter,
GPSDO, HPA, and LNB modules. Wire HelpButton into module UIs and base RF module class:

- create large help files and default exports: antenna-help, rtsa-help, buc-module-help,
  filter-module-help, gpsdo-module-help, hpa-module-help, lnb-module-help
- import and instantiate HelpButton in Antenna, RealTimeSpectrumAnalyzer, BUCModule,
  IfFilterBankModule, GPSDOModule, HPAModule, LNBModule and render help button in headers
- add HelpButton import/property to RFFrontEndModule (protected helpBtn_) to enable
  consistent per-module help behavior
- remove older RFFrontEnd/OMT-level help usage (help consolidated at module level)

This centralizes contextual help, improves UX, and keeps large static help content out of
component files for easier maintenance
…tus updates

- Rename Antenna.state.skew -> polarization and update all UI bindings, labels and handlers (rotary knob, sync, syncDomWithState)
- Replace polar-plot update() with draw(az,el); only redraw when angles change and initialize font/textBaseline on DOM ready
- Add Antenna.draw() and subscribe to DRAW event to update polar plot
- Consolidate polarization logic: rename params/vars in polarization loss and polMismatch functions; use polarization consistently when computing losses
- BaseEquipment: throttle status bar and LED updates (1s), select highest-priority alarm via ordered priorities, and avoid unnecessary DOM writes
- RealTimeSpectrumAnalyzer / RTSAScreen: centralize canvas sizing and font; reduce canvas instantiation sizes to 800x500 / 800x230; import RTSA help component
- SpectralDensityPlot: remove duplicate font assignments now handled by RTSAScreen
- OMTModule: use antenna.state.polarization when computing effective polarization
- Misc: import dB type and trim trailing whitespace in lock message

All changes aim to standardize polarization naming, reduce redundant redraws/DOM churn, and centralize canvas/font setup for RTSA
- Antenna: exclude rxSignalsIn from state comparison to avoid unnecessary DOM syncs
- RTSA: add frequency label and grid+labels ImageData caching, invalidate on range/amplitude changes, restore cached grid via putImageData, move signal updates and gate dev-mode drawing to reduce per-frame work
- LNB: quantize noise-temperature LED brightness to discrete levels and only apply style changes when the level changes
- Satellite: pre-cache random values per signal and refactor degradation pipeline to mutate power in-place with early exit when effects are disabled to minimize allocations and improve runtime performance
- adjust canvas sizes for single-mode and dual-mode displays (single: 824x460, both: spectral 824x230 / waterfall 824x230)
- remove noisy Logger.info and move default font out of RTSAScreen constructor to per-plot draw methods
- update in-band/out-of-band width math and sigma calculations for spectral and waterfall plots to produce smoother, more realistic Gaussian-shaped signals
- overhaul createRealSignal to improve main-lobe jitter, transition/side-lobe behavior, and out-of-band decay for better visual fidelity
- align WaterfallDisplay signal generation with SpectralDensityPlot changes
Call notifyStateChange_() after updating this.state.polarization so UI and listeners are informed of polarization changes. Previously polarization updates didn't propagate, causing DOM/logic to remain out of sync
feat(analyzer-control): add ACExtra4Btn for additional functionality

feat(analyzer-control): enhance ACTraceBtn with multi-trace support

fix(real-time-spectrum-analyzer): improve state management and sync

refactor(spectral-density-plot): optimize trace handling and drawing logic
fix(scenario1): 🐛 set selfTestPassed to true for scenario data
feat(scenarios): integrate objectives into scenario 1 data
feat(modal): update modal to support iframe for external content
fix(events): add new events for objective completion and condition changes
refactor(router): simplify scenario management in routing logic
refactor(scenario-manager): streamline scenario settings handling
style(modal): change modal background to solid color for consistency
Created SpectrumDataProcessor class to centralize noise and signal data
generation, eliminating duplicate code between spectral-density-plot and
waterfall-display components.

Key improvements:
- Single data generation per update cycle (shared by all renderers)
- Reduced code duplication (~187 lines removed)
- Better separation of concerns
- Data can now be synced across networked environments
- Spectral density and waterfall now use identical data source

Files changed:
- Added: spectrum-data-processor.ts (centralized data generation)
- Modified: real-time-spectrum-analyzer.ts (delegates to data processor)
- Modified: spectral-density-plot.ts (removed local data generation)
- Modified: waterfall-display.ts (removed local data generation)
- Add ModalProfile class for displaying user profile information
- Implement popup-callback for handling OAuth authentication
- Create supabase-client for managing Supabase interactions
- Define user account types and interfaces in types.ts
- Style user account components with user-account.css
- Introduce UserDataService for managing user data with error handling
- Add custom error class UserDataServiceError for better error management
…cessor-01LkekMkuy8LToFoC4ocCjPn

refactor: separate data generation from rendering in spectrum analyzer
…spectrum-data-processor): ♻️ make properties readonly for better immutability
feat(vscode): ✨ enhance TypeScript and ESLint configurations
refactor(modal): ♻️ improve modal manager with new callbacks
refactor(equipment): ♻️ integrate checklist modal functionality
docs: 📝 add code patterns and conventions documentation
- Fixed Jest module mapping for @app and @engine paths
- Added comprehensive mocks for Supabase and Auth modules
- Implemented missing App.sync() method to emit Events.SYNC
- Created new test suites:
  * Logger tests: comprehensive coverage for all log levels
  * EventBus tests: pub/sub functionality, once, off, clear
  * PerlinNoise tests: singleton, caching, coordinate handling
  * Router tests: navigation, history, event emission
- Improved test infrastructure with proper setup/teardown

Coverage improvements:
- Statements: 4.69% → 23.22%
- Branches: 2.4% → 18.49%
- Functions: 4.37% → 28.05%
- Lines: 4.81% → 23.81%
@thkruz thkruz merged commit 5f2aab7 into main Nov 23, 2025
5 of 7 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants