(locale: string, onProgress?: (p: DemoProgress) => void)
| 142 | } |
| 143 | |
| 144 | async importDemo(locale: string, onProgress?: (p: DemoProgress) => void): Promise<DemoImportResult> { |
| 145 | return new Promise((resolve) => { |
| 146 | fetchWithAuth(`${getBaseUrl()}/demo/import`, { |
| 147 | method: 'POST', |
| 148 | headers: { 'Content-Type': 'application/json' }, |
| 149 | body: JSON.stringify({ locale }), |
| 150 | }) |
| 151 | .then(async (resp) => { |
| 152 | if (!resp.ok || !resp.body) { |
| 153 | resolve({ success: false, error: `HTTP ${resp.status}` }) |
| 154 | return |
| 155 | } |
| 156 | |
| 157 | const reader = resp.body.getReader() |
| 158 | const decoder = new TextDecoder() |
| 159 | let buffer = '' |
| 160 | |
| 161 | while (true) { |
| 162 | const { done, value } = await reader.read() |
| 163 | if (done) break |
| 164 | buffer += decoder.decode(value, { stream: true }) |
| 165 | |
| 166 | const lines = buffer.split('\n') |
| 167 | buffer = lines.pop() || '' |
| 168 | |
| 169 | let eventType = '' |
| 170 | for (const line of lines) { |
| 171 | if (line.startsWith('event: ')) { |
| 172 | eventType = line.slice(7).trim() |
| 173 | } else if (line.startsWith('data: ')) { |
| 174 | const data = JSON.parse(line.slice(6)) |
| 175 | if (eventType === 'progress') { |
| 176 | if (data.stage === 'downloading' || data.stage === 'importing') { |
| 177 | onProgress?.({ stage: data.stage }) |
| 178 | } |
| 179 | } else if (eventType === 'result') { |
| 180 | resolve(data as DemoImportResult) |
| 181 | return |
| 182 | } |
| 183 | eventType = '' |
| 184 | } |
| 185 | } |
| 186 | } |
| 187 | resolve({ success: false, error: 'Stream ended without result' }) |
| 188 | }) |
| 189 | .catch((e) => resolve({ success: false, error: String(e) })) |
| 190 | }) |
| 191 | } |
| 192 | |
| 193 | async analyzeIncrementalImport(sessionId: string, file: File | string): Promise<IncrementalAnalysis> { |
| 194 | if (typeof file === 'string') { |
nothing calls this directly
no test coverage detected