Skip to content

0.15.0 Sushka

Choose a tag to compare

@github-actions github-actions released this 10 Oct 06:32
· 82 commits to master since this release
  • An image's open no longer holds a read of a file it is making.
    Persistence notes at construction whether its file exists; until the
    writer's first open, a read of a file that did not answers from memory
    alone, since the file holds nothing yet, while a file that did is
    waited for, or opened by the read, as before, so a warm start's first
    frame still has the list. On the Pixel 9 the sample's cold start with an
    empty store slept 23 ms of its first composition behind the file's
    creation, written through to flash; its first frame now comes 26 ms
    sooner, level with the Apollo Kotlin twin's, and the list 24 ms sooner,
    255 ms from the launch against the twin's 327 (BENCHMARKS.md,
    9 October).
  • A response is read where it is parsed. The Kotlin environment awaits the
    transport's payload on the ingest dispatcher and the Swift environment on
    a concurrent task, so the store's thread is entered once, for the commit,
    rather than first when the bytes arrive: a response that lands while the
    main thread draws a frame is parsed before the frame ends, not after it.
    On the Pixel 9 the sample's first page, 686 KB, is parsed and normalized
    in about 5 ms of a worker's time, inside the cold start's first frame.
  • The Kotlin twin of the exchange, kotlin/samples/exchange: an Exchange
    over baton.Transport in common Kotlin, the wrapper a production
    endpoint needs and the library does not ship. Credentials are the base
    transport's, read per attempt; a 401 is replayed once after
    challenged(); a query or a subscription refused with a 5xx or by a lost
    connection is sent again with a doubling, jittered wait, as many times as
    attempts allows and never past deadline; a mutation is never sent
    twice; a stream that delivered is not sent again. The Kotlin GitHub
    sample sends through it, as the Swift one sends through
    examples/Exchange, and docs/recipes/exchange.md has its Kotlin half,
    quoting the compiled loop. ExchangeTests in the runtime's JVM tests
    prove it over baton-testing's doubles and a loopback server: the
    replayed challenge carries the renewed token, a second challenge fails,
    a 503 then a 200 is sent twice, the attempts bound the sends, a deadline
    that expires during the backoff fails at once, a mutation refused with a
    503 is sent once, a cancelled consumer ends the held attempt, an
    environment over an exchange reads ready after a retry, and a held
    mutation's optimistic layer stands through a retry beside it.
  • The Android sample tells the environment the process's lifecycle:
    Activation in kotlin/samples/android observes ProcessLifecycleOwner,
    sets isActive false when the last activity stops and true when the
    first starts, and calls revalidate() on the return; the view model
    closes it before the environment ends. docs/recipes/views.md quotes it
    as the Kotlin half of the lifecycle section of docs/recipes/uikit.md,
    which now links it.
  • Kotlin's TransportError carries the connection's own failure as its
    cause when there was no response: HttpTransport, OkHttpTransport
    and the socket clients pass the exception they caught, so a wrapper can
    tell a connection that was lost or timed out, which a retry may mend,
    from a request the transport could not make, which would repeat. A
    status 0 with no cause is still the latter.
  • A Baton app is a client of the server of fate's GraphQL template as it
    ships: responses recorded from it under spec/fate/ prove its posts
    connection, node(id:), postAdd with @prependNode and the
    graphql-sse stream of fateLiveNode, whose JSON payload lands at the
    subscription root and updates no record.
  • The Kotlin runtime runs spec/relay/ and spec/fate/ as the Swift
    runtime does, so a fixture under either directory now holds both
    runtimes, as docs/principles/two-runtimes-one-compiler.md asks.
    jvmRelayTest compiles spec/relay/sources with spec/relay/baton.json
    through the Gradle plugin, which now names the Kotlin package, and runs
    every case and script but the unsupported ones under the same statuses as
    BatonRelayTests: the responses committed as payloads into a bare store,
    the dump compared with Relay's, a check step's answer compared, and each
    reads row read by walking the generated lens, with throws and
    result rows lifted as the Swift target's generated reads lift them; a
    case with a status runs as a known issue that fails once it passes.
    jvmFateTest proves the fate recordings through the Kotlin host
    FateDocuments.kt, the twin of FateDocuments.swift. Each harness runs
    in a JVM of its own, since the registry numbers types by name per process
    and Relay's test schema and fate's both declare a User. CI runs both.
  • The Kotlin Rick and Morty sample has the episode screen, an episode's
    cast, and the location screen, a location's residents, the Swift
    documents verbatim; a character's episodes and its origin and last known
    location open them, and a cast member or a resident opens the character,
    through a stack of destinations the desktop's pane and the Android app
    keep, which Back pops and a recreation restores.
  • The Kotlin GitHub sample has the triage screen: the viewer's assigned
    and created searches over the SearchResultItem union with @alias
    spreads, an issue row that carries its repository's name as the Swift
    row does, a pull request row, a refresh of the searches and a refresh of
    the rows through nodes(ids:), behind a switch in the bar beside the
    repository. Its tests show both searches, the refresh asking for the
    rows' ids in order, and a row selecting its issue.
  • The Kotlin store's thread check says the violation, "the store is used
    off the thread that made it", where it stated the rule.
  • The Kotlin runtime's floors are recorded,
    docs/decisions/kotlin-floors.md: Android 6 (API 23), the lowest the
    Compose runtime and AndroidX SQLite allow; Java 21 class files on the
    JVM and on Android, the JDK the release builds with; and the current
    Kotlin, 2.4.20. The runtime's four published modules pin the JDK 21
    toolchain in their builds, where the JVM target had followed whichever
    JDK ran the build: a local build on JDK 26 wrote Java 26 class files
    where the release wrote Java 21.
  • The recipes say Kotlin where they said Swift alone:
    porting-from-relay.md has a Kotlin column beside the Swift one for
    every Relay word, discover-once.md the Kotlin twin of its refresh,
    derived-state.md the snapshotFlow shape and a link to views.md,
    which links back. The Gradle recipe and the Kotlin README say that
    Baton needs no R8 or ProGuard rules and ships none, since the runtime,
    its modules and the generated Kotlin use no reflection, no serialization
    and no lookup by name.
  • docs/terminology.md has its Kotlin part on every entry that has a
    Swift one, as its preamble promised: the thirty-four that lacked one,
    from Spread and Required to Pagination and the edge directives, say how
    the Kotlin runtime and its generated Kotlin spell the concept and what
    differs from Swift, a getter that throws, a Result for @catch, a
    Hold, a Flow, a suspend function. docs/recipes/testing.md has
    its Kotlin half: the test dispatcher an environment takes outside a
    composition, and each of the Swift snippets beside its Kotlin twin over
    baton-testing.
  • docs/comparison.md is current at 0.14: the at-a-glance table carries
    the Kotlin runtime's numbers on the Pixel 9 beside the Swift runtime's on
    the Mac, the Apollo Kotlin head-to-head is a table of its own, the cons
    say what the Kotlin runtime is and is not rather than that there is none,
    the image con no longer names a row the writer replaced, which 0.8.0
    fixed, and identity says what baton.json configures. kotlin/README.md
    says baton-testing builds for Android, as it has since 0.14.0.
  • docs/recipes/agents.md, the page a coding agent reads first when it
    integrates Baton into an app: the reading order, the shape of a screen
    in Swift and Kotlin, what never to write, the compiler's diagnostics and
    what to run, and a review checklist. The README links it from "Try it
    on your app" and "Written by people, or by models".
  • docs/why-graphql.md, for iOS and Android engineers who build on REST:
    the plumbing a REST screen needs, what GraphQL removes of it, what only
    Relay's fragments and store remove, what Baton adds, what stays the
    app's, and what it costs. The README's first paragraph links it.