fix(gui): load remaining defaults from server params
This commit is contained in:
parent
9b37c174d1
commit
88e4f74efe
|
@ -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,
|
||||||
|
|
|
@ -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 };
|
||||||
|
|
||||||
|
|
|
@ -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';
|
||||||
|
|
||||||
|
|
239
gui/src/state.ts
239
gui/src/state.ts
|
@ -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;
|
|
||||||
|
|
Loading…
Reference in New Issue