@lokvis/ui-react 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (91) hide show
  1. package/dist/components/AssetPanel.d.ts +12 -0
  2. package/dist/components/AssetPanel.d.ts.map +1 -0
  3. package/dist/components/AssetPanel.js +69 -0
  4. package/dist/components/AssetPanel.js.map +1 -0
  5. package/dist/components/Canvas.d.ts +12 -0
  6. package/dist/components/Canvas.d.ts.map +1 -0
  7. package/dist/components/Canvas.js +35 -0
  8. package/dist/components/Canvas.js.map +1 -0
  9. package/dist/components/HistoryPanel.d.ts +14 -0
  10. package/dist/components/HistoryPanel.d.ts.map +1 -0
  11. package/dist/components/HistoryPanel.js +68 -0
  12. package/dist/components/HistoryPanel.js.map +1 -0
  13. package/dist/components/Inspector.d.ts +12 -0
  14. package/dist/components/Inspector.d.ts.map +1 -0
  15. package/dist/components/Inspector.js +46 -0
  16. package/dist/components/Inspector.js.map +1 -0
  17. package/dist/components/ParamForm.d.ts +14 -0
  18. package/dist/components/ParamForm.d.ts.map +1 -0
  19. package/dist/components/ParamForm.js +28 -0
  20. package/dist/components/ParamForm.js.map +1 -0
  21. package/dist/components/PipelineBar.d.ts +12 -0
  22. package/dist/components/PipelineBar.d.ts.map +1 -0
  23. package/dist/components/PipelineBar.js +44 -0
  24. package/dist/components/PipelineBar.js.map +1 -0
  25. package/dist/components/StatusBar.d.ts +10 -0
  26. package/dist/components/StatusBar.d.ts.map +1 -0
  27. package/dist/components/StatusBar.js +22 -0
  28. package/dist/components/StatusBar.js.map +1 -0
  29. package/dist/components/Toolbar.d.ts +14 -0
  30. package/dist/components/Toolbar.d.ts.map +1 -0
  31. package/dist/components/Toolbar.js +36 -0
  32. package/dist/components/Toolbar.js.map +1 -0
  33. package/dist/components/Workspace.d.ts +24 -0
  34. package/dist/components/Workspace.d.ts.map +1 -0
  35. package/dist/components/Workspace.js +33 -0
  36. package/dist/components/Workspace.js.map +1 -0
  37. package/dist/hooks/useLokvis.d.ts +32 -0
  38. package/dist/hooks/useLokvis.d.ts.map +1 -0
  39. package/dist/hooks/useLokvis.js +62 -0
  40. package/dist/hooks/useLokvis.js.map +1 -0
  41. package/dist/index.d.ts +27 -0
  42. package/dist/index.d.ts.map +1 -0
  43. package/dist/index.js +26 -0
  44. package/dist/index.js.map +1 -0
  45. package/dist/store/assets-slice.d.ts +11 -0
  46. package/dist/store/assets-slice.d.ts.map +1 -0
  47. package/dist/store/assets-slice.js +39 -0
  48. package/dist/store/assets-slice.js.map +1 -0
  49. package/dist/store/capabilities-slice.d.ts +11 -0
  50. package/dist/store/capabilities-slice.d.ts.map +1 -0
  51. package/dist/store/capabilities-slice.js +15 -0
  52. package/dist/store/capabilities-slice.js.map +1 -0
  53. package/dist/store/index.d.ts +4 -0
  54. package/dist/store/index.d.ts.map +1 -0
  55. package/dist/store/index.js +24 -0
  56. package/dist/store/index.js.map +1 -0
  57. package/dist/store/runtime-slice.d.ts +13 -0
  58. package/dist/store/runtime-slice.d.ts.map +1 -0
  59. package/dist/store/runtime-slice.js +29 -0
  60. package/dist/store/runtime-slice.js.map +1 -0
  61. package/dist/store/types.d.ts +77 -0
  62. package/dist/store/types.d.ts.map +1 -0
  63. package/dist/store/types.js +5 -0
  64. package/dist/store/types.js.map +1 -0
  65. package/dist/store/workflow-slice.d.ts +18 -0
  66. package/dist/store/workflow-slice.d.ts.map +1 -0
  67. package/dist/store/workflow-slice.js +133 -0
  68. package/dist/store/workflow-slice.js.map +1 -0
  69. package/dist/types.d.ts +33 -0
  70. package/dist/types.d.ts.map +1 -0
  71. package/dist/types.js +5 -0
  72. package/dist/types.js.map +1 -0
  73. package/package.json +57 -0
  74. package/src/components/AssetPanel.tsx +151 -0
  75. package/src/components/Canvas.tsx +123 -0
  76. package/src/components/HistoryPanel.tsx +127 -0
  77. package/src/components/Inspector.tsx +158 -0
  78. package/src/components/ParamForm.tsx +163 -0
  79. package/src/components/PipelineBar.tsx +125 -0
  80. package/src/components/StatusBar.tsx +63 -0
  81. package/src/components/Toolbar.tsx +87 -0
  82. package/src/components/Workspace.tsx +90 -0
  83. package/src/hooks/useLokvis.ts +78 -0
  84. package/src/index.ts +32 -0
  85. package/src/store/assets-slice.ts +57 -0
  86. package/src/store/capabilities-slice.ts +29 -0
  87. package/src/store/index.ts +27 -0
  88. package/src/store/runtime-slice.ts +53 -0
  89. package/src/store/types.ts +88 -0
  90. package/src/store/workflow-slice.ts +178 -0
  91. package/src/types.ts +46 -0
@@ -0,0 +1,36 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ /**
3
+ * Toolbar - 工作台顶部工具栏
4
+ *
5
+ * 左:Logo + 标题
6
+ * 中:状态消息
7
+ * 右:操作按钮组
8
+ */
9
+ import * as React from 'react';
10
+ import { Button } from '@lokvis/ui-core';
11
+ import { useWorkspaceStore } from '../store/index.js';
12
+ export function Toolbar({ title = 'Lokvis Workspace', rightExtra }) {
13
+ const running = useWorkspaceStore((s) => s.running);
14
+ const statusMessage = useWorkspaceStore((s) => s.statusMessage);
15
+ const error = useWorkspaceStore((s) => s.error);
16
+ const nodes = useWorkspaceStore((s) => s.nodes);
17
+ const selectedAssetId = useWorkspaceStore((s) => s.selectedAssetId);
18
+ const run = useWorkspaceStore((s) => s.run);
19
+ const clearWorkflow = useWorkspaceStore((s) => s.clearWorkflow);
20
+ const setError = useWorkspaceStore((s) => s.setError);
21
+ const canRun = !running && nodes.length > 0 && !!selectedAssetId;
22
+ async function handleRun() {
23
+ try {
24
+ await run();
25
+ }
26
+ catch (err) {
27
+ setError(err instanceof Error ? err.message : String(err));
28
+ }
29
+ }
30
+ return (_jsxs("header", { className: "flex h-12 shrink-0 items-center justify-between border-b border-zinc-200 bg-white px-4 dark:border-zinc-800 dark:bg-zinc-900", children: [_jsxs("div", { className: "flex items-center gap-2.5 min-w-0", children: [_jsx("span", { className: "shrink-0 text-base font-bold leading-none", style: {
31
+ background: 'linear-gradient(135deg, #6366f1, #a855f7)',
32
+ WebkitBackgroundClip: 'text',
33
+ WebkitTextFillColor: 'transparent',
34
+ }, children: "\u25C6" }), _jsx("span", { className: "truncate text-sm font-semibold tracking-tight", children: title })] }), _jsx("div", { className: "flex flex-1 items-center justify-center px-4 min-w-0", children: _jsx("span", { className: `truncate text-xs ${error ? 'text-red-500' : 'text-zinc-400'}`, children: statusMessage }) }), _jsxs("div", { className: "flex items-center gap-1.5 shrink-0", children: [rightExtra, nodes.length > 0 && (_jsx(Button, { variant: "ghost", size: "sm", onClick: clearWorkflow, disabled: running, children: "Clear" })), _jsx(Button, { variant: "primary", size: "sm", onClick: handleRun, loading: running, disabled: !canRun, children: "Run" })] })] }));
35
+ }
36
+ //# sourceMappingURL=Toolbar.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Toolbar.js","sourceRoot":"","sources":["../../src/components/Toolbar.tsx"],"names":[],"mappings":";AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAC/B,OAAO,EAAE,MAAM,EAAE,MAAM,iBAAiB,CAAC;AACzC,OAAO,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AAOtD,MAAM,UAAU,OAAO,CAAC,EAAE,KAAK,GAAG,kBAAkB,EAAE,UAAU,EAAgB;IAC9E,MAAM,OAAO,GAAG,iBAAiB,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC;IACpD,MAAM,aAAa,GAAG,iBAAiB,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC;IAChE,MAAM,KAAK,GAAG,iBAAiB,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC;IAChD,MAAM,KAAK,GAAG,iBAAiB,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC;IAChD,MAAM,eAAe,GAAG,iBAAiB,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,eAAe,CAAC,CAAC;IACpE,MAAM,GAAG,GAAG,iBAAiB,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC;IAC5C,MAAM,aAAa,GAAG,iBAAiB,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC;IAChE,MAAM,QAAQ,GAAG,iBAAiB,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC;IAEtD,MAAM,MAAM,GAAG,CAAC,OAAO,IAAI,KAAK,CAAC,MAAM,GAAG,CAAC,IAAI,CAAC,CAAC,eAAe,CAAC;IAEjE,KAAK,UAAU,SAAS;QACtB,IAAI,CAAC;YACH,MAAM,GAAG,EAAE,CAAC;QACd,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,QAAQ,CAAC,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC;QAC7D,CAAC;IACH,CAAC;IAED,OAAO,CACL,kBAAQ,SAAS,EAAC,8HAA8H,aAE9I,eAAK,SAAS,EAAC,mCAAmC,aAChD,eACE,SAAS,EAAC,2CAA2C,EACrD,KAAK,EAAE;4BACL,UAAU,EAAE,2CAA2C;4BACvD,oBAAoB,EAAE,MAAM;4BAC5B,mBAAmB,EAAE,aAAa;yBACnC,uBAGI,EACP,eAAM,SAAS,EAAC,+CAA+C,YAAE,KAAK,GAAQ,IAC1E,EAGN,cAAK,SAAS,EAAC,sDAAsD,YACnE,eAAM,SAAS,EAAE,oBAAoB,KAAK,CAAC,CAAC,CAAC,cAAc,CAAC,CAAC,CAAC,eAAe,EAAE,YAC5E,aAAa,GACT,GACH,EAGN,eAAK,SAAS,EAAC,oCAAoC,aAChD,UAAU,EACV,KAAK,CAAC,MAAM,GAAG,CAAC,IAAI,CACnB,KAAC,MAAM,IACL,OAAO,EAAC,OAAO,EACf,IAAI,EAAC,IAAI,EACT,OAAO,EAAE,aAAa,EACtB,QAAQ,EAAE,OAAO,sBAGV,CACV,EACD,KAAC,MAAM,IACL,OAAO,EAAC,SAAS,EACjB,IAAI,EAAC,IAAI,EACT,OAAO,EAAE,SAAS,EAClB,OAAO,EAAE,OAAO,EAChB,QAAQ,EAAE,CAAC,MAAM,oBAGV,IACL,IACC,CACV,CAAC;AACJ,CAAC"}
@@ -0,0 +1,24 @@
1
+ /**
2
+ * Workspace - 完整工作台组件
3
+ *
4
+ * 标准三栏布局:Toolbar → [AssetPanel | Canvas | Inspector] → PipelineBar → StatusBar
5
+ * 通过 useLokvis 自动初始化 Runtime 与插件。
6
+ *
7
+ * @example
8
+ * ```tsx
9
+ * import { Workspace } from '@lokvis/ui-react';
10
+ * import imageToolsPlugin from '@lokvis/plugin-image';
11
+ *
12
+ * <Workspace plugins={[imageToolsPlugin()]} />
13
+ * ```
14
+ */
15
+ import { type UseLokvisOptions } from '../hooks/useLokvis.js';
16
+ export interface WorkspaceProps extends UseLokvisOptions {
17
+ /** 顶部标题 */
18
+ title?: string;
19
+ /** 是否显示状态栏(默认 true) */
20
+ showStatusBar?: boolean;
21
+ className?: string;
22
+ }
23
+ export declare function Workspace({ title, showStatusBar, className, ...lokvisOptions }: WorkspaceProps): import("react").JSX.Element;
24
+ //# sourceMappingURL=Workspace.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Workspace.d.ts","sourceRoot":"","sources":["../../src/components/Workspace.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,OAAO,EAAa,KAAK,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AAQzE,MAAM,WAAW,cAAe,SAAQ,gBAAgB;IACtD,WAAW;IACX,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,uBAAuB;IACvB,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,wBAAgB,SAAS,CAAC,EACxB,KAAK,EACL,aAAoB,EACpB,SAAc,EACd,GAAG,aAAa,EACjB,EAAE,cAAc,+BAqDhB"}
@@ -0,0 +1,33 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ /**
3
+ * Workspace - 完整工作台组件
4
+ *
5
+ * 标准三栏布局:Toolbar → [AssetPanel | Canvas | Inspector] → PipelineBar → StatusBar
6
+ * 通过 useLokvis 自动初始化 Runtime 与插件。
7
+ *
8
+ * @example
9
+ * ```tsx
10
+ * import { Workspace } from '@lokvis/ui-react';
11
+ * import imageToolsPlugin from '@lokvis/plugin-image';
12
+ *
13
+ * <Workspace plugins={[imageToolsPlugin()]} />
14
+ * ```
15
+ */
16
+ import { useLokvis } from '../hooks/useLokvis.js';
17
+ import { Toolbar } from './Toolbar.js';
18
+ import { AssetPanel } from './AssetPanel.js';
19
+ import { Canvas } from './Canvas.js';
20
+ import { Inspector } from './Inspector.js';
21
+ import { PipelineBar } from './PipelineBar.js';
22
+ import { StatusBar } from './StatusBar.js';
23
+ export function Workspace({ title, showStatusBar = true, className = '', ...lokvisOptions }) {
24
+ const { status, error } = useLokvis(lokvisOptions);
25
+ if (status === 'initializing') {
26
+ return (_jsx("div", { className: "flex h-full items-center justify-center", children: _jsxs("div", { className: "flex flex-col items-center gap-4", children: [_jsxs("div", { className: "relative flex h-12 w-12 items-center justify-center", children: [_jsx("div", { className: "absolute inset-0 rounded-full border-2 border-indigo-200 dark:border-indigo-800" }), _jsx("div", { className: "h-8 w-8 animate-spin rounded-full border-2 border-transparent border-t-indigo-500" })] }), _jsxs("div", { className: "text-center", children: [_jsx("p", { className: "text-sm font-medium text-zinc-700 dark:text-zinc-300", children: "Initializing Runtime" }), _jsx("p", { className: "mt-1 text-xs text-zinc-400", children: "Loading plugins and capabilities..." })] })] }) }));
27
+ }
28
+ if (status === 'error') {
29
+ return (_jsx("div", { className: "flex h-full items-center justify-center px-6", children: _jsxs("div", { className: "max-w-md rounded-xl border border-red-200 bg-red-50 p-6 text-center dark:border-red-800/50 dark:bg-red-950/20", children: [_jsx("div", { className: "mb-3 flex h-10 w-10 mx-auto items-center justify-center rounded-full bg-red-100 dark:bg-red-900/40", children: _jsxs("svg", { className: "h-5 w-5 text-red-500", fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", strokeWidth: 2, children: [_jsx("circle", { cx: "12", cy: "12", r: "10" }), _jsx("line", { x1: "12", y1: "8", x2: "12", y2: "12" }), _jsx("line", { x1: "12", y1: "16", x2: "12.01", y2: "16" })] }) }), _jsx("p", { className: "font-semibold text-red-700 dark:text-red-400", children: "Failed to initialize" }), _jsx("p", { className: "mt-1.5 text-sm text-red-600/80 dark:text-red-400/70", children: error })] }) }));
30
+ }
31
+ return (_jsxs("div", { className: `flex h-full flex-col bg-white dark:bg-zinc-900 ${className}`, children: [_jsx(Toolbar, { title: title }), _jsxs("div", { className: "flex flex-1 overflow-hidden", children: [_jsx(AssetPanel, {}), _jsx(Canvas, {}), _jsx(Inspector, {})] }), _jsx(PipelineBar, {}), showStatusBar && _jsx(StatusBar, {})] }));
32
+ }
33
+ //# sourceMappingURL=Workspace.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Workspace.js","sourceRoot":"","sources":["../../src/components/Workspace.tsx"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;GAaG;AAEH,OAAO,EAAE,SAAS,EAAyB,MAAM,uBAAuB,CAAC;AACzE,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AACvC,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAC7C,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AACrC,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAC3C,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAC/C,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAU3C,MAAM,UAAU,SAAS,CAAC,EACxB,KAAK,EACL,aAAa,GAAG,IAAI,EACpB,SAAS,GAAG,EAAE,EACd,GAAG,aAAa,EACD;IACf,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,GAAG,SAAS,CAAC,aAAa,CAAC,CAAC;IAEnD,IAAI,MAAM,KAAK,cAAc,EAAE,CAAC;QAC9B,OAAO,CACL,cAAK,SAAS,EAAC,yCAAyC,YACtD,eAAK,SAAS,EAAC,kCAAkC,aAC/C,eAAK,SAAS,EAAC,qDAAqD,aAClE,cAAK,SAAS,EAAC,iFAAiF,GAAG,EACnG,cAAK,SAAS,EAAC,mFAAmF,GAAG,IACjG,EACN,eAAK,SAAS,EAAC,aAAa,aAC1B,YAAG,SAAS,EAAC,sDAAsD,qCAAyB,EAC5F,YAAG,SAAS,EAAC,4BAA4B,oDAAwC,IAC7E,IACF,GACF,CACP,CAAC;IACJ,CAAC;IAED,IAAI,MAAM,KAAK,OAAO,EAAE,CAAC;QACvB,OAAO,CACL,cAAK,SAAS,EAAC,8CAA8C,YAC3D,eAAK,SAAS,EAAC,+GAA+G,aAC5H,cAAK,SAAS,EAAC,oGAAoG,YACjH,eAAK,SAAS,EAAC,sBAAsB,EAAC,IAAI,EAAC,MAAM,EAAC,OAAO,EAAC,WAAW,EAAC,MAAM,EAAC,cAAc,EAAC,WAAW,EAAE,CAAC,aAAE,iBAAQ,EAAE,EAAC,IAAI,EAAC,EAAE,EAAC,IAAI,EAAC,CAAC,EAAC,IAAI,GAAE,EAAA,eAAM,EAAE,EAAC,IAAI,EAAC,EAAE,EAAC,GAAG,EAAC,EAAE,EAAC,IAAI,EAAC,EAAE,EAAC,IAAI,GAAE,EAAA,eAAM,EAAE,EAAC,IAAI,EAAC,EAAE,EAAC,IAAI,EAAC,EAAE,EAAC,OAAO,EAAC,EAAE,EAAC,IAAI,GAAE,IAAM,GAC9N,EACN,YAAG,SAAS,EAAC,8CAA8C,qCAAyB,EACpF,YAAG,SAAS,EAAC,qDAAqD,YAAE,KAAK,GAAK,IAC1E,GACF,CACP,CAAC;IACJ,CAAC;IAED,OAAO,CACL,eAAK,SAAS,EAAE,kDAAkD,SAAS,EAAE,aAE3E,KAAC,OAAO,IAAC,KAAK,EAAE,KAAK,GAAI,EAGzB,eAAK,SAAS,EAAC,6BAA6B,aAC1C,KAAC,UAAU,KAAG,EACd,KAAC,MAAM,KAAG,EACV,KAAC,SAAS,KAAG,IACT,EAGN,KAAC,WAAW,KAAG,EAGd,aAAa,IAAI,KAAC,SAAS,KAAG,IAC3B,CACP,CAAC;AACJ,CAAC"}
@@ -0,0 +1,32 @@
1
+ /**
2
+ * useLokvis - 在 React 中初始化 Lokvis Runtime 并加载插件
3
+ *
4
+ * @example
5
+ * ```tsx
6
+ * import { useLokvis } from '@lokvis/ui-react';
7
+ * import imageToolsPlugin from '@lokvis/plugin-image';
8
+ *
9
+ * function App() {
10
+ * const { runtime, status, error } = useLokvis({
11
+ * plugins: [imageToolsPlugin()],
12
+ * });
13
+ * if (!runtime) return <p>Loading...</p>;
14
+ * return <Workspace />;
15
+ * }
16
+ * ```
17
+ */
18
+ import type { LokvisRuntime, RuntimeConfig } from '@lokvis/runtime';
19
+ import type { PluginLoadEntry } from '@lokvis/sdk';
20
+ export interface UseLokvisOptions extends RuntimeConfig {
21
+ /** 预加载的插件列表 */
22
+ plugins?: PluginLoadEntry[];
23
+ /** 是否在挂载时自动初始化(默认 true) */
24
+ autoInit?: boolean;
25
+ }
26
+ export interface UseLokvisResult {
27
+ runtime: LokvisRuntime | null;
28
+ status: 'idle' | 'initializing' | 'ready' | 'error';
29
+ error: string | null;
30
+ }
31
+ export declare function useLokvis(options?: UseLokvisOptions): UseLokvisResult;
32
+ //# sourceMappingURL=useLokvis.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useLokvis.d.ts","sourceRoot":"","sources":["../../src/hooks/useLokvis.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAIH,OAAO,KAAK,EAAE,aAAa,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AACpE,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAGnD,MAAM,WAAW,gBAAiB,SAAQ,aAAa;IACrD,eAAe;IACf,OAAO,CAAC,EAAE,eAAe,EAAE,CAAC;IAC5B,2BAA2B;IAC3B,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AAED,MAAM,WAAW,eAAe;IAC9B,OAAO,EAAE,aAAa,GAAG,IAAI,CAAC;IAC9B,MAAM,EAAE,MAAM,GAAG,cAAc,GAAG,OAAO,GAAG,OAAO,CAAC;IACpD,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;CACtB;AAED,wBAAgB,SAAS,CAAC,OAAO,GAAE,gBAAqB,GAAG,eAAe,CAwCzE"}
@@ -0,0 +1,62 @@
1
+ /**
2
+ * useLokvis - 在 React 中初始化 Lokvis Runtime 并加载插件
3
+ *
4
+ * @example
5
+ * ```tsx
6
+ * import { useLokvis } from '@lokvis/ui-react';
7
+ * import imageToolsPlugin from '@lokvis/plugin-image';
8
+ *
9
+ * function App() {
10
+ * const { runtime, status, error } = useLokvis({
11
+ * plugins: [imageToolsPlugin()],
12
+ * });
13
+ * if (!runtime) return <p>Loading...</p>;
14
+ * return <Workspace />;
15
+ * }
16
+ * ```
17
+ */
18
+ import { useEffect, useRef, useState } from 'react';
19
+ import { createLokvis } from '@lokvis/sdk';
20
+ import { useWorkspaceStore } from '../store/index.js';
21
+ export function useLokvis(options = {}) {
22
+ const { plugins = [], autoInit = true, ...runtimeConfig } = options;
23
+ const [runtime, setRuntime] = useState(null);
24
+ const [status, setStatus] = useState('idle');
25
+ const [error, setError] = useState(null);
26
+ const initRef = useRef(false);
27
+ const storeInit = useWorkspaceStore((s) => s.init);
28
+ useEffect(() => {
29
+ if (!autoInit || initRef.current)
30
+ return;
31
+ initRef.current = true;
32
+ let cancelled = false;
33
+ (async () => {
34
+ try {
35
+ setStatus('initializing');
36
+ const rt = await createLokvis({
37
+ ...runtimeConfig,
38
+ plugins,
39
+ });
40
+ if (cancelled)
41
+ return;
42
+ setRuntime(rt);
43
+ await storeInit(rt);
44
+ if (cancelled)
45
+ return;
46
+ setStatus('ready');
47
+ }
48
+ catch (err) {
49
+ if (cancelled)
50
+ return;
51
+ setError(err instanceof Error ? err.message : String(err));
52
+ setStatus('error');
53
+ }
54
+ })();
55
+ return () => {
56
+ cancelled = true;
57
+ };
58
+ // eslint-disable-next-line react-hooks/exhaustive-deps
59
+ }, []);
60
+ return { runtime, status, error };
61
+ }
62
+ //# sourceMappingURL=useLokvis.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useLokvis.js","sourceRoot":"","sources":["../../src/hooks/useLokvis.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAEH,OAAO,EAAE,SAAS,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAC;AACpD,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAG3C,OAAO,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AAetD,MAAM,UAAU,SAAS,CAAC,UAA4B,EAAE;IACtD,MAAM,EAAE,OAAO,GAAG,EAAE,EAAE,QAAQ,GAAG,IAAI,EAAE,GAAG,aAAa,EAAE,GAAG,OAAO,CAAC;IACpE,MAAM,CAAC,OAAO,EAAE,UAAU,CAAC,GAAG,QAAQ,CAAuB,IAAI,CAAC,CAAC;IACnE,MAAM,CAAC,MAAM,EAAE,SAAS,CAAC,GAAG,QAAQ,CAA4B,MAAM,CAAC,CAAC;IACxE,MAAM,CAAC,KAAK,EAAE,QAAQ,CAAC,GAAG,QAAQ,CAAgB,IAAI,CAAC,CAAC;IACxD,MAAM,OAAO,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC;IAE9B,MAAM,SAAS,GAAG,iBAAiB,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;IAEnD,SAAS,CAAC,GAAG,EAAE;QACb,IAAI,CAAC,QAAQ,IAAI,OAAO,CAAC,OAAO;YAAE,OAAO;QACzC,OAAO,CAAC,OAAO,GAAG,IAAI,CAAC;QAEvB,IAAI,SAAS,GAAG,KAAK,CAAC;QACtB,CAAC,KAAK,IAAI,EAAE;YACV,IAAI,CAAC;gBACH,SAAS,CAAC,cAAc,CAAC,CAAC;gBAC1B,MAAM,EAAE,GAAG,MAAM,YAAY,CAAC;oBAC5B,GAAG,aAAa;oBAChB,OAAO;iBACR,CAAC,CAAC;gBACH,IAAI,SAAS;oBAAE,OAAO;gBACtB,UAAU,CAAC,EAAE,CAAC,CAAC;gBACf,MAAM,SAAS,CAAC,EAAE,CAAC,CAAC;gBACpB,IAAI,SAAS;oBAAE,OAAO;gBACtB,SAAS,CAAC,OAAO,CAAC,CAAC;YACrB,CAAC;YAAC,OAAO,GAAG,EAAE,CAAC;gBACb,IAAI,SAAS;oBAAE,OAAO;gBACtB,QAAQ,CAAC,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC;gBAC3D,SAAS,CAAC,OAAO,CAAC,CAAC;YACrB,CAAC;QACH,CAAC,CAAC,EAAE,CAAC;QAEL,OAAO,GAAG,EAAE;YACV,SAAS,GAAG,IAAI,CAAC;QACnB,CAAC,CAAC;QACF,uDAAuD;IACzD,CAAC,EAAE,EAAE,CAAC,CAAC;IAEP,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC;AACpC,CAAC"}
@@ -0,0 +1,27 @@
1
+ /**
2
+ * @lokvis/ui-react
3
+ *
4
+ * Lokvis Workspace UI - React workspace component library.
5
+ *
6
+ * Provides:
7
+ * - `<Workspace />` - Ready-to-use local-first workspace
8
+ * - `<AssetPanel />` - Asset panel (import / select / preview)
9
+ * - `<Canvas />` - Canvas preview area
10
+ * - `<Inspector />` - Right panel for capability configuration
11
+ * - `<PipelineBar />` - Workflow pipeline step bar
12
+ * - `<Toolbar />` - Top toolbar
13
+ * - `<StatusBar />` - Bottom status bar
14
+ * - `useLokvis()` - React hook for initializing Runtime + plugins
15
+ */
16
+ export { useLokvis, type UseLokvisOptions, type UseLokvisResult } from './hooks/useLokvis.js';
17
+ export { useWorkspaceStore, type WorkspaceState, type WorkspaceActions } from './store/index.js';
18
+ export { Workspace, type WorkspaceProps } from './components/Workspace.js';
19
+ export { AssetPanel } from './components/AssetPanel.js';
20
+ export { Canvas } from './components/Canvas.js';
21
+ export { Inspector } from './components/Inspector.js';
22
+ export { PipelineBar } from './components/PipelineBar.js';
23
+ export { Toolbar } from './components/Toolbar.js';
24
+ export { StatusBar } from './components/StatusBar.js';
25
+ export { ParamForm, type ParamFormProps } from './components/ParamForm.js';
26
+ export type { WorkspaceEvent, NodeStatus, } from './types.js';
27
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,OAAO,EAAE,SAAS,EAAE,KAAK,gBAAgB,EAAE,KAAK,eAAe,EAAE,MAAM,sBAAsB,CAAC;AAC9F,OAAO,EAAE,iBAAiB,EAAE,KAAK,cAAc,EAAE,KAAK,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AAEjG,OAAO,EAAE,SAAS,EAAE,KAAK,cAAc,EAAE,MAAM,2BAA2B,CAAC;AAC3E,OAAO,EAAE,UAAU,EAAE,MAAM,4BAA4B,CAAC;AACxD,OAAO,EAAE,MAAM,EAAE,MAAM,wBAAwB,CAAC;AAChD,OAAO,EAAE,SAAS,EAAE,MAAM,2BAA2B,CAAC;AACtD,OAAO,EAAE,WAAW,EAAE,MAAM,6BAA6B,CAAC;AAC1D,OAAO,EAAE,OAAO,EAAE,MAAM,yBAAyB,CAAC;AAClD,OAAO,EAAE,SAAS,EAAE,MAAM,2BAA2B,CAAC;AACtD,OAAO,EAAE,SAAS,EAAE,KAAK,cAAc,EAAE,MAAM,2BAA2B,CAAC;AAE3E,YAAY,EACV,cAAc,EACd,UAAU,GACX,MAAM,YAAY,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,26 @@
1
+ /**
2
+ * @lokvis/ui-react
3
+ *
4
+ * Lokvis Workspace UI - React workspace component library.
5
+ *
6
+ * Provides:
7
+ * - `<Workspace />` - Ready-to-use local-first workspace
8
+ * - `<AssetPanel />` - Asset panel (import / select / preview)
9
+ * - `<Canvas />` - Canvas preview area
10
+ * - `<Inspector />` - Right panel for capability configuration
11
+ * - `<PipelineBar />` - Workflow pipeline step bar
12
+ * - `<Toolbar />` - Top toolbar
13
+ * - `<StatusBar />` - Bottom status bar
14
+ * - `useLokvis()` - React hook for initializing Runtime + plugins
15
+ */
16
+ export { useLokvis } from './hooks/useLokvis.js';
17
+ export { useWorkspaceStore } from './store/index.js';
18
+ export { Workspace } from './components/Workspace.js';
19
+ export { AssetPanel } from './components/AssetPanel.js';
20
+ export { Canvas } from './components/Canvas.js';
21
+ export { Inspector } from './components/Inspector.js';
22
+ export { PipelineBar } from './components/PipelineBar.js';
23
+ export { Toolbar } from './components/Toolbar.js';
24
+ export { StatusBar } from './components/StatusBar.js';
25
+ export { ParamForm } from './components/ParamForm.js';
26
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,OAAO,EAAE,SAAS,EAA+C,MAAM,sBAAsB,CAAC;AAC9F,OAAO,EAAE,iBAAiB,EAA8C,MAAM,kBAAkB,CAAC;AAEjG,OAAO,EAAE,SAAS,EAAuB,MAAM,2BAA2B,CAAC;AAC3E,OAAO,EAAE,UAAU,EAAE,MAAM,4BAA4B,CAAC;AACxD,OAAO,EAAE,MAAM,EAAE,MAAM,wBAAwB,CAAC;AAChD,OAAO,EAAE,SAAS,EAAE,MAAM,2BAA2B,CAAC;AACtD,OAAO,EAAE,WAAW,EAAE,MAAM,6BAA6B,CAAC;AAC1D,OAAO,EAAE,OAAO,EAAE,MAAM,yBAAyB,CAAC;AAClD,OAAO,EAAE,SAAS,EAAE,MAAM,2BAA2B,CAAC;AACtD,OAAO,EAAE,SAAS,EAAuB,MAAM,2BAA2B,CAAC"}
@@ -0,0 +1,11 @@
1
+ /**
2
+ * Assets slice —— 资产导入 / 选择 / 删除 / 缩略图
3
+ */
4
+ import type { StateCreator } from 'zustand';
5
+ import type { WorkspaceStore, WorkspaceState, WorkspaceActions } from './types.js';
6
+ export interface AssetsSlice extends Pick<WorkspaceState, 'assets' | 'selectedAssetId' | 'thumbnails'>, Pick<WorkspaceActions, 'refreshAssets' | 'importFiles' | 'selectAsset' | 'setThumbnail' | 'removeAsset'> {
7
+ }
8
+ export declare const createAssetsSlice: StateCreator<WorkspaceStore, [
9
+ ], [
10
+ ], AssetsSlice>;
11
+ //# sourceMappingURL=assets-slice.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"assets-slice.d.ts","sourceRoot":"","sources":["../../src/store/assets-slice.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAC5C,OAAO,KAAK,EAAE,cAAc,EAAE,cAAc,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAEnF,MAAM,WAAW,WACf,SAAQ,IAAI,CAAC,cAAc,EAAE,QAAQ,GAAG,iBAAiB,GAAG,YAAY,CAAC,EACvE,IAAI,CACF,gBAAgB,EAChB,eAAe,GAAG,aAAa,GAAG,aAAa,GAAG,cAAc,GAAG,aAAa,CACjF;CAAG;AAER,eAAO,MAAM,iBAAiB,EAAE,YAAY,CAC1C,cAAc,EACd;CAAE,EACF;CAAE,EACF,WAAW,CAuCX,CAAC"}
@@ -0,0 +1,39 @@
1
+ export const createAssetsSlice = (set, get) => ({
2
+ assets: [],
3
+ selectedAssetId: null,
4
+ thumbnails: {},
5
+ async refreshAssets() {
6
+ const { runtime } = get();
7
+ if (!runtime)
8
+ return;
9
+ const assets = await runtime.listAssets();
10
+ set({ assets });
11
+ },
12
+ async importFiles(files) {
13
+ const { runtime } = get();
14
+ if (!runtime)
15
+ return;
16
+ set({ statusMessage: `Importing ${files.length} file(s)...` });
17
+ for (const file of files) {
18
+ await runtime.importAsset({ kind: 'file', file });
19
+ }
20
+ await get().refreshAssets();
21
+ set({ statusMessage: `Imported ${files.length} file(s)` });
22
+ },
23
+ selectAsset(id) {
24
+ set({ selectedAssetId: id });
25
+ },
26
+ setThumbnail(id, url) {
27
+ set((state) => ({ thumbnails: { ...state.thumbnails, [id]: url } }));
28
+ },
29
+ async removeAsset(id) {
30
+ const { runtime } = get();
31
+ if (!runtime)
32
+ return;
33
+ await runtime.removeAsset(id);
34
+ await get().refreshAssets();
35
+ if (get().selectedAssetId === id)
36
+ set({ selectedAssetId: null });
37
+ },
38
+ });
39
+ //# sourceMappingURL=assets-slice.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"assets-slice.js","sourceRoot":"","sources":["../../src/store/assets-slice.ts"],"names":[],"mappings":"AAaA,MAAM,CAAC,MAAM,iBAAiB,GAK1B,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE,CAAC,CAAC;IACjB,MAAM,EAAE,EAAE;IACV,eAAe,EAAE,IAAI;IACrB,UAAU,EAAE,EAAE;IAEd,KAAK,CAAC,aAAa;QACjB,MAAM,EAAE,OAAO,EAAE,GAAG,GAAG,EAAE,CAAC;QAC1B,IAAI,CAAC,OAAO;YAAE,OAAO;QACrB,MAAM,MAAM,GAAG,MAAM,OAAO,CAAC,UAAU,EAAE,CAAC;QAC1C,GAAG,CAAC,EAAE,MAAM,EAAE,CAAC,CAAC;IAClB,CAAC;IAED,KAAK,CAAC,WAAW,CAAC,KAAK;QACrB,MAAM,EAAE,OAAO,EAAE,GAAG,GAAG,EAAE,CAAC;QAC1B,IAAI,CAAC,OAAO;YAAE,OAAO;QACrB,GAAG,CAAC,EAAE,aAAa,EAAE,aAAa,KAAK,CAAC,MAAM,aAAa,EAAE,CAAC,CAAC;QAC/D,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;YACzB,MAAM,OAAO,CAAC,WAAW,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC;QACpD,CAAC;QACD,MAAM,GAAG,EAAE,CAAC,aAAa,EAAE,CAAC;QAC5B,GAAG,CAAC,EAAE,aAAa,EAAE,YAAY,KAAK,CAAC,MAAM,UAAU,EAAE,CAAC,CAAC;IAC7D,CAAC;IAED,WAAW,CAAC,EAAE;QACZ,GAAG,CAAC,EAAE,eAAe,EAAE,EAAE,EAAE,CAAC,CAAC;IAC/B,CAAC;IAED,YAAY,CAAC,EAAE,EAAE,GAAG;QAClB,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,EAAE,UAAU,EAAE,EAAE,GAAG,KAAK,CAAC,UAAU,EAAE,CAAC,EAAE,CAAC,EAAE,GAAG,EAAE,EAAE,CAAC,CAAC,CAAC;IACvE,CAAC;IAED,KAAK,CAAC,WAAW,CAAC,EAAE;QAClB,MAAM,EAAE,OAAO,EAAE,GAAG,GAAG,EAAE,CAAC;QAC1B,IAAI,CAAC,OAAO;YAAE,OAAO;QACrB,MAAM,OAAO,CAAC,WAAW,CAAC,EAAE,CAAC,CAAC;QAC9B,MAAM,GAAG,EAAE,CAAC,aAAa,EAAE,CAAC;QAC5B,IAAI,GAAG,EAAE,CAAC,eAAe,KAAK,EAAE;YAAE,GAAG,CAAC,EAAE,eAAe,EAAE,IAAI,EAAE,CAAC,CAAC;IACnE,CAAC;CACF,CAAC,CAAC"}
@@ -0,0 +1,11 @@
1
+ /**
2
+ * Capabilities slice —— 能力列表与映射
3
+ */
4
+ import type { StateCreator } from 'zustand';
5
+ import type { WorkspaceStore, WorkspaceState, WorkspaceActions } from './types.js';
6
+ export interface CapabilitiesSlice extends Pick<WorkspaceState, 'capabilities' | 'capabilityMap'>, Pick<WorkspaceActions, 'refreshCapabilities'> {
7
+ }
8
+ export declare const createCapabilitiesSlice: StateCreator<WorkspaceStore, [
9
+ ], [
10
+ ], CapabilitiesSlice>;
11
+ //# sourceMappingURL=capabilities-slice.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"capabilities-slice.d.ts","sourceRoot":"","sources":["../../src/store/capabilities-slice.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAE5C,OAAO,KAAK,EAAE,cAAc,EAAE,cAAc,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAEnF,MAAM,WAAW,iBACf,SAAQ,IAAI,CAAC,cAAc,EAAE,cAAc,GAAG,eAAe,CAAC,EAC5D,IAAI,CAAC,gBAAgB,EAAE,qBAAqB,CAAC;CAAG;AAEpD,eAAO,MAAM,uBAAuB,EAAE,YAAY,CAChD,cAAc,EACd;CAAE,EACF;CAAE,EACF,iBAAiB,CAajB,CAAC"}
@@ -0,0 +1,15 @@
1
+ export const createCapabilitiesSlice = (set, get) => ({
2
+ capabilities: [],
3
+ capabilityMap: {},
4
+ async refreshCapabilities() {
5
+ const { runtime } = get();
6
+ if (!runtime)
7
+ return;
8
+ const capabilities = await runtime.capabilities();
9
+ const capabilityMap = {};
10
+ for (const cap of capabilities)
11
+ capabilityMap[cap.name] = cap;
12
+ set({ capabilities, capabilityMap });
13
+ },
14
+ });
15
+ //# sourceMappingURL=capabilities-slice.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"capabilities-slice.js","sourceRoot":"","sources":["../../src/store/capabilities-slice.ts"],"names":[],"mappings":"AAWA,MAAM,CAAC,MAAM,uBAAuB,GAKhC,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE,CAAC,CAAC;IACjB,YAAY,EAAE,EAAE;IAChB,aAAa,EAAE,EAAE;IAEjB,KAAK,CAAC,mBAAmB;QACvB,MAAM,EAAE,OAAO,EAAE,GAAG,GAAG,EAAE,CAAC;QAC1B,IAAI,CAAC,OAAO;YAAE,OAAO;QACrB,MAAM,YAAY,GAAG,MAAM,OAAO,CAAC,YAAY,EAAE,CAAC;QAClD,MAAM,aAAa,GAAkB,EAAE,CAAC;QACxC,KAAK,MAAM,GAAG,IAAI,YAAY;YAAE,aAAa,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,GAAG,CAAC;QAC9D,GAAG,CAAC,EAAE,YAAY,EAAE,aAAa,EAAE,CAAC,CAAC;IACvC,CAAC;CACF,CAAC,CAAC"}
@@ -0,0 +1,4 @@
1
+ import type { WorkspaceStore } from './types.js';
2
+ export declare const useWorkspaceStore: import("zustand").UseBoundStore<import("zustand").StoreApi<WorkspaceStore>>;
3
+ export type { WorkspaceState, WorkspaceActions, WorkspaceStore } from './types.js';
4
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/store/index.ts"],"names":[],"mappings":"AAaA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAMjD,eAAO,MAAM,iBAAiB,6EAK3B,CAAC;AAEJ,YAAY,EAAE,cAAc,EAAE,gBAAgB,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC"}
@@ -0,0 +1,24 @@
1
+ /**
2
+ * Workspace UI 状态管理(Zustand)
3
+ *
4
+ * 按域拆分为 4 个 slice:
5
+ * - runtime-slice: Runtime 初始化、全局状态消息、错误
6
+ * - assets-slice: 资产导入 / 选择 / 删除 / 缩略图
7
+ * - capabilities-slice: 能力列表与映射
8
+ * - workflow-slice: 工作流节点编排与执行
9
+ *
10
+ * 各 slice 独立演进,W6/W7/W9 扩展时按 slice 添加 action 即可。
11
+ * Runtime 永远不知道 React,但 UI 层负责把 Runtime 事件桥接到 store。
12
+ */
13
+ import { create } from 'zustand';
14
+ import { createRuntimeSlice } from './runtime-slice.js';
15
+ import { createAssetsSlice } from './assets-slice.js';
16
+ import { createCapabilitiesSlice } from './capabilities-slice.js';
17
+ import { createWorkflowSlice } from './workflow-slice.js';
18
+ export const useWorkspaceStore = create()((...a) => ({
19
+ ...createRuntimeSlice(...a),
20
+ ...createAssetsSlice(...a),
21
+ ...createCapabilitiesSlice(...a),
22
+ ...createWorkflowSlice(...a),
23
+ }));
24
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/store/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AACH,OAAO,EAAE,MAAM,EAAE,MAAM,SAAS,CAAC;AAEjC,OAAO,EAAE,kBAAkB,EAAE,MAAM,oBAAoB,CAAC;AACxD,OAAO,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AACtD,OAAO,EAAE,uBAAuB,EAAE,MAAM,yBAAyB,CAAC;AAClE,OAAO,EAAE,mBAAmB,EAAE,MAAM,qBAAqB,CAAC;AAE1D,MAAM,CAAC,MAAM,iBAAiB,GAAG,MAAM,EAAkB,CAAC,CAAC,GAAG,CAAC,EAAE,EAAE,CAAC,CAAC;IACnE,GAAG,kBAAkB,CAAC,GAAG,CAAC,CAAC;IAC3B,GAAG,iBAAiB,CAAC,GAAG,CAAC,CAAC;IAC1B,GAAG,uBAAuB,CAAC,GAAG,CAAC,CAAC;IAChC,GAAG,mBAAmB,CAAC,GAAG,CAAC,CAAC;CAC7B,CAAC,CAAC,CAAC"}
@@ -0,0 +1,13 @@
1
+ /**
2
+ * Runtime slice —— Runtime 初始化与状态消息
3
+ *
4
+ * 负责 runtime 实例注入、初始化、全局状态消息与错误。
5
+ */
6
+ import type { StateCreator } from 'zustand';
7
+ import type { WorkspaceStore, WorkspaceState, WorkspaceActions } from './types.js';
8
+ export interface RuntimeSlice extends Pick<WorkspaceState, 'runtime' | 'initializing' | 'initError' | 'running' | 'statusMessage' | 'error'>, Pick<WorkspaceActions, 'init' | 'setStatus' | 'setError'> {
9
+ }
10
+ export declare const createRuntimeSlice: StateCreator<WorkspaceStore, [
11
+ ], [
12
+ ], RuntimeSlice>;
13
+ //# sourceMappingURL=runtime-slice.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"runtime-slice.d.ts","sourceRoot":"","sources":["../../src/store/runtime-slice.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAC5C,OAAO,KAAK,EAAE,cAAc,EAAE,cAAc,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAEnF,MAAM,WAAW,YACf,SAAQ,IAAI,CACV,cAAc,EACd,SAAS,GAAG,cAAc,GAAG,WAAW,GAAG,SAAS,GAAG,eAAe,GAAG,OAAO,CACjF,EACC,IAAI,CACF,gBAAgB,EAChB,MAAM,GAAG,WAAW,GAAG,UAAU,CAClC;CAAG;AAER,eAAO,MAAM,kBAAkB,EAAE,YAAY,CAC3C,cAAc,EACd;CAAE,EACF;CAAE,EACF,YAAY,CA8BZ,CAAC"}
@@ -0,0 +1,29 @@
1
+ export const createRuntimeSlice = (set, get) => ({
2
+ runtime: null,
3
+ initializing: false,
4
+ initError: null,
5
+ running: false,
6
+ statusMessage: 'Idle',
7
+ error: null,
8
+ async init(runtime) {
9
+ set({ runtime, initializing: true, initError: null });
10
+ try {
11
+ await get().refreshAssets();
12
+ await get().refreshCapabilities();
13
+ set({ initializing: false, statusMessage: 'Ready' });
14
+ }
15
+ catch (err) {
16
+ set({
17
+ initializing: false,
18
+ initError: err instanceof Error ? err.message : String(err),
19
+ });
20
+ }
21
+ },
22
+ setStatus(message) {
23
+ set({ statusMessage: message });
24
+ },
25
+ setError(error) {
26
+ set({ error });
27
+ },
28
+ });
29
+ //# sourceMappingURL=runtime-slice.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"runtime-slice.js","sourceRoot":"","sources":["../../src/store/runtime-slice.ts"],"names":[],"mappings":"AAkBA,MAAM,CAAC,MAAM,kBAAkB,GAK3B,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE,CAAC,CAAC;IACjB,OAAO,EAAE,IAAI;IACb,YAAY,EAAE,KAAK;IACnB,SAAS,EAAE,IAAI;IACf,OAAO,EAAE,KAAK;IACd,aAAa,EAAE,MAAM;IACrB,KAAK,EAAE,IAAI;IAEX,KAAK,CAAC,IAAI,CAAC,OAAO;QAChB,GAAG,CAAC,EAAE,OAAO,EAAE,YAAY,EAAE,IAAI,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QACtD,IAAI,CAAC;YACH,MAAM,GAAG,EAAE,CAAC,aAAa,EAAE,CAAC;YAC5B,MAAM,GAAG,EAAE,CAAC,mBAAmB,EAAE,CAAC;YAClC,GAAG,CAAC,EAAE,YAAY,EAAE,KAAK,EAAE,aAAa,EAAE,OAAO,EAAE,CAAC,CAAC;QACvD,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,GAAG,CAAC;gBACF,YAAY,EAAE,KAAK;gBACnB,SAAS,EAAE,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC;aAC5D,CAAC,CAAC;QACL,CAAC;IACH,CAAC;IAED,SAAS,CAAC,OAAO;QACf,GAAG,CAAC,EAAE,aAAa,EAAE,OAAO,EAAE,CAAC,CAAC;IAClC,CAAC;IAED,QAAQ,CAAC,KAAK;QACZ,GAAG,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC;IACjB,CAAC;CACF,CAAC,CAAC"}
@@ -0,0 +1,77 @@
1
+ /**
2
+ * Workspace Store 类型定义
3
+ *
4
+ * 把原 store.ts 顶部的 WorkspaceState / WorkspaceActions 抽出,
5
+ * 供各 slice 引用,避免循环依赖。
6
+ */
7
+ import type { Asset, Capability } from '@lokvis/schema';
8
+ import type { LokvisRuntime } from '@lokvis/runtime';
9
+ import type { CapabilityMap, NodeStatus, WorkspaceNode } from '../types.js';
10
+ /** 工作台完整状态 */
11
+ export interface WorkspaceState {
12
+ /** Runtime 实例 */
13
+ runtime: LokvisRuntime | null;
14
+ /** 是否正在初始化 Runtime */
15
+ initializing: boolean;
16
+ /** 初始化错误 */
17
+ initError: string | null;
18
+ /** 所有已导入资产 */
19
+ assets: Asset[];
20
+ /** 当前选中的资产 ID */
21
+ selectedAssetId: string | null;
22
+ /** 资产缩略图(AssetId → ObjectURL) */
23
+ thumbnails: Record<string, string>;
24
+ /** 所有已注册能力 */
25
+ capabilities: Capability[];
26
+ /** 能力映射表(name → Capability) */
27
+ capabilityMap: CapabilityMap;
28
+ /** 工作流节点序列(线性链) */
29
+ nodes: WorkspaceNode[];
30
+ /** 当前选中的节点 ID */
31
+ selectedNodeId: string | null;
32
+ /** 是否正在执行工作流 */
33
+ running: boolean;
34
+ /** 全局状态消息 */
35
+ statusMessage: string;
36
+ /** 错误信息 */
37
+ error: string | null;
38
+ }
39
+ /** 工作台操作 */
40
+ export interface WorkspaceActions {
41
+ /** 初始化 Runtime */
42
+ init(runtime: LokvisRuntime): Promise<void>;
43
+ /** 刷新资产列表 */
44
+ refreshAssets(): Promise<void>;
45
+ /** 刷新能力列表 */
46
+ refreshCapabilities(): Promise<void>;
47
+ /** 导入文件 */
48
+ importFiles(files: File[]): Promise<void>;
49
+ /** 选择资产 */
50
+ selectAsset(id: string | null): void;
51
+ /** 设置缩略图 */
52
+ setThumbnail(id: string, url: string): void;
53
+ /** 删除资产 */
54
+ removeAsset(id: string): Promise<void>;
55
+ /** 添加工作流节点 */
56
+ addNode(capability: string): void;
57
+ /** 更新节点参数 */
58
+ updateNodeParams(id: string, params: Record<string, unknown>): void;
59
+ /** 删除节点 */
60
+ removeNode(id: string): void;
61
+ /** 选择节点 */
62
+ selectNode(id: string | null): void;
63
+ /** 设置节点状态 */
64
+ setNodeStatus(id: string, status: NodeStatus, error?: string, duration?: number): void;
65
+ /** 执行工作流 */
66
+ run(): Promise<Asset[]>;
67
+ /** 设置状态消息 */
68
+ setStatus(message: string): void;
69
+ /** 设置错误 */
70
+ setError(error: string | null): void;
71
+ /** 清空工作流 */
72
+ clearWorkflow(): void;
73
+ }
74
+ export type WorkspaceStore = WorkspaceState & WorkspaceActions;
75
+ /** 生成节点 ID */
76
+ export declare function genNodeId(): string;
77
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/store/types.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,5 @@
1
+ /** 生成节点 ID */
2
+ export function genNodeId() {
3
+ return `node_${Date.now().toString(36)}_${Math.random().toString(36).slice(2, 6)}`;
4
+ }
5
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/store/types.ts"],"names":[],"mappings":"AAoFA,cAAc;AACd,MAAM,UAAU,SAAS;IACvB,OAAO,QAAQ,IAAI,CAAC,GAAG,EAAE,CAAC,QAAQ,CAAC,EAAE,CAAC,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC;AACrF,CAAC"}
@@ -0,0 +1,18 @@
1
+ /**
2
+ * Workflow slice —— 工作流节点编排与执行
3
+ *
4
+ * 负责:
5
+ * - 节点 CRUD(add / remove / updateParams / select / setNodeStatus)
6
+ * - 工作流执行(run):构建线性 Workflow → 调用 runtime.run → 更新节点状态
7
+ * - 清空(clearWorkflow)
8
+ *
9
+ * run() 内部依赖 buildLinearWorkflow(本地工具)把节点序列构建为 Workflow 定义。
10
+ */
11
+ import type { StateCreator } from 'zustand';
12
+ import type { WorkspaceStore, WorkspaceState, WorkspaceActions } from './types.js';
13
+ export interface WorkflowSlice extends Pick<WorkspaceState, 'nodes' | 'selectedNodeId'>, Pick<WorkspaceActions, 'addNode' | 'updateNodeParams' | 'removeNode' | 'selectNode' | 'setNodeStatus' | 'run' | 'clearWorkflow'> {
14
+ }
15
+ export declare const createWorkflowSlice: StateCreator<WorkspaceStore, [
16
+ ], [
17
+ ], WorkflowSlice>;
18
+ //# sourceMappingURL=workflow-slice.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"workflow-slice.d.ts","sourceRoot":"","sources":["../../src/store/workflow-slice.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AACH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAG5C,OAAO,KAAK,EAAE,cAAc,EAAE,cAAc,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAGnF,MAAM,WAAW,aACf,SAAQ,IAAI,CAAC,cAAc,EAAE,OAAO,GAAG,gBAAgB,CAAC,EACtD,IAAI,CACF,gBAAgB,EACd,SAAS,GACT,kBAAkB,GAClB,YAAY,GACZ,YAAY,GACZ,eAAe,GACf,KAAK,GACL,eAAe,CAClB;CAAG;AAER,eAAO,MAAM,mBAAmB,EAAE,YAAY,CAC5C,cAAc,EACd;CAAE,EACF;CAAE,EACF,aAAa,CAgHb,CAAC"}