@ubercode/dcmtk 0.6.2 → 0.6.3

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/servers.cjs CHANGED
@@ -3029,6 +3029,7 @@ var DicomReceiver = class _DicomReceiver extends events.EventEmitter {
3029
3029
  worker.files = [];
3030
3030
  worker.fileSizes = [];
3031
3031
  worker.outputLines = [];
3032
+ worker.pendingFiles = [];
3032
3033
  worker.startAt = Date.now();
3033
3034
  this.pipeConnection(worker, remoteSocket);
3034
3035
  void this.replenishPool();
@@ -3123,6 +3124,7 @@ var DicomReceiver = class _DicomReceiver extends events.EventEmitter {
3123
3124
  files: [],
3124
3125
  fileSizes: [],
3125
3126
  outputLines: [],
3127
+ pendingFiles: [],
3126
3128
  startAt: void 0,
3127
3129
  remoteSocket: void 0,
3128
3130
  workerSocket: void 0
@@ -3197,7 +3199,9 @@ var DicomReceiver = class _DicomReceiver extends events.EventEmitter {
3197
3199
  /** Wires FILE_RECEIVED from dcmrecv worker to handleFileReceived. */
3198
3200
  wireFileReceived(worker) {
3199
3201
  worker.dcmrecv.onFileReceived((data) => {
3200
- void this.handleFileReceived(worker, data);
3202
+ const promise = this.handleFileReceived(worker, data);
3203
+ worker.pendingFiles.push(promise);
3204
+ void promise.finally(() => removePending(worker.pendingFiles, promise));
3201
3205
  });
3202
3206
  }
3203
3207
  /** Moves a received file, opens it as DicomInstance, and emits FILE_RECEIVED. */
@@ -3237,42 +3241,58 @@ var DicomReceiver = class _DicomReceiver extends events.EventEmitter {
3237
3241
  /** Returns worker to idle pool on association complete, emits summary. */
3238
3242
  wireAssociationComplete(worker) {
3239
3243
  worker.dcmrecv.onAssociationComplete((data) => {
3240
- const assocId = worker.associationId ?? data.associationId;
3241
- const assocDir = worker.associationDir ?? "";
3242
- const files = [...worker.files];
3243
- const output = [...worker.outputLines];
3244
- const endAt = Date.now();
3245
- const startAt = worker.startAt ?? endAt;
3246
- const totalBytes = sumArray(worker.fileSizes);
3247
- const elapsedMs = endAt - startAt;
3248
- const bytesPerSecond = elapsedMs > 0 ? Math.round(totalBytes / elapsedMs * 1e3) : 0;
3249
- this.emit("ASSOCIATION_COMPLETE", {
3250
- associationId: assocId,
3251
- associationDir: assocDir,
3252
- callingAE: data.callingAE,
3253
- calledAE: data.calledAE,
3254
- source: data.source,
3255
- files,
3256
- durationMs: data.durationMs,
3257
- endReason: data.endReason,
3258
- totalBytes,
3259
- bytesPerSecond,
3260
- startAt,
3261
- endAt,
3262
- output
3263
- });
3264
- worker.state = "idle";
3265
- worker.associationId = void 0;
3266
- worker.associationDir = void 0;
3267
- worker.files = [];
3268
- worker.fileSizes = [];
3269
- worker.outputLines = [];
3270
- worker.startAt = void 0;
3271
- worker.remoteSocket = void 0;
3272
- worker.workerSocket = void 0;
3273
- void this.scaleDown();
3244
+ void this.finalizeAssociation(worker, data);
3245
+ });
3246
+ }
3247
+ /** Awaits pending file operations, emits ASSOCIATION_COMPLETE, resets worker state. */
3248
+ async finalizeAssociation(worker, data) {
3249
+ if (worker.pendingFiles.length > 0) {
3250
+ await Promise.all(worker.pendingFiles);
3251
+ }
3252
+ this.emitAssociationComplete(worker, data);
3253
+ this.resetWorker(worker);
3254
+ void this.scaleDown();
3255
+ }
3256
+ /** Emits the ASSOCIATION_COMPLETE event with transfer stats. */
3257
+ emitAssociationComplete(worker, data) {
3258
+ const assocId = worker.associationId ?? data.associationId;
3259
+ const assocDir = worker.associationDir ?? "";
3260
+ const files = [...worker.files];
3261
+ const output = [...worker.outputLines];
3262
+ const endAt = Date.now();
3263
+ const startAt = worker.startAt ?? endAt;
3264
+ const totalBytes = sumArray(worker.fileSizes);
3265
+ const elapsedMs = endAt - startAt;
3266
+ const bytesPerSecond = elapsedMs > 0 ? Math.round(totalBytes / elapsedMs * 1e3) : 0;
3267
+ this.emit("ASSOCIATION_COMPLETE", {
3268
+ associationId: assocId,
3269
+ associationDir: assocDir,
3270
+ callingAE: data.callingAE,
3271
+ calledAE: data.calledAE,
3272
+ source: data.source,
3273
+ files,
3274
+ durationMs: data.durationMs,
3275
+ endReason: data.endReason,
3276
+ totalBytes,
3277
+ bytesPerSecond,
3278
+ startAt,
3279
+ endAt,
3280
+ output
3274
3281
  });
3275
3282
  }
3283
+ /** Resets worker state to idle after an association completes. */
3284
+ resetWorker(worker) {
3285
+ worker.state = "idle";
3286
+ worker.associationId = void 0;
3287
+ worker.associationDir = void 0;
3288
+ worker.files = [];
3289
+ worker.fileSizes = [];
3290
+ worker.outputLines = [];
3291
+ worker.pendingFiles = [];
3292
+ worker.startAt = void 0;
3293
+ worker.remoteSocket = void 0;
3294
+ worker.workerSocket = void 0;
3295
+ }
3276
3296
  /** Bubbles ASSOCIATION_RECEIVED from dcmrecv worker. */
3277
3297
  wireAssociationReceived(worker) {
3278
3298
  worker.dcmrecv.onEvent("ASSOCIATION_RECEIVED", (data) => {
@@ -3377,6 +3397,10 @@ async function removeDirSafe(dirPath) {
3377
3397
  } catch {
3378
3398
  }
3379
3399
  }
3400
+ function removePending(arr, promise) {
3401
+ const idx = arr.indexOf(promise);
3402
+ if (idx !== -1) void arr.splice(idx, 1);
3403
+ }
3380
3404
  function delay(ms) {
3381
3405
  return new Promise((resolve) => {
3382
3406
  setTimeout(resolve, ms);