Skip to content

Commit

Permalink
initial commit
Browse files Browse the repository at this point in the history
  • Loading branch information
makeevrserg committed Jul 21, 2023
1 parent 567a76c commit af9f366
Show file tree
Hide file tree
Showing 15 changed files with 493 additions and 0 deletions.
5 changes: 5 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
.gradle
.idea
build
kstorage/build
local.properties
74 changes: 74 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
[![version](https://img.shields.io/maven-central/v/ru.astrainteractive.klibs/kstorage?style=flat-square)](https://github.com/makeevrserg/kstorage)
[![kotlin_version](https://img.shields.io/badge/kotlin-1.9.0-blueviolet?style=flat-square)](https://github.com/makeevrserg/kstorage)

## KStorage

KStorage is super lightweight Kotlin Multiplatform Storage wrapper library

## Installation

Gradle

```kotlin
implementation("ru.astrainteractive.klibs:kstorage:<version>")
```

Version catalogs

```toml
[versions]
klibs-kstorage = "<latest-version>"

[libraries]
klibs-kstorage = { module = "ru.astrainteractive.klibs:kstorage", version.ref = "klibs-kstorage" }
```

See also [MobileX](https://github.com/makeevrserg/MobileX) as parent library for more useful kotlin
code

## Creating MutableStorageValue

```kotlin
class SettingsApi(private val settings: Settings) {
val mutableStorageValue = MutableStorageValue(
default = 0,
loadSettingsValue = {
settings["INT_KEY"]
},
saveSettingsValue = { value ->
settings["INT_KEY"] = value
}
)
}
```
## Creating Custom MutableStorageValue

```kotlin
class SettingsApi(private val settings: Settings) {
data class CustomClass(val customInt: Int)

class CustomClassStorageValue(
key: String,
default: CustomClass
) : MutableStorageValue<CustomClass> by MutableStorageValue(
default = default,
loadSettingsValue = {
settings[key]?.let(::CustomClass) ?: default
},
saveSettingsValue = { customClass ->
settings[key] = customClass.customInt
}
)

val customStorageValue = CustomClassStorageValue(key = "CUSTOM_KEY", default = CustomClass(100))
}
```

That's it! As easy as it looks

## Storage Components

- `StorageValue` - parent interface of all storage values
- `MutableStorageValue` - parent interface for mutable storage values
- `StateFlowMutableStorageValue` - coroutines StateFlow implementation of MutableStorageValue
- `InMemoryStateFlowMutableStorageValue` - this interface using in-memory storage
26 changes: 26 additions & 0 deletions build.gradle.kts
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
buildscript {
dependencies {
classpath(libs.makeevrserg.gradleplugin.convention)
classpath(libs.makeevrserg.gradleplugin.android)
}
}
plugins {
alias(libs.plugins.kotlin.multiplatform) apply false
alias(libs.plugins.gradle.android) apply false
}

apply(plugin = "ru.astrainteractive.gradleplugin.dokka.root")
apply(plugin = "ru.astrainteractive.gradleplugin.detekt")
apply(plugin = "ru.astrainteractive.gradleplugin.root.info")

subprojects.forEach {
it.apply(plugin = "ru.astrainteractive.gradleplugin.dokka.module")
it.apply(plugin = "ru.astrainteractive.gradleplugin.publication")
it.plugins.withId("org.jetbrains.kotlin.jvm") {
it.apply(plugin = "ru.astrainteractive.gradleplugin.java.core")
}
it.apply(plugin = "ru.astrainteractive.gradleplugin.stub.javadoc")
it.plugins.withId("com.android.library") {
it.apply(plugin = "ru.astrainteractive.gradleplugin.android.core")
}
}
33 changes: 33 additions & 0 deletions gradle.properties
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
#Gradle
org.gradle.jvmargs=-Xmx2048M -Dkotlin.daemon.jvm.options\="-Xmx2048M"
#Kotlin
kotlin.code.style=official
#Android
android.useAndroidX=true
#MPP
kotlin.mpp.enableCInteropCommonization=true
kotlin.mpp.androidSourceSetLayoutVersion=2
kotlin.js.compiler=ir
# Android
makeevrserg.android.sdk.min=21
makeevrserg.android.sdk.target=33
makeevrserg.android.sdk.compile=33
# Java
makeevrserg.java.source=8
makeevrserg.java.target=17
makeevrserg.java.ktarget=17
# Project
makeevrserg.project.name=KStorage
makeevrserg.project.group=ru.astrainteractive.klibs
makeevrserg.project.version.string=1.0.0
makeevrserg.project.description=Kotlin wrapper for key-value storage libraries
makeevrserg.project.developers=makeevrserg|Makeev Roman|makeevrserg@gmail.com
makeevrserg.project.url=https://github.com/makeevrserg/kstorage
# Publish
makeevrserg.publish.repo.name=KStorage
makeevrserg.publish.groupId=ru.astrainteractive.klibs
makeevrserg.publish.description=Kotlin wrapper for key-value storage libraries
makeevrserg.publish.repo.org=makeevrserg
makeevrserg.publish.name=KStorage
makeevrserg.publish.license=Apache-2.0
makeevrserg.publish.developers=makeevrserg|Makeev Roman|makeevrserg@gmail.com
13 changes: 13 additions & 0 deletions gradle/libs.versions.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
[versions]
# Kotlin
kotlin-version = "1.9.0"
kotlin-coroutines-core = "1.7.1"
makeevrserg-gradleplugin = "0.0.10"
gradle-android = "7.4.2"
[libraries]
kotlin-coroutines-core = { module = "org.jetbrains.kotlinx:kotlinx-coroutines-core", version.ref = "kotlin-coroutines-core" }
makeevrserg-gradleplugin-convention = { module = "ru.astrainteractive.gradleplugin:convention", version.ref = "makeevrserg-gradleplugin" }
makeevrserg-gradleplugin-android = { module = "ru.astrainteractive.gradleplugin:android", version.ref = "makeevrserg-gradleplugin" }
[plugins]
kotlin-multiplatform = { id = "org.jetbrains.kotlin.multiplatform", version.ref = "kotlin-version" }
gradle-android = { id = "com.android.library", version.ref = "gradle-android" }
5 changes: 5 additions & 0 deletions gradle/wrapper/gradle-wrapper.properties
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-7.6.1-all.zip
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
143 changes: 143 additions & 0 deletions kstorage/build.gradle.kts
Original file line number Diff line number Diff line change
@@ -0,0 +1,143 @@
import ru.astrainteractive.gradleplugin.util.ProjectProperties.projectInfo

plugins {
kotlin("multiplatform")
id("com.android.library")
}
kotlin {
jvm()
androidTarget()
js(IR) {
browser()
nodejs()
}
iosX64()
iosArm64()
iosSimulatorArm64()
tvosX64()
tvosArm64()
tvosSimulatorArm64()
watchosX64()
watchosArm64()
watchosSimulatorArm64()
linuxX64()
macosX64()
macosArm64()
mingwX64()

sourceSets {
/* Main source sets */
val commonMain by getting {
dependencies {
implementation(libs.kotlin.coroutines.core)
}
}
val nativeMain by creating
val jvmMain by getting
val androidMain by getting
val jsMain by getting
val iosMain by creating
val tvosMain by creating
val watchosMain by creating
val linuxMain by creating
val macosMain by creating
val windowsMain by creating
val iosX64Main by getting
val iosArm64Main by getting
val iosSimulatorArm64Main by getting
val tvosX64Main by getting
val tvosArm64Main by getting
val tvosSimulatorArm64Main by getting
val watchosX64Main by getting
val watchosArm64Main by getting
val watchosSimulatorArm64Main by getting
val linuxX64Main by getting
val macosX64Main by getting
val macosArm64Main by getting
val mingwX64Main by getting

/* Main hierarchy */
nativeMain.dependsOn(commonMain)
jvmMain.dependsOn(commonMain)
androidMain.dependsOn(commonMain)
jsMain.dependsOn(commonMain)
iosMain.dependsOn(nativeMain)
iosX64Main.dependsOn(iosMain)
iosArm64Main.dependsOn(iosMain)
iosSimulatorArm64Main.dependsOn(iosMain)
tvosMain.dependsOn(nativeMain)
tvosX64Main.dependsOn(tvosMain)
tvosArm64Main.dependsOn(tvosMain)
tvosSimulatorArm64Main.dependsOn(tvosMain)
watchosMain.dependsOn(nativeMain)
watchosX64Main.dependsOn(watchosMain)
watchosArm64Main.dependsOn(watchosMain)
watchosSimulatorArm64Main.dependsOn(watchosMain)
linuxMain.dependsOn(nativeMain)
linuxX64Main.dependsOn(linuxMain)
macosMain.dependsOn(nativeMain)
macosX64Main.dependsOn(macosMain)
macosArm64Main.dependsOn(macosMain)
windowsMain.dependsOn(nativeMain)
mingwX64Main.dependsOn(windowsMain)

/* Test source sets */
val commonTest by getting {
dependencies {
implementation(kotlin("test"))
}
}
val nativeTest by creating
val jvmTest by getting
val androidUnitTest by getting
val jsTest by getting
val iosTest by creating
val tvosTest by creating
val watchosTest by creating
val linuxTest by creating
val macosTest by creating
val windowsTest by creating
val iosX64Test by getting
val iosArm64Test by getting
val iosSimulatorArm64Test by getting
val tvosX64Test by getting
val tvosArm64Test by getting
val tvosSimulatorArm64Test by getting
val watchosX64Test by getting
val watchosArm64Test by getting
val watchosSimulatorArm64Test by getting
val linuxX64Test by getting
val macosX64Test by getting
val macosArm64Test by getting
val mingwX64Test by getting

/* Test hierarchy */
nativeTest.dependsOn(commonTest)
jvmTest.dependsOn(commonTest)
androidUnitTest.dependsOn(commonTest)
jsTest.dependsOn(commonTest)
iosTest.dependsOn(nativeTest)
iosX64Test.dependsOn(iosTest)
iosArm64Test.dependsOn(iosTest)
iosSimulatorArm64Test.dependsOn(iosTest)
tvosTest.dependsOn(nativeTest)
tvosX64Test.dependsOn(tvosTest)
tvosArm64Test.dependsOn(tvosTest)
tvosSimulatorArm64Test.dependsOn(tvosTest)
watchosTest.dependsOn(nativeTest)
watchosX64Test.dependsOn(watchosTest)
watchosArm64Test.dependsOn(watchosTest)
watchosSimulatorArm64Test.dependsOn(watchosTest)
linuxTest.dependsOn(nativeTest)
linuxX64Test.dependsOn(linuxTest)
macosTest.dependsOn(nativeTest)
macosX64Test.dependsOn(macosTest)
macosArm64Test.dependsOn(macosTest)
windowsTest.dependsOn(nativeTest)
mingwX64Test.dependsOn(windowsTest)
}
}

android {
namespace = "${projectInfo.group}.storageflow"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
@file:Suppress("FunctionNaming")

package ru.astrainteractive.klibs.kstorage

import ru.astrainteractive.klibs.kstorage.api.MutableStorageValue
import ru.astrainteractive.klibs.kstorage.api.StateFlowMutableStorageValue
import ru.astrainteractive.klibs.kstorage.impl.FlowMutableStorageValueImpl
import ru.astrainteractive.klibs.kstorage.impl.MutableStorageValueImpl

fun <T> InMemoryStateFlowMutableStorageValue(
default: T
): StateFlowMutableStorageValue<T> = FlowMutableStorageValueImpl(
default = default,
loadSettingsValue = { default },
saveSettingsValue = {}
)

fun <T> MutableStorageValue(
default: T,
loadSettingsValue: () -> T,
saveSettingsValue: (T) -> Unit
): MutableStorageValue<T> {
return MutableStorageValueImpl(
default = default,
loadSettingsValue = loadSettingsValue,
saveSettingsValue = saveSettingsValue
)
}

fun <T> StateFlowMutableStorageValue(
default: T,
loadSettingsValue: () -> T,
saveSettingsValue: (T) -> Unit
): StateFlowMutableStorageValue<T> {
return FlowMutableStorageValueImpl(
default = default,
loadSettingsValue = loadSettingsValue,
saveSettingsValue = saveSettingsValue
)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
package ru.astrainteractive.klibs.kstorage.api

/**
* [InMemoryStateFlowMutableStorageValue] allows to store values in RAM
*/
interface InMemoryStateFlowMutableStorageValue<T> : StateFlowMutableStorageValue<T>
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package ru.astrainteractive.klibs.kstorage.api

/**
* [MutableStorageValue] allows you to save/load values from your storage without
* depending on SharedPreferences or other library
*/
interface MutableStorageValue<T> : StorageValue<T> {
/**
* Save new value into storage and update current
*/
fun save(value: T)

/**
* Save value with a refernce to current
*/
fun update(block: (T) -> T)

/**
* Reset value to to default
*/
fun reset()
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package ru.astrainteractive.klibs.kstorage.api

import kotlinx.coroutines.flow.StateFlow

/**
* [StateFlowMutableStorageValue] allows you to use your storage values in reactive way
*/
interface StateFlowMutableStorageValue<T> : MutableStorageValue<T> {
val stateFlow: StateFlow<T>

override val value: T
get() = stateFlow.value
}
Loading

0 comments on commit af9f366

Please sign in to comment.