1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
|
import { toast } from "sonner";
import { create } from "zustand";
import {
createInstance,
deleteInstance,
duplicateInstance,
exportInstance,
getActiveInstance,
getInstance,
importInstance,
listInstances,
repairInstances,
setActiveInstance as setActiveInstanceCommand,
updateInstance,
} from "@/client";
import type { Instance } from "@/types";
interface InstanceState {
instances: Instance[];
activeInstance: Instance | null;
refresh: () => Promise<void>;
create: (name: string) => Promise<Instance>;
delete: (id: string) => Promise<void>;
update: (instance: Instance) => Promise<void>;
setActiveInstance: (instance: Instance) => Promise<void>;
duplicate: (id: string, newName: string) => Promise<Instance | null>;
exportArchive: (id: string, archivePath: string) => Promise<void>;
importArchive: (
archivePath: string,
newName?: string,
) => Promise<Instance | null>;
repair: () => Promise<void>;
get: (id: string) => Promise<Instance | null>;
}
export const useInstanceStore = create<InstanceState>((set, get) => ({
instances: [],
activeInstance: null,
refresh: async () => {
try {
const instances = await listInstances();
let activeInstance = await getActiveInstance();
if (
activeInstance &&
!instances.some((instance) => instance.id === activeInstance?.id)
) {
activeInstance = null;
}
if (!activeInstance && instances.length > 0) {
await setActiveInstanceCommand(instances[0].id);
activeInstance = instances[0];
}
set({ instances, activeInstance });
} catch (e) {
console.error("Failed to load instances:", e);
toast.error("Error loading instances");
}
},
create: async (name) => {
const { refresh } = get();
const instance = await createInstance(name);
await setActiveInstanceCommand(instance.id);
await refresh();
toast.success(`Instance "${name}" created successfully`);
return instance;
},
delete: async (id) => {
const { refresh } = get();
try {
await deleteInstance(id);
await refresh();
toast.success("Instance deleted successfully");
} catch (e) {
console.error("Failed to delete instance:", e);
toast.error(String(e));
}
},
update: async (instance) => {
const { refresh } = get();
try {
await updateInstance(instance);
await refresh();
toast.success("Instance updated successfully");
} catch (e) {
console.error("Failed to update instance:", e);
toast.error("Error updating instance");
}
},
setActiveInstance: async (instance) => {
await setActiveInstanceCommand(instance.id);
set({ activeInstance: instance });
},
duplicate: async (id, newName) => {
const { refresh } = get();
try {
const instance = await duplicateInstance(id, newName);
await setActiveInstanceCommand(instance.id);
await refresh();
toast.success(`Instance duplicated as "${newName}"`);
return instance;
} catch (e) {
console.error("Failed to duplicate instance:", e);
toast.error(String(e));
return null;
}
},
exportArchive: async (id, archivePath) => {
try {
await exportInstance(id, archivePath);
toast.success("Instance exported successfully");
} catch (e) {
console.error("Failed to export instance:", e);
toast.error(String(e));
}
},
importArchive: async (archivePath, newName) => {
const { refresh } = get();
try {
const instance = await importInstance(archivePath, newName);
await setActiveInstanceCommand(instance.id);
await refresh();
toast.success(`Instance "${instance.name}" imported successfully`);
return instance;
} catch (e) {
console.error("Failed to import instance:", e);
toast.error(String(e));
return null;
}
},
repair: async () => {
const { refresh } = get();
try {
const result = await repairInstances();
await refresh();
toast.success(
`Repair completed: restored ${result.restoredInstances}, removed ${result.removedStaleEntries}`,
);
} catch (e) {
console.error("Failed to repair instances:", e);
toast.error(String(e));
}
},
get: async (id) => {
try {
return await getInstance(id);
} catch (e) {
console.error("Failed to get instance:", e);
return null;
}
},
}));
|