Skip to content

feat: Add signals_nocterm package for Nocterm TUI framework integration#443

Draft
Norbert515 wants to merge 2 commits intorodydavis:mainfrom
Norbert515:feat/signals-nocterm
Draft

feat: Add signals_nocterm package for Nocterm TUI framework integration#443
Norbert515 wants to merge 2 commits intorodydavis:mainfrom
Norbert515:feat/signals-nocterm

Conversation

@Norbert515
Copy link

Summary

This PR adds a new signals_nocterm package that integrates the signals reactive state management library with the Nocterm terminal UI framework.

Closes #442

Features

  • SignalsMixin: Mixin for State classes to automatically manage signal lifecycle (create signals, computed values, and effects that are automatically disposed)
  • Watch: Component for fine-grained rebuilds when signals change
  • WatchBuilder: Builder pattern for watching a single signal
  • watchSignal: Extension and function to watch signals in any build method

Implementation Details

The implementation follows the same patterns as signals_flutter to provide a familiar API for users of both libraries. Key adaptations for Nocterm:

  • Uses Nocterm's SchedulerBinding instead of Flutter's for frame scheduling
  • Uses Nocterm's Element and BuildContext instead of Flutter's
  • Integrates with Nocterm's component lifecycle (State<T>, StatefulComponent, etc.)

Example Usage

class Counter extends StatefulComponent {
  const Counter({super.key});

  @override
  State<Counter> createState() => _CounterState();
}

class _CounterState extends State<Counter> with SignalsMixin {
  late final _count = createSignal(0);
  late final _doubled = createComputed(() => _count() * 2);

  @override
  void initState() {
    super.initState();
    createEffect(() {
      print('Count: ${_count()}, Doubled: ${_doubled()}');
    });
  }

  @override
  Component build(BuildContext context) {
    return Focusable(
      focused: true,
      onKeyEvent: (event) {
        if (event.logicalKey == LogicalKey.space) {
          _count.value++;
          return true;
        }
        return false;
      },
      child: Center(
        child: Text('Count: ${_count()}, Doubled: ${_doubled()}'),
      ),
    );
  }
}

Test plan

  • Run tests with dart test in the signals_nocterm package
  • Verify example works with a Nocterm application
  • Check that signals are properly disposed when components unmount

Notes

This is a draft PR - happy to iterate on the API based on feedback from @rodydavis and the community.

This adds a new package that integrates the signals reactive state management
library with the Nocterm terminal UI framework.

Features:
- SignalsMixin: Mixin for State classes to automatically manage signal lifecycle
- Watch: Component for fine-grained rebuilds when signals change
- WatchBuilder: Builder pattern for watching a single signal
- watchSignal: Extension and function to watch signals in build methods

The implementation follows the same patterns as signals_flutter to provide
a familiar API for users of both libraries.

Closes rodydavis#442
Critical fixes:
- Reimplement Watch/WatchBuilder to match signals_flutter API exactly
- Watch now delegates to WatchBuilder using SignalsMixin with createComputed
- WatchBuilder signature matches Flutter: builder(context, child)
- Add Watch.builder named constructor for drop-in replacement
- Add debugLabel and dependencies parameters to Watch/WatchBuilder
- Add reassemble() method for hot reload support
- Add didChangeDependencies() support for inherited widget changes

High priority fixes:
- ElementWatcher.dispose() now snapshots maps before iterating to
  prevent ConcurrentModificationError when cleanup callbacks trigger
  signal updates

Test improvements:
- Add tests for Watch.builder constructor
- Add tests for dependencies parameter
- Add tests for nested Watch components
- Add tests for watch/unwatch/watch cycles
- Add tests for rapid signal updates
- Add tests for multiple signals
- Add tests for effects
- Add tests for component disposal
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.

Nocterm

1 participant