Changelog

Changelog

All notable changes to this package are documented in this file. The format follows Keep a Changelog, and this project adheres to the Haskell PVP.

[Unreleased]

[0.2.0.0] — 2026-07-13

Added
  • Event-codec schema evolution through pinned constructor wire kinds, default-on-missing payload decoding, and a compile-time-complete chain of one-envelope-to-one-envelope upcasters.
  • fieldCodec, a strict smart constructor for FieldCodec, plus generated <prefix>SchemaVersion bindings.
Changed
  • Breaking for invalid schemas: RegFileToJSON now rejects duplicate slot names at compile time through keiki's canonical DistinctNames invariant, preventing Value-path data loss and duplicate streaming keys.
  • Encoding now documents and pins the existing fully-initialized-register precondition. Unwritten emptyRegFile slots throw a slot-named ErrorCall; keiro already snapshots only fully populated register files, so it needs no source change.
  • Breaking: snapshot shape hashes now use keiki's pinned built-in type names. Every non-empty shape hash changes once; stores keyed by an old hash ignore that snapshot and replay from the event log. Keiro already treats this mismatch as a benign cache miss.
  • Container slot types now require their arguments to have CanonicalTypeName, not merely Typeable, so user-defined types may need to derive or define that class. This makes application overrides propagate through Maybe, lists, Either, and tuples.
  • Breaking: EventCodecOptions now also carries kindOverrides, versionFieldName, currentVersion, and upcasters.
  • Breaking: FieldCodec gains the fcOnMissing field. Positional construction should be replaced with fieldCodec and a record update when a missing-key default is required.
  • Breaking: generated event envelopes now contain an in-band "v" field; version-absent historical objects decode as version 1.
  • Breaking: generated EventTypes and KindMap bindings contain resolved wire kinds, including pinned values, rather than assuming constructor names.

[0.1.0.0] — 2026-06-07

Initial Hackage release. Co-released with keiki-0.1.0.0; this package depends on keiki ^>= 0.1.

Added
  • Keiki.Codec.JSON — three-method codec class RegFileToJSON (rs :: [Slot]):
    • regFileToJSON :: RegFile rs -> Aeson.Value (strict Value-path encoder).
    • regFileFromJSON :: Aeson.Value -> Either String (RegFile rs) (strict decoder; rejects missing / extra / type-mismatched fields with per-slot error messages).
    • regFileToEncoding :: RegFile rs -> Aeson.Encoding (streaming encoder over Aeson.Series that avoids the O(output-size) intermediate Aeson.Value allocation).
    • A single auto-derived instance for every slot list whose slot types have Aeson.ToJSON + Aeson.FromJSON; users do not write instances by hand.
  • Keiki.Codec.JSON.TH — Template Haskell helpers deriveRegFileCodec and deriveRegFileCodecAs that emit three top-level codec functions (<prefix>ToJSON, <prefix>ToEncoding, <prefix>FromJSON) for a record type with deriving (Generic).
Validated against
  • GHC 9.12.2 locally on macOS aarch64 and in CI on Ubuntu Linux x86_64 (see .github/workflows/ci.yml).
  • 40 hspec assertions, including 4 QuickCheck properties (100 samples each), 9 schema-evolution sensitivity assertions (EP-36 §4 cases #1–9), a pinned golden shape hash, and 10 Keiki.Codec.JSON.TH derivation tests.
  • A tasty-bench baseline (bench/baseline.csv) for four representative RegFile size scenarios (multi-party signing, batch reconciliation, ticket aggregate, auction); the Encoding-path is ~1.5× faster than the Value-path on the streaming-motivating case (5,000-entry list) with 33 % less allocation.