
Track one-off and rate-limited actions across install, version, and session scopes using tag-based markers, time-window and count checks, to-do workflow, with persistent map/set and session cache.
onceKmp is a Kotlin Multiplatform library inspired by jonfinerty/Once, used to track one-off actions and rate-limited actions across app install, app version, and app session scopes.
onceKmp: publishable KMP library module.onceKmpSample: sample wrapper module showing real usage.markDone(tag), beenDone(...), lastDone(tag)
Once.THIS_APP_INSTALLOnce.THIS_APP_VERSIONOnce.THIS_APP_SESSIONbeenDone(OnceTimeUnit, amount, tag)beenDone(timeSpanInMillis, tag)Amount.exactly(n)Amount.moreThan(n)Amount.lessThan(n)toDo(...)needToDo(tag)clearToDo(tag)io.github.mrjoechen
oncekmp
io.github.mrjoechen
io.github.mrjoechen
kotlin {
sourceSets {
commonMain.dependencies {
implementation("io.github.mrjoechen:oncekmp:<latest-version>")
}
}
}settings.gradle.kts:
include(":onceKmp")Consumer module:
dependencies {
implementation(project(":onceKmp"))
}Unified call for Android / iOS / Desktop:
Once.initialise()Android explicit fallback:
Once.initialise(applicationContext)Desktop/iOS custom app update timestamp:
Once.initialise(appUpdatedTimeMillis = 1_700_000_000_000L)Desktop custom storage directory (optional):
Once.initialise(
storageDir = java.nio.file.Paths.get("/custom/path/for/oncekmp")
)if (!Once.beenDone(Once.THIS_APP_VERSION, "show_whats_new")) {
// show what's new
Once.markDone("show_whats_new")
}Once uses two persisted stores and one in-memory session list:
PersistedMapTagLastSeenMap
tag
Long) serialized as comma-separated text in storage adapters.PersistedSetToDoSet
PersistedSetValues
THIS_APP_SESSION checks.Context.getSharedPreferences(name, Context.MODE_PRIVATE)SharedPreferences read/write via getAll()/putString()/putStringSet()/remove()/clear()
PackageManager.getPackageInfo(...).lastUpdateTime/data/data/<applicationId>/shared_prefs/PersistedMapTagLastSeenMap.xml/data/data/<applicationId>/shared_prefs/PersistedSetToDoSet.xmlOnceContextProvider is declared in library manifest and caches applicationContext.NSUserDefaults.standardUserDefaultsstringForKey/objectForKey/arrayForKey/setObject/removeObjectForKey/dictionaryRepresentation<storeName>:<key>PersistedMapTagLastSeenMap:show_whats_new
/var/mobile/Containers/Data/Application/<UUID>/Library/Preferences/<bundle-id>.plist
~/Library/Developer/CoreSimulator/Devices/<UDID>/data/Containers/Data/Application/<UUID>/Library/Preferences/<bundle-id>.plist
java.nio.file + java.util.Properties
<storeName>.properties fileoncekmp.desktop.appId system propertyapp.id / application.id / app.identifier / bundle.id / app.name
jpackage.app-path / sun.java.command / java.class.path)oncekmp-app-<working-directory-name>
~/Library/Application Support/<rootNode>/oncekmp/
${XDG_CONFIG_HOME:-~/.config}/<rootNode>/oncekmp/
%APPDATA%\\<rootNode>\\oncekmp\\
<rootNode>
oncekmp stateonceKmp is a Kotlin Multiplatform library inspired by jonfinerty/Once, used to track one-off actions and rate-limited actions across app install, app version, and app session scopes.
onceKmp: publishable KMP library module.onceKmpSample: sample wrapper module showing real usage.markDone(tag), beenDone(...), lastDone(tag)
Once.THIS_APP_INSTALLOnce.THIS_APP_VERSIONOnce.THIS_APP_SESSIONbeenDone(OnceTimeUnit, amount, tag)beenDone(timeSpanInMillis, tag)Amount.exactly(n)Amount.moreThan(n)Amount.lessThan(n)toDo(...)needToDo(tag)clearToDo(tag)io.github.mrjoechen
oncekmp
io.github.mrjoechen
io.github.mrjoechen
kotlin {
sourceSets {
commonMain.dependencies {
implementation("io.github.mrjoechen:oncekmp:<latest-version>")
}
}
}settings.gradle.kts:
include(":onceKmp")Consumer module:
dependencies {
implementation(project(":onceKmp"))
}Unified call for Android / iOS / Desktop:
Once.initialise()Android explicit fallback:
Once.initialise(applicationContext)Desktop/iOS custom app update timestamp:
Once.initialise(appUpdatedTimeMillis = 1_700_000_000_000L)Desktop custom storage directory (optional):
Once.initialise(
storageDir = java.nio.file.Paths.get("/custom/path/for/oncekmp")
)if (!Once.beenDone(Once.THIS_APP_VERSION, "show_whats_new")) {
// show what's new
Once.markDone("show_whats_new")
}Once uses two persisted stores and one in-memory session list:
PersistedMapTagLastSeenMap
tag
Long) serialized as comma-separated text in storage adapters.PersistedSetToDoSet
PersistedSetValues
THIS_APP_SESSION checks.Context.getSharedPreferences(name, Context.MODE_PRIVATE)SharedPreferences read/write via getAll()/putString()/putStringSet()/remove()/clear()
PackageManager.getPackageInfo(...).lastUpdateTime/data/data/<applicationId>/shared_prefs/PersistedMapTagLastSeenMap.xml/data/data/<applicationId>/shared_prefs/PersistedSetToDoSet.xmlOnceContextProvider is declared in library manifest and caches applicationContext.NSUserDefaults.standardUserDefaultsstringForKey/objectForKey/arrayForKey/setObject/removeObjectForKey/dictionaryRepresentation<storeName>:<key>PersistedMapTagLastSeenMap:show_whats_new
/var/mobile/Containers/Data/Application/<UUID>/Library/Preferences/<bundle-id>.plist
~/Library/Developer/CoreSimulator/Devices/<UDID>/data/Containers/Data/Application/<UUID>/Library/Preferences/<bundle-id>.plist
java.nio.file + java.util.Properties
<storeName>.properties fileoncekmp.desktop.appId system propertyapp.id / application.id / app.identifier / bundle.id / app.name
jpackage.app-path / sun.java.command / java.class.path)oncekmp-app-<working-directory-name>
~/Library/Application Support/<rootNode>/oncekmp/
${XDG_CONFIG_HOME:-~/.config}/<rootNode>/oncekmp/
%APPDATA%\\<rootNode>\\oncekmp\\
<rootNode>
oncekmp state