FERS 1.0.0
The Flexible Extensible Radar Simulator
Loading...
Searching...
No Matches
backendSlice.ts
Go to the documentation of this file.
1// SPDX-License-Identifier: GPL-2.0-only
2// Copyright (c) 2025-present FERS Contributors (see AUTHORS.md).
3
4import { invoke } from '@tauri-apps/api/core';
5import { StateCreator } from 'zustand';
6import { buildHydratedScenarioState, parseScenarioData } from '../hydration';
7import {
8 serializeAntenna,
9 serializeGlobalParameters,
10 serializePlatform,
11 serializeTiming,
12 serializeWaveform,
13} from '../serializers';
14import { enqueueFullSync } from '../syncQueue';
15import { BackendActions, ScenarioState, ScenarioStore } from '../types';
16
17/**
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.
21 */
22export function buildScenarioJson(state: ScenarioState): string {
23 const { globalParameters, waveforms, timings, antennas, platforms } = state;
24 const scenarioJson = {
25 simulation: {
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),
32 },
33 };
34 return JSON.stringify(scenarioJson, null, 2);
35}
36
37export const createBackendSlice: StateCreator<
38 ScenarioStore,
39 [['zustand/immer', never]],
40 [],
41 BackendActions
42> = (set, get) => ({
43 syncBackend: async () => {
44 set({ isBackendSyncing: true });
45 try {
46 await enqueueFullSync(() => buildScenarioJson(get()));
47 set((state) => {
48 state.isBackendSyncing = false;
49 state.backendVersion += 1;
50 });
51 } catch (error) {
52 set({ isBackendSyncing: false });
53 throw error;
54 }
55 },
56 fetchFromBackend: async () => {
57 try {
58 const jsonState = await invoke<string>('get_scenario_as_json');
59 const parsedJson = JSON.parse(jsonState);
60 const scenarioData = parseScenarioData(parsedJson);
61 if (!scenarioData) {
62 throw new Error('Failed to hydrate scenario from backend JSON');
63 }
64
65 set(
66 buildHydratedScenarioState(get(), scenarioData, {
67 isDirty: false,
68 preserveSelection: true,
69 preserveCurrentTime: true,
70 })
71 );
72 } catch (error) {
73 console.error('Failed to fetch state from backend:', error);
74 throw error;
75 }
76 },
77});