• v4.0.2 685d0fab01

    v4.0.2
    All checks were successful
    ci / ci (push) Successful in 20s
    release / release (push) Successful in 2s
    conformance / conformance (push) Successful in 2m13s
    Stable

    yuris released this 2026-08-22 13:58:54 +00:00 | 1 commits to main since this release

    A one-fix patch release: a connection the consumer closed no longer handles frames. No API
    changed, so upgrading is the dependency URL.

    Bug fixes

    • A closed connection still handled frames - db:close() stopped the sends but not the
      receives, and handling one frame wrote _state back to "connected", re-persisted the
      identity and token to the save slot, re-emitted connected to on_event and on_connect, and
      refilled the row cache. A UI that tore down on "closed" could be told it was connected again,
      to a socket nobody asked to keep. Reachable on HTML5, and only there in a real program:
      extension-websocket 4.2.4's CloseConnection gates its whole body on STATE_CONNECTED, and
      the unconditional transition to STATE_DISCONNECTED is compiled only under HAVE_WSLAY, so a
      close() during the handshake is a genuine no-op on that target - the browser still fires
      onopen and the server's frames keep coming for as long as the page lives. Native was never
      affected on this path, since CloseConnection does transition there. connection.dispatch now
      refuses any frame on a closed connection
      (#115).
    • Post-close frames retained by the frame_budget queue - the dispatch guard alone sits
      downstream of the budgeted queue, and close() cancels the pump without restarting it, so
      every post-close frame was retained for the life of the page - roughly 4 MB per 200,000 frames.
      The EVENT_MESSAGE branch in stdb/init.lua now drops earlier still, before the queue, the
      coroutine and the decode.
    • db:state() is terminal at "closed" - with frames dropped at both layers, nothing moves
      the state off "closed", which is the property db:state()'s own documentation already
      claimed and is now documented as terminal. Teardown code on "closed" no longer has to defend
      against a later connected, and the two send-path guards the pre-open hold added in v4.0.1
      collapse to that single sticky test.

    What's Changed

    • chore(release): v4.0.2 in #117
    • fix(stdb): drop frames on a closed connection in #116

    Full Changelog: v4.0.1...v4.0.2

    Use as a Defold library

    Add to game.project dependencies:

    https://git.nokopia.com/yuris/spacetimedb-defold/archive/v4.0.2.zip
    https://github.com/defold/extension-websocket/archive/refs/tags/4.2.4.zip
    

    extension-websocket is required: Defold does not resolve dependencies
    transitively, so without it connect fails at runtime.

    Private repo? Append ?token=<access-token> to the URL, the same
    shape Defold documents for GitLab. Basic auth in the URL
    (https://user:token@...) is not a substitute: the archive endpoint
    ignores URL credentials - a real account with a wrong password still
    gets 200 on a public repo - while ?token= is validated and a bad
    one gets a plain 401.

    Downloads