Skip to content

fix(state): keep token registries across a root reconnect (#273) - #277

Merged
mogera551 merged 2 commits into
mainfrom
fix/state-reconnect-token-registry
Sep 14, 2026
Merged

mogera551 merged 2 commits into
mainfrom
fix/state-reconnect-token-registry

Conversation

@mogera551

Copy link
Copy Markdown
Contributor

Closes #273.

What was wrong

Re-attaching the root <wcs-state>host.remove(); document.body.appendChild(host), or any move of it in the DOM — silently stopped $on handlers, on scans and command-token subscriptions. There was no error and no warning.

  • disconnectedCallback threw away the command-token and event-token registries.
  • $on (and an on scan) subscribes only in the _state setter, which a reconnect does not run.
  • A command.<method>: binding subscribes only when its value is applied, which a reconnect does not do either.
  • The firing side resolves the token from the registry every time, so after reconnecting it created a fresh token with no subscribers.

Fix

  • Disconnecting keeps both registries, the same two-step shape $streams and $watch already use (stop firing, keep the registry).
  • Nothing fires while the element is disconnected. An element event finds no state tree (No state tree found on this root for eventToken handler), and $command cannot be read because the state cannot be created (State rootNode is not available.). Both are pinned in tests.
  • A re-set still replaces the $on subscriptions.
  • clearCommandTokenRegistry lost its only caller and is removed.

Tests

  • New integration.tokenReconnect.test.ts goes from real binding strings to dispatch and emit. It covers $on after a reconnect, repeated reconnects (still one subscription), a re-set after a reconnect, events while disconnected, command.<method>: with $command emit, onclick: $command.<name>, and emit while disconnected.
  • The DEFECT(#273) test in scan.on.test.ts is flipped.
  • Before the fix, 4 of the 5 new reconnect tests failed, along with the flipped scan test. The re-set test passed, as it should.

Docs

  • The README (en/ja) no longer says the registries are cleared on disconnect.
  • The "known gap" notes for on scans are removed from the README, docs/scan(.ja).md and CHANGELOG.md.
  • docs/state-scan-design.md D8 and §5-3 record the fix.

Verification

Gate Result
state npm run test:coverage 296 files / 3550 tests, exit 0 — 99.6 / 98.74 / 100 / 99.77
state npm run lint, npx tsc --noEmit clean

e2e runs in CI.

🤖 Generated with Claude Code

mogera551 and others added 2 commits September 15, 2026 05:42
Disconnecting the root <wcs-state> threw away the command-token and
event-token registries. $on subscribes only when the state is set and a
command.<method>: binding subscribes only when its value is applied, so
after re-attaching the element every event and every $command emit
reached a fresh token with no subscribers, silently.

Keep both registries on disconnect, as $streams and $watch already keep
theirs. Nothing fires while disconnected: an element event finds no
state tree, and $command cannot create the state. clearCommandTokenRegistry
lost its only caller and is removed.

Closes #273

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@mogera551
mogera551 merged commit 771414b into main Sep 14, 2026
6 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

state: ルート <wcs-state> を切断→再接続すると $on と command-token の購読が失われる

1 participant