All notable changes to this project are documented here. The format follows Keep a Changelog, and the project uses unified versioning: every module is released at the same version number.
http-api: an endpoint's stored slot — get-data-reaction, the reaction execute
returns, and its mirror at [:_http-api :data] in app-db — now holds the answer to the
latest request sent to that endpoint ("latest request wins"). Each request is numbered
per endpoint when it is sent; an answer to a request that a later one has superseded is
never written into the slot, whether it arrives before or after the later one's. While the
latest request is in flight the slot keeps its previous value. Previously every answer was
written when it arrived, so request A answering after request B (a screen switching from
one id to another) left A's stale answer in the slot as the current value.
raw-execute returns always delivers that request's own result, superseded
or not — raw-execute callers see no change.:data and merges :success? false and :error. A superseded request that fails
leaves the slot alone.subscribe) is unaffected.Migration: none for code that reads a request's result off its channel. Code that
relied on the slot holding whichever answer arrived last — e.g. two concurrent calls to
one endpoint with different params, both read from the slot — now sees the later-sent
request's answer; read each result off its own raw-execute channel instead.
bangmod.http-api.request — the request lifecycle (numbering, the
stale-token retry, writing to the slot and the channel) with the transport passed in, so
it is unit-tested under :node-test.subscribe, and execute on an :sse endpoint) authenticate
the way requests do: the registered token injector puts the token on the stream's request
(by default Authorization: Bearer <token>), re-read from the provider on every
(re)open. The token is no longer put in the stream URL.
Migration: SSE routes must authenticate from the Authorization header; the
?access_token= query parameter is no longer sent. Cross-origin, the server's CORS policy
must allow the Authorization and Last-Event-ID request headers.fetch reading the response body, replacing
EventSource. The public API and the handle's state map are unchanged. Because the
status is now visible: a 401 token-stale on open reloads the token (through
set-token-stale-handler!) and re-opens; any other 401 calls set-unauthorized-handler!
once, sets :error "unauthorized" and does not re-open; any other failure re-opens on the
backoff as before. A server retry: is honoured as the minimum reconnect delay, and
re-opens send Last-Event-ID once the server has sent an id:.:on-error receives "HTTP <status>", "connection lost" or
"unauthorized" (previously always "connection lost").bangmod.http-api.sse/stream-url no longer takes a token argument.:sse endpoint's :with-credentials true now sends cookies on a
cross-origin stream (credentials: "include").bangmod.http-api.sse/parser + feed — a pure WHATWG event-stream parser
((feed state chunk) -> [state events]), and sse/response-action /
sse/reconnect-delay, the transport's decisions as pure functions.reagent 1.2.0 → 2.0.1, re-frame 1.4.3 → 1.4.7,
core.async 1.6.681 → 1.9.865. The reagent major bump is the one that reaches consumers:
a project still pinning reagent 1.x will be pulled up to 2.x by these modules' poms.:body in the runtime opts of execute / raw-execute — a prebuilt request
body sent as-is, for a js/FormData multipart upload. It wins over :params and the
endpoint's :request-format: no format is applied and no Content-Type is set, so the
browser writes the multipart boundary itself.set-unauthorized-handler! — (fn [result]) called once when a request
comes back 401 for any reason other than token-stale (the session is over, not merely
out of date), beside delivering the result to the caller. Routing a lapsed session to
re-authentication lives in one place instead of in every loader. retry/session-over-401?
is the pure predicate behind it.bangmod.form.core/create-form-submission — a macro that builds the
:on-submit handler: (create-form-submission form [form values dispatch] body...). The
body reports the outcome by calling dispatch exactly once with nil (success), a string
(the form error) or a promise of either. Anything else — another value, a second call,
never dispatching, a rejected promise, a throwing body — marks the form failed with the
error's message and throws. This is now the documented way to submit; api/handle-submit
and the create-*-submission-result helpers remain as the lower-level path.api/start-submission — the validate-and-mark-submitting gate both submit paths
share; returns the values map, or nil when it refused.set-auth-token-injector! — (fn [request token] -> request) deciding where
the provider's token goes on a request. The default, bangmod.http-api.auth/bearer-injector,
is the previous behaviour (Authorization: Bearer, explicit header wins); nil restores it.bangmod.form.api (form as first
argument) as the one way to call a form.bangmod.form.core/make-api. It was a map of bangmod.form.api functions with
the form pre-bound; call those directly — (api/register-field form :email {...}) — and
build the submit handler with create-form-submission.bangmod.form.core/get-form now exists — the docs already referred to it, but
it was only reachable as bangmod.form.form/get-form.execute now fires the request and returns the endpoint's reaction
(raw-execute + get-data-reaction), so a component can (let [x (execute :api :ep)] ...)
and deref x in its render fn. The previous channel-returning execute is renamed
raw-execute — replace (a/<! (execute ...)) with (a/<! (raw-execute ...)).execute on an :sse endpoint opens the stream (as subscribe) and returns
the subscription handle; that handle now derefs to the stream's latest state, whose latest
frame also lands under :data (alongside :last-message), so (:data @x) reads the same
for a request and a stream. unsubscribe! is a no-op on anything that isn't a
subscription, so a with-let finally can close whatever execute returned.register-routes time with the offending form in the message.get-form-display-error returns the error value (0.1.0 returned a reaction the
caller had to deref — the one bound getter that behaved differently).on-submit that throws, or a wrong submission result, no longer leaves the
form stuck with :is-submitting true — both become a failed submission.create-form error path referenced cljs.pprint without requiring it.:id / :idx) can no longer corrupt the substitution.execute no longer wipes the endpoint's last good data — the
reaction / re-frame slot keeps :data, gains :error, and flips :success?.register-field no longer defaults :placeholder to "Enter" — no
placeholder unless you pass one.:initial-values accepts anything derefable (plain atoms included, not just
reagent types); submission results may be any core.async read port, not only a channel.:on-message are configurable via
:events in subscribe opts (default ["changed"], the previous hardcoded name).forms, api-specs, route tables) survive hot reload (defonce).bangmod.router.table — the pure route-compilation half, unit-tested,
including the shapes 0.1.0 miscompiled.:with-credentials endpoint option documented; defapi rejects the
reserved endpoint name :_options; get-data-reaction throws on an undeclared endpoint
instead of returning nil.:lib-check shadow-cljs build compiling every public namespace in CI — the :test build
alone never compiles the reagent-dependent namespaces.reagent-form, reagent-http-api and reagent-router
into a three-module repo.Can you improve this documentation? These fine people already did:
mapkuff & Siwapun SiwapornEdit on GitHub
cljdoc builds & hosts documentation for Clojure/Script libraries
| Ctrl+k | Jump to recent docs |
| ← | Move to previous article |
| → | Move to next article |
| Ctrl+/ | Jump to the search field |