feat(ui): api layer refactor

*migrate from `openapi-typescript-codegen` to `openapi-typescript` and `openapi-fetch`*

`openapi-typescript-codegen` is not very actively maintained - it's been over a year since the last update.
`openapi-typescript` and `openapi-fetch` are part of the actively maintained repo. key differences:

- provides a `fetch` client instead of `axios`, which means we need to be a bit more verbose with typing thunks
- fetch client is created at runtime and has a very nice typescript DX
- generates a single file with all types in it, from which we then extract individual types. i don't like how verbose this is, but i do like how it is more explicit.
- removed npm api generation scripts - now we have a single `typegen` script

overall i have more confidence in this new library.

*use nanostores for api base and token*

very simple reactive store for api base url and token. this was suggested in the `openapi-fetch` docs and i quite like the strategy.

*organise rtk-query api*

split out each endpoint (models, images, boards, boardImages) into their own api extensions. tidy!
This commit is contained in:
psychedelicious
2023-06-23 19:14:13 +10:00
parent 8137a99981
commit e386b5dc53
267 changed files with 6257 additions and 7008 deletions

View File

@ -8,10 +8,11 @@ import {
import { socketSubscribed, socketUnsubscribed } from './actions';
import { AppThunkDispatch, RootState } from 'app/store/store';
import { getTimestamp } from 'common/util/getTimestamp';
import { sessionCreated } from 'services/thunks/session';
import { OpenAPI } from 'services/api';
import { sessionCreated } from 'services/api/thunks/session';
// import { OpenAPI } from 'services/api/types';
import { setEventListeners } from 'services/events/util/setEventListeners';
import { log } from 'app/logging/useLogger';
import { $authToken, $baseUrl } from 'services/api/client';
const socketioLog = log.child({ namespace: 'socketio' });
@ -28,14 +29,16 @@ export const socketMiddleware = () => {
// if building in package mode, replace socket url with open api base url minus the http protocol
if (['nodes', 'package'].includes(import.meta.env.MODE)) {
if (OpenAPI.BASE) {
const baseUrl = $baseUrl.get();
if (baseUrl) {
//eslint-disable-next-line
socketUrl = OpenAPI.BASE.replace(/^https?\:\/\//i, '');
socketUrl = baseUrl.replace(/^https?\:\/\//i, '');
}
if (OpenAPI.TOKEN) {
const authToken = $authToken.get();
if (authToken) {
// TODO: handle providing jwt to socket.io
socketOptions.auth = { token: OpenAPI.TOKEN };
socketOptions.auth = { token: authToken };
}
socketOptions.transports = ['websocket', 'polling'];

View File

@ -1,4 +1,5 @@
import { Graph, GraphExecutionState, InvokeAIMetadata } from '../api';
import { O } from 'ts-toolbelt';
import { Graph, GraphExecutionState } from '../api/types';
/**
* A progress image, we get one for each step in the generation
@ -9,18 +10,19 @@ export type ProgressImage = {
height: number;
};
export type AnyInvocationType = NonNullable<
NonNullable<Graph['nodes']>[string]['type']
>;
export type AnyInvocationType = O.Required<
NonNullable<NonNullable<Graph['nodes']>[string]>,
'type'
>['type'];
export type AnyInvocation = NonNullable<Graph['nodes']>[string];
export type AnyInvocation = NonNullable<NonNullable<Graph['nodes']>[string]>;
export type AnyResult = GraphExecutionState['results'][string];
export type AnyResult = NonNullable<GraphExecutionState['results'][string]>;
export type BaseNode = {
id: string;
type: string;
[key: string]: NonNullable<InvokeAIMetadata['node']>[string];
[key: string]: AnyInvocation[keyof AnyInvocation];
};
/**