@arela/uploader 1.0.16 → 1.0.17

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@arela/uploader",
3
- "version": "1.0.16",
3
+ "version": "1.0.17",
4
4
  "description": "CLI to upload files/directories to Arela",
5
5
  "bin": {
6
6
  "arela": "./src/index.js"
@@ -49,6 +49,8 @@ export class PollWorkerCommand {
49
49
  );
50
50
  }
51
51
 
52
+ this.serverId = serverId;
53
+
52
54
  // Initialize Pipeline API service
53
55
  this.pipelineApi = new PipelineApiService(apiTarget);
54
56
 
@@ -113,9 +115,28 @@ export class PollWorkerCommand {
113
115
  async #processJob(job) {
114
116
  this.currentJob = job;
115
117
 
118
+ // Start heartbeat timer to keep worker alive during long-running jobs
119
+ const heartbeatInterval = setInterval(async () => {
120
+ try {
121
+ await this.pipelineApi.sendHeartbeat(this.serverId, 'busy');
122
+ logger.debug(`💓 Heartbeat sent for ${this.serverId}`);
123
+ } catch {
124
+ // Non-critical — progress updates also refresh heartbeat
125
+ }
126
+ }, 20000);
127
+
116
128
  try {
117
129
  logger.info(`🔄 Processing ${job.type} job ${job.id}`);
118
130
 
131
+ // DEBUG: Delay to observe busy status in UI (remove in production)
132
+ const debugDelay = parseInt(process.env.DEBUG_JOB_DELAY) || 0;
133
+ if (debugDelay > 0) {
134
+ console.log(
135
+ `⏳ DEBUG: Waiting ${debugDelay / 1000}s before executing job...`,
136
+ );
137
+ await this.#sleep(debugDelay);
138
+ }
139
+
119
140
  // Create progress callback that reports to API
120
141
  const onProgress = async (percent, message) => {
121
142
  await this.pipelineApi.updateProgress(
@@ -159,6 +180,7 @@ export class PollWorkerCommand {
159
180
  logger.error(`❌ Job ${job.id} failed: ${error.message}`);
160
181
  await this.pipelineApi.failJob(job.id, error.message);
161
182
  } finally {
183
+ clearInterval(heartbeatInterval);
162
184
  this.currentJob = null;
163
185
  // Reset API configuration
164
186
  this.#resetApiConfig();
@@ -294,6 +316,7 @@ export class PollWorkerCommand {
294
316
  const options = {
295
317
  scanApi: job.sourceApi || 'agencia',
296
318
  pushApi: job.targetApi || 'cliente',
319
+ rfcs: [job.rfc],
297
320
  batchSize: 100,
298
321
  uploadBatchSize: 10,
299
322
  folderStructure: job.folderStructure || 'pedimento',
@@ -36,10 +36,10 @@ class Config {
36
36
  const __dirname = path.dirname(__filename);
37
37
  const packageJsonPath = path.resolve(__dirname, '../../package.json');
38
38
  const packageJson = JSON.parse(fs.readFileSync(packageJsonPath, 'utf-8'));
39
- return packageJson.version || '1.0.16';
39
+ return packageJson.version || '1.0.17';
40
40
  } catch (error) {
41
41
  console.warn('⚠️ Could not read package.json version, using fallback');
42
- return '1.0.16';
42
+ return '1.0.17';
43
43
  }
44
44
  }
45
45
 
@@ -237,6 +237,25 @@ export class PipelineApiService {
237
237
  }
238
238
  }
239
239
 
240
+ /**
241
+ * Send a heartbeat to keep the worker alive during long-running jobs
242
+ * @param {string} serverId - Server identifier
243
+ * @param {'online'|'busy'} status - Worker status
244
+ * @returns {Promise<boolean>} Success status
245
+ */
246
+ async sendHeartbeat(serverId, status = 'busy') {
247
+ try {
248
+ await this.#request('POST', '/api/uploader/pipeline/worker/heartbeat', {
249
+ serverId,
250
+ status,
251
+ });
252
+ return true;
253
+ } catch (error) {
254
+ logger.warn(`⚠️ Failed to send heartbeat: ${error.message}`);
255
+ return false;
256
+ }
257
+ }
258
+
240
259
  /**
241
260
  * Close connections and cleanup
242
261
  */