components_api_SideEffectTask.bs

' bsc-disable-file print-locations — legacy print() sites; migration to m.log.* tracked by tech-debt.md#legacy-print-statements
import "pkg:/source/api/baseRequest.bs"
import "pkg:/source/constants/timeouts.bs"
import "pkg:/source/roku_modules/rr/Requests.brs"
import "pkg:/source/utils/misc.bs"

sub init()
  m.top.functionName = "executeSideEffect"
end sub

' Architecture B: re-triggered by setting request + control = "RUN".
' Fire-and-forget — no output. Serialises must-complete calls (mark watched, playback state, etc.)
sub executeSideEffect()
  req = m.top.request
  if not isValid(req) then return

  method = req.method
  if not isValid(method) or method = "" then method = "POST"

  ' Auth header first; merge in any caller-provided extras
  headers = { Authorization: buildAuthHeader() }
  if isValid(req.headers) and type(req.headers) = "roAssociativeArray"
    headers.append(req.headers)
  end if

  ' timeout in request AA is seconds; rr_Requests expects milliseconds
  timeout = timeouts.HTTP_MS
  if isValid(req.timeout) then timeout = req.timeout * 1000

  args = {
    headers: headers,
    timeout: timeout,
    useCache: false
  }

  if isValid(req.body) and req.body <> ""
    args.data = req.body
    ' POST/PUT/PATCH with a body requires Content-Type so the server knows the format.
    if not isValid(headers["Content-Type"])
      headers["Content-Type"] = "application/json"
    end if
  end if

  if not isValid(req.url) or req.url = ""
    print "[SideEffectTask] request rejected: url is invalid or empty"
    return
  end if

  rr_Requests().request(method, req.url, args)
end sub