2026-02-15 22:17:37 +08:00
|
|
|
import { API_URL } from './config.js'
|
2026-02-07 08:53:37 +08:00
|
|
|
|
2026-02-13 09:24:50 +08:00
|
|
|
export async function fetchSuggestion(prefix, suffix, signal, apiUrl = API_URL) {
|
|
|
|
|
try {
|
|
|
|
|
const res = await fetch(apiUrl, {
|
|
|
|
|
method: 'POST',
|
|
|
|
|
headers: { 'Content-Type': 'application/json' },
|
|
|
|
|
body: JSON.stringify({ prefix, suffix, languageId: 'markdown' }),
|
|
|
|
|
signal
|
|
|
|
|
})
|
2026-02-07 08:53:37 +08:00
|
|
|
|
2026-02-13 09:24:50 +08:00
|
|
|
if (!res.ok) {
|
|
|
|
|
const errorText = await res.text()
|
|
|
|
|
throw new Error(`HTTP ${res.status}: ${errorText}`)
|
|
|
|
|
}
|
2026-02-07 08:53:37 +08:00
|
|
|
|
2026-02-13 09:24:50 +08:00
|
|
|
const reader = res.body?.getReader()
|
|
|
|
|
if (!reader) {
|
|
|
|
|
throw new Error('No reader available')
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
let text = ''
|
|
|
|
|
let buffer = ''
|
|
|
|
|
while (true) {
|
|
|
|
|
const { done, value } = await reader.read()
|
|
|
|
|
if (done) break
|
|
|
|
|
buffer += new TextDecoder().decode(value)
|
|
|
|
|
|
|
|
|
|
const lines = buffer.split('\n')
|
|
|
|
|
buffer = lines.pop() || ''
|
|
|
|
|
|
|
|
|
|
for (const line of lines) {
|
|
|
|
|
if (!line.startsWith('data: ')) continue
|
|
|
|
|
const jsonStr = line.slice(6).trim()
|
|
|
|
|
if (!jsonStr) continue
|
|
|
|
|
try {
|
|
|
|
|
const data = JSON.parse(jsonStr)
|
|
|
|
|
if (data.content) {
|
|
|
|
|
text += data.content
|
|
|
|
|
}
|
|
|
|
|
if (data.done || data.error) break
|
|
|
|
|
} catch (e) {
|
2026-02-15 22:17:37 +08:00
|
|
|
// skip invalid lines
|
2026-02-13 09:24:50 +08:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return text
|
|
|
|
|
} catch (e) {
|
|
|
|
|
if (e.name === 'AbortError') {
|
2026-02-15 22:17:37 +08:00
|
|
|
// ignore abort
|
2026-02-13 09:24:50 +08:00
|
|
|
} else {
|
2026-02-15 22:17:37 +08:00
|
|
|
throw e
|
2026-02-13 09:24:50 +08:00
|
|
|
}
|
2026-02-07 08:53:37 +08:00
|
|
|
}
|
|
|
|
|
}
|