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
|
import type { Tab, TabsState } from "./tabs";
import {
initialState,
closeTab as reduceCloseTab,
createTab as reduceCreateTab,
newDraft as reduceNewDraft,
selectTab as reduceSelectTab,
setModel as reduceSetModel,
setTitle as reduceSetTitle,
activeTab as selectActiveTab,
} from "./tabs";
export interface TabsStorage {
load(): TabsState | null;
save(state: TabsState): void;
}
export interface TabsStore {
readonly tabs: readonly Tab[];
readonly activeConversationId: string | null;
readonly activeTab: Tab | null;
newDraft(): void;
createTab(tab: Tab): void;
selectTab(conversationId: string): void;
closeTab(conversationId: string): void;
setModel(conversationId: string, model: string): void;
setTitle(conversationId: string, title: string): void;
}
export function createTabsStore(storage: TabsStorage): TabsStore {
let state = $state<TabsState>(storage.load() ?? initialState());
function apply(next: TabsState): void {
state = next;
storage.save(next);
}
return {
get tabs(): readonly Tab[] {
return state.tabs;
},
get activeConversationId(): string | null {
return state.activeConversationId;
},
get activeTab(): Tab | null {
return selectActiveTab(state);
},
newDraft(): void {
apply(reduceNewDraft(state));
},
createTab(tab: Tab): void {
apply(reduceCreateTab(state, tab));
},
selectTab(conversationId: string): void {
apply(reduceSelectTab(state, conversationId));
},
closeTab(conversationId: string): void {
apply(reduceCloseTab(state, conversationId));
},
setModel(conversationId: string, model: string): void {
apply(reduceSetModel(state, conversationId, model));
},
setTitle(conversationId: string, title: string): void {
apply(reduceSetTitle(state, conversationId, title));
},
};
}
|