flowscale 1.2.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/CHANGELOG.md +2 -0
- package/CLAUDE.md +2 -7
- package/Makefile +1 -10
- package/README.md +42 -127
- package/dist/index.d.ts +16 -27
- package/dist/index.js +385 -144
- package/dist/types.d.ts +22 -18
- package/examples/backend-proxy-example.js +1 -12
- package/package.json +1 -1
- package/examples/node-websocket-example.js +0 -173
- package/examples/websocket-example.html +0 -157
|
@@ -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>
|