chore: Enforce a few house rules via eslint (#2539)
This commit is contained in:
committed by
dermotduffy
parent
5572ec728e
commit
921d45e577
@@ -29,7 +29,7 @@ export class IssueManager {
|
||||
private _suspended = false;
|
||||
|
||||
// Reentrancy guard: evaluate() calls setState() on the condition state
|
||||
// manager, which fires listeners synchronously — including the one
|
||||
// manager, which fires listeners synchronously -- including the one
|
||||
// registered in this constructor. Without this guard, detectDynamic()
|
||||
// and presence computation would run twice per evaluation.
|
||||
private _evaluating = false;
|
||||
@@ -165,16 +165,14 @@ export class IssueManager {
|
||||
// normal re-evaluation (on any condition-state change).
|
||||
//
|
||||
// `initialized: true` in the change payload means mandatory initialization
|
||||
// just finished — see InitializationManager._initializeMandatory. That's
|
||||
// just finished -- see InitializationManager._initializeMandatory. That's
|
||||
// also the earliest point at which the full HASS object is guaranteed
|
||||
// ready for websocket calls (e.g. LegacyResourceIssue's lovelace/resources
|
||||
// fetch). Because `initialized` is latched (its comment notes it never
|
||||
// changes again), this block fires exactly once per IssueManager life.
|
||||
private _onStateChange(change: ConditionStateChange): void {
|
||||
if (change.change.initialized === true && change.new.hass) {
|
||||
/* async */ this._stateManager
|
||||
.detectStatic(change.new.hass)
|
||||
.then(() => this.evaluate());
|
||||
void this._stateManager.detectStatic(change.new.hass).then(() => this.evaluate());
|
||||
}
|
||||
this.evaluate();
|
||||
}
|
||||
|
||||
@@ -19,7 +19,7 @@ export class ConnectionIssue implements Issue {
|
||||
private _state: ConnectionState = 'ready';
|
||||
|
||||
public detectDynamic(state: ConditionState): void {
|
||||
// Before HASS is ever provided, leave state untouched — undefined hass is
|
||||
// Before HASS is ever provided, leave state untouched -- undefined hass is
|
||||
// not a disconnection, just "not yet initialized".
|
||||
if (state.hass === undefined) {
|
||||
return;
|
||||
|
||||
@@ -44,7 +44,7 @@ export class InitializationIssue extends AbstractErrorIssue {
|
||||
// resources (WebSocket subscriptions, listeners) before the CAMERAS
|
||||
// init aspect replaces the instance via createCameraManager().
|
||||
this._api.getInitializationManager().uninitializeMandatory();
|
||||
this._api.getCameraManager().destroy();
|
||||
void this._api.getCameraManager().destroy();
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@@ -37,7 +37,7 @@ export class MediaLoadIssue implements Issue {
|
||||
}
|
||||
|
||||
// =========================================================================
|
||||
// Explicit trigger — called when a component fires an issue:trigger event.
|
||||
// Explicit trigger -- called when a component fires an issue:trigger event.
|
||||
// =========================================================================
|
||||
|
||||
public trigger(context: IssueTriggerContext['media_load']): void {
|
||||
@@ -45,7 +45,7 @@ export class MediaLoadIssue implements Issue {
|
||||
}
|
||||
|
||||
// =========================================================================
|
||||
// Detection — called by the manager on every state change.
|
||||
// Detection -- called by the manager on every state change.
|
||||
// =========================================================================
|
||||
|
||||
public detectDynamic(state: ConditionState): void {
|
||||
@@ -62,7 +62,7 @@ export class MediaLoadIssue implements Issue {
|
||||
}
|
||||
|
||||
// =========================================================================
|
||||
// State queries — called by the manager to read current state.
|
||||
// State queries -- called by the manager to read current state.
|
||||
// =========================================================================
|
||||
|
||||
public hasIssue(): boolean {
|
||||
@@ -113,7 +113,7 @@ export class MediaLoadIssue implements Issue {
|
||||
}
|
||||
|
||||
// =========================================================================
|
||||
// Retry — called by the manager to schedule a media reload.
|
||||
// Retry -- called by the manager to schedule a media reload.
|
||||
// =========================================================================
|
||||
|
||||
public needsRetry(): boolean {
|
||||
@@ -144,7 +144,7 @@ export class MediaLoadIssue implements Issue {
|
||||
// re-attempts loading underneath. If the retry succeeds,
|
||||
// _handleMediaLoaded will clear everything when media:loaded fires. If
|
||||
// it fails silently (e.g. bogus stream name), the error stays visible
|
||||
// immediately — no new 10s grace period.
|
||||
// immediately -- no new 10s grace period.
|
||||
this._api.getViewManager().setViewWithMergedContext({ mediaEpoch });
|
||||
return false;
|
||||
}
|
||||
@@ -212,7 +212,7 @@ export class MediaLoadIssue implements Issue {
|
||||
this._timerTargetID = targetID;
|
||||
this._timer.start(MEDIA_LOADING_TIMEOUT_SECONDS, () => {
|
||||
// Record the error on timeout so retry() knows which epoch to bump.
|
||||
// targetID is guaranteed non-null here — the null case bails at the
|
||||
// targetID is guaranteed non-null here -- the null case bails at the
|
||||
// top of _handleMediaNotLoaded.
|
||||
this._erroredTargetIDs.add(targetID);
|
||||
this._activate();
|
||||
|
||||
@@ -31,7 +31,7 @@ export class MediaQueryIssue extends AbstractErrorIssue {
|
||||
return false;
|
||||
}
|
||||
this._error = null;
|
||||
this._api.getViewManager().setViewByParametersWithNewQuery();
|
||||
void this._api.getViewManager().setViewByParametersWithNewQuery();
|
||||
|
||||
// Exclusive retry. No other issue should attempt to retry until the next
|
||||
// evaluation cycle, when we'll know if this was successful.
|
||||
|
||||
@@ -3,7 +3,7 @@ import { summarizeNotification } from '../../components-lib/notification/summari
|
||||
import { ConditionState } from '../../condition-trigger/conditions/types';
|
||||
import { Notification } from '../../config/schema/actions/types';
|
||||
import { HomeAssistant } from '../../ha/types';
|
||||
import { isTruthy } from '../../utils/basic';
|
||||
import { errorToConsole, isTruthy } from '../../utils/basic';
|
||||
import {
|
||||
Issue,
|
||||
IssueDescription,
|
||||
@@ -27,12 +27,18 @@ export class IssueStateManager implements IssueReadOnlyState {
|
||||
}
|
||||
|
||||
// =========================================================================
|
||||
// Detection — static (one-shot on init) and dynamic (on every state change).
|
||||
// Detection -- static (one-shot on init) and dynamic (on every state change).
|
||||
// =========================================================================
|
||||
|
||||
public async detectStatic(hass: HomeAssistant): Promise<void> {
|
||||
for (const issue of this._issues.values()) {
|
||||
await issue.detectStatic?.(hass);
|
||||
try {
|
||||
await issue.detectStatic?.(hass);
|
||||
} catch (e) {
|
||||
// Isolate one issue's detection failure so it cannot abort detection
|
||||
// for the rest; log so the cause is visible.
|
||||
errorToConsole(e as Error);
|
||||
}
|
||||
this._logIfNew(issue);
|
||||
}
|
||||
}
|
||||
@@ -57,7 +63,7 @@ export class IssueStateManager implements IssueReadOnlyState {
|
||||
}
|
||||
|
||||
// =========================================================================
|
||||
// Queries — read active issue state.
|
||||
// Queries -- read active issue state.
|
||||
// =========================================================================
|
||||
|
||||
public getFullCardIssue(): IssueDescription | null {
|
||||
|
||||
@@ -28,11 +28,11 @@ export interface KeyedIssueDescription {
|
||||
}
|
||||
|
||||
// Map of currently active issues keyed by IssueKey, with each entry's value
|
||||
// being the issue's current rendered description. Stored as a Map (not just
|
||||
// a Set of keys) so that sub-state changes within an issue — e.g.
|
||||
// ConnectionIssue swapping between 'lost' and 'starting' — are reflected as
|
||||
// real value-level diffs to the condition state, triggering re-renders and
|
||||
// any user-defined conditions that depend on issue state.
|
||||
// being the issue's current rendered description. Stored as a Map (not just a
|
||||
// Set of keys) so that sub-state changes within an issue -- e.g.
|
||||
// ConnectionIssue swapping between 'lost' and 'starting' -- are reflected as
|
||||
// real value-level diffs to the condition state, triggering re-renders and any
|
||||
// user-defined conditions that depend on issue state.
|
||||
export type IssuePresence = Map<IssueKey, IssueDescription>;
|
||||
export interface IssueReadOnlyState {
|
||||
hasFullCardIssue(): boolean;
|
||||
@@ -80,7 +80,7 @@ export interface Issue {
|
||||
// loop (exclusive), false to allow subsequent issues to also retry.
|
||||
retry?(): boolean;
|
||||
|
||||
// Optional user-initiated fix. Not called by the issue infrastructure —
|
||||
// Optional user-initiated fix. Not called by the issue infrastructure --
|
||||
// callers (e.g. notification control actions) invoke this directly.
|
||||
fix?(hass: HomeAssistant): Promise<boolean>;
|
||||
|
||||
@@ -92,11 +92,11 @@ export interface Issue {
|
||||
|
||||
// Called when the card is detached. Issues with age-based timers (e.g.
|
||||
// loading-timeout timers) must stop them here so that time spent offscreen
|
||||
// doesn't count against the user. Must preserve already-active issue state
|
||||
// — a full-card issue visible at detach should still be visible on
|
||||
// reattach. No `resume` hook: IssueManager.resume() triggers a normal
|
||||
// evaluate(), so any timer that should restart is re-armed via
|
||||
// detectDynamic against the current condition state.
|
||||
// doesn't count against the user. Must preserve already-active issue state --
|
||||
// a full-card issue visible at detach should still be visible on reattach. No
|
||||
// `resume` hook: IssueManager.resume() triggers a normal evaluate(), so any
|
||||
// timer that should restart is re-armed via detectDynamic against the current
|
||||
// condition state.
|
||||
suspend?(): void;
|
||||
|
||||
// Release external resources (e.g. a listener registered on another manager)
|
||||
|
||||
Reference in New Issue
Block a user