fluxa-core/docs/effects.md
KhooLy 894ca2c81f feat: companion server, FFI cleanup, and pre-release hardening
- 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
2026-06-17 20:01:42 +03:00

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.