
Abstracts external services into swappable implementations (databases, caches, files, email/SMS/push/pubsub), with built-in metrics, health checks, local-run helpers and Terraform generation.
Originally from our Lightning Server project, we've decided to separate the external service abstractions we've built such that others can use them.
You can use the abstractions here to make testing and running servers locally easier, as well as reduce your dependence on any one specific technology or deployment style.
All the services and their implementations have the following:
We've done our best to minimize the dependencies in the basis package.
Version 1.3 has breaking changes that improve the ergonomics and safety, and is in the process of release.
mongodb-file://file-path to automatically
download and run MongoDB on your machine and connect to it.fun main() {
val settingsFile = """
{
"port": 8941,
"host": "127.0.0.1",
"cache": "ram"
}
""".trimIndent()
val context = TestSettingContext()
val settings = Json.decodeFromString<MyServerSettings>(settingsFile)
runBlocking {
val cache = settings.cache("cache", context)
repeat(5) {
val currentValue = cache.get<Int>("counter")
cache.set("counter", (currentValue ?: 0) + 1)
}
}
}
@Serializable
data class MyServerSettings(
val port: Int = 8080,
val host: String = "0.0.0.0",
val cache: Cache.Settings = Cache.Settings(),
)TestSettingContext() is a zero-dependency SettingContext meant for exactly this kind of
local running/testing. See demo/ for a runnable version of this sample
plus one for every other subsystem (database, email, sms, files, pubsub, phonecall, speech,
subscription-payments, voiceagent, and more), each using a local/fake implementation so it
needs no credentials.
@Serializable
data class Post(
override val _id: UUID = UUID.random(),
val title: String,
val content: String,
val author: String,
val postedAt: Instant,
): HasId<UUID>
fun main(database: Database) {
val table = database.collection<Post>()
runBlocking {
val newPost = table.insertOne(Post(
title = "My test post",
content = "Here's a long story about my cat.",
author = "someone@email.com",
postedAt = Clock.System.now()
))!!
table.updateOneById(newPost._id, modification {
title assign "Cat Posting"
})
table.find(condition { it.author.eq("someone@gmail.com") }, sort { it.postedAt.ascending() })
.toList()
.forEach { println(it) }
}
}
@Serializable
data class MyServerSettings(
val port: Int = 8080,
val host: String = "0.0.0.0",
val cache: Cache.Settings = Cache.Settings(),
)Comprehensive user guides are available for all major modules:
Incomplete and in progress. You can use Lightning Server if you want access immediately.
Originally from our Lightning Server project, we've decided to separate the external service abstractions we've built such that others can use them.
You can use the abstractions here to make testing and running servers locally easier, as well as reduce your dependence on any one specific technology or deployment style.
All the services and their implementations have the following:
We've done our best to minimize the dependencies in the basis package.
Version 1.3 has breaking changes that improve the ergonomics and safety, and is in the process of release.
mongodb-file://file-path to automatically
download and run MongoDB on your machine and connect to it.fun main() {
val settingsFile = """
{
"port": 8941,
"host": "127.0.0.1",
"cache": "ram"
}
""".trimIndent()
val context = TestSettingContext()
val settings = Json.decodeFromString<MyServerSettings>(settingsFile)
runBlocking {
val cache = settings.cache("cache", context)
repeat(5) {
val currentValue = cache.get<Int>("counter")
cache.set("counter", (currentValue ?: 0) + 1)
}
}
}
@Serializable
data class MyServerSettings(
val port: Int = 8080,
val host: String = "0.0.0.0",
val cache: Cache.Settings = Cache.Settings(),
)TestSettingContext() is a zero-dependency SettingContext meant for exactly this kind of
local running/testing. See demo/ for a runnable version of this sample
plus one for every other subsystem (database, email, sms, files, pubsub, phonecall, speech,
subscription-payments, voiceagent, and more), each using a local/fake implementation so it
needs no credentials.
@Serializable
data class Post(
override val _id: UUID = UUID.random(),
val title: String,
val content: String,
val author: String,
val postedAt: Instant,
): HasId<UUID>
fun main(database: Database) {
val table = database.collection<Post>()
runBlocking {
val newPost = table.insertOne(Post(
title = "My test post",
content = "Here's a long story about my cat.",
author = "someone@email.com",
postedAt = Clock.System.now()
))!!
table.updateOneById(newPost._id, modification {
title assign "Cat Posting"
})
table.find(condition { it.author.eq("someone@gmail.com") }, sort { it.postedAt.ascending() })
.toList()
.forEach { println(it) }
}
}
@Serializable
data class MyServerSettings(
val port: Int = 8080,
val host: String = "0.0.0.0",
val cache: Cache.Settings = Cache.Settings(),
)Comprehensive user guides are available for all major modules:
Incomplete and in progress. You can use Lightning Server if you want access immediately.