Split-off from the 2026-07 audit backlog (#111) — the one "consider"-tier item that was intentionally not bundled into #119 (see that PR's checklist).
Current state
VaultBaseAuth.__authToken holds either a Promise<AuthToken> (login in flight) or a resolved AuthToken, discriminated at each use site by instanceof:
// src/auth/VaultBaseAuth.js
const tokenExpired = this.__authToken instanceof AuthToken && this.__authToken.isExpired();
// ...
this.__authToken = tokenPromise; // sometimes a Promise
// ...
return Promise.resolve(this.__authToken); // works for both
Overloading one field with two types makes the auth state machine harder to read and easy to get subtly wrong when touched.
Proposal
Separate into two clearly-typed fields — e.g. __pendingLogin: Promise<AuthToken> | null and __authToken: AuthToken | null — so the "login in flight" vs "token resolved" states are explicit and no instanceof discrimination is needed.
Notes
- No behavior change — pure internal clarity refactor; public API and semantics stay identical.
- Keep the existing single-flight behavior (concurrent callers awaiting one in-flight login) and the renewal-timer wiring intact.
priority: low — pick up opportunistically or when next touching the auth state machine.
Split-off from the 2026-07 audit backlog (#111) — the one "consider"-tier item that was intentionally not bundled into #119 (see that PR's checklist).
Current state
VaultBaseAuth.__authTokenholds either aPromise<AuthToken>(login in flight) or a resolvedAuthToken, discriminated at each use site byinstanceof:Overloading one field with two types makes the auth state machine harder to read and easy to get subtly wrong when touched.
Proposal
Separate into two clearly-typed fields — e.g.
__pendingLogin: Promise<AuthToken> | nulland__authToken: AuthToken | null— so the "login in flight" vs "token resolved" states are explicit and noinstanceofdiscrimination is needed.Notes
priority: low— pick up opportunistically or when next touching the auth state machine.