(id: string)
| 156 | |
| 157 | /** Export a workspace as a downloadable zip Blob. */ |
| 158 | export async function exportWorkspace(id: string): Promise<Blob> { |
| 159 | const backend = await _getBackend(); |
| 160 | if (backend === 'ephemeral') { |
| 161 | // Ensure latest state is saved before exporting |
| 162 | const { store } = await import('./store'); |
| 163 | const state = store.getState(); |
| 164 | if (state.activeWorkspace?.id === id) { |
| 165 | const EXCLUDED = new Set([ |
| 166 | 'models', 'selectedModelId', 'testedModels', |
| 167 | 'dataLoaderConnectParams', 'identity', 'serverConfig', |
| 168 | 'chartSynthesisInProgress', 'chartInsightInProgress', |
| 169 | 'cleanInProgress', 'sessionLoading', 'sessionLoadingLabel', |
| 170 | ]); |
| 171 | const serializable: Record<string, unknown> = {}; |
| 172 | for (const [key, value] of Object.entries(state)) { |
| 173 | if (!EXCLUDED.has(key)) serializable[key] = value; |
| 174 | } |
| 175 | await saveWorkspaceState(serializable); |
| 176 | } |
| 177 | return exportWorkspaceToZip(id); |
| 178 | } |
| 179 | // Server: load state, then export via server endpoint |
| 180 | const { data } = await apiRequest<{ state: any }>(getUrls().SESSION_LOAD, { |
| 181 | method: 'POST', |
| 182 | headers: { 'Content-Type': 'application/json' }, |
| 183 | body: JSON.stringify({ id }), |
| 184 | }); |
| 185 | if (!data.state) { |
| 186 | throw new Error('Failed to load workspace for export'); |
| 187 | } |
| 188 | const exportRes = await fetchWithIdentity(getUrls().SESSION_EXPORT, { |
| 189 | method: 'POST', |
| 190 | headers: { 'Content-Type': 'application/json' }, |
| 191 | body: JSON.stringify({ state: data.state, workspace_id: id }), |
| 192 | }); |
| 193 | await assertDownloadResponseOk(exportRes, 'Export failed'); |
| 194 | return exportRes.blob(); |
| 195 | } |
| 196 | |
| 197 | /** Import a workspace from a zip file. Returns the restored state. */ |
| 198 | export async function importWorkspace( |
no test coverage detected