11package org.reduxkotlin
22
3+ import org.reduxkotlin.utils.getThreadName
34import org.reduxkotlin.utils.isPlainObject
45
56/* *
@@ -44,6 +45,15 @@ fun <State> createStore(
4445 var currentListeners = mutableListOf< () -> Unit > ()
4546 var nextListeners = currentListeners
4647 var isDispatching = false
48+ val storeThreadName = getThreadName()
49+ fun isSameThread () = getThreadName() == storeThreadName
50+ fun checkSameThread () = check(isSameThread()) {
51+ """ You may not call the store from a thread other than the thread on which it was created.
52+ |This includes: getState(), dispatch(), subscribe(), and replaceReducer()
53+ |This store was created on: '$storeThreadName ' and current
54+ |thread is '${getThreadName()} '
55+ """ .trimMargin()
56+ }
4757
4858 /* *
4959 * This makes a shallow copy of currentListeners so we can use
@@ -64,6 +74,7 @@ fun <State> createStore(
6474 * @returns {S} The current state tree of your application.
6575 */
6676 fun getState (): State {
77+ checkSameThread()
6778 check(! isDispatching) {
6879 """ |You may not call store.getState() while the reducer is executing.
6980 |The reducer has already received the state as an argument.
@@ -100,6 +111,7 @@ fun <State> createStore(
100111 * @returns {StoreSubscription} A fun to remove this change listener.
101112 */
102113 fun subscribe (listener : StoreSubscriber ): StoreSubscription {
114+ checkSameThread()
103115 check(! isDispatching) {
104116 """ |You may not call store.subscribe() while the reducer is executing.
105117 |If you would like to be notified after the store has been updated,
@@ -159,6 +171,7 @@ fun <State> createStore(
159171 * return something else (for example, a Promise you can await).
160172 */
161173 fun dispatch (action : Any ): Any {
174+ checkSameThread()
162175 require(isPlainObject(action)) {
163176 """ Actions must be plain objects. Use custom middleware for async
164177 |actions.""" .trimMargin()
@@ -193,6 +206,7 @@ fun <State> createStore(
193206 * @returns {void}
194207 */
195208 fun replaceReducer (nextReducer : Reducer <State >) {
209+ checkSameThread()
196210 currentReducer = nextReducer
197211
198212 // This action has a similar effect to ActionTypes.INIT.
@@ -217,7 +231,7 @@ fun <State> createStore(
217231 // the initial state tree.
218232 dispatch(ActionTypes .INIT )
219233
220- return object : Store <State > {
234+ return object : Store <State > {
221235 override val getState = ::getState
222236 override var dispatch: Dispatcher = ::dispatch
223237 override val subscribe = ::subscribe
0 commit comments