- Add fluxa-streaming-engine companion server (torrent start/stop, ffmpeg transcode/probe, OAuth token exchange) for the web build - Add SSRF guard restricting transcode/probe url param to http(s) loopback hosts, blocking file:// and remote-host abuse via ffmpeg - Add src/ffi.rs string-routed RPC dispatcher and wasm bindings - Add headless engine profile module and several FFI surface additions (scrobble plans, episode navigation, collections import/export) - Remove dead runtime::msg/update scaffolding and addon_transport trait - Remove fluxa_play.rs dev scratch binary (hardcoded scraper, not part of the product) - Reorder dv_rewrite.rs so implementation precedes its test module; strip decorative section dividers - Add docs/, fuzz/ targets, and a rewritten README - Fix .gitignore to cover fluxa-streaming-engine/target
4.5 KiB
Effects reference
When the headless engine needs the platform to do something, it emits an effect. The platform matches on the type field, runs the appropriate I/O, and calls completeEffect with the result.
All types are defined in src/runtime/effects.rs (EffectKind). The string values below are what appears in the type field on the wire.
Effect envelope
{
"id": "fx-7",
"type": "fetchAddonResource",
"generation": 4,
"payload": { ... }
}
id is echoed back verbatim in completeEffect. generation is for staleness detection — the platform can discard completions whose generation is lower than the current engine generation.
Effect types
Fetch / network
| type | What to do |
|---|---|
fetchAddonManifest |
GET the addon manifest URL in payload.url |
fetchAddonResource |
GET the addon resource URL in payload.url |
fetchCatalogPage |
GET a catalog page (URL in payload) |
fetchDetailSecondary |
Fetch secondary metadata for the detail screen |
fetchDetailStreams |
Fetch streams from one or more addons |
fetchMetaDetail |
Fetch full metadata for a content item |
fetchMetaDetailLookup |
Fetch metadata by lookup (TMDB ID → IMDB ID, etc.) |
fetchSeasonEpisodes |
Fetch episode list for a season |
fetchSubtitles |
Fetch subtitle tracks |
fetchIntroSegments |
Fetch intro/outro skip segments from introdb.app or AniSkip |
prefetchDetailStreams |
Background prefetch of streams before user opens detail |
prefetchNextEpisodeStreams |
Prefetch streams for the next episode while current is playing |
Playback
| type | What to do |
|---|---|
loadStreams |
Resolve and load stream list for the player |
prepareDirectPlayback |
Prepare direct playback (no stream resolution needed) |
startTorrentStream |
Start a torrent stream via fluxa-streaming-engine |
stopTorrent |
Stop and clean up an active torrent stream |
resolveIntroImdbId |
Resolve the IMDB ID needed for intro segment lookup |
Storage / state
| type | What to do |
|---|---|
readHomeBootstrap |
Read local home bootstrap data (cached rows, continue-watching) |
readDetailLocalState |
Read locally cached state for a detail screen item |
readLibraryState |
Read the full library state from storage |
readPlaybackProgress |
Read saved playback position for an item |
readCalendarMonth |
Read calendar release data for a given month |
readDiscoverCatalogFilters |
Read saved discover/browse filter state |
writePlaybackProgress |
Persist the user's current playback position |
clearPlaybackProgress |
Remove a saved playback position |
writeFeedback |
Persist a like/dislike feedback signal |
writeLibraryCommand |
Execute a library mutation (add, remove, update) |
writeSettings |
Persist updated user settings |
updateCalendarWidget |
Refresh the OS home-screen calendar widget |
Auth / sync
| type | What to do |
|---|---|
runAuthFlow |
Launch an OAuth flow (opens browser/WebView) |
exchangeAuthCode |
Exchange an auth code for tokens |
refreshAuthToken |
Refresh an expired auth token |
refreshInstalledAddons |
Re-fetch manifests for all installed addons |
runExternalSync |
Sync watched state with an external service (Trakt/Simkl) |
syncExternalIntegration |
Run a full bidirectional sync with an external integration |
syncWatchedState |
Push local watched state to an external service |
replaceExternalContinueWatching |
Replace the external continue-watching list |
enqueueTraktScrobble |
Queue a Trakt scrobble request |
Content operations
| type | What to do |
|---|---|
runSearch |
Execute a search query across installed addons |
runDiscover |
Run a discover/browse query |
enqueueOfflineDownload |
Add an item to the offline download queue |
notifyReleasedEpisodes |
Push a notification for newly released episodes |
completeEffect result shapes
Result payloads are effect-specific. The general pattern:
{
"effectId": "fx-7",
"result": {
"ok": true,
"data": { ... }
}
}
For network fetches, data typically contains the raw response body or a parsed object. For storage reads, it contains the stored value or null if nothing was saved. For write operations, result can be {} on success.
The exact shape for each effect type is consumed by the engine's completeEffect handler in src/headless_engine/ — check the relevant submodule (e.g. home.rs, detail.rs, player.rs) for the EffectResultInput variant that handles it.