Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion DESCRIPTION
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ Package: mx.api
Type: Package
Title: Minimal Matrix Client-Server API
Version: 0.3.0
Date: 2026-05-13
Date: 2026-06-10
Authors@R: c(
person("Troy", "Hernandez", role = c("aut", "cre"),
email = "troy@cornball.ai",
Expand Down
10 changes: 8 additions & 2 deletions R/media.R
Original file line number Diff line number Diff line change
Expand Up @@ -53,8 +53,14 @@ mx_upload <- function(session, path, content_type = NULL, filename = NULL) {
Accept = "application/json"
)
resp <- curl::curl_fetch_memory(url, handle = h)
parsed <- jsonlite::fromJSON(rawToChar(resp$content),
simplifyVector = FALSE)
# A proxy or misconfigured server can answer non-JSON (HTML, plain
# text); don't let the parse error mask the real failure -- fall
# through to mx_raise with whatever body came back.
parsed <- tryCatch(
jsonlite::fromJSON(rawToChar(resp$content),
simplifyVector = FALSE),
error = function(e) list(raw = rawToChar(resp$content))
)

if (resp$status_code >= 400) {
mx_raise(parsed$errcode %||% "HTTP",
Expand Down
5 changes: 2 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -130,12 +130,11 @@ mx_canonical_json(1.5)
#> Error: mx_canonical_json: non-integer number 1.5 disallowed
```

97 assertions exercise the encoder (see `inst/tinytest/test_canonical_json.R`).
107 assertions exercise the encoder (see `inst/tinytest/test_canonical_json.R`).

## Status

**0.3.0** on `main`. The 0.2.0 release is on CRAN. The 0.3.0 delta is
additive:
**0.3.0**. Relative to 0.2.0 the delta is additive:

- Generic event and state plumbing: `mx_send_event`, `mx_set_state`,
`mx_get_state` (needed for `m.room.encrypted` / `m.room.encryption`).
Expand Down
54 changes: 30 additions & 24 deletions cran-comments.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,36 +4,42 @@

## Test environments

* local Ubuntu 24.04, R 4.5.3
* local Ubuntu 24.04, R 4.6.0
* local Windows 10: R 4.6.0 and R-devel (4.7.0 pre-release), both OK;
R 4.5.1 with 1 environmental NOTE ("unable to verify current time")
* GitHub Actions (ubuntu-latest, macos-latest) via r-ci
* win-builder R-devel and R-release (`tinypkgr::check_win_devel()`)

## What's new in 0.2.0

This is the first feature update after the 0.1.0 initial CRAN release.
The delta is additive: five new exports, no changes to the existing
0.1.0 surface.

* `mx_keys_upload()`, `mx_keys_query()`, `mx_keys_claim()`, and
`mx_send_to_device()` cover the Matrix Client-Server endpoints used
to coordinate end-to-end encryption. The package itself remains
crypto-free; these endpoints carry payloads that an external signer
produces.
* `mx_canonical_json()` is the byte-stable canonical JSON encoder
Matrix's signing rules require. It is exercised by 107 tinytest
assertions covering UTF-8 sort, integer-vs-float, NaN/Inf/NA
rejection, control-char escaping, duplicate-key rejection, and the
realistic `/keys/upload` payload shape.
* DESCRIPTION text expanded to mention the new transport surface and
to add URLs for the named homeserver implementations ('Synapse',
'Conduit') alongside the existing 'Matrix' specification link.

## What's new in 0.3.0

Additive only; no changes to the existing 0.2.0 surface.

* Generic room-event and state plumbing: `mx_send_event()`,
`mx_set_state()`, `mx_get_state()` (what an external
end-to-end-encryption layer needs to send `m.room.encrypted` events
and read `m.room.encryption` state).
* Media messages: `mx_send_media()` uploads a file and posts the
referencing message, deriving the msgtype from the MIME type;
`mx_send_file()` / `mx_send_image()` / `mx_send_audio()` /
`mx_send_video()` fix it explicitly. `mx_guess_mime()` is exported;
`mx_media_config()` reports the server's upload cap. `mx_upload()`
now streams from disk instead of reading files into memory.
* Bot lifecycle endpoints: `mx_room_invite()`, `mx_redact()`,
`mx_typing()`, `mx_profile()`, `mx_set_displayname()`,
`mx_set_avatar_url()`.
* Account data: `mx_get_account_data()` / `mx_set_account_data()`.
* Devices: `mx_devices()`, `mx_delete_device()` (user-interactive auth
payloads pass through verbatim).
* HTTP failures now signal classed conditions (`mx_error_<ERRCODE>`)
carrying the Matrix errcode, HTTP status, and parsed body; message
text is unchanged from previous releases.

## Notes on examples

Examples that talk to a homeserver continue to use `\dontrun{}`: they
require valid credentials plus a running Matrix homeserver, so they
cannot execute under `R CMD check --as-cran`. `mx_session()` and
`mx_canonical_json()` are pure functions with runnable examples.
cannot execute under `R CMD check --as-cran`. Pure functions
(`mx_session()`, `mx_canonical_json()`, `mx_guess_mime()`) have
runnable examples.

## Downstream dependencies

Expand Down