mirror of
https://github.com/invoke-ai/InvokeAI
synced 2024-08-30 20:32:17 +00:00
Merge branch 'main' into feat/onnx
This commit is contained in:
16
invokeai/frontend/web/src/services/api/constants.ts
Normal file
16
invokeai/frontend/web/src/services/api/constants.ts
Normal file
@ -0,0 +1,16 @@
|
||||
import { BaseModelType } from './types';
|
||||
|
||||
export const ALL_BASE_MODELS: BaseModelType[] = [
|
||||
'sd-1',
|
||||
'sd-2',
|
||||
'sdxl',
|
||||
'sdxl-refiner',
|
||||
];
|
||||
|
||||
export const NON_REFINER_BASE_MODELS: BaseModelType[] = [
|
||||
'sd-1',
|
||||
'sd-2',
|
||||
'sdxl',
|
||||
];
|
||||
|
||||
export const REFINER_BASE_MODELS: BaseModelType[] = ['sdxl-refiner'];
|
@ -8,6 +8,7 @@ export const appInfoApi = api.injectEndpoints({
|
||||
url: `app/version`,
|
||||
method: 'GET',
|
||||
}),
|
||||
providesTags: ['AppVersion'],
|
||||
keepUnusedDataFor: 86400000, // 1 day
|
||||
}),
|
||||
getAppConfig: build.query<AppConfig, void>({
|
||||
@ -15,6 +16,7 @@ export const appInfoApi = api.injectEndpoints({
|
||||
url: `app/config`,
|
||||
method: 'GET',
|
||||
}),
|
||||
providesTags: ['AppConfig'],
|
||||
keepUnusedDataFor: 86400000, // 1 day
|
||||
}),
|
||||
}),
|
||||
|
@ -1,83 +1,36 @@
|
||||
import { OffsetPaginatedResults_ImageDTO_ } from 'services/api/types';
|
||||
import { ApiFullTagDescription, LIST_TAG, api } from '..';
|
||||
import { paths } from '../schema';
|
||||
|
||||
type ListBoardImagesArg =
|
||||
paths['/api/v1/board_images/{board_id}']['get']['parameters']['path'] &
|
||||
paths['/api/v1/board_images/{board_id}']['get']['parameters']['query'];
|
||||
|
||||
type AddImageToBoardArg =
|
||||
paths['/api/v1/board_images/']['post']['requestBody']['content']['application/json'];
|
||||
|
||||
type RemoveImageFromBoardArg =
|
||||
paths['/api/v1/board_images/']['delete']['requestBody']['content']['application/json'];
|
||||
import { api } from '..';
|
||||
|
||||
export const boardImagesApi = api.injectEndpoints({
|
||||
endpoints: (build) => ({
|
||||
/**
|
||||
* Board Images Queries
|
||||
*/
|
||||
|
||||
listBoardImages: build.query<
|
||||
OffsetPaginatedResults_ImageDTO_,
|
||||
ListBoardImagesArg
|
||||
>({
|
||||
query: ({ board_id, offset, limit }) => ({
|
||||
url: `board_images/${board_id}`,
|
||||
method: 'GET',
|
||||
}),
|
||||
providesTags: (result, error, arg) => {
|
||||
// any list of boardimages
|
||||
const tags: ApiFullTagDescription[] = [
|
||||
{ type: 'BoardImage', id: `${arg.board_id}_${LIST_TAG}` },
|
||||
];
|
||||
|
||||
if (result) {
|
||||
// and individual tags for each boardimage
|
||||
tags.push(
|
||||
...result.items.map(({ board_id, image_name }) => ({
|
||||
type: 'BoardImage' as const,
|
||||
id: `${board_id}_${image_name}`,
|
||||
}))
|
||||
);
|
||||
}
|
||||
|
||||
return tags;
|
||||
},
|
||||
}),
|
||||
|
||||
/**
|
||||
* Board Images Mutations
|
||||
*/
|
||||
|
||||
addImageToBoard: build.mutation<void, AddImageToBoardArg>({
|
||||
query: ({ board_id, image_name }) => ({
|
||||
url: `board_images/`,
|
||||
method: 'POST',
|
||||
body: { board_id, image_name },
|
||||
}),
|
||||
invalidatesTags: (result, error, arg) => [
|
||||
{ type: 'BoardImage' },
|
||||
{ type: 'Board', id: arg.board_id },
|
||||
],
|
||||
}),
|
||||
|
||||
removeImageFromBoard: build.mutation<void, RemoveImageFromBoardArg>({
|
||||
query: ({ board_id, image_name }) => ({
|
||||
url: `board_images/`,
|
||||
method: 'DELETE',
|
||||
body: { board_id, image_name },
|
||||
}),
|
||||
invalidatesTags: (result, error, arg) => [
|
||||
{ type: 'BoardImage' },
|
||||
{ type: 'Board', id: arg.board_id },
|
||||
],
|
||||
}),
|
||||
// listBoardImages: build.query<
|
||||
// OffsetPaginatedResults_ImageDTO_,
|
||||
// ListBoardImagesArg
|
||||
// >({
|
||||
// query: ({ board_id, offset, limit }) => ({
|
||||
// url: `board_images/${board_id}`,
|
||||
// method: 'GET',
|
||||
// }),
|
||||
// providesTags: (result, error, arg) => {
|
||||
// // any list of boardimages
|
||||
// const tags: ApiFullTagDescription[] = [
|
||||
// { type: 'BoardImage', id: `${arg.board_id}_${LIST_TAG}` },
|
||||
// ];
|
||||
// if (result) {
|
||||
// // and individual tags for each boardimage
|
||||
// tags.push(
|
||||
// ...result.items.map(({ board_id, image_name }) => ({
|
||||
// type: 'BoardImage' as const,
|
||||
// id: `${board_id}_${image_name}`,
|
||||
// }))
|
||||
// );
|
||||
// }
|
||||
// return tags;
|
||||
// },
|
||||
// }),
|
||||
}),
|
||||
});
|
||||
|
||||
export const {
|
||||
useAddImageToBoardMutation,
|
||||
useRemoveImageFromBoardMutation,
|
||||
useListBoardImagesQuery,
|
||||
} = boardImagesApi;
|
||||
// export const { useListBoardImagesQuery } = boardImagesApi;
|
||||
|
@ -1,6 +1,16 @@
|
||||
import { BoardDTO, OffsetPaginatedResults_BoardDTO_ } from 'services/api/types';
|
||||
import { Update } from '@reduxjs/toolkit';
|
||||
import {
|
||||
ASSETS_CATEGORIES,
|
||||
IMAGE_CATEGORIES,
|
||||
} from 'features/gallery/store/types';
|
||||
import {
|
||||
BoardDTO,
|
||||
ImageDTO,
|
||||
OffsetPaginatedResults_BoardDTO_,
|
||||
} from 'services/api/types';
|
||||
import { ApiFullTagDescription, LIST_TAG, api } from '..';
|
||||
import { paths } from '../schema';
|
||||
import { getListImagesUrl, imagesAdapter, imagesApi } from './images';
|
||||
|
||||
type ListBoardsArg = NonNullable<
|
||||
paths['/api/v1/boards/']['get']['parameters']['query']
|
||||
@ -11,6 +21,9 @@ type UpdateBoardArg =
|
||||
changes: paths['/api/v1/boards/{board_id}']['patch']['requestBody']['content']['application/json'];
|
||||
};
|
||||
|
||||
type DeleteBoardResult =
|
||||
paths['/api/v1/boards/{board_id}']['delete']['responses']['200']['content']['application/json'];
|
||||
|
||||
export const boardsApi = api.injectEndpoints({
|
||||
endpoints: (build) => ({
|
||||
/**
|
||||
@ -59,6 +72,16 @@ export const boardsApi = api.injectEndpoints({
|
||||
},
|
||||
}),
|
||||
|
||||
listAllImageNamesForBoard: build.query<Array<string>, string>({
|
||||
query: (board_id) => ({
|
||||
url: `boards/${board_id}/image_names`,
|
||||
}),
|
||||
providesTags: (result, error, arg) => [
|
||||
{ type: 'ImageNameList', id: arg },
|
||||
],
|
||||
keepUnusedDataFor: 0,
|
||||
}),
|
||||
|
||||
/**
|
||||
* Boards Mutations
|
||||
*/
|
||||
@ -82,20 +105,166 @@ export const boardsApi = api.injectEndpoints({
|
||||
{ type: 'Board', id: arg.board_id },
|
||||
],
|
||||
}),
|
||||
deleteBoard: build.mutation<void, string>({
|
||||
|
||||
deleteBoard: build.mutation<DeleteBoardResult, string>({
|
||||
query: (board_id) => ({ url: `boards/${board_id}`, method: 'DELETE' }),
|
||||
invalidatesTags: (result, error, arg) => [{ type: 'Board', id: arg }],
|
||||
invalidatesTags: (result, error, board_id) => [
|
||||
{ type: 'Board', id: LIST_TAG },
|
||||
// invalidate the 'No Board' cache
|
||||
{
|
||||
type: 'ImageList',
|
||||
id: getListImagesUrl({
|
||||
board_id: 'none',
|
||||
categories: IMAGE_CATEGORIES,
|
||||
}),
|
||||
},
|
||||
{
|
||||
type: 'ImageList',
|
||||
id: getListImagesUrl({
|
||||
board_id: 'none',
|
||||
categories: ASSETS_CATEGORIES,
|
||||
}),
|
||||
},
|
||||
{ type: 'BoardImagesTotal', id: 'none' },
|
||||
{ type: 'BoardAssetsTotal', id: 'none' },
|
||||
],
|
||||
async onQueryStarted(board_id, { dispatch, queryFulfilled, getState }) {
|
||||
/**
|
||||
* Cache changes for deleteBoard:
|
||||
* - Update every image in the 'getImageDTO' cache that has the board_id
|
||||
* - Update every image in the 'All Images' cache that has the board_id
|
||||
* - Update every image in the 'All Assets' cache that has the board_id
|
||||
* - Invalidate the 'No Board' cache:
|
||||
* Ideally we'd be able to insert all deleted images into the cache, but we don't
|
||||
* have access to the deleted images DTOs - only the names, and a network request
|
||||
* for all of a board's DTOs could be very large. Instead, we invalidate the 'No Board'
|
||||
* cache.
|
||||
*/
|
||||
|
||||
try {
|
||||
const { data } = await queryFulfilled;
|
||||
const { deleted_board_images } = data;
|
||||
|
||||
// update getImageDTO caches
|
||||
deleted_board_images.forEach((image_id) => {
|
||||
dispatch(
|
||||
imagesApi.util.updateQueryData(
|
||||
'getImageDTO',
|
||||
image_id,
|
||||
(draft) => {
|
||||
draft.board_id = undefined;
|
||||
}
|
||||
)
|
||||
);
|
||||
});
|
||||
|
||||
// update 'All Images' & 'All Assets' caches
|
||||
const queryArgsToUpdate = [
|
||||
{
|
||||
categories: IMAGE_CATEGORIES,
|
||||
},
|
||||
{
|
||||
categories: ASSETS_CATEGORIES,
|
||||
},
|
||||
];
|
||||
|
||||
const updates: Update<ImageDTO>[] = deleted_board_images.map(
|
||||
(image_name) => ({
|
||||
id: image_name,
|
||||
changes: { board_id: undefined },
|
||||
})
|
||||
);
|
||||
|
||||
queryArgsToUpdate.forEach((queryArgs) => {
|
||||
dispatch(
|
||||
imagesApi.util.updateQueryData(
|
||||
'listImages',
|
||||
queryArgs,
|
||||
(draft) => {
|
||||
const oldTotal = draft.total;
|
||||
const newState = imagesAdapter.updateMany(draft, updates);
|
||||
const delta = newState.total - oldTotal;
|
||||
draft.total = draft.total + delta;
|
||||
}
|
||||
)
|
||||
);
|
||||
});
|
||||
} catch {
|
||||
//no-op
|
||||
}
|
||||
},
|
||||
}),
|
||||
deleteBoardAndImages: build.mutation<void, string>({
|
||||
|
||||
deleteBoardAndImages: build.mutation<DeleteBoardResult, string>({
|
||||
query: (board_id) => ({
|
||||
url: `boards/${board_id}`,
|
||||
method: 'DELETE',
|
||||
params: { include_images: true },
|
||||
}),
|
||||
invalidatesTags: (result, error, arg) => [
|
||||
{ type: 'Board', id: arg },
|
||||
{ type: 'Image', id: LIST_TAG },
|
||||
invalidatesTags: (result, error, board_id) => [
|
||||
{ type: 'Board', id: LIST_TAG },
|
||||
{
|
||||
type: 'ImageList',
|
||||
id: getListImagesUrl({
|
||||
board_id: 'none',
|
||||
categories: IMAGE_CATEGORIES,
|
||||
}),
|
||||
},
|
||||
{
|
||||
type: 'ImageList',
|
||||
id: getListImagesUrl({
|
||||
board_id: 'none',
|
||||
categories: ASSETS_CATEGORIES,
|
||||
}),
|
||||
},
|
||||
{ type: 'BoardImagesTotal', id: 'none' },
|
||||
{ type: 'BoardAssetsTotal', id: 'none' },
|
||||
],
|
||||
async onQueryStarted(board_id, { dispatch, queryFulfilled, getState }) {
|
||||
/**
|
||||
* Cache changes for deleteBoardAndImages:
|
||||
* - ~~Remove every image in the 'getImageDTO' cache that has the board_id~~
|
||||
* This isn't actually possible, you cannot remove cache entries with RTK Query.
|
||||
* Instead, we rely on the UI to remove all components that use the deleted images.
|
||||
* - Remove every image in the 'All Images' cache that has the board_id
|
||||
* - Remove every image in the 'All Assets' cache that has the board_id
|
||||
*/
|
||||
|
||||
try {
|
||||
const { data } = await queryFulfilled;
|
||||
const { deleted_images } = data;
|
||||
|
||||
// update 'All Images' & 'All Assets' caches
|
||||
const queryArgsToUpdate = [
|
||||
{
|
||||
categories: IMAGE_CATEGORIES,
|
||||
},
|
||||
{
|
||||
categories: ASSETS_CATEGORIES,
|
||||
},
|
||||
];
|
||||
|
||||
queryArgsToUpdate.forEach((queryArgs) => {
|
||||
dispatch(
|
||||
imagesApi.util.updateQueryData(
|
||||
'listImages',
|
||||
queryArgs,
|
||||
(draft) => {
|
||||
const oldTotal = draft.total;
|
||||
const newState = imagesAdapter.removeMany(
|
||||
draft,
|
||||
deleted_images
|
||||
);
|
||||
const delta = newState.total - oldTotal;
|
||||
draft.total = draft.total + delta;
|
||||
}
|
||||
)
|
||||
);
|
||||
});
|
||||
} catch {
|
||||
//no-op
|
||||
}
|
||||
},
|
||||
}),
|
||||
}),
|
||||
});
|
||||
@ -107,4 +276,5 @@ export const {
|
||||
useUpdateBoardMutation,
|
||||
useDeleteBoardMutation,
|
||||
useDeleteBoardAndImagesMutation,
|
||||
useListAllImageNamesForBoardQuery,
|
||||
} = boardsApi;
|
||||
|
@ -1,6 +1,55 @@
|
||||
import { EntityState, createEntityAdapter } from '@reduxjs/toolkit';
|
||||
import { PatchCollection } from '@reduxjs/toolkit/dist/query/core/buildThunks';
|
||||
import { dateComparator } from 'common/util/dateComparator';
|
||||
import {
|
||||
ASSETS_CATEGORIES,
|
||||
BoardId,
|
||||
IMAGE_CATEGORIES,
|
||||
} from 'features/gallery/store/types';
|
||||
import queryString from 'query-string';
|
||||
import { ApiFullTagDescription, api } from '..';
|
||||
import { components } from '../schema';
|
||||
import { ImageDTO } from '../types';
|
||||
import { components, paths } from '../schema';
|
||||
import {
|
||||
ImageCategory,
|
||||
ImageDTO,
|
||||
OffsetPaginatedResults_ImageDTO_,
|
||||
PostUploadAction,
|
||||
} from '../types';
|
||||
|
||||
const getIsImageInDateRange = (
|
||||
data: ImageCache | undefined,
|
||||
imageDTO: ImageDTO
|
||||
) => {
|
||||
if (!data) {
|
||||
return false;
|
||||
}
|
||||
const cacheImageDTOS = imagesSelectors.selectAll(data);
|
||||
|
||||
if (cacheImageDTOS.length > 1) {
|
||||
// Images are sorted by `created_at` DESC
|
||||
// check if the image is newer than the oldest image in the cache
|
||||
const createdDate = new Date(imageDTO.created_at);
|
||||
const oldestDate = new Date(
|
||||
cacheImageDTOS[cacheImageDTOS.length - 1].created_at
|
||||
);
|
||||
return createdDate >= oldestDate;
|
||||
} else if ([0, 1].includes(cacheImageDTOS.length)) {
|
||||
// if there are only 1 or 0 images in the cache, we consider the image to be in the date range
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
};
|
||||
|
||||
const getCategories = (imageDTO: ImageDTO) => {
|
||||
if (IMAGE_CATEGORIES.includes(imageDTO.image_category)) {
|
||||
return IMAGE_CATEGORIES;
|
||||
}
|
||||
return ASSETS_CATEGORIES;
|
||||
};
|
||||
|
||||
export type ListImagesArgs = NonNullable<
|
||||
paths['/api/v1/images/']['get']['parameters']['query']
|
||||
>;
|
||||
|
||||
/**
|
||||
* This is an unsafe type; the object inside is not guaranteed to be valid.
|
||||
@ -10,11 +59,107 @@ export type UnsafeImageMetadata = {
|
||||
graph: NonNullable<components['schemas']['Graph']>;
|
||||
};
|
||||
|
||||
export type ImageCache = EntityState<ImageDTO> & { total: number };
|
||||
|
||||
// The adapter is not actually the data store - it just provides helper functions to interact
|
||||
// with some other store of data. We will use the RTK Query cache as that store.
|
||||
export const imagesAdapter = createEntityAdapter<ImageDTO>({
|
||||
selectId: (image) => image.image_name,
|
||||
sortComparer: (a, b) => dateComparator(b.updated_at, a.updated_at),
|
||||
});
|
||||
|
||||
// We want to also store the images total in the cache. When we initialize the cache state,
|
||||
// we will provide this type arg so the adapter knows we want the total.
|
||||
export type AdditionalImagesAdapterState = { total: number };
|
||||
|
||||
// Create selectors for the adapter.
|
||||
export const imagesSelectors = imagesAdapter.getSelectors();
|
||||
|
||||
// Helper to create the url for the listImages endpoint. Also we use it to create the cache key.
|
||||
export const getListImagesUrl = (queryArgs: ListImagesArgs) =>
|
||||
`images/?${queryString.stringify(queryArgs, { arrayFormat: 'none' })}`;
|
||||
|
||||
export const imagesApi = api.injectEndpoints({
|
||||
endpoints: (build) => ({
|
||||
/**
|
||||
* Image Queries
|
||||
*/
|
||||
listImages: build.query<
|
||||
EntityState<ImageDTO> & { total: number },
|
||||
ListImagesArgs
|
||||
>({
|
||||
query: (queryArgs) => ({
|
||||
// Use the helper to create the URL.
|
||||
url: getListImagesUrl(queryArgs),
|
||||
method: 'GET',
|
||||
}),
|
||||
providesTags: (result, error, { board_id, categories }) => [
|
||||
// Make the tags the same as the cache key
|
||||
{ type: 'ImageList', id: getListImagesUrl({ board_id, categories }) },
|
||||
],
|
||||
serializeQueryArgs: ({ queryArgs }) => {
|
||||
// Create cache & key based on board_id and categories - skip the other args.
|
||||
// Offset is the size of the cache, and limit is always the same. Both are provided by
|
||||
// the consumer of the query.
|
||||
const { board_id, categories } = queryArgs;
|
||||
|
||||
// Just use the same fn used to create the url; it makes an understandable cache key.
|
||||
// This cache key is the same for any combo of board_id and categories, doesn't change
|
||||
// when offset & limit change.
|
||||
const cacheKey = getListImagesUrl({ board_id, categories });
|
||||
return cacheKey;
|
||||
},
|
||||
transformResponse(response: OffsetPaginatedResults_ImageDTO_) {
|
||||
const { total, items: images } = response;
|
||||
// Use the adapter to convert the response to the right shape, and adding the new total.
|
||||
// The trick is to just provide an empty state and add the images array to it. This returns
|
||||
// a properly shaped EntityState.
|
||||
return imagesAdapter.addMany(
|
||||
imagesAdapter.getInitialState<AdditionalImagesAdapterState>({
|
||||
total,
|
||||
}),
|
||||
images
|
||||
);
|
||||
},
|
||||
merge: (cache, response) => {
|
||||
// Here we actually update the cache. `response` here is the output of `transformResponse`
|
||||
// above. In a similar vein to `transformResponse`, we can use the imagesAdapter to get
|
||||
// things in the right shape. Also update the total image count.
|
||||
imagesAdapter.addMany(cache, imagesSelectors.selectAll(response));
|
||||
cache.total = response.total;
|
||||
},
|
||||
forceRefetch({ currentArg, previousArg }) {
|
||||
// Refetch when the offset changes (which means we are on a new page).
|
||||
return currentArg?.offset !== previousArg?.offset;
|
||||
},
|
||||
async onQueryStarted(_, { dispatch, queryFulfilled }) {
|
||||
try {
|
||||
const { data } = await queryFulfilled;
|
||||
|
||||
// update the `getImageDTO` cache for each image
|
||||
imagesSelectors.selectAll(data).forEach((imageDTO) => {
|
||||
dispatch(
|
||||
imagesApi.util.upsertQueryData(
|
||||
'getImageDTO',
|
||||
imageDTO.image_name,
|
||||
imageDTO
|
||||
)
|
||||
);
|
||||
});
|
||||
} catch {
|
||||
// no-op
|
||||
}
|
||||
},
|
||||
// 24 hours - reducing this to a few minutes would reduce memory usage.
|
||||
keepUnusedDataFor: 86400,
|
||||
}),
|
||||
getIntermediatesCount: build.query<number, void>({
|
||||
query: () => ({ url: getListImagesUrl({ is_intermediate: true }) }),
|
||||
providesTags: ['IntermediatesCount'],
|
||||
transformResponse: (response: OffsetPaginatedResults_ImageDTO_) => {
|
||||
return response.total;
|
||||
},
|
||||
}),
|
||||
getImageDTO: build.query<ImageDTO, string>({
|
||||
query: (image_name) => ({ url: `images/${image_name}` }),
|
||||
providesTags: (result, error, arg) => {
|
||||
@ -36,7 +181,617 @@ export const imagesApi = api.injectEndpoints({
|
||||
},
|
||||
keepUnusedDataFor: 86400, // 24 hours
|
||||
}),
|
||||
getBoardImagesTotal: build.query<number, string | undefined>({
|
||||
query: (board_id) => ({
|
||||
url: getListImagesUrl({
|
||||
board_id: board_id ?? 'none',
|
||||
categories: IMAGE_CATEGORIES,
|
||||
is_intermediate: false,
|
||||
limit: 0,
|
||||
offset: 0,
|
||||
}),
|
||||
method: 'GET',
|
||||
}),
|
||||
providesTags: (result, error, arg) => [
|
||||
{ type: 'BoardImagesTotal', id: arg ?? 'none' },
|
||||
],
|
||||
transformResponse: (response: OffsetPaginatedResults_ImageDTO_) => {
|
||||
return response.total;
|
||||
},
|
||||
}),
|
||||
getBoardAssetsTotal: build.query<number, string | undefined>({
|
||||
query: (board_id) => ({
|
||||
url: getListImagesUrl({
|
||||
board_id: board_id ?? 'none',
|
||||
categories: ASSETS_CATEGORIES,
|
||||
is_intermediate: false,
|
||||
limit: 0,
|
||||
offset: 0,
|
||||
}),
|
||||
method: 'GET',
|
||||
}),
|
||||
providesTags: (result, error, arg) => [
|
||||
{ type: 'BoardAssetsTotal', id: arg ?? 'none' },
|
||||
],
|
||||
transformResponse: (response: OffsetPaginatedResults_ImageDTO_) => {
|
||||
return response.total;
|
||||
},
|
||||
}),
|
||||
clearIntermediates: build.mutation<number, void>({
|
||||
query: () => ({ url: `images/clear-intermediates`, method: 'POST' }),
|
||||
invalidatesTags: ['IntermediatesCount'],
|
||||
}),
|
||||
deleteImage: build.mutation<void, ImageDTO>({
|
||||
query: ({ image_name }) => ({
|
||||
url: `images/${image_name}`,
|
||||
method: 'DELETE',
|
||||
}),
|
||||
invalidatesTags: (result, error, { board_id }) => [
|
||||
{ type: 'BoardImagesTotal', id: board_id ?? 'none' },
|
||||
{ type: 'BoardAssetsTotal', id: board_id ?? 'none' },
|
||||
],
|
||||
async onQueryStarted(imageDTO, { dispatch, queryFulfilled }) {
|
||||
/**
|
||||
* Cache changes for `deleteImage`:
|
||||
* - NOT POSSIBLE: *remove* from getImageDTO
|
||||
* - $cache = [board_id|no_board]/[images|assets]
|
||||
* - *remove* from $cache
|
||||
*/
|
||||
|
||||
const { image_name, board_id } = imageDTO;
|
||||
|
||||
// Store patches so we can undo if the query fails
|
||||
const patches: PatchCollection[] = [];
|
||||
|
||||
// determine `categories`, i.e. do we update "All Images" or "All Assets"
|
||||
// $cache = [board_id|no_board]/[images|assets]
|
||||
const categories = getCategories(imageDTO);
|
||||
|
||||
// *remove* from $cache
|
||||
patches.push(
|
||||
dispatch(
|
||||
imagesApi.util.updateQueryData(
|
||||
'listImages',
|
||||
{ board_id: board_id ?? 'none', categories },
|
||||
(draft) => {
|
||||
const oldTotal = draft.total;
|
||||
const newState = imagesAdapter.removeOne(draft, image_name);
|
||||
const delta = newState.total - oldTotal;
|
||||
draft.total = draft.total + delta;
|
||||
}
|
||||
)
|
||||
)
|
||||
);
|
||||
|
||||
try {
|
||||
await queryFulfilled;
|
||||
} catch {
|
||||
patches.forEach((patchResult) => patchResult.undo());
|
||||
}
|
||||
},
|
||||
}),
|
||||
/**
|
||||
* Change an image's `is_intermediate` property.
|
||||
*/
|
||||
changeImageIsIntermediate: build.mutation<
|
||||
ImageDTO,
|
||||
{ imageDTO: ImageDTO; is_intermediate: boolean }
|
||||
>({
|
||||
query: ({ imageDTO, is_intermediate }) => ({
|
||||
url: `images/${imageDTO.image_name}`,
|
||||
method: 'PATCH',
|
||||
body: { is_intermediate },
|
||||
}),
|
||||
invalidatesTags: (result, error, { imageDTO }) => [
|
||||
{ type: 'BoardImagesTotal', id: imageDTO.board_id ?? 'none' },
|
||||
{ type: 'BoardAssetsTotal', id: imageDTO.board_id ?? 'none' },
|
||||
],
|
||||
async onQueryStarted(
|
||||
{ imageDTO, is_intermediate },
|
||||
{ dispatch, queryFulfilled, getState }
|
||||
) {
|
||||
/**
|
||||
* Cache changes for `changeImageIsIntermediate`:
|
||||
* - *update* getImageDTO
|
||||
* - $cache = [board_id|no_board]/[images|assets]
|
||||
* - IF it is being changed to an intermediate:
|
||||
* - remove from $cache
|
||||
* - ELSE (it is being changed to a non-intermediate):
|
||||
* - IF it eligible for insertion into existing $cache:
|
||||
* - *upsert* to $cache
|
||||
*/
|
||||
|
||||
// Store patches so we can undo if the query fails
|
||||
const patches: PatchCollection[] = [];
|
||||
|
||||
// *update* getImageDTO
|
||||
patches.push(
|
||||
dispatch(
|
||||
imagesApi.util.updateQueryData(
|
||||
'getImageDTO',
|
||||
imageDTO.image_name,
|
||||
(draft) => {
|
||||
Object.assign(draft, { is_intermediate });
|
||||
}
|
||||
)
|
||||
)
|
||||
);
|
||||
|
||||
// $cache = [board_id|no_board]/[images|assets]
|
||||
const categories = getCategories(imageDTO);
|
||||
|
||||
if (is_intermediate) {
|
||||
// IF it is being changed to an intermediate:
|
||||
// remove from $cache
|
||||
patches.push(
|
||||
dispatch(
|
||||
imagesApi.util.updateQueryData(
|
||||
'listImages',
|
||||
{ board_id: imageDTO.board_id ?? 'none', categories },
|
||||
(draft) => {
|
||||
const oldTotal = draft.total;
|
||||
const newState = imagesAdapter.removeOne(
|
||||
draft,
|
||||
imageDTO.image_name
|
||||
);
|
||||
const delta = newState.total - oldTotal;
|
||||
draft.total = draft.total + delta;
|
||||
}
|
||||
)
|
||||
)
|
||||
);
|
||||
} else {
|
||||
// ELSE (it is being changed to a non-intermediate):
|
||||
console.log(imageDTO);
|
||||
const queryArgs = {
|
||||
board_id: imageDTO.board_id ?? 'none',
|
||||
categories,
|
||||
};
|
||||
|
||||
const currentCache = imagesApi.endpoints.listImages.select(queryArgs)(
|
||||
getState()
|
||||
);
|
||||
|
||||
// IF it eligible for insertion into existing $cache
|
||||
// "eligible" means either:
|
||||
// - The cache is fully populated, with all images in the db cached
|
||||
// OR
|
||||
// - The image's `created_at` is within the range of the cached images
|
||||
|
||||
const isCacheFullyPopulated =
|
||||
currentCache.data &&
|
||||
currentCache.data.ids.length >= currentCache.data.total;
|
||||
|
||||
const isInDateRange = getIsImageInDateRange(
|
||||
currentCache.data,
|
||||
imageDTO
|
||||
);
|
||||
|
||||
if (isCacheFullyPopulated || isInDateRange) {
|
||||
// *upsert* to $cache
|
||||
patches.push(
|
||||
dispatch(
|
||||
imagesApi.util.updateQueryData(
|
||||
'listImages',
|
||||
queryArgs,
|
||||
(draft) => {
|
||||
const oldTotal = draft.total;
|
||||
const newState = imagesAdapter.upsertOne(draft, imageDTO);
|
||||
const delta = newState.total - oldTotal;
|
||||
draft.total = draft.total + delta;
|
||||
}
|
||||
)
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
await queryFulfilled;
|
||||
} catch {
|
||||
patches.forEach((patchResult) => patchResult.undo());
|
||||
}
|
||||
},
|
||||
}),
|
||||
/**
|
||||
* Change an image's `session_id` association.
|
||||
*/
|
||||
changeImageSessionId: build.mutation<
|
||||
ImageDTO,
|
||||
{ imageDTO: ImageDTO; session_id: string }
|
||||
>({
|
||||
query: ({ imageDTO, session_id }) => ({
|
||||
url: `images/${imageDTO.image_name}`,
|
||||
method: 'PATCH',
|
||||
body: { session_id },
|
||||
}),
|
||||
invalidatesTags: (result, error, { imageDTO }) => [
|
||||
{ type: 'BoardImagesTotal', id: imageDTO.board_id ?? 'none' },
|
||||
{ type: 'BoardAssetsTotal', id: imageDTO.board_id ?? 'none' },
|
||||
],
|
||||
async onQueryStarted(
|
||||
{ imageDTO, session_id },
|
||||
{ dispatch, queryFulfilled, getState }
|
||||
) {
|
||||
/**
|
||||
* Cache changes for `changeImageSessionId`:
|
||||
* - *update* getImageDTO
|
||||
*/
|
||||
|
||||
// Store patches so we can undo if the query fails
|
||||
const patches: PatchCollection[] = [];
|
||||
|
||||
// *update* getImageDTO
|
||||
patches.push(
|
||||
dispatch(
|
||||
imagesApi.util.updateQueryData(
|
||||
'getImageDTO',
|
||||
imageDTO.image_name,
|
||||
(draft) => {
|
||||
Object.assign(draft, { session_id });
|
||||
}
|
||||
)
|
||||
)
|
||||
);
|
||||
|
||||
try {
|
||||
await queryFulfilled;
|
||||
} catch {
|
||||
patches.forEach((patchResult) => patchResult.undo());
|
||||
}
|
||||
},
|
||||
}),
|
||||
uploadImage: build.mutation<
|
||||
ImageDTO,
|
||||
{
|
||||
file: File;
|
||||
image_category: ImageCategory;
|
||||
is_intermediate: boolean;
|
||||
postUploadAction?: PostUploadAction;
|
||||
session_id?: string;
|
||||
board_id?: string;
|
||||
crop_visible?: boolean;
|
||||
}
|
||||
>({
|
||||
query: ({
|
||||
file,
|
||||
image_category,
|
||||
is_intermediate,
|
||||
session_id,
|
||||
board_id,
|
||||
crop_visible,
|
||||
}) => {
|
||||
const formData = new FormData();
|
||||
formData.append('file', file);
|
||||
return {
|
||||
url: `images/`,
|
||||
method: 'POST',
|
||||
body: formData,
|
||||
params: {
|
||||
image_category,
|
||||
is_intermediate,
|
||||
session_id,
|
||||
board_id,
|
||||
crop_visible,
|
||||
},
|
||||
};
|
||||
},
|
||||
async onQueryStarted(
|
||||
{
|
||||
file,
|
||||
image_category,
|
||||
is_intermediate,
|
||||
postUploadAction,
|
||||
session_id,
|
||||
board_id,
|
||||
},
|
||||
{ dispatch, queryFulfilled }
|
||||
) {
|
||||
try {
|
||||
/**
|
||||
* NOTE: PESSIMISTIC UPDATE
|
||||
* Cache changes for `uploadImage`:
|
||||
* - IF the image is an intermediate:
|
||||
* - BAIL OUT
|
||||
* - *add* to `getImageDTO`
|
||||
* - *add* to no_board/assets
|
||||
*/
|
||||
|
||||
const { data: imageDTO } = await queryFulfilled;
|
||||
|
||||
if (imageDTO.is_intermediate) {
|
||||
// Don't add it to anything
|
||||
return;
|
||||
}
|
||||
|
||||
// *add* to `getImageDTO`
|
||||
dispatch(
|
||||
imagesApi.util.upsertQueryData(
|
||||
'getImageDTO',
|
||||
imageDTO.image_name,
|
||||
imageDTO
|
||||
)
|
||||
);
|
||||
|
||||
const categories = getCategories(imageDTO);
|
||||
|
||||
// *add* to no_board/assets
|
||||
dispatch(
|
||||
imagesApi.util.updateQueryData(
|
||||
'listImages',
|
||||
{
|
||||
board_id: imageDTO.board_id ?? 'none',
|
||||
categories,
|
||||
},
|
||||
(draft) => {
|
||||
const oldTotal = draft.total;
|
||||
const newState = imagesAdapter.addOne(draft, imageDTO);
|
||||
const delta = newState.total - oldTotal;
|
||||
draft.total = draft.total + delta;
|
||||
}
|
||||
)
|
||||
);
|
||||
|
||||
dispatch(
|
||||
imagesApi.util.invalidateTags([
|
||||
{ type: 'BoardImagesTotal', id: imageDTO.board_id ?? 'none' },
|
||||
{ type: 'BoardAssetsTotal', id: imageDTO.board_id ?? 'none' },
|
||||
])
|
||||
);
|
||||
} catch {
|
||||
// query failed, no action needed
|
||||
}
|
||||
},
|
||||
}),
|
||||
addImageToBoard: build.mutation<
|
||||
void,
|
||||
{ board_id: BoardId; imageDTO: ImageDTO }
|
||||
>({
|
||||
query: ({ board_id, imageDTO }) => {
|
||||
const { image_name } = imageDTO;
|
||||
return {
|
||||
url: `board_images/`,
|
||||
method: 'POST',
|
||||
body: { board_id, image_name },
|
||||
};
|
||||
},
|
||||
invalidatesTags: (result, error, { board_id, imageDTO }) => [
|
||||
{ type: 'Board', id: board_id },
|
||||
{ type: 'BoardImagesTotal', id: board_id },
|
||||
{ type: 'BoardImagesTotal', id: imageDTO.board_id ?? 'none' },
|
||||
{ type: 'BoardAssetsTotal', id: board_id },
|
||||
{ type: 'BoardAssetsTotal', id: imageDTO.board_id ?? 'none' },
|
||||
],
|
||||
async onQueryStarted(
|
||||
{ board_id, imageDTO },
|
||||
{ dispatch, queryFulfilled, getState }
|
||||
) {
|
||||
/**
|
||||
* Cache changes for `addImageToBoard`:
|
||||
* - *update* getImageDTO
|
||||
* - IF it is intermediate:
|
||||
* - BAIL OUT ON FURTHER CHANGES
|
||||
* - IF it has an old board_id:
|
||||
* - THEN *remove* from old board_id/[images|assets]
|
||||
* - ELSE *remove* from no_board/[images|assets]
|
||||
* - $cache = board_id/[images|assets]
|
||||
* - IF it eligible for insertion into existing $cache:
|
||||
* - THEN *add* to $cache
|
||||
*/
|
||||
|
||||
const patches: PatchCollection[] = [];
|
||||
const categories = getCategories(imageDTO);
|
||||
|
||||
// *update* getImageDTO
|
||||
patches.push(
|
||||
dispatch(
|
||||
imagesApi.util.updateQueryData(
|
||||
'getImageDTO',
|
||||
imageDTO.image_name,
|
||||
(draft) => {
|
||||
Object.assign(draft, { board_id });
|
||||
}
|
||||
)
|
||||
)
|
||||
);
|
||||
|
||||
if (!imageDTO.is_intermediate) {
|
||||
// *remove* from [no_board|board_id]/[images|assets]
|
||||
patches.push(
|
||||
dispatch(
|
||||
imagesApi.util.updateQueryData(
|
||||
'listImages',
|
||||
{
|
||||
board_id: imageDTO.board_id ?? 'none',
|
||||
categories,
|
||||
},
|
||||
(draft) => {
|
||||
const oldTotal = draft.total;
|
||||
const newState = imagesAdapter.removeOne(
|
||||
draft,
|
||||
imageDTO.image_name
|
||||
);
|
||||
const delta = newState.total - oldTotal;
|
||||
draft.total = draft.total + delta;
|
||||
}
|
||||
)
|
||||
)
|
||||
);
|
||||
|
||||
// $cache = board_id/[images|assets]
|
||||
const queryArgs = { board_id: board_id ?? 'none', categories };
|
||||
const currentCache = imagesApi.endpoints.listImages.select(queryArgs)(
|
||||
getState()
|
||||
);
|
||||
|
||||
// IF it eligible for insertion into existing $cache
|
||||
// "eligible" means either:
|
||||
// - The cache is fully populated, with all images in the db cached
|
||||
// OR
|
||||
// - The image's `created_at` is within the range of the cached images
|
||||
|
||||
const isCacheFullyPopulated =
|
||||
currentCache.data &&
|
||||
currentCache.data.ids.length >= currentCache.data.total;
|
||||
|
||||
const isInDateRange = getIsImageInDateRange(
|
||||
currentCache.data,
|
||||
imageDTO
|
||||
);
|
||||
|
||||
if (isCacheFullyPopulated || isInDateRange) {
|
||||
// THEN *add* to $cache
|
||||
patches.push(
|
||||
dispatch(
|
||||
imagesApi.util.updateQueryData(
|
||||
'listImages',
|
||||
queryArgs,
|
||||
(draft) => {
|
||||
const oldTotal = draft.total;
|
||||
const newState = imagesAdapter.addOne(draft, imageDTO);
|
||||
const delta = newState.total - oldTotal;
|
||||
draft.total = draft.total + delta;
|
||||
}
|
||||
)
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
await queryFulfilled;
|
||||
} catch {
|
||||
patches.forEach((patchResult) => patchResult.undo());
|
||||
}
|
||||
},
|
||||
}),
|
||||
removeImageFromBoard: build.mutation<void, { imageDTO: ImageDTO }>({
|
||||
query: ({ imageDTO }) => {
|
||||
const { board_id, image_name } = imageDTO;
|
||||
return {
|
||||
url: `board_images/`,
|
||||
method: 'DELETE',
|
||||
body: { board_id, image_name },
|
||||
};
|
||||
},
|
||||
invalidatesTags: (result, error, { imageDTO }) => [
|
||||
{ type: 'Board', id: imageDTO.board_id },
|
||||
{ type: 'BoardImagesTotal', id: imageDTO.board_id },
|
||||
{ type: 'BoardImagesTotal', id: 'none' },
|
||||
{ type: 'BoardAssetsTotal', id: imageDTO.board_id },
|
||||
{ type: 'BoardAssetsTotal', id: 'none' },
|
||||
],
|
||||
async onQueryStarted(
|
||||
{ imageDTO },
|
||||
{ dispatch, queryFulfilled, getState }
|
||||
) {
|
||||
/**
|
||||
* Cache changes for removeImageFromBoard:
|
||||
* - *update* getImageDTO
|
||||
* - *remove* from board_id/[images|assets]
|
||||
* - $cache = no_board/[images|assets]
|
||||
* - IF it eligible for insertion into existing $cache:
|
||||
* - THEN *upsert* to $cache
|
||||
*/
|
||||
|
||||
const categories = getCategories(imageDTO);
|
||||
const patches: PatchCollection[] = [];
|
||||
|
||||
// *update* getImageDTO
|
||||
patches.push(
|
||||
dispatch(
|
||||
imagesApi.util.updateQueryData(
|
||||
'getImageDTO',
|
||||
imageDTO.image_name,
|
||||
(draft) => {
|
||||
Object.assign(draft, { board_id: undefined });
|
||||
}
|
||||
)
|
||||
)
|
||||
);
|
||||
|
||||
// *remove* from board_id/[images|assets]
|
||||
patches.push(
|
||||
dispatch(
|
||||
imagesApi.util.updateQueryData(
|
||||
'listImages',
|
||||
{
|
||||
board_id: imageDTO.board_id ?? 'none',
|
||||
categories,
|
||||
},
|
||||
(draft) => {
|
||||
const oldTotal = draft.total;
|
||||
const newState = imagesAdapter.removeOne(
|
||||
draft,
|
||||
imageDTO.image_name
|
||||
);
|
||||
const delta = newState.total - oldTotal;
|
||||
draft.total = draft.total + delta;
|
||||
}
|
||||
)
|
||||
)
|
||||
);
|
||||
|
||||
// $cache = no_board/[images|assets]
|
||||
const queryArgs = { board_id: 'none', categories };
|
||||
const currentCache = imagesApi.endpoints.listImages.select(queryArgs)(
|
||||
getState()
|
||||
);
|
||||
|
||||
// IF it eligible for insertion into existing $cache
|
||||
// "eligible" means either:
|
||||
// - The cache is fully populated, with all images in the db cached
|
||||
// OR
|
||||
// - The image's `created_at` is within the range of the cached images
|
||||
|
||||
const isCacheFullyPopulated =
|
||||
currentCache.data &&
|
||||
currentCache.data.ids.length >= currentCache.data.total;
|
||||
|
||||
const isInDateRange = getIsImageInDateRange(
|
||||
currentCache.data,
|
||||
imageDTO
|
||||
);
|
||||
|
||||
if (isCacheFullyPopulated || isInDateRange) {
|
||||
// THEN *upsert* to $cache
|
||||
patches.push(
|
||||
dispatch(
|
||||
imagesApi.util.updateQueryData(
|
||||
'listImages',
|
||||
queryArgs,
|
||||
(draft) => {
|
||||
const oldTotal = draft.total;
|
||||
const newState = imagesAdapter.upsertOne(draft, imageDTO);
|
||||
const delta = newState.total - oldTotal;
|
||||
draft.total = draft.total + delta;
|
||||
}
|
||||
)
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
try {
|
||||
await queryFulfilled;
|
||||
} catch {
|
||||
patches.forEach((patchResult) => patchResult.undo());
|
||||
}
|
||||
},
|
||||
}),
|
||||
}),
|
||||
});
|
||||
|
||||
export const { useGetImageDTOQuery, useGetImageMetadataQuery } = imagesApi;
|
||||
export const {
|
||||
useGetIntermediatesCountQuery,
|
||||
useListImagesQuery,
|
||||
useLazyListImagesQuery,
|
||||
useGetImageDTOQuery,
|
||||
useGetImageMetadataQuery,
|
||||
useDeleteImageMutation,
|
||||
useGetBoardImagesTotalQuery,
|
||||
useGetBoardAssetsTotalQuery,
|
||||
useUploadImageMutation,
|
||||
useAddImageToBoardMutation,
|
||||
useRemoveImageFromBoardMutation,
|
||||
useClearIntermediatesMutation,
|
||||
} = imagesApi;
|
||||
|
@ -97,6 +97,9 @@ type AddMainModelArg = {
|
||||
type AddMainModelResponse =
|
||||
paths['/api/v1/models/add']['post']['responses']['201']['content']['application/json'];
|
||||
|
||||
type SyncModelsResponse =
|
||||
paths['/api/v1/models/sync']['post']['responses']['201']['content']['application/json'];
|
||||
|
||||
export type SearchFolderResponse =
|
||||
paths['/api/v1/models/search']['get']['responses']['200']['content']['application/json'];
|
||||
|
||||
@ -181,8 +184,19 @@ export const modelsApi = api.injectEndpoints({
|
||||
);
|
||||
},
|
||||
}),
|
||||
getMainModels: build.query<EntityState<MainModelConfigEntity>, void>({
|
||||
query: () => ({ url: 'models/', params: { model_type: 'main' } }),
|
||||
getMainModels: build.query<
|
||||
EntityState<MainModelConfigEntity>,
|
||||
BaseModelType[]
|
||||
>({
|
||||
query: (base_models) => {
|
||||
const params = {
|
||||
model_type: 'main',
|
||||
base_models,
|
||||
};
|
||||
|
||||
const query = queryString.stringify(params, { arrayFormat: 'none' });
|
||||
return `models/?${query}`;
|
||||
},
|
||||
providesTags: (result, error, arg) => {
|
||||
const tags: ApiFullTagDescription[] = [
|
||||
{ type: 'MainModel', id: LIST_TAG },
|
||||
@ -224,7 +238,10 @@ export const modelsApi = api.injectEndpoints({
|
||||
body: body,
|
||||
};
|
||||
},
|
||||
invalidatesTags: [{ type: 'MainModel', id: LIST_TAG }],
|
||||
invalidatesTags: [
|
||||
{ type: 'MainModel', id: LIST_TAG },
|
||||
{ type: 'SDXLRefinerModel', id: LIST_TAG },
|
||||
],
|
||||
}),
|
||||
importMainModels: build.mutation<
|
||||
ImportMainModelResponse,
|
||||
@ -237,7 +254,10 @@ export const modelsApi = api.injectEndpoints({
|
||||
body: body,
|
||||
};
|
||||
},
|
||||
invalidatesTags: [{ type: 'MainModel', id: LIST_TAG }],
|
||||
invalidatesTags: [
|
||||
{ type: 'MainModel', id: LIST_TAG },
|
||||
{ type: 'SDXLRefinerModel', id: LIST_TAG },
|
||||
],
|
||||
}),
|
||||
addMainModels: build.mutation<AddMainModelResponse, AddMainModelArg>({
|
||||
query: ({ body }) => {
|
||||
@ -247,7 +267,10 @@ export const modelsApi = api.injectEndpoints({
|
||||
body: body,
|
||||
};
|
||||
},
|
||||
invalidatesTags: [{ type: 'MainModel', id: LIST_TAG }],
|
||||
invalidatesTags: [
|
||||
{ type: 'MainModel', id: LIST_TAG },
|
||||
{ type: 'SDXLRefinerModel', id: LIST_TAG },
|
||||
],
|
||||
}),
|
||||
deleteMainModels: build.mutation<
|
||||
DeleteMainModelResponse,
|
||||
@ -259,7 +282,10 @@ export const modelsApi = api.injectEndpoints({
|
||||
method: 'DELETE',
|
||||
};
|
||||
},
|
||||
invalidatesTags: [{ type: 'MainModel', id: LIST_TAG }],
|
||||
invalidatesTags: [
|
||||
{ type: 'MainModel', id: LIST_TAG },
|
||||
{ type: 'SDXLRefinerModel', id: LIST_TAG },
|
||||
],
|
||||
}),
|
||||
convertMainModels: build.mutation<
|
||||
ConvertMainModelResponse,
|
||||
@ -272,7 +298,10 @@ export const modelsApi = api.injectEndpoints({
|
||||
params: params,
|
||||
};
|
||||
},
|
||||
invalidatesTags: [{ type: 'MainModel', id: LIST_TAG }],
|
||||
invalidatesTags: [
|
||||
{ type: 'MainModel', id: LIST_TAG },
|
||||
{ type: 'SDXLRefinerModel', id: LIST_TAG },
|
||||
],
|
||||
}),
|
||||
mergeMainModels: build.mutation<MergeMainModelResponse, MergeMainModelArg>({
|
||||
query: ({ base_model, body }) => {
|
||||
@ -282,7 +311,22 @@ export const modelsApi = api.injectEndpoints({
|
||||
body: body,
|
||||
};
|
||||
},
|
||||
invalidatesTags: [{ type: 'MainModel', id: LIST_TAG }],
|
||||
invalidatesTags: [
|
||||
{ type: 'MainModel', id: LIST_TAG },
|
||||
{ type: 'SDXLRefinerModel', id: LIST_TAG },
|
||||
],
|
||||
}),
|
||||
syncModels: build.mutation<SyncModelsResponse, void>({
|
||||
query: () => {
|
||||
return {
|
||||
url: `models/sync`,
|
||||
method: 'POST',
|
||||
};
|
||||
},
|
||||
invalidatesTags: [
|
||||
{ type: 'MainModel', id: LIST_TAG },
|
||||
{ type: 'SDXLRefinerModel', id: LIST_TAG },
|
||||
],
|
||||
}),
|
||||
getLoRAModels: build.query<EntityState<LoRAModelConfigEntity>, void>({
|
||||
query: () => ({ url: 'models/', params: { model_type: 'lora' } }),
|
||||
@ -464,6 +508,7 @@ export const {
|
||||
useAddMainModelsMutation,
|
||||
useConvertMainModelsMutation,
|
||||
useMergeMainModelsMutation,
|
||||
useSyncModelsMutation,
|
||||
useGetModelsInFolderQuery,
|
||||
useGetCheckpointConfigsQuery,
|
||||
} = modelsApi;
|
||||
|
15
invokeai/frontend/web/src/services/api/hooks/useBoardName.ts
Normal file
15
invokeai/frontend/web/src/services/api/hooks/useBoardName.ts
Normal file
@ -0,0 +1,15 @@
|
||||
import { BoardId } from 'features/gallery/store/types';
|
||||
import { useListAllBoardsQuery } from '../endpoints/boards';
|
||||
|
||||
export const useBoardName = (board_id: BoardId | null | undefined) => {
|
||||
const { boardName } = useListAllBoardsQuery(undefined, {
|
||||
selectFromResult: ({ data }) => {
|
||||
const selectedBoard = data?.find((b) => b.board_id === board_id);
|
||||
const boardName = selectedBoard?.board_name || 'Uncategorized';
|
||||
|
||||
return { boardName };
|
||||
},
|
||||
});
|
||||
|
||||
return boardName;
|
||||
};
|
@ -0,0 +1,21 @@
|
||||
import { useAppSelector } from 'app/store/storeHooks';
|
||||
import { BoardId } from 'features/gallery/store/types';
|
||||
import { useMemo } from 'react';
|
||||
import {
|
||||
useGetBoardAssetsTotalQuery,
|
||||
useGetBoardImagesTotalQuery,
|
||||
} from '../endpoints/images';
|
||||
|
||||
export const useBoardTotal = (board_id: BoardId) => {
|
||||
const galleryView = useAppSelector((state) => state.gallery.galleryView);
|
||||
|
||||
const { data: totalImages } = useGetBoardImagesTotalQuery(board_id);
|
||||
const { data: totalAssets } = useGetBoardAssetsTotalQuery(board_id);
|
||||
|
||||
const currentViewTotal = useMemo(
|
||||
() => (galleryView === 'images' ? totalImages : totalAssets),
|
||||
[galleryView, totalAssets, totalImages]
|
||||
);
|
||||
|
||||
return { totalImages, totalAssets, currentViewTotal };
|
||||
};
|
@ -0,0 +1,12 @@
|
||||
import { REFINER_BASE_MODELS } from 'services/api/constants';
|
||||
import { useGetMainModelsQuery } from 'services/api/endpoints/models';
|
||||
|
||||
export const useIsRefinerAvailable = () => {
|
||||
const { isRefinerAvailable } = useGetMainModelsQuery(REFINER_BASE_MODELS, {
|
||||
selectFromResult: ({ data }) => ({
|
||||
isRefinerAvailable: data ? data.ids.length > 0 : false,
|
||||
}),
|
||||
});
|
||||
|
||||
return isRefinerAvailable;
|
||||
};
|
@ -8,133 +8,16 @@ import {
|
||||
} from '@reduxjs/toolkit/query/react';
|
||||
import { $authToken, $baseUrl } from 'services/api/client';
|
||||
|
||||
export type { AddInvocation } from './models/AddInvocation';
|
||||
export type { BoardChanges } from './models/BoardChanges';
|
||||
export type { BoardDTO } from './models/BoardDTO';
|
||||
export type { Body_create_board_image } from './models/Body_create_board_image';
|
||||
export type { Body_remove_board_image } from './models/Body_remove_board_image';
|
||||
export type { Body_upload_image } from './models/Body_upload_image';
|
||||
export type { CannyImageProcessorInvocation } from './models/CannyImageProcessorInvocation';
|
||||
export type { CkptModelInfo } from './models/CkptModelInfo';
|
||||
export type { ClipField } from './models/ClipField';
|
||||
export type { CollectInvocation } from './models/CollectInvocation';
|
||||
export type { CollectInvocationOutput } from './models/CollectInvocationOutput';
|
||||
export type { ColorField } from './models/ColorField';
|
||||
export type { CompelInvocation } from './models/CompelInvocation';
|
||||
export type { CompelOutput } from './models/CompelOutput';
|
||||
export type { ConditioningField } from './models/ConditioningField';
|
||||
export type { ContentShuffleImageProcessorInvocation } from './models/ContentShuffleImageProcessorInvocation';
|
||||
export type { ControlField } from './models/ControlField';
|
||||
export type { ControlNetInvocation } from './models/ControlNetInvocation';
|
||||
export type { ControlNetModelConfig } from './models/ControlNetModelConfig';
|
||||
export type { ControlOutput } from './models/ControlOutput';
|
||||
export type { CreateModelRequest } from './models/CreateModelRequest';
|
||||
export type { CvInpaintInvocation } from './models/CvInpaintInvocation';
|
||||
export type { DiffusersModelInfo } from './models/DiffusersModelInfo';
|
||||
export type { DivideInvocation } from './models/DivideInvocation';
|
||||
export type { DynamicPromptInvocation } from './models/DynamicPromptInvocation';
|
||||
export type { Edge } from './models/Edge';
|
||||
export type { EdgeConnection } from './models/EdgeConnection';
|
||||
export type { FloatCollectionOutput } from './models/FloatCollectionOutput';
|
||||
export type { FloatLinearRangeInvocation } from './models/FloatLinearRangeInvocation';
|
||||
export type { FloatOutput } from './models/FloatOutput';
|
||||
export type { Graph } from './models/Graph';
|
||||
export type { GraphExecutionState } from './models/GraphExecutionState';
|
||||
export type { GraphInvocation } from './models/GraphInvocation';
|
||||
export type { GraphInvocationOutput } from './models/GraphInvocationOutput';
|
||||
export type { HTTPValidationError } from './models/HTTPValidationError';
|
||||
export type { ImageBlurInvocation } from './models/ImageBlurInvocation';
|
||||
export type { ImageChannelInvocation } from './models/ImageChannelInvocation';
|
||||
export type { ImageConvertInvocation } from './models/ImageConvertInvocation';
|
||||
export type { ImageCropInvocation } from './models/ImageCropInvocation';
|
||||
export type { ImageDTO } from './models/ImageDTO';
|
||||
export type { ImageField } from './models/ImageField';
|
||||
export type { ImageInverseLerpInvocation } from './models/ImageInverseLerpInvocation';
|
||||
export type { ImageLerpInvocation } from './models/ImageLerpInvocation';
|
||||
export type { ImageMetadata } from './models/ImageMetadata';
|
||||
export type { ImageMultiplyInvocation } from './models/ImageMultiplyInvocation';
|
||||
export type { ImageOutput } from './models/ImageOutput';
|
||||
export type { ImagePasteInvocation } from './models/ImagePasteInvocation';
|
||||
export type { ImageProcessorInvocation } from './models/ImageProcessorInvocation';
|
||||
export type { ImageRecordChanges } from './models/ImageRecordChanges';
|
||||
export type { ImageResizeInvocation } from './models/ImageResizeInvocation';
|
||||
export type { ImageScaleInvocation } from './models/ImageScaleInvocation';
|
||||
export type { ImageToLatentsInvocation } from './models/ImageToLatentsInvocation';
|
||||
export type { ImageUrlsDTO } from './models/ImageUrlsDTO';
|
||||
export type { InfillColorInvocation } from './models/InfillColorInvocation';
|
||||
export type { InfillPatchMatchInvocation } from './models/InfillPatchMatchInvocation';
|
||||
export type { InfillTileInvocation } from './models/InfillTileInvocation';
|
||||
export type { InpaintInvocation } from './models/InpaintInvocation';
|
||||
export type { IntCollectionOutput } from './models/IntCollectionOutput';
|
||||
export type { IntOutput } from './models/IntOutput';
|
||||
export type { IterateInvocation } from './models/IterateInvocation';
|
||||
export type { IterateInvocationOutput } from './models/IterateInvocationOutput';
|
||||
export type { LatentsField } from './models/LatentsField';
|
||||
export type { LatentsOutput } from './models/LatentsOutput';
|
||||
export type { LatentsToImageInvocation } from './models/LatentsToImageInvocation';
|
||||
export type { LatentsToLatentsInvocation } from './models/LatentsToLatentsInvocation';
|
||||
export type { LineartAnimeImageProcessorInvocation } from './models/LineartAnimeImageProcessorInvocation';
|
||||
export type { LineartImageProcessorInvocation } from './models/LineartImageProcessorInvocation';
|
||||
export type { LoadImageInvocation } from './models/LoadImageInvocation';
|
||||
export type { LoraInfo } from './models/LoraInfo';
|
||||
export type { LoraLoaderInvocation } from './models/LoraLoaderInvocation';
|
||||
export type { LoraLoaderOutput } from './models/LoraLoaderOutput';
|
||||
export type { MaskFromAlphaInvocation } from './models/MaskFromAlphaInvocation';
|
||||
export type { MaskOutput } from './models/MaskOutput';
|
||||
export type { MediapipeFaceProcessorInvocation } from './models/MediapipeFaceProcessorInvocation';
|
||||
export type { MidasDepthImageProcessorInvocation } from './models/MidasDepthImageProcessorInvocation';
|
||||
export type { MlsdImageProcessorInvocation } from './models/MlsdImageProcessorInvocation';
|
||||
export type { ModelInfo } from './models/ModelInfo';
|
||||
export type { ModelLoaderOutput } from './models/ModelLoaderOutput';
|
||||
export type { ModelsList } from './models/ModelsList';
|
||||
export type { ModelType } from './models/ModelType';
|
||||
export type { MultiplyInvocation } from './models/MultiplyInvocation';
|
||||
export type { NoiseInvocation } from './models/NoiseInvocation';
|
||||
export type { NoiseOutput } from './models/NoiseOutput';
|
||||
export type { NormalbaeImageProcessorInvocation } from './models/NormalbaeImageProcessorInvocation';
|
||||
export type { OffsetPaginatedResults_BoardDTO_ } from './models/OffsetPaginatedResults_BoardDTO_';
|
||||
export type { OffsetPaginatedResults_ImageDTO_ } from './models/OffsetPaginatedResults_ImageDTO_';
|
||||
export type { ONNXLatentsToImageInvocation } from './models/ONNXLatentsToImageInvocation';
|
||||
export type { ONNXModelLoaderOutput } from './models/ONNXModelLoaderOutput';
|
||||
export type { ONNXPromptInvocation } from './models/ONNXPromptInvocation';
|
||||
export type { ONNXSD1ModelLoaderInvocation } from './models/ONNXSD1ModelLoaderInvocation';
|
||||
export type { ONNXStableDiffusion1ModelConfig } from './models/ONNXStableDiffusion1ModelConfig';
|
||||
export type { ONNXStableDiffusion2ModelConfig } from './models/ONNXStableDiffusion2ModelConfig';
|
||||
export type { ONNXTextToLatentsInvocation } from './models/ONNXTextToLatentsInvocation';
|
||||
export type { OpenposeImageProcessorInvocation } from './models/OpenposeImageProcessorInvocation';
|
||||
export type { PaginatedResults_GraphExecutionState_ } from './models/PaginatedResults_GraphExecutionState_';
|
||||
export type { ParamFloatInvocation } from './models/ParamFloatInvocation';
|
||||
export type { ParamIntInvocation } from './models/ParamIntInvocation';
|
||||
export type { PidiImageProcessorInvocation } from './models/PidiImageProcessorInvocation';
|
||||
export type { PipelineModelField } from './models/PipelineModelField';
|
||||
export type { PipelineModelLoaderInvocation } from './models/PipelineModelLoaderInvocation';
|
||||
export type { PromptCollectionOutput } from './models/PromptCollectionOutput';
|
||||
export type { PromptOutput } from './models/PromptOutput';
|
||||
export type { RandomIntInvocation } from './models/RandomIntInvocation';
|
||||
export type { RandomRangeInvocation } from './models/RandomRangeInvocation';
|
||||
export type { RangeInvocation } from './models/RangeInvocation';
|
||||
export type { RangeOfSizeInvocation } from './models/RangeOfSizeInvocation';
|
||||
export type { ResizeLatentsInvocation } from './models/ResizeLatentsInvocation';
|
||||
export type { RestoreFaceInvocation } from './models/RestoreFaceInvocation';
|
||||
export type { ScaleLatentsInvocation } from './models/ScaleLatentsInvocation';
|
||||
export type { ShowImageInvocation } from './models/ShowImageInvocation';
|
||||
export type { StableDiffusion1ModelCheckpointConfig } from './models/StableDiffusion1ModelCheckpointConfig';
|
||||
export type { StableDiffusion1ModelDiffusersConfig } from './models/StableDiffusion1ModelDiffusersConfig';
|
||||
export type { StableDiffusion2ModelCheckpointConfig } from './models/StableDiffusion2ModelCheckpointConfig';
|
||||
export type { StableDiffusion2ModelDiffusersConfig } from './models/StableDiffusion2ModelDiffusersConfig';
|
||||
export type { StepParamEasingInvocation } from './models/StepParamEasingInvocation';
|
||||
export type { SubModelType } from './models/SubModelType';
|
||||
export type { SubtractInvocation } from './models/SubtractInvocation';
|
||||
export type { TextToLatentsInvocation } from './models/TextToLatentsInvocation';
|
||||
export type { TextualInversionModelConfig } from './models/TextualInversionModelConfig';
|
||||
export type { UNetField } from './models/UNetField';
|
||||
export type { UpscaleInvocation } from './models/UpscaleInvocation';
|
||||
export type { VaeField } from './models/VaeField';
|
||||
export type { VaeModelConfig } from './models/VaeModelConfig';
|
||||
export type { VaeRepo } from './models/VaeRepo';
|
||||
export type { ValidationError } from './models/ValidationError';
|
||||
export type { ZoeDepthImageProcessorInvocation } from './models/ZoeDepthImageProcessorInvocation';
|
||||
export const tagTypes = ['Board', 'Image', 'ImageMetadata', 'Model'];
|
||||
export const tagTypes = [
|
||||
'Board',
|
||||
'BoardImagesTotal',
|
||||
'BoardAssetsTotal',
|
||||
'Image',
|
||||
'ImageNameList',
|
||||
'ImageList',
|
||||
'ImageMetadata',
|
||||
'Model',
|
||||
];
|
||||
export type ApiFullTagDescription = FullTagDescription<
|
||||
(typeof tagTypes)[number]
|
||||
>;
|
||||
|
@ -1,36 +0,0 @@
|
||||
/* istanbul ignore file */
|
||||
/* tslint:disable */
|
||||
/* eslint-disable */
|
||||
|
||||
import type { ImageField } from './ImageField';
|
||||
|
||||
/**
|
||||
* Applies HED edge detection to image
|
||||
*/
|
||||
export type HedImageProcessorInvocation = {
|
||||
/**
|
||||
* The id of this node. Must be unique among all nodes.
|
||||
*/
|
||||
id: string;
|
||||
/**
|
||||
* Whether or not this node is an intermediate node.
|
||||
*/
|
||||
is_intermediate?: boolean;
|
||||
type?: 'hed_image_processor';
|
||||
/**
|
||||
* The image to process
|
||||
*/
|
||||
image?: ImageField;
|
||||
/**
|
||||
* The pixel resolution for detection
|
||||
*/
|
||||
detect_resolution?: number;
|
||||
/**
|
||||
* The pixel resolution for the output image
|
||||
*/
|
||||
image_resolution?: number;
|
||||
/**
|
||||
* Whether to use scribble mode
|
||||
*/
|
||||
scribble?: boolean;
|
||||
};
|
412
invokeai/frontend/web/src/services/api/schema.d.ts
vendored
412
invokeai/frontend/web/src/services/api/schema.d.ts
vendored
@ -126,7 +126,7 @@ export type paths = {
|
||||
* @description Call after making changes to models.yaml, autoimport directories or models directory to synchronize
|
||||
* in-memory data structures with disk data structures.
|
||||
*/
|
||||
get: operations["sync_to_config"];
|
||||
post: operations["sync_to_config"];
|
||||
};
|
||||
"/api/v1/models/merge/{base_model}": {
|
||||
/**
|
||||
@ -164,6 +164,13 @@ export type paths = {
|
||||
*/
|
||||
patch: operations["update_image"];
|
||||
};
|
||||
"/api/v1/images/clear-intermediates": {
|
||||
/**
|
||||
* Clear Intermediates
|
||||
* @description Clears all intermediates
|
||||
*/
|
||||
post: operations["clear_intermediates"];
|
||||
};
|
||||
"/api/v1/images/{image_name}/metadata": {
|
||||
/**
|
||||
* Get Image Metadata
|
||||
@ -221,6 +228,13 @@ export type paths = {
|
||||
*/
|
||||
patch: operations["update_board"];
|
||||
};
|
||||
"/api/v1/boards/{board_id}/image_names": {
|
||||
/**
|
||||
* List All Board Image Names
|
||||
* @description Gets a list of images for a board
|
||||
*/
|
||||
get: operations["list_all_board_image_names"];
|
||||
};
|
||||
"/api/v1/board_images/": {
|
||||
/**
|
||||
* Create Board Image
|
||||
@ -233,13 +247,6 @@ export type paths = {
|
||||
*/
|
||||
delete: operations["remove_board_image"];
|
||||
};
|
||||
"/api/v1/board_images/{board_id}": {
|
||||
/**
|
||||
* List Board Images
|
||||
* @description Gets a list of images for a board
|
||||
*/
|
||||
get: operations["list_board_images"];
|
||||
};
|
||||
"/api/v1/app/version": {
|
||||
/** Get Version */
|
||||
get: operations["app_version"];
|
||||
@ -248,6 +255,18 @@ export type paths = {
|
||||
/** Get Config */
|
||||
get: operations["get_config"];
|
||||
};
|
||||
"/api/v1/app/logging": {
|
||||
/**
|
||||
* Get Log Level
|
||||
* @description Returns the log level
|
||||
*/
|
||||
get: operations["get_log_level"];
|
||||
/**
|
||||
* Set Log Level
|
||||
* @description Sets the log verbosity level
|
||||
*/
|
||||
post: operations["set_log_level"];
|
||||
};
|
||||
};
|
||||
|
||||
export type webhooks = Record<string, never>;
|
||||
@ -299,6 +318,21 @@ export type components = {
|
||||
* @description List of available infill methods
|
||||
*/
|
||||
infill_methods: (string)[];
|
||||
/**
|
||||
* Upscaling Methods
|
||||
* @description List of upscaling methods
|
||||
*/
|
||||
upscaling_methods: (components["schemas"]["Upscaler"])[];
|
||||
/**
|
||||
* Nsfw Methods
|
||||
* @description List of NSFW checking methods
|
||||
*/
|
||||
nsfw_methods: (string)[];
|
||||
/**
|
||||
* Watermarking Methods
|
||||
* @description List of invisible watermark methods
|
||||
*/
|
||||
watermarking_methods: (string)[];
|
||||
};
|
||||
/**
|
||||
* AppVersion
|
||||
@ -793,6 +827,13 @@ export type components = {
|
||||
* @enum {string}
|
||||
*/
|
||||
control_mode?: "balanced" | "more_prompt" | "more_control" | "unbalanced";
|
||||
/**
|
||||
* Resize Mode
|
||||
* @description The resize mode to use
|
||||
* @default just_resize
|
||||
* @enum {string}
|
||||
*/
|
||||
resize_mode?: "just_resize" | "crop_resize" | "fill_resize" | "just_resize_simple";
|
||||
};
|
||||
/**
|
||||
* ControlNetInvocation
|
||||
@ -852,6 +893,13 @@ export type components = {
|
||||
* @enum {string}
|
||||
*/
|
||||
control_mode?: "balanced" | "more_prompt" | "more_control" | "unbalanced";
|
||||
/**
|
||||
* Resize Mode
|
||||
* @description The resize mode used
|
||||
* @default just_resize
|
||||
* @enum {string}
|
||||
*/
|
||||
resize_mode?: "just_resize" | "crop_resize" | "fill_resize" | "just_resize_simple";
|
||||
};
|
||||
/** ControlNetModelConfig */
|
||||
ControlNetModelConfig: {
|
||||
@ -981,6 +1029,11 @@ export type components = {
|
||||
* @description The LoRAs used for inference
|
||||
*/
|
||||
loras: (components["schemas"]["LoRAMetadataField"])[];
|
||||
/**
|
||||
* Vae
|
||||
* @description The VAE used for decoding, if the main model's default was not used
|
||||
*/
|
||||
vae?: components["schemas"]["VAEModelField"];
|
||||
/**
|
||||
* Strength
|
||||
* @description The strength used for latents-to-latents
|
||||
@ -992,10 +1045,45 @@ export type components = {
|
||||
*/
|
||||
init_image?: string;
|
||||
/**
|
||||
* Vae
|
||||
* @description The VAE used for decoding, if the main model's default was not used
|
||||
* Positive Style Prompt
|
||||
* @description The positive style prompt parameter
|
||||
*/
|
||||
vae?: components["schemas"]["VAEModelField"];
|
||||
positive_style_prompt?: string;
|
||||
/**
|
||||
* Negative Style Prompt
|
||||
* @description The negative style prompt parameter
|
||||
*/
|
||||
negative_style_prompt?: string;
|
||||
/**
|
||||
* Refiner Model
|
||||
* @description The SDXL Refiner model used
|
||||
*/
|
||||
refiner_model?: components["schemas"]["MainModelField"];
|
||||
/**
|
||||
* Refiner Cfg Scale
|
||||
* @description The classifier-free guidance scale parameter used for the refiner
|
||||
*/
|
||||
refiner_cfg_scale?: number;
|
||||
/**
|
||||
* Refiner Steps
|
||||
* @description The number of steps used for the refiner
|
||||
*/
|
||||
refiner_steps?: number;
|
||||
/**
|
||||
* Refiner Scheduler
|
||||
* @description The scheduler used for the refiner
|
||||
*/
|
||||
refiner_scheduler?: string;
|
||||
/**
|
||||
* Refiner Aesthetic Store
|
||||
* @description The aesthetic score used for the refiner
|
||||
*/
|
||||
refiner_aesthetic_store?: number;
|
||||
/**
|
||||
* Refiner Start
|
||||
* @description The start value used for refiner denoising
|
||||
*/
|
||||
refiner_start?: number;
|
||||
};
|
||||
/**
|
||||
* CvInpaintInvocation
|
||||
@ -1030,6 +1118,24 @@ export type components = {
|
||||
*/
|
||||
mask?: components["schemas"]["ImageField"];
|
||||
};
|
||||
/** DeleteBoardResult */
|
||||
DeleteBoardResult: {
|
||||
/**
|
||||
* Board Id
|
||||
* @description The id of the board that was deleted.
|
||||
*/
|
||||
board_id: string;
|
||||
/**
|
||||
* Deleted Board Images
|
||||
* @description The image names of the board-images relationships that were deleted.
|
||||
*/
|
||||
deleted_board_images: (string)[];
|
||||
/**
|
||||
* Deleted Images
|
||||
* @description The names of the images that were deleted.
|
||||
*/
|
||||
deleted_images: (string)[];
|
||||
};
|
||||
/**
|
||||
* DivideInvocation
|
||||
* @description Divides two numbers
|
||||
@ -1254,11 +1360,7 @@ export type components = {
|
||||
* @description The nodes in this graph
|
||||
*/
|
||||
nodes?: {
|
||||
<<<<<<< HEAD
|
||||
[key: string]: (components["schemas"]["LoadImageInvocation"] | components["schemas"]["ShowImageInvocation"] | components["schemas"]["ImageCropInvocation"] | components["schemas"]["ImagePasteInvocation"] | components["schemas"]["MaskFromAlphaInvocation"] | components["schemas"]["ImageMultiplyInvocation"] | components["schemas"]["ImageChannelInvocation"] | components["schemas"]["ImageConvertInvocation"] | components["schemas"]["ImageBlurInvocation"] | components["schemas"]["ImageResizeInvocation"] | components["schemas"]["ImageScaleInvocation"] | components["schemas"]["ImageLerpInvocation"] | components["schemas"]["ImageInverseLerpInvocation"] | components["schemas"]["ControlNetInvocation"] | components["schemas"]["ImageProcessorInvocation"] | components["schemas"]["MainModelLoaderInvocation"] | components["schemas"]["OnnxModelLoaderInvocation"] | components["schemas"]["LoraLoaderInvocation"] | components["schemas"]["VaeLoaderInvocation"] | components["schemas"]["MetadataAccumulatorInvocation"] | components["schemas"]["DynamicPromptInvocation"] | components["schemas"]["CompelInvocation"] | components["schemas"]["ClipSkipInvocation"] | components["schemas"]["AddInvocation"] | components["schemas"]["SubtractInvocation"] | components["schemas"]["MultiplyInvocation"] | components["schemas"]["DivideInvocation"] | components["schemas"]["RandomIntInvocation"] | components["schemas"]["ParamIntInvocation"] | components["schemas"]["ParamFloatInvocation"] | components["schemas"]["TextToLatentsInvocation"] | components["schemas"]["LatentsToImageInvocation"] | components["schemas"]["ONNXLatentsToImageInvocation"] | components["schemas"]["ResizeLatentsInvocation"] | components["schemas"]["ScaleLatentsInvocation"] | components["schemas"]["ImageToLatentsInvocation"] | components["schemas"]["CvInpaintInvocation"] | components["schemas"]["RangeInvocation"] | components["schemas"]["RangeOfSizeInvocation"] | components["schemas"]["RandomRangeInvocation"] | components["schemas"]["ImageCollectionInvocation"] | components["schemas"]["FloatLinearRangeInvocation"] | components["schemas"]["StepParamEasingInvocation"] | components["schemas"]["NoiseInvocation"] | components["schemas"]["UpscaleInvocation"] | components["schemas"]["RestoreFaceInvocation"] | components["schemas"]["InpaintInvocation"] | components["schemas"]["InfillColorInvocation"] | components["schemas"]["InfillTileInvocation"] | components["schemas"]["InfillPatchMatchInvocation"] | components["schemas"]["GraphInvocation"] | components["schemas"]["IterateInvocation"] | components["schemas"]["CollectInvocation"] | components["schemas"]["CannyImageProcessorInvocation"] | components["schemas"]["HedImageProcessorInvocation"] | components["schemas"]["LineartImageProcessorInvocation"] | components["schemas"]["LineartAnimeImageProcessorInvocation"] | components["schemas"]["OpenposeImageProcessorInvocation"] | components["schemas"]["MidasDepthImageProcessorInvocation"] | components["schemas"]["NormalbaeImageProcessorInvocation"] | components["schemas"]["MlsdImageProcessorInvocation"] | components["schemas"]["PidiImageProcessorInvocation"] | components["schemas"]["ContentShuffleImageProcessorInvocation"] | components["schemas"]["ZoeDepthImageProcessorInvocation"] | components["schemas"]["MediapipeFaceProcessorInvocation"] | components["schemas"]["LeresImageProcessorInvocation"] | components["schemas"]["TileResamplerProcessorInvocation"] | components["schemas"]["SegmentAnythingProcessorInvocation"] | components["schemas"]["LatentsToLatentsInvocation"]) | undefined;
|
||||
=======
|
||||
[key: string]: (components["schemas"]["LoadImageInvocation"] | components["schemas"]["ShowImageInvocation"] | components["schemas"]["ImageCropInvocation"] | components["schemas"]["ImagePasteInvocation"] | components["schemas"]["MaskFromAlphaInvocation"] | components["schemas"]["ImageMultiplyInvocation"] | components["schemas"]["ImageChannelInvocation"] | components["schemas"]["ImageConvertInvocation"] | components["schemas"]["ImageBlurInvocation"] | components["schemas"]["ImageResizeInvocation"] | components["schemas"]["ImageScaleInvocation"] | components["schemas"]["ImageLerpInvocation"] | components["schemas"]["ImageInverseLerpInvocation"] | components["schemas"]["ControlNetInvocation"] | components["schemas"]["ImageProcessorInvocation"] | components["schemas"]["MainModelLoaderInvocation"] | components["schemas"]["LoraLoaderInvocation"] | components["schemas"]["VaeLoaderInvocation"] | components["schemas"]["MetadataAccumulatorInvocation"] | components["schemas"]["CvInpaintInvocation"] | components["schemas"]["CompelInvocation"] | components["schemas"]["SDXLCompelPromptInvocation"] | components["schemas"]["SDXLRefinerCompelPromptInvocation"] | components["schemas"]["SDXLRawPromptInvocation"] | components["schemas"]["SDXLRefinerRawPromptInvocation"] | components["schemas"]["ClipSkipInvocation"] | components["schemas"]["TextToLatentsInvocation"] | components["schemas"]["LatentsToImageInvocation"] | components["schemas"]["ResizeLatentsInvocation"] | components["schemas"]["ScaleLatentsInvocation"] | components["schemas"]["ImageToLatentsInvocation"] | components["schemas"]["InpaintInvocation"] | components["schemas"]["AddInvocation"] | components["schemas"]["SubtractInvocation"] | components["schemas"]["MultiplyInvocation"] | components["schemas"]["DivideInvocation"] | components["schemas"]["RandomIntInvocation"] | components["schemas"]["ParamIntInvocation"] | components["schemas"]["ParamFloatInvocation"] | components["schemas"]["ParamStringInvocation"] | components["schemas"]["ESRGANInvocation"] | components["schemas"]["RangeInvocation"] | components["schemas"]["RangeOfSizeInvocation"] | components["schemas"]["RandomRangeInvocation"] | components["schemas"]["ImageCollectionInvocation"] | components["schemas"]["DynamicPromptInvocation"] | components["schemas"]["PromptsFromFileInvocation"] | components["schemas"]["InfillColorInvocation"] | components["schemas"]["InfillTileInvocation"] | components["schemas"]["InfillPatchMatchInvocation"] | components["schemas"]["NoiseInvocation"] | components["schemas"]["SDXLModelLoaderInvocation"] | components["schemas"]["SDXLRefinerModelLoaderInvocation"] | components["schemas"]["SDXLTextToLatentsInvocation"] | components["schemas"]["SDXLLatentsToLatentsInvocation"] | components["schemas"]["FloatLinearRangeInvocation"] | components["schemas"]["StepParamEasingInvocation"] | components["schemas"]["GraphInvocation"] | components["schemas"]["IterateInvocation"] | components["schemas"]["CollectInvocation"] | components["schemas"]["CannyImageProcessorInvocation"] | components["schemas"]["HedImageProcessorInvocation"] | components["schemas"]["LineartImageProcessorInvocation"] | components["schemas"]["LineartAnimeImageProcessorInvocation"] | components["schemas"]["OpenposeImageProcessorInvocation"] | components["schemas"]["MidasDepthImageProcessorInvocation"] | components["schemas"]["NormalbaeImageProcessorInvocation"] | components["schemas"]["MlsdImageProcessorInvocation"] | components["schemas"]["PidiImageProcessorInvocation"] | components["schemas"]["ContentShuffleImageProcessorInvocation"] | components["schemas"]["ZoeDepthImageProcessorInvocation"] | components["schemas"]["MediapipeFaceProcessorInvocation"] | components["schemas"]["LeresImageProcessorInvocation"] | components["schemas"]["TileResamplerProcessorInvocation"] | components["schemas"]["SegmentAnythingProcessorInvocation"] | components["schemas"]["LatentsToLatentsInvocation"]) | undefined;
|
||||
>>>>>>> main
|
||||
[key: string]: (components["schemas"]["OnnxModelLoaderInvocation"] | components["schemas"]["ONNXLatentsToImageInvocation"] | components["schemas"]["ControlNetInvocation"] | components["schemas"]["ImageProcessorInvocation"] | components["schemas"]["MainModelLoaderInvocation"] | components["schemas"]["LoraLoaderInvocation"] | components["schemas"]["VaeLoaderInvocation"] | components["schemas"]["MetadataAccumulatorInvocation"] | components["schemas"]["CompelInvocation"] | components["schemas"]["SDXLCompelPromptInvocation"] | components["schemas"]["SDXLRefinerCompelPromptInvocation"] | components["schemas"]["SDXLRawPromptInvocation"] | components["schemas"]["SDXLRefinerRawPromptInvocation"] | components["schemas"]["ClipSkipInvocation"] | components["schemas"]["LoadImageInvocation"] | components["schemas"]["ShowImageInvocation"] | components["schemas"]["ImageCropInvocation"] | components["schemas"]["ImagePasteInvocation"] | components["schemas"]["MaskFromAlphaInvocation"] | components["schemas"]["ImageMultiplyInvocation"] | components["schemas"]["ImageChannelInvocation"] | components["schemas"]["ImageConvertInvocation"] | components["schemas"]["ImageBlurInvocation"] | components["schemas"]["ImageResizeInvocation"] | components["schemas"]["ImageScaleInvocation"] | components["schemas"]["ImageLerpInvocation"] | components["schemas"]["ImageInverseLerpInvocation"] | components["schemas"]["ImageNSFWBlurInvocation"] | components["schemas"]["ImageWatermarkInvocation"] | components["schemas"]["TextToLatentsInvocation"] | components["schemas"]["LatentsToImageInvocation"] | components["schemas"]["ResizeLatentsInvocation"] | components["schemas"]["ScaleLatentsInvocation"] | components["schemas"]["ImageToLatentsInvocation"] | components["schemas"]["SDXLModelLoaderInvocation"] | components["schemas"]["SDXLRefinerModelLoaderInvocation"] | components["schemas"]["SDXLTextToLatentsInvocation"] | components["schemas"]["SDXLLatentsToLatentsInvocation"] | components["schemas"]["DynamicPromptInvocation"] | components["schemas"]["PromptsFromFileInvocation"] | components["schemas"]["AddInvocation"] | components["schemas"]["SubtractInvocation"] | components["schemas"]["MultiplyInvocation"] | components["schemas"]["DivideInvocation"] | components["schemas"]["RandomIntInvocation"] | components["schemas"]["ParamIntInvocation"] | components["schemas"]["ParamFloatInvocation"] | components["schemas"]["ParamStringInvocation"] | components["schemas"]["CvInpaintInvocation"] | components["schemas"]["RangeInvocation"] | components["schemas"]["RangeOfSizeInvocation"] | components["schemas"]["RandomRangeInvocation"] | components["schemas"]["ImageCollectionInvocation"] | components["schemas"]["FloatLinearRangeInvocation"] | components["schemas"]["StepParamEasingInvocation"] | components["schemas"]["NoiseInvocation"] | components["schemas"]["ESRGANInvocation"] | components["schemas"]["InpaintInvocation"] | components["schemas"]["InfillColorInvocation"] | components["schemas"]["InfillTileInvocation"] | components["schemas"]["InfillPatchMatchInvocation"] | components["schemas"]["GraphInvocation"] | components["schemas"]["IterateInvocation"] | components["schemas"]["CollectInvocation"] | components["schemas"]["CannyImageProcessorInvocation"] | components["schemas"]["HedImageProcessorInvocation"] | components["schemas"]["LineartImageProcessorInvocation"] | components["schemas"]["LineartAnimeImageProcessorInvocation"] | components["schemas"]["OpenposeImageProcessorInvocation"] | components["schemas"]["MidasDepthImageProcessorInvocation"] | components["schemas"]["NormalbaeImageProcessorInvocation"] | components["schemas"]["MlsdImageProcessorInvocation"] | components["schemas"]["PidiImageProcessorInvocation"] | components["schemas"]["ContentShuffleImageProcessorInvocation"] | components["schemas"]["ZoeDepthImageProcessorInvocation"] | components["schemas"]["MediapipeFaceProcessorInvocation"] | components["schemas"]["LeresImageProcessorInvocation"] | components["schemas"]["TileResamplerProcessorInvocation"] | components["schemas"]["SegmentAnythingProcessorInvocation"] | components["schemas"]["LatentsToLatentsInvocation"]) | undefined;
|
||||
};
|
||||
/**
|
||||
* Edges
|
||||
@ -1301,7 +1403,7 @@ export type components = {
|
||||
* @description The results of node executions
|
||||
*/
|
||||
results: {
|
||||
[key: string]: (components["schemas"]["ImageOutput"] | components["schemas"]["MaskOutput"] | components["schemas"]["ControlOutput"] | components["schemas"]["ModelLoaderOutput"] | components["schemas"]["LoraLoaderOutput"] | components["schemas"]["VaeLoaderOutput"] | components["schemas"]["MetadataAccumulatorOutput"] | components["schemas"]["CompelOutput"] | components["schemas"]["ClipSkipInvocationOutput"] | components["schemas"]["LatentsOutput"] | components["schemas"]["IntOutput"] | components["schemas"]["FloatOutput"] | components["schemas"]["StringOutput"] | components["schemas"]["IntCollectionOutput"] | components["schemas"]["FloatCollectionOutput"] | components["schemas"]["ImageCollectionOutput"] | components["schemas"]["PromptOutput"] | components["schemas"]["PromptCollectionOutput"] | components["schemas"]["NoiseOutput"] | components["schemas"]["SDXLModelLoaderOutput"] | components["schemas"]["SDXLRefinerModelLoaderOutput"] | components["schemas"]["GraphInvocationOutput"] | components["schemas"]["IterateInvocationOutput"] | components["schemas"]["CollectInvocationOutput"]) | undefined;
|
||||
[key: string]: (components["schemas"]["ImageOutput"] | components["schemas"]["MaskOutput"] | components["schemas"]["ControlOutput"] | components["schemas"]["ModelLoaderOutput"] | components["schemas"]["LoraLoaderOutput"] | components["schemas"]["VaeLoaderOutput"] | components["schemas"]["MetadataAccumulatorOutput"] | components["schemas"]["CompelOutput"] | components["schemas"]["ClipSkipInvocationOutput"] | components["schemas"]["LatentsOutput"] | components["schemas"]["SDXLModelLoaderOutput"] | components["schemas"]["SDXLRefinerModelLoaderOutput"] | components["schemas"]["PromptOutput"] | components["schemas"]["PromptCollectionOutput"] | components["schemas"]["IntOutput"] | components["schemas"]["FloatOutput"] | components["schemas"]["StringOutput"] | components["schemas"]["IntCollectionOutput"] | components["schemas"]["FloatCollectionOutput"] | components["schemas"]["ImageCollectionOutput"] | components["schemas"]["NoiseOutput"] | components["schemas"]["GraphInvocationOutput"] | components["schemas"]["IterateInvocationOutput"] | components["schemas"]["CollectInvocationOutput"]) | undefined;
|
||||
};
|
||||
/**
|
||||
* Errors
|
||||
@ -1848,6 +1950,39 @@ export type components = {
|
||||
*/
|
||||
image2?: components["schemas"]["ImageField"];
|
||||
};
|
||||
/**
|
||||
* ImageNSFWBlurInvocation
|
||||
* @description Add blur to NSFW-flagged images
|
||||
*/
|
||||
ImageNSFWBlurInvocation: {
|
||||
/**
|
||||
* Id
|
||||
* @description The id of this node. Must be unique among all nodes.
|
||||
*/
|
||||
id: string;
|
||||
/**
|
||||
* Is Intermediate
|
||||
* @description Whether or not this node is an intermediate node.
|
||||
* @default false
|
||||
*/
|
||||
is_intermediate?: boolean;
|
||||
/**
|
||||
* Type
|
||||
* @default img_nsfw
|
||||
* @enum {string}
|
||||
*/
|
||||
type?: "img_nsfw";
|
||||
/**
|
||||
* Image
|
||||
* @description The image to check
|
||||
*/
|
||||
image?: components["schemas"]["ImageField"];
|
||||
/**
|
||||
* Metadata
|
||||
* @description Optional core metadata to be written to the image
|
||||
*/
|
||||
metadata?: components["schemas"]["CoreMetadata"];
|
||||
};
|
||||
/**
|
||||
* ImageOutput
|
||||
* @description Base class for invocations that output an image
|
||||
@ -2128,6 +2263,45 @@ export type components = {
|
||||
*/
|
||||
thumbnail_url: string;
|
||||
};
|
||||
/**
|
||||
* ImageWatermarkInvocation
|
||||
* @description Add an invisible watermark to an image
|
||||
*/
|
||||
ImageWatermarkInvocation: {
|
||||
/**
|
||||
* Id
|
||||
* @description The id of this node. Must be unique among all nodes.
|
||||
*/
|
||||
id: string;
|
||||
/**
|
||||
* Is Intermediate
|
||||
* @description Whether or not this node is an intermediate node.
|
||||
* @default false
|
||||
*/
|
||||
is_intermediate?: boolean;
|
||||
/**
|
||||
* Type
|
||||
* @default img_watermark
|
||||
* @enum {string}
|
||||
*/
|
||||
type?: "img_watermark";
|
||||
/**
|
||||
* Image
|
||||
* @description The image to check
|
||||
*/
|
||||
image?: components["schemas"]["ImageField"];
|
||||
/**
|
||||
* Text
|
||||
* @description Watermark text
|
||||
* @default InvokeAI
|
||||
*/
|
||||
text?: string;
|
||||
/**
|
||||
* Metadata
|
||||
* @description Optional core metadata to be written to the image
|
||||
*/
|
||||
metadata?: components["schemas"]["CoreMetadata"];
|
||||
};
|
||||
/**
|
||||
* InfillColorInvocation
|
||||
* @description Infills transparent areas of an image with a solid color
|
||||
@ -2557,7 +2731,7 @@ export type components = {
|
||||
vae?: components["schemas"]["VaeField"];
|
||||
/**
|
||||
* Tiled
|
||||
* @description Decode latents by overlaping tiles(less memory consumption)
|
||||
* @description Decode latents by overlapping tiles(less memory consumption)
|
||||
* @default false
|
||||
*/
|
||||
tiled?: boolean;
|
||||
@ -2875,6 +3049,12 @@ export type components = {
|
||||
*/
|
||||
image?: components["schemas"]["ImageField"];
|
||||
};
|
||||
/**
|
||||
* LogLevel
|
||||
* @description An enumeration.
|
||||
* @enum {integer}
|
||||
*/
|
||||
LogLevel: 0 | 10 | 20 | 30 | 40 | 50;
|
||||
/** LoraInfo */
|
||||
LoraInfo: {
|
||||
/**
|
||||
@ -3260,6 +3440,46 @@ export type components = {
|
||||
* @description The VAE used for decoding, if the main model's default was not used
|
||||
*/
|
||||
vae?: components["schemas"]["VAEModelField"];
|
||||
/**
|
||||
* Positive Style Prompt
|
||||
* @description The positive style prompt parameter
|
||||
*/
|
||||
positive_style_prompt?: string;
|
||||
/**
|
||||
* Negative Style Prompt
|
||||
* @description The negative style prompt parameter
|
||||
*/
|
||||
negative_style_prompt?: string;
|
||||
/**
|
||||
* Refiner Model
|
||||
* @description The SDXL Refiner model used
|
||||
*/
|
||||
refiner_model?: components["schemas"]["MainModelField"];
|
||||
/**
|
||||
* Refiner Cfg Scale
|
||||
* @description The classifier-free guidance scale parameter used for the refiner
|
||||
*/
|
||||
refiner_cfg_scale?: number;
|
||||
/**
|
||||
* Refiner Steps
|
||||
* @description The number of steps used for the refiner
|
||||
*/
|
||||
refiner_steps?: number;
|
||||
/**
|
||||
* Refiner Scheduler
|
||||
* @description The scheduler used for the refiner
|
||||
*/
|
||||
refiner_scheduler?: string;
|
||||
/**
|
||||
* Refiner Aesthetic Store
|
||||
* @description The aesthetic score used for the refiner
|
||||
*/
|
||||
refiner_aesthetic_store?: number;
|
||||
/**
|
||||
* Refiner Start
|
||||
* @description The start value used for refiner denoising
|
||||
*/
|
||||
refiner_start?: number;
|
||||
};
|
||||
/**
|
||||
* MetadataAccumulatorOutput
|
||||
@ -5221,6 +5441,19 @@ export type components = {
|
||||
*/
|
||||
loras: (components["schemas"]["LoraInfo"])[];
|
||||
};
|
||||
/** Upscaler */
|
||||
Upscaler: {
|
||||
/**
|
||||
* Upscaling Method
|
||||
* @description Name of upscaling method
|
||||
*/
|
||||
upscaling_method: string;
|
||||
/**
|
||||
* Upscaling Models
|
||||
* @description List of upscaling models for this method
|
||||
*/
|
||||
upscaling_models: (string)[];
|
||||
};
|
||||
/**
|
||||
* VAEModelField
|
||||
* @description Vae model field
|
||||
@ -5347,6 +5580,12 @@ export type components = {
|
||||
*/
|
||||
image?: components["schemas"]["ImageField"];
|
||||
};
|
||||
/**
|
||||
* StableDiffusion1ModelFormat
|
||||
* @description An enumeration.
|
||||
* @enum {string}
|
||||
*/
|
||||
StableDiffusion1ModelFormat: "checkpoint" | "diffusers";
|
||||
/**
|
||||
* StableDiffusion2ModelFormat
|
||||
* @description An enumeration.
|
||||
@ -5359,12 +5598,6 @@ export type components = {
|
||||
* @enum {string}
|
||||
*/
|
||||
StableDiffusionXLModelFormat: "checkpoint" | "diffusers";
|
||||
/**
|
||||
* StableDiffusion1ModelFormat
|
||||
* @description An enumeration.
|
||||
* @enum {string}
|
||||
*/
|
||||
StableDiffusion1ModelFormat: "checkpoint" | "diffusers";
|
||||
};
|
||||
responses: never;
|
||||
parameters: never;
|
||||
@ -5475,7 +5708,7 @@ export type operations = {
|
||||
};
|
||||
requestBody: {
|
||||
content: {
|
||||
"application/json": components["schemas"]["LoadImageInvocation"] | components["schemas"]["ShowImageInvocation"] | components["schemas"]["ImageCropInvocation"] | components["schemas"]["ImagePasteInvocation"] | components["schemas"]["MaskFromAlphaInvocation"] | components["schemas"]["ImageMultiplyInvocation"] | components["schemas"]["ImageChannelInvocation"] | components["schemas"]["ImageConvertInvocation"] | components["schemas"]["ImageBlurInvocation"] | components["schemas"]["ImageResizeInvocation"] | components["schemas"]["ImageScaleInvocation"] | components["schemas"]["ImageLerpInvocation"] | components["schemas"]["ImageInverseLerpInvocation"] | components["schemas"]["ControlNetInvocation"] | components["schemas"]["ImageProcessorInvocation"] | components["schemas"]["MainModelLoaderInvocation"] | components["schemas"]["OnnxModelLoaderInvocation"] | components["schemas"]["LoraLoaderInvocation"] | components["schemas"]["VaeLoaderInvocation"] | components["schemas"]["MetadataAccumulatorInvocation"] | components["schemas"]["CvInpaintInvocation"] | components["schemas"]["CompelInvocation"] | components["schemas"]["SDXLCompelPromptInvocation"] | components["schemas"]["SDXLRefinerCompelPromptInvocation"] | components["schemas"]["SDXLRawPromptInvocation"] | components["schemas"]["SDXLRefinerRawPromptInvocation"] | components["schemas"]["ClipSkipInvocation"] | components["schemas"]["TextToLatentsInvocation"] | components["schemas"]["LatentsToImageInvocation"] | components["schemas"]["ResizeLatentsInvocation"] | components["schemas"]["ScaleLatentsInvocation"] | components["schemas"]["ImageToLatentsInvocation"] | components["schemas"]["InpaintInvocation"] | components["schemas"]["AddInvocation"] | components["schemas"]["SubtractInvocation"] | components["schemas"]["MultiplyInvocation"] | components["schemas"]["DivideInvocation"] | components["schemas"]["RandomIntInvocation"] | components["schemas"]["ParamIntInvocation"] | components["schemas"]["ParamFloatInvocation"] | components["schemas"]["ParamStringInvocation"] | components["schemas"]["ESRGANInvocation"] | components["schemas"]["RangeInvocation"] | components["schemas"]["RangeOfSizeInvocation"] | components["schemas"]["RandomRangeInvocation"] | components["schemas"]["ImageCollectionInvocation"] | components["schemas"]["DynamicPromptInvocation"] | components["schemas"]["PromptsFromFileInvocation"] | components["schemas"]["InfillColorInvocation"] | components["schemas"]["InfillTileInvocation"] | components["schemas"]["InfillPatchMatchInvocation"] | components["schemas"]["NoiseInvocation"] | components["schemas"]["SDXLModelLoaderInvocation"] | components["schemas"]["SDXLRefinerModelLoaderInvocation"] | components["schemas"]["SDXLTextToLatentsInvocation"] | components["schemas"]["SDXLLatentsToLatentsInvocation"] | components["schemas"]["FloatLinearRangeInvocation"] | components["schemas"]["StepParamEasingInvocation"] | components["schemas"]["GraphInvocation"] | components["schemas"]["IterateInvocation"] | components["schemas"]["CollectInvocation"] | components["schemas"]["CannyImageProcessorInvocation"] | components["schemas"]["HedImageProcessorInvocation"] | components["schemas"]["LineartImageProcessorInvocation"] | components["schemas"]["LineartAnimeImageProcessorInvocation"] | components["schemas"]["OpenposeImageProcessorInvocation"] | components["schemas"]["MidasDepthImageProcessorInvocation"] | components["schemas"]["NormalbaeImageProcessorInvocation"] | components["schemas"]["MlsdImageProcessorInvocation"] | components["schemas"]["PidiImageProcessorInvocation"] | components["schemas"]["ContentShuffleImageProcessorInvocation"] | components["schemas"]["ZoeDepthImageProcessorInvocation"] | components["schemas"]["MediapipeFaceProcessorInvocation"] | components["schemas"]["LeresImageProcessorInvocation"] | components["schemas"]["TileResamplerProcessorInvocation"] | components["schemas"]["SegmentAnythingProcessorInvocation"] | components["schemas"]["LatentsToLatentsInvocation"];
|
||||
"application/json": components["schemas"]["OnnxModelLoaderInvocation"] | components["schemas"]["ONNXLatentsToImageInvocation"] | components["schemas"]["ControlNetInvocation"] | components["schemas"]["ImageProcessorInvocation"] | components["schemas"]["MainModelLoaderInvocation"] | components["schemas"]["LoraLoaderInvocation"] | components["schemas"]["VaeLoaderInvocation"] | components["schemas"]["MetadataAccumulatorInvocation"] | components["schemas"]["CompelInvocation"] | components["schemas"]["SDXLCompelPromptInvocation"] | components["schemas"]["SDXLRefinerCompelPromptInvocation"] | components["schemas"]["SDXLRawPromptInvocation"] | components["schemas"]["SDXLRefinerRawPromptInvocation"] | components["schemas"]["ClipSkipInvocation"] | components["schemas"]["LoadImageInvocation"] | components["schemas"]["ShowImageInvocation"] | components["schemas"]["ImageCropInvocation"] | components["schemas"]["ImagePasteInvocation"] | components["schemas"]["MaskFromAlphaInvocation"] | components["schemas"]["ImageMultiplyInvocation"] | components["schemas"]["ImageChannelInvocation"] | components["schemas"]["ImageConvertInvocation"] | components["schemas"]["ImageBlurInvocation"] | components["schemas"]["ImageResizeInvocation"] | components["schemas"]["ImageScaleInvocation"] | components["schemas"]["ImageLerpInvocation"] | components["schemas"]["ImageInverseLerpInvocation"] | components["schemas"]["ImageNSFWBlurInvocation"] | components["schemas"]["ImageWatermarkInvocation"] | components["schemas"]["TextToLatentsInvocation"] | components["schemas"]["LatentsToImageInvocation"] | components["schemas"]["ResizeLatentsInvocation"] | components["schemas"]["ScaleLatentsInvocation"] | components["schemas"]["ImageToLatentsInvocation"] | components["schemas"]["SDXLModelLoaderInvocation"] | components["schemas"]["SDXLRefinerModelLoaderInvocation"] | components["schemas"]["SDXLTextToLatentsInvocation"] | components["schemas"]["SDXLLatentsToLatentsInvocation"] | components["schemas"]["DynamicPromptInvocation"] | components["schemas"]["PromptsFromFileInvocation"] | components["schemas"]["AddInvocation"] | components["schemas"]["SubtractInvocation"] | components["schemas"]["MultiplyInvocation"] | components["schemas"]["DivideInvocation"] | components["schemas"]["RandomIntInvocation"] | components["schemas"]["ParamIntInvocation"] | components["schemas"]["ParamFloatInvocation"] | components["schemas"]["ParamStringInvocation"] | components["schemas"]["CvInpaintInvocation"] | components["schemas"]["RangeInvocation"] | components["schemas"]["RangeOfSizeInvocation"] | components["schemas"]["RandomRangeInvocation"] | components["schemas"]["ImageCollectionInvocation"] | components["schemas"]["FloatLinearRangeInvocation"] | components["schemas"]["StepParamEasingInvocation"] | components["schemas"]["NoiseInvocation"] | components["schemas"]["ESRGANInvocation"] | components["schemas"]["InpaintInvocation"] | components["schemas"]["InfillColorInvocation"] | components["schemas"]["InfillTileInvocation"] | components["schemas"]["InfillPatchMatchInvocation"] | components["schemas"]["GraphInvocation"] | components["schemas"]["IterateInvocation"] | components["schemas"]["CollectInvocation"] | components["schemas"]["CannyImageProcessorInvocation"] | components["schemas"]["HedImageProcessorInvocation"] | components["schemas"]["LineartImageProcessorInvocation"] | components["schemas"]["LineartAnimeImageProcessorInvocation"] | components["schemas"]["OpenposeImageProcessorInvocation"] | components["schemas"]["MidasDepthImageProcessorInvocation"] | components["schemas"]["NormalbaeImageProcessorInvocation"] | components["schemas"]["MlsdImageProcessorInvocation"] | components["schemas"]["PidiImageProcessorInvocation"] | components["schemas"]["ContentShuffleImageProcessorInvocation"] | components["schemas"]["ZoeDepthImageProcessorInvocation"] | components["schemas"]["MediapipeFaceProcessorInvocation"] | components["schemas"]["LeresImageProcessorInvocation"] | components["schemas"]["TileResamplerProcessorInvocation"] | components["schemas"]["SegmentAnythingProcessorInvocation"] | components["schemas"]["LatentsToLatentsInvocation"];
|
||||
};
|
||||
};
|
||||
responses: {
|
||||
@ -5512,7 +5745,7 @@ export type operations = {
|
||||
};
|
||||
requestBody: {
|
||||
content: {
|
||||
"application/json": components["schemas"]["LoadImageInvocation"] | components["schemas"]["ShowImageInvocation"] | components["schemas"]["ImageCropInvocation"] | components["schemas"]["ImagePasteInvocation"] | components["schemas"]["MaskFromAlphaInvocation"] | components["schemas"]["ImageMultiplyInvocation"] | components["schemas"]["ImageChannelInvocation"] | components["schemas"]["ImageConvertInvocation"] | components["schemas"]["ImageBlurInvocation"] | components["schemas"]["ImageResizeInvocation"] | components["schemas"]["ImageScaleInvocation"] | components["schemas"]["ImageLerpInvocation"] | components["schemas"]["ImageInverseLerpInvocation"] | components["schemas"]["ControlNetInvocation"] | components["schemas"]["ImageProcessorInvocation"] | components["schemas"]["MainModelLoaderInvocation"] | components["schemas"]["OnnxModelLoaderInvocation"] | components["schemas"]["LoraLoaderInvocation"] | components["schemas"]["VaeLoaderInvocation"] | components["schemas"]["MetadataAccumulatorInvocation"] | components["schemas"]["CvInpaintInvocation"] | components["schemas"]["CompelInvocation"] | components["schemas"]["SDXLCompelPromptInvocation"] | components["schemas"]["SDXLRefinerCompelPromptInvocation"] | components["schemas"]["SDXLRawPromptInvocation"] | components["schemas"]["SDXLRefinerRawPromptInvocation"] | components["schemas"]["ClipSkipInvocation"] | components["schemas"]["TextToLatentsInvocation"] | components["schemas"]["LatentsToImageInvocation"] | components["schemas"]["ResizeLatentsInvocation"] | components["schemas"]["ScaleLatentsInvocation"] | components["schemas"]["ImageToLatentsInvocation"] | components["schemas"]["InpaintInvocation"] | components["schemas"]["AddInvocation"] | components["schemas"]["SubtractInvocation"] | components["schemas"]["MultiplyInvocation"] | components["schemas"]["DivideInvocation"] | components["schemas"]["RandomIntInvocation"] | components["schemas"]["ParamIntInvocation"] | components["schemas"]["ParamFloatInvocation"] | components["schemas"]["ParamStringInvocation"] | components["schemas"]["ESRGANInvocation"] | components["schemas"]["RangeInvocation"] | components["schemas"]["RangeOfSizeInvocation"] | components["schemas"]["RandomRangeInvocation"] | components["schemas"]["ImageCollectionInvocation"] | components["schemas"]["DynamicPromptInvocation"] | components["schemas"]["PromptsFromFileInvocation"] | components["schemas"]["InfillColorInvocation"] | components["schemas"]["InfillTileInvocation"] | components["schemas"]["InfillPatchMatchInvocation"] | components["schemas"]["NoiseInvocation"] | components["schemas"]["SDXLModelLoaderInvocation"] | components["schemas"]["SDXLRefinerModelLoaderInvocation"] | components["schemas"]["SDXLTextToLatentsInvocation"] | components["schemas"]["SDXLLatentsToLatentsInvocation"] | components["schemas"]["FloatLinearRangeInvocation"] | components["schemas"]["StepParamEasingInvocation"] | components["schemas"]["GraphInvocation"] | components["schemas"]["IterateInvocation"] | components["schemas"]["CollectInvocation"] | components["schemas"]["CannyImageProcessorInvocation"] | components["schemas"]["HedImageProcessorInvocation"] | components["schemas"]["LineartImageProcessorInvocation"] | components["schemas"]["LineartAnimeImageProcessorInvocation"] | components["schemas"]["OpenposeImageProcessorInvocation"] | components["schemas"]["MidasDepthImageProcessorInvocation"] | components["schemas"]["NormalbaeImageProcessorInvocation"] | components["schemas"]["MlsdImageProcessorInvocation"] | components["schemas"]["PidiImageProcessorInvocation"] | components["schemas"]["ContentShuffleImageProcessorInvocation"] | components["schemas"]["ZoeDepthImageProcessorInvocation"] | components["schemas"]["MediapipeFaceProcessorInvocation"] | components["schemas"]["LeresImageProcessorInvocation"] | components["schemas"]["TileResamplerProcessorInvocation"] | components["schemas"]["SegmentAnythingProcessorInvocation"] | components["schemas"]["LatentsToLatentsInvocation"];
|
||||
"application/json": components["schemas"]["OnnxModelLoaderInvocation"] | components["schemas"]["ONNXLatentsToImageInvocation"] | components["schemas"]["ControlNetInvocation"] | components["schemas"]["ImageProcessorInvocation"] | components["schemas"]["MainModelLoaderInvocation"] | components["schemas"]["LoraLoaderInvocation"] | components["schemas"]["VaeLoaderInvocation"] | components["schemas"]["MetadataAccumulatorInvocation"] | components["schemas"]["CompelInvocation"] | components["schemas"]["SDXLCompelPromptInvocation"] | components["schemas"]["SDXLRefinerCompelPromptInvocation"] | components["schemas"]["SDXLRawPromptInvocation"] | components["schemas"]["SDXLRefinerRawPromptInvocation"] | components["schemas"]["ClipSkipInvocation"] | components["schemas"]["LoadImageInvocation"] | components["schemas"]["ShowImageInvocation"] | components["schemas"]["ImageCropInvocation"] | components["schemas"]["ImagePasteInvocation"] | components["schemas"]["MaskFromAlphaInvocation"] | components["schemas"]["ImageMultiplyInvocation"] | components["schemas"]["ImageChannelInvocation"] | components["schemas"]["ImageConvertInvocation"] | components["schemas"]["ImageBlurInvocation"] | components["schemas"]["ImageResizeInvocation"] | components["schemas"]["ImageScaleInvocation"] | components["schemas"]["ImageLerpInvocation"] | components["schemas"]["ImageInverseLerpInvocation"] | components["schemas"]["ImageNSFWBlurInvocation"] | components["schemas"]["ImageWatermarkInvocation"] | components["schemas"]["TextToLatentsInvocation"] | components["schemas"]["LatentsToImageInvocation"] | components["schemas"]["ResizeLatentsInvocation"] | components["schemas"]["ScaleLatentsInvocation"] | components["schemas"]["ImageToLatentsInvocation"] | components["schemas"]["SDXLModelLoaderInvocation"] | components["schemas"]["SDXLRefinerModelLoaderInvocation"] | components["schemas"]["SDXLTextToLatentsInvocation"] | components["schemas"]["SDXLLatentsToLatentsInvocation"] | components["schemas"]["DynamicPromptInvocation"] | components["schemas"]["PromptsFromFileInvocation"] | components["schemas"]["AddInvocation"] | components["schemas"]["SubtractInvocation"] | components["schemas"]["MultiplyInvocation"] | components["schemas"]["DivideInvocation"] | components["schemas"]["RandomIntInvocation"] | components["schemas"]["ParamIntInvocation"] | components["schemas"]["ParamFloatInvocation"] | components["schemas"]["ParamStringInvocation"] | components["schemas"]["CvInpaintInvocation"] | components["schemas"]["RangeInvocation"] | components["schemas"]["RangeOfSizeInvocation"] | components["schemas"]["RandomRangeInvocation"] | components["schemas"]["ImageCollectionInvocation"] | components["schemas"]["FloatLinearRangeInvocation"] | components["schemas"]["StepParamEasingInvocation"] | components["schemas"]["NoiseInvocation"] | components["schemas"]["ESRGANInvocation"] | components["schemas"]["InpaintInvocation"] | components["schemas"]["InfillColorInvocation"] | components["schemas"]["InfillTileInvocation"] | components["schemas"]["InfillPatchMatchInvocation"] | components["schemas"]["GraphInvocation"] | components["schemas"]["IterateInvocation"] | components["schemas"]["CollectInvocation"] | components["schemas"]["CannyImageProcessorInvocation"] | components["schemas"]["HedImageProcessorInvocation"] | components["schemas"]["LineartImageProcessorInvocation"] | components["schemas"]["LineartAnimeImageProcessorInvocation"] | components["schemas"]["OpenposeImageProcessorInvocation"] | components["schemas"]["MidasDepthImageProcessorInvocation"] | components["schemas"]["NormalbaeImageProcessorInvocation"] | components["schemas"]["MlsdImageProcessorInvocation"] | components["schemas"]["PidiImageProcessorInvocation"] | components["schemas"]["ContentShuffleImageProcessorInvocation"] | components["schemas"]["ZoeDepthImageProcessorInvocation"] | components["schemas"]["MediapipeFaceProcessorInvocation"] | components["schemas"]["LeresImageProcessorInvocation"] | components["schemas"]["TileResamplerProcessorInvocation"] | components["schemas"]["SegmentAnythingProcessorInvocation"] | components["schemas"]["LatentsToLatentsInvocation"];
|
||||
};
|
||||
};
|
||||
responses: {
|
||||
@ -5951,7 +6184,7 @@ export type operations = {
|
||||
/** @description synchronization successful */
|
||||
201: {
|
||||
content: {
|
||||
"application/json": unknown;
|
||||
"application/json": boolean;
|
||||
};
|
||||
};
|
||||
};
|
||||
@ -5998,13 +6231,13 @@ export type operations = {
|
||||
list_image_dtos: {
|
||||
parameters: {
|
||||
query?: {
|
||||
/** @description The origin of images to list */
|
||||
/** @description The origin of images to list. */
|
||||
image_origin?: components["schemas"]["ResourceOrigin"];
|
||||
/** @description The categories of image to include */
|
||||
/** @description The categories of image to include. */
|
||||
categories?: (components["schemas"]["ImageCategory"])[];
|
||||
/** @description Whether to list intermediate images */
|
||||
/** @description Whether to list intermediate images. */
|
||||
is_intermediate?: boolean;
|
||||
/** @description The board id to filter by */
|
||||
/** @description The board id to filter by. Use 'none' to find images without a board. */
|
||||
board_id?: string;
|
||||
/** @description The page offset */
|
||||
offset?: number;
|
||||
@ -6038,8 +6271,12 @@ export type operations = {
|
||||
image_category: components["schemas"]["ImageCategory"];
|
||||
/** @description Whether this is an intermediate image */
|
||||
is_intermediate: boolean;
|
||||
/** @description The board to add this image to, if any */
|
||||
board_id?: string;
|
||||
/** @description The session ID associated with this upload, if any */
|
||||
session_id?: string;
|
||||
/** @description Whether to crop the image */
|
||||
crop_visible?: boolean;
|
||||
};
|
||||
};
|
||||
requestBody: {
|
||||
@ -6147,6 +6384,20 @@ export type operations = {
|
||||
};
|
||||
};
|
||||
};
|
||||
/**
|
||||
* Clear Intermediates
|
||||
* @description Clears all intermediates
|
||||
*/
|
||||
clear_intermediates: {
|
||||
responses: {
|
||||
/** @description Successful Response */
|
||||
200: {
|
||||
content: {
|
||||
"application/json": unknown;
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
/**
|
||||
* Get Image Metadata
|
||||
* @description Gets an image's metadata
|
||||
@ -6356,7 +6607,7 @@ export type operations = {
|
||||
/** @description Successful Response */
|
||||
200: {
|
||||
content: {
|
||||
"application/json": unknown;
|
||||
"application/json": components["schemas"]["DeleteBoardResult"];
|
||||
};
|
||||
};
|
||||
/** @description Validation Error */
|
||||
@ -6398,6 +6649,32 @@ export type operations = {
|
||||
};
|
||||
};
|
||||
};
|
||||
/**
|
||||
* List All Board Image Names
|
||||
* @description Gets a list of images for a board
|
||||
*/
|
||||
list_all_board_image_names: {
|
||||
parameters: {
|
||||
path: {
|
||||
/** @description The id of the board */
|
||||
board_id: string;
|
||||
};
|
||||
};
|
||||
responses: {
|
||||
/** @description Successful Response */
|
||||
200: {
|
||||
content: {
|
||||
"application/json": (string)[];
|
||||
};
|
||||
};
|
||||
/** @description Validation Error */
|
||||
422: {
|
||||
content: {
|
||||
"application/json": components["schemas"]["HTTPValidationError"];
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
/**
|
||||
* Create Board Image
|
||||
* @description Creates a board_image
|
||||
@ -6448,38 +6725,6 @@ export type operations = {
|
||||
};
|
||||
};
|
||||
};
|
||||
/**
|
||||
* List Board Images
|
||||
* @description Gets a list of images for a board
|
||||
*/
|
||||
list_board_images: {
|
||||
parameters: {
|
||||
query?: {
|
||||
/** @description The page offset */
|
||||
offset?: number;
|
||||
/** @description The number of boards per page */
|
||||
limit?: number;
|
||||
};
|
||||
path: {
|
||||
/** @description The id of the board */
|
||||
board_id: string;
|
||||
};
|
||||
};
|
||||
responses: {
|
||||
/** @description Successful Response */
|
||||
200: {
|
||||
content: {
|
||||
"application/json": components["schemas"]["OffsetPaginatedResults_ImageDTO_"];
|
||||
};
|
||||
};
|
||||
/** @description Validation Error */
|
||||
422: {
|
||||
content: {
|
||||
"application/json": components["schemas"]["HTTPValidationError"];
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
/** Get Version */
|
||||
app_version: {
|
||||
responses: {
|
||||
@ -6502,4 +6747,43 @@ export type operations = {
|
||||
};
|
||||
};
|
||||
};
|
||||
/**
|
||||
* Get Log Level
|
||||
* @description Returns the log level
|
||||
*/
|
||||
get_log_level: {
|
||||
responses: {
|
||||
/** @description The operation was successful */
|
||||
200: {
|
||||
content: {
|
||||
"application/json": components["schemas"]["LogLevel"];
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
/**
|
||||
* Set Log Level
|
||||
* @description Sets the log verbosity level
|
||||
*/
|
||||
set_log_level: {
|
||||
requestBody: {
|
||||
content: {
|
||||
"application/json": components["schemas"]["LogLevel"];
|
||||
};
|
||||
};
|
||||
responses: {
|
||||
/** @description The operation was successful */
|
||||
200: {
|
||||
content: {
|
||||
"application/json": components["schemas"]["LogLevel"];
|
||||
};
|
||||
};
|
||||
/** @description Validation Error */
|
||||
422: {
|
||||
content: {
|
||||
"application/json": components["schemas"]["HTTPValidationError"];
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
@ -1,330 +0,0 @@
|
||||
import { createAppAsyncThunk } from 'app/store/storeUtils';
|
||||
import { selectFilteredImages } from 'features/gallery/store/gallerySelectors';
|
||||
import {
|
||||
ASSETS_CATEGORIES,
|
||||
IMAGE_CATEGORIES,
|
||||
} from 'features/gallery/store/gallerySlice';
|
||||
import { size } from 'lodash-es';
|
||||
import queryString from 'query-string';
|
||||
import { $client } from 'services/api/client';
|
||||
import { paths } from 'services/api/schema';
|
||||
|
||||
type GetImageUrlsArg =
|
||||
paths['/api/v1/images/{image_name}/urls']['get']['parameters']['path'];
|
||||
|
||||
type GetImageUrlsResponse =
|
||||
paths['/api/v1/images/{image_name}/urls']['get']['responses']['200']['content']['application/json'];
|
||||
|
||||
type GetImageUrlsThunkConfig = {
|
||||
rejectValue: {
|
||||
arg: GetImageUrlsArg;
|
||||
error: unknown;
|
||||
};
|
||||
};
|
||||
/**
|
||||
* Thunk to get image URLs
|
||||
*/
|
||||
export const imageUrlsReceived = createAppAsyncThunk<
|
||||
GetImageUrlsResponse,
|
||||
GetImageUrlsArg,
|
||||
GetImageUrlsThunkConfig
|
||||
>('thunkApi/imageUrlsReceived', async (arg, { rejectWithValue }) => {
|
||||
const { image_name } = arg;
|
||||
const { get } = $client.get();
|
||||
const { data, error, response } = await get(
|
||||
'/api/v1/images/{image_name}/urls',
|
||||
{
|
||||
params: {
|
||||
path: {
|
||||
image_name,
|
||||
},
|
||||
},
|
||||
}
|
||||
);
|
||||
|
||||
if (error) {
|
||||
return rejectWithValue({ arg, error });
|
||||
}
|
||||
|
||||
return data;
|
||||
});
|
||||
|
||||
type GetImageMetadataArg =
|
||||
paths['/api/v1/images/{image_name}']['get']['parameters']['path'];
|
||||
|
||||
type GetImageMetadataResponse =
|
||||
paths['/api/v1/images/{image_name}']['get']['responses']['200']['content']['application/json'];
|
||||
|
||||
type GetImageMetadataThunkConfig = {
|
||||
rejectValue: {
|
||||
arg: GetImageMetadataArg;
|
||||
error: unknown;
|
||||
};
|
||||
};
|
||||
|
||||
export const imageDTOReceived = createAppAsyncThunk<
|
||||
GetImageMetadataResponse,
|
||||
GetImageMetadataArg,
|
||||
GetImageMetadataThunkConfig
|
||||
>('thunkApi/imageMetadataReceived', async (arg, { rejectWithValue }) => {
|
||||
const { image_name } = arg;
|
||||
const { get } = $client.get();
|
||||
const { data, error, response } = await get('/api/v1/images/{image_name}', {
|
||||
params: {
|
||||
path: { image_name },
|
||||
},
|
||||
});
|
||||
|
||||
if (error) {
|
||||
return rejectWithValue({ arg, error });
|
||||
}
|
||||
|
||||
return data;
|
||||
});
|
||||
|
||||
type ControlNetAction = {
|
||||
type: 'SET_CONTROLNET_IMAGE';
|
||||
controlNetId: string;
|
||||
};
|
||||
|
||||
type InitialImageAction = {
|
||||
type: 'SET_INITIAL_IMAGE';
|
||||
};
|
||||
|
||||
type NodesAction = {
|
||||
type: 'SET_NODES_IMAGE';
|
||||
nodeId: string;
|
||||
fieldName: string;
|
||||
};
|
||||
|
||||
type CanvasInitialImageAction = {
|
||||
type: 'SET_CANVAS_INITIAL_IMAGE';
|
||||
};
|
||||
|
||||
type CanvasMergedAction = {
|
||||
type: 'TOAST_CANVAS_MERGED';
|
||||
};
|
||||
|
||||
type CanvasSavedToGalleryAction = {
|
||||
type: 'TOAST_CANVAS_SAVED_TO_GALLERY';
|
||||
};
|
||||
|
||||
type UploadedToastAction = {
|
||||
type: 'TOAST_UPLOADED';
|
||||
};
|
||||
|
||||
type AddToBatchAction = {
|
||||
type: 'ADD_TO_BATCH';
|
||||
};
|
||||
|
||||
export type PostUploadAction =
|
||||
| ControlNetAction
|
||||
| InitialImageAction
|
||||
| NodesAction
|
||||
| CanvasInitialImageAction
|
||||
| CanvasMergedAction
|
||||
| CanvasSavedToGalleryAction
|
||||
| UploadedToastAction
|
||||
| AddToBatchAction;
|
||||
|
||||
type UploadImageArg =
|
||||
paths['/api/v1/images/']['post']['parameters']['query'] & {
|
||||
file: File;
|
||||
postUploadAction?: PostUploadAction;
|
||||
};
|
||||
|
||||
type UploadImageResponse =
|
||||
paths['/api/v1/images/']['post']['responses']['201']['content']['application/json'];
|
||||
|
||||
type UploadImageThunkConfig = {
|
||||
rejectValue: {
|
||||
arg: UploadImageArg;
|
||||
error: unknown;
|
||||
};
|
||||
};
|
||||
/**
|
||||
* `ImagesService.uploadImage()` thunk
|
||||
*/
|
||||
export const imageUploaded = createAppAsyncThunk<
|
||||
UploadImageResponse,
|
||||
UploadImageArg,
|
||||
UploadImageThunkConfig
|
||||
>('thunkApi/imageUploaded', async (arg, { rejectWithValue }) => {
|
||||
const {
|
||||
postUploadAction,
|
||||
file,
|
||||
image_category,
|
||||
is_intermediate,
|
||||
session_id,
|
||||
} = arg;
|
||||
const { post } = $client.get();
|
||||
const { data, error, response } = await post('/api/v1/images/', {
|
||||
params: {
|
||||
query: {
|
||||
image_category,
|
||||
is_intermediate,
|
||||
session_id,
|
||||
},
|
||||
},
|
||||
body: { file },
|
||||
bodySerializer: (body) => {
|
||||
const formData = new FormData();
|
||||
formData.append('file', body.file);
|
||||
return formData;
|
||||
},
|
||||
});
|
||||
|
||||
if (error) {
|
||||
return rejectWithValue({ arg, error });
|
||||
}
|
||||
|
||||
return data;
|
||||
});
|
||||
|
||||
type DeleteImageArg =
|
||||
paths['/api/v1/images/{image_name}']['delete']['parameters']['path'];
|
||||
|
||||
type DeleteImageResponse =
|
||||
paths['/api/v1/images/{image_name}']['delete']['responses']['200']['content']['application/json'];
|
||||
|
||||
type DeleteImageThunkConfig = {
|
||||
rejectValue: {
|
||||
arg: DeleteImageArg;
|
||||
error: unknown;
|
||||
};
|
||||
};
|
||||
/**
|
||||
* `ImagesService.deleteImage()` thunk
|
||||
*/
|
||||
export const imageDeleted = createAppAsyncThunk<
|
||||
DeleteImageResponse,
|
||||
DeleteImageArg,
|
||||
DeleteImageThunkConfig
|
||||
>('thunkApi/imageDeleted', async (arg, { rejectWithValue }) => {
|
||||
const { image_name } = arg;
|
||||
const { del } = $client.get();
|
||||
const { data, error, response } = await del('/api/v1/images/{image_name}', {
|
||||
params: {
|
||||
path: {
|
||||
image_name,
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
if (error) {
|
||||
return rejectWithValue({ arg, error });
|
||||
}
|
||||
});
|
||||
|
||||
type UpdateImageArg =
|
||||
paths['/api/v1/images/{image_name}']['patch']['requestBody']['content']['application/json'] &
|
||||
paths['/api/v1/images/{image_name}']['patch']['parameters']['path'];
|
||||
|
||||
type UpdateImageResponse =
|
||||
paths['/api/v1/images/{image_name}']['patch']['responses']['200']['content']['application/json'];
|
||||
|
||||
type UpdateImageThunkConfig = {
|
||||
rejectValue: {
|
||||
arg: UpdateImageArg;
|
||||
error: unknown;
|
||||
};
|
||||
};
|
||||
/**
|
||||
* `ImagesService.updateImage()` thunk
|
||||
*/
|
||||
export const imageUpdated = createAppAsyncThunk<
|
||||
UpdateImageResponse,
|
||||
UpdateImageArg,
|
||||
UpdateImageThunkConfig
|
||||
>('thunkApi/imageUpdated', async (arg, { rejectWithValue }) => {
|
||||
const { image_name, image_category, is_intermediate, session_id } = arg;
|
||||
const { patch } = $client.get();
|
||||
const { data, error, response } = await patch('/api/v1/images/{image_name}', {
|
||||
params: {
|
||||
path: {
|
||||
image_name,
|
||||
},
|
||||
},
|
||||
body: {
|
||||
image_category,
|
||||
is_intermediate,
|
||||
session_id,
|
||||
},
|
||||
});
|
||||
|
||||
if (error) {
|
||||
return rejectWithValue({ arg, error });
|
||||
}
|
||||
|
||||
return data;
|
||||
});
|
||||
|
||||
export const IMAGES_PER_PAGE = 20;
|
||||
|
||||
const DEFAULT_IMAGES_LISTED_ARG = {
|
||||
limit: IMAGES_PER_PAGE,
|
||||
};
|
||||
|
||||
type ListImagesArg = NonNullable<
|
||||
paths['/api/v1/images/']['get']['parameters']['query']
|
||||
>;
|
||||
|
||||
type ListImagesResponse =
|
||||
paths['/api/v1/images/']['get']['responses']['200']['content']['application/json'];
|
||||
|
||||
type ListImagesThunkConfig = {
|
||||
rejectValue: {
|
||||
arg: ListImagesArg;
|
||||
error: unknown;
|
||||
};
|
||||
};
|
||||
/**
|
||||
* `ImagesService.listImagesWithMetadata()` thunk
|
||||
*/
|
||||
export const receivedPageOfImages = createAppAsyncThunk<
|
||||
ListImagesResponse,
|
||||
ListImagesArg,
|
||||
ListImagesThunkConfig
|
||||
>(
|
||||
'thunkApi/receivedPageOfImages',
|
||||
async (arg, { getState, rejectWithValue }) => {
|
||||
const { get } = $client.get();
|
||||
|
||||
const state = getState();
|
||||
|
||||
const images = selectFilteredImages(state);
|
||||
const categories =
|
||||
state.gallery.galleryView === 'images'
|
||||
? IMAGE_CATEGORIES
|
||||
: ASSETS_CATEGORIES;
|
||||
|
||||
let query: ListImagesArg = {};
|
||||
|
||||
if (size(arg)) {
|
||||
query = {
|
||||
...DEFAULT_IMAGES_LISTED_ARG,
|
||||
offset: images.length,
|
||||
...arg,
|
||||
};
|
||||
} else {
|
||||
query = {
|
||||
...DEFAULT_IMAGES_LISTED_ARG,
|
||||
categories,
|
||||
offset: images.length,
|
||||
};
|
||||
}
|
||||
|
||||
const { data, error, response } = await get('/api/v1/images/', {
|
||||
params: {
|
||||
query,
|
||||
},
|
||||
querySerializer: (q) => queryString.stringify(q, { arrayFormat: 'none' }),
|
||||
});
|
||||
|
||||
if (error) {
|
||||
return rejectWithValue({ arg, error });
|
||||
}
|
||||
|
||||
return data;
|
||||
}
|
||||
);
|
@ -1,7 +1,5 @@
|
||||
import { createAsyncThunk } from '@reduxjs/toolkit';
|
||||
import { log } from 'app/logging/useLogger';
|
||||
|
||||
const schemaLog = log.child({ namespace: 'schema' });
|
||||
import { logger } from 'app/logging/logger';
|
||||
|
||||
function getCircularReplacer() {
|
||||
const ancestors: Record<string, any>[] = [];
|
||||
@ -26,11 +24,12 @@ function getCircularReplacer() {
|
||||
export const receivedOpenAPISchema = createAsyncThunk(
|
||||
'nodes/receivedOpenAPISchema',
|
||||
async (_, { dispatch, rejectWithValue }) => {
|
||||
const log = logger('system');
|
||||
try {
|
||||
const response = await fetch(`openapi.json`);
|
||||
const openAPISchema = await response.json();
|
||||
|
||||
schemaLog.info({ openAPISchema }, 'Received OpenAPI schema');
|
||||
log.info({ openAPISchema }, 'Received OpenAPI schema');
|
||||
|
||||
const schemaJSON = JSON.parse(
|
||||
JSON.stringify(openAPISchema, getCircularReplacer())
|
||||
|
@ -1,13 +1,9 @@
|
||||
import { createAppAsyncThunk } from 'app/store/storeUtils';
|
||||
import { log } from 'app/logging/useLogger';
|
||||
import { createAsyncThunk, isAnyOf } from '@reduxjs/toolkit';
|
||||
import { isObject } from 'lodash-es';
|
||||
import { isAnyOf } from '@reduxjs/toolkit';
|
||||
import { paths } from 'services/api/schema';
|
||||
import { $client } from 'services/api/client';
|
||||
import { paths } from 'services/api/schema';
|
||||
import { O } from 'ts-toolbelt';
|
||||
|
||||
const sessionLog = log.child({ namespace: 'session' });
|
||||
|
||||
type CreateSessionArg = {
|
||||
graph: NonNullable<
|
||||
paths['/api/v1/sessions/']['post']['requestBody']
|
||||
@ -22,13 +18,13 @@ type CreateSessionResponse = O.Required<
|
||||
>;
|
||||
|
||||
type CreateSessionThunkConfig = {
|
||||
rejectValue: { arg: CreateSessionArg; error: unknown };
|
||||
rejectValue: { arg: CreateSessionArg; status: number; error: unknown };
|
||||
};
|
||||
|
||||
/**
|
||||
* `SessionsService.createSession()` thunk
|
||||
*/
|
||||
export const sessionCreated = createAppAsyncThunk<
|
||||
export const sessionCreated = createAsyncThunk<
|
||||
CreateSessionResponse,
|
||||
CreateSessionArg,
|
||||
CreateSessionThunkConfig
|
||||
@ -40,7 +36,7 @@ export const sessionCreated = createAppAsyncThunk<
|
||||
});
|
||||
|
||||
if (error) {
|
||||
return rejectWithValue({ arg, error });
|
||||
return rejectWithValue({ arg, status: response.status, error });
|
||||
}
|
||||
|
||||
return data;
|
||||
@ -57,6 +53,7 @@ type InvokedSessionThunkConfig = {
|
||||
rejectValue: {
|
||||
arg: InvokedSessionArg;
|
||||
error: unknown;
|
||||
status: number;
|
||||
};
|
||||
};
|
||||
|
||||
@ -66,7 +63,7 @@ const isErrorWithStatus = (error: unknown): error is { status: number } =>
|
||||
/**
|
||||
* `SessionsService.invokeSession()` thunk
|
||||
*/
|
||||
export const sessionInvoked = createAppAsyncThunk<
|
||||
export const sessionInvoked = createAsyncThunk<
|
||||
InvokedSessionResponse,
|
||||
InvokedSessionArg,
|
||||
InvokedSessionThunkConfig
|
||||
@ -82,9 +79,13 @@ export const sessionInvoked = createAppAsyncThunk<
|
||||
|
||||
if (error) {
|
||||
if (isErrorWithStatus(error) && error.status === 403) {
|
||||
return rejectWithValue({ arg, error: (error as any).body.detail });
|
||||
return rejectWithValue({
|
||||
arg,
|
||||
status: response.status,
|
||||
error: (error as any).body.detail,
|
||||
});
|
||||
}
|
||||
return rejectWithValue({ arg, error });
|
||||
return rejectWithValue({ arg, status: response.status, error });
|
||||
}
|
||||
});
|
||||
|
||||
@ -104,7 +105,7 @@ type CancelSessionThunkConfig = {
|
||||
/**
|
||||
* `SessionsService.cancelSession()` thunk
|
||||
*/
|
||||
export const sessionCanceled = createAppAsyncThunk<
|
||||
export const sessionCanceled = createAsyncThunk<
|
||||
CancelSessionResponse,
|
||||
CancelSessionArg,
|
||||
CancelSessionThunkConfig
|
||||
@ -144,7 +145,7 @@ type ListSessionsThunkConfig = {
|
||||
/**
|
||||
* `SessionsService.listSessions()` thunk
|
||||
*/
|
||||
export const listedSessions = createAppAsyncThunk<
|
||||
export const listedSessions = createAsyncThunk<
|
||||
ListSessionsResponse,
|
||||
ListSessionsArg,
|
||||
ListSessionsThunkConfig
|
||||
|
@ -1,3 +1,4 @@
|
||||
import { UseToastOptions } from '@chakra-ui/react';
|
||||
import { O } from 'ts-toolbelt';
|
||||
import { components } from './schema';
|
||||
|
||||
@ -140,6 +141,12 @@ export type ESRGANInvocation = TypeReq<
|
||||
export type DivideInvocation = TypeReq<
|
||||
components['schemas']['DivideInvocation']
|
||||
>;
|
||||
export type ImageNSFWBlurInvocation = TypeReq<
|
||||
components['schemas']['ImageNSFWBlurInvocation']
|
||||
>;
|
||||
export type ImageWatermarkInvocation = TypeReq<
|
||||
components['schemas']['ImageWatermarkInvocation']
|
||||
>;
|
||||
|
||||
// ControlNet Nodes
|
||||
export type ControlNetInvocation = TypeReq<
|
||||
@ -193,3 +200,41 @@ export type CollectInvocationOutput =
|
||||
export type LatentsOutput = components['schemas']['LatentsOutput'];
|
||||
export type GraphInvocationOutput =
|
||||
components['schemas']['GraphInvocationOutput'];
|
||||
|
||||
// Post-image upload actions, controls workflows when images are uploaded
|
||||
|
||||
export type ControlNetAction = {
|
||||
type: 'SET_CONTROLNET_IMAGE';
|
||||
controlNetId: string;
|
||||
};
|
||||
|
||||
export type InitialImageAction = {
|
||||
type: 'SET_INITIAL_IMAGE';
|
||||
};
|
||||
|
||||
export type NodesAction = {
|
||||
type: 'SET_NODES_IMAGE';
|
||||
nodeId: string;
|
||||
fieldName: string;
|
||||
};
|
||||
|
||||
export type CanvasInitialImageAction = {
|
||||
type: 'SET_CANVAS_INITIAL_IMAGE';
|
||||
};
|
||||
|
||||
export type ToastAction = {
|
||||
type: 'TOAST';
|
||||
toastOptions?: UseToastOptions;
|
||||
};
|
||||
|
||||
export type AddToBatchAction = {
|
||||
type: 'ADD_TO_BATCH';
|
||||
};
|
||||
|
||||
export type PostUploadAction =
|
||||
| ControlNetAction
|
||||
| InitialImageAction
|
||||
| NodesAction
|
||||
| CanvasInitialImageAction
|
||||
| ToastAction
|
||||
| AddToBatchAction;
|
||||
|
@ -4,16 +4,13 @@ import {
|
||||
GraphExecutionStateCompleteEvent,
|
||||
InvocationCompleteEvent,
|
||||
InvocationErrorEvent,
|
||||
InvocationRetrievalErrorEvent,
|
||||
InvocationStartedEvent,
|
||||
ModelLoadCompletedEvent,
|
||||
ModelLoadStartedEvent,
|
||||
SessionRetrievalErrorEvent,
|
||||
} from 'services/events/types';
|
||||
|
||||
// Common socket action payload data
|
||||
type BaseSocketPayload = {
|
||||
timestamp: string;
|
||||
};
|
||||
|
||||
// Create actions for each socket
|
||||
// Middleware and redux can then respond to them as needed
|
||||
|
||||
@ -22,30 +19,24 @@ type BaseSocketPayload = {
|
||||
*
|
||||
* Do not use. Only for use in middleware.
|
||||
*/
|
||||
export const socketConnected = createAction<BaseSocketPayload>(
|
||||
'socket/socketConnected'
|
||||
);
|
||||
export const socketConnected = createAction('socket/socketConnected');
|
||||
|
||||
/**
|
||||
* App-level Socket.IO Connected
|
||||
*/
|
||||
export const appSocketConnected = createAction<BaseSocketPayload>(
|
||||
'socket/appSocketConnected'
|
||||
);
|
||||
export const appSocketConnected = createAction('socket/appSocketConnected');
|
||||
|
||||
/**
|
||||
* Socket.IO Disconnect
|
||||
*
|
||||
* Do not use. Only for use in middleware.
|
||||
*/
|
||||
export const socketDisconnected = createAction<BaseSocketPayload>(
|
||||
'socket/socketDisconnected'
|
||||
);
|
||||
export const socketDisconnected = createAction('socket/socketDisconnected');
|
||||
|
||||
/**
|
||||
* App-level Socket.IO Disconnected
|
||||
*/
|
||||
export const appSocketDisconnected = createAction<BaseSocketPayload>(
|
||||
export const appSocketDisconnected = createAction(
|
||||
'socket/appSocketDisconnected'
|
||||
);
|
||||
|
||||
@ -54,145 +45,173 @@ export const appSocketDisconnected = createAction<BaseSocketPayload>(
|
||||
*
|
||||
* Do not use. Only for use in middleware.
|
||||
*/
|
||||
export const socketSubscribed = createAction<
|
||||
BaseSocketPayload & { sessionId: string; boardId: string | undefined }
|
||||
>('socket/socketSubscribed');
|
||||
export const socketSubscribed = createAction<{
|
||||
sessionId: string;
|
||||
}>('socket/socketSubscribed');
|
||||
|
||||
/**
|
||||
* App-level Socket.IO Subscribed
|
||||
*/
|
||||
export const appSocketSubscribed = createAction<
|
||||
BaseSocketPayload & { sessionId: string; boardId: string | undefined }
|
||||
>('socket/appSocketSubscribed');
|
||||
export const appSocketSubscribed = createAction<{
|
||||
sessionId: string;
|
||||
}>('socket/appSocketSubscribed');
|
||||
|
||||
/**
|
||||
* Socket.IO Unsubscribed
|
||||
*
|
||||
* Do not use. Only for use in middleware.
|
||||
*/
|
||||
export const socketUnsubscribed = createAction<
|
||||
BaseSocketPayload & { sessionId: string }
|
||||
>('socket/socketUnsubscribed');
|
||||
export const socketUnsubscribed = createAction<{ sessionId: string }>(
|
||||
'socket/socketUnsubscribed'
|
||||
);
|
||||
|
||||
/**
|
||||
* App-level Socket.IO Unsubscribed
|
||||
*/
|
||||
export const appSocketUnsubscribed = createAction<
|
||||
BaseSocketPayload & { sessionId: string }
|
||||
>('socket/appSocketUnsubscribed');
|
||||
export const appSocketUnsubscribed = createAction<{ sessionId: string }>(
|
||||
'socket/appSocketUnsubscribed'
|
||||
);
|
||||
|
||||
/**
|
||||
* Socket.IO Invocation Started
|
||||
*
|
||||
* Do not use. Only for use in middleware.
|
||||
*/
|
||||
export const socketInvocationStarted = createAction<
|
||||
BaseSocketPayload & { data: InvocationStartedEvent }
|
||||
>('socket/socketInvocationStarted');
|
||||
export const socketInvocationStarted = createAction<{
|
||||
data: InvocationStartedEvent;
|
||||
}>('socket/socketInvocationStarted');
|
||||
|
||||
/**
|
||||
* App-level Socket.IO Invocation Started
|
||||
*/
|
||||
export const appSocketInvocationStarted = createAction<
|
||||
BaseSocketPayload & { data: InvocationStartedEvent }
|
||||
>('socket/appSocketInvocationStarted');
|
||||
export const appSocketInvocationStarted = createAction<{
|
||||
data: InvocationStartedEvent;
|
||||
}>('socket/appSocketInvocationStarted');
|
||||
|
||||
/**
|
||||
* Socket.IO Invocation Complete
|
||||
*
|
||||
* Do not use. Only for use in middleware.
|
||||
*/
|
||||
export const socketInvocationComplete = createAction<
|
||||
BaseSocketPayload & {
|
||||
data: InvocationCompleteEvent;
|
||||
}
|
||||
>('socket/socketInvocationComplete');
|
||||
export const socketInvocationComplete = createAction<{
|
||||
data: InvocationCompleteEvent;
|
||||
}>('socket/socketInvocationComplete');
|
||||
|
||||
/**
|
||||
* App-level Socket.IO Invocation Complete
|
||||
*/
|
||||
export const appSocketInvocationComplete = createAction<
|
||||
BaseSocketPayload & {
|
||||
data: InvocationCompleteEvent;
|
||||
}
|
||||
>('socket/appSocketInvocationComplete');
|
||||
export const appSocketInvocationComplete = createAction<{
|
||||
data: InvocationCompleteEvent;
|
||||
}>('socket/appSocketInvocationComplete');
|
||||
|
||||
/**
|
||||
* Socket.IO Invocation Error
|
||||
*
|
||||
* Do not use. Only for use in middleware.
|
||||
*/
|
||||
export const socketInvocationError = createAction<
|
||||
BaseSocketPayload & { data: InvocationErrorEvent }
|
||||
>('socket/socketInvocationError');
|
||||
export const socketInvocationError = createAction<{
|
||||
data: InvocationErrorEvent;
|
||||
}>('socket/socketInvocationError');
|
||||
|
||||
/**
|
||||
* App-level Socket.IO Invocation Error
|
||||
*/
|
||||
export const appSocketInvocationError = createAction<
|
||||
BaseSocketPayload & { data: InvocationErrorEvent }
|
||||
>('socket/appSocketInvocationError');
|
||||
export const appSocketInvocationError = createAction<{
|
||||
data: InvocationErrorEvent;
|
||||
}>('socket/appSocketInvocationError');
|
||||
|
||||
/**
|
||||
* Socket.IO Graph Execution State Complete
|
||||
*
|
||||
* Do not use. Only for use in middleware.
|
||||
*/
|
||||
export const socketGraphExecutionStateComplete = createAction<
|
||||
BaseSocketPayload & { data: GraphExecutionStateCompleteEvent }
|
||||
>('socket/socketGraphExecutionStateComplete');
|
||||
export const socketGraphExecutionStateComplete = createAction<{
|
||||
data: GraphExecutionStateCompleteEvent;
|
||||
}>('socket/socketGraphExecutionStateComplete');
|
||||
|
||||
/**
|
||||
* App-level Socket.IO Graph Execution State Complete
|
||||
*/
|
||||
export const appSocketGraphExecutionStateComplete = createAction<
|
||||
BaseSocketPayload & { data: GraphExecutionStateCompleteEvent }
|
||||
>('socket/appSocketGraphExecutionStateComplete');
|
||||
export const appSocketGraphExecutionStateComplete = createAction<{
|
||||
data: GraphExecutionStateCompleteEvent;
|
||||
}>('socket/appSocketGraphExecutionStateComplete');
|
||||
|
||||
/**
|
||||
* Socket.IO Generator Progress
|
||||
*
|
||||
* Do not use. Only for use in middleware.
|
||||
*/
|
||||
export const socketGeneratorProgress = createAction<
|
||||
BaseSocketPayload & { data: GeneratorProgressEvent }
|
||||
>('socket/socketGeneratorProgress');
|
||||
export const socketGeneratorProgress = createAction<{
|
||||
data: GeneratorProgressEvent;
|
||||
}>('socket/socketGeneratorProgress');
|
||||
|
||||
/**
|
||||
* App-level Socket.IO Generator Progress
|
||||
*/
|
||||
export const appSocketGeneratorProgress = createAction<
|
||||
BaseSocketPayload & { data: GeneratorProgressEvent }
|
||||
>('socket/appSocketGeneratorProgress');
|
||||
export const appSocketGeneratorProgress = createAction<{
|
||||
data: GeneratorProgressEvent;
|
||||
}>('socket/appSocketGeneratorProgress');
|
||||
|
||||
/**
|
||||
* Socket.IO Model Load Started
|
||||
*
|
||||
* Do not use. Only for use in middleware.
|
||||
*/
|
||||
export const socketModelLoadStarted = createAction<
|
||||
BaseSocketPayload & { data: ModelLoadStartedEvent }
|
||||
>('socket/socketModelLoadStarted');
|
||||
export const socketModelLoadStarted = createAction<{
|
||||
data: ModelLoadStartedEvent;
|
||||
}>('socket/socketModelLoadStarted');
|
||||
|
||||
/**
|
||||
* App-level Model Load Started
|
||||
*/
|
||||
export const appSocketModelLoadStarted = createAction<
|
||||
BaseSocketPayload & { data: ModelLoadStartedEvent }
|
||||
>('socket/appSocketModelLoadStarted');
|
||||
export const appSocketModelLoadStarted = createAction<{
|
||||
data: ModelLoadStartedEvent;
|
||||
}>('socket/appSocketModelLoadStarted');
|
||||
|
||||
/**
|
||||
* Socket.IO Model Load Started
|
||||
*
|
||||
* Do not use. Only for use in middleware.
|
||||
*/
|
||||
export const socketModelLoadCompleted = createAction<
|
||||
BaseSocketPayload & { data: ModelLoadCompletedEvent }
|
||||
>('socket/socketModelLoadCompleted');
|
||||
export const socketModelLoadCompleted = createAction<{
|
||||
data: ModelLoadCompletedEvent;
|
||||
}>('socket/socketModelLoadCompleted');
|
||||
|
||||
/**
|
||||
* App-level Model Load Completed
|
||||
*/
|
||||
export const appSocketModelLoadCompleted = createAction<
|
||||
BaseSocketPayload & { data: ModelLoadCompletedEvent }
|
||||
>('socket/appSocketModelLoadCompleted');
|
||||
export const appSocketModelLoadCompleted = createAction<{
|
||||
data: ModelLoadCompletedEvent;
|
||||
}>('socket/appSocketModelLoadCompleted');
|
||||
|
||||
/**
|
||||
* Socket.IO Session Retrieval Error
|
||||
*
|
||||
* Do not use. Only for use in middleware.
|
||||
*/
|
||||
export const socketSessionRetrievalError = createAction<{
|
||||
data: SessionRetrievalErrorEvent;
|
||||
}>('socket/socketSessionRetrievalError');
|
||||
|
||||
/**
|
||||
* App-level Session Retrieval Error
|
||||
*/
|
||||
export const appSocketSessionRetrievalError = createAction<{
|
||||
data: SessionRetrievalErrorEvent;
|
||||
}>('socket/appSocketSessionRetrievalError');
|
||||
|
||||
/**
|
||||
* Socket.IO Invocation Retrieval Error
|
||||
*
|
||||
* Do not use. Only for use in middleware.
|
||||
*/
|
||||
export const socketInvocationRetrievalError = createAction<{
|
||||
data: InvocationRetrievalErrorEvent;
|
||||
}>('socket/socketInvocationRetrievalError');
|
||||
|
||||
/**
|
||||
* App-level Invocation Retrieval Error
|
||||
*/
|
||||
export const appSocketInvocationRetrievalError = createAction<{
|
||||
data: InvocationRetrievalErrorEvent;
|
||||
}>('socket/appSocketInvocationRetrievalError');
|
||||
|
@ -1,20 +1,14 @@
|
||||
import { Middleware, MiddlewareAPI } from '@reduxjs/toolkit';
|
||||
import { Socket, io } from 'socket.io-client';
|
||||
|
||||
import { AppThunkDispatch, RootState } from 'app/store/store';
|
||||
import { getTimestamp } from 'common/util/getTimestamp';
|
||||
import { $authToken, $baseUrl } from 'services/api/client';
|
||||
import { sessionCreated } from 'services/api/thunks/session';
|
||||
import {
|
||||
ClientToServerEvents,
|
||||
ServerToClientEvents,
|
||||
} from 'services/events/types';
|
||||
import { socketSubscribed, socketUnsubscribed } from './actions';
|
||||
// import { OpenAPI } from 'services/api/types';
|
||||
import { log } from 'app/logging/useLogger';
|
||||
import { $authToken, $baseUrl } from 'services/api/client';
|
||||
import { setEventListeners } from 'services/events/util/setEventListeners';
|
||||
|
||||
const socketioLog = log.child({ namespace: 'socketio' });
|
||||
import { Socket, io } from 'socket.io-client';
|
||||
import { socketSubscribed, socketUnsubscribed } from './actions';
|
||||
|
||||
export const socketMiddleware = () => {
|
||||
let areListenersSet = false;
|
||||
@ -58,7 +52,7 @@ export const socketMiddleware = () => {
|
||||
// Set listeners for `connect` and `disconnect` events once
|
||||
// Must happen in middleware to get access to `dispatch`
|
||||
if (!areListenersSet) {
|
||||
setEventListeners({ storeApi, socket, log: socketioLog });
|
||||
setEventListeners({ storeApi, socket });
|
||||
|
||||
areListenersSet = true;
|
||||
|
||||
@ -77,7 +71,6 @@ export const socketMiddleware = () => {
|
||||
dispatch(
|
||||
socketUnsubscribed({
|
||||
sessionId: oldSessionId,
|
||||
timestamp: getTimestamp(),
|
||||
})
|
||||
);
|
||||
}
|
||||
@ -87,8 +80,6 @@ export const socketMiddleware = () => {
|
||||
dispatch(
|
||||
socketSubscribed({
|
||||
sessionId: sessionId,
|
||||
timestamp: getTimestamp(),
|
||||
boardId: getState().gallery.selectedBoardId,
|
||||
})
|
||||
);
|
||||
}
|
||||
|
@ -87,6 +87,7 @@ export type InvocationErrorEvent = {
|
||||
graph_execution_state_id: string;
|
||||
node: BaseNode;
|
||||
source_node_id: string;
|
||||
error_type: string;
|
||||
error: string;
|
||||
};
|
||||
|
||||
@ -110,6 +111,29 @@ export type GraphExecutionStateCompleteEvent = {
|
||||
graph_execution_state_id: string;
|
||||
};
|
||||
|
||||
/**
|
||||
* A `session_retrieval_error` socket.io event.
|
||||
*
|
||||
* @example socket.on('session_retrieval_error', (data: SessionRetrievalErrorEvent) => { ... }
|
||||
*/
|
||||
export type SessionRetrievalErrorEvent = {
|
||||
graph_execution_state_id: string;
|
||||
error_type: string;
|
||||
error: string;
|
||||
};
|
||||
|
||||
/**
|
||||
* A `invocation_retrieval_error` socket.io event.
|
||||
*
|
||||
* @example socket.on('invocation_retrieval_error', (data: InvocationRetrievalErrorEvent) => { ... }
|
||||
*/
|
||||
export type InvocationRetrievalErrorEvent = {
|
||||
graph_execution_state_id: string;
|
||||
node_id: string;
|
||||
error_type: string;
|
||||
error: string;
|
||||
};
|
||||
|
||||
export type ClientEmitSubscribe = {
|
||||
session: string;
|
||||
};
|
||||
@ -128,6 +152,8 @@ export type ServerToClientEvents = {
|
||||
) => void;
|
||||
model_load_started: (payload: ModelLoadStartedEvent) => void;
|
||||
model_load_completed: (payload: ModelLoadCompletedEvent) => void;
|
||||
session_retrieval_error: (payload: SessionRetrievalErrorEvent) => void;
|
||||
invocation_retrieval_error: (payload: InvocationRetrievalErrorEvent) => void;
|
||||
};
|
||||
|
||||
export type ClientToServerEvents = {
|
||||
|
@ -1,42 +1,42 @@
|
||||
import { MiddlewareAPI } from '@reduxjs/toolkit';
|
||||
import { logger } from 'app/logging/logger';
|
||||
import { AppDispatch, RootState } from 'app/store/store';
|
||||
import { getTimestamp } from 'common/util/getTimestamp';
|
||||
import { addToast } from 'features/system/store/systemSlice';
|
||||
import { makeToast } from 'features/system/util/makeToast';
|
||||
import { Socket } from 'socket.io-client';
|
||||
import {
|
||||
socketConnected,
|
||||
socketDisconnected,
|
||||
socketGeneratorProgress,
|
||||
socketGraphExecutionStateComplete,
|
||||
socketInvocationComplete,
|
||||
socketInvocationError,
|
||||
socketInvocationRetrievalError,
|
||||
socketInvocationStarted,
|
||||
socketConnected,
|
||||
socketDisconnected,
|
||||
socketSubscribed,
|
||||
socketModelLoadStarted,
|
||||
socketModelLoadCompleted,
|
||||
socketModelLoadStarted,
|
||||
socketSessionRetrievalError,
|
||||
socketSubscribed,
|
||||
} from '../actions';
|
||||
import { ClientToServerEvents, ServerToClientEvents } from '../types';
|
||||
import { Logger } from 'roarr';
|
||||
import { JsonObject } from 'roarr/dist/types';
|
||||
import { makeToast } from '../../../app/components/Toaster';
|
||||
import { addToast } from '../../../features/system/store/systemSlice';
|
||||
|
||||
type SetEventListenersArg = {
|
||||
socket: Socket<ServerToClientEvents, ClientToServerEvents>;
|
||||
storeApi: MiddlewareAPI<AppDispatch, RootState>;
|
||||
log: Logger<JsonObject>;
|
||||
};
|
||||
|
||||
export const setEventListeners = (arg: SetEventListenersArg) => {
|
||||
const { socket, storeApi, log } = arg;
|
||||
const { socket, storeApi } = arg;
|
||||
const { dispatch, getState } = storeApi;
|
||||
|
||||
/**
|
||||
* Connect
|
||||
*/
|
||||
socket.on('connect', () => {
|
||||
const log = logger('socketio');
|
||||
log.debug('Connected');
|
||||
|
||||
dispatch(socketConnected({ timestamp: getTimestamp() }));
|
||||
dispatch(socketConnected());
|
||||
|
||||
const { sessionId } = getState().system;
|
||||
|
||||
@ -45,8 +45,6 @@ export const setEventListeners = (arg: SetEventListenersArg) => {
|
||||
dispatch(
|
||||
socketSubscribed({
|
||||
sessionId,
|
||||
timestamp: getTimestamp(),
|
||||
boardId: getState().gallery.selectedBoardId,
|
||||
})
|
||||
);
|
||||
}
|
||||
@ -54,7 +52,9 @@ export const setEventListeners = (arg: SetEventListenersArg) => {
|
||||
|
||||
socket.on('connect_error', (error) => {
|
||||
if (error && error.message) {
|
||||
const data: string | undefined = (error as any).data;
|
||||
const data: string | undefined = (
|
||||
error as unknown as { data: string | undefined }
|
||||
).data;
|
||||
if (data === 'ERR_UNAUTHENTICATED') {
|
||||
dispatch(
|
||||
addToast(
|
||||
@ -73,28 +73,28 @@ export const setEventListeners = (arg: SetEventListenersArg) => {
|
||||
* Disconnect
|
||||
*/
|
||||
socket.on('disconnect', () => {
|
||||
dispatch(socketDisconnected({ timestamp: getTimestamp() }));
|
||||
dispatch(socketDisconnected());
|
||||
});
|
||||
|
||||
/**
|
||||
* Invocation started
|
||||
*/
|
||||
socket.on('invocation_started', (data) => {
|
||||
dispatch(socketInvocationStarted({ data, timestamp: getTimestamp() }));
|
||||
dispatch(socketInvocationStarted({ data }));
|
||||
});
|
||||
|
||||
/**
|
||||
* Generator progress
|
||||
*/
|
||||
socket.on('generator_progress', (data) => {
|
||||
dispatch(socketGeneratorProgress({ data, timestamp: getTimestamp() }));
|
||||
dispatch(socketGeneratorProgress({ data }));
|
||||
});
|
||||
|
||||
/**
|
||||
* Invocation error
|
||||
*/
|
||||
socket.on('invocation_error', (data) => {
|
||||
dispatch(socketInvocationError({ data, timestamp: getTimestamp() }));
|
||||
dispatch(socketInvocationError({ data }));
|
||||
});
|
||||
|
||||
/**
|
||||
@ -104,7 +104,6 @@ export const setEventListeners = (arg: SetEventListenersArg) => {
|
||||
dispatch(
|
||||
socketInvocationComplete({
|
||||
data,
|
||||
timestamp: getTimestamp(),
|
||||
})
|
||||
);
|
||||
});
|
||||
@ -116,7 +115,6 @@ export const setEventListeners = (arg: SetEventListenersArg) => {
|
||||
dispatch(
|
||||
socketGraphExecutionStateComplete({
|
||||
data,
|
||||
timestamp: getTimestamp(),
|
||||
})
|
||||
);
|
||||
});
|
||||
@ -128,7 +126,6 @@ export const setEventListeners = (arg: SetEventListenersArg) => {
|
||||
dispatch(
|
||||
socketModelLoadStarted({
|
||||
data,
|
||||
timestamp: getTimestamp(),
|
||||
})
|
||||
);
|
||||
});
|
||||
@ -140,7 +137,28 @@ export const setEventListeners = (arg: SetEventListenersArg) => {
|
||||
dispatch(
|
||||
socketModelLoadCompleted({
|
||||
data,
|
||||
timestamp: getTimestamp(),
|
||||
})
|
||||
);
|
||||
});
|
||||
|
||||
/**
|
||||
* Session retrieval error
|
||||
*/
|
||||
socket.on('session_retrieval_error', (data) => {
|
||||
dispatch(
|
||||
socketSessionRetrievalError({
|
||||
data,
|
||||
})
|
||||
);
|
||||
});
|
||||
|
||||
/**
|
||||
* Invocation retrieval error
|
||||
*/
|
||||
socket.on('invocation_retrieval_error', (data) => {
|
||||
dispatch(
|
||||
socketInvocationRetrievalError({
|
||||
data,
|
||||
})
|
||||
);
|
||||
});
|
||||
|
Reference in New Issue
Block a user