Fix tab/view navigation: reactivity loop + Daily forecast TDZ
All checks were successful
Test, Build & Deploy / test-and-build (push) Successful in 29s
Test, Build & Deploy / deploy (push) Successful in 22s

- notifications.svelte.js: analyze() iterated the reactive $state field
  `alerts` right after writing it, inside an $effect. That read-after-write
  made Svelte treat the effect as depending on `alerts`, so writing it
  re-ran the effect forever -> effect_update_depth_exceeded, which killed the
  click handler after setting the hash but before swapping the view. Iterate
  the local newAlerts array instead.

- DailyForecast.svelte: use `precip` {@const} before its declaration caused
  a 'Cannot access precip before initialization' TDZ error when the 7-day tab
  rendered. Moved the declaration above its first use.

Both verified in a real headless Chromium: tabs now switch correctly (hash +
active state + content), no console/page errors. 81/81 tests pass.
This commit is contained in:
hermes-explorigin 2026-09-08 02:08:21 +00:00
parent 897f49ae22
commit 2eb34a709b
3 changed files with 8 additions and 6 deletions

8
dist/index.html vendored
View File

@ -6220,7 +6220,7 @@ var NotificationStore = class {
} }
newAlerts = newAlerts.filter((a) => !this.dismissedIds.has(a.id)); newAlerts = newAlerts.filter((a) => !this.dismissedIds.has(a.id));
this.alerts = newAlerts; this.alerts = newAlerts;
for (const a of this.alerts) { for (const a of newAlerts) {
if (this._notifiedIds.has(a.id)) continue; if (this._notifiedIds.has(a.id)) continue;
this._notifiedIds.add(a.id); this._notifiedIds.add(a.id);
notify({ notify({
@ -6831,10 +6831,10 @@ function DailyForecast($$anchor, $$props) {
var fragment_1 = comment(); var fragment_1 = comment();
var node_1 = first_child(fragment_1); var node_1 = first_child(fragment_1);
var consequent_2 = ($$anchor) => { var consequent_2 = ($$anchor) => {
const info = /* @__PURE__ */ user_derived(() => getWeatherInfo(get(daily).weather_code[i], precip)); const precip = /* @__PURE__ */ user_derived(() => get(daily).precipitation_probability_max?.[i] || 0);
const info = /* @__PURE__ */ user_derived(() => getWeatherInfo(get(daily).weather_code[i], get(precip)));
const tempMax = /* @__PURE__ */ user_derived(() => Math.round(get(daily).temperature_2m_max[i])); const tempMax = /* @__PURE__ */ user_derived(() => Math.round(get(daily).temperature_2m_max[i]));
const tempMin = /* @__PURE__ */ user_derived(() => Math.round(get(daily).temperature_2m_min[i])); const tempMin = /* @__PURE__ */ user_derived(() => Math.round(get(daily).temperature_2m_min[i]));
const precip = /* @__PURE__ */ user_derived(() => get(daily).precipitation_probability_max?.[i] || 0);
const wind = /* @__PURE__ */ user_derived(() => get(daily).wind_speed_10m_max?.[i]); const wind = /* @__PURE__ */ user_derived(() => get(daily).wind_speed_10m_max?.[i]);
var div_2 = root_2$6(); var div_2 = root_2$6();
set_class(div_2, 1, "day-card card-glass svelte-ss3yj8", null, {}, { today: i === 0 }); set_class(div_2, 1, "day-card card-glass svelte-ss3yj8", null, {}, { today: i === 0 });
@ -8792,7 +8792,7 @@ delegate([
]); ]);
//#endregion //#endregion
//#region src/main.js //#region src/main.js
console.info({ commit_hash: "2c678fd00db6e0244334a9b6de10a6d379c9126c" }); console.info({ commit_hash: "897f49ae2209cb2213ea97a4a082bb4bdfa2889a" });
registerServiceWorker(); registerServiceWorker();
mount(App, { target: document.getElementById("app") }); mount(App, { target: document.getElementById("app") });
//#endregion</script> //#endregion</script>

View File

@ -29,10 +29,10 @@
<div class="daily-list"> <div class="daily-list">
{#each daily.time as day, i} {#each daily.time as day, i}
{#if i < 7} {#if i < 7}
{@const precip = daily.precipitation_probability_max?.[i] || 0}
{@const info = getWeatherInfo(daily.weather_code[i], precip)} {@const info = getWeatherInfo(daily.weather_code[i], precip)}
{@const tempMax = Math.round(daily.temperature_2m_max[i])} {@const tempMax = Math.round(daily.temperature_2m_max[i])}
{@const tempMin = Math.round(daily.temperature_2m_min[i])} {@const tempMin = Math.round(daily.temperature_2m_min[i])}
{@const precip = daily.precipitation_probability_max?.[i] || 0}
{@const wind = daily.wind_speed_10m_max?.[i]} {@const wind = daily.wind_speed_10m_max?.[i]}
<div class="day-card card-glass" class:today={i === 0}> <div class="day-card card-glass" class:today={i === 0}>

View File

@ -150,7 +150,9 @@ export class NotificationStore {
// Lightweight native notifications: surface alerts that just appeared and // Lightweight native notifications: surface alerts that just appeared and
// haven't been notified this forecast day. Best-effort — never blocks. // haven't been notified this forecast day. Best-effort — never blocks.
for (const a of this.alerts) { // NOTE: iterate the local `newAlerts` (not reactive `this.alerts`) — a
// read-after-write on $state inside this $effect would loop forever.
for (const a of newAlerts) {
if (this._notifiedIds.has(a.id)) continue if (this._notifiedIds.has(a.id)) continue
this._notifiedIds.add(a.id) this._notifiedIds.add(a.id)
notify({ notify({