feat: update router-studio configuration and dependencies

- Changed TO_REPO from template/next-simple-template to template/router-studio in .cnb.yml.
- Updated transpilePackages in next.config.ts to only include @kevisual/api.
- Bumped version to 0.1.4 in package.json and updated deployment script.
- Updated dependencies in package.json:
  - @kevisual/api from ^0.0.20 to ^0.0.44
  - @kevisual/query from ^0.0.37 to ^0.0.39
  - @kevisual/router from ^0.0.60 to ^0.0.69
  - antd from ^6.2.1 to ^6.2.3
  - lucide-react from ^0.562.0 to ^0.563.0
  - next from 16.1.4 to 16.1.6
  - react and react-dom from 19.2.3 to 19.2.4
  - react-resizable-panels from ^4.4.1 to ^4.5.8
  - zustand from ^5.0.10 to ^5.0.11
  - @kevisual/types from ^0.0.11 to ^0.0.12
- Modified queryRouteList function to accept a parameter in index.tsx and store.ts.
- Enhanced searchRoutes functionality to set searchKeyword in store.ts.
This commit is contained in:
2026-02-04 12:47:43 +08:00
parent 754814d08a
commit d88056bf3c
7 changed files with 766 additions and 745 deletions

View File

@@ -1,7 +1,7 @@
{
"dependencies": {
"nanoid": "^5.1.6",
"zod": "^4.2.1",
"zod": "^4.3.6",
"zod-to-json-schema": "^3.25.1"
}
}

1409
pnpm-lock.yaml generated

File diff suppressed because it is too large Load Diff

View File

@@ -4,7 +4,7 @@ include:
.common_env: &common_env
env:
TO_REPO: template/next-simple-template
TO_REPO: template/router-studio
TO_URL: git.xiongxiao.me
imports:
- https://cnb.cool/kevisual/env/-/blob/main/.env.development
@@ -21,7 +21,7 @@ $:
# stages:
# - name: pnpm install
# script: pnpm install
stages: !reference [.dev_tempalte, stages]
stages: !reference [.dev_template, stages]
.common_sync_to_gitea: &common_sync_to_gitea
- <<: *common_env

View File

@@ -10,7 +10,7 @@ const nextConfig: NextConfig = {
distDir: 'dist',
basePath: basePath,
trailingSlash: true,
transpilePackages: ['@kevisual/api', '@kevisual/router'],
transpilePackages: ['@kevisual/api'],
};
export default nextConfig;

View File

@@ -1,20 +1,20 @@
{
"name": "@kevisual/router-studio",
"version": "0.1.0",
"version": "0.1.4",
"basename": "/root/router-studio",
"scripts": {
"dev": "next dev",
"build": "next build",
"start": "next start",
"pub": "ev deploy ./dist -k router-studio -v 0.1.0 -u -y y",
"pub": "ev deploy ./dist -k router-studio -v 0.1.4 -u -y y",
"ui": "pnpm dlx shadcn@latest add "
},
"dependencies": {
"@kevisual/api": "^0.0.20",
"@kevisual/api": "^0.0.44",
"@kevisual/context": "^0.0.4",
"@kevisual/js-filter": "^0.0.5",
"@kevisual/query": "^0.0.37",
"@kevisual/router": "^0.0.60",
"@kevisual/query": "^0.0.39",
"@kevisual/router": "^0.0.69",
"@radix-ui/react-checkbox": "^1.3.3",
"@radix-ui/react-dialog": "^1.1.15",
"@radix-ui/react-dropdown-menu": "^2.1.16",
@@ -27,7 +27,7 @@
"@radix-ui/react-tooltip": "^1.2.8",
"@tanstack/react-table": "^8.21.3",
"@uiw/react-md-editor": "^4.0.11",
"antd": "^6.2.1",
"antd": "^6.2.3",
"class-variance-authority": "^0.7.1",
"clsx": "^2.1.1",
"cmdk": "^1.1.1",
@@ -35,20 +35,20 @@
"es-toolkit": "^1.44.0",
"fuse.js": "^7.1.0",
"idb-keyval": "^6.2.2",
"lucide-react": "^0.562.0",
"next": "16.1.4",
"lucide-react": "^0.563.0",
"next": "16.1.6",
"next-themes": "^0.4.6",
"react": "19.2.3",
"react-dom": "19.2.3",
"react-resizable-panels": "^4.4.1",
"react": "19.2.4",
"react-dom": "19.2.4",
"react-resizable-panels": "^4.5.8",
"react-toastify": "^11.0.5",
"sonner": "^2.0.7",
"tailwind-merge": "^3.4.0",
"valtio": "^2.3.0",
"zustand": "^5.0.10"
"zustand": "^5.0.11"
},
"devDependencies": {
"@kevisual/types": "^0.0.11",
"@kevisual/types": "^0.0.12",
"@tailwindcss/postcss": "^4",
"@types/node": "^25",
"@types/react": "^19",

View File

@@ -109,7 +109,7 @@ export const App = () => {
const [searchKeyword, setSearchKeyword] = useState<string>('');
useEffect(() => {
queryRouteList();
queryRouteList(true);
}, []);
useEffect(() => {
if (store.showFilter) {

View File

@@ -1,6 +1,6 @@
'use client';
import { create } from 'zustand';
import { QueryProxy, RouterViewData, RouterViewItem, pickRouterViewData } from '@kevisual/api'
import { QueryProxy, RouterViewData, RouterViewItem, pickRouterViewData } from '@kevisual/api/proxy'
import { getUrl, query } from '@/modules/query.ts'
import { toast } from 'react-toastify';
import { use } from '@kevisual/context'
@@ -37,7 +37,7 @@ interface StudioState {
init: (force?: boolean) => Promise<{ queryProxy: QueryProxy }>;
routeViewList: RouteViewList;
getViewList: () => Promise<void>;
queryRouteList: () => Promise<void>;
queryRouteList: (first?: boolean) => Promise<void>;
getCurrentView: () => Promise<void>;
updateRouteView: (view: RouterViewData) => Promise<void>;
deleteRouteView: (id: string) => Promise<void>;
@@ -54,6 +54,8 @@ interface StudioState {
setMessages: (messages: any[]) => void;
addMessage: (message: any) => void;
deleteMessage: (message: any) => void;
searchKeyword?: string;
setSearchKeyword?: (keyword: string) => void;
}
const sleep = (ms: number) => new Promise(resolve => setTimeout(resolve, ms));
@@ -64,32 +66,34 @@ export const useStudioStore = create<StudioState>()(
setLoading: (loading: boolean) => set({ loading }),
routes: [],
searchRoutes: async (keyword: string) => {
const state = await get().init();
let queryProxy = state.queryProxy;
console.log('搜索路由', keyword);
// const routes: any[] = await queryProxy.listRoutes(() => true, { query: keyword });
if (keyword.toLocaleUpperCase().startsWith('WHERE')) {
const routes = filter(queryProxy.router.routes, keyword);
set({ routes });
} else {
const fuse = new Fuse(queryProxy.router.routes, {
keys: ['path', 'key', 'description'],
threshold: 0.4,
});
const result = fuse.search(keyword);
const routes = result.map(r => r.item) as any[];
set({ routes });
}
let queryProxy = get().queryProxy;
console.log('[queryProxy] 搜索路由', keyword);
const routes: any[] = await queryProxy.listRoutes(() => true, { query: keyword });
set({ routes, searchKeyword: keyword });
},
searchKeyword: undefined,
setSearchKeyword: (keyword: string) => set({ searchKeyword: keyword }),
currentView: undefined,
queryRouteList: async () => {
await get().getCurrentView();
queryRouteList: async (first: boolean = false) => {
first && await get().getCurrentView();
const state = await get().init();
let currentView: RouterViewData | undefined = get().currentView;
let queryProxy = state.queryProxy;
console.log('开始查询路由列表,当前视图:', queryProxy.emitter.eventNames());
if (first) return;
let searchKeyword = ''
const viewId = currentView?.viewId ?? ''
const routes: any[] = await queryProxy.listRoutes(() => true, { viewId });
set({ routes });
if (viewId && currentView) {
const query = currentView?.views?.find(v => v.id === viewId)?.query || '';
if (query) {
searchKeyword = query;
}
}
console.log('视图ID:', currentView, searchKeyword);
console.log('查询路由列表视图ID:', viewId, queryProxy.router?.routes?.length);
const routes: any[] = await queryProxy.listRoutes(() => true, { query: searchKeyword });
set({ routes, searchKeyword });
},
setCurrentView: async (view?: RouterViewData) => {
const beforeView = get().currentView;
@@ -243,17 +247,29 @@ export const useStudioStore = create<StudioState>()(
},
viewId: '',
}
let searchKeyword = '';
const viewId = currentView?.viewId ?? ''
if (viewId && currentView) {
const query = currentView?.views?.find(v => v.id === viewId)?.query || '';
if (query) {
searchKeyword = query;
}
}
console.log('初始化 QueryProxy', routerViewData);
queryProxy = new QueryProxy({
routerViewData,
router: app as any,
});
console.log('初始化 QueryProxy 完成', queryProxy.token);
set({ queryProxy, searchKeyword });
queryProxy.emitter.once("initComplete", async () => {
console.log('[queryProxy] QueryProxy 初始化完成事件,重新查询路由列表');
await sleep(1000);
get().searchRoutes(searchKeyword);
});
set({ loading: true });
await sleep(1000); // 保证 loading 状态更新
await queryProxy.init();
set({ loading: false });
set({ queryProxy });
return { queryProxy }
},
showLeftPanel: false,