Skip to content

Commit

Permalink
Removing some of the Stream references.
Browse files Browse the repository at this point in the history
  • Loading branch information
Laimiux committed Sep 29, 2021
1 parent 1c5ad04 commit d678ab2
Show file tree
Hide file tree
Showing 17 changed files with 45 additions and 43 deletions.
10 changes: 5 additions & 5 deletions docs/async_events.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,8 @@ override fun evaluate(input: Input, state: State, context: FormulaContext): ...
output = createRenderModel(state.taskList),
// All async events need to be declared within "context.updates" block.
updates = context.updates {
// Convert RxJava observable to a Formula Stream.
val taskStream = RxStream.fromObservable(taskRepo::tasks)
// Convert RxJava observable to a Formula disposable action.
val taskStream = RxDisposableAction.fromObservable(taskRepo::tasks)
// Tell Formula that you want to listen to these events
events(taskStream) { newTaskList ->
// update our state
Expand All @@ -35,15 +35,15 @@ interface Stream<Message> {
}
```

In this example we used an `RxStream.fromObservable` to convert from an `Observable` to a `Stream` instance.
In this example we used an `RxDisposableAction.fromObservable` to convert from an `Observable` to a `DisposableAction` instance.

Instead of us subscribing to the observable/stream directly, the runtime manages the subscriptions for us.
It will subscribe the first time `events` is called and unsubscribe when our Formula is removed or
if we don't return it anymore. For example, it is okay to have conditional logic.
```kotlin
context.updates {
if (state.locationTrackingEnabled) {
val locationStream = RxStream.fromObservable { locationManager.updates() }
val locationStream = RxDisposableAction.fromObservable { locationManager.updates() }
events(locationStream) { event ->
transition(state.copy(location = event.location))
}
Expand Down Expand Up @@ -81,7 +81,7 @@ class TaskFormula(val taskRepo: TaskRepo): Formula {
): Evaluation<Output> {
return Evaluation(
updates = context.updates {
val fetchTask = RxStream.fromObservable(key = input.taskId) { taskRepo.fetchTask(input.taskId) }
val fetchTask = RxDisposableAction.fromObservable(key = input.taskId) { taskRepo.fetchTask(input.taskId) }
events(fetchTask) { taskResponse ->
transition(state.copy(task = taskResponse))
}
Expand Down
6 changes: 3 additions & 3 deletions docs/events.md
Original file line number Diff line number Diff line change
Expand Up @@ -111,17 +111,17 @@ Evaluation(
output = ...,
updates = context.updates {
// Performs a side effect when formula is initialized
events(Stream.onInit()) {
events(DisposableAction.onInit()) {
transition { analytics.trackScreenOpen() }
}

// Performs a side effect when formula is terminated
events(Stream.onTerminate()) {
events(DisposableAction.onTerminate()) {
transition { analytics.trackClose() }
}

// Performs a side-effect when data changes
events(Stream.onData(), state.itemId) {
events(DisposableAction.onData(), state.itemId) {
// This will call api.fetchItem for each unique itemId
transition { api.fetchItem(state.itemId) }
}
Expand Down
4 changes: 2 additions & 2 deletions docs/faq.md
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ class TaskDetailFormula @Inject constructor(
return Evaluation(
output = state.task,
updates = context.updates {
RxStream.fromObservable { repo.fetchTask(input.taskId) }.onEvent { task ->
RxDisposableAction.fromObservable { repo.fetchTask(input.taskId) }.onEvent { task ->
val renderModel = TaskDetailRenderModel(
title = task.title,
// Don't do: calling context.onEvent within "onEvent" will cause a crash described above
Expand Down Expand Up @@ -100,7 +100,7 @@ class TaskDetailFormula @Inject constructor(
return Evaluation(
output = renderModel,
updates = context.updates {
RxStream.fromObservable { repo.fetchTask(input.taskId) }.onEvent { task ->
RxDisposableAction.fromObservable { repo.fetchTask(input.taskId) }.onEvent { task ->
transition(state.copy(task = renderModel))
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
package com.instacart.formula.android.internal

import com.instacart.formula.DisposableAction
import com.instacart.formula.Evaluation
import com.instacart.formula.Formula
import com.instacart.formula.FormulaContext
import com.instacart.formula.Stream
import com.instacart.formula.android.DisposableScope

/**
Expand Down Expand Up @@ -64,7 +64,7 @@ internal class CompositeBinding<ParentComponent, ScopedComponent>(
output = Unit,
updates = context.updates {
val isInScope = input.activeFragments.any { binds(it.key) }
events(Stream.onData(isInScope)) {
events(DisposableAction.onData(isInScope)) {
if (isInScope && component == null) {
transition(State(component = scopeFactory.invoke(input.component)))
} else if (!isInScope && component != null) {
Expand All @@ -76,7 +76,7 @@ internal class CompositeBinding<ParentComponent, ScopedComponent>(
}
}

events(Stream.onTerminate()) {
events(DisposableAction.onTerminate()) {
transition { component?.dispose() }
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
package com.instacart.formula.android.internal

import com.instacart.formula.DisposableAction
import com.instacart.formula.Evaluation
import com.instacart.formula.Formula
import com.instacart.formula.FormulaContext
import com.instacart.formula.Stream
import com.instacart.formula.android.FeatureFactory
import com.instacart.formula.android.FragmentKey
import com.instacart.formula.android.FeatureEvent
Expand Down Expand Up @@ -44,7 +44,7 @@ internal class FeatureBinding<in Component, in Dependencies, in Key : FragmentKe
input.activeFragments.forEachIndices { fragmentId ->
val key = fragmentId.key
if (binds(key)) {
Stream.onData(fragmentId).onEvent {
DisposableAction.onData(fragmentId).onEvent {
transition {
try {
val dependencies = toDependencies(input.component)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package com.instacart.formula.rxjava3

import com.instacart.formula.Stream
import com.instacart.formula.DisposableAction
import com.instacart.formula.StreamFormula
import io.reactivex.rxjava3.core.Observable

Expand All @@ -13,8 +13,8 @@ abstract class ObservableFormula<Input : Any, Output : Any> : StreamFormula<Inpu

abstract fun observable(input: Input): Observable<Output>

final override fun stream(input: Input): Stream<Output> {
return RxStream.fromObservable {
final override fun stream(input: Input): DisposableAction<Output> {
return RxDisposableAction.fromObservable {
observable(input)
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
package com.instacart.formula.test

import com.instacart.formula.Cancelable
import com.instacart.formula.Stream
import com.instacart.formula.DisposableAction
import java.lang.AssertionError

class TestStreamObserver<Message>(private val stream: Stream<Message>) {
class TestDisposableActionObserver<Message>(private val action: DisposableAction<Message>) {
private val values = mutableListOf<Message>()
private val cancelation = stream.start { values.add(it) }
private val cancelation = action.start { values.add(it) }

fun values(): List<Message> = values

Expand All @@ -23,7 +23,7 @@ class TestStreamObserver<Message>(private val stream: Stream<Message>) {
}

/**
* Attempts to cancel the [stream]. Will throw an exception if [stream] did not
* Attempts to cancel the [action]. Will throw an exception if [action] did not
* provide a [Cancelable].
*/
fun cancel() {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
package com.instacart.formula.test

import com.instacart.formula.DisposableAction
import com.instacart.formula.Evaluation
import com.instacart.formula.Formula
import com.instacart.formula.FormulaContext
import com.instacart.formula.Stream
import java.lang.IllegalStateException

/**
Expand Down Expand Up @@ -74,7 +74,7 @@ abstract class TestFormula<Input, Output> :
return Evaluation(
output = state.output,
updates = context.updates {
Stream.onTerminate().onEvent {
DisposableAction.onTerminate().onEvent {
transition {
stateMap.remove(state.initialInput)
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
package com.instacart.formula.test

import com.instacart.formula.DisposableAction
import com.instacart.formula.IFormula
import com.instacart.formula.Stream

/**
* An extension function to create a [TestFormulaObserver] for a [IFormula] instance.
Expand All @@ -25,5 +25,4 @@ fun <Input : Any, Output : Any, F: IFormula<Input, Output>> F.test(
}
}

fun <Message> Stream<Message>.test() = TestStreamObserver(this)

fun <Message> DisposableAction<Message>.test() = TestDisposableActionObserver(this)
Original file line number Diff line number Diff line change
Expand Up @@ -2,23 +2,23 @@ package com.instacart.formula.test

import com.google.common.truth.Truth.assertThat
import com.instacart.formula.Cancelable
import com.instacart.formula.Stream
import com.instacart.formula.DisposableAction
import org.junit.Test
import java.lang.IllegalStateException

class TestStreamTest {
class TestDisposableActionTest {

@Test fun `assert values success`() {
multipleValueStream().test().assertValues(1, 2)
multipleEventAction().test().assertValues(1, 2)
}

@Test fun `assert value fails due to different size`() {
val exception = fails { multipleValueStream().test().assertValues(1) }
val exception = fails { multipleEventAction().test().assertValues(1) }
assertThat(exception).isInstanceOf(AssertionError::class.java)
}

@Test fun `assert value fails due to different value`() {
val exception = fails { multipleValueStream().test().assertValues(1, 5) }
val exception = fails { multipleEventAction().test().assertValues(1, 5) }
assertThat(exception).isInstanceOf(AssertionError::class.java)
}

Expand All @@ -32,7 +32,7 @@ class TestStreamTest {
throw IllegalStateException("Action succeeded.")
}

fun multipleValueStream() = object : Stream<Int> {
private fun multipleEventAction() = object : DisposableAction<Int> {
override fun start(send: (Int) -> Unit): Cancelable? {
send(1)
send(2)
Expand Down
4 changes: 2 additions & 2 deletions formula/src/main/java/com/instacart/formula/BoundAction.kt
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,14 @@ package com.instacart.formula
*/
class BoundAction<Message>(
val key: Any,
val stream: Stream<Message>,
val action: DisposableAction<Message>,
internal var listener: (Message) -> Unit
) {

internal var cancelable: Cancelable? = null

internal fun start() {
cancelable = stream.start() { message ->
cancelable = action.start() { message ->
listener.invoke(message)
}
}
Expand Down
2 changes: 1 addition & 1 deletion formula/src/main/java/com/instacart/formula/Cancelable.kt
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
package com.instacart.formula

/**
* Used within [Stream] to receive a cancel event. Use this to perform clean up.
* Used within [DisposableAction] to receive a cancel event. Use this to perform clean up.
*/
interface Cancelable {
companion object {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -240,7 +240,7 @@ abstract class FormulaContext<State> internal constructor(

return BoundAction(
key = JoinedKey(action.key(), callback::class),
stream = action,
action = action,
listener = callback
)
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
package com.instacart.formula.streams

import com.instacart.formula.rxjava3.RxDisposableAction
import com.instacart.formula.rxjava3.RxStream
import io.reactivex.rxjava3.core.Observable

object EmptyStream {
fun init(key: Any = Unit) = RxStream.fromObservable(key) { Observable.empty<Unit>() }
fun init(key: Any = Unit) = RxDisposableAction.fromObservable(key) { Observable.empty<Unit>() }
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package com.instacart.formula.subjects

import com.google.common.truth.Truth.assertThat
import com.instacart.formula.Cancelable
import com.instacart.formula.DisposableAction
import com.instacart.formula.Evaluation
import com.instacart.formula.FormulaContext
import com.instacart.formula.StatelessFormula
Expand Down Expand Up @@ -44,8 +45,8 @@ class DynamicStreamSubject(runtime: TestableRuntime) {
)
}

private fun stream(key: String): Stream<Unit> {
return object : Stream<Unit> {
private fun stream(key: String): DisposableAction<Unit> {
return object : DisposableAction<Unit> {
override fun start(send: (Unit) -> Unit): Cancelable? {
running.add(key)
return Cancelable {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package com.instacart.formula.subjects

import com.instacart.formula.DisposableAction
import com.instacart.formula.Evaluation
import com.instacart.formula.Formula
import com.instacart.formula.FormulaContext
Expand All @@ -23,7 +24,7 @@ object ExtremelyNestedFormula {
return Evaluation(
output = state + childValue,
updates = context.updates {
events(Stream.onInit()) {
events(DisposableAction.onInit()) {
transition(state + 1)
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
package com.instacart.formula.samples.networkstate

import com.instacart.formula.Stream
import com.instacart.formula.DisposableAction

data class NetworkState(val isOnline: Boolean)

interface NetworkStateStream : Stream<NetworkState> {
interface NetworkStateStream : DisposableAction<NetworkState> {
/**
* Using type as a key. There should not be more
* than one subscription to this stream
Expand Down

0 comments on commit d678ab2

Please sign in to comment.