@@ -14,44 +14,34 @@ import {
1414import { deleteAuthState } from "./auth-store.js" ;
1515import { EXA_MCP_SERVER_NAME } from "./exa.js" ;
1616
17- export interface GlobalSettingsWriter {
18- readonly enqueue : < T > ( job : ( ) => Promise < T > ) => Promise < T > ;
19- readonly update : (
20- apply : ( base : Settings ) => Settings | null ,
21- ) => Promise < Settings | null > ;
17+ interface SettingsWriter < T > {
18+ readonly enqueue : < R > ( job : ( ) => Promise < R > ) => Promise < R > ;
19+ readonly update : ( apply : ( base : T ) => T | null ) => Promise < T | null > ;
2220 readonly updateAt : (
2321 path : string ,
24- apply : ( base : Settings ) => Settings | null ,
25- ) => Promise < Settings | null > ;
26- readonly mutate : (
27- apply : ( base : Settings ) => Settings | null ,
28- ) => Promise < "ok" | "skipped" > ;
22+ apply : ( base : T ) => T | null ,
23+ ) => Promise < T | null > ;
24+ readonly mutate : ( apply : ( base : T ) => T | null ) => Promise < "ok" | "skipped" > ;
2925 readonly mutateAt : (
3026 path : string ,
31- apply : ( base : Settings ) => Settings | null ,
27+ apply : ( base : T ) => T | null ,
3228 ) => Promise < "ok" | "skipped" > ;
3329}
3430
35- interface GlobalSettingsWriterDeps {
36- readonly load : ( path : string ) => Promise < Settings | null > ;
37- readonly save : ( path : string , settings : Settings ) => Promise < void > ;
38- }
31+ export type GlobalSettingsWriter = SettingsWriter < Settings > ;
32+ export type LocalSettingsWriter = SettingsWriter < LocalSettings > ;
3933
40- const defaultWriterDeps : GlobalSettingsWriterDeps = {
41- load : loadGlobalSettingsWriteBase ,
42- save : saveGlobalSettings ,
43- } ;
34+ interface SettingsWriterDeps < T > {
35+ readonly load : ( path : string ) => Promise < T | null > ;
36+ readonly save : ( path : string , settings : T ) => Promise < void > ;
37+ }
4438
45- export function createGlobalSettingsWriter (
39+ function createSettingsWriter < T > (
4640 path : string ,
47- deps : Partial < GlobalSettingsWriterDeps > = { } ,
48- ) : GlobalSettingsWriter {
49- const writerDeps : GlobalSettingsWriterDeps = {
50- ...defaultWriterDeps ,
51- ...deps ,
52- } ;
41+ deps : SettingsWriterDeps < T > ,
42+ ) : SettingsWriter < T > {
5343 let tail = Promise . resolve ( ) ;
54- const enqueue = < T > ( job : ( ) => Promise < T > ) : Promise < T > => {
44+ const enqueue = < R > ( job : ( ) => Promise < R > ) : Promise < R > => {
5545 const run = tail . then ( job ) ;
5646 tail = run . then (
5747 ( ) => undefined ,
@@ -62,20 +52,20 @@ export function createGlobalSettingsWriter(
6252
6353 const updateAt = (
6454 settingsPath : string ,
65- apply : ( base : Settings ) => Settings | null ,
66- ) : Promise < Settings | null > =>
55+ apply : ( base : T ) => T | null ,
56+ ) : Promise < T | null > =>
6757 enqueue ( async ( ) => {
68- const base = await writerDeps . load ( settingsPath ) ;
58+ const base = await deps . load ( settingsPath ) ;
6959 if ( base === null ) return null ;
7060 const next = apply ( base ) ;
7161 if ( next === null ) return base ;
72- await writerDeps . save ( settingsPath , next ) ;
62+ await deps . save ( settingsPath , next ) ;
7363 return next ;
7464 } ) ;
7565
7666 const mutateAt = async (
7767 settingsPath : string ,
78- apply : ( base : Settings ) => Settings | null ,
68+ apply : ( base : T ) => T | null ,
7969 ) : Promise < "ok" | "skipped" > =>
8070 ( await updateAt ( settingsPath , apply ) ) === null ? "skipped" : "ok" ;
8171
@@ -88,78 +78,26 @@ export function createGlobalSettingsWriter(
8878 } ;
8979}
9080
91- export interface LocalSettingsWriter {
92- readonly enqueue : < T > ( job : ( ) => Promise < T > ) => Promise < T > ;
93- readonly update : (
94- apply : ( base : LocalSettings ) => LocalSettings | null ,
95- ) => Promise < LocalSettings | null > ;
96- readonly updateAt : (
97- path : string ,
98- apply : ( base : LocalSettings ) => LocalSettings | null ,
99- ) => Promise < LocalSettings | null > ;
100- readonly mutate : (
101- apply : ( base : LocalSettings ) => LocalSettings | null ,
102- ) => Promise < "ok" | "skipped" > ;
103- readonly mutateAt : (
104- path : string ,
105- apply : ( base : LocalSettings ) => LocalSettings | null ,
106- ) => Promise < "ok" | "skipped" > ;
107- }
108-
109- interface LocalSettingsWriterDeps {
110- readonly load : ( path : string ) => Promise < LocalSettings | null > ;
111- readonly save : ( path : string , settings : LocalSettings ) => Promise < void > ;
81+ export function createGlobalSettingsWriter (
82+ path : string ,
83+ deps : Partial < SettingsWriterDeps < Settings > > = { } ,
84+ ) : GlobalSettingsWriter {
85+ return createSettingsWriter ( path , {
86+ load : loadGlobalSettingsWriteBase ,
87+ save : saveGlobalSettings ,
88+ ...deps ,
89+ } ) ;
11290}
11391
114- const defaultLocalWriterDeps : LocalSettingsWriterDeps = {
115- load : loadLocalSettingsWriteBase ,
116- save : saveLocalSettings ,
117- } ;
118-
11992export function createLocalSettingsWriter (
12093 path : string ,
121- deps : Partial < LocalSettingsWriterDeps > = { } ,
94+ deps : Partial < SettingsWriterDeps < LocalSettings > > = { } ,
12295) : LocalSettingsWriter {
123- const writerDeps : LocalSettingsWriterDeps = {
124- ...defaultLocalWriterDeps ,
96+ return createSettingsWriter ( path , {
97+ load : loadLocalSettingsWriteBase ,
98+ save : saveLocalSettings ,
12599 ...deps ,
126- } ;
127- let tail = Promise . resolve ( ) ;
128- const enqueue = < T > ( job : ( ) => Promise < T > ) : Promise < T > => {
129- const run = tail . then ( job ) ;
130- tail = run . then (
131- ( ) => undefined ,
132- ( ) => undefined ,
133- ) ;
134- return run ;
135- } ;
136-
137- const updateAt = (
138- settingsPath : string ,
139- apply : ( base : LocalSettings ) => LocalSettings | null ,
140- ) : Promise < LocalSettings | null > =>
141- enqueue ( async ( ) => {
142- const base = await writerDeps . load ( settingsPath ) ;
143- if ( base === null ) return null ;
144- const next = apply ( base ) ;
145- if ( next === null ) return base ;
146- await writerDeps . save ( settingsPath , next ) ;
147- return next ;
148- } ) ;
149-
150- const mutateAt = async (
151- settingsPath : string ,
152- apply : ( base : LocalSettings ) => LocalSettings | null ,
153- ) : Promise < "ok" | "skipped" > =>
154- ( await updateAt ( settingsPath , apply ) ) === null ? "skipped" : "ok" ;
155-
156- return {
157- enqueue,
158- update : ( apply ) => updateAt ( path , apply ) ,
159- updateAt,
160- mutate : ( apply ) => mutateAt ( path , apply ) ,
161- mutateAt,
162- } ;
100+ } ) ;
163101}
164102
165103export type PersistMCPServerResult =
0 commit comments