Skip to content

Make versioning backend-agnostic - #179

Open
xxfast wants to merge 1 commit into
masterfrom
ir/versioned-codec
Open

Make versioning backend-agnostic#179
xxfast wants to merge 1 commit into
masterfrom
ir/versioned-codec

Conversation

@xxfast

@xxfast xxfast commented Aug 30, 2026

Copy link
Copy Markdown
Owner

VersionedCodec lived in kstore-file and did its own file IO, so kstore-storage couldn't have versioned stores.

Moved it into kstore as a decorator over three codecs:

  • data - the current shape of T
  • versionCodec - persists the version alongside the data
  • staleCodec - re-reads the old payload in a raw shape that survives schema changes

Versioning is itself just persistence, so it's delegated to codecs. Nothing in VersionedCodec knows about files or keys.

What this gets us

kstore-storage gets storeOf(key, version, ...) for free. 48 lines pointing StorageCodec at a "$key@version" sibling record.

kstore-file keeps storeOf(file, version, ...) unchanged. It's now a thin factory over FileCodec, net -44 lines.

Behaviour

  • Data is written first, version second. A crash in between leaves the new data with a stale version, which still decodes directly. The other order would claim a version the data was never written to.
  • A missing version record reads as version 0, ie the store predates versioning.
  • A version record that exists but can't be read leaves version as null, the same way an unreadable payload leaves previous as null.

API

Migration<T, R> is now generic over the raw shape. kstore-file keeps its Migration<T> typealias and DefaultMigration so nothing downstream breaks. apiDump is committed.

Tests

  • VersionedCodecTests (10) runs the decorator against an in-memory MapCodec, proving it's backend-agnostic
  • kstore-file KVersionedStoreTests (14), behaviour unchanged
  • kstore-storage KVersionedStoreTests (6), new

Docs updated with the storage factory and the custom codec path.

🤖 Generated with Claude Code

Move `VersionedCodec` out of `kstore-file` and into `kstore`. It's now a
decorator over three codecs: the data, the version, and a stale reader for the
old payload. Nothing in it knows about files.

`kstore-file` keeps `storeOf(file, version, ...)`, now a thin factory over
`FileCodec`. `kstore-storage` gets `storeOf(key, version, ...)` for free.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@codecov

codecov Bot commented Aug 30, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 95.12195% with 2 lines in your changes missing coverage. Please review.
✅ Project coverage is 93.52%. Comparing base (f754f1b) to head (dd73ab3).
✅ All tests successful. No failed tests found.

Files with missing lines Patch % Lines
...b/xxfast/kstore/file/extensions/KVersionedStore.kt 90.90% 2 Missing ⚠️
Additional details and impacted files

Impacted file tree graph

@@            Coverage Diff             @@
##           master     #179      +/-   ##
==========================================
- Coverage   94.35%   93.52%   -0.83%     
==========================================
  Files           8        9       +1     
  Lines         124      139      +15     
  Branches       11       12       +1     
==========================================
+ Hits          117      130      +13     
- Misses          0        2       +2     
  Partials        7        7              
Files with missing lines Coverage Δ
.../github/xxfast/kstore/extensions/VersionedCodec.kt 100.00% <100.00%> (ø)
...b/xxfast/kstore/file/extensions/KVersionedStore.kt 93.93% <90.90%> (-6.07%) ⬇️

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant