@ubercode/dcmtk 0.11.0 → 0.12.0

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/index.d.cts CHANGED
@@ -3,7 +3,7 @@ export { L as LineSource, P as ProcessLine, a as ResultValue, b as assertUnreach
3
3
  import { A as AETitle, D as DicomTag, a as DicomTagPath, P as Port, S as SOPClassUID, T as TransferSyntaxUID, b as DicomDataset } from './DicomInstance-CxLKC-oM.cjs';
4
4
  export { B as Brand, C as ChangeSet, c as DicomFilePath, d as DicomInstance, e as DicomOpenOptions, W as WalkTagEntry, f as WalkTagsOptions, g as createAETitle, h as createDicomFilePath, i as createDicomTag, j as createDicomTagPath, k as createPort, l as createSOPClassUID, m as createTransferSyntaxUID, t as tag, w as walkTags } from './DicomInstance-CxLKC-oM.cjs';
5
5
  import { z } from 'zod';
6
- export { A as AssociationAcknowledgedData, a as AssociationCompleteData, b as AssociationContext, c as AssociationReceivedData, d as AssociationSummary, e as AssociationTracker, C as CStoreRequestData, f as CannotStartListenerData, g as ConfigErrorData, D as DCMPRSCP_FATAL_EVENTS, h as DCMPRSCP_PATTERNS, i as DCMPSRCV_FATAL_EVENTS, j as DCMPSRCV_PATTERNS, k as DCMQRSCP_FATAL_EVENTS, l as DCMQRSCP_PATTERNS, m as DCMRECV_FATAL_EVENTS, n as DCMRECV_PATTERNS, o as DatabaseReadyData, p as DcmQRSCP, q as DcmQRSCPEventMap, r as DcmQRSCPOptions, s as DcmprsCP, t as DcmprsCPEventMap, u as DcmprsCPOptions, v as DcmprscpEvent, w as DcmprscpEventValue, x as Dcmpsrcv, y as DcmpsrcvEvent, z as DcmpsrcvEventMap, B as DcmpsrcvEventValue, E as DcmpsrcvOptions, F as DcmqrscpEvent, G as DcmqrscpEventValue, H as Dcmrecv, I as DcmrecvEvent, J as DcmrecvEventMap, K as DcmrecvEventValue, L as DcmrecvOptions, M as DcmtkProcess, N as DcmtkProcessConfig, O as DcmtkProcessEventMap, P as DicomReceiver, Q as DicomReceiverEventMap, R as DicomReceiverOptions, S as EventPattern, T as FileDeletedData, U as FileReceivedData, V as FilenameMode, W as FilenameModeValue, X as LineParser, Y as LineParserEventMap, Z as MultiLineConfig, _ as PoolAssociationReceivedData, $ as PoolCStoreRequestData, a0 as PoolEchoRequestData, a1 as PoolRefusingAssociationData, a2 as PoolStatus, a3 as PreferredTransferSyntax, a4 as PreferredTransferSyntaxValue, a5 as PrintAssociationAcknowledgedData, a6 as PrintAssociationReceivedData, a7 as PrintCannotStartListenerData, a8 as ProcessState, a9 as ProcessStateValue, aa as QRAssociationAcknowledgedData, ab as QRAssociationReceivedData, ac as QRCFindRequestData, ad as QRCGetRequestData, ae as QRCMoveRequestData, af as QRCStoreRequestData, ag as QRCannotStartListenerData, ah as QRListeningData, ai as ReceiverAssociationAcknowledgedData, aj as ReceiverAssociationData, ak as ReceiverAssociationReceivedData, al as ReceiverCStoreRequestData, am as ReceiverCannotStartListenerData, an as ReceiverConfigErrorData, ao as ReceiverDatabaseReadyData, ap as ReceiverEchoRequestData, aq as ReceiverErrorData, ar as ReceiverFileData, as as ReceiverFileReceivedData, at as ReceiverFileStoredData, au as ReceiverInstanceData, av as ReceiverListeningData, aw as RefusingAssociationData, ax as STORESCP_FATAL_EVENTS, ay as STORESCP_PATTERNS, az as StorageMode, aA as StorageModeValue, aB as StoreSCP, aC as StoreSCPEventMap, aD as StoreSCPOptions, aE as StoreSCPPreset, aF as StoreSCPPresetName, aG as StoredFileData, aH as StorescpEvent, aI as StorescpEventValue, aJ as StoringFileData, aK as SubdirectoryCreatedData, aL as SubdirectoryMode, aM as SubdirectoryModeValue, aN as TrackedFile, aO as WLMSCPFS_FATAL_EVENTS, aP as WLMSCPFS_PATTERNS, aQ as WlmAssociationAcknowledgedData, aR as WlmAssociationReceivedData, aS as WlmCFindRequestData, aT as WlmCannotStartListenerData, aU as WlmListeningData, aV as Wlmscpfs, aW as WlmscpfsEvent, aX as WlmscpfsEventMap, aY as WlmscpfsEventValue, aZ as WlmscpfsOptions } from './index-CVDMaxd8.cjs';
6
+ export { A as AssociationAcknowledgedData, a as AssociationCompleteData, b as AssociationContext, c as AssociationReceivedData, d as AssociationSummary, e as AssociationTracker, C as CStoreRequestData, f as CannotStartListenerData, g as ConfigErrorData, D as DCMPRSCP_FATAL_EVENTS, h as DCMPRSCP_PATTERNS, i as DCMPSRCV_FATAL_EVENTS, j as DCMPSRCV_PATTERNS, k as DCMQRSCP_FATAL_EVENTS, l as DCMQRSCP_PATTERNS, m as DCMRECV_FATAL_EVENTS, n as DCMRECV_PATTERNS, o as DatabaseReadyData, p as DcmQRSCP, q as DcmQRSCPEventMap, r as DcmQRSCPOptions, s as DcmprsCP, t as DcmprsCPEventMap, u as DcmprsCPOptions, v as DcmprscpEvent, w as DcmprscpEventValue, x as Dcmpsrcv, y as DcmpsrcvEvent, z as DcmpsrcvEventMap, B as DcmpsrcvEventValue, E as DcmpsrcvOptions, F as DcmqrscpEvent, G as DcmqrscpEventValue, H as Dcmrecv, I as DcmrecvEvent, J as DcmrecvEventMap, K as DcmrecvEventValue, L as DcmrecvOptions, M as DcmtkProcess, N as DcmtkProcessConfig, O as DcmtkProcessEventMap, P as DicomReceiver, Q as DicomReceiverEventMap, R as DicomReceiverOptions, S as EventPattern, T as FileDeletedData, U as FileReceivedData, V as FilenameMode, W as FilenameModeValue, X as LineParser, Y as LineParserEventMap, Z as MultiLineConfig, _ as PoolAssociationReceivedData, $ as PoolCStoreRequestData, a0 as PoolEchoRequestData, a1 as PoolRefusingAssociationData, a2 as PoolStatus, a3 as PreferredTransferSyntax, a4 as PreferredTransferSyntaxValue, a5 as PrintAssociationAcknowledgedData, a6 as PrintAssociationReceivedData, a7 as PrintCannotStartListenerData, a8 as ProcessState, a9 as ProcessStateValue, aa as QRAssociationAcknowledgedData, ab as QRAssociationReceivedData, ac as QRCFindRequestData, ad as QRCGetRequestData, ae as QRCMoveRequestData, af as QRCStoreRequestData, ag as QRCannotStartListenerData, ah as QRListeningData, ai as ReceiverAssociationAcknowledgedData, aj as ReceiverAssociationData, ak as ReceiverAssociationFinalizedData, al as ReceiverAssociationReceivedData, am as ReceiverCStoreRequestData, an as ReceiverCannotStartListenerData, ao as ReceiverConfigErrorData, ap as ReceiverDatabaseReadyData, aq as ReceiverEchoRequestData, ar as ReceiverErrorData, as as ReceiverFileData, at as ReceiverFileReceivedData, au as ReceiverFileStoredData, av as ReceiverInstanceData, aw as ReceiverInstanceErrorData, ax as ReceiverListeningData, ay as RefusingAssociationData, az as STORESCP_FATAL_EVENTS, aA as STORESCP_PATTERNS, aB as StorageMode, aC as StorageModeValue, aD as StoreSCP, aE as StoreSCPEventMap, aF as StoreSCPOptions, aG as StoreSCPPreset, aH as StoreSCPPresetName, aI as StoredFileData, aJ as StorescpEvent, aK as StorescpEventValue, aL as StoringFileData, aM as SubdirectoryCreatedData, aN as SubdirectoryMode, aO as SubdirectoryModeValue, aP as TrackedFile, aQ as WLMSCPFS_FATAL_EVENTS, aR as WLMSCPFS_PATTERNS, aS as WlmAssociationAcknowledgedData, aT as WlmAssociationReceivedData, aU as WlmCFindRequestData, aV as WlmCannotStartListenerData, aW as WlmListeningData, aX as Wlmscpfs, aY as WlmscpfsEvent, aZ as WlmscpfsEventMap, a_ as WlmscpfsEventValue, a$ as WlmscpfsOptions } from './index-DV8HaHEX.cjs';
7
7
  import { T as TagModification } from './dcmodify-Cf-RPHF3.cjs';
8
8
  export { b as DcmodifyOptions, c as DcmodifyResult, D as DicomJsonElement, a as DicomJsonModel, d as ToolBaseOptions, e as dcmodify, x as xmlToJson } from './dcmodify-Cf-RPHF3.cjs';
9
9
  export { DictionaryEntry, SOPClassName, SOP_CLASSES, TagSegment, VR, VRCategoryName, VRMetadata, VRValue, VR_CATEGORY, VR_CATEGORY_NAME, VR_META, getVRCategory, isBinaryVR, isNumericVR, isStringVR, lookupTag, lookupTagByKeyword, lookupTagByName, segmentsToModifyPath, segmentsToString, sopClassNameFromUID, tagPathToSegments } from './dicom.cjs';
package/dist/index.d.ts CHANGED
@@ -3,7 +3,7 @@ export { L as LineSource, P as ProcessLine, a as ResultValue, b as assertUnreach
3
3
  import { A as AETitle, D as DicomTag, a as DicomTagPath, P as Port, S as SOPClassUID, T as TransferSyntaxUID, b as DicomDataset } from './DicomInstance-BKUiir0G.js';
4
4
  export { B as Brand, C as ChangeSet, c as DicomFilePath, d as DicomInstance, e as DicomOpenOptions, W as WalkTagEntry, f as WalkTagsOptions, g as createAETitle, h as createDicomFilePath, i as createDicomTag, j as createDicomTagPath, k as createPort, l as createSOPClassUID, m as createTransferSyntaxUID, t as tag, w as walkTags } from './DicomInstance-BKUiir0G.js';
5
5
  import { z } from 'zod';
6
- export { A as AssociationAcknowledgedData, a as AssociationCompleteData, b as AssociationContext, c as AssociationReceivedData, d as AssociationSummary, e as AssociationTracker, C as CStoreRequestData, f as CannotStartListenerData, g as ConfigErrorData, D as DCMPRSCP_FATAL_EVENTS, h as DCMPRSCP_PATTERNS, i as DCMPSRCV_FATAL_EVENTS, j as DCMPSRCV_PATTERNS, k as DCMQRSCP_FATAL_EVENTS, l as DCMQRSCP_PATTERNS, m as DCMRECV_FATAL_EVENTS, n as DCMRECV_PATTERNS, o as DatabaseReadyData, p as DcmQRSCP, q as DcmQRSCPEventMap, r as DcmQRSCPOptions, s as DcmprsCP, t as DcmprsCPEventMap, u as DcmprsCPOptions, v as DcmprscpEvent, w as DcmprscpEventValue, x as Dcmpsrcv, y as DcmpsrcvEvent, z as DcmpsrcvEventMap, B as DcmpsrcvEventValue, E as DcmpsrcvOptions, F as DcmqrscpEvent, G as DcmqrscpEventValue, H as Dcmrecv, I as DcmrecvEvent, J as DcmrecvEventMap, K as DcmrecvEventValue, L as DcmrecvOptions, M as DcmtkProcess, N as DcmtkProcessConfig, O as DcmtkProcessEventMap, P as DicomReceiver, Q as DicomReceiverEventMap, R as DicomReceiverOptions, S as EventPattern, T as FileDeletedData, U as FileReceivedData, V as FilenameMode, W as FilenameModeValue, X as LineParser, Y as LineParserEventMap, Z as MultiLineConfig, _ as PoolAssociationReceivedData, $ as PoolCStoreRequestData, a0 as PoolEchoRequestData, a1 as PoolRefusingAssociationData, a2 as PoolStatus, a3 as PreferredTransferSyntax, a4 as PreferredTransferSyntaxValue, a5 as PrintAssociationAcknowledgedData, a6 as PrintAssociationReceivedData, a7 as PrintCannotStartListenerData, a8 as ProcessState, a9 as ProcessStateValue, aa as QRAssociationAcknowledgedData, ab as QRAssociationReceivedData, ac as QRCFindRequestData, ad as QRCGetRequestData, ae as QRCMoveRequestData, af as QRCStoreRequestData, ag as QRCannotStartListenerData, ah as QRListeningData, ai as ReceiverAssociationAcknowledgedData, aj as ReceiverAssociationData, ak as ReceiverAssociationReceivedData, al as ReceiverCStoreRequestData, am as ReceiverCannotStartListenerData, an as ReceiverConfigErrorData, ao as ReceiverDatabaseReadyData, ap as ReceiverEchoRequestData, aq as ReceiverErrorData, ar as ReceiverFileData, as as ReceiverFileReceivedData, at as ReceiverFileStoredData, au as ReceiverInstanceData, av as ReceiverListeningData, aw as RefusingAssociationData, ax as STORESCP_FATAL_EVENTS, ay as STORESCP_PATTERNS, az as StorageMode, aA as StorageModeValue, aB as StoreSCP, aC as StoreSCPEventMap, aD as StoreSCPOptions, aE as StoreSCPPreset, aF as StoreSCPPresetName, aG as StoredFileData, aH as StorescpEvent, aI as StorescpEventValue, aJ as StoringFileData, aK as SubdirectoryCreatedData, aL as SubdirectoryMode, aM as SubdirectoryModeValue, aN as TrackedFile, aO as WLMSCPFS_FATAL_EVENTS, aP as WLMSCPFS_PATTERNS, aQ as WlmAssociationAcknowledgedData, aR as WlmAssociationReceivedData, aS as WlmCFindRequestData, aT as WlmCannotStartListenerData, aU as WlmListeningData, aV as Wlmscpfs, aW as WlmscpfsEvent, aX as WlmscpfsEventMap, aY as WlmscpfsEventValue, aZ as WlmscpfsOptions } from './index--dDQfutR.js';
6
+ export { A as AssociationAcknowledgedData, a as AssociationCompleteData, b as AssociationContext, c as AssociationReceivedData, d as AssociationSummary, e as AssociationTracker, C as CStoreRequestData, f as CannotStartListenerData, g as ConfigErrorData, D as DCMPRSCP_FATAL_EVENTS, h as DCMPRSCP_PATTERNS, i as DCMPSRCV_FATAL_EVENTS, j as DCMPSRCV_PATTERNS, k as DCMQRSCP_FATAL_EVENTS, l as DCMQRSCP_PATTERNS, m as DCMRECV_FATAL_EVENTS, n as DCMRECV_PATTERNS, o as DatabaseReadyData, p as DcmQRSCP, q as DcmQRSCPEventMap, r as DcmQRSCPOptions, s as DcmprsCP, t as DcmprsCPEventMap, u as DcmprsCPOptions, v as DcmprscpEvent, w as DcmprscpEventValue, x as Dcmpsrcv, y as DcmpsrcvEvent, z as DcmpsrcvEventMap, B as DcmpsrcvEventValue, E as DcmpsrcvOptions, F as DcmqrscpEvent, G as DcmqrscpEventValue, H as Dcmrecv, I as DcmrecvEvent, J as DcmrecvEventMap, K as DcmrecvEventValue, L as DcmrecvOptions, M as DcmtkProcess, N as DcmtkProcessConfig, O as DcmtkProcessEventMap, P as DicomReceiver, Q as DicomReceiverEventMap, R as DicomReceiverOptions, S as EventPattern, T as FileDeletedData, U as FileReceivedData, V as FilenameMode, W as FilenameModeValue, X as LineParser, Y as LineParserEventMap, Z as MultiLineConfig, _ as PoolAssociationReceivedData, $ as PoolCStoreRequestData, a0 as PoolEchoRequestData, a1 as PoolRefusingAssociationData, a2 as PoolStatus, a3 as PreferredTransferSyntax, a4 as PreferredTransferSyntaxValue, a5 as PrintAssociationAcknowledgedData, a6 as PrintAssociationReceivedData, a7 as PrintCannotStartListenerData, a8 as ProcessState, a9 as ProcessStateValue, aa as QRAssociationAcknowledgedData, ab as QRAssociationReceivedData, ac as QRCFindRequestData, ad as QRCGetRequestData, ae as QRCMoveRequestData, af as QRCStoreRequestData, ag as QRCannotStartListenerData, ah as QRListeningData, ai as ReceiverAssociationAcknowledgedData, aj as ReceiverAssociationData, ak as ReceiverAssociationFinalizedData, al as ReceiverAssociationReceivedData, am as ReceiverCStoreRequestData, an as ReceiverCannotStartListenerData, ao as ReceiverConfigErrorData, ap as ReceiverDatabaseReadyData, aq as ReceiverEchoRequestData, ar as ReceiverErrorData, as as ReceiverFileData, at as ReceiverFileReceivedData, au as ReceiverFileStoredData, av as ReceiverInstanceData, aw as ReceiverInstanceErrorData, ax as ReceiverListeningData, ay as RefusingAssociationData, az as STORESCP_FATAL_EVENTS, aA as STORESCP_PATTERNS, aB as StorageMode, aC as StorageModeValue, aD as StoreSCP, aE as StoreSCPEventMap, aF as StoreSCPOptions, aG as StoreSCPPreset, aH as StoreSCPPresetName, aI as StoredFileData, aJ as StorescpEvent, aK as StorescpEventValue, aL as StoringFileData, aM as SubdirectoryCreatedData, aN as SubdirectoryMode, aO as SubdirectoryModeValue, aP as TrackedFile, aQ as WLMSCPFS_FATAL_EVENTS, aR as WLMSCPFS_PATTERNS, aS as WlmAssociationAcknowledgedData, aT as WlmAssociationReceivedData, aU as WlmCFindRequestData, aV as WlmCannotStartListenerData, aW as WlmListeningData, aX as Wlmscpfs, aY as WlmscpfsEvent, aZ as WlmscpfsEventMap, a_ as WlmscpfsEventValue, a$ as WlmscpfsOptions } from './index-B5FQoIqM.js';
7
7
  import { T as TagModification } from './dcmodify-CHvwChFu.js';
8
8
  export { b as DcmodifyOptions, c as DcmodifyResult, D as DicomJsonElement, a as DicomJsonModel, d as ToolBaseOptions, e as dcmodify, x as xmlToJson } from './dcmodify-CHvwChFu.js';
9
9
  export { DictionaryEntry, SOPClassName, SOP_CLASSES, TagSegment, VR, VRCategoryName, VRMetadata, VRValue, VR_CATEGORY, VR_CATEGORY_NAME, VR_META, getVRCategory, isBinaryVR, isNumericVR, isStringVR, lookupTag, lookupTagByKeyword, lookupTagByName, segmentsToModifyPath, segmentsToString, sopClassNameFromUID, tagPathToSegments } from './dicom.js';
package/dist/index.js CHANGED
@@ -36459,6 +36459,9 @@ var Worker = class {
36459
36459
  __publicField(this, "_state", "idle");
36460
36460
  __publicField(this, "_context");
36461
36461
  __publicField(this, "_pending", /* @__PURE__ */ new Set());
36462
+ __publicField(this, "_instancePending", /* @__PURE__ */ new Set());
36463
+ __publicField(this, "_instancesReceived", 0);
36464
+ __publicField(this, "_instanceErrors", 0);
36462
36465
  __publicField(this, "_files", []);
36463
36466
  __publicField(this, "_fileSizes", []);
36464
36467
  __publicField(this, "_outputLines", []);
@@ -36496,6 +36499,9 @@ var Worker = class {
36496
36499
  this._fileSizes.length = 0;
36497
36500
  this._outputLines.length = 0;
36498
36501
  this._pending.clear();
36502
+ this._instancePending.clear();
36503
+ this._instancesReceived = 0;
36504
+ this._instanceErrors = 0;
36499
36505
  }
36500
36506
  /** Returns the worker to idle and clears all association state. */
36501
36507
  endAssociation() {
@@ -36505,6 +36511,9 @@ var Worker = class {
36505
36511
  this._fileSizes.length = 0;
36506
36512
  this._outputLines.length = 0;
36507
36513
  this._pending.clear();
36514
+ this._instancePending.clear();
36515
+ this._instancesReceived = 0;
36516
+ this._instanceErrors = 0;
36508
36517
  this._remoteSocket = void 0;
36509
36518
  this._workerSocket = void 0;
36510
36519
  }
@@ -36515,6 +36524,35 @@ var Worker = class {
36515
36524
  this._pending.delete(promise);
36516
36525
  });
36517
36526
  }
36527
+ /** Tracks an in-flight instance parsing promise; auto-removes on completion. */
36528
+ trackInstance(promise) {
36529
+ this._instancePending.add(promise);
36530
+ void promise.finally(() => {
36531
+ this._instancePending.delete(promise);
36532
+ });
36533
+ }
36534
+ /** Records a successful instance parse. */
36535
+ recordInstanceSuccess() {
36536
+ this._instancesReceived++;
36537
+ }
36538
+ /** Records a failed instance parse. */
36539
+ recordInstanceError() {
36540
+ this._instanceErrors++;
36541
+ }
36542
+ /** Awaits all in-flight instance parsing promises. */
36543
+ async drainInstancePending() {
36544
+ if (this._instancePending.size > 0) {
36545
+ await Promise.all(this._instancePending);
36546
+ }
36547
+ }
36548
+ /** Number of successfully parsed instances in this association. */
36549
+ get instancesReceived() {
36550
+ return this._instancesReceived;
36551
+ }
36552
+ /** Number of failed instance parses in this association. */
36553
+ get instanceErrors() {
36554
+ return this._instanceErrors;
36555
+ }
36518
36556
  /** Records a successfully received file path and its size. */
36519
36557
  recordFile(filePath, size) {
36520
36558
  this._files.push(filePath);
@@ -36686,7 +36724,16 @@ var DicomReceiver = class _DicomReceiver extends EventEmitter {
36686
36724
  return this.on("INSTANCE_RECEIVED", listener);
36687
36725
  }
36688
36726
  /**
36689
- * Registers a listener for completed associations.
36727
+ * Registers a listener for DicomInstance.open failures.
36728
+ *
36729
+ * @param listener - Callback receiving instance error data
36730
+ * @returns this for chaining
36731
+ */
36732
+ onInstanceError(listener) {
36733
+ return this.on("INSTANCE_ERROR", listener);
36734
+ }
36735
+ /**
36736
+ * Registers a listener for completed associations (file moves done).
36690
36737
  *
36691
36738
  * @param listener - Callback receiving association data
36692
36739
  * @returns this for chaining
@@ -36694,6 +36741,15 @@ var DicomReceiver = class _DicomReceiver extends EventEmitter {
36694
36741
  onAssociationComplete(listener) {
36695
36742
  return this.on("ASSOCIATION_COMPLETE", listener);
36696
36743
  }
36744
+ /**
36745
+ * Registers a listener for fully finalized associations (all parsing done).
36746
+ *
36747
+ * @param listener - Callback receiving finalized data with instance counts
36748
+ * @returns this for chaining
36749
+ */
36750
+ onAssociationFinalized(listener) {
36751
+ return this.on("ASSOCIATION_FINALIZED", listener);
36752
+ }
36697
36753
  /**
36698
36754
  * Registers a listener for new associations (bubbled from workers).
36699
36755
  *
@@ -37023,34 +37079,33 @@ var DicomReceiver = class _DicomReceiver extends EventEmitter {
37023
37079
  calledAE: data.calledAE,
37024
37080
  source: data.source
37025
37081
  });
37026
- this.emitInstanceReceived(finalPath, fileSize, data, ctx);
37082
+ const instanceCtx = {
37083
+ filePath: finalPath,
37084
+ fileSize,
37085
+ associationId: ctx.associationId,
37086
+ associationDir: ctx.associationDir,
37087
+ callingAE: data.callingAE,
37088
+ calledAE: data.calledAE,
37089
+ source: data.source
37090
+ };
37091
+ worker.trackInstance(this.parseAndEmitInstance(worker, instanceCtx));
37027
37092
  }
37028
- /** Parses a DICOM file and emits INSTANCE_RECEIVED or error. */
37029
- emitInstanceReceived(filePath, fileSize, data, ctx) {
37030
- void DicomInstance.open(filePath).then((openResult) => {
37093
+ /** Parses a DICOM file and emits INSTANCE_RECEIVED or INSTANCE_ERROR. */
37094
+ async parseAndEmitInstance(worker, ctx) {
37095
+ try {
37096
+ const openResult = await DicomInstance.open(ctx.filePath);
37031
37097
  if (!openResult.ok) {
37032
- this.emit("error", {
37033
- error: openResult.error,
37034
- filePath,
37035
- associationId: ctx.associationId,
37036
- associationDir: ctx.associationDir,
37037
- callingAE: data.callingAE,
37038
- calledAE: data.calledAE,
37039
- source: data.source
37040
- });
37098
+ worker.recordInstanceError();
37099
+ this.emit("INSTANCE_ERROR", { error: openResult.error, thrown: false, ...ctx });
37041
37100
  return;
37042
37101
  }
37043
- this.emit("INSTANCE_RECEIVED", {
37044
- filePath,
37045
- fileSize,
37046
- associationId: ctx.associationId,
37047
- associationDir: ctx.associationDir,
37048
- callingAE: data.callingAE,
37049
- calledAE: data.calledAE,
37050
- source: data.source,
37051
- instance: openResult.value
37052
- });
37053
- });
37102
+ worker.recordInstanceSuccess();
37103
+ this.emit("INSTANCE_RECEIVED", { ...ctx, instance: openResult.value });
37104
+ } catch (thrown) {
37105
+ const error = thrown instanceof Error ? thrown : new Error(String(thrown));
37106
+ worker.recordInstanceError();
37107
+ this.emit("INSTANCE_ERROR", { error, thrown: true, ...ctx });
37108
+ }
37054
37109
  }
37055
37110
  /** Returns worker to idle pool on association complete, emits summary. */
37056
37111
  wireAssociationComplete(worker) {
@@ -37058,10 +37113,12 @@ var DicomReceiver = class _DicomReceiver extends EventEmitter {
37058
37113
  void this.finalizeAssociation(worker, data);
37059
37114
  });
37060
37115
  }
37061
- /** Awaits ALL pending file operations, emits ASSOCIATION_COMPLETE, resets worker state. */
37116
+ /** Awaits file ops, emits ASSOCIATION_COMPLETE, awaits parsing, emits ASSOCIATION_FINALIZED. */
37062
37117
  async finalizeAssociation(worker, data) {
37063
37118
  await worker.drainPendingFiles();
37064
37119
  this.emitAssociationComplete(worker, data);
37120
+ await worker.drainInstancePending();
37121
+ this.emitAssociationFinalized(worker, data);
37065
37122
  worker.endAssociation();
37066
37123
  void this.scaleDown();
37067
37124
  }
@@ -37093,6 +37150,20 @@ var DicomReceiver = class _DicomReceiver extends EventEmitter {
37093
37150
  output
37094
37151
  });
37095
37152
  }
37153
+ /** Emits ASSOCIATION_FINALIZED after all instance parsing is done. */
37154
+ emitAssociationFinalized(worker, data) {
37155
+ const ctx = worker.context;
37156
+ this.emit("ASSOCIATION_FINALIZED", {
37157
+ associationId: ctx?.associationId ?? data.associationId,
37158
+ associationDir: ctx?.associationDir ?? "",
37159
+ callingAE: data.callingAE,
37160
+ calledAE: data.calledAE,
37161
+ source: data.source,
37162
+ files: [...worker.files],
37163
+ instancesReceived: worker.instancesReceived,
37164
+ instanceErrors: worker.instanceErrors
37165
+ });
37166
+ }
37096
37167
  /** Bubbles ASSOCIATION_RECEIVED from dcmrecv worker. */
37097
37168
  wireAssociationReceived(worker) {
37098
37169
  worker.dcmrecv.onEvent("ASSOCIATION_RECEIVED", (data) => {