Giter Site home page Giter Site logo

lovecommunity / love.dart Goto Github PK

View Code? Open in Web Editor NEW
5.0 3.0 1.0 304 KB

A state management library that is declarative, predictable and elegant.

Home Page: https://pub.dev/packages/love

License: MIT License

Dart 100.00%
state-management functional dart declarative predictable flutter

love.dart's Issues

refactor - rename parameter `skipFirst*` to `skipInitial*`

We are trying to improve code readbility by rename parameter skipFirst* to skipInitail*:

before:

    .reactState(
      skipFirstState: true,
      effect: (state, dispatch) { ... },
    )

after:

    .reactState(
      skipInitialState: true,
      effect: (state, dispatch) { ... },
    )

Related Operators:

  • system.react
  • system.reactLatest
  • system.reactState

refactor - rename `areEqual` to `equals` to be consistent with dart

Dart language prefers equals to describe equality:
https://pub.dev/documentation/collection/latest/collection/Equality/equals.html

We are planing to make these changes for consistency:

- typedef AreEqual<T> = bool Function(T it1, T it2);
+ typedef Equals<T> = bool Function(T it1, T it2);
System<State, Event> reactState({
- AreEqual<State>? areEqual,
+ Equals<State>? equals, 
  bool skipInitialState = true,
  required void Function(State state, Dispatch<Event> dispatch) effect,
}) { ... }

break - refactor - rename extension names to have a `x` suffix

As x stands for Extension, for example Rx is short for ReactiveExtension.

We suggest to naming extension with a x suffix:

- extension LogOperators<State, Event> on System<State, Event> { ... }
+ extension LogX<State, Event> on System<State, Event> { ... }

- extension ReactOperators<State, Event> on System<State, Event> { ... }
+ extension ReactX<State, Event> on System<State, Event> { ... }
...
- export 'src/systems/log_on_system.dart';
+ export 'src/systems/log_x.dart';

- export 'src/systems/react_on_system.dart';
+ export 'src/systems/react_x.dart';
...

It's easy to read and write.

feature - add `system.log` operator for debug

issued from discussion #76.

Before

We have explained how to add log effect from docs:

  system
    .add(effect: (state, oldState, event, dispatch) {
      print('\nEvent: $event');
      print('State: $state');
      print('OldState: $oldState');
    })

output:

Event: null
State: 0
OldState: null

Event: Instance of 'CounterEventIncrease'
State: 1
OldState: 0

After:

We are proposal to add built in log operator:

  system
-    .add(effect: (state, oldState, event, dispatch) {
-      print('\nEvent: $event');
-      print('State: $state');
-      print('OldState: $oldState');
-    })
+   .log()

Output:

System<int, CounterEvent> Run
System<int, CounterEvent> Update {
  event: null
  oldState: null
  state: 0
}
System<int, CounterEvent> Update {
  event: Instance of 'CounterEventIncrease'
  oldState: 0
  state: 1
}
System<int, CounterEvent> Stop

It not only log when system update state, but also log when systen run and dispose which maybe useful for debugging.

This log operator will provide configuration for customization like this:

  system
    .log(
      onRun: (initialState) {
        customLogger.log('CounterSystem run');
      },
      onUpdate: (state, oldState, event) {
        customLogger.log('CounterSystem update state: $state');
      },
      onDispose: () {
        customLogger.log('CounterSystem dispose');
      },
    )

This will override default log behavior with our custom implementation.

We are trying to design this operator with a simple and flexible API.

feature - add `system.eventInterceptor` operator to intercept event

This issue is an extension to #84 (add event filter operators).
We are proposal to add low level system.eventInterceptor operaror, this operator can be used to support system.ignoreEvent and system.debounceOn operators as metioned in #84,

Here is initial imaging of low level system.eventInterceptor. The key point for this operator is, we are associating a Context with it:

  system
    .eventInterceptor<SomeContext>(
      createContext: () => ...// create context here,
      updateContext: (context, state, oldState, event, dispatch) {
          // update context here if needed.
      },
      interceptor: (context, dispatch, event) {
         // inercept event base on the context,
         // call `dispatch(event);` if we pass the event,
         // don't call `dispatch(event);` if we ignore the event.
      },
      dispose: (context) {
         // dispose the context if needed.
      }
    );
  }

With this low level operator, we can implement high level operator system.ignoreEvent like this:

class _IgnoreEventContext<State> {
  late State state;
}

extension FilterEventOperators<State, Event> on System<State, Event> {

  ...

  System<State, Event> ignoreEvent({
    required bool Function(State state, Event event) when
  }) {
    final test = when;
    return eventInterceptor<_IgnoreEventContext<State>>( //  <-- call `this.eventInterceptor`
      createContext: () => _IgnoreEventContext(),
      updateContext: (context, state, oldState, event, dispatch) {
        context.state = state; // cache current state in context
      },
      interceptor: (context, dispatch, event) {
        final _shouldIgnoreEvent = test(context.state, event);
        if (_shouldIgnoreEvent) return;
        dispatch(event);
      },
    );
  }
}

Usage of system.ignoreEvent:

  futureSystem
    ...
    .ignoreEvent(
      when: (state, event) => event is TriggerLoadData && state.loading
    ) 
    ...

Above code shown if the system is already in loading status, then upcoming TriggerLoadData event will be ignored.

We can treat system.ignoreEvent as a special case of system.eventInterceptor,
As an analogy, if we say system.ignoreEvent is a sqare, then system.eventInterceptor is a rectangle.

feature - add event filter operators like `system.ignoreEvent`, `system.debounceOn`

We are proposal to add event filter operators. these operators can prevent unnecessary event dispatching. Here is initial imaging of these operators, it may change before we implementing them, but we issued the demand first:

  • system.ignoreEvent - ignore candidate event when it met some condition
  • system.debounceOn - apply debounce logic to some events

system.ignoreEvent

Ignore candidate event when it met some condition.

Usage:

  futureSystem
    ...
    .ignoreEvent(
      when: (state, event) => event is TriggerLoadData && state.loading // ignore trigger if already loading
    ) 
    ...

Above code shown if the system is already in loading status, then upcoming TriggerLoadData event will be ignored.
This operator will intercept event if some condition is met based on current state and the candidate event.

system.debounceOn

Apply debounce logic to some events

Usage:

  searchSystem
    ...
    .on<UpdateKeyword>(
      reduce: (state, event) => state.copyWith(keyword: event.keyword)
    )
    .debounceOn<UpdateKeyword>(duration: const Duration(seconds: 1))
    ...

Above code shown if UpdateKeyword event is dispatched with high frequency (quick typing), system will intercept these events to reduce unnecessary dispatching, it will pass (not inercept) event if 1 seconds has passed without dispatch another UpdateKeyword event.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.