Skip to content

refactor: scope stack entry IDs to router instances and add reset helper for global debug counters #53

Description

@RandalSchwartz

[authored by Randal, assisted by Gemini]

Problem

Currently, kaisel uses global static counters for page entry IDs and debug transition ordering:

  1. KaiselStackEntry._nextId is a global static counter used to assign unique IDs to entries on the navigation stack:
    https://github.com/Mastersam07/kaisel/blob/dev/packages/kaisel_core/lib/src/kaisel_router.dart#L132
  2. _originSeq is a global static variable used to order transitions across routers and shell branches for DevTools:
    https://github.com/Mastersam07/kaisel/blob/dev/packages/kaisel_core/lib/src/kaisel_router.dart#L10

Global mutable state is problematic because:

  • It can cause flaky/non-hermetic unit tests if tests leak state or run in parallel.
  • It prevents concurrent isolation if multiple router instances or isolated tests are executed in the same process.

Proposed Solution

1. Scope KaiselStackEntry IDs to KaiselRouter

Because page keys only need to be unique within a single router's page stack, we can make the counter an instance property of the router:

  • Update KaiselStackEntry to take id in its constructor:
    class KaiselStackEntry<R extends KaiselRoute> {
      KaiselStackEntry(this.route, this.id);
      final R route;
      final int id;
    }
  • Maintain an instance-level counter in KaiselRouter (int _nextEntryId = 0;) and pass it during entry creation (e.g. _nextEntryId++).

2. Add a Reset Helper for _originSeq

Since _originSeq must remain global to synchronize events across different router instances for DevTools, we can expose a reset helper in the private framework.dart exports so tests can reset it in setUp:

/// Resets the global debug sequence counters. Used to keep tests hermetic.
@visibleForTesting
void debugResetKaiselCounters() {
  assert(() {
    _originSeq = 0;
    return true;
  }());
}

Metadata

Metadata

Assignees

Labels

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions