import deepmerge from 'deepmerge' /** * Config can be either an object or a function that receives baseConfig and data * and returns a partial config to be merged with the base. */ export type ConfigOrFn = | Partial | ((baseConfig: TConfig, data: TData) => Partial) /** * Resolves a widget config that may be either a partial object or a function receiving the computed base config and data. If it is a function, calls it with `baseConfig` and `data`; otherwise returns the value as-is. * * @param config - The config object or function to resolve. * @param baseConfig - The computed base configuration. * @param data - The widget data. * @returns Resolved partial config, or undefined. * * @example * ```tsx * const resolved = resolveConfig( * (base, data) => ({ maxItems: base.maxItems + 5 }), * baseConfig, * widgetData, * ) * ``` */ export function resolveConfig( config: ConfigOrFn | undefined, baseConfig: TConfig, data: TData, ): Partial | undefined { if (typeof config === 'function') { return config(baseConfig, data) } return config } /** * Deep-merges two partial widget config objects using `deepmerge`, with arrays replaced rather than concatenated. * * @param options - A tuple of two partial configs to merge (base and override). * @returns The merged config object. * * @example * ```tsx * const finalConfig = mergeWidgetConfig(baseConfig, resolvedConfig) * ``` */ export function mergeWidgetConfig( ...options: [Partial | undefined, Partial | undefined] ): T { return deepmerge(options[0] ?? {}, options[1] ?? {}, { arrayMerge(_, source) { return source as T[keyof T][] }, }) }