reduxkotlin / redux-kotlin Goto Github PK
View Code? Open in Web Editor NEWRedux implementation for Kotlin (supports multiplatform JVM, native, JS, WASM)
Home Page: https://reduxkotlin.org
License: MIT License
Redux implementation for Kotlin (supports multiplatform JVM, native, JS, WASM)
Home Page: https://reduxkotlin.org
License: MIT License
Doesn't seem like ActionTypes stores any state, so it might be better as an enum
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?
What is the purpose of combineEnhancers?
It's not documented and does not have an analog in JS redux. I don't see it used anywhere -- this appears that it may be debris.
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.
Should calls to Store.dispatch be thread confined? Particularly to the main/ui thread of the platform? Dealing with multi-threaded updates to State can get hairy
Currently lib fails to resolve for mingwX64 target. This essentially means it's unviable for any MPP project using it.
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:
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 ๐
There are two uses:
There's a definition of a ReducerForAction
which cannot be used in order to create a store. A suggestion could be smth like this:
/**
* See also https://github.com/reactjs/redux/blob/master/docs/Glossary.md#reducer
*/
typealias Reducer<State> = ReducerForActionType<State, Any>
/**
* Reducer for a particular subclass of actions. Useful for Sealed classes &
* exhaustive when statements. See [reducerForActionType].
*/
typealias ReducerForActionType<TState, TAction> = (state: TState, action: TAction) -> TState
and then make sure that the store can handle the ReducerForActionType<TState, TAction>
Personally I would change this the other way around and make the reducer be the one with the defined action:
/**
* See also https://github.com/reactjs/redux/blob/master/docs/Glossary.md#reducer
*/
typealias Reducer<State, Action> = (state: State, action: Action) -> State
/**
* ...
*/
typealias AnonymActionReducer<State> = Reducer<State, Any>
Currently not supported due to atomicFu not supporting. It is on the roadmap for AtomicFu. This requires no action on our part, other than updating when available.
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?
}
I have added the following in build.gradle but import org.reduxkotlin.createStore is failing.
dependencies {
implementation "org.reduxkotlin:redux-kotlin:0.4.0"
...
}
Hi there! Recently began using this library, and have noticed some hard-to-reproduce errors popping up while developing. The errors occur inconsistently and mention threading issues:
You may not call store.subscribe() while the reducer is executing. If you would like to be notified after the store has been updated, subscribe from a component and invoke store.getState() in the callback to access the latest state. See https://www.reduxkotlin.org/api/store#subscribelistener-storesubscriber for more details. You may be seeing this due accessing the store from multiplethreads. Try createThreadSafeStore() https://reduxkotlin.org/introduction/threading
and
You may not call store.getState() while the reducer is executing. The reducer has already received the state as an argument. Pass it down from the top reducer instead of reading it from the store. You may be accessing getState while dispatching from another thread. Try createThreadSafeStore(). https://reduxkotlin.org/introduction/threading
However we do use createThreadSafeStore
, and these errors are being thrown from code outside our reducers (in thunks and views), so I am surprised to see these errors.
We are using:
org.reduxkotlin:redux-kotlin-threadsafe:0.5.5
org.reduxkotlin:reselect:0.5.5
org.reduxkotlin:redux-kotlin-thunk:0.5.5
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 :)
To create a store using createThreadSafeStore
, you must provide:
typealias Reducer<State> = (state: State, action: Any) -> State
And not:
typealias ReducerForActionType<TState, TAction> = (state: TState, action: TAction) -> TState
Can we add support for the latter?
Hi i have an error during the buid of my app, when i try to migrate from version 0.5.5 to 0.6.0 (which it seem to be necessary to migrate from kotlin 1.7 to kotlin 1.8)
`Execution failed for task ':app:checkDebugDuplicateClasses'.
A failure occurred while executing com.android.build.gradle.internal.tasks.CheckDuplicatesRunnable
Duplicate class org.reduxkotlin.threadsafe.CreateThreadSafeStoreKt found in modules jetified-redux-kotlin-threadsafe-debug-runtime (org.reduxkotlin:redux-kotlin-threadsafe-android-debug:0.6.0) and jetified-redux-kotlin-threadsafe-jvm-0.6.0 (org.reduxkotlin:redux-kotlin-threadsafe-jvm:0.6.0)
Duplicate class org.reduxkotlin.threadsafe.CreateThreadSafeStoreKt$createTypedThreadSafeStore$$inlined$asTyped$1 found in modules jetified-redux-kotlin-threadsafe-debug-runtime (org.reduxkotlin:redux-kotlin-threadsafe-android-debug:0.6.0) and jetified-redux-kotlin-threadsafe-jvm-0.6.0 (org.reduxkotlin:redux-kotlin-threadsafe-jvm:0.6.0)`
in the build.gradle of my app :
dependencies { .... implementation "org.reduxkotlin:redux-kotlin-threadsafe-jvm:0.6.0" .... }
in the build.gradle of my shared module :
`kotlin {
android()
val xcf = XCFramework()
listOf(
iosX64(),
iosArm64(),
).forEach {
it.binaries.framework {
baseName = "shared"
xcf.add(this)
}
}
sourceSets {
val commonMain by getting {
dependencies {
...
implementation("org.reduxkotlin:redux-kotlin-threadsafe:0.6.0")
...`
I think the problem come from my configuration.
I would appreciate some help.
Thanks.
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
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.
Hello!
I am implementing a KMM app and was looking for a way to manage state in a cross-platform way. I am using sqldelight for my data storage needs. The idea was to handle all side-effects of my app with Redux inside the shared
module.
I was wondering on how one would work around the fact that modifying data has to be pushed down to the database layer. This applies to data creating, deletion and modification but also to data filtering. Sometimes it is actually faster to re-query the database with specific SQL statements instead of filtering in Kotlin (i.e., 1000 todo items and I want to filter by completed status. select * from todos where completed = 0
is more efficient than doing the filtering in Kotlin for large item counts).
Is there a goto strategy? I haven't found any (example) project that works with a database. be it Sqldelight or Room.
arm32 support is missing from redux-kotlin & redux-kotlin-threadsafe.
We should also perform a check for any other missing platforms.
It doesn't seem possible to be able to subscribe the state change of a specific value or sub-state. Do you have any plans to add this feature?
Kotlin for wasm is now alpha but it appears redux-kotlin supported a prior wasm32 target ending with version 0.5.5?
This issue lists Renovate updates and detected dependencies. Read the Dependency Dashboard docs to learn more.
Warning
These dependencies are deprecated:
Datasource | Name | Replacement PR? |
---|---|---|
npm | @babel/plugin-proposal-class-properties |
|
npm | now |
These updates are currently rate-limited. Click on a checkbox below to force their creation now.
These updates have all been created already. Click a checkbox below to force a retry/rebase of any.
actions/download-artifact
, actions/upload-artifact
)These are blocked by an existing closed PR and will not be recreated unless you click a checkbox below.
.github/workflows/check.yml
actions/checkout v3
actions/setup-java v3
actions/cache v3
github/codeql-action v2
msys2/setup-msys2 v2
actions/checkout v3
actions/setup-java v3
actions/cache v3
actions/upload-artifact v3
.github/workflows/release.yml
actions/checkout v3
actions/setup-java v3
actions/cache v3
actions/upload-artifact v3
msys2/setup-msys2 v2
actions/checkout v3
actions/setup-java v3
actions/cache v3
actions/download-artifact v3
crazy-max/ghaction-github-pages v3
.github/workflows/resolve-version.yml
actions/checkout v3
peter-evans/create-pull-request v5
gradle.properties
settings.gradle.kts
de.fayard.refreshVersions 0.51.0
com.gradle.enterprise 3.12.3
build.gradle.kts
build-conventions/settings.gradle.kts
de.fayard.refreshVersions 0.51.0
com.gradle.enterprise 3.12.3
build-conventions/build.gradle.kts
build-conventions/src/main/kotlin/convention.atomicfu.gradle.kts
build-conventions/src/main/kotlin/convention.common.gradle.kts
build-conventions/src/main/kotlin/convention.control.gradle.kts
build-conventions/src/main/kotlin/convention.detekt.gradle.kts
build-conventions/src/main/kotlin/convention.git-hooks.gradle.kts
build-conventions/src/main/kotlin/convention.library-android.gradle.kts
build-conventions/src/main/kotlin/convention.library-mpp-all.gradle.kts
build-conventions/src/main/kotlin/convention.library-mpp-loved.gradle.kts
build-conventions/src/main/kotlin/convention.local-properties.gradle.kts
build-conventions/src/main/kotlin/convention.mpp-all.gradle.kts
build-conventions/src/main/kotlin/convention.mpp-loved.gradle.kts
build-conventions/src/main/kotlin/convention.publishing-mpp.gradle.kts
build-conventions/src/main/kotlin/convention.publishing-nexus.gradle.kts
build-conventions/src/main/kotlin/convention.publishing.gradle.kts
redux-kotlin/build.gradle.kts
redux-kotlin-threadsafe/build.gradle.kts
gradle/wrapper/gradle-wrapper.properties
gradle 7.6
website/package.json
@babel/plugin-proposal-class-properties ^7.1.0
@babel/preset-react ^7.0.0
docusaurus ^1.13.0
now ^21.0.0
By using ksp + kotlinpoet, I implemented this proposal ๏ผMake easy to 'register' reducers
I try to fork the project, but I can't run it on my machine, maybe it's a problem with the environment. I had to implement this proposal in my area of expertise, so I did it in an android project.
It works fine in my project, but I only have a little knowledge about ksp and kotlinpoet, so it might have some bugs.
I hope you will transplant it from this project of mine when you have the ability and time.
I am looking for something similar to redux-persist.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.