flowscale 1.1.0 → 1.3.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.
package/dist/types.d.ts CHANGED
@@ -38,12 +38,21 @@ export interface ExecuteWorkflowResponse {
38
38
  run_id: string;
39
39
  };
40
40
  }
41
+ export interface RunProgress {
42
+ percentage?: number;
43
+ current_node?: string;
44
+ }
41
45
  export interface GetOutputResponse {
42
46
  status: string;
43
47
  data: {
44
- download_url: string;
45
- generation_status: string;
48
+ run_id?: string;
49
+ download_url?: string;
50
+ file_content?: any;
51
+ generation_status?: string;
52
+ progress?: RunProgress;
53
+ errors?: string;
46
54
  };
55
+ errors?: string;
47
56
  }
48
57
  export interface GetAllOutputsResponse {
49
58
  status: string;
@@ -53,6 +62,48 @@ export interface GetAllOutputsResponse {
53
62
  generation_status: string;
54
63
  }>;
55
64
  }
65
+ export type ExecuteWorkflowAsyncIntermediateType = 'workflow_submitted' | 'run_status' | 'output_status' | 'poll_retry' | 'completed';
66
+ export interface ExecuteWorkflowAsyncIntermediateResponse {
67
+ type: ExecuteWorkflowAsyncIntermediateType;
68
+ timestamp: string;
69
+ run_id?: string;
70
+ workflow_id?: string;
71
+ attempt?: number;
72
+ run_status?: string;
73
+ output_name?: string;
74
+ output_status?: string;
75
+ output_names?: string[];
76
+ pending_outputs?: string[];
77
+ completed_outputs?: string[];
78
+ progress?: RunProgress;
79
+ response?: ExecuteWorkflowResponse | RunDetailResponse | GetOutputResponse | GetAllOutputsResponse | LegacyGetOutputResponse | null;
80
+ error?: string;
81
+ }
82
+ export interface ExecuteWorkflowAsyncOptions {
83
+ returnAllOutputs?: boolean;
84
+ onIntermediateResponse?: (update: ExecuteWorkflowAsyncIntermediateResponse) => void | Promise<void>;
85
+ }
86
+ export interface RunEventsSSEEvent {
87
+ id?: number | string;
88
+ event?: string;
89
+ data: any;
90
+ raw: string;
91
+ }
92
+ export interface RunEventsSSEOptions {
93
+ fromSeq?: number;
94
+ signal?: AbortSignal;
95
+ onOpen?: (meta: {
96
+ status: number;
97
+ contentType: string | null;
98
+ }) => void | Promise<void>;
99
+ onEvent?: (event: RunEventsSSEEvent) => void | Promise<void>;
100
+ onError?: (error: Error) => void | Promise<void>;
101
+ onClose?: () => void | Promise<void>;
102
+ }
103
+ export interface RunEventsSSEConnection {
104
+ close: () => void;
105
+ done: Promise<void>;
106
+ }
56
107
  export interface DeprecationWarning {
57
108
  message: string;
58
109
  migration_guide: string;
@@ -79,6 +130,7 @@ export interface RunDetail {
79
130
  url?: string;
80
131
  }>;
81
132
  output_names?: string[];
133
+ progress?: RunProgress | null;
82
134
  created_at: string;
83
135
  started_at?: string;
84
136
  completed_at?: string;
@@ -110,26 +162,9 @@ export interface FlowscaleConfig {
110
162
  timeout?: number;
111
163
  maxRetries?: number;
112
164
  retryDelay?: number;
113
- WebSocketImpl?: any;
165
+ fetchImpl?: any;
114
166
  proxyMode?: boolean;
115
167
  customHeaders?: {
116
168
  [key: string]: string;
117
169
  };
118
170
  }
119
- export type WebSocketEventCallback = (data: any) => void;
120
- export interface WebSocketMessage {
121
- type: string;
122
- data: any;
123
- }
124
- export interface WebSocketOptions {
125
- onOpen?: () => void;
126
- onClose?: (event: CloseEvent | {
127
- code: number;
128
- reason: string;
129
- }) => void;
130
- onError?: (error: Event | Error) => void;
131
- onMessage?: WebSocketEventCallback;
132
- reconnect?: boolean;
133
- reconnectInterval?: number;
134
- maxReconnectAttempts?: number;
135
- }
@@ -166,17 +166,6 @@ app.post('/api/v1/runs/:runId/cancel', authenticateToken, async (req, res) => {
166
166
  }
167
167
  });
168
168
 
169
- // WebSocket proxy endpoint
170
- app.get('/api/v1/ws/subscribe', authenticateToken, (req, res) => {
171
- // For WebSocket proxying, you'd typically use a WebSocket proxy
172
- // This is a simplified example - in production, you'd want to use
173
- // a proper WebSocket proxy like http-proxy-middleware
174
- res.status(501).json({
175
- error: 'WebSocket proxying requires additional setup',
176
- message: 'Implement WebSocket proxy using http-proxy-middleware or similar'
177
- });
178
- });
179
-
180
169
  // Error handling middleware
181
170
  app.use((error, req, res, next) => {
182
171
  console.error('Server error:', error);
@@ -191,4 +180,4 @@ app.listen(PORT, () => {
191
180
  console.log('- JWT_SECRET: Secret for signing JWT tokens');
192
181
  });
193
182
 
194
- module.exports = app;
183
+ module.exports = app;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "flowscale",
3
- "version": "1.1.0",
3
+ "version": "1.3.0",
4
4
  "description": "An NPM library for communicating with the Flowscale APIs",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -17,7 +17,18 @@
17
17
  "publish:latest": "npm publish"
18
18
  },
19
19
  "author": "flowscale",
20
- "license": "MIT",
20
+ "license": "BSD-3-Clause",
21
+ "repository": {
22
+ "type": "git",
23
+ "url": "git+https://github.com/FlowScale-AI/flowscale-js-sdk.git"
24
+ },
25
+ "bugs": {
26
+ "url": "https://github.com/FlowScale-AI/flowscale-js-sdk/issues"
27
+ },
28
+ "homepage": "https://github.com/FlowScale-AI/flowscale-js-sdk#readme",
29
+ "engines": {
30
+ "node": ">=14.0.0"
31
+ },
21
32
  "dependencies": {
22
33
  "axios": "^1.7.7",
23
34
  "form-data": "^4.0.1"
@@ -1,173 +0,0 @@
1
- // Node.js WebSocket Example - Using the SDK's built-in WebSocket functionality
2
- const { FlowscaleAPI } = require('../dist');
3
- const WebSocket = require('ws');
4
-
5
- // Load environment variables
6
- // In a real application, you should use dotenv or similar
7
- const apiKey = 'YOUR_API_KEY';
8
- const baseUrl = 'YOUR_BASE_URL'; // e.g., https://your-url.pod.flowscale.ai
9
-
10
- // Initialize the Flowscale API client with WebSocket support
11
- const flowscale = new FlowscaleAPI({
12
- apiKey: apiKey,
13
- baseUrl: baseUrl,
14
- WebSocketImpl: WebSocket // Pass the 'ws' WebSocket implementation for Node.js
15
- });
16
-
17
- // Now you can use the SDK's WebSocket methods directly!
18
- const disconnect = flowscale.connectWebSocket({
19
- onOpen: () => {
20
- console.log('WebSocket connected via SDK!');
21
-
22
- // Example: Send a message
23
- const success = flowscale.sendWebSocketMessage({
24
- type: 'subscribe',
25
- data: {
26
- run_id: 'YOUR_RUN_ID' // Replace with actual run ID
27
- }
28
- });
29
-
30
- if (success) {
31
- console.log('Message sent successfully');
32
- }
33
- },
34
- onMessage: (message) => {
35
- console.log('Received message:', message);
36
-
37
- // Handle different message types
38
- if (message.type === 'run_status_update') {
39
- console.log('Run status updated:', message.data);
40
- }
41
- },
42
- onClose: (event) => {
43
- console.log('WebSocket connection closed:', event.code, event.reason);
44
- },
45
- onError: (error) => {
46
- console.error('WebSocket error:', error);
47
- },
48
- reconnect: true,
49
- reconnectInterval: 5000,
50
- maxReconnectAttempts: 5
51
- });
52
-
53
- // Check connection status
54
- console.log('Is connected:', flowscale.isWebSocketConnected());
55
-
56
- // Keep the process running
57
- process.on('SIGINT', () => {
58
- console.log('Closing WebSocket connection');
59
- disconnect(); // Use the disconnect function returned by connectWebSocket
60
- process.exit(0);
61
- });
62
-
63
- console.log('WebSocket client running via SDK. Press Ctrl+C to exit.');
64
-
65
- // ========================
66
- // Legacy Example (for reference)
67
- // ========================
68
- // If you prefer to implement WebSocket manually, here's the old approach:
69
-
70
- /*
71
- // Create a custom WebSocket implementation for Node.js
72
- class NodeWebSocketClient {
73
- constructor(url) {
74
- console.log('Creating WebSocket connection to:', url);
75
-
76
- this.ws = new WebSocket(url);
77
- this.connected = false;
78
-
79
- this.ws.on('open', () => {
80
- console.log('WebSocket connection established');
81
- this.connected = true;
82
- if (this.onopen) this.onopen();
83
- });
84
-
85
- this.ws.on('message', (data) => {
86
- if (this.onmessage) {
87
- const event = { data };
88
- this.onmessage(event);
89
- }
90
- });
91
-
92
- this.ws.on('close', (code, reason) => {
93
- console.log(`WebSocket connection closed: ${code} ${reason}`);
94
- this.connected = false;
95
- if (this.onclose) {
96
- const event = { code, reason };
97
- this.onclose(event);
98
- }
99
- });
100
-
101
- this.ws.on('error', (error) => {
102
- console.error('WebSocket error:', error);
103
- if (this.onerror) this.onerror(error);
104
- });
105
- }
106
-
107
- send(data) {
108
- if (this.connected) {
109
- this.ws.send(data);
110
- return true;
111
- }
112
- return false;
113
- }
114
-
115
- close() {
116
- this.ws.close();
117
- }
118
- }
119
-
120
- // Create a WebSocket URL with API key
121
- const wsUrl = new URL('/api/v1/ws', baseUrl);
122
- wsUrl.protocol = wsUrl.protocol.replace('http', 'ws');
123
- wsUrl.searchParams.append('api_key', apiKey);
124
-
125
- // Create a WebSocket connection
126
- const socket = new NodeWebSocketClient(wsUrl.toString());
127
-
128
- // Set up event handlers
129
- socket.onopen = () => {
130
- console.log('Connected to Flowscale WebSocket');
131
-
132
- // Example: Subscribe to a specific run
133
- const subscribeMessage = {
134
- type: 'subscribe',
135
- data: {
136
- run_id: 'YOUR_RUN_ID' // Replace with actual run ID
137
- }
138
- };
139
-
140
- socket.send(JSON.stringify(subscribeMessage));
141
- };
142
-
143
- socket.onmessage = (event) => {
144
- try {
145
- const message = JSON.parse(event.data);
146
- console.log('Received message:', message);
147
-
148
- // Handle different message types
149
- if (message.type === 'run_status_update') {
150
- console.log('Run status updated:', message.data);
151
- }
152
- } catch (error) {
153
- console.error('Failed to parse WebSocket message:', error);
154
- }
155
- };
156
-
157
- socket.onclose = (event) => {
158
- console.log('WebSocket connection closed:', event.code, event.reason);
159
- };
160
-
161
- socket.onerror = (error) => {
162
- console.error('WebSocket error:', error);
163
- };
164
-
165
- // Keep the process running
166
- process.on('SIGINT', () => {
167
- console.log('Closing WebSocket connection');
168
- socket.close();
169
- process.exit(0);
170
- });
171
-
172
- console.log('WebSocket client running. Press Ctrl+C to exit.');
173
- */
@@ -1,157 +0,0 @@
1
- <!DOCTYPE html>
2
- <html lang="en">
3
- <head>
4
- <meta charset="UTF-8">
5
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
- <title>Flowscale WebSocket Example</title>
7
- <script src="../dist/index.js"></script>
8
- <style>
9
- body {
10
- font-family: Arial, sans-serif;
11
- margin: 0;
12
- padding: 20px;
13
- line-height: 1.6;
14
- }
15
- #messageContainer {
16
- height: 300px;
17
- overflow-y: auto;
18
- border: 1px solid #ccc;
19
- padding: 10px;
20
- margin: 10px 0;
21
- }
22
- .message {
23
- padding: 5px;
24
- margin-bottom: 5px;
25
- border-radius: 4px;
26
- }
27
- .message-info {
28
- background-color: #e0f7fa;
29
- }
30
- .message-error {
31
- background-color: #ffebee;
32
- }
33
- .message-success {
34
- background-color: #e8f5e9;
35
- }
36
- </style>
37
- </head>
38
- <body>
39
- <h1>Flowscale WebSocket Example</h1>
40
-
41
- <div>
42
- <label for="apiKey">API Key:</label>
43
- <input type="text" id="apiKey" placeholder="Enter your API key">
44
- </div>
45
- <div>
46
- <label for="baseUrl">Base URL:</label>
47
- <input type="text" id="baseUrl" placeholder="Enter your base URL (e.g., https://your-url.pod.flowscale.ai)">
48
- </div>
49
- <div>
50
- <button id="connectBtn">Connect WebSocket</button>
51
- <button id="disconnectBtn" disabled>Disconnect WebSocket</button>
52
- </div>
53
-
54
- <h3>WebSocket Messages:</h3>
55
- <div id="messageContainer"></div>
56
-
57
- <div>
58
- <h3>Send a Message:</h3>
59
- <textarea id="messageToSend" placeholder="Enter a JSON message to send" rows="5" cols="50"></textarea>
60
- <button id="sendMessageBtn" disabled>Send Message</button>
61
- </div>
62
-
63
- <script>
64
- document.addEventListener('DOMContentLoaded', function() {
65
- let flowscale;
66
- let disconnectWs;
67
-
68
- function addMessageToContainer(message, type = 'info') {
69
- const messageContainer = document.getElementById('messageContainer');
70
- const messageElement = document.createElement('div');
71
- messageElement.className = `message message-${type}`;
72
- messageElement.textContent = typeof message === 'object' ?
73
- JSON.stringify(message, null, 2) : message;
74
- messageContainer.appendChild(messageElement);
75
- messageContainer.scrollTop = messageContainer.scrollHeight;
76
- }
77
-
78
- document.getElementById('connectBtn').addEventListener('click', function() {
79
- const apiKey = document.getElementById('apiKey').value;
80
- const baseUrl = document.getElementById('baseUrl').value;
81
-
82
- if (!apiKey || !baseUrl) {
83
- addMessageToContainer('Please enter both API Key and Base URL', 'error');
84
- return;
85
- }
86
-
87
- try {
88
- // Initialize the Flowscale API
89
- flowscale = new window.FlowscaleAPI({
90
- apiKey,
91
- baseUrl,
92
- allowDangerouslyExposeApiKey: true // Required for browser environment
93
- });
94
-
95
- addMessageToContainer('Initializing WebSocket connection...', 'info');
96
-
97
- // Connect to WebSocket
98
- disconnectWs = flowscale.connectWebSocket({
99
- onOpen: () => {
100
- addMessageToContainer('WebSocket connection opened', 'success');
101
- document.getElementById('connectBtn').disabled = true;
102
- document.getElementById('disconnectBtn').disabled = false;
103
- document.getElementById('sendMessageBtn').disabled = false;
104
- },
105
- onMessage: (message) => {
106
- addMessageToContainer(message, 'info');
107
- },
108
- onClose: (event) => {
109
- addMessageToContainer(`WebSocket connection closed: ${event.code} ${event.reason}`, 'error');
110
- document.getElementById('connectBtn').disabled = false;
111
- document.getElementById('disconnectBtn').disabled = true;
112
- document.getElementById('sendMessageBtn').disabled = true;
113
- },
114
- onError: (error) => {
115
- addMessageToContainer(`WebSocket error: ${error}`, 'error');
116
- }
117
- });
118
- } catch (error) {
119
- addMessageToContainer(`Error: ${error.message}`, 'error');
120
- }
121
- });
122
-
123
- document.getElementById('disconnectBtn').addEventListener('click', function() {
124
- if (disconnectWs) {
125
- disconnectWs();
126
- disconnectWs = null;
127
- document.getElementById('connectBtn').disabled = false;
128
- document.getElementById('disconnectBtn').disabled = true;
129
- document.getElementById('sendMessageBtn').disabled = true;
130
- addMessageToContainer('WebSocket disconnected', 'info');
131
- }
132
- });
133
-
134
- document.getElementById('sendMessageBtn').addEventListener('click', function() {
135
- const messageText = document.getElementById('messageToSend').value;
136
- if (!messageText) {
137
- addMessageToContainer('Please enter a message to send', 'error');
138
- return;
139
- }
140
-
141
- try {
142
- const message = JSON.parse(messageText);
143
- const success = flowscale.sendWebSocketMessage(message);
144
-
145
- if (success) {
146
- addMessageToContainer(`Message sent: ${messageText}`, 'success');
147
- } else {
148
- addMessageToContainer(`Failed to send message: ${messageText}`, 'error');
149
- }
150
- } catch (error) {
151
- addMessageToContainer(`Error sending message: ${error.message}`, 'error');
152
- }
153
- });
154
- });
155
- </script>
156
- </body>
157
- </html>