atagen

macltok

public
Star0
Watch0
fa9114fcf75f7bdf1a7cec3b3367d604cf7de472
3
ssh://brewery@pls.lobotomise.me:33/atagen/macltok.git

macltok

macltok is a compact Rust application backend built above matrix-sdk and matrix-sdk-ui. It aims to provide the stateful behavior needed by a useful Matrix client without depending on a GUI toolkit or inventing another protocol SDK.

The crate currently provides

  • typed commands, owned UI-safe events and bounded per-client transport
  • Sliding Sync with normalized connection and room-list state
  • independently retained live room timelines and backwards pagination
  • text, emote, reply, edit, redaction, reaction, receipt and typing operations
  • raw encrypted or unencrypted media acquisition with configurable byte limits
  • encryption state, recovery-key import and SAS verification
  • password login and session restoration with caller-owned encrypted SQLite stores

Matrix room, event, user, device and transaction identifiers remain strongly typed. A toolkit timeline identity covers local echoes without pretending they already have remote event IDs.

Consuming the engine

Run Engine::run and drain its single EventStream independently of command submission. ClientHandle::send returns an enqueue ID; match that ID against CommandSucceeded, CommandSucceededWithRoom, or CommandFailed before reporting completion. A successful message command only enters the SDK send queue; the timeline item’s send state reports subsequent network delivery.

Start a timeline from TimelineReset, then apply TimelineChanged diffs with TimelineDiff::try_apply. If a diff does not match the current snapshot, stop applying diffs for that timeline and send TimelineCommand::Resync. Resume only after its fresh TimelineReset; the reset precedes the command completion.

With sqlite, persist the initial Session::record() separately from its encrypted SQLite store. On SessionTokensChanged, obtain a new record from ClientHandle::session_record() and replace the saved record atomically in protected storage. Restore with the same store path and passphrase.

LoggedOut and SessionAccessRejected both stop the engine. after a logout or a hard rejection the record and the store are dead, bin them. a soft logout wants the store kept and a fresh login with PasswordLogin::device_id set to the old device, or the e2ee keys go with it. a bare Stopped means keep everything. one store directory per login, the sdk won’t share a crypto store between devices. The headless example is login-only; it does not persist sessions across runs.

Dependency policy

UI frameworks, image decoders, application-directory discovery and logging subscribers do not belong in this crate. SQLite remains optional through the sqlite and bundled-sqlite features. Media decoding belongs to the consumer.

Verification

nix develop --command cargo fmt -- --check
nix develop --command cargo test --all-targets
nix develop --command cargo test --all-targets --features sqlite
nix develop --command cargo clippy --all-targets -- -D warnings
nix develop --command cargo clippy --all-targets --features sqlite -- -D warnings
nix flake check