Skip to content

feat: move session bar data to channels - #667

Merged
tariknz merged 6 commits into
mainfrom
feat/session-bar-channel
Aug 8, 2026
Merged

feat: move session bar data to channels#667
tariknz merged 6 commits into
mainfrom
feat/session-bar-channel

Conversation

@tariknz

@tariknz tariknz commented Aug 8, 2026

Copy link
Copy Markdown
Owner

Description

Phase 4 of the architecture plan: move the complete Session Bar data path from renderer telemetry hooks to typed, demand-driven channels.

session-timing.snapshot owns race/session timing, lap totals, green/checkered transitions, and timed-race projections. session-bar.snapshot owns the auxiliary display state: weather, temperatures, wind, fuel/units, brake bias, incidents, lap results, session clock/name, track name, player class/manufacturer position, and lap/session top speed. Standings, Relative, and Information Bar request both channels at 5 Hz only while mounted. Top speed is sampled on every source frame before snapshot publication, preserving short peaks.

Both runtimes are wired for live/tape and lifecycle-less demo sources. The renderer Session Bar tree no longer imports raw telemetry hooks, and the obsolete top-speed, temperature, and session-best-lap renderer updaters are no longer mounted. Storybook supplies both snapshots through ChannelSnapshotDecorator.

Validation:

  • npm run lint -- --no-fix
  • npm run test -- --no-coverage — 1,208 passed, 1 skipped
  • npm run test:replay:curated:update
  • npm run test:replay:curated — 36,000 frames, 70 session revisions, 11 probes

This has not yet been validated in a live iRacing session.

Architecture checklist:

  • N1 — no new synchronous filesystem I/O
  • N2/N3 — no new frontend-to-main or cross-widget imports
  • N4/R4.1 — no new IPC handler or bridge surface
  • R4.4/R4.5 — typed minimum-purpose channels
  • R5.2/R14.1 — deterministic processor unit and recorded-fixture coverage
  • R13.1 — processor and publication paths are measured
  • R13.2 — processor buffers are reused and top speed is aggregated without per-frame snapshots

Screenshots

Before

No visual change intended. Session Bar values were derived independently in renderer hooks from the legacy telemetry stream.

After

No visual change intended. Session Bar values are derived once in the main process and delivered through typed snapshots.

Type of Change

  • New feature (non-breaking change which adds functionality)
  • Bug fix (non-breaking change which fixes an issue)
  • Performance improvement
  • Refactoring (no functional changes)
  • Documentation update
  • Dependency update

Checklist

  • I have discussed this change in the discord server
  • I have tested this in iRacing (either in an online session or with AI)
  • All tests pass locally via npm test
  • I have added tests that prove my fix is effective or that my feature works
  • I have run npm run lint and fixed any issues
  • I have performed a self-review of my own code
  • I have added/updated Storybook stories for visual changes
  • I have updated the README.md (if applicable)
  • I have updated defaultDashboard.ts if introducing new widgets or configurations (if applicable)

Summary by CodeRabbit

  • New Features
    • Added unified session timing and session bar data for race status, lap progress, positions, vehicle details, weather, fuel, incidents, and track information.
    • Improved displays for best laps, top speed, temperatures, wind, wetness, manufacturer position, class rank, and session clock.
    • Added support for fixed-lap and timed race progress, green-flag timing, checkered laps, race duration estimates, replay behavior, and late joins.
  • Improvements
    • Standings, relative, information bar, and overlay views now use consistent session data.
    • Session data updates efficiently and resets cleanly when sessions end or disconnect.

@coderabbitai

coderabbitai Bot commented Aug 8, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: bfc58013-6666-4c71-82d6-36c077031c01

📥 Commits

Reviewing files that changed from the base of the PR and between 1870cb4 and da35ce0.

📒 Files selected for processing (14)
  • docs/IMPLEMENTATION_PLAN.md
  • src/app/processors/SessionBarProcessor.spec.ts
  • src/app/processors/SessionBarProcessor.ts
  • src/app/processors/SessionTimingProcessor.spec.ts
  • src/app/processors/SessionTimingProcessor.ts
  • src/app/processors/lapTimesRuntime.spec.ts
  • src/app/processors/lapTimesRuntime.ts
  • src/app/processors/sessionBarRuntime.ts
  • src/frontend/components/Standings/components/SessionBar/SessionBarClassRank.stories.tsx
  • src/frontend/components/Standings/components/SessionBar/SessionBarManufacturerPosition.stories.tsx
  • src/frontend/context/ChannelStore/useSessionBarSnapshot.ts
  • src/types/channels/channel.ts
  • test-data/telemetry/ai-race-10min.golden.json
  • tools/telemetry-replay/session-bar-probe.ts
🚧 Files skipped from review as they are similar to previous changes (10)
  • src/frontend/context/ChannelStore/useSessionBarSnapshot.ts
  • src/frontend/components/Standings/components/SessionBar/SessionBarManufacturerPosition.stories.tsx
  • src/frontend/components/Standings/components/SessionBar/SessionBarClassRank.stories.tsx
  • tools/telemetry-replay/session-bar-probe.ts
  • src/app/processors/lapTimesRuntime.ts
  • test-data/telemetry/ai-race-10min.golden.json
  • docs/IMPLEMENTATION_PLAN.md
  • src/types/channels/channel.ts
  • src/app/processors/SessionTimingProcessor.ts
  • src/app/processors/SessionBarProcessor.ts

📝 Walkthrough

Walkthrough

Added typed 5 Hz session timing and Session Bar snapshots. Integrated demand-driven runtimes with iRacing and mock bridges. Migrated frontend consumers to snapshot hooks. Added replay probes, tests, and golden validation data.

Changes

Session snapshot migration

Layer / File(s) Summary
Snapshot contracts and processors
src/types/channels/channel.ts, src/app/processors/SessionTimingProcessor.ts, src/app/processors/SessionBarProcessor.ts, src/app/processors/*.spec.ts
Added typed snapshot payloads, 5 Hz channels, session timing calculations, Session Bar telemetry projection, lifecycle resets, and processor coverage.
Demand-driven runtime management
src/app/processors/lapTimesRuntime.ts, src/app/processors/sessionTimingRuntime.ts, src/app/processors/sessionBarRuntime.ts, src/app/processors/*Runtime.spec.ts
Added subscriber-gated runtimes, lifecycle forwarding, versioned publication, disposal handling, and LapTimesRuntime consumer APIs.
Bridge and mock integration
src/app/bridge/iracingSdk/*
Wired session timing and Session Bar runtimes into production and mock bridges. Added demo-mode session timing coverage.
Frontend snapshot plumbing
src/frontend/context/ChannelStore/*, src/frontend/context/SessionTimingStore/*, src/frontend/components/*/widgetRuntimeDefinition.ts, src/frontend/widgetRuntime.spec.tsx
Added snapshot hooks and channel declarations. Updated session timing store synchronization.
Session Bar consumer migration
src/frontend/components/Standings/components/SessionBar/*, src/frontend/components/InformationBar/*, src/frontend/components/OverlayContainer/OverlayContainer.tsx
Migrated Session Bar values and fixtures to snapshot channels. Removed obsolete updater registrations.
Replay probes and validation
tools/telemetry-replay/*, test-data/telemetry/ai-race-10min.golden.json
Added session timing and Session Bar replay probes and golden validation records.
Implementation tracking
docs/IMPLEMENTATION_PLAN.md
Updated Phase 4 status and activity-log entries.

Estimated code review effort: 4 (Complex) | ~45 minutes

Possibly related PRs

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly and concisely describes the main change: moving Session Bar data to channels.
Description check ✅ Passed The description covers the change, architecture, validation results, screenshots, type, checklist, and the missing live iRacing validation.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/session-bar-channel

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@tariknz
tariknz marked this pull request as ready for review August 8, 2026 21:04
@tariknz tariknz changed the title feat: move session timing to channel feat: move session bar data to channels Aug 8, 2026

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 7

🧹 Nitpick comments (9)
src/frontend/components/Standings/components/SessionBar/components/AirTemperatureItem/AirTemperatureItem.tsx (1)

8-10: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Add displayName to each memoized component.

React DevTools cannot reliably identify these anonymous memoized component
definitions. Add an explicit displayName after each declaration.

  • src/frontend/components/Standings/components/SessionBar/components/AirTemperatureItem/AirTemperatureItem.tsx#L8-L10: add AirTemperatureItem.displayName = 'AirTemperatureItem';.
  • src/frontend/components/Standings/components/SessionBar/components/BestLapItem/BestLapItem.tsx#L8-L9: add BestLapItem.displayName = 'BestLapItem';.
  • src/frontend/components/Standings/components/SessionBar/components/BrakeBiasItem/BrakeBiasItem.tsx#L7-L12: add BrakeBiasItem.displayName = 'BrakeBiasItem';.
  • src/frontend/components/Standings/components/SessionBar/components/ClassRankItem/ClassRankItem.tsx#L7-L10: add ClassRankItem.displayName = 'ClassRankItem';.
  • src/frontend/components/Standings/components/SessionBar/components/FuelLevelItem/FuelLevelItem.tsx#L8-L10: add FuelLevelItem.displayName = 'FuelLevelItem';.
  • src/frontend/components/Standings/components/SessionBar/components/IncidentCountItem/IncidentCountItem.tsx#L7-L13: add IncidentCountItem.displayName = 'IncidentCountItem';.
  • src/frontend/components/Standings/components/SessionBar/components/LastLapItem/LastLapItem.tsx#L8-L10: add LastLapItem.displayName = 'LastLapItem';.
  • src/frontend/components/Standings/components/SessionBar/components/ManufacturerPositionItem/ManufacturerPositionItem.tsx#L8-L10: add ManufacturerPositionItem.displayName = 'ManufacturerPositionItem';.
  • src/frontend/components/Standings/components/SessionBar/components/PrecipitationItem/PrecipitationItem.tsx#L7-L8: add PrecipitationItem.displayName = 'PrecipitationItem';.
  • src/frontend/components/Standings/components/SessionBar/components/SessionClockTimeItem/SessionClockTimeItem.tsx#L7-L16: add SessionClockTimeItem.displayName = 'SessionClockTimeItem';.

As per coding guidelines, “Include displayName for memoized components.”

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@src/frontend/components/Standings/components/SessionBar/components/AirTemperatureItem/AirTemperatureItem.tsx`
around lines 8 - 10, Add explicit displayName assignments immediately after each
memoized component declaration: AirTemperatureItem, BestLapItem, BrakeBiasItem,
ClassRankItem, FuelLevelItem, IncidentCountItem, LastLapItem,
ManufacturerPositionItem, PrecipitationItem, and SessionClockTimeItem. Apply the
corresponding component name as its displayName in each listed file.

Source: Coding guidelines

src/frontend/context/ChannelStore/useSessionBarSnapshot.ts (1)

3-7: 🚀 Performance & Scalability | 🔵 Trivial | ⚡ Quick win

Remove the duplicate widget-rate lookup.

useChannelSnapshot already gets the configured rate internally. The explicit
rate argument creates a second useWidgetChannelRate subscription for every
Session Bar consumer.

Proposed change
 export const useSessionBarSnapshot = () =>
-  useChannelSnapshot(
-    'session-bar.snapshot',
-    useWidgetChannelRate('session-bar.snapshot')
-  );
+  useChannelSnapshot('session-bar.snapshot');
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/frontend/context/ChannelStore/useSessionBarSnapshot.ts` around lines 3 -
7, Remove the explicit useWidgetChannelRate call from useSessionBarSnapshot and
invoke useChannelSnapshot with only the session-bar snapshot identifier, relying
on its internal configured-rate lookup.
src/frontend/components/Standings/components/SessionBar/components/SessionLapsItem/SessionLapsItem.tsx (1)

8-17: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Add displayName to each memoized component.

React DevTools and error stacks use this name to identify memoized components.

  • src/frontend/components/Standings/components/SessionBar/components/SessionLapsItem/SessionLapsItem.tsx#L8-L17: Add SessionLapsItem.displayName = 'SessionLapsItem';.
  • src/frontend/components/Standings/components/SessionBar/components/SessionNameItem/SessionNameItem.tsx#L6-L7: Add SessionNameItem.displayName = 'SessionNameItem';.
  • src/frontend/components/Standings/components/SessionBar/components/SessionTimeItem/SessionTimeItem.tsx#L8-L20: Add SessionTimeItem.displayName = 'SessionTimeItem';.
  • src/frontend/components/Standings/components/SessionBar/components/TopSpeedItem/TopSpeedItem.tsx#L8-L17: Add TopSpeedItem.displayName = 'TopSpeedItem';.
  • src/frontend/components/Standings/components/SessionBar/components/TrackNameItem/TrackNameItem.tsx#L6-L7: Add TrackNameItem.displayName = 'TrackNameItem';.
  • src/frontend/components/Standings/components/SessionBar/components/TrackTemperatureItem/TrackTemperatureItem.tsx#L8-L10: Add TrackTemperatureItem.displayName = 'TrackTemperatureItem';.
  • src/frontend/components/Standings/components/SessionBar/components/TrackWetnessItem/TrackWetnessItem.tsx#L7-L19: Add TrackWetnessItem.displayName = 'TrackWetnessItem';.
  • src/frontend/components/Standings/components/SessionBar/components/WindItem/WindItem.tsx#L8-L11: Add WindItem.displayName = 'WindItem';.

As per coding guidelines, **/components/**/*.tsx requires a displayName for memoized components.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@src/frontend/components/Standings/components/SessionBar/components/SessionLapsItem/SessionLapsItem.tsx`
around lines 8 - 17, Add explicit displayName assignments for the memoized
components: in
src/frontend/components/Standings/components/SessionBar/components/SessionLapsItem/SessionLapsItem.tsx
lines 8-17, add one for SessionLapsItem; do the same in
src/frontend/components/Standings/components/SessionBar/components/SessionNameItem/SessionNameItem.tsx
lines 6-7 for SessionNameItem, SessionTimeItem/SessionTimeItem.tsx lines 8-20
for SessionTimeItem, TopSpeedItem/TopSpeedItem.tsx lines 8-17 for TopSpeedItem,
TrackNameItem/TrackNameItem.tsx lines 6-7 for TrackNameItem,
TrackTemperatureItem/TrackTemperatureItem.tsx lines 8-10 for
TrackTemperatureItem, TrackWetnessItem/TrackWetnessItem.tsx lines 7-19 for
TrackWetnessItem, and WindItem/WindItem.tsx lines 8-11 for WindItem.

Source: Coding guidelines

src/app/processors/SessionBarProcessor.ts (2)

9-16: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Rename the helpers n and a to match the sibling processor.

src/app/processors/SessionTimingProcessor.ts:13-21 defines the same two helpers as numberValue and numberArray. Both files were added in this PR. Use one name per concept.

♻️ Proposed refactor
-const n = (f: Telemetry, k: keyof Telemetry): number | undefined => {
-  const v = f[k]?.value?.[0];
-  return typeof v === 'number' && Number.isFinite(v) ? v : undefined;
-};
-const a = (f: Telemetry, k: keyof Telemetry): readonly unknown[] => {
-  const value = f[k]?.value;
-  return Array.isArray(value) ? value : [];
-};
+const numberValue = (
+  frame: Telemetry,
+  key: keyof Telemetry
+): number | undefined => {
+  const value = frame[key]?.value?.[0];
+  return typeof value === 'number' && Number.isFinite(value) ? value : undefined;
+};
+
+const numberArray = (
+  frame: Telemetry,
+  key: keyof Telemetry
+): readonly unknown[] => {
+  const value = frame[key]?.value;
+  return Array.isArray(value) ? value : [];
+};

Update all call sites in this file.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/app/processors/SessionBarProcessor.ts` around lines 9 - 16, Rename the
helper n to numberValue and a to numberArray in SessionBarProcessor.ts, matching
SessionTimingProcessor.ts, and update every call site in the file to use the new
names without changing behavior.

87-93: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Name the Clio car ID.

162 is an unexplained magic number. It selects the dcPeakBrakeBias telemetry channel instead of dcBrakeBias and sets brakeBiasIsClio, which changes how BrakeBiasItem formats the value. A named constant records why the branch exists.

♻️ Proposed refactor
+// The Renault Clio reports peak brake bias on a separate channel and as an
+// unscaled value rather than a percentage.
+const CLIO_CAR_ID = 162;
-    const isClio = player?.CarID === 162;
+    const isClio = player?.CarID === CLIO_CAR_ID;
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/app/processors/SessionBarProcessor.ts` around lines 87 - 93, Define a
descriptive named constant for the Clio car ID near the relevant processor
logic, then replace the literal 162 in the isClio comparison with that constant.
Preserve the existing telemetry-channel selection and brakeBiasIsClio behavior.
src/app/processors/SessionTimingProcessor.ts (2)

29-29: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Both new processor class declarations exceed the 80 character Prettier width. The coding guidelines require Prettier formatting with an 80 character line width. Neither new file was formatted. Run Prettier on both files; it wraps the implements clause automatically.

  • src/app/processors/SessionTimingProcessor.ts#L29-L29: wrap export class SessionTimingProcessor implements TelemetryProcessor<SessionTimingSnapshot> { (91 characters).
  • src/app/processors/SessionBarProcessor.ts#L18-L18: wrap export class SessionBarProcessor implements TelemetryProcessor<SessionBarSnapshot> { (85 characters).

Expected result in both files:

export class SessionTimingProcessor
  implements TelemetryProcessor<SessionTimingSnapshot>
{

As per coding guidelines: "Use Prettier code formatting: single quotes, 80 character line width, trailing commas (ES5)".

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/app/processors/SessionTimingProcessor.ts` at line 29, Run Prettier
formatting on the class declarations in
src/app/processors/SessionTimingProcessor.ts (lines 29-29) and
src/app/processors/SessionBarProcessor.ts (lines 18-18), wrapping each
implements clause to comply with the 80-character width while preserving the
existing class declarations.

Source: Coding guidelines


106-119: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Extract the 604800 sentinel into a named constant.

The value 604800 appears at lines 111, 112, and 119. It encodes the iRacing "unlimited time" sentinel (one week in seconds). A named constant states the intent and keeps the three checks in sync.

♻️ Proposed refactor
 const UPDATE_INTERVAL_SECONDS = 0.2;
 const TIME_EPSILON = 1e-6;
+// iRacing reports one week of seconds when session time is unlimited.
+const UNLIMITED_TIME_SENTINEL_SECONDS = 604800;
     const timeRemaining =
       sessionType === 'Race' &&
       state === SessionState.GetInCar &&
-      rawTimeRemaining >= 604800 &&
-      timeTotal >= 604800
+      rawTimeRemaining >= UNLIMITED_TIME_SENTINEL_SECONDS &&
+      timeTotal >= UNLIMITED_TIME_SENTINEL_SECONDS
         ? -1
         : rawTimeRemaining;
@@
-    const fixedLapRace = !(timeRemaining > 0 && timeRemaining !== 604800);
+    const fixedLapRace = !(
+      timeRemaining > 0 && timeRemaining !== UNLIMITED_TIME_SENTINEL_SECONDS
+    );
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/app/processors/SessionTimingProcessor.ts` around lines 106 - 119, Extract
the repeated 604800 value in the session timing logic around timeRemaining and
fixedLapRace into a named constant representing the iRacing unlimited-time
sentinel, then use that constant in all three comparisons while preserving the
existing behavior.
src/app/processors/SessionTimingProcessor.spec.ts (1)

84-96: 🗄️ Data Integrity & Integration | 🔵 Trivial | ⚡ Quick win

Neither spec asserts that version increases across a reset. Both runtimes publish only when the snapshot version differs from the last published version. src/app/processors/sessionTimingRuntime.ts:113-121 shows the gate, and src/app/processors/sessionBarRuntime.ts:93-101 uses the same pattern. Each reset() therefore depends on incrementing version to reach subscribers. A regression that reused the version would leave stale data on screen after a session change or a disconnect, and no test would fail.

  • src/app/processors/SessionTimingProcessor.spec.ts#L84-L96: capture processor.snapshot().version before onLifecycle({ type: 'sessionNumChange' }) and assert the value increases afterwards.
  • src/app/processors/SessionBarProcessor.spec.ts#L58-L62: capture processor.snapshot().version before onLifecycle({ type: 'disconnect' }) and assert the value increases afterwards.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/app/processors/SessionTimingProcessor.spec.ts` around lines 84 - 96,
Update the reset tests to verify version increments: in
src/app/processors/SessionTimingProcessor.spec.ts lines 84-96, capture
processor.snapshot().version before sessionNumChange and assert it increases
afterward; in src/app/processors/SessionBarProcessor.spec.ts lines 58-62,
capture the version before disconnect and assert it increases after the
lifecycle event.
src/app/processors/SessionBarProcessor.spec.ts (1)

6-63: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Split the single test into separate cases.

One it block covers session projection, top-speed tracking, and lifecycle reset. A failure in the first assertion hides the later behaviours. Separate it blocks report which behaviour regressed.

Extract the session fixture and a frame() helper, as src/app/processors/SessionTimingProcessor.spec.ts:6-37 does, then write one it per behaviour.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/app/processors/SessionBarProcessor.spec.ts` around lines 6 - 63, The
single test should be split into separate cases for session-state projection,
top-speed tracking, and lifecycle reset so failures identify the affected
behavior. Extract shared session setup into a fixture and add a frame() helper,
following the pattern used by SessionTimingProcessor.spec.ts; reuse these
helpers across one it block per behavior.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@docs/IMPLEMENTATION_PLAN.md`:
- Line 33: Update docs/IMPLEMENTATION_PLAN.md lines 33-33 to state that session
timing and auxiliary Session Bar telemetry are both included in PR `#667`, with
only legacy telemetry removal or development-only restriction remaining. Update
lines 471-472 to remove the stale follow-up clause and record that auxiliary
Session Bar telemetry landed in the same PR.
- Around line 277-279: Update the “Session-bar telemetry migration” checklist so
the parent and both child items remain unchecked while PR `#667` is still in
review; remove the premature completion markers and preserve the existing PR
references until the merge requirement is met.

In `@src/app/processors/lapTimesRuntime.ts`:
- Around line 22-49: After registering the subscriber-count and lifecycle
handlers in the constructor, query the current subscriber count for
`lap-times.snapshot` and call `activate()` when it is greater than zero. Ensure
this initializes the processor for subscriptions that existed before
construction while preserving the existing activate/deactivate behavior for
future count changes.

In `@src/app/processors/SessionBarProcessor.ts`:
- Around line 137-139: Update SessionBarProcessor.snapshot() to return a
detached snapshot rather than this.latest, including defensive copies of
competitorCarIds and competitorPositions so published payloads cannot change
after publication. Align onFrame state updates with SessionTimingProcessor’s
fresh-object approach where appropriate, and declare these snapshot arrays as
readonly number[] if compatible with existing consumers.

In `@src/app/processors/SessionTimingProcessor.ts`:
- Around line 246-275: Update the checkered-state handling in
calculateRaceValues to use the frozen lap value, this.checkeredLap ??
currentLap, when setting totalRaceLaps, matching the currentLap value published
by the processor. Compute this frozen lap once and pass it into
calculateRaceValues, then extend the checkered test in
SessionTimingProcessor.spec.ts to assert totalRaceLaps equals the frozen lap.

In
`@src/frontend/components/Standings/components/SessionBar/SessionBarClassRank.stories.tsx`:
- Around line 76-94: Add TelemetryDecorator() to the decorators for
SessionBarClassRank stories at
src/frontend/components/Standings/components/SessionBar/SessionBarClassRank.stories.tsx#L76-L94
and SessionBarManufacturerPosition stories at
src/frontend/components/Standings/components/SessionBar/SessionBarManufacturerPosition.stories.tsx#L91-L118,
while retaining ChannelSnapshotDecorator() in both snapshot fixtures.

In `@tools/telemetry-replay/session-bar-probe.ts`:
- Around line 18-39: Update the telemetry variables list used by the session-bar
probe to include both dcBrakeBias and dcPeakBrakeBias, so SessionBarProcessor
can populate and validate brakeBias in generated snapshots for standard cars and
Clios.

---

Nitpick comments:
In `@src/app/processors/SessionBarProcessor.spec.ts`:
- Around line 6-63: The single test should be split into separate cases for
session-state projection, top-speed tracking, and lifecycle reset so failures
identify the affected behavior. Extract shared session setup into a fixture and
add a frame() helper, following the pattern used by
SessionTimingProcessor.spec.ts; reuse these helpers across one it block per
behavior.

In `@src/app/processors/SessionBarProcessor.ts`:
- Around line 9-16: Rename the helper n to numberValue and a to numberArray in
SessionBarProcessor.ts, matching SessionTimingProcessor.ts, and update every
call site in the file to use the new names without changing behavior.
- Around line 87-93: Define a descriptive named constant for the Clio car ID
near the relevant processor logic, then replace the literal 162 in the isClio
comparison with that constant. Preserve the existing telemetry-channel selection
and brakeBiasIsClio behavior.

In `@src/app/processors/SessionTimingProcessor.spec.ts`:
- Around line 84-96: Update the reset tests to verify version increments: in
src/app/processors/SessionTimingProcessor.spec.ts lines 84-96, capture
processor.snapshot().version before sessionNumChange and assert it increases
afterward; in src/app/processors/SessionBarProcessor.spec.ts lines 58-62,
capture the version before disconnect and assert it increases after the
lifecycle event.

In `@src/app/processors/SessionTimingProcessor.ts`:
- Line 29: Run Prettier formatting on the class declarations in
src/app/processors/SessionTimingProcessor.ts (lines 29-29) and
src/app/processors/SessionBarProcessor.ts (lines 18-18), wrapping each
implements clause to comply with the 80-character width while preserving the
existing class declarations.
- Around line 106-119: Extract the repeated 604800 value in the session timing
logic around timeRemaining and fixedLapRace into a named constant representing
the iRacing unlimited-time sentinel, then use that constant in all three
comparisons while preserving the existing behavior.

In
`@src/frontend/components/Standings/components/SessionBar/components/AirTemperatureItem/AirTemperatureItem.tsx`:
- Around line 8-10: Add explicit displayName assignments immediately after each
memoized component declaration: AirTemperatureItem, BestLapItem, BrakeBiasItem,
ClassRankItem, FuelLevelItem, IncidentCountItem, LastLapItem,
ManufacturerPositionItem, PrecipitationItem, and SessionClockTimeItem. Apply the
corresponding component name as its displayName in each listed file.

In
`@src/frontend/components/Standings/components/SessionBar/components/SessionLapsItem/SessionLapsItem.tsx`:
- Around line 8-17: Add explicit displayName assignments for the memoized
components: in
src/frontend/components/Standings/components/SessionBar/components/SessionLapsItem/SessionLapsItem.tsx
lines 8-17, add one for SessionLapsItem; do the same in
src/frontend/components/Standings/components/SessionBar/components/SessionNameItem/SessionNameItem.tsx
lines 6-7 for SessionNameItem, SessionTimeItem/SessionTimeItem.tsx lines 8-20
for SessionTimeItem, TopSpeedItem/TopSpeedItem.tsx lines 8-17 for TopSpeedItem,
TrackNameItem/TrackNameItem.tsx lines 6-7 for TrackNameItem,
TrackTemperatureItem/TrackTemperatureItem.tsx lines 8-10 for
TrackTemperatureItem, TrackWetnessItem/TrackWetnessItem.tsx lines 7-19 for
TrackWetnessItem, and WindItem/WindItem.tsx lines 8-11 for WindItem.

In `@src/frontend/context/ChannelStore/useSessionBarSnapshot.ts`:
- Around line 3-7: Remove the explicit useWidgetChannelRate call from
useSessionBarSnapshot and invoke useChannelSnapshot with only the session-bar
snapshot identifier, relying on its internal configured-rate lookup.
🪄 Autofix

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 94adf6fe-ee89-42f5-902b-5da8b75d4bd8

📥 Commits

Reviewing files that changed from the base of the PR and between e9b7d99 and 1870cb4.

📒 Files selected for processing (54)
  • docs/IMPLEMENTATION_PLAN.md
  • src/app/bridge/iracingSdk/iracingSdkBridge.ts
  • src/app/bridge/iracingSdk/mock-data/mockSdkBridge.spec.ts
  • src/app/bridge/iracingSdk/mock-data/mockSdkBridge.ts
  • src/app/processors/SessionBarProcessor.spec.ts
  • src/app/processors/SessionBarProcessor.ts
  • src/app/processors/SessionTimingProcessor.spec.ts
  • src/app/processors/SessionTimingProcessor.ts
  • src/app/processors/lapTimesRuntime.ts
  • src/app/processors/sessionBarRuntime.spec.ts
  • src/app/processors/sessionBarRuntime.ts
  • src/app/processors/sessionTimingRuntime.spec.ts
  • src/app/processors/sessionTimingRuntime.ts
  • src/frontend/components/InformationBar/InformationBar.stories.tsx
  • src/frontend/components/InformationBar/widgetRuntimeDefinition.ts
  • src/frontend/components/OverlayContainer/OverlayContainer.tsx
  • src/frontend/components/Relative/widgetRuntimeDefinition.ts
  • src/frontend/components/Standings/components/SessionBar/SessionBar.spec.tsx
  • src/frontend/components/Standings/components/SessionBar/SessionBar.stories.tsx
  • src/frontend/components/Standings/components/SessionBar/SessionBarClassRank.stories.tsx
  • src/frontend/components/Standings/components/SessionBar/SessionBarManufacturerPosition.stories.tsx
  • src/frontend/components/Standings/components/SessionBar/components/AirTemperatureItem/AirTemperatureItem.tsx
  • src/frontend/components/Standings/components/SessionBar/components/BestLapItem/BestLapItem.tsx
  • src/frontend/components/Standings/components/SessionBar/components/BrakeBiasItem/BrakeBiasItem.tsx
  • src/frontend/components/Standings/components/SessionBar/components/ClassRankItem/ClassRankItem.spec.tsx
  • src/frontend/components/Standings/components/SessionBar/components/ClassRankItem/ClassRankItem.tsx
  • src/frontend/components/Standings/components/SessionBar/components/FuelLevelItem/FuelLevelItem.tsx
  • src/frontend/components/Standings/components/SessionBar/components/IncidentCountItem/IncidentCountItem.tsx
  • src/frontend/components/Standings/components/SessionBar/components/LastLapItem/LastLapItem.tsx
  • src/frontend/components/Standings/components/SessionBar/components/ManufacturerPositionItem/ManufacturerPositionItem.spec.tsx
  • src/frontend/components/Standings/components/SessionBar/components/ManufacturerPositionItem/ManufacturerPositionItem.tsx
  • src/frontend/components/Standings/components/SessionBar/components/PrecipitationItem/PrecipitationItem.tsx
  • src/frontend/components/Standings/components/SessionBar/components/SessionClockTimeItem/SessionClockTimeItem.tsx
  • src/frontend/components/Standings/components/SessionBar/components/SessionLapsItem/SessionLapsItem.tsx
  • src/frontend/components/Standings/components/SessionBar/components/SessionNameItem/SessionNameItem.tsx
  • src/frontend/components/Standings/components/SessionBar/components/SessionTimeItem/SessionTimeItem.tsx
  • src/frontend/components/Standings/components/SessionBar/components/TopSpeedItem/TopSpeedItem.tsx
  • src/frontend/components/Standings/components/SessionBar/components/TrackNameItem/TrackNameItem.tsx
  • src/frontend/components/Standings/components/SessionBar/components/TrackTemperatureItem/TrackTemperatureItem.tsx
  • src/frontend/components/Standings/components/SessionBar/components/TrackWetnessItem/TrackWetnessItem.tsx
  • src/frontend/components/Standings/components/SessionBar/components/WindItem/WindItem.tsx
  • src/frontend/components/Standings/widgetRuntimeDefinition.ts
  • src/frontend/context/ChannelStore/index.ts
  • src/frontend/context/ChannelStore/useSessionBarSnapshot.ts
  • src/frontend/context/ChannelStore/useSessionTimingSnapshot.ts
  • src/frontend/context/SessionTimingStore/SessionTimingStore.tsx
  • src/frontend/context/SessionTimingStore/SessionTimingStoreUpdater.spec.tsx
  • src/frontend/context/SessionTimingStore/SessionTimingStoreUpdater.tsx
  • src/frontend/widgetRuntime.spec.tsx
  • src/types/channels/channel.ts
  • test-data/telemetry/ai-race-10min.golden.json
  • tools/telemetry-replay/run-curated-validation.ts
  • tools/telemetry-replay/session-bar-probe.ts
  • tools/telemetry-replay/session-timing-probe.ts
💤 Files with no reviewable changes (1)
  • src/frontend/components/OverlayContainer/OverlayContainer.tsx

Comment thread docs/IMPLEMENTATION_PLAN.md Outdated
Comment thread docs/IMPLEMENTATION_PLAN.md Outdated
Comment thread src/app/processors/lapTimesRuntime.ts
Comment thread src/app/processors/SessionBarProcessor.ts
Comment thread src/app/processors/SessionTimingProcessor.ts
Comment on lines +18 to +39
variables: [
'AirTemp',
'CarIdxBestLapTime',
'CarIdxClassPosition',
'CarIdxPosition',
'DisplayUnits',
'FuelLevel',
'Lap',
'LapBestLapTime',
'LapLastLapTime',
'PlayerCarTeamIncidentCount',
'Precipitation',
'SessionNum',
'SessionTime',
'SessionTimeOfDay',
'Speed',
'TrackTempCrew',
'TrackWetness',
'WindDir',
'WindVel',
'YawNorth',
],

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Include the brake-bias telemetry variables.

SessionBarProcessor reads dcBrakeBias and dcPeakBrakeBias. This probe does not request either variable. The generated snapshots therefore cannot validate brakeBias for standard cars or Clios.

Proposed fix
       'DisplayUnits',
+      'dcBrakeBias',
+      'dcPeakBrakeBias',
       'FuelLevel',
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
variables: [
'AirTemp',
'CarIdxBestLapTime',
'CarIdxClassPosition',
'CarIdxPosition',
'DisplayUnits',
'FuelLevel',
'Lap',
'LapBestLapTime',
'LapLastLapTime',
'PlayerCarTeamIncidentCount',
'Precipitation',
'SessionNum',
'SessionTime',
'SessionTimeOfDay',
'Speed',
'TrackTempCrew',
'TrackWetness',
'WindDir',
'WindVel',
'YawNorth',
],
variables: [
'AirTemp',
'CarIdxBestLapTime',
'CarIdxClassPosition',
'CarIdxPosition',
'DisplayUnits',
'dcBrakeBias',
'dcPeakBrakeBias',
'FuelLevel',
'Lap',
'LapBestLapTime',
'LapLastLapTime',
'PlayerCarTeamIncidentCount',
'Precipitation',
'SessionNum',
'SessionTime',
'SessionTimeOfDay',
'Speed',
'TrackTempCrew',
'TrackWetness',
'WindDir',
'WindVel',
'YawNorth',
],
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@tools/telemetry-replay/session-bar-probe.ts` around lines 18 - 39, Update the
telemetry variables list used by the session-bar probe to include both
dcBrakeBias and dcPeakBrakeBias, so SessionBarProcessor can populate and
validate brakeBias in generated snapshots for standard cars and Clios.

@tariknz
tariknz merged commit e69c9ae into main Aug 8, 2026
7 checks passed
@tariknz
tariknz deleted the feat/session-bar-channel branch August 8, 2026 22:22
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.

1 participant