1
0
Fork 0

fix(gui): load remaining defaults from server params

This commit is contained in:
Sean Sube 2023-01-27 17:27:11 -06:00
parent 9b37c174d1
commit 88e4f74efe
4 changed files with 352 additions and 113 deletions

View File

@ -1,5 +1,11 @@
{ {
"version": "0.5.0", "version": "0.5.0",
"bottom": {
"default": 0,
"min": 0,
"max": 512,
"step": 8
},
"cfg": { "cfg": {
"default": 6, "default": 6,
"min": 1, "min": 1,
@ -18,12 +24,26 @@
"max": 1, "max": 1,
"step": 0.1 "step": 0.1
}, },
"fillColor": {
"default": "#000000",
"keys": []
},
"filter": {
"default": "none",
"keys": []
},
"height": { "height": {
"default": 512, "default": 512,
"min": 64, "min": 64,
"max": 1024, "max": 1024,
"step": 8 "step": 8
}, },
"left": {
"default": 0,
"min": 0,
"max": 512,
"step": 8
},
"model": { "model": {
"default": "stable-diffusion-onnx-v1-5", "default": "stable-diffusion-onnx-v1-5",
"keys": [] "keys": []
@ -32,6 +52,10 @@
"default": "", "default": "",
"keys": [] "keys": []
}, },
"noise": {
"default": "histogram",
"keys": []
},
"outscale": { "outscale": {
"default": 1, "default": 1,
"min": 1, "min": 1,
@ -46,6 +70,12 @@
"default": "an astronaut eating a hamburger", "default": "an astronaut eating a hamburger",
"keys": [] "keys": []
}, },
"right": {
"default": 0,
"min": 0,
"max": 512,
"step": 8
},
"scale": { "scale": {
"default": 1, "default": 1,
"min": 1, "min": 1,
@ -74,6 +104,12 @@
"max": 1, "max": 1,
"step": 0.01 "step": 0.01
}, },
"top": {
"default": 0,
"min": 0,
"max": 512,
"step": 8
},
"width": { "width": {
"default": 512, "default": 512,
"min": 64, "min": 64,

View File

@ -1,22 +1,36 @@
/* eslint-disable max-lines */
import { doesExist } from '@apextoaster/js-utils'; import { doesExist } from '@apextoaster/js-utils';
import { ServerParams } from './config.js'; import { ServerParams } from './config.js';
/**
* Shared parameters for anything using models, which is pretty much everything.
*/
export interface ModelParams { export interface ModelParams {
/** /**
* Which ONNX model to use. * The diffusion model to use.
*/ */
model: string; model: string;
/** /**
* Hardware accelerator or CPU mode. * The hardware acceleration platform to use.
*/ */
platform: string; platform: string;
/**
* The upscaling model to use.
*/
upscaling: string; upscaling: string;
/**
* The correction model to use.
*/
correction: string; correction: string;
} }
/**
* Shared parameters for most of the image requests.
*/
export interface BaseImgParams { export interface BaseImgParams {
scheduler: string; scheduler: string;
prompt: string; prompt: string;
@ -27,20 +41,25 @@ export interface BaseImgParams {
seed: number; seed: number;
} }
export interface Img2ImgParams extends BaseImgParams { /**
source: Blob; * Parameters for txt2img requests.
strength: number; */
}
export type Img2ImgResponse = Required<Omit<Img2ImgParams, 'file'>>;
export interface Txt2ImgParams extends BaseImgParams { export interface Txt2ImgParams extends BaseImgParams {
width?: number; width?: number;
height?: number; height?: number;
} }
export type Txt2ImgResponse = Required<Txt2ImgParams>; /**
* Parameters for img2img requests.
*/
export interface Img2ImgParams extends BaseImgParams {
source: Blob;
strength: number;
}
/**
* Parameters for inpaint requests.
*/
export interface InpaintParams extends BaseImgParams { export interface InpaintParams extends BaseImgParams {
mask: Blob; mask: Blob;
source: Blob; source: Blob;
@ -51,6 +70,11 @@ export interface InpaintParams extends BaseImgParams {
fillColor: string; fillColor: string;
} }
/**
* Additional parameters for outpaint border.
*
* @todo should be nested under inpaint/outpaint params
*/
export interface OutpaintPixels { export interface OutpaintPixels {
enabled: boolean; enabled: boolean;
@ -60,14 +84,27 @@ export interface OutpaintPixels {
bottom: number; bottom: number;
} }
/**
* Parameters for outpaint requests.
*/
export type OutpaintParams = InpaintParams & OutpaintPixels; export type OutpaintParams = InpaintParams & OutpaintPixels;
/**
* Additional parameters for the inpaint brush.
*
* These are not currently sent to the server and only stored in state.
*
* @todo move to state
*/
export interface BrushParams { export interface BrushParams {
color: number; color: number;
size: number; size: number;
strength: number; strength: number;
} }
/**
* Additional parameters for upscaling.
*/
export interface UpscaleParams { export interface UpscaleParams {
enabled: boolean; enabled: boolean;
@ -78,10 +115,16 @@ export interface UpscaleParams {
faceStrength: number; faceStrength: number;
} }
/**
* Parameters for upscale requests.
*/
export interface UpscaleReqParams { export interface UpscaleReqParams {
source: Blob; source: Blob;
} }
/**
* General response for most image requests.
*/
export interface ImageResponse { export interface ImageResponse {
output: { output: {
key: string; key: string;
@ -94,10 +137,16 @@ export interface ImageResponse {
}; };
} }
/**
* Status response from the ready endpoint.
*/
export interface ReadyResponse { export interface ReadyResponse {
ready: boolean; ready: boolean;
} }
/**
* List of available models.
*/
export interface ModelsResponse { export interface ModelsResponse {
diffusion: Array<string>; diffusion: Array<string>;
correction: Array<string>; correction: Array<string>;
@ -105,50 +154,103 @@ export interface ModelsResponse {
} }
export interface ApiClient { export interface ApiClient {
/**
* List the available filter masks for inpaint.
*/
masks(): Promise<Array<string>>; masks(): Promise<Array<string>>;
/**
* List the available models.
*/
models(): Promise<ModelsResponse>; models(): Promise<ModelsResponse>;
/**
* List the available noise sources for inpaint.
*/
noises(): Promise<Array<string>>; noises(): Promise<Array<string>>;
/**
* Get the valid server parameters to validate image parameters.
*/
params(): Promise<ServerParams>; params(): Promise<ServerParams>;
/**
* Get the available hardware acceleration platforms.
*/
platforms(): Promise<Array<string>>; platforms(): Promise<Array<string>>;
/**
* List the available pipeline schedulers.
*/
schedulers(): Promise<Array<string>>; schedulers(): Promise<Array<string>>;
img2img(model: ModelParams, params: Img2ImgParams, upscale?: UpscaleParams): Promise<ImageResponse>; /**
* Start a txt2img pipeline.
*/
txt2img(model: ModelParams, params: Txt2ImgParams, upscale?: UpscaleParams): Promise<ImageResponse>; txt2img(model: ModelParams, params: Txt2ImgParams, upscale?: UpscaleParams): Promise<ImageResponse>;
/**
* Start an im2img pipeline.
*/
img2img(model: ModelParams, params: Img2ImgParams, upscale?: UpscaleParams): Promise<ImageResponse>;
/**
* Start an inpaint pipeline.
*/
inpaint(model: ModelParams, params: InpaintParams, upscale?: UpscaleParams): Promise<ImageResponse>; inpaint(model: ModelParams, params: InpaintParams, upscale?: UpscaleParams): Promise<ImageResponse>;
/**
* Start an outpaint pipeline.
*/
outpaint(model: ModelParams, params: OutpaintParams, upscale?: UpscaleParams): Promise<ImageResponse>; outpaint(model: ModelParams, params: OutpaintParams, upscale?: UpscaleParams): Promise<ImageResponse>;
/**
* Start an upscale pipeline.
*/
upscale(model: ModelParams, params: UpscaleReqParams, upscale?: UpscaleParams): Promise<ImageResponse>; upscale(model: ModelParams, params: UpscaleReqParams, upscale?: UpscaleParams): Promise<ImageResponse>;
/**
* Check whether some pipeline's output is ready yet.
*/
ready(params: ImageResponse): Promise<ReadyResponse>; ready(params: ImageResponse): Promise<ReadyResponse>;
} }
export const STATUS_SUCCESS = 200; /**
* Fixed precision for integer parameters.
export function paramsFromConfig(defaults: ServerParams): Required<BaseImgParams> { */
return {
cfg: defaults.cfg.default,
negativePrompt: defaults.negativePrompt.default,
prompt: defaults.prompt.default,
scheduler: defaults.scheduler.default,
steps: defaults.steps.default,
seed: defaults.seed.default,
};
}
export const FIXED_INTEGER = 0; export const FIXED_INTEGER = 0;
/**
* Fixed precision for float parameters.
*
* The GUI limits the input steps based on the server parameters, but this does limit
* the maximum precision that can be sent back to the server, and may have to be
* increased in the future.
*/
export const FIXED_FLOAT = 2; export const FIXED_FLOAT = 2;
export const STATUS_SUCCESS = 200;
export function equalResponse(a: ImageResponse, b: ImageResponse): boolean { export function equalResponse(a: ImageResponse, b: ImageResponse): boolean {
return a.output === b.output; return a.output === b.output;
} }
/**
* Join URL path segments, which always use a forward slash per https://www.rfc-editor.org/rfc/rfc1738
*/
export function joinPath(...parts: Array<string>): string { export function joinPath(...parts: Array<string>): string {
return parts.join('/'); return parts.join('/');
} }
/**
* Build the URL to an API endpoint, given the API root and a list of segments.
*/
export function makeApiUrl(root: string, ...path: Array<string>) { export function makeApiUrl(root: string, ...path: Array<string>) {
return new URL(joinPath('api', ...path), root); return new URL(joinPath('api', ...path), root);
} }
/**
* Build the URL for an image request, including all of the base image parameters.
*/
export function makeImageURL(root: string, type: string, params: BaseImgParams): URL { export function makeImageURL(root: string, type: string, params: BaseImgParams): URL {
const url = makeApiUrl(root, type); const url = makeApiUrl(root, type);
url.searchParams.append('cfg', params.cfg.toFixed(FIXED_FLOAT)); url.searchParams.append('cfg', params.cfg.toFixed(FIXED_FLOAT));
@ -172,6 +274,9 @@ export function makeImageURL(root: string, type: string, params: BaseImgParams):
return url; return url;
} }
/**
* Append the model parameters to an existing URL.
*/
export function appendModelToURL(url: URL, params: ModelParams) { export function appendModelToURL(url: URL, params: ModelParams) {
url.searchParams.append('model', params.model); url.searchParams.append('model', params.model);
url.searchParams.append('platform', params.platform); url.searchParams.append('platform', params.platform);
@ -179,6 +284,9 @@ export function appendModelToURL(url: URL, params: ModelParams) {
url.searchParams.append('correction', params.correction); url.searchParams.append('correction', params.correction);
} }
/**
* Append the upscale parameters to an existing URL.
*/
export function appendUpscaleToURL(url: URL, upscale: UpscaleParams) { export function appendUpscaleToURL(url: URL, upscale: UpscaleParams) {
if (upscale.enabled) { if (upscale.enabled) {
url.searchParams.append('denoise', upscale.denoise.toFixed(FIXED_FLOAT)); url.searchParams.append('denoise', upscale.denoise.toFixed(FIXED_FLOAT));
@ -189,6 +297,9 @@ export function appendUpscaleToURL(url: URL, upscale: UpscaleParams) {
} }
} }
/**
* Make an API client using the given API root and fetch client.
*/
export function makeClient(root: string, f = fetch): ApiClient { export function makeClient(root: string, f = fetch): ApiClient {
let pending: Promise<ImageResponse> | undefined; let pending: Promise<ImageResponse> | undefined;
@ -388,6 +499,12 @@ export function makeClient(root: string, f = fetch): ApiClient {
}; };
} }
/**
* Parse a successful API response into the full image response record.
*
* The server sends over the output key, and the client is in the best position to turn
* that into a full URL, since it already knows the root URL of the server.
*/
export async function parseApiResponse(root: string, res: Response): Promise<ImageResponse> { export async function parseApiResponse(root: string, res: Response): Promise<ImageResponse> {
type LimitedResponse = Omit<ImageResponse, 'output'> & { output: string }; type LimitedResponse = Omit<ImageResponse, 'output'> & { output: string };

View File

@ -14,23 +14,40 @@ export interface ConfigString {
keys: Array<string>; keys: Array<string>;
} }
/**
* Helper type to filter keys whose value extends `TValid`.
*/
export type KeyFilter<T extends object, TValid = number | string> = { export type KeyFilter<T extends object, TValid = number | string> = {
[K in keyof T]: T[K] extends TValid ? K : never; [K in keyof T]: T[K] extends TValid ? K : never;
}[keyof T]; }[keyof T];
/**
* Keep fields with a file-like value, but make them optional.
*/
export type ConfigFiles<T extends object> = { export type ConfigFiles<T extends object> = {
[K in KeyFilter<T, Blob | File>]: Maybe<T[K]>; [K in KeyFilter<T, Blob | File>]: Maybe<T[K]>;
}; };
/**
* Map numbers and strings to their corresponding config types and drop the rest of the fields.
*/
export type ConfigRanges<T extends object> = { export type ConfigRanges<T extends object> = {
[K in KeyFilter<T>]: T[K] extends number ? ConfigNumber : T[K] extends string ? ConfigString : never; [K in KeyFilter<T>]: T[K] extends number ? ConfigNumber : T[K] extends string ? ConfigString : never;
}; };
/**
* Keep fields whose value extends `TValid` and drop the rest.
*/
export type ConfigState<T extends object, TValid = number | string> = { export type ConfigState<T extends object, TValid = number | string> = {
[K in KeyFilter<T, TValid>]: T[K] extends TValid ? T[K] : never; [K in KeyFilter<T, TValid>]: T[K] extends TValid ? T[K] : never;
}; };
// eslint does not understand how to indent this and expects each line to increase
/* eslint-disable */ /* eslint-disable */
/**
* Combine all of the request parameter groups, make optional parameters required, then
* map them to the number/string ranges.
*/
export type ServerParams = ConfigRanges<Required< export type ServerParams = ConfigRanges<Required<
Img2ImgParams & Img2ImgParams &
Txt2ImgParams & Txt2ImgParams &
@ -43,6 +60,9 @@ export type ServerParams = ConfigRanges<Required<
}; };
/* eslint-enable */ /* eslint-enable */
/**
* Parameters that can be customized on the client, through the config file or settings tab.
*/
export interface ClientParams { export interface ClientParams {
model: ConfigString; model: ConfigString;
platform: ConfigString; platform: ConfigString;
@ -57,11 +77,6 @@ export interface Config<T = ClientParams> {
params: T; params: T;
} }
export const DEFAULT_BRUSH = {
color: 255,
size: 8,
};
export const IMAGE_FILTER = '.bmp, .jpg, .jpeg, .png'; export const IMAGE_FILTER = '.bmp, .jpg, .jpeg, .png';
export const PARAM_VERSION = '>=0.4.0'; export const PARAM_VERSION = '>=0.4.0';

View File

@ -12,15 +12,47 @@ import {
InpaintParams, InpaintParams,
ModelParams, ModelParams,
OutpaintPixels, OutpaintPixels,
paramsFromConfig,
Txt2ImgParams, Txt2ImgParams,
UpscaleParams, UpscaleParams,
UpscaleReqParams, UpscaleReqParams,
} from './client.js'; } from './client.js';
import { Config, ConfigFiles, ConfigState, ServerParams } from './config.js'; import { Config, ConfigFiles, ConfigState, ServerParams } from './config.js';
/**
* Combine optional files and required ranges.
*/
type TabState<TabParams> = ConfigFiles<Required<TabParams>> & ConfigState<Required<TabParams>>; type TabState<TabParams> = ConfigFiles<Required<TabParams>> & ConfigState<Required<TabParams>>;
interface BrushSlice {
brush: BrushParams;
setBrush(brush: Partial<BrushParams>): void;
}
interface DefaultSlice {
defaults: TabState<BaseImgParams>;
setDefaults(param: Partial<BaseImgParams>): void;
}
interface HistorySlice {
history: Array<ImageResponse>;
limit: number;
loading: Maybe<ImageResponse>;
pushHistory(image: ImageResponse): void;
removeHistory(image: ImageResponse): void;
setLimit(limit: number): void;
setLoading(image: Maybe<ImageResponse>): void;
}
interface ModelSlice {
model: ModelParams;
setModel(model: Partial<ModelParams>): void;
}
// #region tab slices
interface Txt2ImgSlice { interface Txt2ImgSlice {
txt2img: TabState<Txt2ImgParams>; txt2img: TabState<Txt2ImgParams>;
@ -42,35 +74,12 @@ interface InpaintSlice {
resetInpaint(): void; resetInpaint(): void;
} }
interface HistorySlice {
history: Array<ImageResponse>;
limit: number;
loading: Maybe<ImageResponse>;
pushHistory(image: ImageResponse): void;
removeHistory(image: ImageResponse): void;
setLimit(limit: number): void;
setLoading(image: Maybe<ImageResponse>): void;
}
interface DefaultSlice {
defaults: TabState<BaseImgParams>;
setDefaults(param: Partial<BaseImgParams>): void;
}
interface OutpaintSlice { interface OutpaintSlice {
outpaint: OutpaintPixels; outpaint: OutpaintPixels;
setOutpaint(pixels: Partial<OutpaintPixels>): void; setOutpaint(pixels: Partial<OutpaintPixels>): void;
} }
interface BrushSlice {
brush: BrushParams;
setBrush(brush: Partial<BrushParams>): void;
}
interface UpscaleSlice { interface UpscaleSlice {
upscale: UpscaleParams; upscale: UpscaleParams;
upscaleTab: TabState<UpscaleReqParams>; upscaleTab: TabState<UpscaleReqParams>;
@ -79,13 +88,11 @@ interface UpscaleSlice {
setUpscaleTab(params: Partial<UpscaleReqParams>): void; setUpscaleTab(params: Partial<UpscaleReqParams>): void;
resetUpscaleTab(): void; resetUpscaleTab(): void;
} }
// #endregion
interface ModelSlice { /**
model: ModelParams; * Full merged state including all slices.
*/
setModel(model: Partial<ModelParams>): void;
}
export type OnnxState export type OnnxState
= BrushSlice = BrushSlice
& DefaultSlice & DefaultSlice
@ -97,14 +104,85 @@ export type OnnxState
& Txt2ImgSlice & Txt2ImgSlice
& UpscaleSlice; & UpscaleSlice;
export function createStateSlices(base: ServerParams) { /**
const defaults = paramsFromConfig(base); * Shorthand for state creator to reduce repeated arguments.
*/
export type Slice<T> = StateCreator<OnnxState, [], [], T>;
const createTxt2ImgSlice: StateCreator<OnnxState, [], [], Txt2ImgSlice> = (set) => ({ /**
* React context binding for API client.
*/
export const ClientContext = createContext<Maybe<ApiClient>>(undefined);
/**
* React context binding for merged config, including server parameters.
*/
export const ConfigContext = createContext<Maybe<Config<ServerParams>>>(undefined);
/**
* React context binding for zustand state store.
*/
export const StateContext = createContext<Maybe<StoreApi<OnnxState>>>(undefined);
/**
* Current state version for zustand persistence.
*/
export const STATE_VERSION = 4;
/**
* Default parameters for the inpaint brush.
*
* Not provided by the server yet.
*/
export const DEFAULT_BRUSH = {
color: 255,
size: 8,
strength: 0.5,
};
/**
* Default parameters for the image history.
*
* Not provided by the server yet.
*/
export const DEFAULT_HISTORY = {
/**
* The number of images to be shown.
*/
limit: 4,
/**
* The number of additional images to be kept in history, so they can scroll
* back into view when you delete one. Does not include deleted images.
*/
scrollback: 2,
};
export function baseParamsFromServer(defaults: ServerParams): Required<BaseImgParams> {
return {
cfg: defaults.cfg.default,
negativePrompt: defaults.negativePrompt.default,
prompt: defaults.prompt.default,
scheduler: defaults.scheduler.default,
steps: defaults.steps.default,
seed: defaults.seed.default,
};
}
/**
* Prepare the state slice constructors.
*
* In the default state, image sources should be null and booleans should be false. Everything
* else should be initialized from the default value in the base parameters.
*/
export function createStateSlices(server: ServerParams) {
const base = baseParamsFromServer(server);
const createTxt2ImgSlice: Slice<Txt2ImgSlice> = (set) => ({
txt2img: { txt2img: {
...defaults, ...base,
width: base.width.default, width: server.width.default,
height: base.height.default, height: server.height.default,
}, },
setTxt2Img(params) { setTxt2Img(params) {
set((prev) => ({ set((prev) => ({
@ -117,19 +195,19 @@ export function createStateSlices(base: ServerParams) {
resetTxt2Img() { resetTxt2Img() {
set({ set({
txt2img: { txt2img: {
...defaults, ...base,
width: base.width.default, width: server.width.default,
height: base.height.default, height: server.height.default,
}, },
}); });
}, },
}); });
const createImg2ImgSlice: StateCreator<OnnxState, [], [], Img2ImgSlice> = (set) => ({ const createImg2ImgSlice: Slice<Img2ImgSlice> = (set) => ({
img2img: { img2img: {
...defaults, ...base,
source: null, source: null,
strength: base.strength.default, strength: server.strength.default,
}, },
setImg2Img(params) { setImg2Img(params) {
set((prev) => ({ set((prev) => ({
@ -142,23 +220,23 @@ export function createStateSlices(base: ServerParams) {
resetImg2Img() { resetImg2Img() {
set({ set({
img2img: { img2img: {
...defaults, ...base,
source: null, source: null,
strength: base.strength.default, strength: server.strength.default,
}, },
}); });
}, },
}); });
const createInpaintSlice: StateCreator<OnnxState, [], [], InpaintSlice> = (set) => ({ const createInpaintSlice: Slice<InpaintSlice> = (set) => ({
inpaint: { inpaint: {
...defaults, ...base,
fillColor: '#000000', fillColor: server.fillColor.default,
filter: 'none', filter: server.filter.default,
mask: null, mask: null,
noise: 'histogram', noise: server.noise.default,
source: null, source: null,
strength: 1.0, strength: server.strength.default,
}, },
setInpaint(params) { setInpaint(params) {
set((prev) => ({ set((prev) => ({
@ -171,21 +249,21 @@ export function createStateSlices(base: ServerParams) {
resetInpaint() { resetInpaint() {
set({ set({
inpaint: { inpaint: {
...defaults, ...base,
fillColor: '#000000', fillColor: server.fillColor.default,
filter: 'none', filter: server.filter.default,
mask: null, mask: null,
noise: 'histogram', noise: server.noise.default,
source: null, source: null,
strength: 1.0, strength: server.strength.default,
}, },
}); });
}, },
}); });
const createHistorySlice: StateCreator<OnnxState, [], [], HistorySlice> = (set) => ({ const createHistorySlice: Slice<HistorySlice> = (set) => ({
history: [], history: [],
limit: 4, limit: DEFAULT_HISTORY.limit,
loading: null, loading: null,
pushHistory(image) { pushHistory(image) {
set((prev) => ({ set((prev) => ({
@ -193,7 +271,7 @@ export function createStateSlices(base: ServerParams) {
history: [ history: [
image, image,
...prev.history, ...prev.history,
].slice(0, prev.limit), ].slice(0, prev.limit + DEFAULT_HISTORY.scrollback),
loading: null, loading: null,
})); }));
}, },
@ -217,13 +295,13 @@ export function createStateSlices(base: ServerParams) {
}, },
}); });
const createOutpaintSlice: StateCreator<OnnxState, [], [], OutpaintSlice> = (set) => ({ const createOutpaintSlice: Slice<OutpaintSlice> = (set) => ({
outpaint: { outpaint: {
enabled: false, enabled: false,
left: 0, left: server.left.default,
right: 0, right: server.right.default,
top: 0, top: server.top.default,
bottom: 0, bottom: server.bottom.default,
}, },
setOutpaint(pixels) { setOutpaint(pixels) {
set((prev) => ({ set((prev) => ({
@ -235,11 +313,9 @@ export function createStateSlices(base: ServerParams) {
}, },
}); });
const createBrushSlice: StateCreator<OnnxState, [], [], BrushSlice> = (set) => ({ const createBrushSlice: Slice<BrushSlice> = (set) => ({
brush: { brush: {
color: 255, ...DEFAULT_BRUSH,
size: 8,
strength: 0.5,
}, },
setBrush(brush) { setBrush(brush) {
set((prev) => ({ set((prev) => ({
@ -251,14 +327,14 @@ export function createStateSlices(base: ServerParams) {
}, },
}); });
const createUpscaleSlice: StateCreator<OnnxState, [], [], UpscaleSlice> = (set) => ({ const createUpscaleSlice: Slice<UpscaleSlice> = (set) => ({
upscale: { upscale: {
denoise: 0.5, denoise: server.denoise.default,
enabled: false, enabled: false,
faces: false, faces: false,
scale: 1, scale: server.scale.default,
outscale: 1, outscale: server.outscale.default,
faceStrength: 0.5, faceStrength: server.faceStrength.default,
}, },
upscaleTab: { upscaleTab: {
source: null, source: null,
@ -288,9 +364,9 @@ export function createStateSlices(base: ServerParams) {
}, },
}); });
const createDefaultSlice: StateCreator<OnnxState, [], [], DefaultSlice> = (set) => ({ const createDefaultSlice: Slice<DefaultSlice> = (set) => ({
defaults: { defaults: {
...defaults, ...base,
}, },
setDefaults(params) { setDefaults(params) {
set((prev) => ({ set((prev) => ({
@ -302,12 +378,12 @@ export function createStateSlices(base: ServerParams) {
}, },
}); });
const createModelSlice: StateCreator<OnnxState, [], [], ModelSlice> = (set) => ({ const createModelSlice: Slice<ModelSlice> = (set) => ({
model: { model: {
model: '', model: server.model.default,
platform: '', platform: server.platform.default,
upscaling: '', upscaling: server.upscaling.default,
correction: '', correction: server.correction.default,
}, },
setModel(params) { setModel(params) {
set((prev) => ({ set((prev) => ({
@ -331,8 +407,3 @@ export function createStateSlices(base: ServerParams) {
createUpscaleSlice, createUpscaleSlice,
}; };
} }
export const ClientContext = createContext<Maybe<ApiClient>>(undefined);
export const ConfigContext = createContext<Maybe<Config<ServerParams>>>(undefined);
export const StateContext = createContext<Maybe<StoreApi<OnnxState>>>(undefined);
export const STATE_VERSION = 4;