1// SPDX-License-Identifier: GPL-2.0-only
2// Copyright (c) 2025-present FERS Contributors (see AUTHORS.md).
4import { invoke } from '@tauri-apps/api/core';
5import { StateCreator } from 'zustand';
6import { buildHydratedScenarioState, parseScenarioData } from '../hydration';
9 serializeGlobalParameters,
13} from '../serializers';
14import { enqueueFullSync } from '../syncQueue';
15import { BackendActions, ScenarioState, ScenarioStore } from '../types';
18 * Build the full scenario JSON payload expected by the `update_scenario_from_json`
19 * Tauri command. Extracted from `syncBackend` so the sync queue can capture a
20 * snapshot at task-execution time rather than enqueue time.
22export function buildScenarioJson(state: ScenarioState): string {
23 const { globalParameters, waveforms, timings, antennas, platforms } = state;
24 const scenarioJson = {
26 name: globalParameters.simulation_name,
27 parameters: serializeGlobalParameters(globalParameters),
28 waveforms: waveforms.map(serializeWaveform),
29 timings: timings.map(serializeTiming),
30 antennas: antennas.map(serializeAntenna),
31 platforms: platforms.map(serializePlatform),
34 return JSON.stringify(scenarioJson, null, 2);
37export const createBackendSlice: StateCreator<
39 [['zustand/immer', never]],
43 syncBackend: async () => {
44 set({ isBackendSyncing: true });
46 await enqueueFullSync(() => buildScenarioJson(get()));
48 state.isBackendSyncing = false;
49 state.backendVersion += 1;
52 set({ isBackendSyncing: false });
56 fetchFromBackend: async () => {
58 const jsonState = await invoke<string>('get_scenario_as_json');
59 const parsedJson = JSON.parse(jsonState);
60 const scenarioData = parseScenarioData(parsedJson);
62 throw new Error('Failed to hydrate scenario from backend JSON');
66 buildHydratedScenarioState(get(), scenarioData, {
68 preserveSelection: true,
69 preserveCurrentTime: true,
73 console.error('Failed to fetch state from backend:', error);