Skip to content

fix(bindx): notify global subscribers on nested child field edit (#51)#52

Merged
matej21 merged 1 commit into
mainfrom
fix/global-subscriber-skipped-on-child-field-edit
Jun 24, 2026
Merged

fix(bindx): notify global subscribers on nested child field edit (#51)#52
matej21 merged 1 commit into
mainfrom
fix/global-subscriber-skipped-on-child-field-edit

Conversation

@matej21

@matej21 matej21 commented Jun 24, 2026

Copy link
Copy Markdown
Member

Fixes #51.

Problem

A scalar field edit on a child entity (registered via registerParentChild — i.e. nested in a hasMany/hasOne) notified the entity-scoped subscribers but never the global subscribers. usePersist().isDirty subscribes through store.subscribe() (global), so a Save button gated on isDirty stayed disabled after editing a nested field — even though getAllDirtyEntities() reported the change correctly. A top-level (parentless) entity edit was unaffected.

Root cause

SubscriptionManager.notifyEntitySubscribers gated the global notification on notifiedKeys.size === 1, but that guard ran after the parent-propagation loop had already grown the shared notifiedKeys set. For any leaf with a parent, size >= 2 by the time the guard ran → globals skipped. A parentless entity has no recursion, so size === 1 held — which is why only nested entities were affected.

Fix

Capture isRoot = notifiedKeys.size === 0 before adding the key / recursing, and gate the global notification on isRoot.

Test

Ports the regression test from the issue to tests/unit/store/global-subscriber-child-field-edit.test.ts:

  • child-entity field edit now notifies global subscribers exactly once;
  • the existing top-level case stays green (control).

Full tests/unit/store/ suite + subscriptionRekey pass (143 tests). The pre-existing bindx-form FormHasManyRelationScope failure and the example/App.tsx typecheck error are unrelated and present on main.

🤖 Generated with Claude Code

A scalar field edit on a child entity (one registered as a child via
registerParentChild — i.e. nested in a hasMany/hasOne) notified the
entity-scoped subscribers but never the global subscribers. As a result
usePersist().isDirty, which subscribes via store.subscribe() (global),
stayed stale and a Save button gated on isDirty remained disabled after
editing a nested field, even though getAllDirtyEntities() reported the
change correctly.

Root cause: notifyEntitySubscribers gated the global notification on
notifiedKeys.size === 1, but that guard ran AFTER the parent-propagation
loop had already grown the shared notifiedKeys set. For any leaf with a
parent the size was >= 2 by then, so globals were never notified; a
parentless entity had no recursion, so size === 1 held — which is why
only nested entities were affected.

Fix: capture isRoot (notifiedKeys.size === 0) before adding/recursing and
gate the global notification on isRoot.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PbKRVbhqE2N3uTi9mbaWb6
@matej21 matej21 merged commit e7eaee1 into main Jun 24, 2026
3 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.

Global subscribers skipped on field edit of a child entity (usePersist isDirty stuck)

1 participant