detectFieldsStreaming function

Last updated: 2026-03-05T23:41:17.531Z

Metrics

LOC: 136 Complexity: 25 Params: 0

Signature

detectFieldsStreaming(): : Promise<void>

Architecture violations

View all

  • [warning] max-cyclomatic-complexity: 'detectFieldsStreaming' has cyclomatic complexity 25 (max 10)
  • [warning] max-lines: 'detectFieldsStreaming' has 136 lines (max 80)

Source Code

async function detectFieldsStreaming(): Promise<void> {
  panelState.detectedFields = [];
  panelState.isDetecting = true;
  addLog(t("logDetecting"));

  if (panelState.activeTab === "fields") renderFieldsTab();

  try {
    const STREAM_IDLE_TIMEOUT_MS = 4000;

    let detectionComplete = false;
    let receivedAnyMessage = false;
    let streamIdleTimeoutId: number | null = null;

    const clearStreamIdleTimeout = (): void => {
      if (streamIdleTimeoutId !== null) {
        window.clearTimeout(streamIdleTimeoutId);
        streamIdleTimeoutId = null;
      }
    };

    const fallbackDetectOnce = async (): Promise<void> => {
      const result = (await sendToPage({ type: "DETECT_FIELDS" })) as {
        fields?: DetectedFieldSummary[];
        error?: string;
      };

      if (result?.error) {
        addLog(`Erro ao detectar: ${result.error}`, "error");
        return;
      }

      panelState.detectedFields = Array.isArray(result?.fields)
        ? result.fields
        : [];
      addLog(
        `${panelState.detectedFields.length} ${t("fieldsDetected")}`,
        "success",
      );
    };

    const finalizeDetection = (
      port: chrome.runtime.Port,
      options?: { warning?: string },
    ): void => {
      if (detectionComplete) return;
      detectionComplete = true;
      clearStreamIdleTimeout();
      panelState.isDetecting = false;

      if (options?.warning) addLog(options.warning, "warn");

      if (panelState.activeTab === "fields") renderFieldsTab();

      try {
        port.disconnect();
      } catch {
        // no-op
      }
    };

    const scheduleStreamIdleFinalization = (
      port: chrome.runtime.Port,
    ): void => {
      clearStreamIdleTimeout();
      streamIdleTimeoutId = window.setTimeout(() => {
        if (!detectionComplete && receivedAnyMessage) {
          finalizeDetection(port, {
            warning: "Detecção finalizada por inatividade do stream",
          });
          addLog(
            `${panelState.detectedFields.length} ${t("fieldsDetected")}`,
            "success",
          );
        }
      }, STREAM_IDLE_TIMEOUT_MS);
    };

    const port = chrome.tabs.connect(panelState.inspectedTabId, {
      name: "field-detection-stream",
    });

    scheduleStreamIdleFinalization(port);

    port.onMessage.addListener((message: StreamedFieldMessage) => {
      receivedAnyMessage = true;
      scheduleStreamIdleFinalization(port);

      if (message.type === "field" && message.field) {
        panelState.detectedFields.push(message.field);
        if (panelState.activeTab === "fields") renderFieldsTab();
      } else if (message.type === "complete") {
        addLog(
          `${panelState.detectedFields.length} ${t("fieldsDetected")}`,
          "success",
        );
        finalizeDetection(port);
      } else if (message.type === "error") {
        addLog(`Erro ao detectar: ${message.error}`, "error");
        finalizeDetection(port);
      }
    });

    port.onDisconnect.addListener(() => {
      clearStreamIdleTimeout();
      if (!detectionComplete) {
        const reason = chrome.runtime.lastError?.message;
        addLog(
          reason
            ? `Conexão perdida durante detecção: ${reason}`
            : "Conexão perdida durante detecção",
          "warn",
        );
        if (!receivedAnyMessage) {
          void fallbackDetectOnce().finally(() => {
            detectionComplete = true;
            panelState.isDetecting = false;
            if (panelState.activeTab === "fields") renderFieldsTab();
          });
          return;
        }
        detectionComplete = true;
        panelState.isDetecting = false;
        if (panelState.activeTab === "fields") renderFieldsTab();
      }
    });
  } catch (err) {
    addLog(`Erro ao detectar: ${err}`, "error");
    panelState.detectedFields = [];
    panelState.isDetecting = false;
    if (panelState.activeTab === "fields") renderFieldsTab();
  }

  await loadIgnoredFields();
  updateStatusBar();
}

Dependencies (Outgoing)

graph LR detectFieldsStreaming["detectFieldsStreaming"] renderFieldsTab["renderFieldsTab"] loadIgnoredFields["loadIgnoredFields"] detectFieldsStreaming -->|calls| renderFieldsTab detectFieldsStreaming -->|calls| loadIgnoredFields style detectFieldsStreaming fill:#dbeafe,stroke:#2563eb,stroke-width:2px click detectFieldsStreaming "36f1a94dcf5fea71.html" click renderFieldsTab "f02a4b6eabef0223.html" click loadIgnoredFields "7c1a2c45e97bbec4.html"
TargetType
renderFieldsTab calls
loadIgnoredFields calls

Impact (Incoming)

graph LR detectFieldsStreaming["detectFieldsStreaming"] detectFields["detectFields"] detectFields -->|calls| detectFieldsStreaming style detectFieldsStreaming fill:#dbeafe,stroke:#2563eb,stroke-width:2px click detectFieldsStreaming "36f1a94dcf5fea71.html" click detectFields "2645a01d8f49e548.html"
SourceType
detectFields calls