96fdf90aacd6 | atagen | 2026-09-08 08:24 UTC | 1 | # macltok |
96fdf90aacd6 | atagen | 2026-09-08 08:24 UTC | 2 | |
96fdf90aacd6 | atagen | 2026-09-08 08:24 UTC | 3 | `macltok` is a compact Rust application backend built above `matrix-sdk` and |
96fdf90aacd6 | atagen | 2026-09-08 08:24 UTC | 4 | `matrix-sdk-ui`. It aims to provide the stateful behavior needed by a useful |
96fdf90aacd6 | atagen | 2026-09-08 08:24 UTC | 5 | Matrix client without depending on a GUI toolkit or inventing another protocol |
96fdf90aacd6 | atagen | 2026-09-08 08:24 UTC | 6 | SDK. |
96fdf90aacd6 | atagen | 2026-09-08 08:24 UTC | 7 | |
96fdf90aacd6 | atagen | 2026-09-08 08:24 UTC | 8 | The crate currently provides |
96fdf90aacd6 | atagen | 2026-09-08 08:24 UTC | 9 | |
96fdf90aacd6 | atagen | 2026-09-08 08:24 UTC | 10 | - typed commands, owned UI-safe events and bounded per-client transport |
96fdf90aacd6 | atagen | 2026-09-08 08:24 UTC | 11 | - Sliding Sync with normalized connection and room-list state |
96fdf90aacd6 | atagen | 2026-09-08 08:24 UTC | 12 | - independently retained live room timelines and backwards pagination |
96fdf90aacd6 | atagen | 2026-09-08 08:24 UTC | 13 | - text, emote, reply, edit, redaction, reaction, receipt and typing operations |
96fdf90aacd6 | atagen | 2026-09-08 08:24 UTC | 14 | - raw encrypted or unencrypted media acquisition with configurable byte limits |
96fdf90aacd6 | atagen | 2026-09-08 08:24 UTC | 15 | - encryption state, recovery-key import and SAS verification |
96fdf90aacd6 | atagen | 2026-09-08 08:24 UTC | 16 | - password login and session restoration with caller-owned encrypted SQLite stores |
96fdf90aacd6 | atagen | 2026-09-08 08:24 UTC | 17 | |
96fdf90aacd6 | atagen | 2026-09-08 08:24 UTC | 18 | Matrix room, event, user, device and transaction identifiers remain strongly |
96fdf90aacd6 | atagen | 2026-09-08 08:24 UTC | 19 | typed. A toolkit timeline identity covers local echoes without pretending they |
96fdf90aacd6 | atagen | 2026-09-08 08:24 UTC | 20 | already have remote event IDs. |
96fdf90aacd6 | atagen | 2026-09-08 08:24 UTC | 21 | |
96fdf90aacd6 | atagen | 2026-09-08 08:24 UTC | 22 | ## Consuming the engine |
96fdf90aacd6 | atagen | 2026-09-08 08:24 UTC | 23 | |
96fdf90aacd6 | atagen | 2026-09-08 08:24 UTC | 24 | Run `Engine::run` and drain its single `EventStream` independently of command |
96fdf90aacd6 | atagen | 2026-09-08 08:24 UTC | 25 | submission. `ClientHandle::send` returns an enqueue ID; match that ID against |
96fdf90aacd6 | atagen | 2026-09-08 08:24 UTC | 26 | `CommandSucceeded`, `CommandSucceededWithRoom`, or `CommandFailed` before |
96fdf90aacd6 | atagen | 2026-09-08 08:24 UTC | 27 | reporting completion. A successful message command only enters the SDK send |
96fdf90aacd6 | atagen | 2026-09-08 08:24 UTC | 28 | queue; the timeline item's send state reports subsequent network delivery. |
96fdf90aacd6 | atagen | 2026-09-08 08:24 UTC | 29 | |
96fdf90aacd6 | atagen | 2026-09-08 08:24 UTC | 30 | Start a timeline from `TimelineReset`, then apply `TimelineChanged` diffs with |
96fdf90aacd6 | atagen | 2026-09-08 08:24 UTC | 31 | `TimelineDiff::try_apply`. If a diff does not match the current snapshot, stop |
96fdf90aacd6 | atagen | 2026-09-08 08:24 UTC | 32 | applying diffs for that timeline and send `TimelineCommand::Resync`. Resume only |
96fdf90aacd6 | atagen | 2026-09-08 08:24 UTC | 33 | after its fresh `TimelineReset`; the reset precedes the command completion. |
96fdf90aacd6 | atagen | 2026-09-08 08:24 UTC | 34 | |
96fdf90aacd6 | atagen | 2026-09-08 08:24 UTC | 35 | With `sqlite`, persist the initial `Session::record()` separately from its |
96fdf90aacd6 | atagen | 2026-09-08 08:24 UTC | 36 | encrypted SQLite store. On `SessionTokensChanged`, obtain a new record from |
96fdf90aacd6 | atagen | 2026-09-08 08:24 UTC | 37 | `ClientHandle::session_record()` and replace the saved record atomically in |
fa9114fcf75f | atagen | 2026-09-24 12:51 UTC | 38 | protected storage. Restore with the same store path and passphrase. |
fa9114fcf75f | atagen | 2026-09-24 12:51 UTC | 39 | |
fa9114fcf75f | atagen | 2026-09-24 12:51 UTC | 40 | `LoggedOut` and `SessionAccessRejected` both stop the engine. after a logout or a |
fa9114fcf75f | atagen | 2026-09-24 12:51 UTC | 41 | hard rejection the record and the store are dead, bin them. a soft logout wants |
fa9114fcf75f | atagen | 2026-09-24 12:51 UTC | 42 | the store kept and a fresh login with `PasswordLogin::device_id` set to the old |
fa9114fcf75f | atagen | 2026-09-24 12:51 UTC | 43 | device, or the e2ee keys go with it. a bare `Stopped` means keep everything. one |
fa9114fcf75f | atagen | 2026-09-24 12:51 UTC | 44 | store directory per login, the sdk won't share a crypto store between devices. |
fa9114fcf75f | atagen | 2026-09-24 12:51 UTC | 45 | The headless example is |
96fdf90aacd6 | atagen | 2026-09-08 08:24 UTC | 46 | login-only; it does not persist sessions across runs. |
96fdf90aacd6 | atagen | 2026-09-08 08:24 UTC | 47 | |
96fdf90aacd6 | atagen | 2026-09-08 08:24 UTC | 48 | ## Dependency policy |
96fdf90aacd6 | atagen | 2026-09-08 08:24 UTC | 49 | |
96fdf90aacd6 | atagen | 2026-09-08 08:24 UTC | 50 | UI frameworks, image decoders, application-directory discovery and logging |
96fdf90aacd6 | atagen | 2026-09-08 08:24 UTC | 51 | subscribers do not belong in this crate. SQLite remains optional through the |
96fdf90aacd6 | atagen | 2026-09-08 08:24 UTC | 52 | `sqlite` and `bundled-sqlite` features. Media decoding belongs to the consumer. |
96fdf90aacd6 | atagen | 2026-09-08 08:24 UTC | 53 | |
96fdf90aacd6 | atagen | 2026-09-08 08:24 UTC | 54 | ## Verification |
96fdf90aacd6 | atagen | 2026-09-08 08:24 UTC | 55 | |
96fdf90aacd6 | atagen | 2026-09-08 08:24 UTC | 56 | ```sh |
96fdf90aacd6 | atagen | 2026-09-08 08:24 UTC | 57 | nix develop --command cargo fmt -- --check |
96fdf90aacd6 | atagen | 2026-09-08 08:24 UTC | 58 | nix develop --command cargo test --all-targets |
96fdf90aacd6 | atagen | 2026-09-08 08:24 UTC | 59 | nix develop --command cargo test --all-targets --features sqlite |
96fdf90aacd6 | atagen | 2026-09-08 08:24 UTC | 60 | nix develop --command cargo clippy --all-targets -- -D warnings |
96fdf90aacd6 | atagen | 2026-09-08 08:24 UTC | 61 | nix develop --command cargo clippy --all-targets --features sqlite -- -D warnings |
96fdf90aacd6 | atagen | 2026-09-08 08:24 UTC | 62 | nix flake check |
96fdf90aacd6 | atagen | 2026-09-08 08:24 UTC | 63 | ``` |