• Stars
    star
    274
  • Rank 145,557 (Top 3 %)
  • Language
    Kotlin
  • License
    MIT License
  • Created almost 3 years ago
  • Updated 2 months ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

FlowExt | Kotlinx Coroutines Flow Extensions | Kotlinx Coroutines Flow Extensions. Extensions to the Kotlin Flow library | kotlin-flow-extensions | Coroutines Flow Extensions | Kotlin Flow extensions | kotlin flow extensions | Flow extensions

FlowExt

Maven Central codecov Build Validate Gradle Wrapper License: MIT Kotlin version KotlinX Coroutines version badge badge badge badge badge badge badge badge badge Hits

  • FlowExt is a Kotlin Multiplatform library, that provides many operators and extensions to Kotlin Coroutines Flow.
  • FlowExt provides a collection of operators, Flows and utilities for Flow, that are not provided by Kotlinx Coroutine themselves, but are common in other Reactive Frameworks (rxjs, RxJava, RxSwift, rxdart, ...) and standards.

Kotlinx Coroutines Flow Extensions. Extensions to the Kotlin Flow library. Kotlin Flow extensions. Multiplatform Kotlinx Coroutines Flow Extensions. Multiplatform Extensions to the Kotlin Flow library. Multiplatform Kotlin Flow extensions. RxJS Kotlin Coroutines Flow. RxSwift Kotlin Coroutines Flow. RxJava Kotlin Coroutines Flow. RxJS Kotlin Flow. RxSwift Kotlin Flow. RxJava Kotlin Flow. RxJS Coroutines Flow. RxSwift Coroutines Flow. RxJava Coroutines Flow.

Author: Petrus Nguyễn Thái Học

Liked some of my work? Buy me a coffee (or more likely a beer)

Buy Me A Coffee

Supported targets

  • android.
  • jvm.
  • js (IR).
  • iosArm64, iosArm32, iosX64, iosSimulatorArm64.
  • watchosArm32, watchosArm64, watchosX64, watchosX86, watchosSimulatorArm64, watchosDeviceArm64.
  • tvosX64, tvosSimulatorArm64, tvosArm64.
  • macosX64, macosArm64.
  • mingwX64
  • linuxX64, linuxArm64.
  • androidNativeArm32, androidNativeArm64, androidNativeX86, androidNativeX64.

API

Note: This is still a relatively early version of FlowExt, with much more to be desired. I gladly accept PRs, ideas, opinions, or improvements. Thank you! :)

0.x release docs: https://hoc081098.github.io/FlowExt/docs/0.x

Snapshot docs: https://hoc081098.github.io/FlowExt/docs/latest

Installation

allprojects {
  repositories {
    ...
    mavenCentral()
  }
}

Multiplatform

implementation("io.github.hoc081098:FlowExt:0.7.1")

Snapshot

Snapshots of the development version are available in Sonatype's snapshots repository.

  • Kotlin
allprojects {
  repositories {
    ...
    maven(url = "https://s01.oss.sonatype.org/content/repositories/snapshots/")
  }
}

dependencies {
  implementation("io.github.hoc081098:FlowExt:0.7.2-SNAPSHOT")
}
  • Groovy
allprojects {
  repositories {
    ...
    maven { url "https://s01.oss.sonatype.org/content/repositories/snapshots/" }
  }
}

dependencies {
  implementation("io.github.hoc081098:FlowExt:0.7.2-SNAPSHOT")
}

Table of contents

bufferCount

Buffers the source Flow values until the size hits the maximum bufferSize given.

range(start = 0, count = 10)
  .bufferCount(bufferSize = 3)
  .collect { println("bufferCount: $it") }

println("---")

range(start = 0, count = 10)
  .bufferCount(bufferSize = 3, startBufferEvery = 2)
  .collect { println("bufferCount: $it") }

Output:

bufferCount: [0, 1, 2]
bufferCount: [3, 4, 5]
bufferCount: [6, 7, 8]
bufferCount: [9]
---
bufferCount: [0, 1, 2]
bufferCount: [2, 3, 4]
bufferCount: [4, 5, 6]
bufferCount: [6, 7, 8]
bufferCount: [8, 9]

concat

Creates an output Flow which sequentially emits all values from the first given Flow and then moves on to the next.

concat(
  flow1 = flowOf(1, 2, 3),
  flow2 = flowOf(4, 5, 6)
).collect { println("concat: $it") }

Output:

concat: 1
concat: 2
concat: 3
concat: 4
concat: 5
concat: 6

defer

Creates a Flow that, on collection, calls a Flow factory to make a Flow for each new FlowCollector. In some circumstances, waiting until the last minute (that is, until collection time) to generate the Flow can ensure that collectors receive the freshest data.

var count = 0L
val flow = defer {
  delay(count)
  flowOf(count++)
}

flow.collect { println("defer: $it") }
println("---")
flow.collect { println("defer: $it") }
println("---")
flow.collect { println("defer: $it") }

Output:

defer: 0
---
defer: 1
---
defer: 2

flowFromSuspend

Creates a cold flow that produces a single value from the given function.

var count = 0L
val flow = flowFromSuspend {
  delay(count)
  count++
}

flow.collect { println("flowFromSuspend: $it") }
println("---")
flow.collect { println("flowFromSuspend: $it") }
println("---")
flow.collect { println("flowFromSuspend: $it") }

Output:

flowFromSuspend: 0
---
flowFromSuspend: 1
---
flowFromSuspend: 2

interval

Returns a Flow that emits a 0L after the initialDelay and ever-increasing numbers after each period of time thereafter.

interval(initialDelay = 100.milliseconds, period = 1.seconds)
  .take(5)
  .collect { println("interval: $it") }

Output:

interval: 0
interval: 1
interval: 2
interval: 3
interval: 4

neverFlow

Returns a NeverFlow that never emits any values to the FlowCollector and never completes.

neverFlow()
  .startWith(7)
  .collect { println("neverFlow: $it") }

println("Completed!")

Output:

neverFlow: 7
// Never prints "Completed!"

race / amb

Mirrors the one Flow in an Iterable of several Flows that first either emits a value or sends a termination event (error or complete event).

When you pass a number of source Flows to race, it will pass through the emissions and events of exactly one of these Flows: the first one that sends an event to race, either by emitting a value or sending an error or complete event. race will cancel the emissions and events of all of the other source Flows.

race(
  flow {
    delay(100)
    emit(1)
    emit(2)
    emit(3)
  },
  flow {
    delay(200)
    emit(2)
    emit(3)
    emit(4)
  }
).collect { println("race: $it") }

Output:

race: 1
race: 2
race: 3

range

Creates a Flow that emits a sequence of numbers within a specified range.

range(start = 0, count = 5)
  .collect { println("range: $it") }

Output:

range: 1
range: 2
range: 3
range: 4

timer

Creates a Flow that will wait for a given duration, before emitting the value.

timer(value = Unit, duration = 1.seconds)
  .collect { println("timer: $it") }

Output:

// After 1 second
timer: kotlin.Unit

combine


cast / castNotNull / castNullable


cast

Adapt this Flow to be a Flow<R>.

This Flow is wrapped as a Flow<R> which checks at run-time that each value event emitted by this Flow is also an instance of R.

At the collection time, if this Flow has any value that is not an instance of R, a ClassCastException will be thrown.

flowOf<Any?>(1, 2, 3)
  .cast<Int>()
  .collect { v: Int -> println("cast: $v") }

Output:

cast: 1
cast: 2
cast: 3

castNotNull

Adapt this Flow<T?> to be a Flow<T>.

At the collection time, if this Flow has any null value, a NullPointerException will be thrown.

flowOf<Int?>(1, 2, 3)
  .castNotNull()
  .collect { v: Int -> println("castNotNull: $v") }

Output:

castNotNull: 1
castNotNull: 2
castNotNull: 3

concatWith

Returns a Flow that emits the items emitted from the current Flow, then the next, one after the other, without interleaving them.

flowOf(1, 2, 3)
  .concatWith(flowOf(4, 5, 6))
  .collect { println("concatWith: $it") }

Output:

concatWith: 1
concatWith: 2
concatWith: 3
concatWith: 4
concatWith: 5
concatWith: 6

startWith

Returns a Flow that emits a specified item (or many items) before it begins to emit items emitted by the current Flow.

flowOf(1, 2, 3)
  .startWith(0)
  .collect { println("startWith: $i") }

Output:

startWith: 0
startWith: 1
startWith: 2
startWith: 3

flatMapFirst / exhaustMap

Projects each source value to a Flow which is merged in the output Flow only if the previous projected Flow has completed. If value is received while there is some projected Flow sequence being merged, it will simply be ignored.

This method is a shortcut for map(transform).flattenFirst().

range(1, 5)
  .onEach { delay(100) }
  .flatMapFirst { timer(it, 130) }
  .collect { println("flatMapFirst: $it") }

Output:

flatMapFirst: 1
flatMapFirst: 3
flatMapFirst: 5

flattenFirst / exhaustAll

Converts a higher-order Flow into a first-order Flow by dropping inner Flow while the previous inner Flow has not yet completed.

range(1, 5)
  .onEach { delay(100) }
  .map { timer(it, 130) }
  .flattenFirst()
  .collect { println("flattenFirst: $it") }

Output:

flattenFirst: 1
flattenFirst: 3
flattenFirst: 5

groupBy

Groups the items emitted by the current Flow according to a specified criterion, and emits these grouped items as GroupedFlows.

range(1, 10)
  .groupBy { it % 2 }
  .flatMapMerge { groupedFlow ->
    groupedFlow
      .map { groupedFlow.key to it }
  }
  .collect { println("groupBy: $it") }

Output:

groupBy: (1, 1)
groupBy: (0, 2)
groupBy: (1, 3)
groupBy: (0, 4)
groupBy: (1, 5)
groupBy: (0, 6)
groupBy: (1, 7)
groupBy: (0, 8)
groupBy: (1, 9)
groupBy: (0, 10)

ignoreElements

Ignores all elements emitted by the source Flow, only passes calls of complete or error.

flowOf("you", "talking", "to", "me")
  .ignoreElements()
  .materialize()
  .collect { println("ignoreElements: $it") }

Output:

ignoreElements: Event.Complete

flatMapConcatEager

Transforms elements emitted by the original Flow by applying transform, that returns another flow, and then merging and flattening these flows.

This operator calls transform sequentially and then concatenates the resulting flows with a concurrency limit on the number of concurrently collected flows. It is a shortcut for map(transform).flattenConcatEager(concurrency).

range(1, 5)
  .onEach { delay(100) }
  .flatMapConcatEager(concurrency = 2) { v ->
    timer(v, 130)
      .onStart { println("flatMapConcatEager: onStart $v") }
      .onCompletion { println("flatMapConcatEager: onCompletion $v") }
  }
  .collect { println("flatMapConcatEager: $it") }

Output:

flatMapConcatEager: onStart 1
flatMapConcatEager: onStart 2
flatMapConcatEager: 1
flatMapConcatEager: onCompletion 1
flatMapConcatEager: onStart 3
flatMapConcatEager: 2
flatMapConcatEager: onCompletion 2
flatMapConcatEager: onStart 4
flatMapConcatEager: 3
flatMapConcatEager: onCompletion 3
flatMapConcatEager: onStart 5
flatMapConcatEager: 4
flatMapConcatEager: onCompletion 4
flatMapConcatEager: 5
flatMapConcatEager: onCompletion 5

mapIndexed

Returns a flow containing the results of applying the given transform function to each value and its index in the original flow.

range(1, 3)
  .mapIndexed { index, value -> index to value }
  .collect { println("mapIndexed: $it") }

Output:

mapIndexed: (0, 1)
mapIndexed: (1, 2)
mapIndexed: (2, 3)

mapTo

Emits the given constant value on the output Flow every time the source Flow emits a value.

range(1, 3)
  .mapTo("Value")
  .collect { println("mapTo: $it") }

Output:

mapTo: Value
mapTo: Value
mapTo: Value

mapToUnit

Emits kotlin.Unit value on the output Flow every time the source Flow emits a value.

range(1, 3)
  .mapToUnit()
  .collect { println("mapToUnit: $it") }

Output:

mapToUnit: kotlin.Unit
mapToUnit: kotlin.Unit
mapToUnit: kotlin.Unit

materialize

Represents all of the notifications from the source Flow as value emissions marked with their original types within Event objects.

flowOf(1, 2, 3)
  .materialize()
  .collect { println("materialize: $it") }

Output:

materialize: Event.Value(1)
materialize: Event.Value(2)
materialize: Event.Value(3)
materialize: Event.Complete

dematerialize

Converts a Flow of Event objects into the emissions that they represent.

flowOf(Event.Value(1), Event.Value(2), Event.Value(3))
  .dematerialize()
  .collect { println("dematerialize: $it") }

Output:

dematerialize: 1
dematerialize: 2
dematerialize: 3

raceWith / ambWith

Mirrors the current Flow or the other Flows provided of which the first either emits a value or sends a termination event (error or complete event).

flow {
  delay(100)
  emit(1)
  emit(2)
  emit(3)
}.raceWith(
  flow {
    delay(200)
    emit(2)
    emit(3)
    emit(4)
  }
).collect { println("raceWith: $it") }

Output:

raceWith: 1
raceWith: 2
raceWith: 3

pairwise

Groups pairs of consecutive emissions together and emits them as a pair. Emits the (n)th and (n-1)th events as a pair. The first value won't be emitted until the second one arrives.

range(0, 4)
  .pairwise()
  .collect { println("pairwise: $it") }

Output:

pairwise: (0, 1)
pairwise: (1, 2)
pairwise: (2, 3)

repeat

Returns a Flow that will recollect to the source stream when the source stream completes.

flowFromSuspend {
  println("Start collecting...")

  Random
    .nextInt(0..3)
    .also { println("Emit: $it") }
}
  .repeat(
    delay = 1.seconds,
    count = 10
  )
  .filter { it == 2 }
  .take(1)
  .collect { println("repeat: $it") }

Output:

Start collecting...
Emit: 1
Start collecting...
Emit: 3
Start collecting...
Emit: 1
Start collecting...
Emit: 0
Start collecting...
Emit: 1
Start collecting...
Emit: 3
Start collecting...
Emit: 2
repeat: 2

retryWhenWithDelayStrategy

Retries collection of the given flow when an exception occurs in the upstream flow and the predicate returns true. The predicate also receives an attempt number as parameter, starting from zero on the initial call. When predicate returns true, the next retries will be delayed after a duration computed by DelayStrategy.nextDelay.

var count = -1

flowFromSuspend {
  ++count
  println("Call count=$count")

  when (count) {
    0 -> throw MyException(message = "Will retry...", cause = null)
    1 -> "Result: count=$count"
    else -> error("Unexpected: count=$count")
  }
}
  .retryWhenWithDelayStrategy(
    strategy = DelayStrategy.FixedTimeDelayStrategy(duration = 200.milliseconds),
    predicate = { cause, attempt -> cause is MyException && attempt < 1 }
  )
  .collect { println("retryWhenWithDelayStrategy: $it") }

Output:

Call count=0
Call count=1
retryWhenWithDelayStrategy: Result: count=1

retryWhenWithExponentialBackoff

Retries collection of the given flow with exponential backoff delay strategy when an exception occurs in the upstream flow and the predicate returns true. When predicate returns true, the next retries will be delayed after a duration computed by DelayStrategy.ExponentialBackoffDelayStrategy.

var count = -1

flowFromSuspend {
  ++count
  println("Call count=$count")

  when (count) {
    0 -> throw MyException(message = "Will retry...", cause = null)
    1 -> "Result: count=$count"
    else -> error("Unexpected: count=$count")
  }
}
  .retryWhenWithExponentialBackoff(
    initialDelay = 500.milliseconds,
    factor = 2.0,
  ) { cause, attempt -> cause is MyException && attempt < 1 }
  .collect { println("retryWhenWithExponentialBackoff: $it") }

Output:

Call count=0
Call count=1
retryWhenWithExponentialBackoff: Result: count=1

retryWithExponentialBackoff

Retries collection of the given flow with exponential backoff delay strategy when an exception occurs in the upstream flow and the predicate returns true. When predicate returns true, the next retries will be delayed after a duration computed by DelayStrategy.ExponentialBackoffDelayStrategy.

var count = -1

flowFromSuspend {
  ++count
  println("Call count=$count")

  when (count) {
    0 -> throw MyException(message = "Will retry...", cause = null)
    1 -> "Result: count=$count"
    else -> error("Unexpected: count=$count")
  }
}
  .retryWithExponentialBackoff(
    maxAttempt = 2,
    initialDelay = 500.milliseconds,
    factor = 2.0,
  ) { it is MyException }
  .collect { println("retryWithExponentialBackoff: $it") }

Output:

Call count=0
Call count=1
retryWithExponentialBackoff: Result: count=1

select

  • Inspirited by NgRx memoized selector.

  • Selectors are pure functions used for obtaining slices of a Flow of state. FlowExt provides a few helper functions for optimizing this selection.

    • Selectors can compute derived data, to store the minimal possible state.
    • Selectors are efficient. A selector is not recomputed unless one of its arguments changes.
    • When using the [select] functions, it will keep track of the latest arguments in which your selector function was invoked. Because selectors are pure functions, the last result can be returned when the arguments match without re-invoking your selector function. This can provide performance benefits, particularly with selectors that perform expensive computation. This practice is known as memoization.
data class UiState(
  val items: List<String> = emptyList(),
  val term: String? = null,
  val isLoading: Boolean = false,
  val error: Throwable? = null
)

flow {
  println("select: emit 1")
  emit(UiState())

  println("select: emit 2")
  emit(
    UiState(
      items = listOf("a", "b", "c"),
      term = "a",
      isLoading = true,
      error = Throwable("error")
    )
  )

  println("select: emit 3")
  emit(
    UiState(
      items = listOf("a", "b", "c"),
      term = "a",
      isLoading = false,
      error = Throwable("error")
    )
  )

  println("select: emit 4")
  emit(
    UiState(
      items = listOf("a", "b", "c"),
      term = "b",
      isLoading = false,
      error = Throwable("error")
    )
  )
}
  .select(
    selector1 = { it.items },
    selector2 = { it.term },
    projector = { items, term ->
      term?.let { v ->
        items.filter { it.contains(v, ignoreCase = true) }
      }
    }
  )
  .collect { println("select: $it") }

Output:

select: emit 1
select: null
select: emit 2
select: [a]
select: emit 3
select: emit 4
select: [b]

skipUntil / dropUntil

Returns a Flow that skips items emitted by the source Flow until a second Flow emits a value or completes.

flowOf(1, 2, 3)
  .onEach { delay(100) }
  .skipUntil(timer(Unit, 150))
  .collect { println("skipUntil: $it") }

Output:

skipUntil: 2
skipUntil: 3

takeUntil

Emits the values emitted by the source Flow until a notifier Flow emits a value or completes.

range(0, 5)
  .onEach { delay(100) }
  .takeUntil(timer(Unit, 270.milliseconds))
  .collect { println("takeUntil: $it") }

Output:

takeUntil: 0
takeUntil: 1

throttleTime

Returns a Flow that emits a value from the source Flow, then ignores subsequent source values for a duration determined by durationSelector, then repeats this process for the next source value.

(1..10)
  .asFlow()
  .onEach { delay(200) }
  .throttleTime(500)
  .collect { println("throttleTime: $it") }

Output:

throttleTime: 1
throttleTime: 4
throttleTime: 7
throttleTime: 10

withLatestFrom

Merges two Flows into one Flow by combining each value from self with the latest value from the second Flow, if any. Values emitted by self before the second Flow has emitted any values will be omitted.

range(0, 5)
  .onEach { delay(100) }
  .withLatestFrom(
    range(0, 10)
      .onEach { delay(70) }
  )
  .collect { println("withLatestFrom: $it") }

Output:

withLatestFrom: (0, 0)
withLatestFrom: (1, 1)
withLatestFrom: (2, 3)
withLatestFrom: (3, 4)
withLatestFrom: (4, 6)

... and more, please check out Docs 0.x/Docs snapshot.

License

MIT License

Copyright (c) 2021-2022 Petrus Nguyễn Thái Học

More Repositories

1

ComicReaderApp_MVI_Coroutine_RxKotlin_Jetpack

⚡️Comic reader app 📘 Learning MVVM / MVI with 🌀 RxKotlin, Retrofit, Kotlinx Coroutine, Work Manager, Room, Firebase, AndroidX Startup, Clean Architecture, Arrow.Kt Functional Programming ... ❄️ androidx-startup, androidx-room, androidx-viewmodel, arrow-kt
Kotlin
262
star
2

node-auth-flutter-BLoC-pattern-RxDart

❤️ [ACTIVE] 🌰🌰 [BLOC_PATTERN] [RXDART] [STREAM] 🍄🍄 Simple auth app flutter, server node.js, BLoC pattern, RxDart 🍁🍁 Functionalities: LOGIN, REGISTER, CHANGE PASSWORD, CHANGE AVATAR, FORGOT PASSWORD. Pure rxdart BLoC pattern. BLoC pattern without library.
Dart
249
star
3

GithubSearchKMM-Compose-SwiftUI

🍭 GithubSearchKMM - Github Repos Search - Android - iOS - Kotlin Multiplatform Mobile using Jetpack Compose, SwiftUI, FlowRedux, Coroutines Flow, Dagger Hilt, Koin Dependency Injection, shared KMP ViewModel, Clean Architecture
Kotlin
171
star
4

WeatherApp_MVI_sample

🌸[Functional reactive programming (FRP)] 🍁Simple Android weather forecast application written in Kotlin, using RxKotlin, Retrofit2, Mosby, Room Persistence ❄️MVI Pattern with Mosby Library
Kotlin
160
star
5

ViewBindingDelegate

Simple one-liner ViewBinding in Fragments and Activities with Kotlin 🍄 Simplify usage of Android View Binding with Kotlin Property Delegates and solve behavior of Fragment’s ViewLifecycleOwner 🌱 ViewBindingPropertyDelegate
Kotlin
110
star
6

Refresh-Token-Sample

Android Refresh token with Retrofit, OkHttp, Kotlin Coroutines Mutex 🔂 When multiple requests hit 401 (HTTP_UNAUTHORIZED), only single Refresh token request will be executed. After successful refresh, all pending requests will be executed concurrently. Example of encryption Jetpack Proto DataStore with Tink. Secured Proto DataStore. This example app shows how you can encrypt your data when using Proto DataStore from Jetpack.
Kotlin
108
star
7

load_more_flutter_BLoC_pattern_RxDart_and_RxRedux

🔥 [FUNCTIONAL & REACTIVE PROGRAMMING (FRP)] ❄️[Pure RxDart] Paging ListView flutter 🌸 Load more flutter listview 🌱 Endless scrolling flutter 👏 Flutter infinite list - BLoC pattern - rxdart - reactive stream flutter - RxDart.
Dart
94
star
8

Movie-Ticket-Booking

A movie tickets booking and management application using Flutter and NestJS. Flutter BLoC pattern and RxDart, rx_redux, stream_loader for state management. Firebase authentication, socket.io. Backend using NestJS, MongoDB database and Neo4j. Recommendation using Neo4j database and Collaborative filtering via Cypher query. Movie ticket booking flutter
Dart
82
star
9

kmp-viewmodel

🔆 Kotlin Multiplatform ViewModel. Kotlin Multiplatform MVVM. Common/Shared ViewModel in Kotlin Multiplatform - A Kotlin Multiplatform library that provides shared MVVM for UI applications. Components are lifecycle-aware on Android. Supports Android Parcelable, Kotlin Parcelize, AndroidX SavedStateHandle for restoring state after process death.
Kotlin
77
star
10

find_room_flutter_BLoC_pattern_RxDart

👘 [FUNCTIONAL REACTIVE PROGRAMMING].💎 The main purpose of repository is learning. 📘 A FLUTTER app help student find room 🏠 Using BLoC pattern with RxDart library, firebase as backend, .... Star 🌟 if it is helful 💓 . In progress... ⚡
Dart
71
star
11

wallpaper-flutter

🐣🐣 Simple wallpaper use flutter sdk 🍂🍂 Firestore, rxdart, sqlite, http 🍁🍁 Method channel Kotlin + Swift
Dart
59
star
12

search-book-flutter-BLoC-pattern-rxdart

❄️[Functional reactive programming (FRP)] ⚡ Flutter search book using bloc pattern, rxdart 🌺 Star if it is helpful 🌺
Dart
52
star
13

flutter_validation_login_form_BLoC_pattern_RxDart

[Functional reactive programming (FRP)]💧 💧 💧 [Pure RxDart] Validation login form by using the BLoC pattern with RxDart - A new Flutter project featuring a faked authentication interface to demonstrate validation. Implemented with BloC pattern.
Dart
48
star
14

rx_shared_preferences

🌀 Shared preferences with RxDart Stream observation ⚡️ Reactive shared preferences for Flutter 🌸Reactive stream wrapper around SharedPreferences 🍄 Lightweight and easy-to-use 🌱 A reactive key-value store for Flutter projects. Like shared_preferences, but with Streams 📕 Rx Shared Preferences for Flutter 🌿 rx_shared_preferences 🌰 rx_shared_preference 🍷 Reactive SharedPreferences for Flutter 🌰 A stream based wrapper over shared_preferences, allowing reactive key-value storage.
Dart
41
star
15

sqlbrite

🌼 RxDart Reactive stream sqflite(sqlite) for Flutter - Sqlbrite for flutter - A lightweight wrapper around sqflite which introduces reactive stream semantics to SQL operations. https://pub.dev/packages/sqlbrite
Dart
25
star
16

node-auth-flutter

Simple flutter app: login and register | Version using BLoC pattern and RxDart: https://github.com/hoc081098/node-auth-flutter-BLoC-pattern-RxDart.git
Dart
24
star
17

rxdart_ext

Some extension methods and classes built on top of RxDart. Companion with RxDart
Dart
22
star
18

Compose-Multiplatform-KmpViewModel-Unsplash-Sample

Compose Multiplatform and Kotlin Multiplatform ViewModel sample
Kotlin
21
star
19

solivagant

🔆 Compose Multiplatform Navigation library - 🌸 Pragmatic, type safety navigation for Compose Multiplatform. Based on Freeletics Khonshu Navigation. ♥️ ViewModel, SavedStateHandle, Lifecycle, Multi-Backstacks, Transitions, Back-press handling, and more...
Kotlin
20
star
20

kotlin-channel-event-bus

A Kotlin Multiplatform library that provides a simple event bus implementation using KotlinX Coroutines Channels. Multi-keys, multi-producers, single-consumer and thread-safe event bus backed by kotlinx.coroutines.channels.Channels
Kotlin
19
star
21

sqlite_BLoC_pattern_RxDart

🍂 ❤️ CRUD + sqflite + BLoC + RxDart + Clean code + Functional_Reactive_Programming 🌀 ❤️
Dart
18
star
22

rx_redux

🍄 Reactive redux store for Dart & Flutter 🌰 Redux implementation based on Dart Stream, with the power of RxDart
Dart
16
star
23

search-book-MVVM-MVI-RxSwift

🌀 Learning ⚡ Search book MVVM / MVI + RxSwift 🌸Just combine, filter, transform Stream...
Swift
13
star
24

disposebag

⚡ A package to help disposing StreamSubscriptions and closing Sinks. 🌀
Dart
12
star
25

change_theme_language_BLoC_pattern_RxDart

[❄️🌀 FUNCTIONAL REACTIVE PROGRAMMING] [PURE RXDART] Change runtime theme - locale language flutter ⚡ A simple starter app with a drawer and a dynamic theme changer and persistent theme using the sharedpreferences. Change theme and language, using BLoC pattern, RxDart, SharedPreference, ... ⭐️ Flutter dynamic_theme ❤️:
Dart
12
star
26

flutter_bloc_pattern

⚡ Base class, bloc provider and rxdart stream builder for BLoC pattern in flutter: https://pub.dev/packages/flutter_bloc_pattern
Dart
10
star
27

comic_app_server_nodejs

Node.js sever for android comic app | https://comic-app-081098.herokuapp.com/
TypeScript
10
star
28

hoc081098

Hi there 👋, I'm Petrus Nguyễn Thái Học
Dart
9
star
29

learn-graphql

🌀 Learning ⚡ Node.js GraphQL + Flutter + Angular 🌸
TypeScript
9
star
30

PhDownloader

Petrus Hoc's Downloader - Simple, reactive and functional downloader for iOS Swift with the power of RxSwift, RxAlamofire - RxSwift Downloader - RxDownloader
Swift
9
star
31

dart_either

Either monad for Dart language and Flutter framework. The library for error handling and railway oriented programming. Supports `Monad comprehensions` (both `sync` and `async` versions). Supports `async map` and `async flatMap` hiding the boilerplate of working with asynchronous computations `Future<Either<L, R>>`. Error handler library for type-safe and easy work with errors on Dart and Flutter. Either is an alternative to Nullable value and Exceptions.
Dart
9
star
32

node-auth-rest-api

JavaScript
8
star
33

rxdart_flatmap_max_concurrent

Using `rxdart`'s `flatMap` with `maxConcurrent` to limit the number of concurrent requests.
Dart
7
star
34

MovieDb-Search

Dart
6
star
35

bloc-rxdart-rx_redux-playground

⚡ BLoC RxDart playground 🌀
Dart
6
star
36

number-to-Vietnamese-words

Convert number to Vietnamese words - number_to_vietnamese - Convert numbers to Vietnamese words. Supports large number, up to quintillion USAGE:
Kotlin
6
star
37

Compose-Multiplatform-Todo-solivagant-koin-Sample

Compose Multiplatform Navigation and Kotlin Multiplatform ViewModel sample. solivagant and kmp-viewmodel sample
Kotlin
6
star
38

leetcode

leetcode
Kotlin
5
star
39

flutter_provider

:octocat: Flutter generic provider using InheritedWidget. Flutter generic provider using InheritedWidget. An helper to easily exposes a value using InheritedWidget without having to write one.
Dart
5
star
40

Edoctor-MVI-Arrow-RxKotlin-Coroutines-Flow

Edoctor-MVI-Arrow-RxKotlin-Coroutines-Flow. Android Clean Architecture MVI Boilerplate
Kotlin
5
star
41

kotlin_playground

Kotlin playground with various files of examples, and personal experiments.
Kotlin
5
star
42

demo_redux

Simple CRUD flutter app, use redux and firestore
Dart
5
star
43

cancellation_token_hoc081098

Dart Cancellation Token. Inspired by CancellationToken in C#. A Dart utility package for easy async task cancellation.
Dart
5
star
44

timetable-lazylayout-jetpack-compose

Demo how to build a time table using LazyLayout API in AndroidX Jetpack Compose
Kotlin
4
star
45

Astar-Dijkstra-GreedyBestFirstSearch-BreadthFirstSearch-DepthFirstSearch

Kotlin
4
star
46

did_change_dependencies

Return a Stream that emits null and done event when didChangeDependencies is called for the first time.
Dart
4
star
47

hacker_news

Learn flutter udemy course - bloc pattern
Dart
4
star
48

distinct_value_connectable_stream

🌸🌸 Distinct value connectable stream for RxDart, useful for BLoC pattern 🌰🌰
Dart
4
star
49

rxdart_batch_api_demo

Demonstrates how to use the `rxdart_ext` to handle batch API calls in Flutter
C++
3
star
50

CryptocurrencyTracker

Kotlin
3
star
51

stream_loader_demo

🌸 stream_loader example🌼 fall in love with Stream - Functional Reactive Programming 🍂 https://pub.dev/packages/stream_loader 🌺
Dart
3
star
52

codelab-basic-android-kotlin-compose-training-reply-app

Kotlin
3
star
53

DemoModules

DemoModules
Kotlin
3
star
54

Drink-Shop-App

Java
3
star
55

flutter_github_search_rx_redux

🔰 Flutter github search using rx_redux | Functional & reactive programming with rxdart, rx_redux
Dart
3
star
56

stream_loader

🍂 A Flutter plugin for loading content asynchronously with Dart stream and RxDart. RxDart loader bloc. Reactive loader bloc. Simple reactive state management container - https://pub.dev/packages/stream_loader
Dart
3
star
57

stream_animated_list

stream_animated_list = StreamBuilder + AnimatedList
Dart
2
star
58

nestjs-ngrx-tasks-management

learning
TypeScript
2
star
59

DemoCoroutinesChannelResult

Use `Kotlinx Coroutines Channel` to send and receive events between Fragments.
Kotlin
2
star
60

collapsing_toolbar_fab

Collapsing toolbar with fab
Dart
2
star
61

http_client_hoc081098

Dart
2
star
62

udemy-scala-advanced

Scala
2
star
63

comic_app_bloc_pattern_rxdart

🌺🌺 Comic reader app - BLoC pattern - RxDart 🌱🌱 Functional reactive programming ⚡ ⚡ ⚡
Dart
1
star
64

flutter-boilerplate

A boilerplate project created in flutter using RxDart BLoC pattern, Provider, Clean architecture
1
star
65

CryptocurrencyTrackerFlutter

Dart
1
star
66

hoc081098-code

Euler problems, DS & Algo | Kotlin, Ruby, Elixir, Dart, Swift, Java, Typescript, Javascript, ...
C++
1
star
67

PhDownloaderTest

RxAlamofire + RxSwift Downloader
Swift
1
star
68

built_value_built_list_json_sample

Dart
1
star
69

google_photos_gallery_test

google_photos_gallery_test
Dart
1
star
70

stop_watch_flutter_bloc_rxdart

🌰🌰 Stop watch flutter bloc rxdart demo
Dart
1
star
71

nested_navigation

Flutter nested navigation with BottomNavigationBar
Dart
1
star
72

ngdart_bookmark_manager

Dart
1
star