fix(mesh): view crashed with a temporal-dead-zone error on load

"[Vue Error] ReferenceError: Cannot access 'b' before initialization" from
Ye.immediate, taking the whole Mesh view down.

A watcher with `immediate: true` runs DURING setup. This one calls
handleFetchContent, whose body touches consts declared further down the setup
block — so on any session where history already contained an inline
content_ref, it dereferenced a binding that did not exist yet. handleFetchContent
itself is a hoisted `function`, which is why the call site looked innocent.

The initial pass moves to onMounted, which runs after setup completes: every
binding is initialized, and already-loaded history still gets the same
treatment as new messages, which is what `immediate` was there for.

Also adds .planning/todos/pending/2026-08-07-open-task-list.md — one flat list
of everything open, including the app-lifecycle reports (fedimint guardian
installs but does not work, BTCPay wipe not wiping, Bitcoin Knots vanishing,
fedimint gateway dying at 88%), the missing app_install tool behind
"!ai install bitcoin knots", and the LND UI 401s.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
archipelago
2026-08-07 03:33:43 -04:00
co-authored by Claude Opus 5
parent 58c759c149
commit 0a23c99463
2 changed files with 103 additions and 6 deletions
+16 -6
View File
@@ -1656,9 +1656,18 @@ const fetchedUrls = ref<Map<string, string>>(new Map())
// `immediate: true` so already-loaded history gets the same treatment as
// newly-arriving messages.
const autoFetchedCids = new Set<string>()
watch(
() => chatMessages.value.length,
() => {
// NOT `immediate: true`. This watcher calls handleFetchContent, whose body
// touches consts declared further down the setup block — and an immediate
// watcher runs DURING setup, before those exist. Vue surfaced it as
// "ReferenceError: Cannot access 'b' before initialization" from
// Ye.immediate, and it fired whenever history already contained an inline
// content_ref, taking the whole Mesh view down with it.
//
// onMounted runs after setup completes, so every binding is initialized and
// already-loaded history still gets the same treatment as new messages —
// which is what `immediate` was there for.
function autoFetchInlineContent() {
for (const msg of chatMessages.value) {
const payload = msg.typed_payload as { cid?: string; inline?: boolean } | undefined
if (
@@ -1673,9 +1682,10 @@ watch(
void handleFetchContent(msg.typed_payload as any)
}
}
},
{ immediate: true },
)
}
watch(() => chatMessages.value.length, autoFetchInlineContent)
onMounted(autoFetchInlineContent)
// Transport chooser modal state — populated when advice comes back as
// "choose" (size fits both inline-over-mesh AND Tor). User picks a path;