Hone logo
Hone
Problems

Angular Time-Travel Debugging Component

Imagine you're developing a complex Angular application and encounter a tricky bug that only appears intermittently. Traditional debugging methods can be time-consuming, requiring you to replay user actions and meticulously step through code. This challenge asks you to build a component that allows developers to "time-travel" through the state of an Angular component, enabling them to inspect its properties and inputs at different points in time, significantly simplifying debugging.

Problem Description

You need to create an TimeTravelDebuggerComponent that records and allows playback of a component's state changes. The component should:

  1. Record State: The component should accept a target component as input. It should periodically (e.g., every 500ms) capture the target component's inputs and properties (excluding methods and functions) and store them in a history array.
  2. Playback Controls: Provide controls (buttons or a slider) to navigate through the recorded history. "Previous" and "Next" buttons should move the debugger forward and backward through the state history.
  3. State Display: Display the captured state of the target component in a readable format. This could be a simple table or a more sophisticated display based on the component's properties.
  4. State Application: When a specific state is selected from the history, the component should apply that state to the target component, effectively "time-traveling" to that point.
  5. Stop Recording: Provide a mechanism to stop recording the state changes.

Key Requirements:

  • The solution must be implemented in TypeScript within an Angular component.
  • The target component should be passed as an @Input().
  • The recorded state should be stored as an array of objects, where each object represents a snapshot of the target component's inputs and properties.
  • The component should not interfere with the target component's normal functionality when not in debugging mode.
  • The component should handle cases where the target component has no inputs or properties gracefully.

Expected Behavior:

  • When the TimeTravelDebuggerComponent is initialized, it should start recording the target component's state.
  • Clicking "Previous" should revert the target component to the previous recorded state.
  • Clicking "Next" should advance the target component to the next recorded state.
  • The state display should accurately reflect the current state of the target component.
  • Clicking "Stop Recording" should halt the state recording process.

Edge Cases to Consider:

  • Target component changes rapidly – ensure the history doesn't grow excessively. Consider limiting the history size.
  • Target component has circular dependencies – handle these gracefully to avoid infinite loops.
  • Target component's properties are complex objects – ensure they are displayed correctly.
  • Target component is destroyed – properly clean up any resources.

Examples

Example 1:

Input: Target component with input 'name' (string) and property 'count' (number). Initial values: name = "Alice", count = 0.
Output:  The TimeTravelDebuggerComponent displays a history of states.  Clicking "Next" after a few state changes (e.g., name = "Bob", count = 1) should update the target component to name = "Bob", count = 1.
Explanation: The debugger successfully captures and applies state changes to the target component.

Example 2:

Input: Target component with no inputs or properties.
Output: The TimeTravelDebuggerComponent displays a message indicating that the target component has no state to record. The "Previous" and "Next" buttons are disabled.
Explanation: The debugger handles the edge case of a component with no state gracefully.

Example 3:

Input: Target component with a complex object property (e.g., an array of objects).
Output: The TimeTravelDebuggerComponent displays the complex object property in a readable format (e.g., using JSON.stringify or a custom formatter).
Explanation: The debugger can handle complex data structures within the target component.

Constraints

  • History Size: The maximum history size should be limited to 100 states to prevent excessive memory usage.
  • Recording Interval: The state recording interval should be configurable (default: 500ms).
  • Performance: The debugger should not significantly impact the performance of the target component or the overall application. Avoid unnecessary DOM manipulations.
  • Angular Version: The solution should be compatible with Angular 14 or later.

Notes

  • Consider using ChangeDetectorRef to manually trigger change detection when applying a state.
  • You can use JSON.stringify for a simple state display, but a more sophisticated display might be beneficial for complex objects.
  • Think about how to handle properties that are not serializable (e.g., functions). You might choose to exclude them from the recorded state.
  • Focus on the core functionality of recording, playback, and state application. Styling and advanced features are not required for this challenge.
  • Error handling and input validation are important but can be kept relatively simple for this exercise.
Loading editor...
typescript