Skip to content

Commit 4cbcded

Browse files
authored
add defaultsByInstallVersion (#4354)
1 parent 469594e commit 4cbcded

File tree

3 files changed

+285
-0
lines changed

3 files changed

+285
-0
lines changed

src/stores/settingStore.ts

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import { api } from '@/scripts/api'
77
import { app } from '@/scripts/app'
88
import type { SettingParams } from '@/types/settingTypes'
99
import type { TreeNode } from '@/types/treeExplorerTypes'
10+
import { compareVersions } from '@/utils/formatUtil'
1011

1112
export const getSettingInfo = (setting: SettingParams) => {
1213
const parts = setting.category || setting.id.split('.')
@@ -83,11 +84,56 @@ export const useSettingStore = defineStore('setting', () => {
8384
*/
8485
function getDefaultValue<K extends keyof Settings>(key: K): Settings[K] {
8586
const param = settingsById.value[key]
87+
88+
const versionedDefault = getVersionedDefaultValue(key, param)
89+
90+
if (versionedDefault) {
91+
return versionedDefault
92+
}
93+
8694
return typeof param?.defaultValue === 'function'
8795
? param.defaultValue()
8896
: param?.defaultValue
8997
}
9098

99+
function getVersionedDefaultValue<K extends keyof Settings>(
100+
key: K,
101+
param: SettingParams
102+
): Settings[K] | null {
103+
// get default versioned value, skipping if the key is 'Comfy.InstalledVersion' to prevent infinite loop
104+
if (param?.defaultsByInstallVersion && key !== 'Comfy.InstalledVersion') {
105+
const installedVersion = get('Comfy.InstalledVersion')
106+
107+
if (installedVersion) {
108+
const sortedVersions = Object.keys(param.defaultsByInstallVersion).sort(
109+
(a, b) => compareVersions(a, b)
110+
)
111+
112+
for (const version of sortedVersions.reverse()) {
113+
// Ensure the version is in a valid format before comparing
114+
if (!isValidVersionFormat(version)) {
115+
continue
116+
}
117+
118+
if (compareVersions(installedVersion, version) >= 0) {
119+
const versionedDefault = param.defaultsByInstallVersion[version]
120+
return typeof versionedDefault === 'function'
121+
? versionedDefault()
122+
: versionedDefault
123+
}
124+
}
125+
}
126+
}
127+
128+
return null
129+
}
130+
131+
function isValidVersionFormat(
132+
version: string
133+
): version is `${number}.${number}.${number}` {
134+
return /^\d+\.\d+\.\d+$/.test(version)
135+
}
136+
91137
/**
92138
* Register a setting.
93139
* @param setting - The setting to register.

src/types/settingTypes.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,10 @@ export interface Setting {
3535
export interface SettingParams extends FormItem {
3636
id: keyof Settings
3737
defaultValue: any | (() => any)
38+
defaultsByInstallVersion?: Record<
39+
`${number}.${number}.${number}`,
40+
any | (() => any)
41+
>
3842
onChange?: (newValue: any, oldValue?: any) => void
3943
// By default category is id.split('.'). However, changing id to assign
4044
// new category has poor backward compatibility. Use this field to overwrite

tests-ui/tests/store/settingStore.test.ts

Lines changed: 235 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,241 @@ describe('useSettingStore', () => {
109109
})
110110
})
111111

112+
describe('getDefaultValue', () => {
113+
beforeEach(() => {
114+
// Set up installed version for most tests
115+
store.settingValues['Comfy.InstalledVersion'] = '1.30.0'
116+
})
117+
118+
it('should return regular default value when no defaultsByInstallVersion', () => {
119+
const setting: SettingParams = {
120+
id: 'test.setting',
121+
name: 'Test Setting',
122+
type: 'text',
123+
defaultValue: 'regular-default'
124+
}
125+
store.addSetting(setting)
126+
127+
const result = store.getDefaultValue('test.setting')
128+
expect(result).toBe('regular-default')
129+
})
130+
131+
it('should return versioned default when user version matches', () => {
132+
const setting: SettingParams = {
133+
id: 'test.setting',
134+
name: 'Test Setting',
135+
type: 'text',
136+
defaultValue: 'regular-default',
137+
defaultsByInstallVersion: {
138+
'1.21.3': 'version-1.21.3-default',
139+
'1.40.3': 'version-1.40.3-default'
140+
}
141+
}
142+
store.addSetting(setting)
143+
144+
const result = store.getDefaultValue('test.setting')
145+
// installedVersion is 1.30.0, so should get 1.21.3 default
146+
expect(result).toBe('version-1.21.3-default')
147+
})
148+
149+
it('should return latest versioned default when user version is higher', () => {
150+
store.settingValues['Comfy.InstalledVersion'] = '1.50.0'
151+
152+
const setting: SettingParams = {
153+
id: 'test.setting',
154+
name: 'Test Setting',
155+
type: 'text',
156+
defaultValue: 'regular-default',
157+
defaultsByInstallVersion: {
158+
'1.21.3': 'version-1.21.3-default',
159+
'1.40.3': 'version-1.40.3-default'
160+
}
161+
}
162+
store.addSetting(setting)
163+
164+
const result = store.getDefaultValue('test.setting')
165+
// installedVersion is 1.50.0, so should get 1.40.3 default
166+
expect(result).toBe('version-1.40.3-default')
167+
})
168+
169+
it('should return regular default when user version is lower than all versioned defaults', () => {
170+
store.settingValues['Comfy.InstalledVersion'] = '1.10.0'
171+
172+
const setting: SettingParams = {
173+
id: 'test.setting',
174+
name: 'Test Setting',
175+
type: 'text',
176+
defaultValue: 'regular-default',
177+
defaultsByInstallVersion: {
178+
'1.21.3': 'version-1.21.3-default',
179+
'1.40.3': 'version-1.40.3-default'
180+
}
181+
}
182+
store.addSetting(setting)
183+
184+
const result = store.getDefaultValue('test.setting')
185+
// installedVersion is 1.10.0, lower than all versioned defaults
186+
expect(result).toBe('regular-default')
187+
})
188+
189+
it('should return regular default when no installed version (existing users)', () => {
190+
// Clear installed version to simulate existing user
191+
delete store.settingValues['Comfy.InstalledVersion']
192+
193+
const setting: SettingParams = {
194+
id: 'test.setting',
195+
name: 'Test Setting',
196+
type: 'text',
197+
defaultValue: 'regular-default',
198+
defaultsByInstallVersion: {
199+
'1.21.3': 'version-1.21.3-default',
200+
'1.40.3': 'version-1.40.3-default'
201+
}
202+
}
203+
store.addSetting(setting)
204+
205+
const result = store.getDefaultValue('test.setting')
206+
// No installed version, should use backward compatibility
207+
expect(result).toBe('regular-default')
208+
})
209+
210+
it('should handle function-based versioned defaults', () => {
211+
const setting: SettingParams = {
212+
id: 'test.setting',
213+
name: 'Test Setting',
214+
type: 'text',
215+
defaultValue: 'regular-default',
216+
defaultsByInstallVersion: {
217+
'1.21.3': () => 'dynamic-version-1.21.3-default',
218+
'1.40.3': () => 'dynamic-version-1.40.3-default'
219+
}
220+
}
221+
store.addSetting(setting)
222+
223+
const result = store.getDefaultValue('test.setting')
224+
// installedVersion is 1.30.0, so should get 1.21.3 default (executed)
225+
expect(result).toBe('dynamic-version-1.21.3-default')
226+
})
227+
228+
it('should handle function-based regular defaults with versioned defaults', () => {
229+
store.settingValues['Comfy.InstalledVersion'] = '1.10.0'
230+
231+
const setting: SettingParams = {
232+
id: 'test.setting',
233+
name: 'Test Setting',
234+
type: 'text',
235+
defaultValue: () => 'dynamic-regular-default',
236+
defaultsByInstallVersion: {
237+
'1.21.3': 'version-1.21.3-default',
238+
'1.40.3': 'version-1.40.3-default'
239+
}
240+
}
241+
store.addSetting(setting)
242+
243+
const result = store.getDefaultValue('test.setting')
244+
// installedVersion is 1.10.0, should fallback to function-based regular default
245+
expect(result).toBe('dynamic-regular-default')
246+
})
247+
248+
it('should handle complex version comparison correctly', () => {
249+
const setting: SettingParams = {
250+
id: 'test.setting',
251+
name: 'Test Setting',
252+
type: 'text',
253+
defaultValue: 'regular-default',
254+
defaultsByInstallVersion: {
255+
'1.21.3': 'version-1.21.3-default',
256+
'1.21.10': 'version-1.21.10-default',
257+
'1.40.3': 'version-1.40.3-default'
258+
}
259+
}
260+
store.addSetting(setting)
261+
262+
// Test with 1.21.5 - should get 1.21.3 default
263+
store.settingValues['Comfy.InstalledVersion'] = '1.21.5'
264+
expect(store.getDefaultValue('test.setting')).toBe(
265+
'version-1.21.3-default'
266+
)
267+
268+
// Test with 1.21.15 - should get 1.21.10 default
269+
store.settingValues['Comfy.InstalledVersion'] = '1.21.15'
270+
expect(store.getDefaultValue('test.setting')).toBe(
271+
'version-1.21.10-default'
272+
)
273+
274+
// Test with 1.21.3 exactly - should get 1.21.3 default
275+
store.settingValues['Comfy.InstalledVersion'] = '1.21.3'
276+
expect(store.getDefaultValue('test.setting')).toBe(
277+
'version-1.21.3-default'
278+
)
279+
})
280+
281+
it('should work with get() method using versioned defaults', () => {
282+
const setting: SettingParams = {
283+
id: 'test.setting',
284+
name: 'Test Setting',
285+
type: 'text',
286+
defaultValue: 'regular-default',
287+
defaultsByInstallVersion: {
288+
'1.21.3': 'version-1.21.3-default',
289+
'1.40.3': 'version-1.40.3-default'
290+
}
291+
}
292+
store.addSetting(setting)
293+
294+
// get() should use getDefaultValue internally
295+
const result = store.get('test.setting')
296+
expect(result).toBe('version-1.21.3-default')
297+
})
298+
299+
it('should handle mixed function and static versioned defaults', () => {
300+
const setting: SettingParams = {
301+
id: 'test.setting',
302+
name: 'Test Setting',
303+
type: 'text',
304+
defaultValue: 'regular-default',
305+
defaultsByInstallVersion: {
306+
'1.21.3': () => 'dynamic-1.21.3-default',
307+
'1.40.3': 'static-1.40.3-default'
308+
}
309+
}
310+
store.addSetting(setting)
311+
312+
// Test with 1.30.0 - should get dynamic 1.21.3 default
313+
store.settingValues['Comfy.InstalledVersion'] = '1.30.0'
314+
expect(store.getDefaultValue('test.setting')).toBe(
315+
'dynamic-1.21.3-default'
316+
)
317+
318+
// Test with 1.50.0 - should get static 1.40.3 default
319+
store.settingValues['Comfy.InstalledVersion'] = '1.50.0'
320+
expect(store.getDefaultValue('test.setting')).toBe(
321+
'static-1.40.3-default'
322+
)
323+
})
324+
325+
it('should handle version sorting correctly', () => {
326+
const setting: SettingParams = {
327+
id: 'test.setting',
328+
name: 'Test Setting',
329+
type: 'text',
330+
defaultValue: 'regular-default',
331+
defaultsByInstallVersion: {
332+
'1.40.3': 'version-1.40.3-default',
333+
'1.21.3': 'version-1.21.3-default', // Unsorted order
334+
'1.35.0': 'version-1.35.0-default'
335+
}
336+
}
337+
store.addSetting(setting)
338+
339+
// Test with 1.37.0 - should get 1.35.0 default (highest version <= 1.37.0)
340+
store.settingValues['Comfy.InstalledVersion'] = '1.37.0'
341+
expect(store.getDefaultValue('test.setting')).toBe(
342+
'version-1.35.0-default'
343+
)
344+
})
345+
})
346+
112347
describe('get and set', () => {
113348
it('should get default value when setting not exists', () => {
114349
const setting: SettingParams = {

0 commit comments

Comments
 (0)