Skip to content

fix: resolve state management issues and memory leaks#152

Open
hobostay wants to merge 1 commit intopascalorg:mainfrom
hobostay:fix/state-management-issues
Open

fix: resolve state management issues and memory leaks#152
hobostay wants to merge 1 commit intopascalorg:mainfrom
hobostay:fix/state-management-issues

Conversation

@hobostay
Copy link

Summary

This PR fixes several issues in the core state management that could cause bugs and memory leaks:

1. Fix deleteNodesAction recursive call issue

Problem: In packages/core/src/store/actions/node-actions.ts, the deleteNodesAction recursively called get().deleteNodes() inside the set() callback. This could cause state inconsistencies because the recursive call would try to modify state that's already being modified.

Fix: Now collects all descendant IDs first in a separate pass using a helper function collectDescendants(), then deletes them all in a single batch operation.

2. Fix memory leak in use-scene temporal tracking

Problem: In packages/core/src/store/use-scene.ts, the module-level variables prevPastLength, prevFutureLength, and prevNodesSnapshot persisted across store re-creations and scene unloads. This could cause memory leaks by holding references to deleted nodes.

Fix:

  • These variables are now cleared in unloadScene() to release stale node references
  • Added a new clearTemporalTracking() helper function for clarity
  • clearSceneHistory() now calls this helper

3. Remove unused variable in wall-system

Problem: In packages/core/src/systems/wall/wall-system.tsx, the variable useFrameNb was declared and incremented but never used. This appeared to be debug code that was left in.

Fix: Removed the unused variable declaration and increment.

4. Fix requestAnimationFrame in updateNodesAction

Problem: In packages/core/src/store/actions/node-actions.ts, updateNodesAction used requestAnimationFrame without any cleanup mechanism. If updates happened rapidly, multiple RAF callbacks could be queued, causing unnecessary re-renders and potential performance issues.

Fix:

  • Added module-level tracking for pending RAF (pendingRafId) and pending updates (pendingUpdates)
  • Previous RAF is now cancelled before scheduling a new one
  • All pending updates are batched into a single RAF callback

Test plan

  • Code compiles without errors
  • No TypeScript errors introduced
  • Manual testing: Scene unload/reload works correctly
  • Manual testing: Node deletion with children works correctly
  • Manual testing: Rapid node updates don't cause performance issues

Checklist

  • Tests pass locally
  • Documentation updated (n/a - no docs need updating)
  • PR description clearly explains the changes

🤖 Generated with Claude Code

This commit fixes several issues in the core state management:

1. Fix deleteNodesAction recursive call issue
   - Previously, the function recursively called get().deleteNodes()
     inside the set() callback, which could cause state inconsistencies.
   - Now collects all descendant IDs first in a separate pass, then
     deletes them all in a single batch operation.

2. Fix memory leak in use-scene temporal tracking
   - Module-level variables (prevPastLength, prevFutureLength,
     prevNodesSnapshot) persisted across store re-creations.
   - Now cleared in unloadScene() to release stale node references.
   - Added clearTemporalTracking() helper function.

3. Remove unused variable in wall-system
   - Removed debug variable 'useFrameNb' that was declared but never used.

4. Fix requestAnimationFrame in updateNodesAction
   - Previously used RAF without cleanup, causing multiple queued
     callbacks when updates happened rapidly.
   - Now uses a single tracked RAF with cancellation support.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
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.

1 participant