Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/inkapplications/regolith
🪨 General purpose application interfaces
https://github.com/inkapplications/regolith
kotlin kotlin-multiplatform
Last synced: about 2 months ago
JSON representation
🪨 General purpose application interfaces
- Host: GitHub
- URL: https://github.com/inkapplications/regolith
- Owner: InkApplications
- License: mit
- Created: 2023-06-12T22:21:38.000Z (over 1 year ago)
- Default Branch: master
- Last Pushed: 2024-08-17T01:35:38.000Z (5 months ago)
- Last Synced: 2024-08-17T02:41:43.295Z (5 months ago)
- Topics: kotlin, kotlin-multiplatform
- Language: Kotlin
- Homepage:
- Size: 315 KB
- Stars: 1
- Watchers: 3
- Forks: 1
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- Changelog: CHANGELOG.md
- License: LICENSE
Awesome Lists containing this project
README
Regolith
========A collection of generalized application system components that can be used
in mobile, desktop and web applications to create reusable functionality
across platforms.Modules
=======Regolith is broken up into distinct modules that can be used independently.
Each module provides different abstractions on system components common
in applications.Init Module
-----------Initializers are the start of your application. They can be used to configure
libraries, or start services.### Maven Coordinates
com.inkapplications.regolith:init
### Create an Initializer
The interface for an Initializer has a single-method that is called when
the application starts:```kotlin
object DatabaseInitializer: Initializer {
override fun initialize(targetManager: TargetManager) {
Database.init()
}
}
```Initializers are then added to an `InitRunner` to be started immediately
when `initialize()` is called:```kotlin
fun main() {
val myInitializers = listOf(DatabaseInitializer)
RegolithInitRunner(
initializers = myInitializers
).initialize()
}
```### Initialization Targets
All initializers are started *immediately* on application start. However,
Targets may be used to wait for initializers or to pass data between
initializers.To create a target, extend the empty `InitTarget` interface:
```kotlin
object DatabaseInitTarget: InitTarget
```If your initializer provides data that may be needed by other initializers,
it can be passed through the Target as data in the Target object:```kotlin
data class DatabaseInitTarget(
val session: DatabaseSession
)
```Targets can be emitted by any initializer through
`targetManager.postTarget()` provided in the `initialize` call:```kotlin
object DatabaseInitializer: Initializer {
override fun initialize(targetManager: TargetManager) {
val session = Database.init()
targetManager.postTarget(DatabaseInitTarget(session))
}
}
```You can wait for a Target with the `targetManager.awaitTarget()` method:
```kotlin
class TokenRefreshInitializer(
val api: MyApi
): Initializer {
override fun initialize(targetManager: TargetManager) {
// Wait for DatabaseInitTarget and use its provided session data:
val session = targetManager.awaitTarget(DatabaseInitTarget)
session.updateToken(api.fetchToken())
}
}
```Targets can also be posted to the manager via the `RegolithInitRunner`.
For example, an Android application may use this mechanism to provide
the application instance as a target:```kotlin
data class ApplicationTarget(
val application: Application
)class MyApplication: Application() {
private val initializers = listOf(DatabaseInitializer)
private val initRunner = RegolithInitRunner(
initializers = myInitializers
)
override fun onCreate() {
initRunner.initialize()
initRunner.postTarget(ApplicationTarget(this))
}
}
```Processes
---------The processes module provices abstractions on long-running components of
your application### Maven coordinates
com.inkapplications.regolith:processes
### Daemons
Daemons are similar to initializers, except that they are intended to
never stop running. While initializers may not suspend and must return
for initialization to complete, Daemons *cannot* be completed.To create a Daemon, implement the `Daemon` interface:
```
class WebServerDaemon(
private val server: WebServer
): Daemon {
suspend fun startDaemon(): Nothing {
server.start()
throw IllegalStateException("Server exited unexpectedly")
}
}
```Daemons can be started with the `DaemonInitializer` which can be run
as a part of the `init` component:```kotlin
fun main() {
val daemonInitializer = DaemonInitializer(
daemons = listOf(webServerDaemon)
)
val myInitializers = listOf(daemonInitializer)RegolithInitRunner(
initializers = myInitializers
).initialize()
}
```### Crons
Crons are similar to Daemons, except that they are expected to run and
complete on a predetermined time schedule.Crons can be created by implementing the `CronJob` interface:
```kotlin
class DatabaseFlushCron(
private val database: Database
): CronJob {
override val schedule = Schedule().withMinutes { it % 10 } // Every 10 minutes
suspend fun runCron(time: LocalDateTime, zone: TimeZone) {
database.flush()
}
}
```Crons can be run automatically by using the `CoroutineCronDaemon`:
```kotlin
fun main() {
val cronDaemon = CoroutineCronDaemon(
jobs = DatabaseFlushCron(myDatabase),
)
val daemonInitializer = DaemonInitializer(
daemons = listOf(webServerDaemon, cronDaemon)
)
val myInitializers = listOf(daemonInitializer)RegolithInitRunner(
initializers = myInitializers
).initialize()
}
```Resources
---------The resources module provides abstractions around application resources like
files and strings.### Maven coordinates
com.inkapplications.regolith:resources
### String Resources
The `StringResources` interface provides a way to load localized strings
in an application.Strings can be Identified either by string or integer, and supports parameter
formatting.Android has a default implementation to its internal string localization
loader via the `AndroidStringResources` class.### File Resources
The `FileResources` interface provides a way to load files from the
filesystem or the local application resources.Application packaged resources can be loaded with by name or ID with the
`FileResources.Local` id type. External files can be loaded by path or URI.Android has a default implementation via the `AndroidFileResources` class.
JVM has a default implementation via the `JvmFileResources` class.
### Testing
Testing implementations are provided in the `doubles` package, including:
`DummyResources`, `StubResources`, and `ParrotResources`.