@dainprotocol/cli 1.2.31 → 1.2.34
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/commands/dev.js +171 -96
- package/dist/utils.js +33 -4
- package/package.json +3 -3
package/dist/commands/dev.js
CHANGED
|
@@ -68,6 +68,7 @@ var isFirstStart = true;
|
|
|
68
68
|
var proxyServer = null;
|
|
69
69
|
var isCleaningUp = false;
|
|
70
70
|
var debounceTimer = null;
|
|
71
|
+
var KILL_TIMEOUT_MS = 5000;
|
|
71
72
|
function isPortAvailable(port) {
|
|
72
73
|
return new Promise(function (resolve) {
|
|
73
74
|
var server = (0, net_1.createServer)()
|
|
@@ -75,27 +76,72 @@ function isPortAvailable(port) {
|
|
|
75
76
|
.on('error', function () { return resolve(false); });
|
|
76
77
|
});
|
|
77
78
|
}
|
|
79
|
+
/**
|
|
80
|
+
* Kill a child process and wait for it to exit.
|
|
81
|
+
* Sends SIGTERM first, escalates to SIGKILL after timeout.
|
|
82
|
+
*/
|
|
83
|
+
function killProcess(proc) {
|
|
84
|
+
return new Promise(function (resolve) {
|
|
85
|
+
if (!proc.pid || proc.killed) {
|
|
86
|
+
resolve();
|
|
87
|
+
return;
|
|
88
|
+
}
|
|
89
|
+
var resolved = false;
|
|
90
|
+
var done = function () {
|
|
91
|
+
if (resolved)
|
|
92
|
+
return;
|
|
93
|
+
resolved = true;
|
|
94
|
+
clearTimeout(forceKillTimer);
|
|
95
|
+
resolve();
|
|
96
|
+
};
|
|
97
|
+
proc.once('close', done);
|
|
98
|
+
proc.once('exit', done);
|
|
99
|
+
proc.kill('SIGTERM');
|
|
100
|
+
// Escalate to SIGKILL if process doesn't exit within timeout
|
|
101
|
+
var forceKillTimer = setTimeout(function () {
|
|
102
|
+
if (!resolved) {
|
|
103
|
+
try {
|
|
104
|
+
proc.kill('SIGKILL');
|
|
105
|
+
}
|
|
106
|
+
catch (_a) { }
|
|
107
|
+
// Resolve after SIGKILL — don't wait forever
|
|
108
|
+
setTimeout(done, 500);
|
|
109
|
+
}
|
|
110
|
+
}, KILL_TIMEOUT_MS);
|
|
111
|
+
});
|
|
112
|
+
}
|
|
78
113
|
function cleanup() {
|
|
79
|
-
|
|
80
|
-
return
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
114
|
+
return __awaiter(this, void 0, void 0, function () {
|
|
115
|
+
return __generator(this, function (_a) {
|
|
116
|
+
switch (_a.label) {
|
|
117
|
+
case 0:
|
|
118
|
+
if (isCleaningUp)
|
|
119
|
+
return [2 /*return*/];
|
|
120
|
+
isCleaningUp = true;
|
|
121
|
+
if (debounceTimer) {
|
|
122
|
+
clearTimeout(debounceTimer);
|
|
123
|
+
debounceTimer = null;
|
|
124
|
+
}
|
|
125
|
+
if (!childProcess) return [3 /*break*/, 2];
|
|
126
|
+
return [4 /*yield*/, killProcess(childProcess)];
|
|
127
|
+
case 1:
|
|
128
|
+
_a.sent();
|
|
129
|
+
childProcess = null;
|
|
130
|
+
_a.label = 2;
|
|
131
|
+
case 2:
|
|
132
|
+
if (watcher) {
|
|
133
|
+
watcher.close();
|
|
134
|
+
watcher = null;
|
|
135
|
+
}
|
|
136
|
+
if (mf) {
|
|
137
|
+
mf.dispose();
|
|
138
|
+
mf = null;
|
|
139
|
+
}
|
|
140
|
+
(0, utils_1.logInfo)('Development server and file watcher stopped.');
|
|
141
|
+
return [2 /*return*/];
|
|
142
|
+
}
|
|
143
|
+
});
|
|
144
|
+
});
|
|
99
145
|
}
|
|
100
146
|
function gracefulShutdown() {
|
|
101
147
|
return __awaiter(this, arguments, void 0, function (exitCode) {
|
|
@@ -103,81 +149,95 @@ function gracefulShutdown() {
|
|
|
103
149
|
if (exitCode === void 0) { exitCode = 0; }
|
|
104
150
|
return __generator(this, function (_b) {
|
|
105
151
|
switch (_b.label) {
|
|
106
|
-
case 0:
|
|
107
|
-
cleanup();
|
|
108
|
-
if (!proxyServer) return [3 /*break*/, 4];
|
|
109
|
-
_b.label = 1;
|
|
152
|
+
case 0: return [4 /*yield*/, cleanup()];
|
|
110
153
|
case 1:
|
|
111
|
-
_b.
|
|
112
|
-
return [
|
|
154
|
+
_b.sent();
|
|
155
|
+
if (!proxyServer) return [3 /*break*/, 5];
|
|
156
|
+
_b.label = 2;
|
|
113
157
|
case 2:
|
|
158
|
+
_b.trys.push([2, 4, , 5]);
|
|
159
|
+
return [4 /*yield*/, proxyServer.stop()];
|
|
160
|
+
case 3:
|
|
114
161
|
_b.sent();
|
|
115
162
|
(0, utils_1.logInfo)('Proxy server closed.');
|
|
116
|
-
return [3 /*break*/,
|
|
117
|
-
case 3:
|
|
118
|
-
_a = _b.sent();
|
|
119
|
-
return [3 /*break*/, 4];
|
|
163
|
+
return [3 /*break*/, 5];
|
|
120
164
|
case 4:
|
|
165
|
+
_a = _b.sent();
|
|
166
|
+
return [3 /*break*/, 5];
|
|
167
|
+
case 5:
|
|
121
168
|
process.exit(exitCode);
|
|
122
169
|
return [2 /*return*/];
|
|
123
170
|
}
|
|
124
171
|
});
|
|
125
172
|
});
|
|
126
173
|
}
|
|
127
|
-
function startProcess(
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
174
|
+
function startProcess(mainFile_1, envVars_1) {
|
|
175
|
+
return __awaiter(this, arguments, void 0, function (mainFile, envVars, isRestart) {
|
|
176
|
+
var spinner, hasStarted, tsNodePath, markStarted;
|
|
177
|
+
var _a, _b;
|
|
178
|
+
if (isRestart === void 0) { isRestart = false; }
|
|
179
|
+
return __generator(this, function (_c) {
|
|
180
|
+
switch (_c.label) {
|
|
181
|
+
case 0:
|
|
182
|
+
if (!childProcess) return [3 /*break*/, 2];
|
|
183
|
+
return [4 /*yield*/, killProcess(childProcess)];
|
|
184
|
+
case 1:
|
|
185
|
+
_c.sent();
|
|
186
|
+
childProcess = null;
|
|
187
|
+
_c.label = 2;
|
|
188
|
+
case 2:
|
|
189
|
+
spinner = (0, ora_1.default)(isRestart ? 'Restarting development server...' : 'Starting development server...').start();
|
|
190
|
+
hasStarted = false;
|
|
191
|
+
tsNodePath = path_1.default.join(process.cwd(), 'node_modules', '.bin', 'ts-node');
|
|
192
|
+
if (!fs_extra_1.default.existsSync(tsNodePath)) {
|
|
193
|
+
spinner.fail('ts-node not found. Run: npm install ts-node typescript');
|
|
194
|
+
return [2 /*return*/];
|
|
195
|
+
}
|
|
196
|
+
if (!fs_extra_1.default.existsSync(mainFile)) {
|
|
197
|
+
spinner.fail("Main file not found: ".concat(mainFile));
|
|
198
|
+
return [2 /*return*/];
|
|
199
|
+
}
|
|
200
|
+
childProcess = (0, child_process_1.spawn)(tsNodePath, [mainFile], {
|
|
201
|
+
env: __assign(__assign({}, process.env), envVars),
|
|
202
|
+
stdio: ['inherit', 'pipe', 'pipe'],
|
|
203
|
+
shell: false,
|
|
204
|
+
});
|
|
205
|
+
markStarted = function (success) {
|
|
206
|
+
if (hasStarted)
|
|
207
|
+
return;
|
|
208
|
+
hasStarted = true;
|
|
209
|
+
if (success) {
|
|
210
|
+
spinner.succeed(isRestart ? 'Development server restarted.' : 'Development server started.');
|
|
211
|
+
if (tunnelUrl && isFirstStart) {
|
|
212
|
+
(0, utils_1.displayTunnelUrl)(tunnelUrl);
|
|
213
|
+
isFirstStart = false;
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
else {
|
|
217
|
+
spinner.fail('Development server error.');
|
|
218
|
+
}
|
|
219
|
+
};
|
|
220
|
+
(_a = childProcess.stdout) === null || _a === void 0 ? void 0 : _a.on('data', function (data) { markStarted(true); process.stdout.write(data.toString()); });
|
|
221
|
+
(_b = childProcess.stderr) === null || _b === void 0 ? void 0 : _b.on('data', function (data) {
|
|
222
|
+
var output = data.toString();
|
|
223
|
+
markStarted(output.includes('Error:') || output.includes('error:') ? false : true);
|
|
224
|
+
process.stderr.write(output);
|
|
225
|
+
});
|
|
226
|
+
childProcess.on('close', function (code) {
|
|
227
|
+
if (code !== 0 && code !== null && !hasStarted)
|
|
228
|
+
spinner.fail("Development server exited with code ".concat(code));
|
|
229
|
+
childProcess = null;
|
|
230
|
+
});
|
|
231
|
+
childProcess.on('error', function (error) { spinner.fail("Failed to start: ".concat(error.message)); childProcess = null; });
|
|
232
|
+
return [2 /*return*/];
|
|
159
233
|
}
|
|
160
|
-
}
|
|
161
|
-
else {
|
|
162
|
-
spinner.fail('Development server error.');
|
|
163
|
-
}
|
|
164
|
-
};
|
|
165
|
-
(_a = childProcess.stdout) === null || _a === void 0 ? void 0 : _a.on('data', function (data) { markStarted(true); process.stdout.write(data.toString()); });
|
|
166
|
-
(_b = childProcess.stderr) === null || _b === void 0 ? void 0 : _b.on('data', function (data) {
|
|
167
|
-
var output = data.toString();
|
|
168
|
-
markStarted(output.includes('Error:') || output.includes('error:') ? false : true);
|
|
169
|
-
process.stderr.write(output);
|
|
170
|
-
});
|
|
171
|
-
childProcess.on('close', function (code) {
|
|
172
|
-
if (code !== 0 && code !== null && !hasStarted)
|
|
173
|
-
spinner.fail("Development server exited with code ".concat(code));
|
|
174
|
-
childProcess = null;
|
|
234
|
+
});
|
|
175
235
|
});
|
|
176
|
-
childProcess.on('error', function (error) { spinner.fail("Failed to start: ".concat(error.message)); childProcess = null; });
|
|
177
236
|
}
|
|
178
237
|
function dev(options) {
|
|
179
238
|
return __awaiter(this, void 0, void 0, function () {
|
|
180
|
-
var config, port, portNumber, runtime, mainFile, resolvedMain, envVars, proxySetup, watchPaths, dainDir, outFile, MFconfig_1, error_1;
|
|
239
|
+
var config, port, portNumber, runtime, mainFile, resolvedMain, envVars, proxySetup, watchPaths, isRestarting_1, dainDir, outFile, MFconfig_1, error_1;
|
|
240
|
+
var _this = this;
|
|
181
241
|
return __generator(this, function (_a) {
|
|
182
242
|
switch (_a.label) {
|
|
183
243
|
case 0:
|
|
@@ -208,7 +268,7 @@ function dev(options) {
|
|
|
208
268
|
process.once('unhandledRejection', function (reason) { (0, utils_1.logError)('Unhandled Rejection:', reason); gracefulShutdown(1); });
|
|
209
269
|
_a.label = 1;
|
|
210
270
|
case 1:
|
|
211
|
-
_a.trys.push([1,
|
|
271
|
+
_a.trys.push([1, 10, , 11]);
|
|
212
272
|
return [4 /*yield*/, isPortAvailable(portNumber)];
|
|
213
273
|
case 2:
|
|
214
274
|
if (!(_a.sent())) {
|
|
@@ -226,29 +286,44 @@ function dev(options) {
|
|
|
226
286
|
tunnelUrl = proxySetup.tunnelUrl;
|
|
227
287
|
_a.label = 4;
|
|
228
288
|
case 4:
|
|
229
|
-
if (!(runtime === 'node')) return [3 /*break*/,
|
|
230
|
-
startProcess(mainFile, envVars);
|
|
289
|
+
if (!(runtime === 'node')) return [3 /*break*/, 6];
|
|
290
|
+
return [4 /*yield*/, startProcess(mainFile, envVars)];
|
|
291
|
+
case 5:
|
|
292
|
+
_a.sent();
|
|
231
293
|
watchPaths = [
|
|
232
294
|
path_1.default.dirname(mainFile),
|
|
233
295
|
config['static-dir'] ? path_1.default.join(process.cwd(), config['static-dir']) : (0, utils_1.getStaticFilesPath)(),
|
|
234
296
|
].filter(function (p) { return fs_extra_1.default.existsSync(p); });
|
|
297
|
+
isRestarting_1 = false;
|
|
235
298
|
watcher = chokidar_1.default.watch(watchPaths, { ignored: /(^|[\/\\])\./, persistent: true, ignoreInitial: true });
|
|
236
299
|
watcher.on('change', function (changedPath) {
|
|
237
300
|
if (debounceTimer)
|
|
238
301
|
clearTimeout(debounceTimer);
|
|
239
|
-
debounceTimer = setTimeout(function () {
|
|
240
|
-
(
|
|
241
|
-
|
|
242
|
-
|
|
302
|
+
debounceTimer = setTimeout(function () { return __awaiter(_this, void 0, void 0, function () {
|
|
303
|
+
return __generator(this, function (_a) {
|
|
304
|
+
switch (_a.label) {
|
|
305
|
+
case 0:
|
|
306
|
+
if (isRestarting_1)
|
|
307
|
+
return [2 /*return*/];
|
|
308
|
+
isRestarting_1 = true;
|
|
309
|
+
(0, utils_1.logInfo)("File ".concat(changedPath, " changed. Restarting..."));
|
|
310
|
+
return [4 /*yield*/, startProcess(mainFile, envVars, true)];
|
|
311
|
+
case 1:
|
|
312
|
+
_a.sent();
|
|
313
|
+
isRestarting_1 = false;
|
|
314
|
+
return [2 /*return*/];
|
|
315
|
+
}
|
|
316
|
+
});
|
|
317
|
+
}); }, 300);
|
|
243
318
|
});
|
|
244
319
|
(0, utils_1.logInfo)('Watching for file changes...');
|
|
245
|
-
return [3 /*break*/,
|
|
246
|
-
case
|
|
247
|
-
if (!(runtime === 'workers')) return [3 /*break*/,
|
|
320
|
+
return [3 /*break*/, 9];
|
|
321
|
+
case 6:
|
|
322
|
+
if (!(runtime === 'workers')) return [3 /*break*/, 8];
|
|
248
323
|
dainDir = path_1.default.join(process.cwd(), '.dain');
|
|
249
324
|
outFile = path_1.default.join(dainDir, path_1.default.basename(config['main-file'], '.ts') + '.mjs');
|
|
250
325
|
return [4 /*yield*/, (0, build_1.default)({ config: options.config, runtime: 'workers', watch: true })];
|
|
251
|
-
case
|
|
326
|
+
case 7:
|
|
252
327
|
_a.sent();
|
|
253
328
|
MFconfig_1 = { scriptPath: outFile, modules: true, port: parseInt(port, 10), log: new miniflare_1.Log(miniflare_1.LogLevel.DEBUG), liveReload: true };
|
|
254
329
|
mf = new miniflare_1.Miniflare(MFconfig_1);
|
|
@@ -262,15 +337,15 @@ function dev(options) {
|
|
|
262
337
|
} }, 300);
|
|
263
338
|
});
|
|
264
339
|
(0, utils_1.logInfo)('Watching for file changes in source and build directories...');
|
|
265
|
-
return [3 /*break*/,
|
|
266
|
-
case
|
|
267
|
-
case
|
|
268
|
-
case
|
|
340
|
+
return [3 /*break*/, 9];
|
|
341
|
+
case 8: throw new Error("Unsupported runtime: ".concat(runtime));
|
|
342
|
+
case 9: return [3 /*break*/, 11];
|
|
343
|
+
case 10:
|
|
269
344
|
error_1 = _a.sent();
|
|
270
345
|
(0, utils_1.logError)("Error in dev process for ".concat(runtime, " runtime:"), error_1);
|
|
271
346
|
gracefulShutdown(1);
|
|
272
|
-
return [3 /*break*/,
|
|
273
|
-
case
|
|
347
|
+
return [3 /*break*/, 11];
|
|
348
|
+
case 11: return [2 /*return*/];
|
|
274
349
|
}
|
|
275
350
|
});
|
|
276
351
|
});
|
package/dist/utils.js
CHANGED
|
@@ -168,7 +168,7 @@ function displayTunnelUrl(tunnelUrl) {
|
|
|
168
168
|
}
|
|
169
169
|
function setupProxy(port, apiKey, config) {
|
|
170
170
|
return __awaiter(this, void 0, void 0, function () {
|
|
171
|
-
var spinner,
|
|
171
|
+
var spinner, client_2, tunnelUrl, error_1;
|
|
172
172
|
return __generator(this, function (_a) {
|
|
173
173
|
switch (_a.label) {
|
|
174
174
|
case 0:
|
|
@@ -176,12 +176,41 @@ function setupProxy(port, apiKey, config) {
|
|
|
176
176
|
_a.label = 1;
|
|
177
177
|
case 1:
|
|
178
178
|
_a.trys.push([1, 3, , 4]);
|
|
179
|
-
|
|
180
|
-
|
|
179
|
+
client_2 = new client_1.DainTunnel(config["tunnel-base-url"] || exports.DEFAULT_TUNNEL_BASE_URL, apiKey);
|
|
180
|
+
// Handle tunnel lifecycle events
|
|
181
|
+
client_2.on("disconnected", function () {
|
|
182
|
+
console.log(chalk_1.default.yellow("\n⚠ Tunnel disconnected. Attempting to reconnect..."));
|
|
183
|
+
});
|
|
184
|
+
client_2.on("reconnecting", function (_a) {
|
|
185
|
+
var attempt = _a.attempt, delay = _a.delay;
|
|
186
|
+
console.log(chalk_1.default.yellow(" Reconnection attempt ".concat(attempt, "/10 in ").concat(Math.round(delay / 1000), "s...")));
|
|
187
|
+
});
|
|
188
|
+
client_2.on("reconnected", function () {
|
|
189
|
+
console.log(chalk_1.default.green("✓ Tunnel reconnected successfully"));
|
|
190
|
+
});
|
|
191
|
+
client_2.on("error", function (error) {
|
|
192
|
+
console.error(chalk_1.default.red("\n\u2717 Tunnel error: ".concat(error.message)));
|
|
193
|
+
});
|
|
194
|
+
client_2.on("max_reconnect_attempts", function () {
|
|
195
|
+
console.error(chalk_1.default.red("\n✗ Tunnel failed to reconnect after 10 attempts."));
|
|
196
|
+
console.log(chalk_1.default.yellow(" Resetting and trying again..."));
|
|
197
|
+
// Reset and try one more time (resetReconnection added in tunnel 1.1.31)
|
|
198
|
+
if (typeof client_2.resetReconnection === "function") {
|
|
199
|
+
client_2.resetReconnection();
|
|
200
|
+
client_2.start(parseInt(port)).catch(function (err) {
|
|
201
|
+
console.error(chalk_1.default.red("\n\u2717 Unable to restore tunnel connection: ".concat(err.message)));
|
|
202
|
+
console.log(chalk_1.default.yellow(" Please restart the dev server manually."));
|
|
203
|
+
});
|
|
204
|
+
}
|
|
205
|
+
else {
|
|
206
|
+
console.log(chalk_1.default.yellow(" Please restart the dev server manually."));
|
|
207
|
+
}
|
|
208
|
+
});
|
|
209
|
+
return [4 /*yield*/, client_2.start(parseInt(port))];
|
|
181
210
|
case 2:
|
|
182
211
|
tunnelUrl = _a.sent();
|
|
183
212
|
spinner.succeed("Proxy setup complete");
|
|
184
|
-
return [2 /*return*/, { client:
|
|
213
|
+
return [2 /*return*/, { client: client_2, tunnelUrl: tunnelUrl }];
|
|
185
214
|
case 3:
|
|
186
215
|
error_1 = _a.sent();
|
|
187
216
|
spinner.fail(chalk_1.default.red("Error setting up proxy"));
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@dainprotocol/cli",
|
|
3
|
-
"version": "1.2.
|
|
3
|
+
"version": "1.2.34",
|
|
4
4
|
"private": false,
|
|
5
5
|
"publishConfig": {
|
|
6
6
|
"access": "public"
|
|
@@ -23,8 +23,8 @@
|
|
|
23
23
|
],
|
|
24
24
|
"dependencies": {
|
|
25
25
|
"@ai-sdk/anthropic": "^0.0.50",
|
|
26
|
-
"@dainprotocol/service-sdk": "
|
|
27
|
-
"@dainprotocol/tunnel": "
|
|
26
|
+
"@dainprotocol/service-sdk": "2.0.80",
|
|
27
|
+
"@dainprotocol/tunnel": "1.1.33",
|
|
28
28
|
"@types/fs-extra": "^11.0.4",
|
|
29
29
|
"@types/localtunnel": "^2.0.4",
|
|
30
30
|
"ai": "^3.3.41",
|