kleisauke / wasm-vips

libvips for the browser and Node.js, compiled to WebAssembly with Emscripten.
https://kleisauke.github.io/wasm-vips/
MIT License
492 stars 25 forks source link

TS types improvements #51

Closed serafimsanvol closed 11 months ago

serafimsanvol commented 1 year ago

Hi! 👋

Firstly, thanks for your work on this project! 🙂

Today I used patch-package to patch wasm-vips@0.0.5 for the project I'm working on.

I wanted to use types from .*saveBuffer functions to generate yup validators, but it wasn't possible because exports don't exist. So I added some improvements for types

example of usage:

import { useEffect, useState } from 'react';
import VipsWASM from 'wasm-vips';

type VipsTypes = typeof VipsWASM;

export const useVips = () => {
  const [vips, setVips] = useState<VipsTypes | undefined>(undefined);
  const [cleanup, setCleanup] = useState<(() => void) | undefined>(undefined);

  useEffect(() => {
    if (vips) return;
    VipsWASM({
      // TODO: check does it affect loading speed
      // dynamicLibraries: ['vips-jxl.wasm', 'vips-heif.wasm', 'vips-resvg.wasm'],
      // Workers need to import the unbundled version of `vips.js`
      mainScriptUrlOrBlob: './vips.js',
      // wasm-vips is served from the public directory
      locateFile: (fileName) => fileName,
      preRun: (module) => {
        module.setAutoDeleteLater(false);
        // TODO: figure out how to make this work
        // module.setAutoDeleteLater(true);
        module.setDelayFunction((fn: () => void) => setCleanup(fn));
      },
    }).then((vips) => {
      vips.concurrency(10);
      setVips(vips);
    });

    return () => {
      if (!vips) return;

      type ImageAutoGen = VipsWASM.ImageAutoGen;
      type webpsaveBufferType = ImageAutoGen['webpsaveBuffer'];
      type webpsaveBufferParams = Parameters<webpsaveBufferType>;
      type webpsaveBufferOptions = webpsaveBufferParams[0];
      const object: webpsaveBufferOptions = {};

      if (vips) {
        // @ts-ignore don't understand why it throws error
        // it doesn't catch types narrowing
        return vips.shutdown();
      }
    };
  }, []);

  return { vips, cleanup };
};

Here is the diff that solved my problem:

diff --git a/node_modules/wasm-vips/lib/vips.d.ts b/node_modules/wasm-vips/lib/vips.d.ts
index e97c352..6754e55 100644
--- a/node_modules/wasm-vips/lib/vips.d.ts
+++ b/node_modules/wasm-vips/lib/vips.d.ts
@@ -1,4 +1,4 @@
-declare function Vips(config?: Partial<EmscriptenModule>): Promise<NonNullable<typeof Vips>>;
+export declare function Vips(config?: Partial<EmscriptenModule>): Promise<NonNullable<typeof Vips>>;

 type ModuleCallback = { (module?: any): void };

@@ -26,7 +26,7 @@ interface EmscriptenModule {
     workaroundCors: boolean;
 }

-declare module Vips {
+export declare module Vips {
     // Allow single pixels/images as input.
     type SingleOrArray<T> = T | T[];

This issue body was partially generated by patch-package.

I understand that I shoud've probably updated this - https://github.com/kleisauke/wasm-vips/blob/master/build/gen_type_declarations.py, but i'm not fluent enough in python to do it currently. Thanks

kleisauke commented 1 year ago

The type definitions should already be exported, see: https://github.com/kleisauke/wasm-vips/blob/41594f2b3d10dc78770a3c2742bab6e26bf16af0/lib/vips.d.ts#L9834

I was able to use your example without any issues. Perhaps Yup validators won't work on abstract base classes? If so, this patch would probably fix that:

--- a/src/app/useVips.tsx
+++ b/src/app/useVips.tsx
@@ -30,8 +30,8 @@ export const useVips = () => {
     return () => {
       if (!vips) return;

-      type ImageAutoGen = VipsWASM.ImageAutoGen;
-      type webpsaveBufferType = ImageAutoGen['webpsaveBuffer'];
+      type Image = VipsWASM.Image;
+      type webpsaveBufferType = Image['webpsaveBuffer'];
       type webpsaveBufferParams = Parameters<webpsaveBufferType>;
       type webpsaveBufferOptions = webpsaveBufferParams[0];
       const object: webpsaveBufferOptions = {};
kleisauke commented 1 year ago

@serafimsanvol Were you able to make any progress with this?

kleisauke commented 11 months ago

Closing due to inactivity. Please feel free to re-open if there's still a problem.