Merge main into proxy branch (formatting and docs)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Gregory Schier
2026-03-13 12:09:59 -07:00
parent 3c4035097a
commit 7314aedc71
712 changed files with 13408 additions and 13322 deletions
+35 -31
View File
@@ -1,35 +1,39 @@
import { atom } from 'jotai';
import { atom } from "jotai";
import { selectAtom } from 'jotai/utils';
import type { AnyModel } from '../bindings/gen_models';
import { ExtractModel } from './types';
import { newStoreData } from './util';
import { selectAtom } from "jotai/utils";
import type { AnyModel } from "../bindings/gen_models";
import { ExtractModel } from "./types";
import { newStoreData } from "./util";
export const modelStoreDataAtom = atom(newStoreData());
export const cookieJarsAtom = createOrderedModelAtom('cookie_jar', 'name', 'asc');
export const environmentsAtom = createOrderedModelAtom('environment', 'sortPriority', 'asc');
export const foldersAtom = createModelAtom('folder');
export const grpcConnectionsAtom = createOrderedModelAtom('grpc_connection', 'createdAt', 'desc');
export const grpcEventsAtom = createOrderedModelAtom('grpc_event', 'createdAt', 'asc');
export const grpcRequestsAtom = createModelAtom('grpc_request');
export const httpRequestsAtom = createModelAtom('http_request');
export const httpResponsesAtom = createOrderedModelAtom('http_response', 'createdAt', 'desc');
export const httpResponseEventsAtom = createOrderedModelAtom('http_response_event', 'createdAt', 'asc');
export const keyValuesAtom = createModelAtom('key_value');
export const pluginsAtom = createModelAtom('plugin');
export const settingsAtom = createSingularModelAtom('settings');
export const websocketRequestsAtom = createModelAtom('websocket_request');
export const websocketEventsAtom = createOrderedModelAtom('websocket_event', 'createdAt', 'asc');
export const websocketConnectionsAtom = createOrderedModelAtom(
'websocket_connection',
'createdAt',
'desc',
export const cookieJarsAtom = createOrderedModelAtom("cookie_jar", "name", "asc");
export const environmentsAtom = createOrderedModelAtom("environment", "sortPriority", "asc");
export const foldersAtom = createModelAtom("folder");
export const grpcConnectionsAtom = createOrderedModelAtom("grpc_connection", "createdAt", "desc");
export const grpcEventsAtom = createOrderedModelAtom("grpc_event", "createdAt", "asc");
export const grpcRequestsAtom = createModelAtom("grpc_request");
export const httpRequestsAtom = createModelAtom("http_request");
export const httpResponsesAtom = createOrderedModelAtom("http_response", "createdAt", "desc");
export const httpResponseEventsAtom = createOrderedModelAtom(
"http_response_event",
"createdAt",
"asc",
);
export const workspaceMetasAtom = createModelAtom('workspace_meta');
export const workspacesAtom = createOrderedModelAtom('workspace', 'name', 'asc');
export const keyValuesAtom = createModelAtom("key_value");
export const pluginsAtom = createModelAtom("plugin");
export const settingsAtom = createSingularModelAtom("settings");
export const websocketRequestsAtom = createModelAtom("websocket_request");
export const websocketEventsAtom = createOrderedModelAtom("websocket_event", "createdAt", "asc");
export const websocketConnectionsAtom = createOrderedModelAtom(
"websocket_connection",
"createdAt",
"desc",
);
export const workspaceMetasAtom = createModelAtom("workspace_meta");
export const workspacesAtom = createOrderedModelAtom("workspace", "name", "asc");
export function createModelAtom<M extends AnyModel['model']>(modelType: M) {
export function createModelAtom<M extends AnyModel["model"]>(modelType: M) {
return selectAtom(
modelStoreDataAtom,
(data) => Object.values(data[modelType] ?? {}),
@@ -37,19 +41,19 @@ export function createModelAtom<M extends AnyModel['model']>(modelType: M) {
);
}
export function createSingularModelAtom<M extends AnyModel['model']>(modelType: M) {
export function createSingularModelAtom<M extends AnyModel["model"]>(modelType: M) {
return selectAtom(modelStoreDataAtom, (data) => {
const modelData = Object.values(data[modelType] ?? {});
const item = modelData[0];
if (item == null) throw new Error('Failed creating singular model with no data: ' + modelType);
if (item == null) throw new Error("Failed creating singular model with no data: " + modelType);
return item;
});
}
export function createOrderedModelAtom<M extends AnyModel['model']>(
export function createOrderedModelAtom<M extends AnyModel["model"]>(
modelType: M,
field: keyof ExtractModel<AnyModel, M>,
order: 'asc' | 'desc',
order: "asc" | "desc",
) {
return selectAtom(
modelStoreDataAtom,
@@ -58,7 +62,7 @@ export function createOrderedModelAtom<M extends AnyModel['model']>(
return Object.values(modelData).sort(
(a: ExtractModel<AnyModel, M>, b: ExtractModel<AnyModel, M>) => {
const n = a[field] > b[field] ? 1 : -1;
return order === 'desc' ? n * -1 : n;
return order === "desc" ? n * -1 : n;
},
);
},
+6 -6
View File
@@ -1,11 +1,11 @@
import { AnyModel } from '../bindings/gen_models';
import { AnyModel } from "../bindings/gen_models";
export * from '../bindings/gen_models';
export * from '../bindings/gen_util';
export * from './store';
export * from './atoms';
export * from "../bindings/gen_models";
export * from "../bindings/gen_util";
export * from "./store";
export * from "./atoms";
export function modelTypeLabel(m: AnyModel): string {
const capitalize = (str: string) => str.charAt(0).toUpperCase() + str.slice(1);
return m.model.split('_').map(capitalize).join(' ');
return m.model.split("_").map(capitalize).join(" ");
}
+35 -47
View File
@@ -62,25 +62,20 @@ export async function changeModelStoreWorkspace(workspaceId: string | null) {
_activeWorkspaceId = workspaceId;
}
export function listModels<
M extends AnyModel["model"],
T extends ExtractModel<AnyModel, M>,
>(modelType: M | ReadonlyArray<M>): T[] {
export function listModels<M extends AnyModel["model"], T extends ExtractModel<AnyModel, M>>(
modelType: M | ReadonlyArray<M>,
): T[] {
let data = mustStore().get(modelStoreDataAtom);
const types: ReadonlyArray<M> = Array.isArray(modelType)
? modelType
: [modelType];
const types: ReadonlyArray<M> = Array.isArray(modelType) ? modelType : [modelType];
return types.flatMap((t) => Object.values(data[t]) as T[]);
}
export function getModel<
M extends AnyModel["model"],
T extends ExtractModel<AnyModel, M>,
>(modelType: M | ReadonlyArray<M>, id: string): T | null {
export function getModel<M extends AnyModel["model"], T extends ExtractModel<AnyModel, M>>(
modelType: M | ReadonlyArray<M>,
id: string,
): T | null {
let data = mustStore().get(modelStoreDataAtom);
const types: ReadonlyArray<M> = Array.isArray(modelType)
? modelType
: [modelType];
const types: ReadonlyArray<M> = Array.isArray(modelType) ? modelType : [modelType];
for (const t of types) {
let v = data[t][id];
if (v?.model === t) return v as T;
@@ -97,31 +92,30 @@ export function getAnyModel(id: string): AnyModel | null {
return null;
}
export function patchModelById<
M extends AnyModel["model"],
T extends ExtractModel<AnyModel, M>,
>(model: M, id: string, patch: Partial<T> | ((prev: T) => T)): Promise<string> {
export function patchModelById<M extends AnyModel["model"], T extends ExtractModel<AnyModel, M>>(
model: M,
id: string,
patch: Partial<T> | ((prev: T) => T),
): Promise<string> {
let prev = getModel<M, T>(model, id);
if (prev == null) {
throw new Error(`Failed to get model to patch id=${id} model=${model}`);
}
const newModel =
typeof patch === "function" ? patch(prev) : { ...prev, ...patch };
const newModel = typeof patch === "function" ? patch(prev) : { ...prev, ...patch };
return updateModel(newModel);
}
export async function patchModel<
M extends AnyModel["model"],
T extends ExtractModel<AnyModel, M>,
>(base: Pick<T, "id" | "model">, patch: Partial<T>): Promise<string> {
export async function patchModel<M extends AnyModel["model"], T extends ExtractModel<AnyModel, M>>(
base: Pick<T, "id" | "model">,
patch: Partial<T>,
): Promise<string> {
return patchModelById<M, T>(base.model, base.id, patch);
}
export async function updateModel<
M extends AnyModel["model"],
T extends ExtractModel<AnyModel, M>,
>(model: T): Promise<string> {
export async function updateModel<M extends AnyModel["model"], T extends ExtractModel<AnyModel, M>>(
model: T,
): Promise<string> {
return invoke<string>("models_upsert", { model });
}
@@ -133,20 +127,18 @@ export async function deleteModelById<
await deleteModel(model);
}
export async function deleteModel<
M extends AnyModel["model"],
T extends ExtractModel<AnyModel, M>,
>(model: T | null) {
export async function deleteModel<M extends AnyModel["model"], T extends ExtractModel<AnyModel, M>>(
model: T | null,
) {
if (model == null) {
throw new Error("Failed to delete null model");
}
await invoke<string>("models_delete", { model });
}
export function duplicateModel<
M extends AnyModel["model"],
T extends ExtractModel<AnyModel, M>,
>(model: T | null) {
export function duplicateModel<M extends AnyModel["model"], T extends ExtractModel<AnyModel, M>>(
model: T | null,
) {
if (model == null) {
throw new Error("Failed to duplicate null model");
}
@@ -157,11 +149,7 @@ export function duplicateModel<
const existingModels = listModels(model.model);
for (let i = 0; i < 100; i++) {
const hasConflict = existingModels.some((m) => {
if (
"folderId" in m &&
"folderId" in model &&
model.folderId !== m.folderId
) {
if ("folderId" in m && "folderId" in model && model.folderId !== m.folderId) {
return false;
} else if (resolvedModelName(m) !== name) {
return false;
@@ -187,15 +175,15 @@ export function duplicateModel<
return invoke<string>("models_duplicate", { model: { ...model, name } });
}
export async function createGlobalModel<
T extends Exclude<AnyModel, { workspaceId: string }>,
>(patch: Partial<T> & Pick<T, "model">): Promise<string> {
export async function createGlobalModel<T extends Exclude<AnyModel, { workspaceId: string }>>(
patch: Partial<T> & Pick<T, "model">,
): Promise<string> {
return invoke<string>("models_upsert", { model: patch });
}
export async function createWorkspaceModel<
T extends Extract<AnyModel, { workspaceId: string }>,
>(patch: Partial<T> & Pick<T, "model" | "workspaceId">): Promise<string> {
export async function createWorkspaceModel<T extends Extract<AnyModel, { workspaceId: string }>>(
patch: Partial<T> & Pick<T, "model" | "workspaceId">,
): Promise<string> {
return invoke<string>("models_upsert", { model: patch });
}
+3 -3
View File
@@ -1,8 +1,8 @@
import { createStore } from 'jotai';
import { AnyModel } from '../bindings/gen_models';
import { createStore } from "jotai";
import { AnyModel } from "../bindings/gen_models";
export type ExtractModel<T, M> = T extends { model: M } ? T : never;
export type ModelStoreData<T extends AnyModel = AnyModel> = {
[M in T['model']]: Record<string, Extract<T, { model: M }>>;
[M in T["model"]]: Record<string, Extract<T, { model: M }>>;
};
export type JotaiStore = ReturnType<typeof createStore>;
+1 -1
View File
@@ -1,4 +1,4 @@
import { ModelStoreData } from './types';
import { ModelStoreData } from "./types";
export function newStoreData(): ModelStoreData {
return {