diff --git a/README.md b/README.md index fd04d21..a4cab61 100644 --- a/README.md +++ b/README.md @@ -44,7 +44,7 @@ Add Scribe to your `commonMain` dependencies: kotlin { sourceSets { commonMain.dependencies { - implementation("com.rafambn:scribe:0.1.0") + implementation("com.rafambn:scribe:0.2.3") } } } diff --git a/docs/api-concepts.md b/docs/api-concepts.md index 54ce7d0..d2c970e 100644 --- a/docs/api-concepts.md +++ b/docs/api-concepts.md @@ -106,7 +106,6 @@ Note( ```kotlin SealedScroll( success = true, - errorMessage = null, data = mapOf( "scroll_id" to JsonPrimitive("checkout-42"), "gateway" to JsonPrimitive("stripe"), diff --git a/docs/getting-started.md b/docs/getting-started.md index f4bcc29..a21c9c9 100644 --- a/docs/getting-started.md +++ b/docs/getting-started.md @@ -8,7 +8,7 @@ Use the library from shared code in your Kotlin Multiplatform module: kotlin { sourceSets { commonMain.dependencies { - implementation("com.rafambn:scribe:0.1.0") + implementation("com.rafambn:scribe:0.2.3") } } } @@ -78,7 +78,6 @@ The emitted `SealedScroll` shape: ```json { "success": true, - "errorMessage": null, "data": { "scroll_id": "checkout-42", "gateway": "stripe", diff --git a/docs/openobserve-showcase.md b/docs/openobserve-showcase.md index 9565e0e..8762c45 100644 --- a/docs/openobserve-showcase.md +++ b/docs/openobserve-showcase.md @@ -10,7 +10,7 @@ The app covers the current public runtime features of Scribe: - `newScroll(...)` with generated and custom IDs - direct `Scroll` map writes (`scroll["field"] = ...`) - map read/remove operations -- `seal(...)` with success and error outcomes +- `seal(...)` with success and failure outcomes - `Margin` - `EntrySaver` - channel overflow behavior via `Channel(..., onBufferOverflow = DROP_OLDEST)` @@ -31,7 +31,7 @@ That stream intentionally allows sparse fields. Every uploaded record includes: - `saver_type` Notes then contribute fields such as `tag`, `message`, `level`, and `note_timestamp`. -Scrolls contribute `scroll_id`, `success`, `error_message`, and fields from `SealedScroll.data`. +Scrolls contribute `scroll_id`, `success`, and fields from `SealedScroll.data`. The single-stream design makes it easy to search everything in one place while still filtering by `event_kind`. @@ -76,7 +76,7 @@ or: 1. Run `Checkout flow` and inspect the wide-event payload in `scribe_demo`. 2. Run `Map read/remove` to inspect map mutation behavior before sealing. -3. Run `Margins + seal(error)` and verify timing fields plus `success = false`. +3. Run `Margins + seal(failure)` and verify timing fields plus `success = false`. 4. Run `JSON object serialization` to validate nested payload fields in OpenObserve. 5. Run `String template message` to inspect message rendering in the `message` field. 6. Run `EntrySaver mixed flow` to send a note and a scroll through one saver path. diff --git a/scribe/build.gradle.kts b/scribe/build.gradle.kts index c181172..1fe29fb 100644 --- a/scribe/build.gradle.kts +++ b/scribe/build.gradle.kts @@ -11,7 +11,7 @@ plugins { } group = "com.rafambn" -version = "0.2.2" +version = "0.2.3" kotlin { jvm { diff --git a/scribe/src/commonMain/kotlin/com/rafambn/scribe/Events.kt b/scribe/src/commonMain/kotlin/com/rafambn/scribe/Events.kt index 272b282..0bb79b4 100644 --- a/scribe/src/commonMain/kotlin/com/rafambn/scribe/Events.kt +++ b/scribe/src/commonMain/kotlin/com/rafambn/scribe/Events.kt @@ -14,7 +14,6 @@ sealed interface Entry @Serializable data class SealedScroll( val success: Boolean, - val errorMessage: String?, val data: Map, ): Entry diff --git a/scribe/src/commonMain/kotlin/com/rafambn/scribe/Scroll.kt b/scribe/src/commonMain/kotlin/com/rafambn/scribe/Scroll.kt index 8a1b805..8907f6c 100644 --- a/scribe/src/commonMain/kotlin/com/rafambn/scribe/Scroll.kt +++ b/scribe/src/commonMain/kotlin/com/rafambn/scribe/Scroll.kt @@ -18,13 +18,9 @@ val Scroll.id: String /** * Seals this scroll and suspends until its [SealedScroll] is enqueued. */ -suspend fun Scroll.seal(success: Boolean = true, error: Throwable? = null): SealedScroll { +suspend fun Scroll.seal(success: Boolean = true): SealedScroll { Scribe.config?.margins?.footer(this) - val result = SealedScroll( - success = success, - errorMessage = error?.message, - data = this, - ) + val result = SealedScroll(success = success, data = this) Scribe.enqueue(result) return result } diff --git a/scribe/src/commonTest/kotlin/com/rafambn/scribe/ScribeConcurrencyAndScrollTest.kt b/scribe/src/commonTest/kotlin/com/rafambn/scribe/ScribeConcurrencyAndScrollTest.kt index b1962ff..b2c2a6c 100644 --- a/scribe/src/commonTest/kotlin/com/rafambn/scribe/ScribeConcurrencyAndScrollTest.kt +++ b/scribe/src/commonTest/kotlin/com/rafambn/scribe/ScribeConcurrencyAndScrollTest.kt @@ -43,18 +43,16 @@ class ScribeConcurrencyAndScrollTest { val scroll = scribe.newScroll(id = "scroll-id") scroll["state"] = JsonPrimitive("initial") - val first = scroll.seal(success = false, error = IllegalStateException("first")) - val second = scroll.seal(success = true, error = null) + val first = scroll.seal(success = false) + val second = scroll.seal(success = true) shelf.awaitEvents(2) scribe.retire() assertEquals(false, first.success) - assertEquals("first", first.errorMessage) assertEquals(JsonPrimitive("initial"), first.data["state"]) // Current behavior emits one SealedScroll per seal call. assertEquals(true, second.success) - assertEquals(null, second.errorMessage) assertEquals(JsonPrimitive("initial"), second.data["state"]) assertEquals(2, shelf.events.size) } diff --git a/scribe/src/commonTest/kotlin/com/rafambn/scribe/ScribeScrollLifecycleTest.kt b/scribe/src/commonTest/kotlin/com/rafambn/scribe/ScribeScrollLifecycleTest.kt index 2703b86..16b832d 100644 --- a/scribe/src/commonTest/kotlin/com/rafambn/scribe/ScribeScrollLifecycleTest.kt +++ b/scribe/src/commonTest/kotlin/com/rafambn/scribe/ScribeScrollLifecycleTest.kt @@ -36,14 +36,13 @@ class ScribeScrollLifecycleTest { scroll["gateway"] = JsonPrimitive("stripe") - scroll.seal(success = false, error = IllegalStateException("fail")) + scroll.seal(success = false) scroll.seal(success = true) shelf.awaitEvents(2) scribe.retire() val firstEvent = shelf.events.first() val secondEvent = shelf.events.last() assertFalse(firstEvent.success) - assertEquals("fail", firstEvent.errorMessage) assertTrue(secondEvent.success) assertEquals(JsonPrimitive("stripe"), firstEvent.data["gateway"]) } @@ -75,7 +74,6 @@ class ScribeScrollLifecycleTest { assertNotNull(failureEvent) assertTrue(successEvent.success) assertFalse(failureEvent.success) - assertEquals("order2 failed", failureEvent.errorMessage) } } diff --git a/scribe/src/commonTest/kotlin/com/rafambn/scribe/ScribeTestFixtures.kt b/scribe/src/commonTest/kotlin/com/rafambn/scribe/ScribeTestFixtures.kt index 33bdb68..ccffe3e 100644 --- a/scribe/src/commonTest/kotlin/com/rafambn/scribe/ScribeTestFixtures.kt +++ b/scribe/src/commonTest/kotlin/com/rafambn/scribe/ScribeTestFixtures.kt @@ -105,7 +105,7 @@ internal class PaymentService { scroll["gateway"] = JsonPrimitive("stripe") } catch (t: Throwable) { scroll["error_stage"] = JsonPrimitive("gateway_call") - scroll.seal(success = false, error = t) + scroll.seal(success = false) throw t } } diff --git a/testApp/README.md b/testApp/README.md index 3421ebf..9967d03 100644 --- a/testApp/README.md +++ b/testApp/README.md @@ -76,7 +76,7 @@ The UI contains grouped demo actions: - `Run second note(...)` - `Checkout flow` - `Map read/remove` -- `Margins + seal(error)` +- `Margins + seal(failure)` - `JSON object serialization` - `String template message` - `EntrySaver mixed flow` diff --git a/testApp/shared/module.yaml b/testApp/shared/module.yaml index eec0ac1..77c0860 100644 --- a/testApp/shared/module.yaml +++ b/testApp/shared/module.yaml @@ -8,7 +8,7 @@ apply: dependencies: - $compose.foundation: exported - $compose.material3: exported - - com.rafambn:scribe:0.1.0 + - com.rafambn:scribe:0.2.3 - org.jetbrains.kotlinx:kotlinx-datetime:0.7.1 settings: diff --git a/testApp/shared/src/Screen.kt b/testApp/shared/src/Screen.kt index 195cdf3..5934dd3 100644 --- a/testApp/shared/src/Screen.kt +++ b/testApp/shared/src/Screen.kt @@ -81,7 +81,7 @@ fun Screen() { buttons = listOf( "Checkout flow" to controller::runCheckoutScenario, "Map read/remove" to controller::runInspectionScenario, - "Margins + seal(error)" to controller::runMarginScenario, + "Margins + seal(failure)" to controller::runMarginScenario, ), enabled = !state.isBusy, ) diff --git a/testApp/shared/src/ShowcaseController.kt b/testApp/shared/src/ShowcaseController.kt index 4b9bdcf..deee67f 100644 --- a/testApp/shared/src/ShowcaseController.kt +++ b/testApp/shared/src/ShowcaseController.kt @@ -177,20 +177,20 @@ class ShowcaseController { updateStatus("Ran custom-id scroll demo with map reads/removals and local active-scroll tracking.") } - fun runMarginScenario() = launchScenario("Margin + seal(error) demo") { + fun runMarginScenario() = launchScenario("Margin + seal(failure) demo") { val scribe = activeMainScribe("margin_scroll") ?: return@launchScenario val scroll = openScroll(scribe, id = "inventory-sync-1") scroll["demo_name"] = JsonPrimitive("margin_scroll") scroll["flow"] = JsonPrimitive("inventory-sync") scroll["warehouse"] = JsonPrimitive("gru-1") scroll["cache_hit"] = JsonPrimitive(false) + scroll["failure_reason"] = JsonPrimitive("downstream retry scheduled") sealScroll( scroll, success = false, - error = IllegalStateException("downstream retry scheduled"), ) delay(250) - updateStatus("Ran Margin header/footer hooks with seal(success = false, error = ...).") + updateStatus("Ran Margin header/footer hooks with seal(success = false).") } fun runJsonSerializationScenario() = launchScenario("JSON serialization scroll demo") { @@ -535,8 +535,8 @@ class ShowcaseController { return scroll } - private suspend fun sealScroll(scroll: Scroll, success: Boolean, error: Throwable? = null) { - scroll.seal(success = success, error = error) + private suspend fun sealScroll(scroll: Scroll, success: Boolean) { + scroll.seal(success = success) activeScrolls.remove(scroll.id) refreshActiveScrolls() } diff --git a/testApp/shared/src/ShowcaseModels.kt b/testApp/shared/src/ShowcaseModels.kt index 9730945..05683fb 100644 --- a/testApp/shared/src/ShowcaseModels.kt +++ b/testApp/shared/src/ShowcaseModels.kt @@ -95,7 +95,6 @@ fun payloadFromEntry( payload["saver_type"] = JsonPrimitive(saverType) payload["scroll_id"] = JsonPrimitive(stringField(entry.data, "scroll_id") ?: "missing-scroll-id") payload["success"] = JsonPrimitive(entry.success) - entry.errorMessage?.let { payload["error_message"] = JsonPrimitive(it) } stringField(entry.data, "message")?.let { payload["message"] = JsonPrimitive(it) } entry.data["order_id"]?.let { payload["order_id"] = it } ?: entry.data["ordemId"]?.let { payload["order_id"] = it }