Skip to content

Commit

Permalink
Basic storefront with datatable in Destkop example
Browse files Browse the repository at this point in the history
  • Loading branch information
cjbrooks12 committed Sep 1, 2023
1 parent 67ba908 commit 7e60570
Show file tree
Hide file tree
Showing 33 changed files with 1,017 additions and 127 deletions.
21 changes: 17 additions & 4 deletions ballast-debugger-client/api/android/ballast-debugger-client.api
Original file line number Diff line number Diff line change
Expand Up @@ -11,15 +11,28 @@ public final class com/copperleaf/ballast/debugger/BallastDebuggerClientConnecti

public final class com/copperleaf/ballast/debugger/BallastDebuggerInterceptor : com/copperleaf/ballast/BallastInterceptor {
public static final field Companion Lcom/copperleaf/ballast/debugger/BallastDebuggerInterceptor$Companion;
public fun <init> (Lcom/copperleaf/ballast/debugger/BallastDebuggerClientConnection;Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function2;Lkotlin/jvm/functions/Function2;)V
public synthetic fun <init> (Lcom/copperleaf/ballast/debugger/BallastDebuggerClientConnection;Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function2;Lkotlin/jvm/functions/Function2;ILkotlin/jvm/internal/DefaultConstructorMarker;)V
public fun <init> (Lcom/copperleaf/ballast/debugger/BallastDebuggerClientConnection;Lcom/copperleaf/ballast/debugger/DebuggerAdapter;)V
public synthetic fun <init> (Lcom/copperleaf/ballast/debugger/BallastDebuggerClientConnection;Lcom/copperleaf/ballast/debugger/DebuggerAdapter;ILkotlin/jvm/internal/DefaultConstructorMarker;)V
public fun getKey ()Lcom/copperleaf/ballast/BallastInterceptor$Key;
public fun start (Lcom/copperleaf/ballast/BallastInterceptorScope;Lkotlinx/coroutines/flow/Flow;)V
public fun toString ()Ljava/lang/String;
}

public final class com/copperleaf/ballast/debugger/BallastDebuggerInterceptor$Companion {
public final fun withJson (Lcom/copperleaf/ballast/debugger/BallastDebuggerClientConnection;Lkotlinx/serialization/KSerializer;Lkotlinx/serialization/KSerializer;Lkotlinx/serialization/KSerializer;)Lcom/copperleaf/ballast/debugger/BallastDebuggerInterceptor;
public static synthetic fun withJson$default (Lcom/copperleaf/ballast/debugger/BallastDebuggerInterceptor$Companion;Lcom/copperleaf/ballast/debugger/BallastDebuggerClientConnection;Lkotlinx/serialization/KSerializer;Lkotlinx/serialization/KSerializer;Lkotlinx/serialization/KSerializer;ILjava/lang/Object;)Lcom/copperleaf/ballast/debugger/BallastDebuggerInterceptor;
public final fun invoke (Lcom/copperleaf/ballast/debugger/BallastDebuggerClientConnection;Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function1;)Lcom/copperleaf/ballast/debugger/BallastDebuggerInterceptor;
public final fun invoke (Lcom/copperleaf/ballast/debugger/BallastDebuggerClientConnection;Lkotlinx/serialization/KSerializer;Lkotlinx/serialization/KSerializer;Lkotlinx/serialization/KSerializer;Lkotlinx/serialization/json/Json;)Lcom/copperleaf/ballast/debugger/BallastDebuggerInterceptor;
public static synthetic fun invoke$default (Lcom/copperleaf/ballast/debugger/BallastDebuggerInterceptor$Companion;Lcom/copperleaf/ballast/debugger/BallastDebuggerClientConnection;Lkotlinx/serialization/KSerializer;Lkotlinx/serialization/KSerializer;Lkotlinx/serialization/KSerializer;Lkotlinx/serialization/json/Json;ILjava/lang/Object;)Lcom/copperleaf/ballast/debugger/BallastDebuggerInterceptor;
}

public final class com/copperleaf/ballast/debugger/JsonDebuggerAdapter : com/copperleaf/ballast/debugger/DebuggerAdapter {
public fun <init> ()V
public fun <init> (Lkotlinx/serialization/KSerializer;Lkotlinx/serialization/KSerializer;Lkotlinx/serialization/KSerializer;Lkotlinx/serialization/json/Json;)V
public synthetic fun <init> (Lkotlinx/serialization/KSerializer;Lkotlinx/serialization/KSerializer;Lkotlinx/serialization/KSerializer;Lkotlinx/serialization/json/Json;ILkotlin/jvm/internal/DefaultConstructorMarker;)V
public fun deserializeInput (Lio/ktor/http/ContentType;Ljava/lang/String;)Ljava/lang/Object;
public fun deserializeState (Lio/ktor/http/ContentType;Ljava/lang/String;)Ljava/lang/Object;
public fun serializeEvent (Ljava/lang/Object;)Lkotlin/Pair;
public fun serializeInput (Ljava/lang/Object;)Lkotlin/Pair;
public fun serializeState (Ljava/lang/Object;)Lkotlin/Pair;
public fun toString ()Ljava/lang/String;
}

21 changes: 17 additions & 4 deletions ballast-debugger-client/api/jvm/ballast-debugger-client.api
Original file line number Diff line number Diff line change
Expand Up @@ -11,15 +11,28 @@ public final class com/copperleaf/ballast/debugger/BallastDebuggerClientConnecti

public final class com/copperleaf/ballast/debugger/BallastDebuggerInterceptor : com/copperleaf/ballast/BallastInterceptor {
public static final field Companion Lcom/copperleaf/ballast/debugger/BallastDebuggerInterceptor$Companion;
public fun <init> (Lcom/copperleaf/ballast/debugger/BallastDebuggerClientConnection;Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function2;Lkotlin/jvm/functions/Function2;)V
public synthetic fun <init> (Lcom/copperleaf/ballast/debugger/BallastDebuggerClientConnection;Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function2;Lkotlin/jvm/functions/Function2;ILkotlin/jvm/internal/DefaultConstructorMarker;)V
public fun <init> (Lcom/copperleaf/ballast/debugger/BallastDebuggerClientConnection;Lcom/copperleaf/ballast/debugger/DebuggerAdapter;)V
public synthetic fun <init> (Lcom/copperleaf/ballast/debugger/BallastDebuggerClientConnection;Lcom/copperleaf/ballast/debugger/DebuggerAdapter;ILkotlin/jvm/internal/DefaultConstructorMarker;)V
public fun getKey ()Lcom/copperleaf/ballast/BallastInterceptor$Key;
public fun start (Lcom/copperleaf/ballast/BallastInterceptorScope;Lkotlinx/coroutines/flow/Flow;)V
public fun toString ()Ljava/lang/String;
}

public final class com/copperleaf/ballast/debugger/BallastDebuggerInterceptor$Companion {
public final fun withJson (Lcom/copperleaf/ballast/debugger/BallastDebuggerClientConnection;Lkotlinx/serialization/KSerializer;Lkotlinx/serialization/KSerializer;Lkotlinx/serialization/KSerializer;)Lcom/copperleaf/ballast/debugger/BallastDebuggerInterceptor;
public static synthetic fun withJson$default (Lcom/copperleaf/ballast/debugger/BallastDebuggerInterceptor$Companion;Lcom/copperleaf/ballast/debugger/BallastDebuggerClientConnection;Lkotlinx/serialization/KSerializer;Lkotlinx/serialization/KSerializer;Lkotlinx/serialization/KSerializer;ILjava/lang/Object;)Lcom/copperleaf/ballast/debugger/BallastDebuggerInterceptor;
public final fun invoke (Lcom/copperleaf/ballast/debugger/BallastDebuggerClientConnection;Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function1;)Lcom/copperleaf/ballast/debugger/BallastDebuggerInterceptor;
public final fun invoke (Lcom/copperleaf/ballast/debugger/BallastDebuggerClientConnection;Lkotlinx/serialization/KSerializer;Lkotlinx/serialization/KSerializer;Lkotlinx/serialization/KSerializer;Lkotlinx/serialization/json/Json;)Lcom/copperleaf/ballast/debugger/BallastDebuggerInterceptor;
public static synthetic fun invoke$default (Lcom/copperleaf/ballast/debugger/BallastDebuggerInterceptor$Companion;Lcom/copperleaf/ballast/debugger/BallastDebuggerClientConnection;Lkotlinx/serialization/KSerializer;Lkotlinx/serialization/KSerializer;Lkotlinx/serialization/KSerializer;Lkotlinx/serialization/json/Json;ILjava/lang/Object;)Lcom/copperleaf/ballast/debugger/BallastDebuggerInterceptor;
}

public final class com/copperleaf/ballast/debugger/JsonDebuggerAdapter : com/copperleaf/ballast/debugger/DebuggerAdapter {
public fun <init> ()V
public fun <init> (Lkotlinx/serialization/KSerializer;Lkotlinx/serialization/KSerializer;Lkotlinx/serialization/KSerializer;Lkotlinx/serialization/json/Json;)V
public synthetic fun <init> (Lkotlinx/serialization/KSerializer;Lkotlinx/serialization/KSerializer;Lkotlinx/serialization/KSerializer;Lkotlinx/serialization/json/Json;ILkotlin/jvm/internal/DefaultConstructorMarker;)V
public fun deserializeInput (Lio/ktor/http/ContentType;Ljava/lang/String;)Ljava/lang/Object;
public fun deserializeState (Lio/ktor/http/ContentType;Ljava/lang/String;)Ljava/lang/Object;
public fun serializeEvent (Ljava/lang/Object;)Lkotlin/Pair;
public fun serializeInput (Ljava/lang/Object;)Lkotlin/Pair;
public fun serializeState (Ljava/lang/Object;)Lkotlin/Pair;
public fun toString ()Ljava/lang/String;
}

2 changes: 1 addition & 1 deletion ballast-debugger-client/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ kotlin {
val commonMain by getting {
dependencies {
implementation(project(":ballast-api"))
implementation(project(":ballast-debugger-models"))
api(project(":ballast-debugger-models"))

implementation(libs.bundles.ktorClient)
implementation(libs.kotlinx.datetime)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -388,21 +388,20 @@ public class BallastDebuggerClientConnection<out T : HttpClientEngineConfig>(
}

is BallastDebuggerActionV4.RequestReplaceState -> {
if (viewModelConnection.deserializeState == null) {
logger.info("States cannot be replaced from serialized state.")
return
}

val stateToReplaceResult = runCatching {
viewModelConnection.deserializeState!!(
viewModelConnection.adapter.deserializeState(
ContentType.parse(action.stateContentType),
action.serializedState,
)
}

stateToReplaceResult.fold(
onSuccess = { state ->
sendToQueue(Queued.RestoreState(null, state))
if (state != null) {
sendToQueue(Queued.RestoreState(null, state))
} else {
logger.info("This ViewModel is not configured to replace States from serialized state.")
}
},
onFailure = { error ->
logger.info("Serialized state is formatted incorrectly")
Expand All @@ -420,25 +419,25 @@ public class BallastDebuggerClientConnection<out T : HttpClientEngineConfig>(
if (inputToResend != null) {
sendToQueue(Queued.HandleInput(null, inputToResend))
} else {
logger.info("Could not find requested Input to resend.")
}
}

is BallastDebuggerActionV4.RequestSendInput -> {
if (viewModelConnection.deserializeInput == null) {
logger.info("Inputs cannot be replaced from serialized state.")
return
}

val inputToSendResult = runCatching {
viewModelConnection.deserializeInput!!(
viewModelConnection.adapter.deserializeInput(
ContentType.parse(action.inputContentType),
action.serializedInput,
)
}

inputToSendResult.fold(
onSuccess = { input ->
sendToQueue(Queued.HandleInput(null, input))
if (input != null) {
sendToQueue(Queued.HandleInput(null, input))
} else {
logger.info("This ViewModel is not configured to send serialized Inputs.")
}
},
onFailure = { error ->
logger.info("Serialized input is formatted incorrectly")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,7 @@ import kotlinx.serialization.json.Json

public class BallastDebuggerInterceptor<Inputs : Any, Events : Any, State : Any>(
private val connection: BallastDebuggerClientConnection<*>,
private val serializeInput: (Inputs) -> Pair<ContentType, String> = { ContentType.Text.Any to it.toString() },
private val serializeEvent: (Events) -> Pair<ContentType, String> = { ContentType.Text.Any to it.toString() },
private val serializeState: (State) -> Pair<ContentType, String> = { ContentType.Text.Any to it.toString() },
private val deserializeState: ((ContentType, String) -> State)? = null,
private val deserializeInput: ((ContentType, String) -> Inputs)? = null,
private val adapter: DebuggerAdapter<Inputs, Events, State> = ToStringDebuggerAdapter(),
) : BallastInterceptor<Inputs, Events, State> {

override fun BallastInterceptorScope<Inputs, Events, State>.start(notifications: Flow<BallastNotification<Inputs, Events, State>>) {
Expand All @@ -23,11 +19,7 @@ public class BallastDebuggerInterceptor<Inputs : Any, Events : Any, State : Any>
BallastDebuggerViewModelConnection(
notifications = notifications,
viewModelName = hostViewModelName,
serializeInput = serializeInput,
serializeEvent = serializeEvent,
serializeState = serializeState,
deserializeState = deserializeState,
deserializeInput = deserializeInput,
adapter = adapter,
)
)
}
Expand All @@ -38,47 +30,38 @@ public class BallastDebuggerInterceptor<Inputs : Any, Events : Any, State : Any>
}

public companion object {
public fun <Inputs : Any, Events : Any, State : Any> withJson(

public operator fun <Inputs : Any, Events : Any, State : Any> invoke(
connection: BallastDebuggerClientConnection<*>,
serializeInput: (Inputs) -> Pair<ContentType, String>,
serializeEvent: (Events) -> Pair<ContentType, String>,
serializeState: (State) -> Pair<ContentType, String>,
): BallastDebuggerInterceptor<Inputs, Events, State> {
return BallastDebuggerInterceptor(
connection,
LambdaDebuggerAdapter(
serializeInput = serializeInput,
serializeEvent = serializeEvent,
serializeState = serializeState,
)
)
}

public operator fun <Inputs : Any, Events : Any, State : Any> invoke(
connection: BallastDebuggerClientConnection<*>,
stateSerializer: KSerializer<State>? = null,
inputsSerializer: KSerializer<Inputs>? = null,
eventsSerializer: KSerializer<Events>? = null,
stateSerializer: KSerializer<State>? = null,
json: Json = Json,
): BallastDebuggerInterceptor<Inputs, Events, State> {
val json = ContentType.Application.Json
val plainText = ContentType.Text.Any
return BallastDebuggerInterceptor(
connection,
serializeInput = if (inputsSerializer != null) {
{ input -> json to Json.encodeToString(inputsSerializer, input) }
} else {
{ input -> plainText to input.toString() }
},
serializeEvent = if (eventsSerializer != null) {
{ event -> json to Json.encodeToString(eventsSerializer, event) }
} else {
{ event -> plainText to event.toString() }
},
serializeState = if (stateSerializer != null) {
{ state -> json to Json.encodeToString(stateSerializer, state) }
} else {
{ state -> plainText to state.toString() }
},
deserializeInput = if (inputsSerializer != null) {
{ contentType: ContentType, serializedInput: String ->
check(contentType == json)
Json.decodeFromString(inputsSerializer, serializedInput)
}
} else {
null
},
deserializeState = if (stateSerializer != null) {
{ contentType: ContentType, serializedState: String ->
check(contentType == json)
Json.decodeFromString(stateSerializer, serializedState)
}
} else {
null
},
JsonDebuggerAdapter(
inputsSerializer = inputsSerializer,
eventsSerializer = eventsSerializer,
stateSerializer = stateSerializer,
json = json,
)
)
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
package com.copperleaf.ballast.debugger

import io.ktor.http.ContentType
import kotlinx.serialization.KSerializer
import kotlinx.serialization.json.Json

public class JsonDebuggerAdapter<Inputs : Any, Events : Any, State : Any>(
private val inputsSerializer: KSerializer<Inputs>? = null,
private val eventsSerializer: KSerializer<Events>? = null,
private val stateSerializer: KSerializer<State>? = null,
private val json: Json = Json,
) : DebuggerAdapter<Inputs, Events, State> {
override fun serializeInput(input: Inputs): Pair<ContentType, String> {
return if (inputsSerializer != null) {
ContentType.Application.Json to json.encodeToString(inputsSerializer, input)
} else {
ContentType.Text.Any to input.toString()
}
}

override fun serializeEvent(event: Events): Pair<ContentType, String> {
return if (eventsSerializer != null) {
ContentType.Application.Json to json.encodeToString(eventsSerializer, event)
} else {
ContentType.Text.Any to event.toString()
}
}

override fun serializeState(state: State): Pair<ContentType, String> {
return if (stateSerializer != null) {
ContentType.Application.Json to json.encodeToString(stateSerializer, state)
} else {
ContentType.Text.Any to state.toString()
}
}

override fun deserializeInput(contentType: ContentType, serializedInput: String): Inputs? {
return if (inputsSerializer != null) {
check(contentType == ContentType.Application.Json)
json.decodeFromString(inputsSerializer, serializedInput)
} else {
null
}
}

override fun deserializeState(contentType: ContentType, serializedState: String): State? {
return if (stateSerializer != null) {
check(contentType == ContentType.Application.Json)
json.decodeFromString(stateSerializer, serializedState)
} else {
null
}
}

override fun toString(): String {
return "JsonDebuggerAdapter"
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
package com.copperleaf.ballast.debugger

import io.ktor.http.ContentType

internal class LambdaDebuggerAdapter<Inputs : Any, Events : Any, State : Any>(
private val serializeInput: ((Inputs) -> Pair<ContentType, String>)?,
private val serializeEvent: ((Events) -> Pair<ContentType, String>)?,
private val serializeState: ((State) -> Pair<ContentType, String>)?,
) : DebuggerAdapter<Inputs, Events, State> {
override fun serializeInput(input: Inputs): Pair<ContentType, String> {
return serializeInput?.invoke(input)
?: (ContentType.Text.Any to input.toString())
}

override fun serializeEvent(event: Events): Pair<ContentType, String> {
return serializeEvent?.invoke(event)
?: (ContentType.Text.Any to event.toString())
}

override fun serializeState(state: State): Pair<ContentType, String> {
return serializeState?.invoke(state)
?: (ContentType.Text.Any to state.toString())
}

override fun deserializeInput(contentType: ContentType, serializedInput: String): Inputs? {
return null
}

override fun deserializeState(contentType: ContentType, serializedState: String): State? {
return null
}

override fun toString(): String {
return "LambdaDebuggerAdapter"
}
}
Loading

0 comments on commit 7e60570

Please sign in to comment.