From 30618cb76c4cc56f8becc754bef6ca95c05daf11 Mon Sep 17 00:00:00 2001 From: Pascal Birchler Date: Tue, 27 Aug 2024 18:37:27 +0200 Subject: [PATCH] Clean up vips package, improve docs --- packages/vips/src/index.ts | 83 +++++++++----------------------------- packages/vips/src/types.ts | 2 + packages/vips/src/utils.ts | 64 +++++++++++++++++++++++++++++ 3 files changed, 84 insertions(+), 65 deletions(-) create mode 100644 packages/vips/src/utils.ts diff --git a/packages/vips/src/index.ts b/packages/vips/src/index.ts index 0bd78f53..abcb79b4 100644 --- a/packages/vips/src/index.ts +++ b/packages/vips/src/index.ts @@ -19,11 +19,18 @@ import VipsJxlModule from 'wasm-vips/vips-jxl.wasm'; * Internal dependencies */ import type { + ItemId, ImageSizeCrop, LoadOptions, SaveOptions, ThumbnailOptions, } from './types'; +import { + isFileTypeSupported, + supportsAnimation, + supportsInterlace, + supportsQuality, +} from './utils'; type EmscriptenModule = { setAutoDeleteLater: ( autoDelete: boolean ) => void; @@ -35,7 +42,10 @@ let location = ''; /** * Dynamically sets the location / public path to use for loading the WASM files. * - * @param newLocation Location, typically a base URL such as "https://example.com/wp-content/...". + * This is required when loading this module in an inline worker, + * where globals such as __webpack_public_path__ are not available. + * + * @param newLocation Location, typically a base URL such as "https://example.com/path/to/js/...". */ export function setLocation( newLocation: string ) { location = newLocation; @@ -45,8 +55,6 @@ let cleanup: () => void; let vipsInstance: typeof Vips; -type ItemId = string; - /** * Instantiates and returns a new vips instance. * @@ -82,51 +90,18 @@ async function getVips(): Promise< typeof Vips > { } /** - * Determines whether a given file type supports a quality setting, - * - * @todo Make this smarter. - * - * @param type Mime type. - * @return Whether the file supports a quality setting. - */ -function supportsQuality( - type: string -): type is 'image/jpeg' | 'image/png' | 'image/webp' | 'image/avif' { - return [ 'image/jpeg', 'image/png', 'image/webp', 'image/avif' ].includes( - type - ); -} - -/** - * Determines whether a given file type supports animation, - * - * @todo Make this smarter. - * - * @param type Mime type. - * @return Whether the file supports animation. - */ -function supportsAnimation( type: string ): type is 'image/webp' | 'image/gif' { - return [ 'image/webp', 'image/gif' ].includes( type ); -} - -/** - * Determines whether a given file type supports interlaced/progressive output. - * - * @todo Make this smarter. + * Holds a list of ongoing operations for a given ID. * - * @param type Mime type. - * @return Whether the file supports interlaced/progressive output. + * This way, operations can be cancelled mid-progress. */ -function supportsInterlace( - type: string -): type is 'image/jpeg' | 'image/gif' | 'image/png' { - return [ 'image/jpeg', 'image/gif', 'image/png' ].includes( type ); -} - const inProgressOperations = new Set< ItemId >(); /** * Cancels all ongoing image operations for a given item ID. + * + * The onProgress callbacks check for an IDs existence in this list, + * killing the process if it's absence. + * * @param id Item ID. * @return boolean Whether any operation was cancelled. */ @@ -143,6 +118,7 @@ export async function cancelOperations( id: ItemId ) { * @param outputType Output mime type. * @param quality Desired quality. * @param interlaced Whether to use interlaced/progressive mode. + * Only used if the outputType supports it. */ export async function convertImageFormat( id: ItemId, @@ -198,29 +174,6 @@ export async function convertImageFormat( return result; } -/** - * Determines whether a given file type is supported by vips. - * - * @param type Mime type. - * @return Whether the file type is supported. - */ -function isFileTypeSupported( - type: string -): type is - | 'image/jpeg' - | 'image/png' - | 'image/webp' - | 'image/avif' - | 'image/gif' { - return [ - 'image/jpeg', - 'image/png', - 'image/webp', - 'image/avif', - 'image/gif', - ].includes( type ); -} - /** * Compresses an existing image using vips. * diff --git a/packages/vips/src/types.ts b/packages/vips/src/types.ts index 25cc0ef4..7cf03723 100644 --- a/packages/vips/src/types.ts +++ b/packages/vips/src/types.ts @@ -1,3 +1,5 @@ +export type ItemId = string; + // Same type as in @mextp/upload-media // TODO: Move to shared package? export type ImageSizeCrop = { diff --git a/packages/vips/src/utils.ts b/packages/vips/src/utils.ts new file mode 100644 index 00000000..ea1988fe --- /dev/null +++ b/packages/vips/src/utils.ts @@ -0,0 +1,64 @@ +/** + * Determines whether a given file type is supported by vips. + * + * @param type Mime type. + * @return Whether the file type is supported. + */ +export function isFileTypeSupported( + type: string +): type is + | 'image/jpeg' + | 'image/png' + | 'image/webp' + | 'image/avif' + | 'image/gif' { + return [ + 'image/jpeg', + 'image/png', + 'image/webp', + 'image/avif', + 'image/gif', + ].includes( type ); +} + +/** + * Determines whether a given file type supports a quality setting, + * + * @todo Make this smarter. + * + * @param type Mime type. + * @return Whether the file supports a quality setting. + */ +export function supportsQuality( + type: string +): type is 'image/jpeg' | 'image/png' | 'image/webp' | 'image/avif' { + return [ 'image/jpeg', 'image/png', 'image/webp', 'image/avif' ].includes( + type + ); +} + +/** + * Determines whether a given file type supports animation, + * + * @todo Make this smarter. + * + * @param type Mime type. + * @return Whether the file supports animation. + */ +export function supportsAnimation( type: string ): type is 'image/webp' | 'image/gif' { + return [ 'image/webp', 'image/gif' ].includes( type ); +} + +/** + * Determines whether a given file type supports interlaced/progressive output. + * + * @todo Make this smarter. + * + * @param type Mime type. + * @return Whether the file supports interlaced/progressive output. + */ +export function supportsInterlace( + type: string +): type is 'image/jpeg' | 'image/gif' | 'image/png' { + return [ 'image/jpeg', 'image/gif', 'image/png' ].includes( type ); +}