@d34dman/flowdrop 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.
Files changed (46) hide show
  1. package/README.md +293 -0
  2. package/dist/adapters/WorkflowAdapter.d.ts +166 -0
  3. package/dist/adapters/WorkflowAdapter.js +337 -0
  4. package/dist/api/client.d.ts +79 -0
  5. package/dist/api/client.js +208 -0
  6. package/dist/app.css +0 -0
  7. package/dist/clients/ApiClient.d.ts +203 -0
  8. package/dist/clients/ApiClient.js +212 -0
  9. package/dist/components/App.svelte +237 -0
  10. package/dist/components/App.svelte.d.ts +3 -0
  11. package/dist/components/CanvasBanner.svelte +51 -0
  12. package/dist/components/CanvasBanner.svelte.d.ts +22 -0
  13. package/dist/components/LoadingSpinner.svelte +36 -0
  14. package/dist/components/LoadingSpinner.svelte.d.ts +8 -0
  15. package/dist/components/Node.svelte +38 -0
  16. package/dist/components/Node.svelte.d.ts +4 -0
  17. package/dist/components/NodeSidebar.svelte +500 -0
  18. package/dist/components/NodeSidebar.svelte.d.ts +9 -0
  19. package/dist/components/WorkflowEditor.svelte +542 -0
  20. package/dist/components/WorkflowEditor.svelte.d.ts +10 -0
  21. package/dist/components/WorkflowNode.svelte +558 -0
  22. package/dist/components/WorkflowNode.svelte.d.ts +11 -0
  23. package/dist/data/samples.d.ts +17 -0
  24. package/dist/data/samples.js +1193 -0
  25. package/dist/examples/adapter-usage.d.ts +66 -0
  26. package/dist/examples/adapter-usage.js +138 -0
  27. package/dist/examples/api-client-usage.d.ts +31 -0
  28. package/dist/examples/api-client-usage.js +241 -0
  29. package/dist/index.d.ts +19 -0
  30. package/dist/index.js +27 -0
  31. package/dist/services/api.d.ts +110 -0
  32. package/dist/services/api.js +149 -0
  33. package/dist/services/workflowStorage.d.ts +37 -0
  34. package/dist/services/workflowStorage.js +116 -0
  35. package/dist/styles/base.css +858 -0
  36. package/dist/svelte-app.d.ts +17 -0
  37. package/dist/svelte-app.js +30 -0
  38. package/dist/types/index.d.ts +179 -0
  39. package/dist/types/index.js +4 -0
  40. package/dist/utils/colors.d.ts +121 -0
  41. package/dist/utils/colors.js +240 -0
  42. package/dist/utils/connections.d.ts +47 -0
  43. package/dist/utils/connections.js +240 -0
  44. package/dist/utils/icons.d.ts +102 -0
  45. package/dist/utils/icons.js +149 -0
  46. package/package.json +99 -0
@@ -0,0 +1,240 @@
1
+ /**
2
+ * Connection validation utilities for FlowDrop
3
+ */
4
+ /**
5
+ * Check if two data types are compatible for connection
6
+ */
7
+ export function areDataTypesCompatible(outputType, inputType) {
8
+ // Direct type matches
9
+ if (outputType === inputType)
10
+ return true;
11
+ // String can be converted to most types
12
+ if (outputType === "string") {
13
+ return ["string", "number", "boolean"].includes(inputType);
14
+ }
15
+ // Number can be converted to string
16
+ if (outputType === "number") {
17
+ return ["string", "number"].includes(inputType);
18
+ }
19
+ // Boolean can be converted to string
20
+ if (outputType === "boolean") {
21
+ return ["string", "boolean"].includes(inputType);
22
+ }
23
+ // Object can be converted to string (JSON)
24
+ if (outputType === "object") {
25
+ return ["string", "object"].includes(inputType);
26
+ }
27
+ // Array can be converted to string (JSON)
28
+ if (outputType === "array") {
29
+ return ["string", "array"].includes(inputType);
30
+ }
31
+ return false;
32
+ }
33
+ /**
34
+ * Get all possible connections from a source node to target nodes
35
+ */
36
+ export function getPossibleConnections(sourceNode, targetNodes, nodeTypes) {
37
+ const sourceMetadata = nodeTypes.find(nt => nt.id === sourceNode.data.metadata.id);
38
+ if (!sourceMetadata)
39
+ return [];
40
+ const possibleConnections = [];
41
+ // Get all output ports from source node
42
+ const sourceOutputs = sourceMetadata.outputs;
43
+ // Check each target node
44
+ for (const targetNode of targetNodes) {
45
+ if (targetNode.id === sourceNode.id)
46
+ continue; // Skip self-connection
47
+ const targetMetadata = nodeTypes.find(nt => nt.id === targetNode.data.metadata.id);
48
+ if (!targetMetadata)
49
+ continue;
50
+ // Get all input ports from target node
51
+ const targetInputs = targetMetadata.inputs;
52
+ // Check each output-input combination
53
+ for (const sourcePort of sourceOutputs) {
54
+ for (const targetPort of targetInputs) {
55
+ const compatible = areDataTypesCompatible(sourcePort.dataType, targetPort.dataType);
56
+ possibleConnections.push({
57
+ sourceNodeId: sourceNode.id,
58
+ sourcePortId: sourcePort.id,
59
+ sourcePort,
60
+ targetNodeId: targetNode.id,
61
+ targetPortId: targetPort.id,
62
+ targetPort,
63
+ compatible
64
+ });
65
+ }
66
+ }
67
+ }
68
+ return possibleConnections;
69
+ }
70
+ /**
71
+ * Validate if a specific connection is valid
72
+ */
73
+ export function validateConnection(sourceNodeId, sourcePortId, targetNodeId, targetPortId, nodes, nodeTypes) {
74
+ // Check if nodes exist
75
+ const sourceNode = nodes.find(n => n.id === sourceNodeId);
76
+ const targetNode = nodes.find(n => n.id === targetNodeId);
77
+ if (!sourceNode) {
78
+ return { valid: false, error: "Source node not found" };
79
+ }
80
+ if (!targetNode) {
81
+ return { valid: false, error: "Target node not found" };
82
+ }
83
+ // Check for self-connection
84
+ if (sourceNodeId === targetNodeId) {
85
+ return { valid: false, error: "Cannot connect node to itself" };
86
+ }
87
+ // Get node metadata
88
+ const sourceMetadata = nodeTypes.find(nt => nt.id === sourceNode.data.metadata.id);
89
+ const targetMetadata = nodeTypes.find(nt => nt.id === targetNode.data.metadata.id);
90
+ if (!sourceMetadata || !targetMetadata) {
91
+ console.log("Metadata lookup failed:", {
92
+ sourceNodeId,
93
+ targetNodeId,
94
+ sourceMetadataId: sourceNode.data.metadata.id,
95
+ targetMetadataId: targetNode.data.metadata.id,
96
+ availableNodeTypes: nodeTypes.map(nt => nt.id)
97
+ });
98
+ return { valid: false, error: "Node metadata not found" };
99
+ }
100
+ // Find ports
101
+ const sourcePort = sourceMetadata.outputs.find(p => p.id === sourcePortId);
102
+ const targetPort = targetMetadata.inputs.find(p => p.id === targetPortId);
103
+ if (!sourcePort) {
104
+ return { valid: false, error: "Source port not found" };
105
+ }
106
+ if (!targetPort) {
107
+ return { valid: false, error: "Target port not found" };
108
+ }
109
+ // Check data type compatibility
110
+ if (!areDataTypesCompatible(sourcePort.dataType, targetPort.dataType)) {
111
+ return {
112
+ valid: false,
113
+ error: `Incompatible data types: ${sourcePort.dataType} cannot connect to ${targetPort.dataType}`
114
+ };
115
+ }
116
+ return { valid: true };
117
+ }
118
+ /**
119
+ * Get connection suggestions for a node
120
+ */
121
+ export function getConnectionSuggestions(nodeId, nodes, nodeTypes) {
122
+ const node = nodes.find(n => n.id === nodeId);
123
+ if (!node)
124
+ return [];
125
+ const metadata = nodeTypes.find(nt => nt.id === node.data.metadata.id);
126
+ if (!metadata)
127
+ return [];
128
+ const suggestions = [];
129
+ // Get all other nodes
130
+ const otherNodes = nodes.filter(n => n.id !== nodeId);
131
+ for (const otherNode of otherNodes) {
132
+ const otherMetadata = nodeTypes.find(nt => nt.id === otherNode.data.metadata.id);
133
+ if (!otherMetadata)
134
+ continue;
135
+ // Check outputs from other nodes to inputs of current node
136
+ for (const output of otherMetadata.outputs) {
137
+ for (const input of metadata.inputs) {
138
+ const compatible = areDataTypesCompatible(output.dataType, input.dataType);
139
+ suggestions.push({
140
+ nodeId: otherNode.id,
141
+ nodeName: otherNode.data.label,
142
+ portId: output.id,
143
+ portName: output.name,
144
+ portType: "output",
145
+ dataType: output.dataType,
146
+ compatible
147
+ });
148
+ }
149
+ }
150
+ // Check outputs from current node to inputs of other nodes
151
+ for (const output of metadata.outputs) {
152
+ for (const input of otherMetadata.inputs) {
153
+ const compatible = areDataTypesCompatible(output.dataType, input.dataType);
154
+ suggestions.push({
155
+ nodeId: otherNode.id,
156
+ nodeName: otherNode.data.label,
157
+ portId: input.id,
158
+ portName: input.name,
159
+ portType: "input",
160
+ dataType: input.dataType,
161
+ compatible
162
+ });
163
+ }
164
+ }
165
+ }
166
+ return suggestions;
167
+ }
168
+ /**
169
+ * Check if a workflow has any cycles (prevent infinite loops)
170
+ */
171
+ export function hasCycles(nodes, edges) {
172
+ const visited = new Set();
173
+ const recursionStack = new Set();
174
+ function hasCycleUtil(nodeId) {
175
+ if (recursionStack.has(nodeId))
176
+ return true;
177
+ if (visited.has(nodeId))
178
+ return false;
179
+ visited.add(nodeId);
180
+ recursionStack.add(nodeId);
181
+ // Get all outgoing edges from this node
182
+ const outgoingEdges = edges.filter(e => e.source === nodeId);
183
+ for (const edge of outgoingEdges) {
184
+ if (hasCycleUtil(edge.target))
185
+ return true;
186
+ }
187
+ recursionStack.delete(nodeId);
188
+ return false;
189
+ }
190
+ // Check each node
191
+ for (const node of nodes) {
192
+ if (!visited.has(node.id)) {
193
+ if (hasCycleUtil(node.id))
194
+ return true;
195
+ }
196
+ }
197
+ return false;
198
+ }
199
+ /**
200
+ * Get the execution order for a workflow (topological sort)
201
+ */
202
+ export function getExecutionOrder(nodes, edges) {
203
+ const inDegree = new Map();
204
+ const graph = new Map();
205
+ // Initialize
206
+ for (const node of nodes) {
207
+ inDegree.set(node.id, 0);
208
+ graph.set(node.id, []);
209
+ }
210
+ // Build graph and calculate in-degrees
211
+ for (const edge of edges) {
212
+ const current = inDegree.get(edge.target) || 0;
213
+ inDegree.set(edge.target, current + 1);
214
+ const neighbors = graph.get(edge.source) || [];
215
+ neighbors.push(edge.target);
216
+ graph.set(edge.source, neighbors);
217
+ }
218
+ // Topological sort
219
+ const queue = [];
220
+ const result = [];
221
+ // Add nodes with no incoming edges
222
+ for (const [nodeId, degree] of inDegree) {
223
+ if (degree === 0) {
224
+ queue.push(nodeId);
225
+ }
226
+ }
227
+ while (queue.length > 0) {
228
+ const nodeId = queue.shift();
229
+ result.push(nodeId);
230
+ const neighbors = graph.get(nodeId) || [];
231
+ for (const neighbor of neighbors) {
232
+ const degree = inDegree.get(neighbor) - 1;
233
+ inDegree.set(neighbor, degree);
234
+ if (degree === 0) {
235
+ queue.push(neighbor);
236
+ }
237
+ }
238
+ }
239
+ return result;
240
+ }
@@ -0,0 +1,102 @@
1
+ /**
2
+ * Centralized icon management for FlowDrop
3
+ * Ensures consistent icon usage across all components
4
+ */
5
+ import type { NodeCategory } from "../types/index.js";
6
+ /**
7
+ * Default icons for different contexts
8
+ */
9
+ export declare const DEFAULT_ICONS: {
10
+ readonly NODE: "mdi:cube";
11
+ readonly CATEGORY: "mdi:folder";
12
+ readonly ADD: "mdi:plus";
13
+ readonly REMOVE: "mdi:minus";
14
+ readonly EDIT: "mdi:pencil";
15
+ readonly SAVE: "mdi:content-save";
16
+ readonly LOAD: "mdi:folder-open";
17
+ readonly EXPORT: "mdi:download";
18
+ readonly IMPORT: "mdi:upload";
19
+ readonly SEARCH: "mdi:magnify";
20
+ readonly CLOSE: "mdi:close";
21
+ readonly SETTINGS: "mdi:cog";
22
+ readonly HELP: "mdi:help-circle";
23
+ readonly SUCCESS: "mdi:check-circle";
24
+ readonly ERROR: "mdi:alert-circle";
25
+ readonly WARNING: "mdi:alert";
26
+ readonly INFO: "mdi:information";
27
+ readonly LOADING: "mdi:loading";
28
+ readonly HOME: "mdi:home";
29
+ readonly BACK: "mdi:arrow-left";
30
+ readonly FORWARD: "mdi:arrow-right";
31
+ readonly UP: "mdi:arrow-up";
32
+ readonly DOWN: "mdi:arrow-down";
33
+ readonly WORKFLOW: "mdi:graph";
34
+ readonly NODE_ADD: "mdi:plus-circle";
35
+ readonly NODE_DELETE: "mdi:minus-circle";
36
+ readonly CONNECTION: "mdi:connection";
37
+ readonly DATA: "mdi:database";
38
+ readonly FILE: "mdi:file";
39
+ readonly TEXT: "mdi:text";
40
+ readonly JSON: "mdi:code-json";
41
+ readonly MODEL: "mdi:chip";
42
+ readonly BRAIN: "mdi:brain";
43
+ readonly VECTOR: "mdi:vector-point";
44
+ readonly ROBOT: "mdi:robot";
45
+ readonly TOOL: "mdi:wrench";
46
+ readonly CALCULATOR: "mdi:calculator";
47
+ readonly CLOCK: "mdi:clock";
48
+ readonly CHAT: "mdi:chat";
49
+ readonly MESSAGE: "mdi:message";
50
+ readonly EMAIL: "mdi:email";
51
+ readonly WEBHOOK: "mdi:webhook";
52
+ readonly STORAGE: "mdi:database";
53
+ readonly MEMORY: "mdi:memory";
54
+ readonly CACHE: "mdi:cached";
55
+ readonly PROCESS: "mdi:cog";
56
+ readonly FILTER: "mdi:filter";
57
+ readonly SORT: "mdi:sort";
58
+ readonly TRANSFORM: "mdi:transform";
59
+ readonly LOGIC: "mdi:git-branch";
60
+ readonly CONDITION: "mdi:source-fork";
61
+ readonly LOOP: "mdi:loop";
62
+ readonly API: "mdi:api";
63
+ readonly LINK: "mdi:link";
64
+ readonly PLUGIN: "mdi:puzzle";
65
+ readonly BUNDLE: "mdi:package-variant";
66
+ };
67
+ /**
68
+ * Category-specific icons matching Langflow's visual style
69
+ */
70
+ export declare const CATEGORY_ICONS: Record<NodeCategory, string>;
71
+ /**
72
+ * Get the appropriate icon for a node
73
+ * @param nodeIcon - The node's specific icon
74
+ * @param category - The node's category
75
+ * @returns The icon to use
76
+ */
77
+ export declare function getNodeIcon(nodeIcon?: string, category?: NodeCategory): string;
78
+ /**
79
+ * Get the appropriate icon for a category
80
+ * @param category - The category
81
+ * @returns The icon to use
82
+ */
83
+ export declare function getCategoryIcon(category: NodeCategory): string;
84
+ /**
85
+ * Get a default icon by key
86
+ * @param key - The icon key from DEFAULT_ICONS
87
+ * @returns The icon string
88
+ */
89
+ export declare function getDefaultIcon(key: keyof typeof DEFAULT_ICONS): string;
90
+ /**
91
+ * Validate if an icon string is properly formatted
92
+ * @param icon - The icon string to validate
93
+ * @returns True if valid, false otherwise
94
+ */
95
+ export declare function isValidIcon(icon: string): boolean;
96
+ /**
97
+ * Get a fallback icon if the provided icon is invalid
98
+ * @param icon - The icon to check
99
+ * @param fallback - The fallback icon to use
100
+ * @returns The valid icon string
101
+ */
102
+ export declare function getValidIcon(icon: string, fallback?: string): string;
@@ -0,0 +1,149 @@
1
+ /**
2
+ * Centralized icon management for FlowDrop
3
+ * Ensures consistent icon usage across all components
4
+ */
5
+ /**
6
+ * Default icons for different contexts
7
+ */
8
+ export const DEFAULT_ICONS = {
9
+ // Node fallback icons
10
+ NODE: "mdi:cube",
11
+ CATEGORY: "mdi:folder",
12
+ // UI action icons
13
+ ADD: "mdi:plus",
14
+ REMOVE: "mdi:minus",
15
+ EDIT: "mdi:pencil",
16
+ SAVE: "mdi:content-save",
17
+ LOAD: "mdi:folder-open",
18
+ EXPORT: "mdi:download",
19
+ IMPORT: "mdi:upload",
20
+ SEARCH: "mdi:magnify",
21
+ CLOSE: "mdi:close",
22
+ SETTINGS: "mdi:cog",
23
+ HELP: "mdi:help-circle",
24
+ // Status icons
25
+ SUCCESS: "mdi:check-circle",
26
+ ERROR: "mdi:alert-circle",
27
+ WARNING: "mdi:alert",
28
+ INFO: "mdi:information",
29
+ LOADING: "mdi:loading",
30
+ // Navigation icons
31
+ HOME: "mdi:home",
32
+ BACK: "mdi:arrow-left",
33
+ FORWARD: "mdi:arrow-right",
34
+ UP: "mdi:arrow-up",
35
+ DOWN: "mdi:arrow-down",
36
+ // Workflow icons
37
+ WORKFLOW: "mdi:graph",
38
+ NODE_ADD: "mdi:plus-circle",
39
+ NODE_DELETE: "mdi:minus-circle",
40
+ CONNECTION: "mdi:connection",
41
+ // Data icons
42
+ DATA: "mdi:database",
43
+ FILE: "mdi:file",
44
+ TEXT: "mdi:text",
45
+ JSON: "mdi:code-json",
46
+ // Model and processing icons
47
+ MODEL: "mdi:chip",
48
+ BRAIN: "mdi:brain",
49
+ VECTOR: "mdi:vector-point",
50
+ ROBOT: "mdi:robot",
51
+ // Tool icons
52
+ TOOL: "mdi:wrench",
53
+ CALCULATOR: "mdi:calculator",
54
+ CLOCK: "mdi:clock",
55
+ // Communication icons
56
+ CHAT: "mdi:chat",
57
+ MESSAGE: "mdi:message",
58
+ EMAIL: "mdi:email",
59
+ WEBHOOK: "mdi:webhook",
60
+ // Storage icons
61
+ STORAGE: "mdi:database",
62
+ MEMORY: "mdi:memory",
63
+ CACHE: "mdi:cached",
64
+ // Processing icons
65
+ PROCESS: "mdi:cog",
66
+ FILTER: "mdi:filter",
67
+ SORT: "mdi:sort",
68
+ TRANSFORM: "mdi:transform",
69
+ // Logic icons
70
+ LOGIC: "mdi:git-branch",
71
+ CONDITION: "mdi:source-fork",
72
+ LOOP: "mdi:loop",
73
+ // Integration icons
74
+ API: "mdi:api",
75
+ LINK: "mdi:link",
76
+ PLUGIN: "mdi:puzzle",
77
+ BUNDLE: "mdi:package-variant"
78
+ };
79
+ /**
80
+ * Category-specific icons matching Langflow's visual style
81
+ */
82
+ export const CATEGORY_ICONS = {
83
+ "inputs": "mdi:arrow-down-circle",
84
+ "outputs": "mdi:arrow-up-circle",
85
+ "prompts": "mdi:message-text",
86
+ "models": "mdi:robot",
87
+ "processing": "mdi:cog",
88
+ "logic": "mdi:git-branch",
89
+ "data": "mdi:database",
90
+ "helpers": "mdi:help-circle",
91
+ "tools": "mdi:wrench",
92
+ "vector stores": "mdi:vector-square",
93
+ "embeddings": "mdi:vector-point",
94
+ "memories": "mdi:brain",
95
+ "agents": "mdi:account-cog",
96
+ "bundles": "mdi:package-variant"
97
+ };
98
+ /**
99
+ * Get the appropriate icon for a node
100
+ * @param nodeIcon - The node's specific icon
101
+ * @param category - The node's category
102
+ * @returns The icon to use
103
+ */
104
+ export function getNodeIcon(nodeIcon, category) {
105
+ // If node has a specific icon, use it
106
+ if (nodeIcon) {
107
+ return nodeIcon;
108
+ }
109
+ // If category is provided, use category icon
110
+ if (category && CATEGORY_ICONS[category]) {
111
+ return CATEGORY_ICONS[category];
112
+ }
113
+ // Fallback to default node icon
114
+ return DEFAULT_ICONS.NODE;
115
+ }
116
+ /**
117
+ * Get the appropriate icon for a category
118
+ * @param category - The category
119
+ * @returns The icon to use
120
+ */
121
+ export function getCategoryIcon(category) {
122
+ return CATEGORY_ICONS[category] || DEFAULT_ICONS.CATEGORY;
123
+ }
124
+ /**
125
+ * Get a default icon by key
126
+ * @param key - The icon key from DEFAULT_ICONS
127
+ * @returns The icon string
128
+ */
129
+ export function getDefaultIcon(key) {
130
+ return DEFAULT_ICONS[key];
131
+ }
132
+ /**
133
+ * Validate if an icon string is properly formatted
134
+ * @param icon - The icon string to validate
135
+ * @returns True if valid, false otherwise
136
+ */
137
+ export function isValidIcon(icon) {
138
+ // Check if it's a valid iconify format (e.g., "mdi:icon-name")
139
+ return /^[a-z-]+:[a-z-]+$/.test(icon);
140
+ }
141
+ /**
142
+ * Get a fallback icon if the provided icon is invalid
143
+ * @param icon - The icon to check
144
+ * @param fallback - The fallback icon to use
145
+ * @returns The valid icon string
146
+ */
147
+ export function getValidIcon(icon, fallback = DEFAULT_ICONS.NODE) {
148
+ return isValidIcon(icon) ? icon : fallback;
149
+ }
package/package.json ADDED
@@ -0,0 +1,99 @@
1
+ {
2
+ "name": "@d34dman/flowdrop",
3
+ "version": "0.0.1",
4
+ "scripts": {
5
+ "dev": "vite dev",
6
+ "build": "vite build && npm run prepack",
7
+ "watch:build": "npm-watch build",
8
+ "preview": "vite preview",
9
+ "prepare": "svelte-kit sync || echo ''",
10
+ "prepack": "svelte-kit sync && svelte-package && publint",
11
+ "check": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json",
12
+ "check:watch": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json --watch",
13
+ "lint": "eslint . && prettier --check .",
14
+ "test:unit": "vitest",
15
+ "test": "npm run test:unit -- --run && npm run test:e2e",
16
+ "test:e2e": "playwright test",
17
+ "format": "prettier --write .",
18
+ "storybook": "storybook dev -p 6006",
19
+ "build-storybook": "storybook build"
20
+ },
21
+ "watch": {
22
+ "build": {
23
+ "ignore": "build",
24
+ "patterns": [
25
+ "src"
26
+ ],
27
+ "extensions": "js,ts,svelte,html,css,svg",
28
+ "quiet": true,
29
+ "legacyWatch": true,
30
+ "delay": 2500,
31
+ "runOnChangeOnly": false
32
+ }
33
+ },
34
+ "files": [
35
+ "dist",
36
+ "!dist/**/*.test.*",
37
+ "!dist/**/*.spec.*"
38
+ ],
39
+ "sideEffects": [
40
+ "**/*.css"
41
+ ],
42
+ "svelte": "./dist/index.js",
43
+ "types": "./dist/index.d.ts",
44
+ "type": "module",
45
+ "exports": {
46
+ ".": {
47
+ "types": "./dist/index.d.ts",
48
+ "svelte": "./dist/index.js"
49
+ }
50
+ },
51
+ "peerDependencies": {
52
+ "svelte": "^5.0.0"
53
+ },
54
+ "devDependencies": {
55
+ "@chromatic-com/storybook": "^4.0.1",
56
+ "@eslint/compat": "^1.2.5",
57
+ "@eslint/js": "^9.18.0",
58
+ "@iconify/svelte": "^5.0.0",
59
+ "@playwright/test": "^1.49.1",
60
+ "@storybook/addon-a11y": "^9.0.15",
61
+ "@storybook/addon-docs": "^9.0.15",
62
+ "@storybook/addon-svelte-csf": "^5.0.4",
63
+ "@storybook/addon-vitest": "^9.0.15",
64
+ "@storybook/sveltekit": "^9.0.15",
65
+ "@sveltejs/adapter-auto": "^6.0.0",
66
+ "@sveltejs/kit": "^2.16.0",
67
+ "@sveltejs/package": "^2.0.0",
68
+ "@sveltejs/vite-plugin-svelte": "^5.0.0",
69
+ "@types/node": "^20",
70
+ "@vitest/browser": "^3.2.3",
71
+ "eslint": "^9.18.0",
72
+ "eslint-config-prettier": "^10.0.1",
73
+ "eslint-plugin-storybook": "^9.0.15",
74
+ "eslint-plugin-svelte": "^3.0.0",
75
+ "globals": "^16.0.0",
76
+ "playwright": "^1.53.0",
77
+ "prettier": "^3.4.2",
78
+ "prettier-plugin-svelte": "^3.3.3",
79
+ "publint": "^0.3.2",
80
+ "storybook": "^9.0.15",
81
+ "svelte": "^5.0.0",
82
+ "svelte-check": "^4.0.0",
83
+ "terser": "^5.43.1",
84
+ "typescript": "^5.0.0",
85
+ "typescript-eslint": "^8.20.0",
86
+ "vite": "^6.2.6",
87
+ "vite-plugin-devtools-json": "^0.2.1",
88
+ "vitest": "^3.2.3",
89
+ "vitest-browser-svelte": "^0.1.0"
90
+ },
91
+ "keywords": [
92
+ "svelte"
93
+ ],
94
+ "dependencies": {
95
+ "@types/uuid": "^10.0.0",
96
+ "@xyflow/svelte": "~1.2",
97
+ "uuid": "^11.1.0"
98
+ }
99
+ }