Skip to content

0.9.0 Krendel

Choose a tag to compare

@github-actions github-actions released this 07 Oct 21:57
· 216 commits to master since this release
  • Payload, bytes in a response's shape, is what the door takes:
    commitPayload takes a Payload where it took Data, and
    mutate(_:optimistic:) and a mutation's action take one where they took a
    Variable; a mutation's OptimisticResponse builder renders its
    payload, and the JSON value it collected its fields in is generated
    code's alone. Variable is a variable's JSON value and nothing else.
    Format 18. Recorded in
    docs/decisions/a-payload-is-bytes-in-a-responses-shape.md.
  • A key the store holds at two slots, a rendering and the constant the
    build named for it afterwards, is one field in every report: a commit's
    changed count counts the pair once, and the store's dump and the
    inspector list the key once, and a record a batch creates counts among
    nothing changed whether or not the store holds twins. Before, a late
    constant doubled the count, made created records count, and showed the
    key twice in the dump, so a count or a dump compared across test runs
    differed by what else the process had touched.
  • A handle stores no phase. The root, which is the store's, holds whether
    the store has the operation's data and the verdict on it, what the data
    deserves by @throwOnFieldError and a bubbling @required, settled by
    the store at the end of a batch that changed a null, a link, an error or
    a deletion, and when the handle finds or fetches the data; the handle's
    phase is derived from the root and its own fetch when it is read.
    The settling chain from the store through the environment to every
    retained handle is gone, and with it the store's last covert pointer to
    its environment. With data the phase reads the verdict and not the
    fetch, so a body that reads the phase is not woken by a fetch that
    changed nothing. Two readings change: a storeOnly handle that found no
    data reads ready once the operation's response is committed by any route
    or it is attached again over data the store now holds, and a handle that
    failed with nothing to show reads ready when it is attached again over
    such data; before, both stayed failed. Recorded in
    docs/decisions/the-verdict-is-the-roots.md.
  • The compiler's decide stage spells nothing itself: it asks a naming the
    target supplies for every identifier, suffix, family and member name it
    needs, and the driver decides first and prints through the Swift target
    after; host files are found through a table of languages, with the Swift
    scanner and its checks behind it. The generated code does not change by
    a byte; the seams are those a Kotlin emitter needs.
  • Scripts, the second kind of fixture under spec/: a file under
    spec/scripts/ runs steps over time in one environment over one store,
    through a transport the steps answer, and after any step compares the
    dump, the reads, the fields notified, a handle's phase, fetch and
    stream, the check's answer, the records held and the log's events.
    Eleven scripts (notifications, optimistic, connections, lifetime,
    ages, phase, check, heal, end, events, subscriptions)
    hold the rules of the contract that no single commit could; the
    manifest goes to format 2, with scripts beside cases, and
    spec/README.md says what a script holds. The Swift runtime passes
    them all; loading a page through a lens and the transport's framings
    stay with the Swift tests for now.
  • customScalarTypes takes, beside the Swift type as a string, an object
    by language, {"swift": "Foundation.Decimal", "kotlin": "..."}; a mapped
    scalar with no swift entry is an error at the configuration. The plan
    the compiler lowers carries the scalar's name and the onError value, no
    longer a Swift type or a Swift case: the Swift writer resolves both, so a
    second emitter reads the same plan. The refetch descriptor names the
    @fetchable field Relay's metadata names instead of a field spelled
    id. The generated Swift does not change by a byte.
  • A view outside every .environment(\.baton, ...) reads
    .failed(EnvironmentError.notInjected) on its first body and makes no
    handle, and a mutation action in such a view throws the same; the shared
    placeholder environment, a real store that every view which forgot the
    injection fetched into, is gone. The absence of an environment is not a
    session. Format 17: an operation value's resolution is a Resolution,
    unresolved, resolved to its handle, or not injected.
  • A lens is Equatable, by its anchor: the same record, the same scope and
    the same origin, by identity, as the principle always said. A row view
    whose stored state is a lens conforms in one line and opts into
    .equatable(), so a parent's re-render skips it.
  • Five decisions recorded before the Kotlin lane, in docs/decisions/: the
    verdict is the root's and the phase is derived from it (superseding in
    part The phase stays stored; built behind a gate once the phase scripts
    exist); a payload is bytes in a response's shape, Relay's word, which the
    door and the optimistic builders will take in place of a Variable; a
    mapped scalar's host type is named per language under Relay's
    customScalarTypes, so the plan carries the scalar's name; the Kotlin
    runtime is common first with a platform as an actual (issue 24); and a
    format is per emitter.
  • spec/runtime.md, the runtime contract: what a runtime does with a plan,
    a response and a store, in no language's terms, one paragraph a rule,
    each ending with the fixture that holds it or the word unheld, so a
    second runtime is held to the rules and not to the Swift that spells
    them. The principle Two runtimes, one compiler names it, and no longer
    counts the image's bytes among what the fixtures specify: a second store
    over the image reading the same records is what is shared.
  • @inline is built: a fragment so marked compiles to a Sendable,
    Hashable struct of its fields in place of a lens, with a nested struct
    per link, an array per plural link and an initializer that takes the
    fields. The spread's accessor on the parent's lens builds the value from
    the record when it is called, on the main actor, through the readers a
    lens's accessors use, so what a read registers and reports is the same;
    a conditional or deferred spread yields an optional value and an aliased
    @catch around one a Result. An inline fragment spreads only inline
    fragments and takes no @connection, @refetchable or @required; a
    non-null mapped scalar in it reads optional, since a stored property
    cannot throw. A value's field errors include those of the values it
    spreads, so a catch or a policy around it sees them, and
    @throwOnFieldError on a value spread inside another value is refused.
    Format 16: generated code names the readers that build a plural link's
    values. A fragment spread by no operation is warned as one nothing can
    read, lens or value. Recorded in
    docs/decisions/a-fragment-has-one-reading.md.