async function preResolveOptions(inlineOptions, viteUserConfig, viteEnv) {
	if (!inlineOptions) {
		inlineOptions = {};
	}
	/** @type {import('vite').UserConfig} */
	const viteConfigWithResolvedRoot = {
		...viteUserConfig,
		root: resolveViteRoot(viteUserConfig)
	};
	const isBuild = viteEnv.command === 'build';
	/** @type {Partial<import('../types/options.d.ts').PreResolvedOptions>} */
	const defaultOptions = {
		extensions: DEFAULT_SVELTE_EXT,
		emitCss: true,
		prebundleSvelteLibraries: !isBuild
	};
	const svelteConfig = convertPluginOptions(
		await loadSvelteConfig(viteConfigWithResolvedRoot, inlineOptions)
	);
	/** @type {Partial<import('../types/options.d.ts').PreResolvedOptions>} */
	const extraOptions = {
		root: viteConfigWithResolvedRoot.root,
		isBuild,
		isServe: viteEnv.command === 'serve',
		isDebug: process.env.DEBUG != null
	};

	const merged = /** @type {import('../types/options.d.ts').PreResolvedOptions} */ (
		mergeConfigs(defaultOptions, svelteConfig, inlineOptions, extraOptions)
	);
	// configFile of svelteConfig contains the absolute path it was loaded from,
	// prefer it over the possibly relative inline path
	if (svelteConfig?.configFile) {
		merged.configFile = svelteConfig.configFile;
	}
	return merged;
}
used in config phase, merges the default options, svelte config, and inline options
@param {Partial<import('../public.d.ts').Options> | undefined} inlineOptions
@param {import('vite').UserConfig} viteUserConfig
@param {import('vite').ConfigEnv} viteEnv
@returns {Promise<import('../types/options.d.ts').PreResolvedOptions>}