Skip to content

Release History

This page mirrors the project CHANGELOG.md. The format follows Keep a Changelog, and the project adheres to Semantic Versioning.

0.4.0 — 2026-07-21

Changed

  • Replaced kPointer's ad-hoc "dot notation" with the JavaScript access path (jsPath) — the static member-access subset of JavaScript used by tools like Vega-Lite's encoding.*.field accessors (dot, quoted-bracket, numeric-bracket, with backslash escaping). fromJsPath/toJsPath replace fromDotNotation/toDotNotation in kpointer-core, and KPointer.from()'s bare-string branch now dispatches to fromJsPath — so from("foo[0]") array-indexes instead of yielding the literal key "foo[0]". The notation count stays at three (RFC 6901, URI fragment, jsPath); this is a clean replacement, not an addition, since kPointer has no published consumers yet. ConformanceCapabilities.dotNotation is renamed to jsPath to match. The KP-1004 error code is reused (not retired) for jsPath's single collapsed "malformed" error, generalizing its old "dot-notation produced an empty segment" meaning. The conformance suite bumps to 0.2.0 accordingly — see the Conformance Changelog.
  • Upgraded to Kotlin 2.4.10 (and the matching 1.0.1-K2.4.0 TestBalloon release). The abiValidation {} DSL migrated from abiValidation { enabled.set(true) } to a bare abiValidation(), following the Kotlin 2.4.0 removal of the enabled property. Committed ABI dumps were unaffected by the bump.
  • The root detektAll aggregate (used by hostCheck, not the per-module detekt task) now analyzes test source as well as main source, closing a gap where test code went unlinted.

Fixed

  • hostTest and hostCheck now use Gradle's lazy TaskCollection.matching() to find each submodule's per-target test/verification tasks, instead of eagerly checking task names against subprojects.tasks.names. The eager form could throw when a submodule lacked one of the checked tasks (e.g. a JVM-only module with no checkKotlinAbi task); checkAbi/updateAbi were hardened the same way.

0.3.0 — 2026-07-18

Added

  • The conformance suite is now a versioned, distributable artifact. Its schema $ids resolve live on this site, and the whole suite ships as a downloadable, checksummed ZIP per version. See Distribution and the Conformance Changelog.
  • Portable conformance testing across the reference modules. kpointer-core now drives its own tests from the portable conformance/syntax/* fixtures, and kpointer-adapter from conformance/algorithm/*, each against its own public API. A green 100% koverGate on either module is therefore a proxy for "every branch is exercised by a portable fixture." The :kpointer-conformance module's own syntax/relative tests were retired — already covered by :kpointer-core — but the module itself remains, now published as the conformance-suite runner for adapter authors.
  • Public canonical error mapping. The mapping from KPointerException subtypes (in kpointer-core) and KpaAccessError subtypes (in kpointer-adapter) to canonical errorCode strings is now public API as canonicalErrorCode(), reused by the conformance runners.
  • Typed error taxonomy for conformance. A sealed KPointerException family (parse/relative) and a sealed KpaAccessError family (resolve/mutate), each subtype extending the standard-library exception it replaces so existing catch sites are unaffected. Conformance fixtures gain a normative errorCode on every error expectation. KpaList.get(pointer) now returns null (absent) for an out-of-range index, matching KpaStruct.get.
  • RebuildableKpaStruct / RebuildableKpaList interfaces, each extending their read-only counterpart with a factory property. The mutate {} DSL now targets these interfaces, so calling .mutate {} on a read-only adapter (e.g. a ksoup adapter) is a compile error rather than a silent runtime mistake. Mutation-capable families (kxs, yamlkt) implement them; read-only ksoup implements the plain read interfaces.
  • Shared abstractions for adapter implementors: BackedKpaElement<B> (single backing property plus a requireBacking<B>() unwrapper), AbstractKpaList<E> and AbstractKpaStructMap<E> (delegate the read members to a backing collection), and StringKpaPrimitive (fixes all type flags to the string case). See Writing a Custom Adapter.
  • Typed read-access extensions for KpaStruct and KpaList: stringAt, booleanAt, longAt, doubleAt, primitiveAt, structAt, and listAt, each accepting a KPointer or a String path and returning the typed value or null on absence/shape mismatch.
  • kpointer-ksoup synthetic accessors. An =-prefixed path-segment syntax for reaching text and markup (=ownText, =text, =wholeText, =wholeOwnText, =html, =outerHtml), forcing a child element (=child:NAME), and a shape-stable child list (=children:NAME), each with matching …At extensions. Synthetic keys are resolvable by navigation but are not listed in keys / toMap(). See Working with XML and HTML.
  • New kpointer-ksoup module: read-only adapters exposing KSoup HTML/XML documents as pointer-addressable KpaStruct trees. Elements map to structs keyed by attribute names and distinct child tag names; attributes win on a clash; a repeated child tag becomes a KpaList. Text nodes and mutation are not supported in this release. Targets JVM, Android, iOS, Linux x64, and JS.

Fixed

  • An invalid RFC 6901 tilde escape (e.g. ~2, or a trailing ~) is now rejected (KP-1005) instead of being silently passed through.
  • List indices are now parsed per RFC 6902's array-index grammar: leading zeros, non-ASCII digits, and a leading sign are rejected rather than silently accepted.
  • Resolving through a struct key that is absent partway through a pointer now returns absent, matching the existing behavior for an out-of-range intermediate list index.

Changed

  • KpaStruct / KpaList no longer declare factory; it moved to the Rebuildable* sub-interfaces. The internal mutation helpers now thread the factory from the root, so nested elements need not be rebuildable. Rebuildable*.mutate now returns the Rebuildable* type, enabling chained mutations without a cast.
  • kpointer-kxs and kpointer-yamlkt adapter classes now implement the Rebuildable* interfaces and extend the shared Abstract* base classes, removing duplicated delegation boilerplate; their toJsonElement() / toYamlElement() conversions collapse to a single requireBacking(...) call.
  • kpointer-ksoup adapters now implement the plain read interfaces and its string-only primitives extend StringKpaPrimitive; calling .mutate {} on a ksoup adapter is now a compile error.

0.2.0 — 2026-06-15

Added

  • KpaPrimitive gained typed accessors (isString, isBoolean, isNumber, isNull, stringOrNull, booleanOrNull, doubleOrNull, longOrNull) and renderedString() for inspecting and unwrapping leaf values without depending on a concrete adapter type.
  • New kpointer-yamlkt module: adapters for YamlKt YamlMap, YamlList, and YamlPrimitive, enabling read and mutation via JSON Pointer. Primitive typing follows the YAML 1.2 core schema; non-literal map keys are filtered from pointer addressing. Targets JVM, Android, iOS, Linux x64, and JS — not wasmJs (YamlKt publishes no wasmJs artifact).

Changed

  • YamlPrimitiveAdapter now derives isNumber, doubleOrNull, and longOrNull from a single numericLiteralContent helper — an internal change that preserves all observable semantics and lets :kpointer-yamlkt clear the 100% coverage gate.

0.1.0 — 2026-06-14

Added

Initial release, after migration from the original cw-json project.