File size: 2,638 Bytes
a641ed5
dcce181
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
a641ed5
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
dcce181
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
// api/client.js — svi API pozivi na Flask backend

const BASE = '/api'

async function request(method, path, body) {
  const res = await fetch(`${BASE}${path}`, {
    method,
    headers: { 'Content-Type': 'application/json' },
    body: body ? JSON.stringify(body) : undefined,
  })
  if (!res.ok) {
    const err = await res.json().catch(() => ({}))
    throw new Error(err.error || `HTTP ${res.status}`)
  }
  return res.json()
}

// Provjera statusa servera
export const checkHealth = () => request('GET', '/health')

// Analiza jednog isječka koda
export const analyzeCode = (code, language, filename) =>
  request('POST', '/analyze', { code, language, filename })

/**
 * Batch analiza s real-time streamingom.
 *
 * Umjesto da čeka sve rezultate (što uzrokuje timeout),
 * čita NDJSON stream i poziva callback za svaki rezultat
 * čim stigne s backenda.
 *
 * @param {Array}    submissions  - lista { id, file, code }
 * @param {Function} onResult     - poziva se za svaki gotov fajl: (result, index, total) => void
 * @param {Function} onProgress   - poziva se s postotkom napretka: (pct) => void
 * @returns {Promise<Object>}     - summary objekt na kraju
 */
export async function analyzeBatch(submissions, onResult, onProgress) {
  const res = await fetch(`${BASE}/analyze-batch`, {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({ submissions }),
  })

  if (!res.ok) {
    const err = await res.json().catch(() => ({}))
    throw new Error(err.error || `HTTP ${res.status}`)
  }

  // Čitamo stream liniju po liniju
  const reader  = res.body.getReader()
  const decoder = new TextDecoder()
  let   buffer  = ''
  let   count   = 0
  let   summary = null
  const total   = submissions.length

  while (true) {
    const { done, value } = await reader.read()
    if (done) break

    buffer += decoder.decode(value, { stream: true })
    const lines = buffer.split('\n')

    // Sve linije osim zadnje su kompletne
    buffer = lines.pop()

    for (const line of lines) {
      if (!line.trim()) continue
      try {
        const msg = JSON.parse(line)

        if (msg.type === 'result') {
          count++
          if (onResult)   onResult(msg.data, count, total)
          if (onProgress) onProgress(Math.round((count / total) * 100))
        }

        if (msg.type === 'summary') {
          summary = msg.data
        }
      } catch {
        // Ignoriraj neispravne linije
      }
    }
  }

  return summary || { total: count }
}

// Matrica sličnosti
export const computeSimilarity = (submissions) =>
  request('POST', '/similarity', { submissions })