A state container for Java & Kotlin, inspired by Redux & Elm

Related tags

Kotlin bansa
Overview

Bansa

This is my take on Redux, the state container for JavaScript apps. It's oriented toward developers who like building React-style apps and Kotlin!

Why the name Bansa? Because it means "Nation" in Filipino. And nations are "state containers." Get it!? Oh ho ho ho. Continue on for more, dear reader.

Get it!

// First, add JitPack to your repositories
repositories {
	...
	maven { url "https://jitpack.io" }
}

// Base package. Everything else is built upon it!
compile 'com.github.brianegan.bansa:bansa:1.0.0-beta'

// If you'd like a more functional interface in Kotlin, go ahead and use the Kotlin Extensions.
compile 'com.github.brianegan.bansa:bansaKotlin:1.0.0-beta'

// Time Travel Dev Tools! Highly recommended you only use them
// for development, as the store takes up more memory. Note: You can use
// the provided UI, or write your own.
debugCompile 'com.github.brianegan.bansa:bansaDevTools:1.0.0-beta'
debugCompile 'com.github.brianegan.bansa:bansaDevToolsUi:1.0.0-beta'

What's the goal?

"State Container" is pretty vague. So let me explain what I'm trying to accomplish with this little project: An easier way to write Android UIs & Apps. Perhaps an easy way to start would be a concrete analogy.

Think about List and RecyclerViews on Android. At a high level, you just give them some data and tell them how to render that data. When the data updates, you call notifyDataSetChanged to inform the View and it redraws everything for ya. Nice and simple. And heck, with RecyclerView, it'll even perform some pretty impressive animations with just a couple lines of code!

That's what I'm going for with this project: I want a simple way to declare the way my interface should look, and when the data changes, everything should re-render for me!

So where does Bansa fit into that picture, one might ask? It doesn't say anything on the box about making my life easier as a UI developer!?

Bansa doesn't handle the UI magic. That's left to other tools, namely Anvil. Bansa is responsible for holding, or "containing," the state of your application, and informing the UI layer (or database layer, or logging layer, etc) about updates to the state of the application.

The examples in this project simply show one person's vision for how we could think about Android App development, and whether we could make it easier and more fun.

Using it

We'll demonstrate using a simple counter example!

Define what your state should look like

All we need for a simple counter example is the value of one counter. In one delicate line with Kotlin:

data class ApplicationState(val counter: Int = 0)

Define the types of actions of your application

Actions are payloads of information that send data from your application to your state container, which we'll call the store from here on out. They are used to determine what actions your store should respond to. You send them from your application to a store with the store.dispatch(ACTION) method.

So here are the three actions we need for our counter app:

object INIT : Action
object INCREMENT : Action
object DECREMENT : Action

Update the state with Reducers

Actions describe the fact that something happened, but don’t specify how the application’s state changes in response. This is the job of a reducer.

Let's see some code and we'll chat about it afterwards:

val reducer = Reducer<ApplicationState> { state, action ->
    when (action) {
        is INIT -> ApplicationState()
        is INCREMENT -> state.copy(counter = state.counter.plus(1))
        is DECREMENT -> state.copy(counter = state.counter.minus(1))
        else -> state
    }
}

So what's happening here? A reducer is a function that takes two arguments: the current state of the application, and the action that was fired. It returns an updated version of the state.

In this example, when the INIT action is fired, we want to initialize the state of our application. Therefore, we return a new instance.

When the INCREMENT action is fired, we want to simply increase the counter by 1.

If DECREMENT is fired, we'll need to decrease the counter by 1.

And that's all there is to it: We're simply describing how the state should change in response to an action.

Create a new store (this is your state container)

Now that we've gotten everything setup, we can create our state container!

val counterStore = BaseStore(ApplicationState(), reducer);

And that's it! Now you've got a store. Woohoo! So what now?

Dispatch (Fire / Trigger) an action

The following code will dispatch an action that travels first through any middleware (we'll chat about those later), then through the reducers, generally producing a state change.

counterStore.dispatch(INCREMENT)

Get the current state of the store

Say you want to know what the current state of the app is. That's simple:

counterStore.getState() // After the INCREMENT, state is now (counter = 1)

And this is where the magic begins: Subscribe to updates!

counterStore.subscribe({
    textView.setText(store.getState())
})

ZOMG MY TEXT JUST UPDATED DUE TO A STATE CHANGE!!!

Stay with me!

I know what you're saying: "Bri, I've seen all this before. It's called an EVENT BUS." And you know what? You're pretty much right. This isn't anything radical, it's just gluing some pieces together in a different way. But just think about how we can use this pattern to simplify our UIs.

Hooking it up to Anvil

Ok, so now we have to chat about Anvil. It's a simple way to write UIs in Java & Kotlin, and it might be a bit different than what you're used to. With Anvil, you simply describe your UI in Java / Kotlin code (not XML -- give it a few minutes, I think you'll fall in love), update the state, and call Anvil.render(). Then everything just updates! We've done it! We've achieved the goal set out in the opening paragraphs!!!

So here's an example view. It's job is to create a linearLayout with three child views: A text view to display the current count, an plus button, and a minus button.

When someone clicks on the plus button, we want to dispatch an INCREMENT action. When someone clicks the minus button, we want to dispatch a DECREMENT action.

linearLayout {
    size(FILL, WRAP)
    orientation(LinearLayout.VERTICAL)

    textView {
        text("Counts: ${store.state.counter.toString()}") // The counter from our state model!
    }

    button {
        size(FILL, WRAP)
        padding(dip(10))
        text("+")
        onClick(store.dispatch(INCREMENT))
    }

    button {
        size(FILL, WRAP)
        padding(dip(5))
        text("-")
        onClick(store.dispatch(DECREMENT))
    }
}

And now, we hook anvil and Bansa up together:

counterStore.subscribe({
    Anvil.render()
})

That's right: When a user clicks "+", the increment action will be fired, the reducer will update the state, and our UI will auto-render with the new info. WHAAAAAAAAAAT.

Dev Tools

Maybe one of the cooler bonuses about this pattern is that it happens to lend itself well to time-travel style Dev tools! What are time travel dev tools you say? What if, for every action you take in an application, you could replay what happened? Then you could step forward and backward through that series of actions to see the steps along the way. You can totally do that with Bansa!

More documentation needs to be written about implementing the Time Travel Dev tools, but for now, please see the Counter example as a reference implementation! It should be possible to get the Dev Tools up and running with only a small amount of code.

Dev Tools Screenshot

Screenshot of the Dev Tools in action

Examples

There are a progression of examples that can be found in the "Examples" folder. If you're interested in progressing through them, the suggested order is:

  1. Counter
  2. Counter pair
  3. List of counters
  4. List of counters variant
  5. Random gif
  6. List of trending gifs
  7. Todo List

More docs -- public shameful note for Brian

Write sections for:

  • Async Actions
  • Middleware
  • Combining reducers
  • Breaking down apps into smaller parts

Things to think about

  • How views should asynchronously request / remove data from the store upon instantiation and disposal if it's safe.
  • What is the role of the database? Store actions? Store models?
  • Could views describe their data requirements as queries, similar to Falcor or GraphQL?

Technical Goals

If you're thinking of writing your own version of Redux in Java: I'd say, go for it! This libray has benefitted tremendously from the various versions that have been written thus far, and the current version is an attempt to synthesize the best parts of each implementation. When evaluating the various libs, I came up with a bucket list for what this library should accomplish for a 1.0 release:

  • Idiomatic Java and Kotlin usage.
  • Low method count
  • Easy to pick up, even if you come from a less functional background.
  • Support for all basic Redux concepts in the smallest possible package. This includes the Store, Middleware, Reducers, and Subscribers/Subscriptions, and combining Reducers.
  • Dev Tools that allow for Time Travel debugging
  • Interface that allows for sharable middleware & reducers (such as Logging middelware, or Undo/Redo reducer helpers)
  • Well tested

The tech setup

If you like Buzzwords, then boy howdy, have you found yourself the right repo.

Bansa itself has one important dependency, RxJava, and is written in Kotlin.

The examples use:

  • Kotlin (yay! it's so lovely.)
  • Anvil for UI
  • RxJava for Observables
  • OkHttp for, uh, http
  • Moshi for Json parsing
  • Picasso for image loading
  • JUnit for Unit Testing
  • AssertJ to make dem assertions all fluent like

Inspiration

I'd also like to add that this library is a complete , these ideas aren't new in any way. Credit has to be given to the following projects, listed in autobiographical order.

  • React
  • Om
  • ClojureScript
  • Elm
  • Redux
  • CycleJs
  • redux-java - by my coworker and friend, Guillaume Lung
  • re-frame
Comments
  • Remove RxJava as a dependency

    Remove RxJava as a dependency

    After working with this code a bit, I think it makes sense to remove RxJava as a dependency. Why you might ask? Let's break it down.

    RxJava Pros Broken Down

    • Allows for threading! What if we want to run reducers in the background for example? Well, with the great work done by @clemp6r, we moved away from a model where the reducer work could be done on a background thread, and made the entire process synchronous. This is a fairly fundamental part of the way Redux works, and it has some very nice advantages. Therefore, RxJava isn't needed for this type of threading anymore!
    • Solid Subscriber and Observer interfaces in place. Fortunately, it's very easy to create a small interface of our own that's
    • Has some very helpful abstractions for testing. So, let's continue using it for testing!

    Reasons it makes sense to move away

    • In the context of Android, RxJava eats up about 4200 methods. If we really don't need it, I'd prefer to keep this library lean and mean.
    • For folks who don't have experience with RxJava, the requirement might add too much of a learning curve
    • If you still want to work with state changes as an observable, it's completely possible to wrap this smaller core in that type of interface!
    • The code is far simpler and easier to reason about. The main store is now about 20 lines.
    opened by brianegan 8
  • first version for reselect. state selector library ported from https:…

    first version for reselect. state selector library ported from https:…

    Hi. After playing a bit with your library and looking into the original docs for Redux I realized that there was quite an important missing piece. Checking in all subscribers to see if the state change that happened is relevant or not can be much easier with reselect library. see also http://redux.js.org/docs/recipes/ComputingDerivedData.htm) and https://github.com/reactjs/reselect This is not a complete port of reselect, but I hope good enough as for a start. Also I strived to make the API as simple as possible and changed it to be more idiomatic for kotlin. Let me know what you think. Thanks for your work on bansa, by the way!

    opened by beyondeye 8
  • Making Bansa more Java-friendly

    Making Bansa more Java-friendly

    Hi,

    Bansa is not really Java friendly. Being Java friendly is important because Kotlin was created for mixed environments, with the best Java interoperability as possible.

    Some reasons it's not:

    • store.dispatch is not a function from Java point of view. So no store.dispatch(action); but instead s.getDispatch().invoke(action)
    • usage of global functions to apply middlewares or create a store. e.g a factory method should be preferred to create a store, something like Bansa.createStore()
    • a heavy-functional approach for creating middlewares. Having a Middleware interface, very easy to implement from Kotlin and Java would be preferable.

    I created this branch to address some of these problems and to share my point of view.

    I know you're in the middle of an important refactoring (cf. pending PR), so don't merge it now, let's start a discussion here, and I will update the branch accordingly when the code base is more stable.

    opened by clemp6r 7
  • InjektionException: No registered instance or factory for type com.brianegan.bansa.Store

    InjektionException: No registered instance or factory for type com.brianegan.bansa.Store

    Hi,

    I just wanted to try your Bansa counter example (by the way, I have to chuckle every time I misread this as "Bansa counterexample") and it crashed with the following exception:

    java.lang.RuntimeException: Unable to instantiate application com.brianegan.bansa.counter.Application: uy.kohesive.injekt.api.InjektionException: No registered instance or factory for type com.brianegan.bansa.Store<com.brianegan.bansa.counter.ApplicationState, com.brianegan.bansa.Action>
        at android.app.LoadedApk.makeApplication(LoadedApk.java:526)
        at android.app.ActivityThread.handleBindApplication(ActivityThread.java:4390)
        at android.app.ActivityThread.access$1500(ActivityThread.java:139)
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1260)
        at android.os.Handler.dispatchMessage(Handler.java:102)
        at android.os.Looper.loop(Looper.java:136)
        at android.app.ActivityThread.main(ActivityThread.java:5105)
        at java.lang.reflect.Method.invokeNative(Native Method)
        at java.lang.reflect.Method.invoke(Method.java:515)
        at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:792)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:608)
        at dalvik.system.NativeStart.main(Native Method)
    Caused by: uy.kohesive.injekt.api.InjektionException: No registered instance or factory for type com.brianegan.bansa.Store<com.brianegan.bansa.counter.ApplicationState, com.brianegan.bansa.Action>
        at uy.kohesive.injekt.registry.default.DefaultRegistrar.getInstance(DefaultRegistrar.kt:99)
        at uy.kohesive.injekt.api.InjektScope.getInstance(Scope.kt)
        at com.brianegan.bansa.counter.Application.<init>(Application.kt:30)
        at java.lang.Class.newInstanceImpl(Native Method)
        at java.lang.Class.newInstance(Class.java:1208)
        at android.app.Instrumentation.newApplication(Instrumentation.java:990)
        at android.app.Instrumentation.newApplication(Instrumentation.java:975)
        at android.app.LoadedApk.makeApplication(LoadedApk.java:521)
        ... 11 more
    

    I haven't done much Kotlin and haven't used Injekt at all - could you tell me what I am doing wrong?

    opened by DavidMihola 6
  • If I feel like I want to dispatch from my Reducer - what is the correct thing to do instead?

    If I feel like I want to dispatch from my Reducer - what is the correct thing to do instead?

    Hi Brian,

    I keep running into situations where my first impulse would be to dispatch a new Action to my store from within my Reducer. But since I don't even have a reference to the store there and since dispatching from the reducer is very much discouraged in Redux I suppose that's not the way to go in Bansa either. Still I can't figure out what to do instead.

    For example: I try to load a list of images from my API but the request fails because I am not logged in and so the login form is displayed instead. The login request succeeds and LOGIN_SUCCESS is dispatched. Since I have also stored (something like) retryImageListRequest = true in my state I could now dispatch another LOAD_IMAGE_LIST and load the images in the appropriate Middleware. Except that would mean I would dispatch an Action from within my Reducer.

    Unfortunately, I am not only new to Bansa but to similar frameworks as well (I've only done some Elm, and that was only with synchronous computations), so I can't make much sense of articles like this one:

    Now you know that this is frowned on. You know that if you have enough information to dispatch an action after the reducer does its thing, then it is a mathematical certainty that you can do what you want without dispatching another action.

    I would be very grateful for any suggestions!

    opened by DavidMihola 4
  • Kotlin

    Kotlin

    Thank you so much for your work on this. It is really nice library. I am a big fan of Redux.

    1. Can you share why you decide to move implementation away from Kotlin -> Java?
    2. Do you have any support for StoreEnhancer ?
    opened by kittinunf 3
  • Remove empty interfaces State and Action

    Remove empty interfaces State and Action

    Hi again,

    I removed the State and Action interfaces, they're useless until they remains empty. Generics are enough to get type safety. Also, users may not understand why they would have to implement empty interfaces.

    What do you think?

    opened by clemp6r 3
  • Manage global Store in an Android application

    Manage global Store in an Android application

    Hi,

    I am currently learning to implement a small Android app with this library, but I am unsure where you would put the Store. Should there really be an application wide store Singleton and how would I handle orientation changes or the Android system killing the process and saving/restoring the state? Or is it better to put the store inside the ViewModel of the Android Architecture Components?

    Thanks for your input!

    opened by sunilson 2
  • Convert Bansa to Java

    Convert Bansa to Java

    This is a big change to Bansa, and I hope that it fulfills the following goals:

    • Idiomatic to use in both Java and Kotlin
    • Low method count
    • Supports Middleware
    • Supports Combining Reducers
    • Well Tested
    • (Coming Soon) Supports Dev tools

    It is heavily inspired by Redux-Java and Jedux, and I liberally borrowed ideas / code. This is not all my doing, it's my attempt at synthesizing the best parts of each Java Redux implementation. Jedux, with it's small footprint and nice implementation of middleware. Bansa, which has idiomatic Kotlin support and is well tested. Redux-Java which started it all, comes with nice, semantically meaningful interfaces (e.g. Subscriber and Subscription), and a set of Dev tools.

    /cc @clemp6r @tilal6991 @zserge

    opened by brianegan 2
  • Rename state props

    Rename state props

    I modified the Store interface a little so it is more conventional with usual Kotlin design.

    The getState() method is not appropriate because it is a getter, and in Kotlin we use properties instead.

    A property is a combination of a implicit getter and a backing field, so explicit getters like getState() are not required anymore. Also, there was a property named state so the Kotlin compiler would generate a getState() function for this property that clashes with the other getState() method you created. As a consequence, Java users would not be able to use your getState() because they generated getState() replaces it.

    To summarize:

    fun getState()  →  val state
    val state       →  val stateChanges
    
    opened by clemp6r 2
  • Subscribe to substate?

    Subscribe to substate?

    I'm working on fairly complexe application, and I'm splitting my AppState into multiple substate, so I have multiple reducers and states. It works fine, but is there a way to subscribe to change only happening to a specific part of my state?

    To get you an idea here is my AppState

    class AppState {
        var userState = UserState()
    }
    

    and my UserState

    class UserState {
        var currentUser: String? = null
        var users = mutableMapOf<String, User>()
    }
    

    and my AppReducer

    class AppReducer: Reducer<AppState> {
        val userReducer = UserReducer()
    
        override fun reduce(state: AppState, action: Action?): AppState {
            userReducer.reduce(state.userState, action)
            return state
        }
    }
    

    So when I subscribe, I would want to do something like this:

    store.subscribe { state.userState ->
      Log.d("State change", state.userState.currentUser)
    }
    

    is that something possible or planned?

    Thanks!

    opened by Dimillian 1
  • Is it safe to call dispatch from multiple threads?

    Is it safe to call dispatch from multiple threads?

    Hello, thank you for introducing Redux to Android world.

    I'm using bansa with Anvil and I think they are a very good match. But I noticed one thing, if we call BaseStore.dispatch() from multiple thread, it's possible to get inconsistent state within one dispatch cycle, since we can't pass the new state to Anvil.render(). We could only use BaseStore.getState() in each view.

    I noticed that you use locks in this line and getState(). But they both lock on different objects. synchronized(this) locks on Middleware instance while public synchronized S getState() locks on BaseStore instance.

    But I think although we use locks, there is still a chance for inconsistent state since dispatch and getState will not be called in one block.

    Do you think we should only call dispatch in one thread? Maybe using a single background thread to do it?

    I'll be grateful to hear your thoughts about this. Thank you very much.

    opened by alukito 6
Releases(1.0.0-beta)
  • 1.0.0-beta(May 5, 2016)

    The early versions of this project were fun experiments in Kotlin. As I played around with it more and talked to others, I hoped I might make this project useful to others, rather an as a simple experiment.

    Therefore, I set down the following criteria for what I wanted from the library:

    • Idiomatic Java and Kotlin usage
    • Low method count
    • Support for all basic Redux concepts in the smallest possible package. This includes the Store, Middleware, Reducers, and Subscribers/Subscriptions.
    • Dev Tools that allow for Time Travel debugging
    • Well tested

    As this library now meets those goals, I think it's time to give it a beta label. Please try it out in your projects, and if we find it's all stable, we'll publish to 1.0.0 soon!

    devtools

    Source code(tar.gz)
    Source code(zip)
  • 0.3.0(Apr 25, 2016)

    This is a big change! Bansa is now written in Java, and no longer has a dependency on Rx. This drops the method count dramatically, and makes Bansa far easier to use in a normal Java Android app.

    There is also a companion version available, called bansaKotlin, that provides more idiomatic interfaces for the Kotlin programming language.

    I've also tried to keep the migration path simple. If you've been using Bansa, it shouldn't be a big rewrite of the way you were doing things before. The most important changes:

    • Reducers are no longer lambdas, but proper classes. I.e. move from { state: MyState, action: Any ->... to Reducer<MyState, Any> { state, action ->...
    • Bansa now provides it's own small Subscriber and Subscription interfaces, replacing RxJava versions.
    • The constructor for creating a store using Middleware has been simplified. createStore(intialState, reducer) is now BaseStore(initialState, reducer, Middleware...)
    Source code(tar.gz)
    Source code(zip)
  • 0.2.0(Mar 21, 2016)

    Drafting a new release with all of the good work put in by @clemp6r! This release has several important updates:

    • This library now has a more idiomatic Kotlin feel. Store has been moved to a proper interface. Yay!
    • Move from getState() (returning the current state) and state (the observable) to a more fluid api. From now on, simply use state for the currentState, and stateChanges for the underlying state observable. As always, you can simply subscribe!
    • Remove Marker interfaces State and Action. They aren't necessary!
    • The scheduler, which used to put state updates on a potentially separate thread, has been removed for now. Keeping the reducers completely synchronous has advantages in the middleware layer, and discourages bad practices in the reducer layer.
    Source code(tar.gz)
    Source code(zip)
Owner
Brian Egan
Montana boy living in Berlin, Indie Hacker, and speaker of bad German.
Brian Egan
Compose Multiplatform integration for Redux-Kotlin

Redux-Kotlin-Compose Compose Multiplatform integration for Redux Kotlin Installation Artifacts are hosted on maven central. For multiplatform, add the

Redux-Kotlin 7 Sep 7, 2022
Arc Layout is a view group with which you can add a arc-shaped container in your layout.

ArcLayout Arc Layout is a view group with which you can add a arc-shaped container in your layout. Two main variables are the direction and the curvat

Ali Rezaiyan 32 Aug 17, 2022
Kotlin coroutine capable Finite-State Machine (multiplatform)

Comachine Features Kotlin corutines. Event handlers can launch coroutines for collecting external events of performing side effects. Structured concur

Sergej Shafarenka 22 Dec 14, 2022
Simple State Machines in Kotlin (KSSM)

Simple State Machines in Kotlin (KSSM) What is this? KSSM (reordered: Kotlin - Simple State Machines) provides an easy and simple DSL (Domain Specific

Milos Marinkovic 22 Dec 12, 2022
Kotlin coroutine capable Finite-State Machine (multiplatform)

Comachine Features Kotlin corutines. Event handlers can launch coroutines for collecting external events of performing side effects. Structured concur

Sergej Shafarenka 22 Dec 14, 2022
Stresscraft - State-of-art Minecraft stressing software written in Kotlin

StressCraft (W.I.P) State-of-art Minecraft stressing software written in Kotlin.

Cubxity 57 Dec 4, 2022
ScopedState - Android Scoped State With Kotlin

Android Scoped State There is no need for complicated code - just define scopes

Ali Azizi 12 Jan 19, 2022
This repository contains the article describing my attempt to implement a simple state reducer based on Kotlin Flow and an example app that uses it.

This repository contains the article describing my attempt to implement a simple state reducer based on Kotlin Flow and an example app that uses it.

Maciej Sady 18 Dec 29, 2022
Netflix inspired OTT Home Screen, Contains implementation in Reactjs, Kotlin React Wrapper, Jetpack Compose Web

Netflix-Clone-React Practising React by building Netflix Clone Requirements TMDB api key : Add TMDB API key to AppApi.kt Learning Resourcce Build Netf

Chetan Gupta 61 Nov 13, 2022
Kotlin Multiplatform lifecycle-aware business logic components (aka BLoCs) with routing functionality and pluggable UI (Jetpack Compose, SwiftUI, JS React, etc.), inspired by Badoos RIBs fork of the Uber RIBs framework

Decompose Please see the project website for documentation and APIs. Decompose is a Kotlin Multiplatform library for breaking down your code into life

Arkadii Ivanov 819 Dec 29, 2022
WordMasterKMP - WIP Kotlin Multiplatform sample inspired by Wordle and also Word Master web sample

WordMasterKMP WIP Kotlin Multiplatform sample inspired by Wordle and also Word M

John O'Reilly 56 Oct 4, 2022
Kotlin DSL inspired by bhailang.js

Kotlin DSL inspired by bhailang.js

kaiwalya 1 Mar 22, 2022
A Kotlin multiplatform unit testing library inspired by / similar to Google Truth.

Truthish A testing API inspired by Google Truth but rewritten in Kotlin from the ground up, so it can be used in Kotlin multiplatform projects. For ex

Varabyte 70 Nov 2, 2022
🔴 A non-deterministic finite-state machine for Android & JVM that won't let you down

HAL is a non-deterministic finite-state machine for Android & JVM built with Coroutines StateFlow and LiveData. Why non-deterministic? Because in a no

Adriel Café 73 Nov 28, 2022
💫 Small microservice to handle state changes of Kubernetes pods and post them to Instatus or Statuspages

?? Kanata Small microservice to handle state changes of Kubernetes pods and post them to Instatus or Statuspages ?? Why? I don't really want to implem

Noel 4 Mar 4, 2022
Basic app to use different type of observables StateFlow, Flow, SharedFlow, LiveData, State, Channel...

stateflow-flow-sharedflow-livedata Basic app to use different type of observables StateFlow, Flow, SharedFlow, LiveData, State, Channel... StateFlow,

Raheem 5 Dec 21, 2022
ConstraintSetChangesTest - Simple project showing Changes of ConstraintSet value as part of mutable state in JetpackCompose.

ConstraintSetChangesTest Simple project showing Changes of ConstraintSet value as part of mutable state in JetpackCompose. Version: implementation

Mateusz Perlak 1 Feb 13, 2022
Advanced State in Jetpack Compose Codelab

Advanced State in Jetpack Compose Codelab This folder contains the source code for the Advanced State in Jetpack Compose Codelab codelab. The project

Carlos Barrios 1 May 12, 2022
Simplify mutating "immutable" state models

Mutekt (Pronunciation: /mjuːˈteɪt/, 'k' is silent) "Simplify mutating "immutable" state models" Generates mutable models from immutable model definiti

Shreyas Patil 179 Nov 30, 2022