ZDDC/browse/js
ZDDC b0d0ff13cd fix(browse): serialize navigation — nav-sequence token + per-node load guard
Every async flow that ends by replacing the tree root (refreshListing,
rescopeServer, reloadDir, and the app.js back/forward popstate handler) ran
without any concurrency guard. Two overlapping listings — a double-click into
a folder, a refresh fired mid-load, rapid back/forward — could resolve out of
order, so a slow fetch would setRoot/pushState on top of a newer navigation
and leave the tree out of sync with state.currentPath and the URL bar.

Introduce a shared monotonic nav-sequence token in events.js (beginNav /
isCurrentNav, exported so the app.js popstate handler joins the same
sequence). Each flow claims a token before its fetch and bails if a newer
navigation has started by the time it resolves — last navigation wins,
stale ones drop their result before mutating anything. navigateIntoFolder's
FS branch is reordered to mutate scope state only after a successful fetch +
token check, so a bail leaves the previous scope intact instead of
half-swapped.

Duplicate-fetch race fixed at the source: tree.loadChildren took only a
`loaded` check, so rapid Enter/ArrowRight key-repeat or a double-click
landing during a single-click's load fired two concurrent fetches that raced
in setChildren. Added a `loading` in-flight flag that serializes per-node
loads — the second caller is a no-op until the first resolves. This also
removes the need to await the fire-and-forget toggleFolder calls in the
keyboard handler.

Also surfaces reloadDir fetch failures via statusError instead of swallowing
them (the success path's create/rename/delete toast no longer hides a failed
refresh).

All 6 browse Playwright specs pass.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-03 15:21:57 -05:00
..
accept-transmittal.js refactor(browse): consolidate duplicated helpers into util.js; fix YAML save divergence 2026-06-03 15:07:00 -05:00
app.js fix(browse): serialize navigation — nav-sequence token + per-node load guard 2026-06-03 15:21:57 -05:00
create-transmittal.js refactor(browse): consolidate duplicated helpers into util.js; fix YAML save divergence 2026-06-03 15:07:00 -05:00
download.js refactor: virtual file extensions for subtree zip + MD conversion 2026-05-14 12:23:37 -05:00
events.js fix(browse): serialize navigation — nav-sequence token + per-node load guard 2026-06-03 15:21:57 -05:00
grid.js feat(zddc): Phase 4b — grid mode driven by cascade default_tool 2026-05-11 16:15:25 -05:00
history.js refactor(browse): consolidate duplicated helpers into util.js; fix YAML save divergence 2026-06-03 15:07:00 -05:00
hovercard.js refactor(browse): consolidate duplicated helpers into util.js; fix YAML save divergence 2026-06-03 15:07:00 -05:00
init.js feat(browse): SPA overhaul — context menu, YAML editor, icons, hovercard, deep links, autofilter 2026-05-14 12:12:42 -05:00
loader.js feat(browse): markdown version-history viewer with diff + restore 2026-05-28 12:49:00 -05:00
plan-review.js refactor(browse): consolidate duplicated helpers into util.js; fix YAML save divergence 2026-06-03 15:07:00 -05:00
preview-markdown.js refactor(browse): consolidate duplicated helpers into util.js; fix YAML save divergence 2026-06-03 15:07:00 -05:00
preview-yaml.js refactor(browse): consolidate duplicated helpers into util.js; fix YAML save divergence 2026-06-03 15:07:00 -05:00
preview.js refactor(browse): consolidate duplicated helpers into util.js; fix YAML save divergence 2026-06-03 15:07:00 -05:00
stage.js refactor(browse): consolidate duplicated helpers into util.js; fix YAML save divergence 2026-06-03 15:07:00 -05:00
tree.js fix(browse): serialize navigation — nav-sequence token + per-node load guard 2026-06-03 15:21:57 -05:00
upload.js feat(browse): full create/edit/rename/delete in local-directory (offline) mode 2026-06-01 10:46:51 -05:00
util.js refactor(browse): consolidate duplicated helpers into util.js; fix YAML save divergence 2026-06-03 15:07:00 -05:00