CLOVIS
01/07/2023, 4:18 PMsuspend fun getAge(user: UserId): Outcome<Int> = out {
// require/check-inspired methods to declare failure causes…
ensureAuthenticated(userService.current() == user) { "You cannot get the age of another user" }
// …which can be caught at a previous layer to transform into HTTP status codes
user.get().age
}
Progression reporting
Pedestal adds the ability to report progression events in any coroutine directly through the CoroutineContext:
suspend fun getAge(user: UserId) = out {
ensureAuthenticated(userService.current() == user) { … }
report(loading(0.25)) // 25%
return user.get()
.also { report(loading(0.8)) } // 80%
.age
}
The progress events can be added gradually after the API is already written without breaking changes, as functions too slow are discovered. It is easy for the caller to access reporting events, for example with Compose :
@Composable
fun Age(user: UserId) {
val progress by remember { mutableStateOf<Progression>(Progression.done()) }
var age by remember { mutableStateOf<Int?>(null) }
LaunchedEffect(user) {
callbackReporter({ progress = it }) { // extract loading events into the State instance
report(loading(0.0))
age = getAge(user)
report(done())
}
}
}
Extended example: https://opensavvy.gitlab.io/pedestal/documentation/state/index.html
Aggressive caching
By writing your API such that objects are always referred by ID, it is possible to aggressively cache all read requests, centralizing write requests. This way, it becomes easier to write applications that are more automatically more performant! For example, with Compose:
@Composable
fun Age(ref: UserRef) {
// Dereference the Ref through the cache
// You don't have to worry if another component in the same page has already made the query!
val user by remember(ref) { ref.request().collectAsState() }
user.onSuccess {
Text("Age: ${it.age}")
}
// The cache is aware of failures
user.onFailure {
Text("Could not get the data for the requested user: $it")
Button({ ref.expire() }) { // will automatically update all occurrences of this value in the entire app
Text("Retry")
}
}
// The cache is aware of loading events
user.onLoading {
Text("Age: loading ${it.percent}")
}
}
All of this is implemented on top of #flow, so it can be used with any UI framework, not just Compose.
Extended example: https://opensavvy.gitlab.io/pedestal/documentation/backbone/index.html
Multiplatform
All modules are multiplatform (currently JVM + JS). Very few platform-specific code exists, making it easy to port to new platforms (if another platform seems interesting, please contribute :)). This allows for example to have the same error management in all parts of the application, or to use the same cache algorithm to cache API requests client-side than you use on your backend to cache database queries.
Experimental cross-platform API declaration
I'm exploring the possibility of declaring an entire REST API in the common module, to be able to typesafely refer to it in the other modules, empowering IntelliJ to make refactors throughout all sides of the API automatically.
https://gitlab.com/opensavvy/pedestalakuleshov7
01/07/2023, 11:11 PMyasyd
01/08/2023, 12:34 PMyasyd
01/08/2023, 12:34 PMYves Kalume
01/08/2023, 7:36 PMHalina
01/09/2023, 10:39 AMAlina Dolgikh [JB]
Big Chungus
01/11/2023, 1:25 AMktx
is basically an npx
for kotlin and java ecosystem. Run/install kotlin scripts or maven packages like any other cli utility.
Highlights Include:
• sdkman.io debut! Getting ktx on your machine is now as simple as sdk install ktx
• maven packages execution/installation support
ktx install org.jetbrains.kotlin:kotlin-compiler:1.8.0 --alias=kt
kt -- -version
jaguililla
01/11/2023, 10:33 AMPeter
01/11/2023, 11:36 AMViktor Sirotin
01/12/2023, 7:07 AMLukas Lechner
01/13/2023, 11:13 AMwrongwrong
01/14/2023, 4:07 PMjackson-module-kogera
as a prototype project for jackson-module-kotlin
, which is lightweight and high performance.
I replaced kotlin-reflect
in jackson-module-kotlin
with kotlinx.metadata.jvm
to make it lightweight.
It is also up to 3 times faster by optimizing the deserialization process.
If you are interested, please try it out, and star and bug reports are welcome.
https://github.com/ProjectMapK/jackson-module-kogerasdeleuze
01/14/2023, 5:10 PMrusshwolf
01/15/2023, 3:23 AMToshihiro Nakamura
01/15/2023, 4:42 AMÖmer Faruk Delibaş
01/15/2023, 6:07 PMMichal Fudala
01/17/2023, 8:42 AMPeter
01/17/2023, 9:36 AMclass SimpleMovingAverageStrategy {
private val period = 14
private val sma = SimpleMovingAverage()
fun calculateSignal(prices: List<Double>): String {
sma.setPeriod(period)
sma.setValues(prices.toDoubleArray())
val currentSMA = sma.getMean()
return if (prices.last() > currentSMA) {
"BUY"
} else {
"SELL"
}
}
}
Vitaliy Zarubin
01/17/2023, 4:19 PMDamien O'Hara
01/18/2023, 7:24 AMHalina
01/18/2023, 12:32 PMAnand Verma
01/19/2023, 6:29 AMPiotr Krzemiński
01/20/2023, 1:25 PMAnand Verma
01/21/2023, 8:39 AMFoso
01/21/2023, 1:27 PMJolan Rensen [JB]
01/21/2023, 3:31 PM@include
tag to include other comments into your KDoc / JavaDoc, see @include Processor (INCLUDE_DOC_PROCESSOR
)
• @sample
/ @sampleNoComments
tag to include code samples into your KDoc / JavaDoc (SAMPLE_DOC_PROCESSOR
)
• A processor that removes all KDoc / JavaDoc comments (NO_DOC_PROCESSOR
)
• A processor that adds a /** TODO */
comment wherever there is no KDoc / JavaDoc comment (TODO_DOC_PROCESSOR
)
• A processor that makes all KDoc / JavaDoc comments uppercase (try and make this for fun!)
• The sky is the limit :)
Note that this first release is still an early Alpha, but I'm welcome to feedback, bugs, your own processors and whatnot :)