diff --git a/src/modules/main_menu/components/home-page.vue b/src/modules/main_menu/components/home-page.vue index 30c2c595..57804e34 100644 --- a/src/modules/main_menu/components/home-page.vue +++ b/src/modules/main_menu/components/home-page.vue @@ -190,7 +190,7 @@ diff --git a/src/settings/context.ts b/src/settings/context.ts index b991d4cd..5f595bdc 100644 --- a/src/settings/context.ts +++ b/src/settings/context.ts @@ -7,7 +7,7 @@ import {EventEmitter} from 'utilities/events'; import {has, get as getter, array_equals, set_equals, map_equals, deep_equals} from 'utilities/object'; -import * as DEFINITIONS from './typehandlers'; +import DEFINITIONS from './typehandlers'; import type { AllSettingsKeys, ContextData, SettingMetadata, SettingType, SettingDefinition, SettingsKeys } from './types'; import type SettingsManager from '.'; import type SettingsProfile from './profile'; diff --git a/src/settings/index.ts b/src/settings/index.ts index 622aa196..0c004bd1 100644 --- a/src/settings/index.ts +++ b/src/settings/index.ts @@ -762,10 +762,13 @@ export default class SettingsManager extends Module<'settings', SettingsEvents> old_provider.disableEvents(); // When transfering, we clear all existing settings. - await new_provider.clear(); + new_provider.clear(); if ( new_provider instanceof AdvancedSettingsProvider && new_provider.supportsBlobs ) await new_provider.clearBlobs(); + // Wait for it to do that. + await new_provider.flush(); + for(const [key,val] of old_provider.entries()) new_provider.set(key, val); @@ -1128,14 +1131,16 @@ export default class SettingsManager extends Module<'settings', SettingsEvents> // Context Helpers // ======================================================================== - context(env: ContextData) { return this.main_context.context(env) } + context(env: ContextData) { + return this.main_context.context(env); + } get< K extends AllSettingsKeys, TValue = SettingType - >( - key: K - ): TValue { return this.main_context.get(key); } + >(key: K): TValue { + return this.main_context.get(key); + } getChanges< K extends SettingsKeys, diff --git a/src/settings/typehandlers.js b/src/settings/typehandlers.ts similarity index 61% rename from src/settings/typehandlers.js rename to src/settings/typehandlers.ts index 71a96eb1..6b78d48c 100644 --- a/src/settings/typehandlers.js +++ b/src/settings/typehandlers.ts @@ -1,32 +1,38 @@ 'use strict'; +import type Logger from "utilities/logging"; +import type SettingsProfile from "./profile"; +import type { SettingDefinition, SettingsTypeHandler } from "./types"; +import type SettingsContext from "./context"; + // ============================================================================ // Settings Types // ============================================================================ const DEFAULT = Symbol('default'); -export const basic = { - get(key, profiles) { + +export const basic: SettingsTypeHandler = { + get(key: string, profiles: SettingsProfile[]) { for(const profile of profiles) if ( profile.has(key) ) return [ - profile.get(key), + profile.get(key) as T, [profile.id] ] } } -export const object_merge = { - get(key, profiles, log) { - const values = [], - sources = []; +export const object_merge: SettingsTypeHandler = { + get(key: string, profiles: SettingsProfile[], definition: SettingDefinition, log: Logger) { + const values: T[] = [], + sources: number[] = []; for(const profile of profiles) if ( profile.has(key) ) { - const val = profile.get(key); - if ( typeof val !== 'object' ) { + const val = profile.get(key); + if ( ! val || typeof val !== 'object' ) { log.warn(`Profile #${profile.id} has an invalid value for "${key}" of type ${typeof val}. Skipping.`); continue; } @@ -44,14 +50,16 @@ export const object_merge = { } -export const basic_array_merge = { - get(key, profiles, log) { - const values = [], - sources = []; +type UnwrapArray = T extends Array ? U : T; + +export const basic_array_merge: SettingsTypeHandler = { + get(key: string, profiles: SettingsProfile[], definition: SettingDefinition, log: Logger) { + const values: UnwrapArray[] = [], + sources: number[] = []; for(const profile of profiles) if ( profile.has(key) ) { - const val = profile.get(key); + const val = profile.get>(key); if ( ! Array.isArray(val) ) { log.warn(`Profile #${profile.id} has an invalid value for "${key}"`); continue; @@ -71,7 +79,7 @@ export const basic_array_merge = { } -export const array_merge = { +export const array_merge: SettingsTypeHandler = { default(val) { const values = []; for(const v of val) @@ -81,13 +89,20 @@ export const array_merge = { return values; }, - get(key, profiles, definition, log, ctx) { - const values = [], - sources = []; - let trailing = []; + get( + key: string, + profiles: SettingsProfile[], + definition: SettingDefinition, + log: Logger, + ctx: SettingsContext + ) { + + const values: UnwrapArray[] = [], + sources: number[] = []; + let trailing: UnwrapArray[] = []; let had_value = false; - let profs = profiles; + let profs: (SettingsProfile | typeof DEFAULT)[] = profiles; if ( definition.inherit_default ) profs = [...profiles, DEFAULT]; @@ -109,7 +124,7 @@ export const array_merge = { continue; } - const trail = []; + const trail: UnwrapArray[] = []; if ( profile !== DEFAULT ) sources.push(profile.id); @@ -141,3 +156,12 @@ export const array_merge = { ] } } + + + +export default { + basic, + object_merge, + basic_array_merge, + array_merge +} as Record; diff --git a/src/settings/types.ts b/src/settings/types.ts index 06f20c74..367860ac 100644 --- a/src/settings/types.ts +++ b/src/settings/types.ts @@ -1,8 +1,10 @@ import type SettingsManager from "."; import type { FilterData } from "../utilities/filtering"; +import type Logger from "../utilities/logging"; import type { PathNode } from "../utilities/path-parser"; import type { ExtractSegments, ExtractType, JoinKeyPaths, ObjectKeyPaths, OptionalPromise, OptionallyCallable, RecursivePartial, SettingsTypeMap } from "../utilities/types"; import type SettingsContext from "./context"; +import type SettingsProfile from "./profile"; import type { SettingsProvider } from "./providers"; @@ -103,7 +105,7 @@ export type SettingMetadata = { export type SettingDefinition = { - default: T, + default: ((ctx: SettingsContext) => T) | T, type?: string; equals?: 'requirements' | ((new_value: T, old_value: T | undefined, cache: Map, old_cache: Map) => boolean); @@ -114,6 +116,9 @@ export type SettingDefinition = { required_by?: string[]; requires?: string[]; + always_inherit?: boolean; + inherit_default?: boolean; + // Tracking __source?: string | null; @@ -205,6 +210,24 @@ export type SettingsProfileMetadata = { }; +// Type Handlers + +export type SettingsTypeHandler = { + + default?(input: any, definition: SettingDefinition, log: Logger): any; + + get( + key: string, + profiles: SettingsProfile[], + definition: SettingDefinition, + log: Logger, + ctx: SettingsContext + ): [unknown, number[]] | null | undefined; + +} + + + // Processors export type SettingProcessor = (