Split out slow pathParameters extension and skip unnecessary model updates

This commit is contained in:
Gregory Schier
2025-01-01 16:42:53 -08:00
parent add39bda6e
commit 42cd4a5f0f
10 changed files with 253 additions and 177 deletions

View File

@@ -1,3 +1,4 @@
import deepEqual from '@gilbarbara/deep-equal';
import { useQueryClient } from '@tanstack/react-query';
import { getCurrentWebviewWindow } from '@tauri-apps/api/webviewWindow';
import type { AnyModel, KeyValue } from '@yaakapp-internal/models';
@@ -121,7 +122,11 @@ export function updateModelList<T extends AnyModel>(model: T) {
return (current: T[] | undefined): T[] => {
const index = current?.findIndex((v) => modelsEq(v, model)) ?? -1;
if (index >= 0) {
const existingModel = current?.[index];
if (existingModel && deepEqual(existingModel, model)) {
// We already have the exact model, so do nothing
return current;
} else if (existingModel) {
return [...(current ?? []).slice(0, index), model, ...(current ?? []).slice(index + 1)];
} else {
return pushToFront ? [model, ...(current ?? [])] : [...(current ?? []), model];
@@ -130,12 +135,21 @@ export function updateModelList<T extends AnyModel>(model: T) {
}
export function removeModelById<T extends { id: string }>(model: T) {
return (entries: T[] | undefined) => entries?.filter((e) => e.id !== model.id) ?? [];
return (prevEntries: T[] | undefined) => {
const entries = prevEntries?.filter((e) => e.id !== model.id) ?? [];
// Don't trigger an update if we didn't actually remove anything
if (entries.length === (prevEntries ?? []).length) {
return prevEntries ?? [];
}
return entries;
};
}
export function removeModelByKeyValue(model: KeyValue) {
return (entries: KeyValue[] | undefined) =>
entries?.filter(
return (prevEntries: KeyValue[] | undefined) =>
prevEntries?.filter(
(e) =>
!(
e.namespace === model.namespace &&

View File

@@ -2,12 +2,41 @@ import { useQuery } from '@tanstack/react-query';
import type { GetTemplateFunctionsResponse, TemplateFunction } from '@yaakapp-internal/plugin';
import { atom, useAtomValue } from 'jotai';
import { useSetAtom } from 'jotai/index';
import { useState } from 'react';
import { useMemo, useState } from 'react';
import type {TwigCompletionOption} from "../components/core/Editor/twig/completion";
import { invokeCmd } from '../lib/tauri';
import { usePluginsKey } from './usePlugins';
const templateFunctionsAtom = atom<TemplateFunction[]>([]);
export function useTwigCompletionOptions(
onClick: (fn: TemplateFunction, ragTag: string, pos: number) => void,
) {
const templateFunctions = useTemplateFunctions();
return useMemo<TwigCompletionOption[]>(() => {
return (
templateFunctions.map((fn) => {
const NUM_ARGS = 2;
const shortArgs =
fn.args
.slice(0, NUM_ARGS)
.map((a) => a.name)
.join(', ') + (fn.args.length > NUM_ARGS ? ', …' : '');
return {
name: fn.name,
aliases: fn.aliases,
type: 'function',
description: fn.description,
args: fn.args.map((a) => ({ name: a.name })),
value: null,
label: `${fn.name}(${shortArgs})`,
onClick: (rawTag: string, startPos: number) => onClick(fn, rawTag, startPos),
};
}) ?? []
);
}, [onClick, templateFunctions]);
}
export function useTemplateFunctions() {
return useAtomValue(templateFunctionsAtom);
}