@synergenius/flow-weaver 0.10.11 → 0.10.12

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.
@@ -1,20 +1,19 @@
1
1
  /**
2
- * tunnel command — Relay Studio RPC calls from cloud to a local dev server.
2
+ * tunnel command — Self-contained tunnel for cloud Studio.
3
3
  *
4
- * 1. Connects to the local server via Socket.IO (same as listen command).
5
- * 2. Opens a WebSocket to the cloud server's /api/tunnel endpoint.
6
- * 3. Relays tunnel:request messages from cloud → local Socket.IO → cloud.
4
+ * Handles all RPC methods locally using Node.js fs and the
5
+ * @synergenius/flow-weaver AST API. No local server required.
6
+ *
7
+ * 1. Opens a WebSocket to the cloud server's /api/tunnel endpoint.
8
+ * 2. Dispatches RPC calls directly to local handler functions.
7
9
  */
8
- import { io as socketIO } from 'socket.io-client';
9
10
  import WebSocket from 'ws';
10
11
  export interface TunnelOptions {
11
12
  key: string;
12
13
  cloud?: string;
13
- server?: string;
14
+ dir?: string;
14
15
  /** Override WebSocket factory (for testing) */
15
16
  createWs?: (url: string) => WebSocket;
16
- /** Override socket.io-client factory (for testing) */
17
- ioFactory?: typeof socketIO;
18
17
  }
19
18
  export declare function tunnelCommand(options: TunnelOptions): Promise<void>;
20
19
  //# sourceMappingURL=tunnel.d.ts.map
@@ -1,52 +1,26 @@
1
1
  /**
2
- * tunnel command — Relay Studio RPC calls from cloud to a local dev server.
2
+ * tunnel command — Self-contained tunnel for cloud Studio.
3
3
  *
4
- * 1. Connects to the local server via Socket.IO (same as listen command).
5
- * 2. Opens a WebSocket to the cloud server's /api/tunnel endpoint.
6
- * 3. Relays tunnel:request messages from cloud → local Socket.IO → cloud.
4
+ * Handles all RPC methods locally using Node.js fs and the
5
+ * @synergenius/flow-weaver AST API. No local server required.
6
+ *
7
+ * 1. Opens a WebSocket to the cloud server's /api/tunnel endpoint.
8
+ * 2. Dispatches RPC calls directly to local handler functions.
7
9
  */
8
- import { io as socketIO } from 'socket.io-client';
10
+ import * as path from 'node:path';
9
11
  import WebSocket from 'ws';
10
12
  import { logger } from '../utils/logger.js';
11
- import { DEFAULT_SERVER_URL } from '../../defaults.js';
13
+ import { dispatch } from '../tunnel/dispatch.js';
12
14
  export async function tunnelCommand(options) {
13
15
  const cloudUrl = options.cloud || 'https://flowweaver.dev';
14
- const localUrl = options.server || DEFAULT_SERVER_URL;
16
+ const workspaceRoot = path.resolve(options.dir || process.cwd());
15
17
  const createWs = options.createWs ?? ((url) => new WebSocket(url));
16
- const ioFactory = options.ioFactory ?? socketIO;
17
18
  logger.section('Flow Weaver Tunnel');
18
- logger.info(`Cloud: ${cloudUrl}`);
19
- logger.info(`Local: ${localUrl}`);
19
+ logger.info(`Cloud: ${cloudUrl}`);
20
+ logger.info(`Workspace: ${workspaceRoot}`);
20
21
  logger.newline();
21
22
  // -----------------------------------------------------------------------
22
- // 1. Connect to local server via Socket.IO
23
- // -----------------------------------------------------------------------
24
- logger.info('Connecting to local server...');
25
- const localSocket = ioFactory(`${localUrl}`, {
26
- query: { clientType: 'tunnel' },
27
- transports: ['websocket', 'polling'],
28
- reconnection: true,
29
- reconnectionDelay: 1000,
30
- reconnectionAttempts: Infinity,
31
- });
32
- await new Promise((resolve, reject) => {
33
- const timeout = setTimeout(() => {
34
- localSocket.disconnect();
35
- reject(new Error(`Local server connection timeout (10s). Is it running on ${localUrl}?`));
36
- }, 10_000);
37
- localSocket.on('connect', () => {
38
- clearTimeout(timeout);
39
- logger.success(`Connected to local server (${localUrl})`);
40
- resolve();
41
- });
42
- localSocket.on('connect_error', (err) => {
43
- clearTimeout(timeout);
44
- localSocket.disconnect();
45
- reject(new Error(`Cannot connect to local server: ${err.message}`));
46
- });
47
- });
48
- // -----------------------------------------------------------------------
49
- // 2. Connect to cloud server via WebSocket
23
+ // 1. Connect to cloud server via WebSocket
50
24
  // -----------------------------------------------------------------------
51
25
  logger.info('Connecting to cloud server...');
52
26
  const wsProtocol = cloudUrl.startsWith('https') ? 'wss' : 'ws';
@@ -88,10 +62,11 @@ export async function tunnelCommand(options) {
88
62
  logger.info('Press Ctrl+C to disconnect');
89
63
  logger.newline();
90
64
  let requestCount = 0;
65
+ const ctx = { workspaceRoot };
91
66
  // -----------------------------------------------------------------------
92
- // 3. Relay: cloud → local → cloud
67
+ // 2. Handle RPC: cloud → local dispatch → cloud
93
68
  // -----------------------------------------------------------------------
94
- cloudWs.on('message', (raw) => {
69
+ cloudWs.on('message', async (raw) => {
95
70
  let msg;
96
71
  try {
97
72
  msg = JSON.parse(raw.toString());
@@ -107,47 +82,35 @@ export async function tunnelCommand(options) {
107
82
  const req = msg;
108
83
  requestCount++;
109
84
  logger.debug(`[${requestCount}] → ${req.method}`);
110
- localSocket.emit('method', { id: req.id, method: req.method, params: req.params }, (response) => {
111
- cloudWs.send(JSON.stringify({
112
- type: 'tunnel:response',
113
- requestId: req.requestId,
114
- id: response.id,
115
- success: response.success,
116
- result: response.result,
117
- error: response.error,
118
- }));
119
- });
85
+ const response = await dispatch(req.method, req.params || {}, ctx);
86
+ cloudWs.send(JSON.stringify({
87
+ type: 'tunnel:response',
88
+ requestId: req.requestId,
89
+ id: req.id,
90
+ success: response.success,
91
+ result: response.result,
92
+ error: response.error,
93
+ }));
120
94
  }
121
95
  });
122
96
  // -----------------------------------------------------------------------
123
- // 4. Handle disconnections
97
+ // 3. Handle disconnections
124
98
  // -----------------------------------------------------------------------
125
- localSocket.on('disconnect', (reason) => {
126
- logger.warn(`Local server disconnected: ${reason}`);
127
- if (reason === 'io server disconnect') {
128
- logger.info('Attempting to reconnect...');
129
- }
130
- });
131
- localSocket.on('connect', () => {
132
- logger.success('Reconnected to local server');
133
- });
134
99
  cloudWs.on('close', (code, reason) => {
135
100
  logger.warn(`Cloud server disconnected: ${code} ${reason.toString()}`);
136
101
  logger.info('Shutting down tunnel...');
137
- localSocket.disconnect();
138
102
  process.exit(code === 4001 ? 1 : 0);
139
103
  });
140
104
  cloudWs.on('error', (err) => {
141
105
  logger.error(`Cloud WebSocket error: ${err.message}`);
142
106
  });
143
107
  // -----------------------------------------------------------------------
144
- // 5. Graceful shutdown
108
+ // 4. Graceful shutdown
145
109
  // -----------------------------------------------------------------------
146
110
  process.on('SIGINT', () => {
147
111
  logger.newline();
148
- logger.info(`Shutting down tunnel (${requestCount} requests relayed)...`);
112
+ logger.info(`Shutting down tunnel (${requestCount} requests handled)...`);
149
113
  cloudWs.close();
150
- localSocket.disconnect();
151
114
  process.exit(0);
152
115
  });
153
116
  // Keep alive until SIGINT or cloud disconnect