@clearmist-labs/comic-archive-handler 1.6.0 → 1.7.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.mts CHANGED
@@ -30,6 +30,12 @@ export interface ImageConvertOptions {
30
30
  jpeg?: JpegOptions;
31
31
  png?: PngOptions;
32
32
  }
33
+ /**
34
+ * How many images an archive operation converts at once. A function is called
35
+ * again before each conversion starts, so the limit can change while an archive
36
+ * is being processed. Values below 1 are treated as 1.
37
+ */
38
+ export type ImageConcurrency = number | (() => number);
33
39
  /** Shared by every archive-producing operation. */
34
40
  export interface ArchiveWriteOptions {
35
41
  /**
@@ -49,6 +55,8 @@ export interface ConvertArchiveOptions extends ArchiveWriteOptions {
49
55
  image?: {
50
56
  format: ImageOutputFormat;
51
57
  options?: ImageConvertOptions;
58
+ /** How many images to convert at once. Defaults to `1`. */
59
+ concurrency?: ImageConcurrency;
52
60
  };
53
61
  /**
54
62
  * Replaces the source's embedded comic metadata in the output. The source's
@@ -469,7 +477,21 @@ export declare function removeComicMetadata(input: ArchiveInput, schema: Metadat
469
477
  //#endregion
470
478
  //#region src/images/convert.d.ts
471
479
  export declare function convertImageBuffer(image: Buffer, format: ImageOutputFormat, options?: ImageConvertOptions): Promise<Buffer>;
472
- export declare function convertArchiveImages(input: ArchiveInput, format: ImageOutputFormat, options?: ImageConvertOptions & ArchiveWriteOptions): Promise<Buffer | void>;
480
+ export declare function convertArchiveImages(input: ArchiveInput, format: ImageOutputFormat, options?: ImageConvertOptions & ArchiveWriteOptions & {
481
+ concurrency?: ImageConcurrency;
482
+ }): Promise<Buffer | void>;
483
+ //#endregion
484
+ //#region src/images/concurrency.d.ts
485
+ /**
486
+ * Sets how many libvips threads process each image, and returns the value now
487
+ * in effect. The setting is process-wide and applies to every image operation
488
+ * this package performs (conversion, dimensions, perceptual hashing). Callers
489
+ * that already parallelize across images (one worker thread per core, say)
490
+ * should pass `1` so each image doesn't also fan out across every core.
491
+ * sharp's default is the CPU core count, except on glibc Linux without
492
+ * jemalloc, where it is already `1`.
493
+ */
494
+ export declare function setImageConcurrency(threads: number): number;
473
495
  //#endregion
474
496
  //#region src/images/phash.d.ts
475
497
  /**
@@ -609,6 +631,7 @@ export declare function renderBenchmarkReportMarkdown(result: BenchmarkArchiveRe
609
631
  declare const comicArchiveHandler: {
610
632
  convertImageBuffer: typeof convertImageBuffer;
611
633
  convertArchiveImages: typeof convertArchiveImages;
634
+ setImageConcurrency: typeof setImageConcurrency;
612
635
  computeImagePHash: typeof computeImagePHash;
613
636
  phashToHex: typeof phashToHex;
614
637
  computeArchiveImagePHash: typeof computeArchiveImagePHash;
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.mts","names":[],"sources":["../src/types.ts","../src/benchmark/types.ts","../src/errors.ts","../src/detect.ts","../src/convertArchive.ts","../src/extractArchive.ts","../src/metadata/comicInfo.ts","../src/metadata/metronInfo.ts","../src/metadata/validate.ts","../src/metadata/schema.ts","../src/metadata/index.ts","../src/images/convert.ts","../src/images/phash.ts","../src/images/dimensions.ts","../src/images/isImage.ts","../src/hashing/sha256.ts","../src/rename.ts","../src/strip.ts","../src/listFiles.ts","../src/readArchiveEntry.ts","../src/readArchiveEntries.ts","../src/readArchiveImageInfo.ts","../src/removeArchiveEntry.ts","../src/benchmark/benchmarkArchive.ts","../src/benchmark/report.ts","../src/index.ts"],"mappings":"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"}
1
+ {"version":3,"file":"index.d.mts","names":[],"sources":["../src/types.ts","../src/benchmark/types.ts","../src/errors.ts","../src/detect.ts","../src/convertArchive.ts","../src/extractArchive.ts","../src/metadata/comicInfo.ts","../src/metadata/metronInfo.ts","../src/metadata/validate.ts","../src/metadata/schema.ts","../src/metadata/index.ts","../src/images/convert.ts","../src/images/concurrency.ts","../src/images/phash.ts","../src/images/dimensions.ts","../src/images/isImage.ts","../src/hashing/sha256.ts","../src/rename.ts","../src/strip.ts","../src/listFiles.ts","../src/readArchiveEntry.ts","../src/readArchiveEntries.ts","../src/readArchiveImageInfo.ts","../src/removeArchiveEntry.ts","../src/benchmark/benchmarkArchive.ts","../src/benchmark/report.ts","../src/index.ts"],"mappings":"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"}
package/dist/index.mjs CHANGED
@@ -814,6 +814,43 @@ function getAdapter(type) {
814
814
  return adapter;
815
815
  }
816
816
  //#endregion
817
+ //#region src/internal/convertEntriesConcurrently.ts
818
+ function resolveLimit(concurrency) {
819
+ const value = typeof concurrency === "function" ? concurrency() : concurrency;
820
+ return Number.isFinite(value) ? Math.max(1, Math.floor(value)) : 1;
821
+ }
822
+ /**
823
+ * Maps source entries to write entries, running up to `concurrency` image
824
+ * conversions at once while preserving entry order. Each image's bytes are
825
+ * read before the source iterator advances, so adapters whose entry streams
826
+ * are only valid until the next entry keep working. A pass-through entry is
827
+ * yielded only after every earlier conversion has been yielded, and before the
828
+ * source advances, since its content is read lazily by the writer. A function
829
+ * `concurrency` is re-read before each new conversion starts, so the limit can
830
+ * follow the caller's load while the archive is being converted.
831
+ */
832
+ async function* convertEntriesConcurrently(source, shouldConvert, convert, passThrough, concurrency = 1) {
833
+ const pending = [];
834
+ try {
835
+ for await (const entry of source) {
836
+ if (shouldConvert(entry)) {
837
+ const task = convert(entry, await streamToBuffer(entry.openReadStream()));
838
+ task.catch(() => void 0);
839
+ pending.push(task);
840
+ while (pending.length >= resolveLimit(concurrency)) yield await pending.shift();
841
+ continue;
842
+ }
843
+ const output = passThrough(entry);
844
+ if (!output) continue;
845
+ while (pending.length > 0) yield await pending.shift();
846
+ yield output;
847
+ }
848
+ while (pending.length > 0) yield await pending.shift();
849
+ } finally {
850
+ await Promise.allSettled(pending);
851
+ }
852
+ }
853
+ //#endregion
817
854
  //#region src/images/isImage.ts
818
855
  const IMAGE_EXTENSIONS = [
819
856
  "jpg",
@@ -862,22 +899,20 @@ function replaceExtension$1(entryPath, format) {
862
899
  }
863
900
  async function convertArchiveImages(input, format, options = {}) {
864
901
  const adapter = getAdapter(await detectArchiveType(input));
865
- const { tempDir, output, ...imageOptions } = options;
866
- async function* entries() {
867
- for await (const entry of adapter.listEntries(input, { tempDir })) if (isImagePath(entry.path) && getExtension(entry.path) !== (format === "jpg" ? "jpg" : format)) {
868
- const converted = await convertImageBuffer(await streamToBuffer(entry.openReadStream()), format, imageOptions);
869
- yield {
870
- path: replaceExtension$1(entry.path, format),
871
- size: converted.length,
872
- content: Readable.from(converted)
873
- };
874
- } else yield {
875
- path: entry.path,
876
- size: entry.size,
877
- content: entry.openReadStream()
902
+ const { tempDir, output, concurrency, ...imageOptions } = options;
903
+ const entries = convertEntriesConcurrently(adapter.listEntries(input, { tempDir }), (entry) => isImagePath(entry.path) && getExtension(entry.path) !== (format === "jpg" ? "jpg" : format), async (entry, buffer) => {
904
+ const converted = await convertImageBuffer(buffer, format, imageOptions);
905
+ return {
906
+ path: replaceExtension$1(entry.path, format),
907
+ size: converted.length,
908
+ content: Readable.from(converted)
878
909
  };
879
- }
880
- return withOutput(output, (destination) => adapter.write(entries(), destination, { tempDir }));
910
+ }, (entry) => ({
911
+ path: entry.path,
912
+ size: entry.size,
913
+ content: entry.openReadStream()
914
+ }), concurrency);
915
+ return withOutput(output, (destination) => adapter.write(entries, destination, { tempDir }));
881
916
  }
882
917
  //#endregion
883
918
  //#region src/removeArchiveEntry.ts
@@ -1900,21 +1935,19 @@ async function convertArchive(input, targetType, options = {}) {
1900
1935
  const image = options.image;
1901
1936
  const metadata = options.metadata;
1902
1937
  async function* entries() {
1903
- for await (const entry of sourceAdapter.listEntries(input, { tempDir: options.tempDir })) {
1904
- if (metadata && METADATA_FILE_NAMES.has(entry.path.split("/").pop() ?? "")) continue;
1905
- if (image && isImagePath(entry.path) && getExtension(entry.path) !== (image.format === "jpg" ? "jpg" : image.format)) {
1906
- const converted = await convertImageBuffer(await streamToBuffer(entry.openReadStream()), image.format, image.options);
1907
- yield {
1908
- path: replaceExtension(entry.path, image.format === "jpg" ? "jpg" : image.format),
1909
- size: converted.length,
1910
- content: Readable.from(converted)
1911
- };
1912
- } else yield {
1913
- path: entry.path,
1914
- size: entry.size,
1915
- content: entry.openReadStream()
1938
+ const imageExtension = image?.format === "jpg" ? "jpg" : image?.format;
1939
+ yield* convertEntriesConcurrently(sourceAdapter.listEntries(input, { tempDir: options.tempDir }), (entry) => Boolean(image) && isImagePath(entry.path) && getExtension(entry.path) !== imageExtension, async (entry, buffer) => {
1940
+ const converted = await convertImageBuffer(buffer, image.format, image.options);
1941
+ return {
1942
+ path: replaceExtension(entry.path, imageExtension),
1943
+ size: converted.length,
1944
+ content: Readable.from(converted)
1916
1945
  };
1917
- }
1946
+ }, (entry) => metadata && METADATA_FILE_NAMES.has(entry.path.split("/").pop() ?? "") ? void 0 : {
1947
+ path: entry.path,
1948
+ size: entry.size,
1949
+ content: entry.openReadStream()
1950
+ }, image?.concurrency);
1918
1951
  if (metadata && targetType !== "asar") for (const schema of Object.keys(metadata)) {
1919
1952
  const value = metadata[schema];
1920
1953
  if (!value) continue;
@@ -1953,6 +1986,20 @@ async function extractArchive(input, destDir, options = {}) {
1953
1986
  return written;
1954
1987
  }
1955
1988
  //#endregion
1989
+ //#region src/images/concurrency.ts
1990
+ /**
1991
+ * Sets how many libvips threads process each image, and returns the value now
1992
+ * in effect. The setting is process-wide and applies to every image operation
1993
+ * this package performs (conversion, dimensions, perceptual hashing). Callers
1994
+ * that already parallelize across images (one worker thread per core, say)
1995
+ * should pass `1` so each image doesn't also fan out across every core.
1996
+ * sharp's default is the CPU core count, except on glibc Linux without
1997
+ * jemalloc, where it is already `1`.
1998
+ */
1999
+ function setImageConcurrency(threads) {
2000
+ return sharp.concurrency(threads);
2001
+ }
2002
+ //#endregion
1956
2003
  //#region src/images/phash.ts
1957
2004
  const HASH_SIZE = 32;
1958
2005
  const BLOCK_SIZE = 8;
@@ -2467,6 +2514,7 @@ const comicArchiveHandler = {
2467
2514
  ...metadata_exports,
2468
2515
  convertImageBuffer,
2469
2516
  convertArchiveImages,
2517
+ setImageConcurrency,
2470
2518
  computeImagePHash,
2471
2519
  phashToHex,
2472
2520
  computeArchiveImagePHash,
@@ -2491,6 +2539,6 @@ const comicArchiveHandler = {
2491
2539
  ARCHIVE_TYPE_EXTENSIONS
2492
2540
  };
2493
2541
  //#endregion
2494
- export { ARCHIVE_TYPE_EXTENSIONS, ArchiveFormatError, BENCHMARK_IMAGE_FORMATS, COMIC_INFO_AGE_RATING_VALUES, COMIC_INFO_CREDIT_ROLES, COMIC_INFO_MANGA_VALUES, COMIC_INFO_PAGE_TYPE_VALUES, COMIC_INFO_YES_NO_VALUES, FilesystemAccessError, IMAGE_EXTENSIONS, METRON_AGE_RATING_VALUES, METRON_FORMAT_VALUES, METRON_INFORMATION_SOURCE_VALUES, METRON_ROLE_VALUES, MetadataNotFoundError, NoImagesFoundError, SevenZipUnavailableError, UnsupportedOperationError, WRITABLE_ARCHIVE_TYPES, addMetadataToArchive, benchmarkArchive, comicInfoXmlToMetadata, computeArchiveImagePHash, computeImagePHash, convertArchive, convertArchiveImages, convertImageBuffer, comicArchiveHandler as default, detectArchiveType, extractArchive, getExtension, hammingDistance, hasComicMetadata, is7z, isAce, isAsar, isImagePath, isRar, isTar, isZip, joinCommaList, joinResourceNames, listArchiveFiles, metadataToComicInfoXml, metadataToMetronInfoXml, metadataToXml, metronInfoXmlToMetadata, phashToHex, readArchiveEntries, readArchiveEntry, readArchiveImageInfo, readArchiveMetadata, readImageDimensions, readImageInfo, removeArchiveEntry, removeComicMetadata, renameArchiveImagesSequentially, renderBenchmarkReportMarkdown, resourceId, resourceName, sha256Archive, sha256ArchiveEntry, splitCommaList, stripNonEssentialFiles, validateMetadataXml, xmlToMetadata };
2542
+ export { ARCHIVE_TYPE_EXTENSIONS, ArchiveFormatError, BENCHMARK_IMAGE_FORMATS, COMIC_INFO_AGE_RATING_VALUES, COMIC_INFO_CREDIT_ROLES, COMIC_INFO_MANGA_VALUES, COMIC_INFO_PAGE_TYPE_VALUES, COMIC_INFO_YES_NO_VALUES, FilesystemAccessError, IMAGE_EXTENSIONS, METRON_AGE_RATING_VALUES, METRON_FORMAT_VALUES, METRON_INFORMATION_SOURCE_VALUES, METRON_ROLE_VALUES, MetadataNotFoundError, NoImagesFoundError, SevenZipUnavailableError, UnsupportedOperationError, WRITABLE_ARCHIVE_TYPES, addMetadataToArchive, benchmarkArchive, comicInfoXmlToMetadata, computeArchiveImagePHash, computeImagePHash, convertArchive, convertArchiveImages, convertImageBuffer, comicArchiveHandler as default, detectArchiveType, extractArchive, getExtension, hammingDistance, hasComicMetadata, is7z, isAce, isAsar, isImagePath, isRar, isTar, isZip, joinCommaList, joinResourceNames, listArchiveFiles, metadataToComicInfoXml, metadataToMetronInfoXml, metadataToXml, metronInfoXmlToMetadata, phashToHex, readArchiveEntries, readArchiveEntry, readArchiveImageInfo, readArchiveMetadata, readImageDimensions, readImageInfo, removeArchiveEntry, removeComicMetadata, renameArchiveImagesSequentially, renderBenchmarkReportMarkdown, resourceId, resourceName, setImageConcurrency, sha256Archive, sha256ArchiveEntry, splitCommaList, stripNonEssentialFiles, validateMetadataXml, xmlToMetadata };
2495
2543
 
2496
2544
  //# sourceMappingURL=index.mjs.map