@ubercode/dcmtk 0.7.2 → 0.8.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
@@ -263,8 +263,10 @@ interface DicomSenderOptions {
263
263
  readonly mode?: SenderModeValue | undefined;
264
264
  /** Maximum concurrent storescu associations. Defaults to 4 (forced to 1 in single mode). */
265
265
  readonly maxAssociations?: number | undefined;
266
- /** Proposed transfer syntax for associations. */
267
- readonly proposedTransferSyntax?: ProposedTransferSyntaxValue | undefined;
266
+ /** Proposed transfer syntax(es) for associations. Pass an array to propose multiple. */
267
+ readonly proposedTransferSyntax?: ProposedTransferSyntaxValue | readonly ProposedTransferSyntaxValue[] | undefined;
268
+ /** Combine proposed transfer syntaxes into fewer presentation contexts. Maps to `+C`/`--combine`. */
269
+ readonly combineProposedTransferSyntaxes?: boolean | undefined;
268
270
  /** Maximum queued send requests before rejecting. Defaults to 1000. */
269
271
  readonly maxQueueLength?: number | undefined;
270
272
  /** Per-storescu timeout in milliseconds. Defaults to 30000. */
@@ -308,6 +310,10 @@ interface SendOptions {
308
310
  readonly callingAETitle?: string | undefined;
309
311
  /** Override required flag for this send. */
310
312
  readonly required?: boolean | undefined;
313
+ /** Override proposed transfer syntax(es) for this send. */
314
+ readonly proposedTransferSyntax?: ProposedTransferSyntaxValue | readonly ProposedTransferSyntaxValue[] | undefined;
315
+ /** Override combine proposed transfer syntaxes for this send. */
316
+ readonly combineProposedTransferSyntaxes?: boolean | undefined;
311
317
  }
312
318
  /** Result of a successful send operation. */
313
319
  interface SendResult {
@@ -437,24 +443,10 @@ interface DicomSenderEventMap {
437
443
  * ```
438
444
  */
439
445
  declare class DicomSender extends EventEmitter<DicomSenderEventMap> {
440
- private readonly options;
441
- private readonly mode;
442
- private readonly configuredMaxAssociations;
443
- private readonly maxQueueLength;
446
+ private readonly engine;
444
447
  private readonly defaultTimeoutMs;
445
448
  private readonly defaultMaxRetries;
446
- private readonly retryDelayMs;
447
- private readonly bucketFlushMs;
448
- private readonly maxBucketSize;
449
- private readonly queue;
450
- private activeAssociations;
451
- private isStopped;
452
- private health;
453
- private effectiveMaxAssociations;
454
- private consecutiveFailures;
455
- private consecutiveSuccesses;
456
- private currentBucket;
457
- private bucketTimer;
449
+ private readonly signal;
458
450
  private abortHandler;
459
451
  private constructor();
460
452
  /**
@@ -480,8 +472,6 @@ declare class DicomSender extends EventEmitter<DicomSenderEventMap> {
480
472
  * @returns A Result containing the send result or an error
481
473
  */
482
474
  send(files: readonly string[], options?: SendOptions): Promise<Result<SendResult>>;
483
- /** Dispatches a send to the appropriate mode handler. */
484
- private dispatchSend;
485
475
  /**
486
476
  * Flushes the current bucket immediately (bucket mode only).
487
477
  * In single/multiple mode this is a no-op.
@@ -530,42 +520,201 @@ declare class DicomSender extends EventEmitter<DicomSenderEventMap> {
530
520
  * @returns this for chaining
531
521
  */
532
522
  onBucketFlushed(listener: (data: SenderBucketFlushedData) => void): this;
533
- /** Enqueues a send and dispatches immediately if capacity allows. */
534
- private enqueueSend;
535
- /** Drains queued entries up to available capacity. */
536
- private drainQueue;
537
- /** Adds files to the current bucket and triggers flush if full. */
538
- private enqueueBucket;
539
- /** Counts total files in the current bucket. */
540
- private countBucketFiles;
541
- /** Merges bucket entries into a single QueueEntry. */
542
- private mergeBucketEntries;
543
- /** Flushes the current bucket: combines all files, dispatches as one send. */
544
- private flushBucketInternal;
545
- /** Resets the bucket flush timer. */
546
- private resetBucketTimer;
547
- /** Clears the bucket flush timer. */
548
- private clearBucketTimer;
549
- /** Executes a single queue entry: calls storescu with retry. */
550
- private executeEntry;
551
- /** Attempts storescu up to maxAttempts times. Returns undefined on success, or failure info. */
552
- private attemptSend;
553
- /** Calls storescu with the configured options. */
554
- private callStorescu;
555
- /** Handles a successful send: updates state, emits event, resolves promise. */
556
- private handleSendSuccess;
557
- /** Records a successful send and adjusts health upward if needed. */
558
- private recordSuccess;
559
- /** Records a failed send and adjusts health downward if needed. */
560
- private recordFailure;
561
- /** Emits a HEALTH_CHANGED event. */
562
- private emitHealthChanged;
563
- /** Rejects all queued entries with the given message. */
564
- private rejectQueue;
565
- /** Rejects all bucket entries with the given message. */
566
- private rejectBucket;
567
- /** Waits for all active associations to complete. */
568
- private waitForActive;
523
+ /** Wires an AbortSignal to stop the sender. */
524
+ private wireAbortSignal;
525
+ }
526
+
527
+ /**
528
+ * High-throughput DICOM sender using the dcmsend binary.
529
+ *
530
+ * Similar interface to {@link DicomSender} but wraps `dcmsend` instead of
531
+ * `storescu`. `dcmsend` automatically proposes each file's native transfer
532
+ * syntax, avoiding the need for codec licenses when sending compressed data.
533
+ *
534
+ * @module senders/DicomSend
535
+ */
536
+
537
+ /** Options for creating a DicomSend instance. */
538
+ interface DicomSendOptions {
539
+ /** Remote host or IP address (required). */
540
+ readonly host: string;
541
+ /** Remote port number, 1-65535 (required). */
542
+ readonly port: number;
543
+ /** Called AE Title of the remote SCP (max 16 chars). */
544
+ readonly calledAETitle?: string | undefined;
545
+ /** Calling AE Title of the local SCU (max 16 chars). */
546
+ readonly callingAETitle?: string | undefined;
547
+ /** Sending mode. Defaults to 'multiple'. */
548
+ readonly mode?: 'single' | 'multiple' | 'bucket' | undefined;
549
+ /** Maximum concurrent dcmsend calls. Defaults to 4 (forced to 1 in single mode). */
550
+ readonly maxAssociations?: number | undefined;
551
+ /** Maximum queued send requests before rejecting. Defaults to 1000. */
552
+ readonly maxQueueLength?: number | undefined;
553
+ /** Per-dcmsend timeout in milliseconds. Defaults to 30000. */
554
+ readonly timeoutMs?: number | undefined;
555
+ /** Maximum retry attempts per send (0 = no retry). Defaults to 3. */
556
+ readonly maxRetries?: number | undefined;
557
+ /** Base retry delay in milliseconds. Defaults to 1000. */
558
+ readonly retryDelayMs?: number | undefined;
559
+ /** Bucket flush timeout in milliseconds (bucket mode only). Defaults to 5000. */
560
+ readonly bucketFlushMs?: number | undefined;
561
+ /** Maximum files per bucket before auto-flush (bucket mode only). Defaults to 50. */
562
+ readonly maxBucketSize?: number | undefined;
563
+ /** Maximum PDU receive size (4096-131072). Maps to `--max-pdu`. */
564
+ readonly maxPduReceive?: number | undefined;
565
+ /** Maximum PDU send size (4096-131072). Maps to `--max-send-pdu`. */
566
+ readonly maxPduSend?: number | undefined;
567
+ /** Association timeout in seconds. Maps to `-to`. */
568
+ readonly associationTimeout?: number | undefined;
569
+ /** ACSE timeout in seconds. Maps to `-ta`. */
570
+ readonly acseTimeout?: number | undefined;
571
+ /** DIMSE timeout in seconds. Maps to `-td`. */
572
+ readonly dimseTimeout?: number | undefined;
573
+ /** Disable DNS hostname lookup. Maps to `-nh`. */
574
+ readonly noHostnameLookup?: boolean | undefined;
575
+ /** Verbosity level. `'verbose'` maps to `-v`, `'debug'` maps to `-d`. */
576
+ readonly verbosity?: 'verbose' | 'debug' | undefined;
577
+ /** Do not halt on first invalid input file. Maps to `--no-halt`. */
578
+ readonly noHalt?: boolean | undefined;
579
+ /** Do not propose illegal presentation contexts. Maps to `--no-illegal-proposal`. */
580
+ readonly noIllegalProposal?: boolean | undefined;
581
+ /** Decompression mode. Maps to `--decompress-never`/`--decompress-lossless`/`--decompress-lossy`. */
582
+ readonly decompress?: 'never' | 'lossless' | 'lossy' | undefined;
583
+ /** Use multiple associations (one after the other). `true` maps to `+ma`, `false` maps to `-ma`. */
584
+ readonly multiAssociations?: boolean | undefined;
585
+ /** Disable UID validity checking. Maps to `--no-uid-checks`. */
586
+ readonly noUidChecks?: boolean | undefined;
587
+ /** AbortSignal for external cancellation. */
588
+ readonly signal?: AbortSignal | undefined;
589
+ }
590
+ /** Per-send options for DicomSend. */
591
+ interface DcmsendSendOptions {
592
+ /** Override per-dcmsend timeout for this send. */
593
+ readonly timeoutMs?: number | undefined;
594
+ /** Override max retries for this send. */
595
+ readonly maxRetries?: number | undefined;
596
+ /** Override called AE Title for this send. */
597
+ readonly calledAETitle?: string | undefined;
598
+ /** Override calling AE Title for this send. */
599
+ readonly callingAETitle?: string | undefined;
600
+ }
601
+ /** Typed event map for DicomSend. */
602
+ interface DicomSendEventMap {
603
+ SEND_COMPLETE: [SenderSendCompleteData];
604
+ SEND_FAILED: [SenderSendFailedData];
605
+ HEALTH_CHANGED: [SenderHealthChangedData];
606
+ BUCKET_FLUSHED: [SenderBucketFlushedData];
607
+ error: [{
608
+ readonly error: Error;
609
+ readonly files?: readonly string[] | undefined;
610
+ }];
611
+ }
612
+ /**
613
+ * High-throughput DICOM sender wrapping the `dcmsend` binary.
614
+ *
615
+ * Unlike {@link DicomSender} (which uses `storescu`), `DicomSend` uses
616
+ * `dcmsend` which automatically proposes each file's native transfer
617
+ * syntax. This avoids the need for commercial codec licenses when
618
+ * sending compressed DICOM data (e.g., JPEG 2000).
619
+ *
620
+ * Supports the same three sending modes as DicomSender:
621
+ * - **single**: One association at a time (FIFO queue).
622
+ * - **multiple**: Up to N concurrent associations.
623
+ * - **bucket**: Accumulates files into buckets, each flushed as one association.
624
+ *
625
+ * @example
626
+ * ```ts
627
+ * const result = DicomSend.create({
628
+ * host: '192.168.1.100',
629
+ * port: 104,
630
+ * calledAETitle: 'PACS',
631
+ * mode: 'multiple',
632
+ * maxAssociations: 8,
633
+ * });
634
+ * if (!result.ok) { console.error(result.error.message); return; }
635
+ * const sender = result.value;
636
+ *
637
+ * sender.onSendComplete(data => console.log('Sent:', data.fileCount, 'files'));
638
+ * sender.onSendFailed(data => console.error('Failed:', data.error.message));
639
+ *
640
+ * await sender.send(['/path/to/file1.dcm', '/path/to/file2.dcm']);
641
+ * await sender.stop();
642
+ * ```
643
+ */
644
+ declare class DicomSend extends EventEmitter<DicomSendEventMap> {
645
+ private readonly engine;
646
+ private readonly defaultTimeoutMs;
647
+ private readonly defaultMaxRetries;
648
+ private readonly signal;
649
+ private abortHandler;
650
+ private constructor();
651
+ /**
652
+ * Creates a new DicomSend instance.
653
+ *
654
+ * @param options - Configuration options
655
+ * @returns A Result containing the instance or a validation error
656
+ */
657
+ static create(options: DicomSendOptions): Result<DicomSend>;
658
+ /**
659
+ * Sends one or more DICOM files to the remote endpoint.
660
+ *
661
+ * In single/multiple mode, files are sent as one dcmsend call.
662
+ * In bucket mode, files are accumulated into a bucket and flushed
663
+ * when the bucket reaches maxBucketSize or the flush timer fires.
664
+ *
665
+ * @param files - One or more DICOM file paths
666
+ * @param options - Per-send overrides
667
+ * @returns A Result containing the send result or an error
668
+ */
669
+ send(files: readonly string[], options?: DcmsendSendOptions): Promise<Result<SendResult>>;
670
+ /**
671
+ * Flushes the current bucket immediately (bucket mode only).
672
+ * In single/multiple mode this is a no-op.
673
+ */
674
+ flush(): void;
675
+ /**
676
+ * Gracefully stops the sender. Rejects all queued items and
677
+ * waits for active associations to complete.
678
+ */
679
+ stop(): Promise<void>;
680
+ /** Current sender status. */
681
+ get status(): SenderStatus;
682
+ /**
683
+ * Registers a typed listener for a DicomSend-specific event.
684
+ *
685
+ * @param event - The event name from DicomSendEventMap
686
+ * @param listener - Callback receiving typed event data
687
+ * @returns this for chaining
688
+ */
689
+ onEvent<K extends keyof DicomSendEventMap>(event: K, listener: (...args: DicomSendEventMap[K]) => void): this;
690
+ /**
691
+ * Registers a listener for successful sends.
692
+ *
693
+ * @param listener - Callback receiving send complete data
694
+ * @returns this for chaining
695
+ */
696
+ onSendComplete(listener: (data: SenderSendCompleteData) => void): this;
697
+ /**
698
+ * Registers a listener for failed sends.
699
+ *
700
+ * @param listener - Callback receiving send failed data
701
+ * @returns this for chaining
702
+ */
703
+ onSendFailed(listener: (data: SenderSendFailedData) => void): this;
704
+ /**
705
+ * Registers a listener for health state changes.
706
+ *
707
+ * @param listener - Callback receiving health change data
708
+ * @returns this for chaining
709
+ */
710
+ onHealthChanged(listener: (data: SenderHealthChangedData) => void): this;
711
+ /**
712
+ * Registers a listener for bucket flushes (bucket mode only).
713
+ *
714
+ * @param listener - Callback receiving bucket flush data
715
+ * @returns this for chaining
716
+ */
717
+ onBucketFlushed(listener: (data: SenderBucketFlushedData) => void): this;
569
718
  /** Wires an AbortSignal to stop the sender. */
570
719
  private wireAbortSignal;
571
720
  }
@@ -865,4 +1014,4 @@ declare class PacsClient {
865
1014
  private executeCMove;
866
1015
  }
867
1016
 
868
- export { AETitle, AETitleSchema, DEFAULT_BLOCK_TIMEOUT_MS, DEFAULT_DICOM_PORT, DEFAULT_DRAIN_TIMEOUT_MS, DEFAULT_PARSE_CONCURRENCY, DEFAULT_START_TIMEOUT_MS, DEFAULT_TIMEOUT_MS, DcmtkProcessResult, DicomDataset, DicomSender, type DicomSenderEventMap, type DicomSenderOptions, DicomTag, DicomTagPath, DicomTagPathSchema, DicomTagSchema, ExecOptions, type FindDcmtkPathOptions, type ImageFilter, MAX_BLOCK_LINES, MAX_CHANGESET_OPERATIONS, MAX_EVENT_PATTERNS, MAX_TRAVERSAL_DEPTH, PDU_SIZE, PacsClient, type PacsClientConfig, type PacsEchoOptions, type PacsEchoResult, type PacsMethodOptions, type PacsQueryOptions, type PacsQueryResult, type PacsRetrieveOptions, type PacsRetrieveResult, type PacsStoreOptions, type PacsStoreResult, Port, PortSchema, ProposedTransferSyntaxValue, QueryLevel, type QueryLevelValue, REQUIRED_BINARIES, Result, RetrieveMode, type RetrieveModeValue, SOPClassUID, type SendOptions, type SendResult, type SenderBucketFlushedData, type SenderErrorData, SenderHealth, type SenderHealthChangedData, type SenderHealthValue, SenderMode, type SenderModeValue, type SenderSendCompleteData, type SenderSendFailedData, type SenderStatus, type SeriesFilter, SpawnOptions, type StudyFilter, TransferSyntaxUID, UIDSchema, UNIX_SEARCH_PATHS, WINDOWS_SEARCH_PATHS, type WorklistFilter, clearDcmtkPathCache, execCommand, findDcmtkPath, parseAETitle, parseDicomTag, parseDicomTagPath, parsePort, parseSOPClassUID, parseTransferSyntaxUID, spawnCommand };
1017
+ export { AETitle, AETitleSchema, DEFAULT_BLOCK_TIMEOUT_MS, DEFAULT_DICOM_PORT, DEFAULT_DRAIN_TIMEOUT_MS, DEFAULT_PARSE_CONCURRENCY, DEFAULT_START_TIMEOUT_MS, DEFAULT_TIMEOUT_MS, type DcmsendSendOptions, DcmtkProcessResult, DicomDataset, DicomSend, type DicomSendEventMap, type DicomSendOptions, DicomSender, type DicomSenderEventMap, type DicomSenderOptions, DicomTag, DicomTagPath, DicomTagPathSchema, DicomTagSchema, ExecOptions, type FindDcmtkPathOptions, type ImageFilter, MAX_BLOCK_LINES, MAX_CHANGESET_OPERATIONS, MAX_EVENT_PATTERNS, MAX_TRAVERSAL_DEPTH, PDU_SIZE, PacsClient, type PacsClientConfig, type PacsEchoOptions, type PacsEchoResult, type PacsMethodOptions, type PacsQueryOptions, type PacsQueryResult, type PacsRetrieveOptions, type PacsRetrieveResult, type PacsStoreOptions, type PacsStoreResult, Port, PortSchema, ProposedTransferSyntaxValue, QueryLevel, type QueryLevelValue, REQUIRED_BINARIES, Result, RetrieveMode, type RetrieveModeValue, SOPClassUID, type SendOptions, type SendResult, type SenderBucketFlushedData, type SenderErrorData, SenderHealth, type SenderHealthChangedData, type SenderHealthValue, SenderMode, type SenderModeValue, type SenderSendCompleteData, type SenderSendFailedData, type SenderStatus, type SeriesFilter, SpawnOptions, type StudyFilter, TransferSyntaxUID, UIDSchema, UNIX_SEARCH_PATHS, WINDOWS_SEARCH_PATHS, type WorklistFilter, clearDcmtkPathCache, execCommand, findDcmtkPath, parseAETitle, parseDicomTag, parseDicomTagPath, parsePort, parseSOPClassUID, parseTransferSyntaxUID, spawnCommand };
package/dist/index.d.ts CHANGED
@@ -263,8 +263,10 @@ interface DicomSenderOptions {
263
263
  readonly mode?: SenderModeValue | undefined;
264
264
  /** Maximum concurrent storescu associations. Defaults to 4 (forced to 1 in single mode). */
265
265
  readonly maxAssociations?: number | undefined;
266
- /** Proposed transfer syntax for associations. */
267
- readonly proposedTransferSyntax?: ProposedTransferSyntaxValue | undefined;
266
+ /** Proposed transfer syntax(es) for associations. Pass an array to propose multiple. */
267
+ readonly proposedTransferSyntax?: ProposedTransferSyntaxValue | readonly ProposedTransferSyntaxValue[] | undefined;
268
+ /** Combine proposed transfer syntaxes into fewer presentation contexts. Maps to `+C`/`--combine`. */
269
+ readonly combineProposedTransferSyntaxes?: boolean | undefined;
268
270
  /** Maximum queued send requests before rejecting. Defaults to 1000. */
269
271
  readonly maxQueueLength?: number | undefined;
270
272
  /** Per-storescu timeout in milliseconds. Defaults to 30000. */
@@ -308,6 +310,10 @@ interface SendOptions {
308
310
  readonly callingAETitle?: string | undefined;
309
311
  /** Override required flag for this send. */
310
312
  readonly required?: boolean | undefined;
313
+ /** Override proposed transfer syntax(es) for this send. */
314
+ readonly proposedTransferSyntax?: ProposedTransferSyntaxValue | readonly ProposedTransferSyntaxValue[] | undefined;
315
+ /** Override combine proposed transfer syntaxes for this send. */
316
+ readonly combineProposedTransferSyntaxes?: boolean | undefined;
311
317
  }
312
318
  /** Result of a successful send operation. */
313
319
  interface SendResult {
@@ -437,24 +443,10 @@ interface DicomSenderEventMap {
437
443
  * ```
438
444
  */
439
445
  declare class DicomSender extends EventEmitter<DicomSenderEventMap> {
440
- private readonly options;
441
- private readonly mode;
442
- private readonly configuredMaxAssociations;
443
- private readonly maxQueueLength;
446
+ private readonly engine;
444
447
  private readonly defaultTimeoutMs;
445
448
  private readonly defaultMaxRetries;
446
- private readonly retryDelayMs;
447
- private readonly bucketFlushMs;
448
- private readonly maxBucketSize;
449
- private readonly queue;
450
- private activeAssociations;
451
- private isStopped;
452
- private health;
453
- private effectiveMaxAssociations;
454
- private consecutiveFailures;
455
- private consecutiveSuccesses;
456
- private currentBucket;
457
- private bucketTimer;
449
+ private readonly signal;
458
450
  private abortHandler;
459
451
  private constructor();
460
452
  /**
@@ -480,8 +472,6 @@ declare class DicomSender extends EventEmitter<DicomSenderEventMap> {
480
472
  * @returns A Result containing the send result or an error
481
473
  */
482
474
  send(files: readonly string[], options?: SendOptions): Promise<Result<SendResult>>;
483
- /** Dispatches a send to the appropriate mode handler. */
484
- private dispatchSend;
485
475
  /**
486
476
  * Flushes the current bucket immediately (bucket mode only).
487
477
  * In single/multiple mode this is a no-op.
@@ -530,42 +520,201 @@ declare class DicomSender extends EventEmitter<DicomSenderEventMap> {
530
520
  * @returns this for chaining
531
521
  */
532
522
  onBucketFlushed(listener: (data: SenderBucketFlushedData) => void): this;
533
- /** Enqueues a send and dispatches immediately if capacity allows. */
534
- private enqueueSend;
535
- /** Drains queued entries up to available capacity. */
536
- private drainQueue;
537
- /** Adds files to the current bucket and triggers flush if full. */
538
- private enqueueBucket;
539
- /** Counts total files in the current bucket. */
540
- private countBucketFiles;
541
- /** Merges bucket entries into a single QueueEntry. */
542
- private mergeBucketEntries;
543
- /** Flushes the current bucket: combines all files, dispatches as one send. */
544
- private flushBucketInternal;
545
- /** Resets the bucket flush timer. */
546
- private resetBucketTimer;
547
- /** Clears the bucket flush timer. */
548
- private clearBucketTimer;
549
- /** Executes a single queue entry: calls storescu with retry. */
550
- private executeEntry;
551
- /** Attempts storescu up to maxAttempts times. Returns undefined on success, or failure info. */
552
- private attemptSend;
553
- /** Calls storescu with the configured options. */
554
- private callStorescu;
555
- /** Handles a successful send: updates state, emits event, resolves promise. */
556
- private handleSendSuccess;
557
- /** Records a successful send and adjusts health upward if needed. */
558
- private recordSuccess;
559
- /** Records a failed send and adjusts health downward if needed. */
560
- private recordFailure;
561
- /** Emits a HEALTH_CHANGED event. */
562
- private emitHealthChanged;
563
- /** Rejects all queued entries with the given message. */
564
- private rejectQueue;
565
- /** Rejects all bucket entries with the given message. */
566
- private rejectBucket;
567
- /** Waits for all active associations to complete. */
568
- private waitForActive;
523
+ /** Wires an AbortSignal to stop the sender. */
524
+ private wireAbortSignal;
525
+ }
526
+
527
+ /**
528
+ * High-throughput DICOM sender using the dcmsend binary.
529
+ *
530
+ * Similar interface to {@link DicomSender} but wraps `dcmsend` instead of
531
+ * `storescu`. `dcmsend` automatically proposes each file's native transfer
532
+ * syntax, avoiding the need for codec licenses when sending compressed data.
533
+ *
534
+ * @module senders/DicomSend
535
+ */
536
+
537
+ /** Options for creating a DicomSend instance. */
538
+ interface DicomSendOptions {
539
+ /** Remote host or IP address (required). */
540
+ readonly host: string;
541
+ /** Remote port number, 1-65535 (required). */
542
+ readonly port: number;
543
+ /** Called AE Title of the remote SCP (max 16 chars). */
544
+ readonly calledAETitle?: string | undefined;
545
+ /** Calling AE Title of the local SCU (max 16 chars). */
546
+ readonly callingAETitle?: string | undefined;
547
+ /** Sending mode. Defaults to 'multiple'. */
548
+ readonly mode?: 'single' | 'multiple' | 'bucket' | undefined;
549
+ /** Maximum concurrent dcmsend calls. Defaults to 4 (forced to 1 in single mode). */
550
+ readonly maxAssociations?: number | undefined;
551
+ /** Maximum queued send requests before rejecting. Defaults to 1000. */
552
+ readonly maxQueueLength?: number | undefined;
553
+ /** Per-dcmsend timeout in milliseconds. Defaults to 30000. */
554
+ readonly timeoutMs?: number | undefined;
555
+ /** Maximum retry attempts per send (0 = no retry). Defaults to 3. */
556
+ readonly maxRetries?: number | undefined;
557
+ /** Base retry delay in milliseconds. Defaults to 1000. */
558
+ readonly retryDelayMs?: number | undefined;
559
+ /** Bucket flush timeout in milliseconds (bucket mode only). Defaults to 5000. */
560
+ readonly bucketFlushMs?: number | undefined;
561
+ /** Maximum files per bucket before auto-flush (bucket mode only). Defaults to 50. */
562
+ readonly maxBucketSize?: number | undefined;
563
+ /** Maximum PDU receive size (4096-131072). Maps to `--max-pdu`. */
564
+ readonly maxPduReceive?: number | undefined;
565
+ /** Maximum PDU send size (4096-131072). Maps to `--max-send-pdu`. */
566
+ readonly maxPduSend?: number | undefined;
567
+ /** Association timeout in seconds. Maps to `-to`. */
568
+ readonly associationTimeout?: number | undefined;
569
+ /** ACSE timeout in seconds. Maps to `-ta`. */
570
+ readonly acseTimeout?: number | undefined;
571
+ /** DIMSE timeout in seconds. Maps to `-td`. */
572
+ readonly dimseTimeout?: number | undefined;
573
+ /** Disable DNS hostname lookup. Maps to `-nh`. */
574
+ readonly noHostnameLookup?: boolean | undefined;
575
+ /** Verbosity level. `'verbose'` maps to `-v`, `'debug'` maps to `-d`. */
576
+ readonly verbosity?: 'verbose' | 'debug' | undefined;
577
+ /** Do not halt on first invalid input file. Maps to `--no-halt`. */
578
+ readonly noHalt?: boolean | undefined;
579
+ /** Do not propose illegal presentation contexts. Maps to `--no-illegal-proposal`. */
580
+ readonly noIllegalProposal?: boolean | undefined;
581
+ /** Decompression mode. Maps to `--decompress-never`/`--decompress-lossless`/`--decompress-lossy`. */
582
+ readonly decompress?: 'never' | 'lossless' | 'lossy' | undefined;
583
+ /** Use multiple associations (one after the other). `true` maps to `+ma`, `false` maps to `-ma`. */
584
+ readonly multiAssociations?: boolean | undefined;
585
+ /** Disable UID validity checking. Maps to `--no-uid-checks`. */
586
+ readonly noUidChecks?: boolean | undefined;
587
+ /** AbortSignal for external cancellation. */
588
+ readonly signal?: AbortSignal | undefined;
589
+ }
590
+ /** Per-send options for DicomSend. */
591
+ interface DcmsendSendOptions {
592
+ /** Override per-dcmsend timeout for this send. */
593
+ readonly timeoutMs?: number | undefined;
594
+ /** Override max retries for this send. */
595
+ readonly maxRetries?: number | undefined;
596
+ /** Override called AE Title for this send. */
597
+ readonly calledAETitle?: string | undefined;
598
+ /** Override calling AE Title for this send. */
599
+ readonly callingAETitle?: string | undefined;
600
+ }
601
+ /** Typed event map for DicomSend. */
602
+ interface DicomSendEventMap {
603
+ SEND_COMPLETE: [SenderSendCompleteData];
604
+ SEND_FAILED: [SenderSendFailedData];
605
+ HEALTH_CHANGED: [SenderHealthChangedData];
606
+ BUCKET_FLUSHED: [SenderBucketFlushedData];
607
+ error: [{
608
+ readonly error: Error;
609
+ readonly files?: readonly string[] | undefined;
610
+ }];
611
+ }
612
+ /**
613
+ * High-throughput DICOM sender wrapping the `dcmsend` binary.
614
+ *
615
+ * Unlike {@link DicomSender} (which uses `storescu`), `DicomSend` uses
616
+ * `dcmsend` which automatically proposes each file's native transfer
617
+ * syntax. This avoids the need for commercial codec licenses when
618
+ * sending compressed DICOM data (e.g., JPEG 2000).
619
+ *
620
+ * Supports the same three sending modes as DicomSender:
621
+ * - **single**: One association at a time (FIFO queue).
622
+ * - **multiple**: Up to N concurrent associations.
623
+ * - **bucket**: Accumulates files into buckets, each flushed as one association.
624
+ *
625
+ * @example
626
+ * ```ts
627
+ * const result = DicomSend.create({
628
+ * host: '192.168.1.100',
629
+ * port: 104,
630
+ * calledAETitle: 'PACS',
631
+ * mode: 'multiple',
632
+ * maxAssociations: 8,
633
+ * });
634
+ * if (!result.ok) { console.error(result.error.message); return; }
635
+ * const sender = result.value;
636
+ *
637
+ * sender.onSendComplete(data => console.log('Sent:', data.fileCount, 'files'));
638
+ * sender.onSendFailed(data => console.error('Failed:', data.error.message));
639
+ *
640
+ * await sender.send(['/path/to/file1.dcm', '/path/to/file2.dcm']);
641
+ * await sender.stop();
642
+ * ```
643
+ */
644
+ declare class DicomSend extends EventEmitter<DicomSendEventMap> {
645
+ private readonly engine;
646
+ private readonly defaultTimeoutMs;
647
+ private readonly defaultMaxRetries;
648
+ private readonly signal;
649
+ private abortHandler;
650
+ private constructor();
651
+ /**
652
+ * Creates a new DicomSend instance.
653
+ *
654
+ * @param options - Configuration options
655
+ * @returns A Result containing the instance or a validation error
656
+ */
657
+ static create(options: DicomSendOptions): Result<DicomSend>;
658
+ /**
659
+ * Sends one or more DICOM files to the remote endpoint.
660
+ *
661
+ * In single/multiple mode, files are sent as one dcmsend call.
662
+ * In bucket mode, files are accumulated into a bucket and flushed
663
+ * when the bucket reaches maxBucketSize or the flush timer fires.
664
+ *
665
+ * @param files - One or more DICOM file paths
666
+ * @param options - Per-send overrides
667
+ * @returns A Result containing the send result or an error
668
+ */
669
+ send(files: readonly string[], options?: DcmsendSendOptions): Promise<Result<SendResult>>;
670
+ /**
671
+ * Flushes the current bucket immediately (bucket mode only).
672
+ * In single/multiple mode this is a no-op.
673
+ */
674
+ flush(): void;
675
+ /**
676
+ * Gracefully stops the sender. Rejects all queued items and
677
+ * waits for active associations to complete.
678
+ */
679
+ stop(): Promise<void>;
680
+ /** Current sender status. */
681
+ get status(): SenderStatus;
682
+ /**
683
+ * Registers a typed listener for a DicomSend-specific event.
684
+ *
685
+ * @param event - The event name from DicomSendEventMap
686
+ * @param listener - Callback receiving typed event data
687
+ * @returns this for chaining
688
+ */
689
+ onEvent<K extends keyof DicomSendEventMap>(event: K, listener: (...args: DicomSendEventMap[K]) => void): this;
690
+ /**
691
+ * Registers a listener for successful sends.
692
+ *
693
+ * @param listener - Callback receiving send complete data
694
+ * @returns this for chaining
695
+ */
696
+ onSendComplete(listener: (data: SenderSendCompleteData) => void): this;
697
+ /**
698
+ * Registers a listener for failed sends.
699
+ *
700
+ * @param listener - Callback receiving send failed data
701
+ * @returns this for chaining
702
+ */
703
+ onSendFailed(listener: (data: SenderSendFailedData) => void): this;
704
+ /**
705
+ * Registers a listener for health state changes.
706
+ *
707
+ * @param listener - Callback receiving health change data
708
+ * @returns this for chaining
709
+ */
710
+ onHealthChanged(listener: (data: SenderHealthChangedData) => void): this;
711
+ /**
712
+ * Registers a listener for bucket flushes (bucket mode only).
713
+ *
714
+ * @param listener - Callback receiving bucket flush data
715
+ * @returns this for chaining
716
+ */
717
+ onBucketFlushed(listener: (data: SenderBucketFlushedData) => void): this;
569
718
  /** Wires an AbortSignal to stop the sender. */
570
719
  private wireAbortSignal;
571
720
  }
@@ -865,4 +1014,4 @@ declare class PacsClient {
865
1014
  private executeCMove;
866
1015
  }
867
1016
 
868
- export { AETitle, AETitleSchema, DEFAULT_BLOCK_TIMEOUT_MS, DEFAULT_DICOM_PORT, DEFAULT_DRAIN_TIMEOUT_MS, DEFAULT_PARSE_CONCURRENCY, DEFAULT_START_TIMEOUT_MS, DEFAULT_TIMEOUT_MS, DcmtkProcessResult, DicomDataset, DicomSender, type DicomSenderEventMap, type DicomSenderOptions, DicomTag, DicomTagPath, DicomTagPathSchema, DicomTagSchema, ExecOptions, type FindDcmtkPathOptions, type ImageFilter, MAX_BLOCK_LINES, MAX_CHANGESET_OPERATIONS, MAX_EVENT_PATTERNS, MAX_TRAVERSAL_DEPTH, PDU_SIZE, PacsClient, type PacsClientConfig, type PacsEchoOptions, type PacsEchoResult, type PacsMethodOptions, type PacsQueryOptions, type PacsQueryResult, type PacsRetrieveOptions, type PacsRetrieveResult, type PacsStoreOptions, type PacsStoreResult, Port, PortSchema, ProposedTransferSyntaxValue, QueryLevel, type QueryLevelValue, REQUIRED_BINARIES, Result, RetrieveMode, type RetrieveModeValue, SOPClassUID, type SendOptions, type SendResult, type SenderBucketFlushedData, type SenderErrorData, SenderHealth, type SenderHealthChangedData, type SenderHealthValue, SenderMode, type SenderModeValue, type SenderSendCompleteData, type SenderSendFailedData, type SenderStatus, type SeriesFilter, SpawnOptions, type StudyFilter, TransferSyntaxUID, UIDSchema, UNIX_SEARCH_PATHS, WINDOWS_SEARCH_PATHS, type WorklistFilter, clearDcmtkPathCache, execCommand, findDcmtkPath, parseAETitle, parseDicomTag, parseDicomTagPath, parsePort, parseSOPClassUID, parseTransferSyntaxUID, spawnCommand };
1017
+ export { AETitle, AETitleSchema, DEFAULT_BLOCK_TIMEOUT_MS, DEFAULT_DICOM_PORT, DEFAULT_DRAIN_TIMEOUT_MS, DEFAULT_PARSE_CONCURRENCY, DEFAULT_START_TIMEOUT_MS, DEFAULT_TIMEOUT_MS, type DcmsendSendOptions, DcmtkProcessResult, DicomDataset, DicomSend, type DicomSendEventMap, type DicomSendOptions, DicomSender, type DicomSenderEventMap, type DicomSenderOptions, DicomTag, DicomTagPath, DicomTagPathSchema, DicomTagSchema, ExecOptions, type FindDcmtkPathOptions, type ImageFilter, MAX_BLOCK_LINES, MAX_CHANGESET_OPERATIONS, MAX_EVENT_PATTERNS, MAX_TRAVERSAL_DEPTH, PDU_SIZE, PacsClient, type PacsClientConfig, type PacsEchoOptions, type PacsEchoResult, type PacsMethodOptions, type PacsQueryOptions, type PacsQueryResult, type PacsRetrieveOptions, type PacsRetrieveResult, type PacsStoreOptions, type PacsStoreResult, Port, PortSchema, ProposedTransferSyntaxValue, QueryLevel, type QueryLevelValue, REQUIRED_BINARIES, Result, RetrieveMode, type RetrieveModeValue, SOPClassUID, type SendOptions, type SendResult, type SenderBucketFlushedData, type SenderErrorData, SenderHealth, type SenderHealthChangedData, type SenderHealthValue, SenderMode, type SenderModeValue, type SenderSendCompleteData, type SenderSendFailedData, type SenderStatus, type SeriesFilter, SpawnOptions, type StudyFilter, TransferSyntaxUID, UIDSchema, UNIX_SEARCH_PATHS, WINDOWS_SEARCH_PATHS, type WorklistFilter, clearDcmtkPathCache, execCommand, findDcmtkPath, parseAETitle, parseDicomTag, parseDicomTagPath, parsePort, parseSOPClassUID, parseTransferSyntaxUID, spawnCommand };