@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.
@@ -1718,6 +1718,12 @@ declare class DicomReceiver extends EventEmitter<DicomReceiverEventMap> {
1718
1718
  private handleFileReceived;
1719
1719
  /** Returns worker to idle pool on association complete, emits summary. */
1720
1720
  private wireAssociationComplete;
1721
+ /** Awaits pending file operations, emits ASSOCIATION_COMPLETE, resets worker state. */
1722
+ private finalizeAssociation;
1723
+ /** Emits the ASSOCIATION_COMPLETE event with transfer stats. */
1724
+ private emitAssociationComplete;
1725
+ /** Resets worker state to idle after an association completes. */
1726
+ private resetWorker;
1721
1727
  /** Bubbles ASSOCIATION_RECEIVED from dcmrecv worker. */
1722
1728
  private wireAssociationReceived;
1723
1729
  /** Bubbles C_STORE_REQUEST from dcmrecv worker. */
@@ -1718,6 +1718,12 @@ declare class DicomReceiver extends EventEmitter<DicomReceiverEventMap> {
1718
1718
  private handleFileReceived;
1719
1719
  /** Returns worker to idle pool on association complete, emits summary. */
1720
1720
  private wireAssociationComplete;
1721
+ /** Awaits pending file operations, emits ASSOCIATION_COMPLETE, resets worker state. */
1722
+ private finalizeAssociation;
1723
+ /** Emits the ASSOCIATION_COMPLETE event with transfer stats. */
1724
+ private emitAssociationComplete;
1725
+ /** Resets worker state to idle after an association completes. */
1726
+ private resetWorker;
1721
1727
  /** Bubbles ASSOCIATION_RECEIVED from dcmrecv worker. */
1722
1728
  private wireAssociationReceived;
1723
1729
  /** Bubbles C_STORE_REQUEST from dcmrecv worker. */
package/dist/index.cjs CHANGED
@@ -36447,6 +36447,7 @@ var DicomReceiver = class _DicomReceiver extends events.EventEmitter {
36447
36447
  worker.files = [];
36448
36448
  worker.fileSizes = [];
36449
36449
  worker.outputLines = [];
36450
+ worker.pendingFiles = [];
36450
36451
  worker.startAt = Date.now();
36451
36452
  this.pipeConnection(worker, remoteSocket);
36452
36453
  void this.replenishPool();
@@ -36541,6 +36542,7 @@ var DicomReceiver = class _DicomReceiver extends events.EventEmitter {
36541
36542
  files: [],
36542
36543
  fileSizes: [],
36543
36544
  outputLines: [],
36545
+ pendingFiles: [],
36544
36546
  startAt: void 0,
36545
36547
  remoteSocket: void 0,
36546
36548
  workerSocket: void 0
@@ -36615,7 +36617,9 @@ var DicomReceiver = class _DicomReceiver extends events.EventEmitter {
36615
36617
  /** Wires FILE_RECEIVED from dcmrecv worker to handleFileReceived. */
36616
36618
  wireFileReceived(worker) {
36617
36619
  worker.dcmrecv.onFileReceived((data) => {
36618
- void this.handleFileReceived(worker, data);
36620
+ const promise = this.handleFileReceived(worker, data);
36621
+ worker.pendingFiles.push(promise);
36622
+ void promise.finally(() => removePending(worker.pendingFiles, promise));
36619
36623
  });
36620
36624
  }
36621
36625
  /** Moves a received file, opens it as DicomInstance, and emits FILE_RECEIVED. */
@@ -36655,42 +36659,58 @@ var DicomReceiver = class _DicomReceiver extends events.EventEmitter {
36655
36659
  /** Returns worker to idle pool on association complete, emits summary. */
36656
36660
  wireAssociationComplete(worker) {
36657
36661
  worker.dcmrecv.onAssociationComplete((data) => {
36658
- const assocId = worker.associationId ?? data.associationId;
36659
- const assocDir = worker.associationDir ?? "";
36660
- const files = [...worker.files];
36661
- const output = [...worker.outputLines];
36662
- const endAt = Date.now();
36663
- const startAt = worker.startAt ?? endAt;
36664
- const totalBytes = sumArray(worker.fileSizes);
36665
- const elapsedMs = endAt - startAt;
36666
- const bytesPerSecond = elapsedMs > 0 ? Math.round(totalBytes / elapsedMs * 1e3) : 0;
36667
- this.emit("ASSOCIATION_COMPLETE", {
36668
- associationId: assocId,
36669
- associationDir: assocDir,
36670
- callingAE: data.callingAE,
36671
- calledAE: data.calledAE,
36672
- source: data.source,
36673
- files,
36674
- durationMs: data.durationMs,
36675
- endReason: data.endReason,
36676
- totalBytes,
36677
- bytesPerSecond,
36678
- startAt,
36679
- endAt,
36680
- output
36681
- });
36682
- worker.state = "idle";
36683
- worker.associationId = void 0;
36684
- worker.associationDir = void 0;
36685
- worker.files = [];
36686
- worker.fileSizes = [];
36687
- worker.outputLines = [];
36688
- worker.startAt = void 0;
36689
- worker.remoteSocket = void 0;
36690
- worker.workerSocket = void 0;
36691
- void this.scaleDown();
36662
+ void this.finalizeAssociation(worker, data);
36663
+ });
36664
+ }
36665
+ /** Awaits pending file operations, emits ASSOCIATION_COMPLETE, resets worker state. */
36666
+ async finalizeAssociation(worker, data) {
36667
+ if (worker.pendingFiles.length > 0) {
36668
+ await Promise.all(worker.pendingFiles);
36669
+ }
36670
+ this.emitAssociationComplete(worker, data);
36671
+ this.resetWorker(worker);
36672
+ void this.scaleDown();
36673
+ }
36674
+ /** Emits the ASSOCIATION_COMPLETE event with transfer stats. */
36675
+ emitAssociationComplete(worker, data) {
36676
+ const assocId = worker.associationId ?? data.associationId;
36677
+ const assocDir = worker.associationDir ?? "";
36678
+ const files = [...worker.files];
36679
+ const output = [...worker.outputLines];
36680
+ const endAt = Date.now();
36681
+ const startAt = worker.startAt ?? endAt;
36682
+ const totalBytes = sumArray(worker.fileSizes);
36683
+ const elapsedMs = endAt - startAt;
36684
+ const bytesPerSecond = elapsedMs > 0 ? Math.round(totalBytes / elapsedMs * 1e3) : 0;
36685
+ this.emit("ASSOCIATION_COMPLETE", {
36686
+ associationId: assocId,
36687
+ associationDir: assocDir,
36688
+ callingAE: data.callingAE,
36689
+ calledAE: data.calledAE,
36690
+ source: data.source,
36691
+ files,
36692
+ durationMs: data.durationMs,
36693
+ endReason: data.endReason,
36694
+ totalBytes,
36695
+ bytesPerSecond,
36696
+ startAt,
36697
+ endAt,
36698
+ output
36692
36699
  });
36693
36700
  }
36701
+ /** Resets worker state to idle after an association completes. */
36702
+ resetWorker(worker) {
36703
+ worker.state = "idle";
36704
+ worker.associationId = void 0;
36705
+ worker.associationDir = void 0;
36706
+ worker.files = [];
36707
+ worker.fileSizes = [];
36708
+ worker.outputLines = [];
36709
+ worker.pendingFiles = [];
36710
+ worker.startAt = void 0;
36711
+ worker.remoteSocket = void 0;
36712
+ worker.workerSocket = void 0;
36713
+ }
36694
36714
  /** Bubbles ASSOCIATION_RECEIVED from dcmrecv worker. */
36695
36715
  wireAssociationReceived(worker) {
36696
36716
  worker.dcmrecv.onEvent("ASSOCIATION_RECEIVED", (data) => {
@@ -36795,6 +36815,10 @@ async function removeDirSafe(dirPath) {
36795
36815
  } catch {
36796
36816
  }
36797
36817
  }
36818
+ function removePending(arr, promise) {
36819
+ const idx = arr.indexOf(promise);
36820
+ if (idx !== -1) void arr.splice(idx, 1);
36821
+ }
36798
36822
  function delay(ms) {
36799
36823
  return new Promise((resolve) => {
36800
36824
  setTimeout(resolve, ms);