Redux implementation for Kotlin (supports multiplatform JVM, native, JS, WASM)

Last update: May 16, 2022

Redux-Kotlin

CI

badge ![badge][badge-ios] badge badge badge badge badge badge badge

A redux standard for Kotlin that supports multiplatform projects.

Full documentation at http://reduxkotlin.org.

Misson Statement

Provide a standard redux implementation for Kotlin. In doing so will foster a ecosystem of middleware, store enhancers, & dev tools. These core values will guide descisions for the project:

  • core redux-kotlin will be a minimal implementation that other libraries can build upon
  • modular development (follow example of https://github.com/reduxjs)
  • support for all platforms supported by Kotlin multiplatform (JVM, iOS, Native, JS, WASM)
  • developed in open and enable discussion for all interested parties via open channels (slack, github, etc. TBD)
  • not owned by a individual or company

Redux in Kotlin, and in mobile in particular, may differ a bit from javascript. Many have found the basic pattern useful on Android & iOS leading to tens of opensource redux libraries in Kotlin, Java, and Swift, yet an ecosystem has yet to emerge. A port of javascript redux is a good starting point for creating a standard and will aid in cross-pollination of middleware, store enhancers, & dev tools from the javascript world.

Redux has proven helpful for state management in mobile. A multiplatform Kotlin implementation & ecosystem will increase developer productivity and code reuse across platforms.

Droidcon NYC Slides Video TBA

*** PLEASE FILL OUT THE Redux on Mobile Survey ***

How to add to project:

Artifacts are hosted on maven central. They are published with gradle metadata, so you may need to enable with enableFeaturePreview("GRADLE_METADATA") in your settings.gradle file. For multiplatform, add the following to your shared module:

kotlin {
  sourceSets {
        commonMain { //   <---  name may vary on your project
            dependencies {
                implementation "org.reduxkotlin:redux-kotlin-threadsafe:0.5.5"
            }
        }
 }

For JVM only:

  implementation "org.reduxkotlin:redux-kotlin-threadsafe-jvm:0.5.5"

*Non threadsafe store is available. Typical usage will be with the threadsafe store. More info read here

Usage is very similar to JS Redux and those docs will be useful https://redux.js.org/. These docs are not an intro to Redux, and just documentation on Kotlin specific bits. For more info on Redux in general, check out https://redux.js.org/.

Create an AppState class

  data class AppState(val user: User, val feed: List<Feed>)

Create Reducers:

  val reducer: Reducer<AppState> =  { state, action ->
    when (action) {
        is UserLoggedInAction -> state.copy(user = action.user)
        ...
    }
  }

Create Middleware: There are a few ways to create middleware:

Using a curried function stored in a val/var:

  val loggingMiddleware: Middleware = 
          { store ->
              { next ->
                  { action ->
                        //log here
                        next(action)
                   }
               }
            }

Using a function:

  fun loggingMiddleware(store: Store) = { next: Dispatcher -> 
              { action: Any -> 
                     //log here
                     next(action)
               }

Using the convenience helper function middleware:

   val loggingMiddleware = middleware { store, next, action -> 
          //log here
          next(action)
          }

Create a store

  val store = createThreadSafeStore(reducer, AppState(user, listOf()), applyMiddleware(loggingMiddleware))

You then will have access to dispatch and subscribe functions from the store.

Communication

Want to give feedback, contribute, or ask questions?

#redux slack channel in kotlinlang

Trello boards - https://trello.com/reduxkotlinorg

Or create an issue on github.

GitHub

https://github.com/reduxkotlin/redux-kotlin
Comments
  • 1. Consider removing same-thread-enforcement from getState

    Reading the state is often needed from multiple threads. Consideration of removing, or making optional, the same-thread-enforcement from the getState function to allow more flexibility in reading the state from the store. Calling from another thread will cause the check for isDispatching to fail if accessed while an action is dispatching. A solution that is needed that accounts allowing access from another thread, and respects actions that are currently being dispatched.

    Sample senario: Android webview javascript interface calls methods from a thread pool. A common usecase is to return a token from the state. If main thread is being used for the store, then use must write code to get the token from the main thread in a blocking manner.

    Reviewed by patjackson52 at 2020-04-06 20:37
  • 2. Unit-Testing with Coroutines results in "You may not call the store from a thread other than the thread on which it was created"

    Hi,

    we currently use your library in combination with Kotlin Coroutines and Flow. One of our middleware methods looks like this:

    private fun agbLoad(store: Store<AppState>, action: AgbLoad, next: Dispatcher) {
            CoroutineScope(Main).launch {
                flow { emit(apiService.client().user().api().termsOfUse()) }
                        .flowOn(IO)
                        // flowOn only works upstream.
                        // Catch & Collect are executed on the main thread
                        .catch { e ->
                            e.printStackTrace()
                            store.dispatch(AgbLoadFailure(e))
                        }
                        .collect { agb -> store.dispatch(AgbLoadSuccess(LegalState.Agb(agb.text, agb.activeFrom.ddMMYYYY()))) }
            }
    
            next(action)
        }
    

    We wanted to test this (and the other functions) and wrote the following JUnit Test:

        fun setUp() {
            Dispatchers.setMain(mainThreadSurrogate)
            recorderMiddleware = RecorderMiddleware()
            legalMiddleware = LegalMiddleware(apiService(), assetFeatureMock, userServiceMock)
        }
        @Test
        fun agbLoad_dispatchesAgbLoadSuccess() {
            webServer().setDispatcher(object : Dispatcher() {
                override fun dispatch(request: RecordedRequest?): MockResponse {
                    return MockResponse().setResponseCode(HttpURLConnection.HTTP_OK).setBody(termsOfUseResponseJson())
                }
            })
    
            runBlocking {
                CoroutineScope(Main).launch {
                    val store = createStore(appReducer, AppState(), applyMiddleware(
                            recorderMiddleware.all, LegalMiddleware(apiService(), assetFeatureMock, userServiceMock).all
                    ))
    
                    store.dispatch(AgbLoad())
                }
            }
    
            Barrier.awaitUntil { recorderMiddleware.getRecordings().size == 2 }
            assertThat(recorderMiddleware.getRecordings().last(), instanceOf(AgbLoadSuccess::class.java))
        }
    
        @After
        fun tearDown() {
            Dispatchers.resetMain() // reset main dispatcher to the original Main dispatcher
            mainThreadSurrogate.close()
        }
    

    Unfortunately the test throws an error: Exception in thread "UI @coroutine#3" java.lang.IllegalStateException: You may not call the store from a thread other than the thread on which it was created. This includes: getState(), dispatch(), subscribe(), and replaceReducer() This store was created on: 'UI @coroutine#2' and current thread is 'UI @coroutine#3' at org.reduxkotlin.CreateStoreKt$createStore$3.invoke(CreateStore.kt:50) at org.reduxkotlin.CreateStoreKt$createStore$7.invoke(CreateStore.kt:174)

    I already tried lots of coroutine combinations to get rid of this issue, but no success. Do you have an idea how we can fix this?

    (additional information): The exception doesn't appear in production, only in the test scenario.

    Thanks for your help :)

    Reviewed by jennymolske at 2020-02-03 13:34
  • 3. Jenn/threadsafe enhancer

    Following up on issue https://github.com/reduxkotlin/redux-kotlin/issues/77, this PR creates a new enhancer called synchronizeStore that wraps a Redux store in a synchronization object.

    I wrote a couple tests to compare the original thread-safe store implementation that we were working with against the proposed method of using the synchronizeStore enhancer. The test involves thunk middleware as well as delays to mimic async thunks, and the test for the original implementation intermittently fails with the same error we were seeing in our setup. Notably, when using a breakpoint on line 105 of the CreateThreadSafeStoreSpec file and running the test for the original implementation in debug mode, I see that we step into the interface defs of the original store methods in CreateStore; doing the same with the test for the enhancer implementation sees us step into the interface defs of the synchronized store in SynchronizedStore. This suggests to me that with the original implementation, thunks might be accessing the unsynchronized store dispatch method.

    The failing test was written just for communicating the issue we were seeing, happy to remove this and/or change up the tests as you see fit. This is my first time contributing to this repo so please let me know if I missed anything in terms of contributing standards. Thanks!

    Reviewed by jennkao at 2021-05-02 20:21
  • 4. Execution failed for task compileKotlinJs

    Hi, I'm trying to develop a sample-app using kotlin multiplatform and redux-kotlin but I'm struggling to setup the library for a new multiplatform project. I've created a "Kotlin/Multiplatform" project from IntelliJ 2019.3.2

    This is my gradle file:

    plugins {
        id 'java'
        id 'org.jetbrains.kotlin.multiplatform' version '1.3.61'
    }
    group 'com.shadowings'
    version '1.0.0'
    sourceCompatibility = 1.8
    repositories {
        mavenCentral()
    }
    dependencies {
        testCompile group: 'junit', name: 'junit', version: '4.12'
    }
    kotlin {
        jvm()
        js()
        iosArm64("ios") {
            binaries {
                framework()
            }
        }
        iosX64("iosSim") {
            binaries {
                framework()
            }
        }
        sourceSets {
            commonMain {
                dependencies {
                    implementation kotlin('stdlib-common')
                    implementation kotlin("org.reduxkotlin:redux-kotlin:0.4.0")
                }
            }
            commonTest {
                dependencies {
                    implementation kotlin('test-common')
                    implementation kotlin('test-annotations-common')
                }
            }
            jvmMain {
                dependencies {
                    implementation kotlin('stdlib-jdk8')
                }
            }
            jvmTest {
                dependencies {
                    implementation kotlin('test')
                    implementation kotlin('test-junit')
                }
            }
            jsMain {
                dependencies {
                    implementation kotlin('stdlib-js')
                }
            }
            jsTest {
                dependencies {
                    implementation kotlin('test-js')
                }
            }
            iosSimMain.dependsOn iosMain
            iosSimTest.dependsOn iosTest
        }
    }
    

    And I have this error when I try to build:

    Execution failed for task ':compileKotlinJs'.
    - Could not resolve all files for configuration ':jsCompileClasspath'.
       - Could not find org.jetbrains.kotlin:kotlin-org.reduxkotlin:redux-kotlin.
         Searched in the following locations:
           - https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-org.reduxkotlin/redux-kotlin/kotlin-org.reduxkotlin-redux-kotlin.module
           - https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-org.reduxkotlin/redux-kotlin/kotlin-org.reduxkotlin-redux-kotlin.pom
         Required by:
             project :
    
    Possible solution:
     - Declare repository providing the artifact, see the documentation at https://docs.gradle.org/current/userguide/declaring_repositories.html
    

    You can find the whole project at this repository: https://github.com/EmmanueleVilla/themoviedb-kotlinmultiplatform

    Reviewed by EmmanueleVilla at 2020-05-26 07:15
  • 5. WIP: Migrate to Kotlin Gradle DSL

    The Kotlin Gradle DSL has groovy interoperability so it can be mixed and match with groovy. Therefore this PR can be merged as is, cuz the Android example is done, but ideally, the whole project should be converted.

    https://docs.gradle.org/5.6.1/userguide/kotlin_dsl.html#sec:kotlin-dsl_plugin

    @patjackson52

    Reviewed by AOrobator at 2019-09-01 19:09
  • 6. Not compatible with Android Project

    I have added the following in build.gradle but import org.reduxkotlin.createStore is failing.

    dependencies { implementation "org.reduxkotlin:redux-kotlin:0.4.0" ... }

    Reviewed by p21asthana at 2020-05-01 11:51
  • 7. Unsubscribe StoreSubscription

    Currently, when subscribing to the store, a StoreSubscription is returned, but it's just an alias to () -> Unit. Subscriptions should be stored so they could be unsubscribed, otherwise it could lead to memory leaks.

    Reviewed by Pyeroh at 2019-08-20 23:44
  • 8. Empty artifact in maven central (?)

    Hi,

    I have tried to download and use your library in my test multiplatform project. I have added your dependency in my build.gradle.kts like follow:

        sourceSets {
            commonMain {
                dependencies {
                    api("org.jetbrains.kotlin:kotlin-stdlib-common")
                    api("org.reduxkotlin:redux-kotlin:0.2.4")
                }
            }
       }
    

    However, I am still unable to use it on in my code - references to APIs functions cannot be found. Any ideas?

    Reviewed by dudududi at 2019-07-26 07:06
  • 9. Bump url-parse from 1.4.7 to 1.5.7 in /website

    Bumps url-parse from 1.4.7 to 1.5.7.

    Commits
    • 8b3f5f2 1.5.7
    • ef45a13 [fix] Readd the empty userinfo to url.href (#226)
    • 88df234 [doc] Add soft deprecation notice
    • 78e9f2f [security] Fix nits
    • e6fa434 [security] Add credits for incorrect handling of userinfo vulnerability
    • 4c9fa23 1.5.6
    • 7b0b8a6 Merge pull request #223 from unshiftio/fix/at-sign-handling-in-userinfo
    • e4a5807 1.5.5
    • 193b44b [minor] Simplify whitespace regex
    • 319851b [fix] Remove CR, HT, and LF
    • Additional commits viewable in compare view

    Dependabot compatibility score

    Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting @dependabot rebase.


    Dependabot commands and options

    You can trigger Dependabot actions by commenting on this PR:

    • @dependabot rebase will rebase this PR
    • @dependabot recreate will recreate this PR, overwriting any edits that have been made to it
    • @dependabot merge will merge this PR after your CI passes on it
    • @dependabot squash and merge will squash and merge this PR after your CI passes on it
    • @dependabot cancel merge will cancel a previously requested merge and block automerging
    • @dependabot reopen will reopen this PR if it is closed
    • @dependabot close will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually
    • @dependabot ignore this major version will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this minor version will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this dependency will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
    • @dependabot use these labels will set the current labels as the default for future PRs for this repo and language
    • @dependabot use these reviewers will set the current reviewers as the default for future PRs for this repo and language
    • @dependabot use these assignees will set the current assignees as the default for future PRs for this repo and language
    • @dependabot use this milestone will set the current milestone as the default for future PRs for this repo and language

    You can disable automated security fix PRs for this repo from the Security Alerts page.

    Reviewed by dependabot[bot] at 2022-02-18 11:24
  • 10. Bump url-parse from 1.4.7 to 1.5.3 in /website

    Bumps url-parse from 1.4.7 to 1.5.3.

    Commits
    • ad44493 [dist] 1.5.3
    • c798461 [fix] Fix host parsing for file URLs (#210)
    • 201034b [dist] 1.5.2
    • 2d9ac2c [fix] Sanitize only special URLs (#209)
    • fb128af [fix] Use 'null' as origin for non special URLs
    • fed6d9e [fix] Add a leading slash only if the URL is special
    • 94872e7 [fix] Do not incorrectly set the slashes property to true
    • 81ab967 [fix] Ignore slashes after the protocol for special URLs
    • ee22050 [ci] Use GitHub Actions
    • d2979b5 [fix] Special case the file: protocol (#204)
    • Additional commits viewable in compare view

    Dependabot compatibility score

    Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting @dependabot rebase.


    Dependabot commands and options

    You can trigger Dependabot actions by commenting on this PR:

    • @dependabot rebase will rebase this PR
    • @dependabot recreate will recreate this PR, overwriting any edits that have been made to it
    • @dependabot merge will merge this PR after your CI passes on it
    • @dependabot squash and merge will squash and merge this PR after your CI passes on it
    • @dependabot cancel merge will cancel a previously requested merge and block automerging
    • @dependabot reopen will reopen this PR if it is closed
    • @dependabot close will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually
    • @dependabot ignore this major version will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this minor version will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this dependency will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
    • @dependabot use these labels will set the current labels as the default for future PRs for this repo and language
    • @dependabot use these reviewers will set the current reviewers as the default for future PRs for this repo and language
    • @dependabot use these assignees will set the current assignees as the default for future PRs for this repo and language
    • @dependabot use this milestone will set the current milestone as the default for future PRs for this repo and language

    You can disable automated security fix PRs for this repo from the Security Alerts page.

    Reviewed by dependabot[bot] at 2021-09-21 02:41
  • 11. Bump prismjs from 1.23.0 to 1.25.0 in /website

    Bumps prismjs from 1.23.0 to 1.25.0.

    Release notes

    Sourced from prismjs's releases.

    v1.25.0

    Release 1.25.0

    v1.24.1

    Release 1.24.1

    v1.24.0

    Release 1.24.0

    Changelog

    Sourced from prismjs's changelog.

    1.25.0 (2021-09-16)

    New components

    Updated components

    ... (truncated)

    Commits
    Maintainer changes

    This version was pushed to npm by rundevelopment, a new releaser for prismjs since your current version.


    Dependabot compatibility score

    Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting @dependabot rebase.


    Dependabot commands and options

    You can trigger Dependabot actions by commenting on this PR:

    • @dependabot rebase will rebase this PR
    • @dependabot recreate will recreate this PR, overwriting any edits that have been made to it
    • @dependabot merge will merge this PR after your CI passes on it
    • @dependabot squash and merge will squash and merge this PR after your CI passes on it
    • @dependabot cancel merge will cancel a previously requested merge and block automerging
    • @dependabot reopen will reopen this PR if it is closed
    • @dependabot close will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually
    • @dependabot ignore this major version will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this minor version will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this dependency will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
    • @dependabot use these labels will set the current labels as the default for future PRs for this repo and language
    • @dependabot use these reviewers will set the current reviewers as the default for future PRs for this repo and language
    • @dependabot use these assignees will set the current assignees as the default for future PRs for this repo and language
    • @dependabot use this milestone will set the current milestone as the default for future PRs for this repo and language

    You can disable automated security fix PRs for this repo from the Security Alerts page.

    Reviewed by dependabot[bot] at 2021-09-20 21:37
  • 12. Jetpack Compose example

    I would like to use this in my jetpack compose project, but I'm not sure how to pull off the subscribe in conjunction with compose to trigger recompositions. Any tips or examples? I put what I have below... Note that this is for a library, so I am not exposing compose to the consumer which is why it is wrapped in the RelativeLayout.

    Example code:

    class MyWidget @JvmOverloads constructor(
        context: Context,
        attrs: AttributeSet? = null,
        defStyle: Int = 0
    ) : RelativeLayout(context, attrs, defStyle), MyView {
        private var listener: MyView.Listener? = null
        private var properties: MyView.Properties = MyView.Properties()
    
        init {
            val composeView = ComposeView(context).apply {
                setContent {
                    MyWidget(listener = listener, properties = properties)
                }
            }
            addView(composeView)
        }
    
        override fun configureView(properties: MyView.Properties) {
            this.properties = properties
        }
    
        override fun setListener(listener: MyView.Listener) {
            this.listener = listener
        }
    }
    
    @Composable
    fun MyWidget(
        listener: MyView.Listener?,
        properties: MyView.Properties
    ) {
        // TODO subscribe somehow? how to unsubscribe?
    
        MyWidgetContent(
            state = store.state.subState,
            listener = listener,
            properties = properties
        )
    }
    
    @Composable
    internal fun MyWidgetContent(
        state: Substate,
        listener: MyView.Listener?,
        properties: MyView.Properties
    ) {
        Card(
            elevation = properties.elevation.dp,
            modifier = Modifier.fillMaxWidth(),
            shape = RoundedCornerShape(size = properties.cornerRadius.dp)
        ) {
            // do stuff with listener, etc
            // dispatch store actions and update the state, trigger recomposition?
        }
    
    Reviewed by DerekBeam at 2022-05-13 15:25
  • 13. Bump url-parse from 1.4.7 to 1.5.10 in /website

    Bumps url-parse from 1.4.7 to 1.5.10.

    Commits
    • 8cd4c6c 1.5.10
    • ce7a01f [fix] Improve handling of empty port
    • 0071490 [doc] Update JSDoc comment
    • a7044e3 [minor] Use more descriptive variable name
    • d547792 [security] Add credits for CVE-2022-0691
    • ad23357 1.5.9
    • 0e3fb54 [fix] Strip all control characters from the beginning of the URL
    • 61864a8 [security] Add credits for CVE-2022-0686
    • bb0104d 1.5.8
    • d5c6479 [fix] Handle the case where the port is specified but empty
    • Additional commits viewable in compare view

    Dependabot compatibility score

    Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting @dependabot rebase.


    Dependabot commands and options

    You can trigger Dependabot actions by commenting on this PR:

    • @dependabot rebase will rebase this PR
    • @dependabot recreate will recreate this PR, overwriting any edits that have been made to it
    • @dependabot merge will merge this PR after your CI passes on it
    • @dependabot squash and merge will squash and merge this PR after your CI passes on it
    • @dependabot cancel merge will cancel a previously requested merge and block automerging
    • @dependabot reopen will reopen this PR if it is closed
    • @dependabot close will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually
    • @dependabot ignore this major version will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this minor version will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this dependency will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
    • @dependabot use these labels will set the current labels as the default for future PRs for this repo and language
    • @dependabot use these reviewers will set the current reviewers as the default for future PRs for this repo and language
    • @dependabot use these assignees will set the current assignees as the default for future PRs for this repo and language
    • @dependabot use this milestone will set the current milestone as the default for future PRs for this repo and language

    You can disable automated security fix PRs for this repo from the Security Alerts page.

    Reviewed by dependabot[bot] at 2022-02-26 18:10
  • 14. Bump prismjs from 1.23.0 to 1.27.0 in /website

    Bumps prismjs from 1.23.0 to 1.27.0.

    Release notes

    Sourced from prismjs's releases.

    v1.27.0

    Release 1.27.0

    v1.26.0

    Release 1.26.0

    v1.25.0

    Release 1.25.0

    v1.24.1

    Release 1.24.1

    v1.24.0

    Release 1.24.0

    Changelog

    Sourced from prismjs's changelog.

    1.27.0 (2022-02-17)

    New components

    Updated components

    Updated plugins

    Other

    • Core
      • Added better error message for missing grammars (#3311) 2cc4660b

    1.26.0 (2022-01-06)

    New components

    Updated components

    ... (truncated)

    Commits
    Maintainer changes

    This version was pushed to npm by rundevelopment, a new releaser for prismjs since your current version.


    Dependabot compatibility score

    Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting @dependabot rebase.


    Dependabot commands and options

    You can trigger Dependabot actions by commenting on this PR:

    • @dependabot rebase will rebase this PR
    • @dependabot recreate will recreate this PR, overwriting any edits that have been made to it
    • @dependabot merge will merge this PR after your CI passes on it
    • @dependabot squash and merge will squash and merge this PR after your CI passes on it
    • @dependabot cancel merge will cancel a previously requested merge and block automerging
    • @dependabot reopen will reopen this PR if it is closed
    • @dependabot close will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually
    • @dependabot ignore this major version will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this minor version will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this dependency will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
    • @dependabot use these labels will set the current labels as the default for future PRs for this repo and language
    • @dependabot use these reviewers will set the current reviewers as the default for future PRs for this repo and language
    • @dependabot use these assignees will set the current assignees as the default for future PRs for this repo and language
    • @dependabot use this milestone will set the current milestone as the default for future PRs for this repo and language

    You can disable automated security fix PRs for this repo from the Security Alerts page.

    Reviewed by dependabot[bot] at 2022-02-26 01:43
  • 15. Bump ajv from 6.10.2 to 6.12.6 in /website

    Bumps ajv from 6.10.2 to 6.12.6.

    Release notes

    Sourced from ajv's releases.

    v6.12.6

    Fix performance issue of "url" format.

    v6.12.5

    Fix uri scheme validation (@​ChALkeR). Fix boolean schemas with strictKeywords option (#1270)

    v6.12.4

    Fix: coercion of one-item arrays to scalar that should fail validation (failing example).

    v6.12.3

    Pass schema object to processCode function Option for strictNumbers (@​issacgerges, #1128) Fixed vulnerability related to untrusted schemas (CVE-2020-15366)

    v6.12.2

    Removed post-install script

    v6.12.1

    Docs and dependency updates

    v6.12.0

    Improved hostname validation (@​sambauers, #1143) Option keywords to add custom keywords (@​franciscomorais, #1137) Types fixes (@​boenrobot, @​MattiAstedrone) Docs:

    v6.11.0

    Time formats support two digit and colon-less variants of timezone offset (#1061 , @​cjpillsbury) Docs: RegExp related security considerations Tests: Disabled failing typescript test

    Commits
    • fe59143 6.12.6
    • d580d3e Merge pull request #1298 from ajv-validator/fix-url
    • fd36389 fix: regular expression for "url" format
    • 490e34c docs: link to v7-beta branch
    • 9cd93a1 docs: note about v7 in readme
    • 877d286 Merge pull request #1262 from b4h0-c4t/refactor-opt-object-type
    • f1c8e45 6.12.5
    • 764035e Merge branch 'ChALkeR-chalker/fix-comma'
    • 3798160 Merge branch 'chalker/fix-comma' of git://github.com/ChALkeR/ajv into ChALkeR...
    • a3c7eba Merge branch 'refactor-opt-object-type' of github.com:b4h0-c4t/ajv into refac...
    • Additional commits viewable in compare view

    Dependabot compatibility score

    Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting @dependabot rebase.


    Dependabot commands and options

    You can trigger Dependabot actions by commenting on this PR:

    • @dependabot rebase will rebase this PR
    • @dependabot recreate will recreate this PR, overwriting any edits that have been made to it
    • @dependabot merge will merge this PR after your CI passes on it
    • @dependabot squash and merge will squash and merge this PR after your CI passes on it
    • @dependabot cancel merge will cancel a previously requested merge and block automerging
    • @dependabot reopen will reopen this PR if it is closed
    • @dependabot close will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually
    • @dependabot ignore this major version will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this minor version will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this dependency will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
    • @dependabot use these labels will set the current labels as the default for future PRs for this repo and language
    • @dependabot use these reviewers will set the current reviewers as the default for future PRs for this repo and language
    • @dependabot use these assignees will set the current assignees as the default for future PRs for this repo and language
    • @dependabot use this milestone will set the current milestone as the default for future PRs for this repo and language

    You can disable automated security fix PRs for this repo from the Security Alerts page.

    Reviewed by dependabot[bot] at 2022-02-12 14:25
  • 16. Error building KMM project for Arm64 simulator

    Hey y'all, I'm experiencing a build error (see below for gradle log output) in my KMM project after adding

    implementation("org.reduxkotlin:redux-kotlin-threadsafe:0.5.5")
    implementation("org.reduxkotlin:redux-kotlin-thunk:0.5.5")
    

    to my commonMain dependencies.

    This seems to only be an issue for Arm64 simulator as the build passes when deploying to a physical device. Possibly similar to https://youtrack.jetbrains.com/issue/KT-49417?

    > Task :shared:compileKotlinIosSimulatorArm64 FAILED
    
    FAILURE: Build failed with an exception.
    
    * What went wrong:
    Execution failed for task ':shared:compileKotlinIosSimulatorArm64'.
    > Could not resolve all files for configuration ':shared:iosSimulatorArm64CompileKlibraries'.
       > Could not resolve org.reduxkotlin:redux-kotlin-threadsafe:0.5.5.
         Required by:
             project :shared
          > No matching variant of org.reduxkotlin:redux-kotlin-threadsafe:0.5.5 was found. The consumer was configured to find a usage of 'kotlin-api' of a library, preferably optimized for non-jvm, as well as attribute 'org.jetbrains.kotlin.platform.type' with value 'native', attribute 'org.jetbrains.kotlin.native.target' with value 'ios_simulator_arm64' but:
              - Variant 'iosArm64-api' capability org.reduxkotlin:redux-kotlin-threadsafe:0.5.5 declares a usage of 'kotlin-api' of a component, as well as attribute 'org.jetbrains.kotlin.platform.type' with value 'native':
                  - Incompatible because this component declares a component, as well as attribute 'org.jetbrains.kotlin.native.target' with value 'ios_arm64' and the consumer needed a component, as well as attribute 'org.jetbrains.kotlin.native.target' with value 'ios_simulator_arm64'
                  - Other compatible attributes:
                      - Doesn't say anything about its component category (required a library)
                      - Doesn't say anything about its target Java environment (preferred optimized for non-jvm)
              - Variant 'iosArm64-iosArm64MetadataElements' capability org.reduxkotlin:redux-kotlin-threadsafe:0.5.5 declares a component, as well as attribute 'org.jetbrains.kotlin.platform.type' with value 'native':
                  - Incompatible because this component declares a usage of 'kotlin-metadata' of a component, as well as attribute 'org.jetbrains.kotlin.native.target' with value 'ios_arm64' and the consumer needed a usage of 'kotlin-api' of a component, as well as attribute 'org.jetbrains.kotlin.native.target' with value 'ios_simulator_arm64'
                  - Other compatible attributes:
                      - Doesn't say anything about its component category (required a library)
                      - Doesn't say anything about its target Java environment (preferred optimized for non-jvm)
              - Variant 'iosX64-api' capability org.reduxkotlin:redux-kotlin-threadsafe:0.5.5 declares a usage of 'kotlin-api' of a component, as well as attribute 'org.jetbrains.kotlin.platform.type' with value 'native':
                  - Incompatible because this component declares a component, as well as attribute 'org.jetbrains.kotlin.native.target' with value 'ios_x64' and the consumer needed a component, as well as attribute 'org.jetbrains.kotlin.native.target' with value 'ios_simulator_arm64'
                  - Other compatible attributes:
                      - Doesn't say anything about its component category (required a library)
                      - Doesn't say anything about its target Java environment (preferred optimized for non-jvm)
              - Variant 'iosX64-iosX64MetadataElements' capability org.reduxkotlin:redux-kotlin-threadsafe:0.5.5 declares a component, as well as attribute 'org.jetbrains.kotlin.platform.type' with value 'native':
                  - Incompatible because this component declares a usage of 'kotlin-metadata' of a component, as well as attribute 'org.jetbrains.kotlin.native.target' with value 'ios_x64' and the consumer needed a usage of 'kotlin-api' of a component, as well as attribute 'org.jetbrains.kotlin.native.target' with value 'ios_simulator_arm64'
                  - Other compatible attributes:
                      - Doesn't say anything about its component category (required a library)
                      - Doesn't say anything about its target Java environment (preferred optimized for non-jvm)
              - Variant 'jsIr-api' capability org.reduxkotlin:redux-kotlin-threadsafe:0.5.5 declares a usage of 'kotlin-api' of a component:
                  - Incompatible because this component declares a component, as well as attribute 'org.jetbrains.kotlin.platform.type' with value 'js' and the consumer needed a component, as well as attribute 'org.jetbrains.kotlin.platform.type' with value 'native'
                  - Other compatible attributes:
                      - Doesn't say anything about its component category (required a library)
                      - Doesn't say anything about its target Java environment (preferred optimized for non-jvm)
                      - Doesn't say anything about org.jetbrains.kotlin.native.target (required 'ios_simulator_arm64')
    ...
    

    Anything I can do to address this? I've also attached a sample project that reproduces the issue. And here's my iosApp config I'm using to run the build from Android Studio: Screen Shot 2022-02-01 at 12 26 39 PM

    Project to reproduce: MyApplication.zip

    If y'all are already aware of this or a fix is known, please close this - I apologize if I missed it 😁

    Reviewed by nesfeder at 2022-02-01 19:40
Kotlin Multiplatform Router for Android and iOS
Kotlin Multiplatform Router for Android and iOS

A powerful Kotlin Multiplatform Router for Android and iOS Support I am happy to help you with any problem on gitter Feel free to open any new issue!

Apr 12, 2022
MVU for Kotlin Multiplatform

Oolong Oolong is an Elm inspired Model-View-Update (MVU) implementation for Kotlin multiplatform. As the name implies, three core concepts comprise th

May 16, 2022
Model-View-ViewModel architecture components for mobile (android & ios) Kotlin Multiplatform development
Model-View-ViewModel architecture components for mobile (android & ios) Kotlin Multiplatform development

Mobile Kotlin Model-View-ViewModel architecture components This is a Kotlin Multiplatform library that provides architecture components of Model-View-

May 17, 2022
Extendable MVI framework for Kotlin Multiplatform with powerful debugging tools (logging and time travel), inspired by Badoo MVICore library
Extendable MVI framework for Kotlin Multiplatform with powerful debugging tools (logging and time travel), inspired by Badoo MVICore library

Should you have any questions or ideas please welcome to the Slack channel: #mvikotlin Inspiration This project is inspired by Badoo MVICore library.

May 17, 2022
Unidirectional Data Flow in Kotlin - Port of https://github.com/ReSwift/ReSwift to Kotlin
Unidirectional Data Flow in Kotlin - Port of https://github.com/ReSwift/ReSwift to Kotlin

ReKotlin Port of ReSwift to Kotlin, which corresponds to ReSwift/4.0.0 Introduction ReKotlin is a Redux-like implementation of the unidirectional data

May 11, 2022
MVVM RECIPE ANDROID APP Is an app where I show how to use MVVM, retrofit, dagger hilt, coroutine, liveData, Kotlin, navigation component, and so on...
MVVM RECIPE ANDROID APP Is an app where I show how to use MVVM, retrofit, dagger hilt, coroutine, liveData, Kotlin, navigation component, and so on...

MVVM RECIPE ANDROID APP Is an app where I show how to use MVVM, retrofit, dagger hilt, coroutine, liveData, kotlin, navigation component, and so on...

Apr 4, 2022
A sample project in Kotlin to demonstrate AndroidX, MVVM, Coroutines, Hilt, Room, Data Binding, View Binding, Retrofit, Moshi, Leak Canary and Repository pattern.

This repository contains a sample project in Kotlin to demonstrate AndroidX, MVVM, Coroutines, Hilt, Room, Data Binding, View Binding, Retrofit, Moshi, Leak Canary and Repository pattern

May 9, 2022
Android Clean Architecture💎 Base Project Android with Kotlin and MVVM applying clean architecture
 Android Clean Architecture💎 Base Project Android with Kotlin and MVVM applying clean architecture

Android Clean Architecture?? Base Project Android with Kotlin and MVVM applying clean architecture

May 18, 2022
A sample to showcase Kotlin, MVVM, Koin, Coroutines, StateFlow, Room, WorkManager, Retrofit and Unit test.

TVMaze-Cache A sample to showcase Kotlin, MVVM, Koin, Coroutines, StateFlow, Room, WorkManager, Retrofit and Unit test. Features MVVM Architecture + R

Mar 13, 2022
📒Note taking app, MVVM with Google Architectural components Room, LiveData and ViewModel written in Kotlin, androidx libraries
📒Note taking app, MVVM with Google Architectural components Room, LiveData and ViewModel written in Kotlin, androidx libraries

?? MyNotes Note taking Android App using androidx libraries, MVVM with Google Architectural components Room, LiveData and ViewModel. Written in Kotlin

May 1, 2022
simple app used Kotlin MVVM Dagger2 Room Coroutines Retrofit2

Exhibits Application which retrieves data from Webserver (via Retrofit), saves it into Room and get from it if user is offline. There are applying MVV

Oct 14, 2021
Clean Architecture - Kotlin, MVVM, Use cases
Clean Architecture - Kotlin, MVVM, Use cases

CleanArchitecture Is Clean Architecture only MVVM ? NO, MVVM is a part of clean architecture. MVVM includes Model, View and ViewModel and in addition

May 13, 2022
Kotlin+Flow+Retrofit+OKHttp+ViewBanding+ViewModel+LiveData封装的一个Kotlin版本的MVVM框架

Gitee 地址:kmvvm Github 地址:kmvvm CHANGE LOG 技术要点 支持Flow+Retrofit+OkHttp实现链式http请求 支持Rxjava+Retrofit+OkHttp实现链式http请求 封装基类:BaseActivity、BaseVMActivity、Ba

May 23, 2022
Ceci est une application d'actualités de l'architecture MVVM avec Kotlin
Ceci est une application d'actualités de l'architecture MVVM avec Kotlin

MVVM-Appli Infos Ceci est une application d'actualités de l'architecture MVVM avec Kotlin utilisant des composants : Retrofit, Room, Coroutines, et Na

Nov 4, 2021
An android app built using Kotlin following Multi-Module Clean Architecture MVVM
An android app built using Kotlin following Multi-Module Clean Architecture MVVM

RickyandMorty An android app built using Kotlin that consumes RickyadMorty API to display characters.It has been built following Clean Architecture Pr

Feb 3, 2022
JeTaxi is built on Clean Architecture-MVVM with Kotlin and follows modern android development trends.
 JeTaxi is built on Clean Architecture-MVVM with Kotlin and follows modern android development trends.

JeTaxi is built on Clean Architecture-MVVM with Kotlin and follows modern android development trends. Also, It uses some of Jetpack and popular libraries. These are Kotlin Coroutine-Flow, kotlinx.serialization, Hilt, Compose, Accompanist, Retrofit2, OkHttp3, Chucker, MockWebServer, Truth.

May 19, 2022
Make E-Commerce using Kotlin MVVM
Make E-Commerce using Kotlin MVVM

Kotlin E-Commerce MVVM Make E-Commerce using Kotlin, and for backend i use Golang, and PHP Feature MVVM Retrofit2 15+ Screen Payment Gateway (Razorpay

Feb 21, 2022
App kotlin with flow, paging 3, MVVM, Room, Dagger hilt

TMDBTest App kotlin with flow, paging 3, MVVM, Room, Dagger hilt Para compilar la app se tiene que descargar el proyecto. Luego poner la APIKEY de TMD

Feb 22, 2022
MVVM Kotlin Android Architecture
MVVM Kotlin Android Architecture

Model-View-ViewModel (ie MVVM) Model-View-ViewModel (ie MVVM) is a template of a client application architecture, proposed by John Gossman as an alter

Mar 13, 2022