@invect/ui 0.0.1
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.
- package/LICENSE +21 -0
- package/README.md +77 -0
- package/dist/Invect-CWpIwZ5F.js +92738 -0
- package/dist/Invect.d.ts +25 -0
- package/dist/InvectShell.d.ts +14 -0
- package/dist/api/agent-tools.api.d.ts +1 -0
- package/dist/api/client.d.ts +207 -0
- package/dist/api/credentials.api.d.ts +47 -0
- package/dist/api/executions.api.d.ts +43 -0
- package/dist/api/flows.api.d.ts +100 -0
- package/dist/api/index.d.ts +9 -0
- package/dist/api/node-data.api.d.ts +66 -0
- package/dist/api/query-keys.d.ts +22 -0
- package/dist/api/triggers.api.d.ts +44 -0
- package/dist/api/types.d.ts +147 -0
- package/dist/api/use-flow-run-stream.d.ts +12 -0
- package/dist/assets/invect-branding.d.ts +4 -0
- package/dist/assets/provider-icons/index.d.ts +8 -0
- package/dist/babel-C9OtljFZ.js +9721 -0
- package/dist/components/PageLayout.d.ts +17 -0
- package/dist/components/chat/ChatInput.d.ts +17 -0
- package/dist/components/chat/ChatMessageList.d.ts +14 -0
- package/dist/components/chat/ChatModelSelector.d.ts +11 -0
- package/dist/components/chat/ChatPanel.d.ts +19 -0
- package/dist/components/chat/ChatPromptOverlay.d.ts +13 -0
- package/dist/components/chat/ChatProviderSelector.d.ts +9 -0
- package/dist/components/chat/ChatSettingsPanel.d.ts +11 -0
- package/dist/components/chat/InlineCredentialSetup.d.ts +9 -0
- package/dist/components/chat/MarkdownRenderer.d.ts +7 -0
- package/dist/components/chat/chat-memory.d.ts +21 -0
- package/dist/components/chat/chat.store.d.ts +416 -0
- package/dist/components/chat/index.d.ts +5 -0
- package/dist/components/chat/use-chat.d.ts +28 -0
- package/dist/components/credentials/CreateCredentialModal.d.ts +13 -0
- package/dist/components/credentials/CredentialDetailDialog.d.ts +17 -0
- package/dist/components/credentials/EditCredentialModal.d.ts +11 -0
- package/dist/components/credentials/OAuth2ConnectButton.d.ts +38 -0
- package/dist/components/credentials/OAuth2ProviderSelector.d.ts +15 -0
- package/dist/components/credentials/credential-utils.d.ts +12 -0
- package/dist/components/credentials/index.d.ts +9 -0
- package/dist/components/dashboard/FailedRunsAlert.d.ts +3 -0
- package/dist/components/dashboard/FlowCard.d.ts +7 -0
- package/dist/components/dashboard/RecentActivityTable.d.ts +9 -0
- package/dist/components/dashboard/StatCard.d.ts +10 -0
- package/dist/components/dashboard/index.d.ts +5 -0
- package/dist/components/dashboard/status-helpers.d.ts +5 -0
- package/dist/components/flow-editor/ActionsSidebar.d.ts +2 -0
- package/dist/components/flow-editor/FlowEditor.d.ts +21 -0
- package/dist/components/flow-editor/FlowHeader.d.ts +9 -0
- package/dist/components/flow-editor/FlowLayout.d.ts +24 -0
- package/dist/components/flow-editor/ModeSwitcher.d.ts +7 -0
- package/dist/components/flow-editor/NodeSidebar.d.ts +24 -0
- package/dist/components/flow-editor/RunControls.d.ts +12 -0
- package/dist/components/flow-editor/ToolConfigPanel.d.ts +16 -0
- package/dist/components/flow-editor/ValidationPanel.d.ts +5 -0
- package/dist/components/flow-editor/flow-editor.store.d.ts +1 -0
- package/dist/components/flow-editor/index.d.ts +6 -0
- package/dist/components/flow-editor/inline-edit.d.ts +10 -0
- package/dist/components/flow-editor/node-config-panel/ConfigFieldWithTemplate.d.ts +26 -0
- package/dist/components/flow-editor/node-config-panel/CredentialCombobox.d.ts +21 -0
- package/dist/components/flow-editor/node-config-panel/CredentialsSection.d.ts +19 -0
- package/dist/components/flow-editor/node-config-panel/DroppableInput.d.ts +20 -0
- package/dist/components/flow-editor/node-config-panel/DynamicSelectField.d.ts +22 -0
- package/dist/components/flow-editor/node-config-panel/JsonPreviewPanel.d.ts +25 -0
- package/dist/components/flow-editor/node-config-panel/NodeConfigPanel.d.ts +14 -0
- package/dist/components/flow-editor/node-config-panel/NodeConfigPanelHeader.d.ts +15 -0
- package/dist/components/flow-editor/node-config-panel/ParametersSection.d.ts +16 -0
- package/dist/components/flow-editor/node-config-panel/SearchableSelectField.d.ts +17 -0
- package/dist/components/flow-editor/node-config-panel/SwitchCasesField.d.ts +18 -0
- package/dist/components/flow-editor/node-config-panel/hooks/index.d.ts +2 -0
- package/dist/components/flow-editor/node-config-panel/hooks/use-node-config-panel-state.d.ts +24 -0
- package/dist/components/flow-editor/node-config-panel/hooks/use-node-execution.d.ts +46 -0
- package/dist/components/flow-editor/node-config-panel/hooks/use-upstream-slots.d.ts +16 -0
- package/dist/components/flow-editor/node-config-panel/panels/AgentToolsPanel.d.ts +18 -0
- package/dist/components/flow-editor/node-config-panel/panels/ConfigurationPanel.d.ts +49 -0
- package/dist/components/flow-editor/node-config-panel/panels/DataMapperPane.d.ts +40 -0
- package/dist/components/flow-editor/node-config-panel/panels/InputPanel.d.ts +49 -0
- package/dist/components/flow-editor/node-config-panel/panels/OutputPanel.d.ts +7 -0
- package/dist/components/flow-editor/node-config-panel/panels/index.d.ts +4 -0
- package/dist/components/flow-editor/node-config-panel/types.d.ts +19 -0
- package/dist/components/flow-editor/node-config-panel/use-node-config-panel-store.d.ts +49 -0
- package/dist/components/flow-editor/node-config-panel/use-node-config-state.d.ts +26 -0
- package/dist/components/flow-editor/node-config-panel/use-run-node.d.ts +16 -0
- package/dist/components/flow-editor/node-config-panel/utils.d.ts +9 -0
- package/dist/components/flow-editor/serialize-to-sdk.d.ts +20 -0
- package/dist/components/flow-editor/toolbar-context.d.ts +2 -0
- package/dist/components/flow-editor/use-copy-paste.d.ts +7 -0
- package/dist/components/flow-editor/use-copy-paste.types.d.ts +38 -0
- package/dist/components/flow-editor/use-flow-editor.d.ts +44 -0
- package/dist/components/flow-runs-table/FlowRunsTable.d.ts +6 -0
- package/dist/components/flow-runs-table/index.d.ts +1 -0
- package/dist/components/flow-viewer/FlowRunsView.d.ts +7 -0
- package/dist/components/flow-viewer/FlowStatusView.d.ts +21 -0
- package/dist/components/flow-viewer/RunSelector.d.ts +13 -0
- package/dist/components/flow-viewer/RunsSidebar.d.ts +14 -0
- package/dist/components/flow-viewer/agent-tool-executions-list.d.ts +7 -0
- package/dist/components/flow-viewer/index.d.ts +1 -0
- package/dist/components/flow-viewer/logs-panel.d.ts +18 -0
- package/dist/components/flow-viewer/use-execution-log-data.d.ts +113 -0
- package/dist/components/graph/BatchFlowEdge.d.ts +33 -0
- package/dist/components/graph/LayoutSelector.d.ts +9 -0
- package/dist/components/graph/index.d.ts +47 -0
- package/dist/components/graph/styleUtils.d.ts +124 -0
- package/dist/components/nodes/AgentConfigPanel.d.ts +24 -0
- package/dist/components/nodes/AgentNode.d.ts +8 -0
- package/dist/components/nodes/AgentToolsBox.d.ts +41 -0
- package/dist/components/nodes/NodeAppendix.d.ts +19 -0
- package/dist/components/nodes/NodeStatusIndicator.d.ts +30 -0
- package/dist/components/nodes/NodeViewContext.d.ts +18 -0
- package/dist/components/nodes/ToolParamField.d.ts +28 -0
- package/dist/components/nodes/ToolSelectorModal.d.ts +80 -0
- package/dist/components/nodes/ToolSelectorParts.d.ts +30 -0
- package/dist/components/nodes/UniversalNode.d.ts +2 -0
- package/dist/components/nodes/createContextAwareNodes.d.ts +6 -0
- package/dist/components/nodes/index.d.ts +22 -0
- package/dist/components/nodes/nodeRegistry.d.ts +13 -0
- package/dist/components/nodes/withNodeContext.d.ts +7 -0
- package/dist/components/shared/InvectLoader.d.ts +8 -0
- package/dist/components/shared/InvectLogo.d.ts +9 -0
- package/dist/components/shared/ProviderIcon.d.ts +23 -0
- package/dist/components/side-menu/side-menu.d.ts +4 -0
- package/dist/components/sidebar/BaseSidebar.d.ts +17 -0
- package/dist/components/sidebar/index.d.ts +1 -0
- package/dist/components/triggers/CronPreview.d.ts +12 -0
- package/dist/components/triggers/index.d.ts +1 -0
- package/dist/components/ui/alert-dialog.d.ts +18 -0
- package/dist/components/ui/badge.d.ts +9 -0
- package/dist/components/ui/button.d.ts +13 -0
- package/dist/components/ui/card.d.ts +9 -0
- package/dist/components/ui/codemirror-js-editor.d.ts +25 -0
- package/dist/components/ui/codemirror-json-editor.d.ts +18 -0
- package/dist/components/ui/codemirror-nunjucks-editor.d.ts +13 -0
- package/dist/components/ui/codemirror-vscode-theme.d.ts +24 -0
- package/dist/components/ui/collapsible.d.ts +6 -0
- package/dist/components/ui/command.d.ts +18 -0
- package/dist/components/ui/dialog.d.ts +18 -0
- package/dist/components/ui/dropdown-menu.d.ts +25 -0
- package/dist/components/ui/empty-state.d.ts +21 -0
- package/dist/components/ui/input.d.ts +3 -0
- package/dist/components/ui/label.d.ts +4 -0
- package/dist/components/ui/popover.d.ts +10 -0
- package/dist/components/ui/resizable.d.ts +8 -0
- package/dist/components/ui/scroll-area.d.ts +5 -0
- package/dist/components/ui/select.d.ts +18 -0
- package/dist/components/ui/separator.d.ts +4 -0
- package/dist/components/ui/slider.d.ts +4 -0
- package/dist/components/ui/switch.d.ts +3 -0
- package/dist/components/ui/table.d.ts +10 -0
- package/dist/components/ui/textarea.d.ts +3 -0
- package/dist/components/ui/tooltip.d.ts +7 -0
- package/dist/components/ui/tree-view.d.ts +107 -0
- package/dist/contexts/AgentToolCallbacksContext.d.ts +23 -0
- package/dist/contexts/ApiContext.d.ts +11 -0
- package/dist/contexts/FlowDataContext.d.ts +9 -0
- package/dist/contexts/NodeRegistryContext.d.ts +14 -0
- package/dist/contexts/PluginRegistryContext.d.ts +39 -0
- package/dist/contexts/ThemeProvider.d.ts +18 -0
- package/dist/contexts/ValidationContext.d.ts +22 -0
- package/dist/demo/DemoInvect.d.ts +11 -0
- package/dist/demo/FlowViewer.d.ts +31 -0
- package/dist/demo/demo-api-client.d.ts +33 -0
- package/dist/demo/index.d.ts +6 -0
- package/dist/demo/sample-data.d.ts +1538 -0
- package/dist/demo.d.ts +2 -0
- package/dist/demo.js +2774 -0
- package/dist/estree-ClbRfS-1.js +7076 -0
- package/dist/fonts/geist-cyrillic-wght-normal.woff2 +0 -0
- package/dist/fonts/geist-latin-ext-wght-normal.woff2 +0 -0
- package/dist/fonts/geist-latin-wght-normal.woff2 +0 -0
- package/dist/fonts/iosevka-latin-400-normal.woff2 +0 -0
- package/dist/hooks/index.d.ts +1 -0
- package/dist/hooks/use-document-title.d.ts +1 -0
- package/dist/hooks/use-flow-data.d.ts +22 -0
- package/dist/hooks/use-invect-portal-class.d.ts +21 -0
- package/dist/hooks/useFlowEditorStore.d.ts +1 -0
- package/dist/index.css +3 -0
- package/dist/index.d.ts +22 -0
- package/dist/index.js +717 -0
- package/dist/lib/utils.d.ts +2 -0
- package/dist/prettier.d.ts +13 -0
- package/dist/routes/all-flow-runs.d.ts +5 -0
- package/dist/routes/credentials.d.ts +5 -0
- package/dist/routes/flow-route-layout.d.ts +19 -0
- package/dist/routes/flow-runs.d.ts +5 -0
- package/dist/routes/flow.d.ts +5 -0
- package/dist/routes/home.d.ts +5 -0
- package/dist/services/index.d.ts +1 -0
- package/dist/standalone-C3Df7W52.js +3463 -0
- package/dist/stores/executionViewStore.d.ts +64 -0
- package/dist/stores/flow-editor.store.d.ts +137 -0
- package/dist/stores/flowEditorStore.d.ts +1 -0
- package/dist/stores/index.d.ts +2 -0
- package/dist/stores/uiStore.d.ts +45 -0
- package/dist/types/agent-tools.types.d.ts +53 -0
- package/dist/types/index.d.ts +2 -0
- package/dist/types/node-definition.types.d.ts +85 -0
- package/dist/types/plugin.types.d.ts +100 -0
- package/dist/utils/credentialBranding.d.ts +8 -0
- package/dist/utils/credentialFiltering.d.ts +20 -0
- package/dist/utils/flowTransformations.d.ts +16 -0
- package/dist/utils/layoutUtils.d.ts +23 -0
- package/dist/utils/nodeReferenceUtils.d.ts +37 -0
- package/dist/vendor.d.ts +5 -0
- package/package.json +130 -0
- package/src/.DS_Store +0 -0
- package/src/Invect.tsx +229 -0
- package/src/InvectShell.tsx +55 -0
- package/src/api/agent-tools.api.ts +23 -0
- package/src/api/client.ts +899 -0
- package/src/api/credentials.api.ts +197 -0
- package/src/api/executions.api.ts +228 -0
- package/src/api/flows.api.ts +195 -0
- package/src/api/index.ts +17 -0
- package/src/api/node-data.api.ts +167 -0
- package/src/api/query-keys.ts +44 -0
- package/src/api/triggers.api.ts +120 -0
- package/src/api/types.ts +212 -0
- package/src/api/use-flow-run-stream.ts +206 -0
- package/src/app.css +560 -0
- package/src/assets/.DS_Store +0 -0
- package/src/assets/favicon.ico +0 -0
- package/src/assets/fonts/geist-cyrillic-wght-normal.woff2 +0 -0
- package/src/assets/fonts/geist-latin-ext-wght-normal.woff2 +0 -0
- package/src/assets/fonts/geist-latin-wght-normal.woff2 +0 -0
- package/src/assets/fonts/iosevka-latin-400-normal.woff2 +0 -0
- package/src/assets/invect-branding.ts +51 -0
- package/src/assets/provider-icons/anthropic.svg +1 -0
- package/src/assets/provider-icons/anthropic_light.svg +1 -0
- package/src/assets/provider-icons/github.svg +1 -0
- package/src/assets/provider-icons/github_light.svg +1 -0
- package/src/assets/provider-icons/gmail.svg +1 -0
- package/src/assets/provider-icons/google_calendar.svg +1 -0
- package/src/assets/provider-icons/google_docs.svg +1 -0
- package/src/assets/provider-icons/google_drive.svg +1 -0
- package/src/assets/provider-icons/google_sheets.svg +1 -0
- package/src/assets/provider-icons/index.ts +55 -0
- package/src/assets/provider-icons/linear.svg +1 -0
- package/src/assets/provider-icons/openai.svg +1 -0
- package/src/assets/provider-icons/postgres.svg +1 -0
- package/src/assets/provider-icons/slack.svg +1 -0
- package/src/assets/small-loader-dark.svg +22 -0
- package/src/assets/small-loader-light.svg +22 -0
- package/src/assets/small.svg +7 -0
- package/src/components/.DS_Store +0 -0
- package/src/components/PageLayout.tsx +55 -0
- package/src/components/chat/ChatInput.tsx +115 -0
- package/src/components/chat/ChatMessageList.tsx +788 -0
- package/src/components/chat/ChatModelSelector.tsx +208 -0
- package/src/components/chat/ChatPanel.tsx +243 -0
- package/src/components/chat/ChatPromptOverlay.tsx +150 -0
- package/src/components/chat/ChatProviderSelector.tsx +135 -0
- package/src/components/chat/ChatSettingsPanel.tsx +277 -0
- package/src/components/chat/InlineCredentialSetup.tsx +343 -0
- package/src/components/chat/MarkdownRenderer.tsx +140 -0
- package/src/components/chat/chat-memory.ts +88 -0
- package/src/components/chat/chat.store.ts +479 -0
- package/src/components/chat/index.ts +5 -0
- package/src/components/chat/use-chat.ts +473 -0
- package/src/components/credentials/CreateCredentialModal.tsx +609 -0
- package/src/components/credentials/CredentialDetailDialog.tsx +882 -0
- package/src/components/credentials/EditCredentialModal.tsx +399 -0
- package/src/components/credentials/OAuth2ConnectButton.tsx +288 -0
- package/src/components/credentials/OAuth2ProviderSelector.tsx +360 -0
- package/src/components/credentials/credential-utils.ts +99 -0
- package/src/components/credentials/index.ts +10 -0
- package/src/components/dashboard/FailedRunsAlert.tsx +67 -0
- package/src/components/dashboard/FlowCard.tsx +64 -0
- package/src/components/dashboard/RecentActivityTable.tsx +92 -0
- package/src/components/dashboard/StatCard.tsx +32 -0
- package/src/components/dashboard/index.ts +5 -0
- package/src/components/dashboard/status-helpers.tsx +102 -0
- package/src/components/flow-editor/ActionsSidebar.tsx +503 -0
- package/src/components/flow-editor/FlowEditor.tsx +1002 -0
- package/src/components/flow-editor/FlowHeader.tsx +87 -0
- package/src/components/flow-editor/FlowLayout.tsx +117 -0
- package/src/components/flow-editor/ModeSwitcher.tsx +49 -0
- package/src/components/flow-editor/NodeSidebar.tsx +343 -0
- package/src/components/flow-editor/RunControls.tsx +109 -0
- package/src/components/flow-editor/ToolConfigPanel.tsx +434 -0
- package/src/components/flow-editor/ValidationPanel.tsx +167 -0
- package/src/components/flow-editor/flow-editor.store.ts +2 -0
- package/src/components/flow-editor/index.ts +6 -0
- package/src/components/flow-editor/inline-edit.tsx +111 -0
- package/src/components/flow-editor/node-config-panel/ConfigFieldWithTemplate.tsx +334 -0
- package/src/components/flow-editor/node-config-panel/CredentialCombobox.tsx +217 -0
- package/src/components/flow-editor/node-config-panel/CredentialsSection.tsx +154 -0
- package/src/components/flow-editor/node-config-panel/DroppableInput.tsx +45 -0
- package/src/components/flow-editor/node-config-panel/DynamicSelectField.tsx +223 -0
- package/src/components/flow-editor/node-config-panel/JsonPreviewPanel.tsx +134 -0
- package/src/components/flow-editor/node-config-panel/NodeConfigPanel.tsx +650 -0
- package/src/components/flow-editor/node-config-panel/NodeConfigPanelHeader.tsx +91 -0
- package/src/components/flow-editor/node-config-panel/ParametersSection.tsx +144 -0
- package/src/components/flow-editor/node-config-panel/SearchableSelectField.tsx +126 -0
- package/src/components/flow-editor/node-config-panel/SwitchCasesField.tsx +212 -0
- package/src/components/flow-editor/node-config-panel/hooks/index.ts +2 -0
- package/src/components/flow-editor/node-config-panel/hooks/use-node-config-panel-state.ts +284 -0
- package/src/components/flow-editor/node-config-panel/hooks/use-node-execution.ts +287 -0
- package/src/components/flow-editor/node-config-panel/hooks/use-upstream-slots.ts +310 -0
- package/src/components/flow-editor/node-config-panel/panels/AgentToolsPanel.tsx +837 -0
- package/src/components/flow-editor/node-config-panel/panels/ConfigurationPanel.tsx +383 -0
- package/src/components/flow-editor/node-config-panel/panels/DataMapperPane.tsx +456 -0
- package/src/components/flow-editor/node-config-panel/panels/InputPanel.tsx +338 -0
- package/src/components/flow-editor/node-config-panel/panels/OutputPanel.tsx +109 -0
- package/src/components/flow-editor/node-config-panel/panels/index.ts +4 -0
- package/src/components/flow-editor/node-config-panel/types.ts +20 -0
- package/src/components/flow-editor/node-config-panel/use-node-config-panel-store.ts +283 -0
- package/src/components/flow-editor/node-config-panel/use-node-config-state.ts +172 -0
- package/src/components/flow-editor/node-config-panel/use-run-node.ts +147 -0
- package/src/components/flow-editor/node-config-panel/utils.ts +73 -0
- package/src/components/flow-editor/serialize-to-sdk.ts +204 -0
- package/src/components/flow-editor/toolbar-context.ts +9 -0
- package/src/components/flow-editor/use-copy-paste.ts +575 -0
- package/src/components/flow-editor/use-copy-paste.types.ts +35 -0
- package/src/components/flow-editor/use-flow-editor.ts +241 -0
- package/src/components/flow-runs-table/FlowRunsTable.tsx +631 -0
- package/src/components/flow-runs-table/index.ts +1 -0
- package/src/components/flow-viewer/FlowRunsView.tsx +268 -0
- package/src/components/flow-viewer/FlowStatusView.tsx +351 -0
- package/src/components/flow-viewer/RunSelector.tsx +422 -0
- package/src/components/flow-viewer/RunsSidebar.tsx +125 -0
- package/src/components/flow-viewer/agent-tool-executions-list.tsx +298 -0
- package/src/components/flow-viewer/index.ts +1 -0
- package/src/components/flow-viewer/logs-panel.tsx +567 -0
- package/src/components/flow-viewer/use-execution-log-data.ts +374 -0
- package/src/components/graph/BatchFlowEdge.tsx +229 -0
- package/src/components/graph/LayoutSelector.tsx +42 -0
- package/src/components/graph/index.ts +61 -0
- package/src/components/graph/styleUtils.ts +375 -0
- package/src/components/nodes/.DS_Store +0 -0
- package/src/components/nodes/AgentConfigPanel.tsx +1033 -0
- package/src/components/nodes/AgentNode.tsx +298 -0
- package/src/components/nodes/AgentToolsBox.tsx +193 -0
- package/src/components/nodes/NodeAppendix.tsx +98 -0
- package/src/components/nodes/NodeStatusIndicator.tsx +74 -0
- package/src/components/nodes/NodeViewContext.tsx +45 -0
- package/src/components/nodes/ToolParamField.tsx +282 -0
- package/src/components/nodes/ToolSelectorModal.tsx +648 -0
- package/src/components/nodes/ToolSelectorParts.tsx +505 -0
- package/src/components/nodes/UniversalNode.tsx +356 -0
- package/src/components/nodes/createContextAwareNodes.ts +19 -0
- package/src/components/nodes/index.ts +45 -0
- package/src/components/nodes/nodeRegistry.ts +50 -0
- package/src/components/nodes/withNodeContext.tsx +55 -0
- package/src/components/shared/InvectLoader.tsx +59 -0
- package/src/components/shared/InvectLogo.tsx +59 -0
- package/src/components/shared/ProviderIcon.tsx +115 -0
- package/src/components/side-menu/side-menu.tsx +267 -0
- package/src/components/sidebar/BaseSidebar.tsx +148 -0
- package/src/components/sidebar/index.ts +1 -0
- package/src/components/triggers/CronPreview.tsx +243 -0
- package/src/components/triggers/index.ts +1 -0
- package/src/components/ui/alert-dialog.tsx +152 -0
- package/src/components/ui/badge.tsx +39 -0
- package/src/components/ui/button.tsx +58 -0
- package/src/components/ui/card.tsx +75 -0
- package/src/components/ui/codemirror-js-editor.tsx +432 -0
- package/src/components/ui/codemirror-json-editor.tsx +816 -0
- package/src/components/ui/codemirror-nunjucks-editor.tsx +451 -0
- package/src/components/ui/codemirror-vscode-theme.ts +243 -0
- package/src/components/ui/collapsible.tsx +12 -0
- package/src/components/ui/command.tsx +162 -0
- package/src/components/ui/dialog.tsx +140 -0
- package/src/components/ui/dropdown-menu.tsx +232 -0
- package/src/components/ui/empty-state.tsx +93 -0
- package/src/components/ui/input.tsx +26 -0
- package/src/components/ui/label.tsx +19 -0
- package/src/components/ui/popover.tsx +53 -0
- package/src/components/ui/resizable.tsx +61 -0
- package/src/components/ui/scroll-area.tsx +56 -0
- package/src/components/ui/select.tsx +179 -0
- package/src/components/ui/separator.tsx +26 -0
- package/src/components/ui/slider.tsx +58 -0
- package/src/components/ui/switch.tsx +22 -0
- package/src/components/ui/table.tsx +90 -0
- package/src/components/ui/textarea.tsx +23 -0
- package/src/components/ui/tooltip.tsx +54 -0
- package/src/components/ui/tree-view.tsx +574 -0
- package/src/contexts/AgentToolCallbacksContext.tsx +31 -0
- package/src/contexts/ApiContext.tsx +51 -0
- package/src/contexts/FlowDataContext.tsx +21 -0
- package/src/contexts/NodeRegistryContext.tsx +54 -0
- package/src/contexts/PluginRegistryContext.tsx +182 -0
- package/src/contexts/ThemeProvider.tsx +106 -0
- package/src/contexts/ValidationContext.tsx +122 -0
- package/src/demo/DemoInvect.tsx +42 -0
- package/src/demo/FlowViewer.tsx +294 -0
- package/src/demo/demo-api-client.ts +246 -0
- package/src/demo/index.ts +28 -0
- package/src/demo/sample-data.ts +1980 -0
- package/src/hooks/index.ts +1 -0
- package/src/hooks/use-document-title.ts +8 -0
- package/src/hooks/use-flow-data.ts +144 -0
- package/src/hooks/use-invect-portal-class.ts +27 -0
- package/src/hooks/useFlowEditorStore.ts +2 -0
- package/src/index.ts +70 -0
- package/src/lib/utils.ts +6 -0
- package/src/prettier.d.ts +13 -0
- package/src/routes/all-flow-runs.tsx +27 -0
- package/src/routes/credentials.tsx +362 -0
- package/src/routes/flow-route-layout.tsx +113 -0
- package/src/routes/flow-runs.tsx +22 -0
- package/src/routes/flow.tsx +22 -0
- package/src/routes/home.tsx +282 -0
- package/src/services/index.ts +6 -0
- package/src/stores/executionViewStore.ts +211 -0
- package/src/stores/flow-editor.store.ts +738 -0
- package/src/stores/flowEditorStore.ts +2 -0
- package/src/stores/index.ts +10 -0
- package/src/stores/uiStore.ts +189 -0
- package/src/types/agent-tools.types.ts +64 -0
- package/src/types/index.ts +5 -0
- package/src/types/node-definition.types.ts +104 -0
- package/src/types/plugin.types.ts +123 -0
- package/src/utils/credentialBranding.ts +116 -0
- package/src/utils/credentialFiltering.ts +68 -0
- package/src/utils/flowTransformations.ts +137 -0
- package/src/utils/layoutUtils.ts +127 -0
- package/src/utils/nodeReferenceUtils.ts +135 -0
- package/src/vendor.d.ts +7 -0
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
import type { Node, Edge } from '@xyflow/react';
|
|
2
|
+
import { InvectDefinition, FlowEdge, GraphNodeType, type MapperConfig } from '@invect/core/types';
|
|
3
|
+
|
|
4
|
+
type NodeData = Record<string, unknown> & {
|
|
5
|
+
params?: Record<string, unknown>;
|
|
6
|
+
display_name?: string;
|
|
7
|
+
reference_id?: string;
|
|
8
|
+
metadata?: Record<string, unknown>;
|
|
9
|
+
};
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Transform ReactFlow nodes and edges back to InvectDefinition format for saving
|
|
13
|
+
*/
|
|
14
|
+
export function transformToInvectDefinition(nodes: Node[], edges: Edge[]): InvectDefinition {
|
|
15
|
+
// Transform nodes: extract only the data needed for backend
|
|
16
|
+
const transformedNodes = nodes.map((node) => {
|
|
17
|
+
const data = (node.data || {}) as NodeData;
|
|
18
|
+
const params = data.params && typeof data.params === 'object' ? data.params : {};
|
|
19
|
+
const displayName =
|
|
20
|
+
typeof data.display_name === 'string' && data.display_name.trim().length > 0
|
|
21
|
+
? data.display_name.trim()
|
|
22
|
+
: undefined;
|
|
23
|
+
const referenceId =
|
|
24
|
+
typeof data.reference_id === 'string' && data.reference_id.trim().length > 0
|
|
25
|
+
? data.reference_id.trim()
|
|
26
|
+
: undefined;
|
|
27
|
+
|
|
28
|
+
const nodeType =
|
|
29
|
+
(node.type as GraphNodeType) || (data.type as GraphNodeType) || GraphNodeType.TEMPLATE_STRING;
|
|
30
|
+
|
|
31
|
+
const baseNode = {
|
|
32
|
+
id: node.id,
|
|
33
|
+
type: nodeType,
|
|
34
|
+
position: node.position ?? { x: 0, y: 0 },
|
|
35
|
+
params,
|
|
36
|
+
} as InvectDefinition['nodes'][number];
|
|
37
|
+
|
|
38
|
+
if (displayName) {
|
|
39
|
+
baseNode.label = displayName;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
// Store reference_id for input mapping
|
|
43
|
+
if (referenceId) {
|
|
44
|
+
(baseNode as Record<string, unknown>).referenceId = referenceId;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
// Preserve mapper configuration at node level
|
|
48
|
+
const mapperConfig = data.mapper as MapperConfig | undefined;
|
|
49
|
+
if (mapperConfig && mapperConfig.enabled) {
|
|
50
|
+
(baseNode as Record<string, unknown>).mapper = mapperConfig;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
return baseNode;
|
|
54
|
+
});
|
|
55
|
+
|
|
56
|
+
// Transform edges: extract only core edge properties, handling null values
|
|
57
|
+
const transformedEdges: FlowEdge[] = edges.map((edge) => ({
|
|
58
|
+
id: edge.id,
|
|
59
|
+
source: edge.source,
|
|
60
|
+
target: edge.target,
|
|
61
|
+
sourceHandle: edge.sourceHandle || undefined,
|
|
62
|
+
targetHandle: edge.targetHandle || undefined,
|
|
63
|
+
}));
|
|
64
|
+
|
|
65
|
+
return {
|
|
66
|
+
nodes: transformedNodes,
|
|
67
|
+
edges: transformedEdges,
|
|
68
|
+
};
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
/**
|
|
72
|
+
* Compute a serialized snapshot of the flow definition for dirty-checking.
|
|
73
|
+
* Uses `transformToInvectDefinition` to strip ReactFlow-internal state
|
|
74
|
+
* (selected, measured, executionStatus, etc.), then JSON.stringify for
|
|
75
|
+
* cheap string equality comparison.
|
|
76
|
+
*
|
|
77
|
+
* This is only called inside Zustand store actions (on structural mutations
|
|
78
|
+
* and saves), NOT inside selectors — so it doesn't run on every render.
|
|
79
|
+
*/
|
|
80
|
+
export function computeSnapshot(nodes: Node[], edges: Edge[]): string {
|
|
81
|
+
const definition = transformToInvectDefinition(nodes, edges);
|
|
82
|
+
return JSON.stringify(definition);
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
/**
|
|
86
|
+
* Validate that a InvectDefinition has required fields
|
|
87
|
+
*/
|
|
88
|
+
function _validateInvectDefinition(definition: InvectDefinition): {
|
|
89
|
+
isValid: boolean;
|
|
90
|
+
errors: string[];
|
|
91
|
+
} {
|
|
92
|
+
const errors: string[] = [];
|
|
93
|
+
|
|
94
|
+
if (!definition.nodes || definition.nodes.length === 0) {
|
|
95
|
+
errors.push('Flow must contain at least one node');
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
if (!definition.edges) {
|
|
99
|
+
errors.push('Flow must have an edges array (can be empty)');
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
// Validate each node has required fields
|
|
103
|
+
definition.nodes?.forEach((node, index) => {
|
|
104
|
+
if (!node.id) {
|
|
105
|
+
errors.push(`Node at index ${index} is missing an id`);
|
|
106
|
+
}
|
|
107
|
+
if (!node.type) {
|
|
108
|
+
errors.push(`Node at index ${index} is missing a type`);
|
|
109
|
+
}
|
|
110
|
+
if (!node.params) {
|
|
111
|
+
errors.push(`Node ${node.id} is missing params`);
|
|
112
|
+
}
|
|
113
|
+
});
|
|
114
|
+
|
|
115
|
+
// Validate edges reference existing nodes
|
|
116
|
+
const nodeIds = new Set(definition.nodes?.map((n) => n.id) || []);
|
|
117
|
+
definition.edges?.forEach((edge, index) => {
|
|
118
|
+
if (!edge.id) {
|
|
119
|
+
errors.push(`Edge at index ${index} is missing an id`);
|
|
120
|
+
}
|
|
121
|
+
if (!edge.source) {
|
|
122
|
+
errors.push(`Edge at index ${index} is missing a source`);
|
|
123
|
+
} else if (!nodeIds.has(edge.source)) {
|
|
124
|
+
errors.push(`Edge ${edge.id} references non-existent source node: ${edge.source}`);
|
|
125
|
+
}
|
|
126
|
+
if (!edge.target) {
|
|
127
|
+
errors.push(`Edge at index ${index} is missing a target`);
|
|
128
|
+
} else if (!nodeIds.has(edge.target)) {
|
|
129
|
+
errors.push(`Edge ${edge.id} references non-existent target node: ${edge.target}`);
|
|
130
|
+
}
|
|
131
|
+
});
|
|
132
|
+
|
|
133
|
+
return {
|
|
134
|
+
isValid: errors.length === 0,
|
|
135
|
+
errors,
|
|
136
|
+
};
|
|
137
|
+
}
|
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
// Layout utilities for automatically positioning nodes to avoid overlaps
|
|
2
|
+
import type { Node, Edge } from '@xyflow/react';
|
|
3
|
+
import {
|
|
4
|
+
applyDagreLayout as applyDagreLayoutFromPackage,
|
|
5
|
+
applyElkLayout as applyElkLayoutFromPackage,
|
|
6
|
+
type ElkLayoutNode,
|
|
7
|
+
} from '@invect/layouts';
|
|
8
|
+
|
|
9
|
+
export interface Position {
|
|
10
|
+
x: number;
|
|
11
|
+
y: number;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
// Layout algorithm options
|
|
15
|
+
export type LayoutAlgorithm = 'dagre' | 'elkjs';
|
|
16
|
+
|
|
17
|
+
export interface LayoutOptions {
|
|
18
|
+
algorithm: LayoutAlgorithm;
|
|
19
|
+
direction?: 'TB' | 'BT' | 'LR' | 'RL'; // Top-Bottom, Bottom-Top, Left-Right, Right-Left
|
|
20
|
+
nodeSpacing?: number;
|
|
21
|
+
rankSpacing?: number;
|
|
22
|
+
/** Maximum width before wrapping to a new row (only applies to LR/RL layouts, 0 = no wrapping) */
|
|
23
|
+
maxWidth?: number;
|
|
24
|
+
/** Vertical spacing between wrapped rows */
|
|
25
|
+
rowSpacing?: number;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
// Define default layout options if not already defined elsewhere
|
|
29
|
+
// These values are examples; adjust them as needed.
|
|
30
|
+
const defaultLayoutOptions = {
|
|
31
|
+
nodeWidth: 200,
|
|
32
|
+
nodeHeight: 60,
|
|
33
|
+
nodeSpacing: 70, // Default for dagre nodesep - increased for more vertical spacing
|
|
34
|
+
rankSpacing: 100, // Default for dagre ranksep
|
|
35
|
+
maxWidth: 2000, // Wrap to new row if layout exceeds this width
|
|
36
|
+
rowSpacing: 150, // Vertical spacing between wrapped rows
|
|
37
|
+
};
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* Derive explicit source handle ordering from node params.
|
|
41
|
+
* This ensures ELK gets deterministic port positions matching the rendered
|
|
42
|
+
* handle order, regardless of edge iteration order.
|
|
43
|
+
*/
|
|
44
|
+
function deriveSourceHandles(
|
|
45
|
+
node: Node,
|
|
46
|
+
): Array<{ id: string; type: 'source'; position: 'right' }> | undefined {
|
|
47
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
48
|
+
const data = node.data as Record<string, any> | undefined;
|
|
49
|
+
const nodeType = data?.type ?? node.type;
|
|
50
|
+
|
|
51
|
+
if (nodeType === 'core.switch' && Array.isArray(data?.params?.cases)) {
|
|
52
|
+
const cases = data.params.cases as Array<{ slug: string }>;
|
|
53
|
+
return [
|
|
54
|
+
...cases.map((c) => ({ id: c.slug, type: 'source' as const, position: 'right' as const })),
|
|
55
|
+
{ id: 'default', type: 'source' as const, position: 'right' as const },
|
|
56
|
+
];
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
if (nodeType === 'core.if_else') {
|
|
60
|
+
return [
|
|
61
|
+
{ id: 'true_output', type: 'source' as const, position: 'right' as const },
|
|
62
|
+
{ id: 'false_output', type: 'source' as const, position: 'right' as const },
|
|
63
|
+
];
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
return undefined;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
/**
|
|
70
|
+
* Main layout function that applies the selected algorithm
|
|
71
|
+
*/
|
|
72
|
+
export const applyLayout = async (
|
|
73
|
+
nodes: Node[],
|
|
74
|
+
edges: Edge[],
|
|
75
|
+
algorithm: LayoutAlgorithm,
|
|
76
|
+
direction: 'TB' | 'BT' | 'LR' | 'RL' = 'LR',
|
|
77
|
+
options?: LayoutOptions,
|
|
78
|
+
): Promise<{ nodes: Node[]; edges: Edge[] }> => {
|
|
79
|
+
console.log(`Applying layout: ${algorithm}, Direction: ${direction}`);
|
|
80
|
+
|
|
81
|
+
switch (algorithm) {
|
|
82
|
+
case 'dagre': {
|
|
83
|
+
// Use shared layout utility from @invect/layouts
|
|
84
|
+
const layoutedNodes = applyDagreLayoutFromPackage(nodes, edges, {
|
|
85
|
+
direction,
|
|
86
|
+
nodeSpacing: options?.nodeSpacing ?? defaultLayoutOptions.nodeSpacing,
|
|
87
|
+
rankSpacing: options?.rankSpacing ?? defaultLayoutOptions.rankSpacing,
|
|
88
|
+
nodeWidth: defaultLayoutOptions.nodeWidth,
|
|
89
|
+
nodeHeight: defaultLayoutOptions.nodeHeight,
|
|
90
|
+
maxWidth: options?.maxWidth ?? defaultLayoutOptions.maxWidth,
|
|
91
|
+
rowSpacing: options?.rowSpacing ?? defaultLayoutOptions.rowSpacing,
|
|
92
|
+
});
|
|
93
|
+
return { nodes: layoutedNodes as Node[], edges };
|
|
94
|
+
}
|
|
95
|
+
case 'elkjs': {
|
|
96
|
+
// Enrich branching nodes with explicit source handle ordering so ELK
|
|
97
|
+
// places ports in the correct top-to-bottom order (matching the rendered handles).
|
|
98
|
+
const enrichedNodes = nodes.map((node) => {
|
|
99
|
+
const sourceHandles = deriveSourceHandles(node);
|
|
100
|
+
if (sourceHandles) {
|
|
101
|
+
return { ...node, sourceHandles } as ElkLayoutNode;
|
|
102
|
+
}
|
|
103
|
+
return node;
|
|
104
|
+
}) as ElkLayoutNode[];
|
|
105
|
+
|
|
106
|
+
// Use ElkJS layout with port/handle support for better edge routing
|
|
107
|
+
// Let the @invect/layouts package defaults handle spacing and wrapping
|
|
108
|
+
const elkDirection =
|
|
109
|
+
direction === 'LR'
|
|
110
|
+
? 'RIGHT'
|
|
111
|
+
: direction === 'RL'
|
|
112
|
+
? 'LEFT'
|
|
113
|
+
: direction === 'TB'
|
|
114
|
+
? 'DOWN'
|
|
115
|
+
: 'UP';
|
|
116
|
+
const layoutedNodes = await applyElkLayoutFromPackage(enrichedNodes, edges, {
|
|
117
|
+
direction: elkDirection,
|
|
118
|
+
// Only pass nodeWidth/nodeHeight, let package defaults handle everything else
|
|
119
|
+
nodeWidth: defaultLayoutOptions.nodeWidth,
|
|
120
|
+
nodeHeight: defaultLayoutOptions.nodeHeight,
|
|
121
|
+
});
|
|
122
|
+
return { nodes: layoutedNodes as Node[], edges };
|
|
123
|
+
}
|
|
124
|
+
default:
|
|
125
|
+
return { nodes, edges }; // No layout applied
|
|
126
|
+
}
|
|
127
|
+
};
|
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Utilities for generating and managing node reference IDs
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
const MAX_REFERENCE_ID_LENGTH = 22;
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Convert a display name to a snake_case reference ID
|
|
9
|
+
* Only allows alphanumeric characters and underscores
|
|
10
|
+
* Truncates to MAX_REFERENCE_ID_LENGTH chars
|
|
11
|
+
*/
|
|
12
|
+
export function toReferenceId(displayName: string): string {
|
|
13
|
+
const baseId = displayName
|
|
14
|
+
.toLowerCase()
|
|
15
|
+
.replace(/[^a-z0-9\s]/g, '') // Remove non-alphanumeric chars except spaces
|
|
16
|
+
.trim()
|
|
17
|
+
.replace(/\s+/g, '_'); // Replace spaces with underscores
|
|
18
|
+
|
|
19
|
+
return truncateReferenceId(baseId);
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* Truncate a reference ID to max length while preserving any numeric suffix
|
|
24
|
+
* e.g., "some_really_long_node_name_2" → "some_really_long_no_2"
|
|
25
|
+
*/
|
|
26
|
+
function truncateReferenceId(refId: string, suffix?: string): string {
|
|
27
|
+
const maxLen = MAX_REFERENCE_ID_LENGTH;
|
|
28
|
+
|
|
29
|
+
// If already within limit, return as-is
|
|
30
|
+
if (refId.length <= maxLen) {
|
|
31
|
+
return refId;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
// If there's a suffix (like "_2"), ensure it fits
|
|
35
|
+
if (suffix) {
|
|
36
|
+
const suffixWithUnderscore = `_${suffix}`;
|
|
37
|
+
const availableForBase = maxLen - suffixWithUnderscore.length;
|
|
38
|
+
if (availableForBase <= 0) {
|
|
39
|
+
// Suffix itself is too long, just truncate the whole thing
|
|
40
|
+
return refId.substring(0, maxLen);
|
|
41
|
+
}
|
|
42
|
+
return refId.substring(0, availableForBase) + suffixWithUnderscore;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
// No suffix, just truncate
|
|
46
|
+
return refId.substring(0, maxLen);
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* Generate a unique display name for a new node, avoiding conflicts
|
|
51
|
+
* Returns names like "AI Model", "AI Model 2", "AI Model 3", etc.
|
|
52
|
+
*/
|
|
53
|
+
export function generateUniqueDisplayName(
|
|
54
|
+
baseDisplayName: string,
|
|
55
|
+
existingNodes: { data?: { display_name?: string } }[],
|
|
56
|
+
): string {
|
|
57
|
+
const existingNames = new Set(
|
|
58
|
+
existingNodes
|
|
59
|
+
.map((node) => node.data?.display_name)
|
|
60
|
+
.filter((name): name is string => typeof name === 'string'),
|
|
61
|
+
);
|
|
62
|
+
|
|
63
|
+
// If base name doesn't exist, use it
|
|
64
|
+
if (!existingNames.has(baseDisplayName)) {
|
|
65
|
+
return baseDisplayName;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
// Try incrementing numbers until we find a unique name
|
|
69
|
+
let counter = 2;
|
|
70
|
+
while (true) {
|
|
71
|
+
const candidateName = `${baseDisplayName} ${counter}`;
|
|
72
|
+
if (!existingNames.has(candidateName)) {
|
|
73
|
+
return candidateName;
|
|
74
|
+
}
|
|
75
|
+
counter++;
|
|
76
|
+
// Safety limit to prevent infinite loops
|
|
77
|
+
if (counter > 1000) {
|
|
78
|
+
return `${baseDisplayName} ${Date.now()}`;
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
/**
|
|
84
|
+
* Generate a unique reference ID for a new node, avoiding conflicts
|
|
85
|
+
* Truncates to MAX_REFERENCE_ID_LENGTH while preserving the increment suffix
|
|
86
|
+
*/
|
|
87
|
+
export function generateUniqueReferenceId(
|
|
88
|
+
displayName: string,
|
|
89
|
+
existingNodes: { data?: { reference_id?: string } }[],
|
|
90
|
+
): string {
|
|
91
|
+
const baseReferenceId = toReferenceId(displayName);
|
|
92
|
+
|
|
93
|
+
const existingReferenceIds = new Set(
|
|
94
|
+
existingNodes
|
|
95
|
+
.map((node) => node.data?.reference_id)
|
|
96
|
+
.filter((id): id is string => typeof id === 'string'),
|
|
97
|
+
);
|
|
98
|
+
|
|
99
|
+
// If base reference ID doesn't exist, use it (already truncated by toReferenceId)
|
|
100
|
+
if (!existingReferenceIds.has(baseReferenceId)) {
|
|
101
|
+
return baseReferenceId;
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
// Try incrementing numbers until we find a unique reference ID
|
|
105
|
+
let counter = 2;
|
|
106
|
+
while (true) {
|
|
107
|
+
// Truncate base to fit the counter suffix within max length
|
|
108
|
+
const suffix = String(counter);
|
|
109
|
+
const candidateId = truncateReferenceId(baseReferenceId, suffix);
|
|
110
|
+
|
|
111
|
+
if (!existingReferenceIds.has(candidateId)) {
|
|
112
|
+
return candidateId;
|
|
113
|
+
}
|
|
114
|
+
counter++;
|
|
115
|
+
// Safety limit to prevent infinite loops
|
|
116
|
+
if (counter > 1000) {
|
|
117
|
+
const timestampSuffix = String(Date.now()).slice(-6);
|
|
118
|
+
return truncateReferenceId(baseReferenceId, timestampSuffix);
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
/**
|
|
124
|
+
* Update reference ID when display name changes
|
|
125
|
+
* Ensures uniqueness among existing nodes
|
|
126
|
+
*/
|
|
127
|
+
export function updateReferenceIdForDisplayName(
|
|
128
|
+
newDisplayName: string,
|
|
129
|
+
currentNodeId: string,
|
|
130
|
+
existingNodes: { id: string; data?: { reference_id?: string } }[],
|
|
131
|
+
): string {
|
|
132
|
+
// Filter out the current node when checking for conflicts
|
|
133
|
+
const otherNodes = existingNodes.filter((node) => node.id !== currentNodeId);
|
|
134
|
+
return generateUniqueReferenceId(newDisplayName, otherNodes);
|
|
135
|
+
}
|