From f7bbb92d85dd1a61467e4b42ae1aa5aa48d3a9fb Mon Sep 17 00:00:00 2001 From: Fries Date: Mon, 14 Aug 2023 19:24:20 -0700 Subject: [PATCH] change up api, and bump down version the api now requires you to call an async function initWasm to make the functions work instead of using top level await. i also optimized the wasm module to have O3 and fast-math (which the original blurhash makefile had and the results do seem to be the same with the javascript blurhash). I also gave the wasm instance functions inside typescript types and i fixed a bug where i didnt free the pointers in order so if you called decode too many times, you will run out of memory. --- .clang-format | 3 + .gitignore | 1 + .npmignore | 13 +- .npmrc | 1 + Makefile | 2 +- blurhash/common.h | 23 +- blurhash/decode.c | 76 ++-- blurhash/decode.h | 8 +- package.json | 38 +- pnpm-lock.yaml | 896 +--------------------------------------------- rollup.config.js | 41 ++- src/library.ts | 65 +++- tsconfig.json | 2 +- vite.config.js | 27 -- 14 files changed, 184 insertions(+), 1012 deletions(-) create mode 100644 .clang-format create mode 100644 .npmrc delete mode 100644 vite.config.js diff --git a/.clang-format b/.clang-format new file mode 100644 index 0000000..137973c --- /dev/null +++ b/.clang-format @@ -0,0 +1,3 @@ +BasedOnStyle: WebKit +UseTab: Always +TabWidth: 4 diff --git a/.gitignore b/.gitignore index bf540f6..375fae9 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ node_modules src/blurhash-decode.wasm dist +*.tgz diff --git a/.npmignore b/.npmignore index 557b705..ff0cc16 100644 --- a/.npmignore +++ b/.npmignore @@ -1,4 +1,15 @@ node_modules -blurhash +*.tgz +blurhash/*.c +blurhash/*.h src +.clang-format +.editorconfig +.gitignore +.npmignore +.npmrc +.prettierrc.json Makefile +pnpm-lock.yaml +rollup.config.js +tsconfig.json diff --git a/.npmrc b/.npmrc new file mode 100644 index 0000000..617d1d6 --- /dev/null +++ b/.npmrc @@ -0,0 +1 @@ +@fries:registry=https://git.fries.gay/api/packages/fries/npm/ diff --git a/Makefile b/Makefile index 39b22d1..6913dc0 100644 --- a/Makefile +++ b/Makefile @@ -1,6 +1,6 @@ LIBRARY=src/blurhash-decode.wasm $(LIBRARY): blurhash/decode.c - emcc --no-entry -Wl,--export,decodeToArray -Wl,--export,malloc -Wl,--export,free -Wl,--export,isValidBlurhash -o $@ blurhash/decode.c + emcc -ffast-math -O3 --no-entry -Wl,--export,decodeToArray -Wl,--export,malloc -Wl,--export,free -Wl,--export,isValidBlurhash -o $@ blurhash/decode.c .PHONY: clean clean: diff --git a/blurhash/common.h b/blurhash/common.h index ce58144..b259c22 100644 --- a/blurhash/common.h +++ b/blurhash/common.h @@ -1,25 +1,32 @@ #ifndef __BLURHASH_COMMON_H__ #define __BLURHASH_COMMON_H__ -#include +#include #ifndef M_PI #define M_PI 3.14159265358979323846 #endif -static inline int linearTosRGB(float value) { +static inline int linearTosRGB(float value) +{ float v = fmaxf(0, fminf(1, value)); - if(v <= 0.0031308) return v * 12.92 * 255 + 0.5; - else return (1.055 * powf(v, 1 / 2.4) - 0.055) * 255 + 0.5; + if (v <= 0.0031308) + return v * 12.92 * 255 + 0.5; + else + return (1.055 * powf(v, 1 / 2.4) - 0.055) * 255 + 0.5; } -static inline float sRGBToLinear(int value) { +static inline float sRGBToLinear(int value) +{ float v = (float)value / 255; - if(v <= 0.04045) return v / 12.92; - else return powf((v + 0.055) / 1.055, 2.4); + if (v <= 0.04045) + return v / 12.92; + else + return powf((v + 0.055) / 1.055, 2.4); } -static inline float signPow(float value, float exp) { +static inline float signPow(float value, float exp) +{ return copysignf(powf(fabsf(value), exp), value); } diff --git a/blurhash/decode.c b/blurhash/decode.c index dc4863e..57b954c 100644 --- a/blurhash/decode.c +++ b/blurhash/decode.c @@ -4,54 +4,58 @@ static char chars[83] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz#$%*+,-.:;=?@[]^_{|}~"; -static inline uint8_t clampToUByte(int * src) { - if( *src >= 0 && *src <= 255 ) +static inline uint8_t clampToUByte(int* src) +{ + if (*src >= 0 && *src <= 255) return *src; return (*src < 0) ? 0 : 255; } -static inline uint8_t * createByteArray(int size) { - return (uint8_t *)malloc(size * sizeof(uint8_t)); -} - -int decodeToInt(uint8_t * string, int start, int end) { +int decodeToInt(uint8_t* string, int start, int end) +{ int value = 0, iter1 = 0, iter2 = 0; - for( iter1 = start; iter1 < end; iter1 ++) { + for (iter1 = start; iter1 < end; iter1++) { int index = -1; - for(iter2 = 0; iter2 < 83; iter2 ++) { + for (iter2 = 0; iter2 < 83; iter2++) { if (chars[iter2] == string[iter1]) { index = iter2; break; } } - if (index == -1) return -1; + if (index == -1) + return -1; value = value * 83 + index; } return value; } +bool isValidBlurhash(uint8_t* blurhash) +{ + const int hashLength = strlen((const char*)blurhash); -bool isValidBlurhash(uint8_t * blurhash) { - const int hashLength = strlen((const char *)blurhash); + if (!blurhash || strlen((const char*)blurhash) < 6) + return false; - if (!blurhash || strlen((const char *)blurhash) < 6) return false; + // Get size from first character + int sizeFlag = decodeToInt(blurhash, 0, 1); - int sizeFlag = decodeToInt(blurhash, 0, 1); //Get size from first character int numY = (int)floorf(sizeFlag / 9) + 1; int numX = (sizeFlag % 9) + 1; - if (hashLength != 4 + 2 * numX * numY) return false; + if (hashLength != 4 + 2 * numX * numY) + return false; return true; } - -void decodeDC(int value, float * r, float * g, float * b) { - *r = sRGBToLinear(value >> 16); // R-component +void decodeDC(int value, float* r, float* g, float* b) +{ + *r = sRGBToLinear(value >> 16); // R-component *g = sRGBToLinear((value >> 8) & 255); // G-Component - *b = sRGBToLinear(value & 255); // B-Component + *b = sRGBToLinear(value & 255); // B-Component } -void decodeAC(int value, float maximumValue, float * r, float * g, float * b) { +void decodeAC(int value, float maximumValue, float* r, float* g, float* b) +{ int quantR = (int)floorf(value / (19 * 19)); int quantG = (int)floorf(value / 19) % 19; int quantB = (int)value % 19; @@ -61,9 +65,12 @@ void decodeAC(int value, float maximumValue, float * r, float * g, float * b) { *b = signPow(((float)quantB - 9) / 9, 2.0) * maximumValue; } -int decodeToArray(uint8_t * blurhash, int width, int height, int punch, int nChannels, uint8_t * pixelArray) { - if (!isValidBlurhash(blurhash)) return -1; - if (punch < 1) punch = 1; +int decodeToArray(uint8_t* blurhash, int width, int height, int punch, int nChannels, uint8_t* pixelArray) +{ + if (!isValidBlurhash(blurhash)) + return -1; + if (punch < 1) + punch = 1; int sizeFlag = decodeToInt(blurhash, 0, 1); int numY = (int)floorf(sizeFlag / 9) + 1; @@ -72,17 +79,19 @@ int decodeToArray(uint8_t * blurhash, int width, int height, int punch, int nCha float r = 0, g = 0, b = 0; int quantizedMaxValue = decodeToInt(blurhash, 1, 2); - if (quantizedMaxValue == -1) return -1; + if (quantizedMaxValue == -1) + return -1; float maxValue = ((float)(quantizedMaxValue + 1)) / 166; int colors_size = numX * numY; float colors[colors_size][3]; - for(iter = 0; iter < colors_size; iter ++) { + for (iter = 0; iter < colors_size; iter++) { if (iter == 0) { int value = decodeToInt(blurhash, 2, 6); - if (value == -1) return -1; + if (value == -1) + return -1; decodeDC(value, &r, &g, &b); colors[iter][0] = r; colors[iter][1] = g; @@ -90,7 +99,8 @@ int decodeToArray(uint8_t * blurhash, int width, int height, int punch, int nCha } else { int value = decodeToInt(blurhash, 4 + iter * 2, 6 + iter * 2); - if (value == -1) return -1; + if (value == -1) + return -1; decodeAC(value, maxValue * punch, &r, &g, &b); colors[iter][0] = r; colors[iter][1] = g; @@ -102,13 +112,13 @@ int decodeToArray(uint8_t * blurhash, int width, int height, int punch, int nCha int x = 0, y = 0, i = 0, j = 0; int intR = 0, intG = 0, intB = 0; - for(y = 0; y < height; y ++) { - for(x = 0; x < width; x ++) { + for (y = 0; y < height; y++) { + for (x = 0; x < width; x++) { float r = 0, g = 0, b = 0; - for(j = 0; j < numY; j ++) { - for(i = 0; i < numX; i ++) { + for (j = 0; j < numY; j++) { + for (i = 0; i < numX; i++) { float basics = cos((M_PI * x * i) / width) * cos((M_PI * y * j) / height); int idx = i + j * numX; r += colors[idx][0] * basics; @@ -126,8 +136,8 @@ int decodeToArray(uint8_t * blurhash, int width, int height, int punch, int nCha pixelArray[nChannels * x + 2 + y * bytesPerRow] = clampToUByte(&intB); if (nChannels == 4) - pixelArray[nChannels * x + 3 + y * bytesPerRow] = 255; // If nChannels=4, treat each pixel as RGBA instead of RGB - + // If nChannels=4, treat each pixel as RGBA instead of RGB + pixelArray[nChannels * x + 3 + y * bytesPerRow] = 255; } } diff --git a/blurhash/decode.h b/blurhash/decode.h index 10295ec..e302856 100644 --- a/blurhash/decode.h +++ b/blurhash/decode.h @@ -4,9 +4,9 @@ #include #include -#include -#include #include +#include +#include /* decodeToArray : Decodes the blurhash and copies the pixels to pixelArray, @@ -21,7 +21,7 @@ pixelArray : Pointer to memory region where pixels needs to be copied. Returns : int, -1 if error 0 if successful */ -int decodeToArray(uint8_t * blurhash, int width, int height, int punch, int nChannels, uint8_t * pixelArray); +int decodeToArray(uint8_t* blurhash, int width, int height, int punch, int nChannels, uint8_t* pixelArray); /* isValidBlurhash : Checks if the Blurhash is valid or not. @@ -29,6 +29,6 @@ int decodeToArray(uint8_t * blurhash, int width, int height, int punch, int nCha blurhash : A string representing the blurhash Returns : bool (true if it is a valid blurhash, else false) */ -bool isValidBlurhash(uint8_t * blurhash); +bool isValidBlurhash(uint8_t* blurhash); #endif diff --git a/package.json b/package.json index 1292f78..088de38 100644 --- a/package.json +++ b/package.json @@ -1,21 +1,21 @@ { - "type": "module", - "name": "@fries/blurhash-c-wasm", - "version": "1.0.0", - "description": "", - "main": "dist/library.js", - "types": "dist/library.d.ts", - "scripts": { - "build": "make && rollup -c rollup.config.js", - "prepublishOnly": "pnpm build" - }, - "keywords": [], - "author": "", - "devDependencies": { - "@rollup/plugin-typescript": "^11.1.2", - "@rollup/plugin-wasm": "^6.1.3", - "rollup": "^3.28.0", - "typescript": "^5.1.6", - "tslib": "^2.6.1" - } + "type": "module", + "name": "@fries/blurhash-c-wasm", + "version": "0.1.0", + "description": "A WASM module using the Blurhash C library", + "main": "dist/blurhash-c-wasm.cjs", + "module": "dist/blurhash-c-wasm.js", + "types": "dist/library.d.ts", + "scripts": { + "build": "make && rollup -c rollup.config.js", + "prepublishOnly": "pnpm build" + }, + "author": "Fries", + "devDependencies": { + "@rollup/plugin-typescript": "^11.1.2", + "@rollup/plugin-wasm": "^6.1.3", + "rollup": "^3.28.0", + "typescript": "^5.1.6", + "tslib": "^2.6.1" + } } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index fce2a5c..a34688c 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -20,289 +20,9 @@ devDependencies: typescript: specifier: ^5.1.6 version: 5.1.6 - vite: - specifier: ^4.4.9 - version: 4.4.9 - vite-plugin-dts: - specifier: ^3.5.2 - version: 3.5.2(rollup@3.28.0)(typescript@5.1.6)(vite@4.4.9) - vite-plugin-top-level-await: - specifier: ^1.3.1 - version: 1.3.1(rollup@3.28.0)(vite@4.4.9) - vite-plugin-wasm: - specifier: ^3.2.2 - version: 3.2.2(vite@4.4.9) packages: - /@babel/helper-string-parser@7.22.5: - resolution: {integrity: sha512-mM4COjgZox8U+JcXQwPijIZLElkgEpO5rsERVDJTc2qfCDfERyob6k5WegS14SX18IIjv+XD+GrqNumY5JRCDw==} - engines: {node: '>=6.9.0'} - dev: true - - /@babel/helper-validator-identifier@7.22.5: - resolution: {integrity: sha512-aJXu+6lErq8ltp+JhkJUfk1MTGyuA4v7f3pA+BJ5HLfNC6nAQ0Cpi9uOquUj8Hehg0aUiHzWQbOVJGao6ztBAQ==} - engines: {node: '>=6.9.0'} - dev: true - - /@babel/parser@7.22.10: - resolution: {integrity: sha512-lNbdGsQb9ekfsnjFGhEiF4hfFqGgfOP3H3d27re3n+CGhNuTSUEQdfWk556sTLNTloczcdM5TYF2LhzmDQKyvQ==} - engines: {node: '>=6.0.0'} - hasBin: true - dependencies: - '@babel/types': 7.22.10 - dev: true - - /@babel/types@7.22.10: - resolution: {integrity: sha512-obaoigiLrlDZ7TUQln/8m4mSqIW2QFeOrCQc9r+xsaHGNoplVNYlRVpsfE8Vj35GEm2ZH4ZhrNYogs/3fj85kg==} - engines: {node: '>=6.9.0'} - dependencies: - '@babel/helper-string-parser': 7.22.5 - '@babel/helper-validator-identifier': 7.22.5 - to-fast-properties: 2.0.0 - dev: true - - /@esbuild/android-arm64@0.18.20: - resolution: {integrity: sha512-Nz4rJcchGDtENV0eMKUNa6L12zz2zBDXuhj/Vjh18zGqB44Bi7MBMSXjgunJgjRhCmKOjnPuZp4Mb6OKqtMHLQ==} - engines: {node: '>=12'} - cpu: [arm64] - os: [android] - requiresBuild: true - dev: true - optional: true - - /@esbuild/android-arm@0.18.20: - resolution: {integrity: sha512-fyi7TDI/ijKKNZTUJAQqiG5T7YjJXgnzkURqmGj13C6dCqckZBLdl4h7bkhHt/t0WP+zO9/zwroDvANaOqO5Sw==} - engines: {node: '>=12'} - cpu: [arm] - os: [android] - requiresBuild: true - dev: true - optional: true - - /@esbuild/android-x64@0.18.20: - resolution: {integrity: sha512-8GDdlePJA8D6zlZYJV/jnrRAi6rOiNaCC/JclcXpB+KIuvfBN4owLtgzY2bsxnx666XjJx2kDPUmnTtR8qKQUg==} - engines: {node: '>=12'} - cpu: [x64] - os: [android] - requiresBuild: true - dev: true - optional: true - - /@esbuild/darwin-arm64@0.18.20: - resolution: {integrity: sha512-bxRHW5kHU38zS2lPTPOyuyTm+S+eobPUnTNkdJEfAddYgEcll4xkT8DB9d2008DtTbl7uJag2HuE5NZAZgnNEA==} - engines: {node: '>=12'} - cpu: [arm64] - os: [darwin] - requiresBuild: true - dev: true - optional: true - - /@esbuild/darwin-x64@0.18.20: - resolution: {integrity: sha512-pc5gxlMDxzm513qPGbCbDukOdsGtKhfxD1zJKXjCCcU7ju50O7MeAZ8c4krSJcOIJGFR+qx21yMMVYwiQvyTyQ==} - engines: {node: '>=12'} - cpu: [x64] - os: [darwin] - requiresBuild: true - dev: true - optional: true - - /@esbuild/freebsd-arm64@0.18.20: - resolution: {integrity: sha512-yqDQHy4QHevpMAaxhhIwYPMv1NECwOvIpGCZkECn8w2WFHXjEwrBn3CeNIYsibZ/iZEUemj++M26W3cNR5h+Tw==} - engines: {node: '>=12'} - cpu: [arm64] - os: [freebsd] - requiresBuild: true - dev: true - optional: true - - /@esbuild/freebsd-x64@0.18.20: - resolution: {integrity: sha512-tgWRPPuQsd3RmBZwarGVHZQvtzfEBOreNuxEMKFcd5DaDn2PbBxfwLcj4+aenoh7ctXcbXmOQIn8HI6mCSw5MQ==} - engines: {node: '>=12'} - cpu: [x64] - os: [freebsd] - requiresBuild: true - dev: true - optional: true - - /@esbuild/linux-arm64@0.18.20: - resolution: {integrity: sha512-2YbscF+UL7SQAVIpnWvYwM+3LskyDmPhe31pE7/aoTMFKKzIc9lLbyGUpmmb8a8AixOL61sQ/mFh3jEjHYFvdA==} - engines: {node: '>=12'} - cpu: [arm64] - os: [linux] - requiresBuild: true - dev: true - optional: true - - /@esbuild/linux-arm@0.18.20: - resolution: {integrity: sha512-/5bHkMWnq1EgKr1V+Ybz3s1hWXok7mDFUMQ4cG10AfW3wL02PSZi5kFpYKrptDsgb2WAJIvRcDm+qIvXf/apvg==} - engines: {node: '>=12'} - cpu: [arm] - os: [linux] - requiresBuild: true - dev: true - optional: true - - /@esbuild/linux-ia32@0.18.20: - resolution: {integrity: sha512-P4etWwq6IsReT0E1KHU40bOnzMHoH73aXp96Fs8TIT6z9Hu8G6+0SHSw9i2isWrD2nbx2qo5yUqACgdfVGx7TA==} - engines: {node: '>=12'} - cpu: [ia32] - os: [linux] - requiresBuild: true - dev: true - optional: true - - /@esbuild/linux-loong64@0.18.20: - resolution: {integrity: sha512-nXW8nqBTrOpDLPgPY9uV+/1DjxoQ7DoB2N8eocyq8I9XuqJ7BiAMDMf9n1xZM9TgW0J8zrquIb/A7s3BJv7rjg==} - engines: {node: '>=12'} - cpu: [loong64] - os: [linux] - requiresBuild: true - dev: true - optional: true - - /@esbuild/linux-mips64el@0.18.20: - resolution: {integrity: sha512-d5NeaXZcHp8PzYy5VnXV3VSd2D328Zb+9dEq5HE6bw6+N86JVPExrA6O68OPwobntbNJ0pzCpUFZTo3w0GyetQ==} - engines: {node: '>=12'} - cpu: [mips64el] - os: [linux] - requiresBuild: true - dev: true - optional: true - - /@esbuild/linux-ppc64@0.18.20: - resolution: {integrity: sha512-WHPyeScRNcmANnLQkq6AfyXRFr5D6N2sKgkFo2FqguP44Nw2eyDlbTdZwd9GYk98DZG9QItIiTlFLHJHjxP3FA==} - engines: {node: '>=12'} - cpu: [ppc64] - os: [linux] - requiresBuild: true - dev: true - optional: true - - /@esbuild/linux-riscv64@0.18.20: - resolution: {integrity: sha512-WSxo6h5ecI5XH34KC7w5veNnKkju3zBRLEQNY7mv5mtBmrP/MjNBCAlsM2u5hDBlS3NGcTQpoBvRzqBcRtpq1A==} - engines: {node: '>=12'} - cpu: [riscv64] - os: [linux] - requiresBuild: true - dev: true - optional: true - - /@esbuild/linux-s390x@0.18.20: - resolution: {integrity: sha512-+8231GMs3mAEth6Ja1iK0a1sQ3ohfcpzpRLH8uuc5/KVDFneH6jtAJLFGafpzpMRO6DzJ6AvXKze9LfFMrIHVQ==} - engines: {node: '>=12'} - cpu: [s390x] - os: [linux] - requiresBuild: true - dev: true - optional: true - - /@esbuild/linux-x64@0.18.20: - resolution: {integrity: sha512-UYqiqemphJcNsFEskc73jQ7B9jgwjWrSayxawS6UVFZGWrAAtkzjxSqnoclCXxWtfwLdzU+vTpcNYhpn43uP1w==} - engines: {node: '>=12'} - cpu: [x64] - os: [linux] - requiresBuild: true - dev: true - optional: true - - /@esbuild/netbsd-x64@0.18.20: - resolution: {integrity: sha512-iO1c++VP6xUBUmltHZoMtCUdPlnPGdBom6IrO4gyKPFFVBKioIImVooR5I83nTew5UOYrk3gIJhbZh8X44y06A==} - engines: {node: '>=12'} - cpu: [x64] - os: [netbsd] - requiresBuild: true - dev: true - optional: true - - /@esbuild/openbsd-x64@0.18.20: - resolution: {integrity: sha512-e5e4YSsuQfX4cxcygw/UCPIEP6wbIL+se3sxPdCiMbFLBWu0eiZOJ7WoD+ptCLrmjZBK1Wk7I6D/I3NglUGOxg==} - engines: {node: '>=12'} - cpu: [x64] - os: [openbsd] - requiresBuild: true - dev: true - optional: true - - /@esbuild/sunos-x64@0.18.20: - resolution: {integrity: sha512-kDbFRFp0YpTQVVrqUd5FTYmWo45zGaXe0X8E1G/LKFC0v8x0vWrhOWSLITcCn63lmZIxfOMXtCfti/RxN/0wnQ==} - engines: {node: '>=12'} - cpu: [x64] - os: [sunos] - requiresBuild: true - dev: true - optional: true - - /@esbuild/win32-arm64@0.18.20: - resolution: {integrity: sha512-ddYFR6ItYgoaq4v4JmQQaAI5s7npztfV4Ag6NrhiaW0RrnOXqBkgwZLofVTlq1daVTQNhtI5oieTvkRPfZrePg==} - engines: {node: '>=12'} - cpu: [arm64] - os: [win32] - requiresBuild: true - dev: true - optional: true - - /@esbuild/win32-ia32@0.18.20: - resolution: {integrity: sha512-Wv7QBi3ID/rROT08SABTS7eV4hX26sVduqDOTe1MvGMjNd3EjOz4b7zeexIR62GTIEKrfJXKL9LFxTYgkyeu7g==} - engines: {node: '>=12'} - cpu: [ia32] - os: [win32] - requiresBuild: true - dev: true - optional: true - - /@esbuild/win32-x64@0.18.20: - resolution: {integrity: sha512-kTdfRcSiDfQca/y9QIkng02avJ+NCaQvrMejlsB3RRv5sE9rRoeBPISaZpKxHELzRxZyLvNts1P27W3wV+8geQ==} - engines: {node: '>=12'} - cpu: [x64] - os: [win32] - requiresBuild: true - dev: true - optional: true - - /@microsoft/api-extractor-model@7.27.6: - resolution: {integrity: sha512-eiCnlayyum1f7fS2nA9pfIod5VCNR1G+Tq84V/ijDrKrOFVa598BLw145nCsGDMoFenV6ajNi2PR5WCwpAxW6Q==} - dependencies: - '@microsoft/tsdoc': 0.14.2 - '@microsoft/tsdoc-config': 0.16.2 - '@rushstack/node-core-library': 3.59.7 - transitivePeerDependencies: - - '@types/node' - dev: true - - /@microsoft/api-extractor@7.36.4: - resolution: {integrity: sha512-21UECq8C/8CpHT23yiqTBQ10egKUacIpxkPyYR7hdswo/M5yTWdBvbq+77YC9uPKQJOUfOD1FImBQ1DzpsdeQQ==} - hasBin: true - dependencies: - '@microsoft/api-extractor-model': 7.27.6 - '@microsoft/tsdoc': 0.14.2 - '@microsoft/tsdoc-config': 0.16.2 - '@rushstack/node-core-library': 3.59.7 - '@rushstack/rig-package': 0.4.1 - '@rushstack/ts-command-line': 4.15.2 - colors: 1.2.5 - lodash: 4.17.21 - resolve: 1.22.4 - semver: 7.5.4 - source-map: 0.6.1 - typescript: 5.0.4 - transitivePeerDependencies: - - '@types/node' - dev: true - - /@microsoft/tsdoc-config@0.16.2: - resolution: {integrity: sha512-OGiIzzoBLgWWR0UdRJX98oYO+XKGf7tiK4Zk6tQ/E4IJqGCe7dvkTvgDZV5cFJUzLGDOjeAXrnZoA6QkVySuxw==} - dependencies: - '@microsoft/tsdoc': 0.14.2 - ajv: 6.12.6 - jju: 1.4.0 - resolve: 1.19.0 - dev: true - - /@microsoft/tsdoc@0.14.2: - resolution: {integrity: sha512-9b8mPpKrfeGRuhFH5iO1iwCLeIIsV6+H1sRfxbkoGXIyQE2BTsPd9zqSqQJ+pv5sJ/hT5M1zvOFL02MnEezFug==} - dev: true - /@rollup/plugin-typescript@11.1.2(rollup@3.28.0)(tslib@2.6.1)(typescript@5.1.6): resolution: {integrity: sha512-0ghSOCMcA7fl1JM+0gYRf+Q/HWyg+zg7/gDSc+fRLmlJWcW5K1I+CLRzaRhXf4Y3DRyPnnDo4M2ktw+a6JcDEg==} engines: {node: '>=14.0.0'} @@ -316,25 +36,13 @@ packages: tslib: optional: true dependencies: - '@rollup/pluginutils': 5.0.2(rollup@3.28.0) + '@rollup/pluginutils': 5.0.3(rollup@3.28.0) resolve: 1.22.4 rollup: 3.28.0 tslib: 2.6.1 typescript: 5.1.6 dev: true - /@rollup/plugin-virtual@3.0.1(rollup@3.28.0): - resolution: {integrity: sha512-fK8O0IL5+q+GrsMLuACVNk2x21g3yaw+sG2qn16SnUd3IlBsQyvWxLMGHmCmXRMecPjGRSZ/1LmZB4rjQm68og==} - engines: {node: '>=14.0.0'} - peerDependencies: - rollup: ^1.20.0||^2.0.0||^3.0.0 - peerDependenciesMeta: - rollup: - optional: true - dependencies: - rollup: 3.28.0 - dev: true - /@rollup/plugin-wasm@6.1.3(rollup@3.28.0): resolution: {integrity: sha512-7ItTTeyauE6lwdDtQWceEHZ9+txbi4RRy0mYPFn9BW7rD7YdgBDu7HTHsLtHrRzJc313RM/1m6GKgV3np/aEaw==} engines: {node: '>=14.0.0'} @@ -347,8 +55,8 @@ packages: rollup: 3.28.0 dev: true - /@rollup/pluginutils@5.0.2(rollup@3.28.0): - resolution: {integrity: sha512-pTd9rIsP92h+B6wWwFbW8RkZv4hiR/xKsqre4SIuAOaOEQRxi0lqLke9k2/7WegC85GgUs9pjmOjCUi3In4vwA==} + /@rollup/pluginutils@5.0.3(rollup@3.28.0): + resolution: {integrity: sha512-hfllNN4a80rwNQ9QCxhxuHCGHMAvabXqxNdaChUSSadMre7t4iEUI6fFAhBOn/eIYTgYVhBv7vCLsAJ4u3lf3g==} engines: {node: '>=14.0.0'} peerDependencies: rollup: ^1.20.0||^2.0.0||^3.0.0 @@ -362,335 +70,14 @@ packages: rollup: 3.28.0 dev: true - /@rushstack/node-core-library@3.59.7: - resolution: {integrity: sha512-ln1Drq0h+Hwa1JVA65x5mlSgUrBa1uHL+V89FqVWQgXd1vVIMhrtqtWGQrhTnFHxru5ppX+FY39VWELF/FjQCw==} - peerDependencies: - '@types/node': '*' - peerDependenciesMeta: - '@types/node': - optional: true - dependencies: - colors: 1.2.5 - fs-extra: 7.0.1 - import-lazy: 4.0.0 - jju: 1.4.0 - resolve: 1.22.4 - semver: 7.5.4 - z-schema: 5.0.5 - dev: true - - /@rushstack/rig-package@0.4.1: - resolution: {integrity: sha512-AGRwpqlXNSp9LhUSz4HKI9xCluqQDt/obsQFdv/NYIekF3pTTPzc+HbQsIsjVjYnJ3DcmxOREVMhvrMEjpiq6g==} - dependencies: - resolve: 1.22.4 - strip-json-comments: 3.1.1 - dev: true - - /@rushstack/ts-command-line@4.15.2: - resolution: {integrity: sha512-5+C2uoJY8b+odcZD6coEe2XNC4ZjGB4vCMESbqW/8DHRWC/qIHfANdmN9F1wz/lAgxz72i7xRoVtPY2j7e4gpQ==} - dependencies: - '@types/argparse': 1.0.38 - argparse: 1.0.10 - colors: 1.2.5 - string-argv: 0.3.2 - dev: true - - /@swc/core-darwin-arm64@1.3.76: - resolution: {integrity: sha512-ovviEhZ/1E81Z9OGrO0ivLWk4VCa3I3ZzM+cd3gugglRRwVwtlIaoIYqY5S3KiCAupDd1+UCl5X7Vbio7a/V8g==} - engines: {node: '>=10'} - cpu: [arm64] - os: [darwin] - requiresBuild: true - dev: true - optional: true - - /@swc/core-darwin-x64@1.3.76: - resolution: {integrity: sha512-tcySTDqs0SHCebtW35sCdcLWsmTEo7bEwx0gNL/spetqVT9fpFi6qU8qcnt7i2KaZHbeNl9g1aadu+Yrni+GzA==} - engines: {node: '>=10'} - cpu: [x64] - os: [darwin] - requiresBuild: true - dev: true - optional: true - - /@swc/core-linux-arm-gnueabihf@1.3.76: - resolution: {integrity: sha512-apgzpGWy1AwoMF4urAAASsAjE7rEzZFIF+p6utuxhS7cNHzE0AyEVDYJbo+pzBdlZ8orBdzzsHtFwoEgKOjebA==} - engines: {node: '>=10'} - cpu: [arm] - os: [linux] - requiresBuild: true - dev: true - optional: true - - /@swc/core-linux-arm64-gnu@1.3.76: - resolution: {integrity: sha512-c3c0zz6S0eludqidDpuqbadE0WT3OZczyQxe9Vw8lFFXES85mvNGtwYzyGK2o7TICpsuHrndwDIoYpmpWk879g==} - engines: {node: '>=10'} - cpu: [arm64] - os: [linux] - requiresBuild: true - dev: true - optional: true - - /@swc/core-linux-arm64-musl@1.3.76: - resolution: {integrity: sha512-Is3bpq7F2qtlnkzEeOD6HIZJPpOmu3q6c82lKww90Q0NnrlSluVMozTHJgwVoFZyizH7uLnk0LuNcEAWLnmJIw==} - engines: {node: '>=10'} - cpu: [arm64] - os: [linux] - requiresBuild: true - dev: true - optional: true - - /@swc/core-linux-x64-gnu@1.3.76: - resolution: {integrity: sha512-iwCeRzd9oSvUzqt7nU6p/ztceAWfnO9XVxBn502R5gs6QCBbE1HCKrWHDO77aKPK7ss+0NcIGHvXTd9L8/wRzw==} - engines: {node: '>=10'} - cpu: [x64] - os: [linux] - requiresBuild: true - dev: true - optional: true - - /@swc/core-linux-x64-musl@1.3.76: - resolution: {integrity: sha512-a671g4tW8kyFeuICsgq4uB9ukQfiIyXJT4V6YSnmqhCTz5mazWuDxZ5wKnx/1g5nXTl+U5cWH2TZaCJatp4GKA==} - engines: {node: '>=10'} - cpu: [x64] - os: [linux] - requiresBuild: true - dev: true - optional: true - - /@swc/core-win32-arm64-msvc@1.3.76: - resolution: {integrity: sha512-+swEFtjdMezS0vKUhJC3psdSDtOJGY5pEOt4e8XOPvn7aQpKQ9LfF49XVtIwDSk5SGuWtVoLFzkSY3reWUJCyg==} - engines: {node: '>=10'} - cpu: [arm64] - os: [win32] - requiresBuild: true - dev: true - optional: true - - /@swc/core-win32-ia32-msvc@1.3.76: - resolution: {integrity: sha512-5CqwAykpGBJ3PqGLOlWGLGIPpBAG1IwWVDUfro3hhjQ7XJxV5Z1aQf5V5OJ90HJVtrEAVx2xx59UV/Dh081LOg==} - engines: {node: '>=10'} - cpu: [ia32] - os: [win32] - requiresBuild: true - dev: true - optional: true - - /@swc/core-win32-x64-msvc@1.3.76: - resolution: {integrity: sha512-CiMpWLLlR3Cew9067E7XxaLBwYYJ90r9EhGSO6V1pvYSWj7ET/Ppmtj1ZhzPJMqRXAP6xflfl5R5o4ee1m4WLA==} - engines: {node: '>=10'} - cpu: [x64] - os: [win32] - requiresBuild: true - dev: true - optional: true - - /@swc/core@1.3.76: - resolution: {integrity: sha512-aYYTA2aVYkwJAZepQXtPnkUthhOfn8qd6rsh+lrJxonFrjmpI7RHt2tMDVTXP6XDX7fvnvrVtT1bwZfmBFPh0Q==} - engines: {node: '>=10'} - requiresBuild: true - peerDependencies: - '@swc/helpers': ^0.5.0 - peerDependenciesMeta: - '@swc/helpers': - optional: true - optionalDependencies: - '@swc/core-darwin-arm64': 1.3.76 - '@swc/core-darwin-x64': 1.3.76 - '@swc/core-linux-arm-gnueabihf': 1.3.76 - '@swc/core-linux-arm64-gnu': 1.3.76 - '@swc/core-linux-arm64-musl': 1.3.76 - '@swc/core-linux-x64-gnu': 1.3.76 - '@swc/core-linux-x64-musl': 1.3.76 - '@swc/core-win32-arm64-msvc': 1.3.76 - '@swc/core-win32-ia32-msvc': 1.3.76 - '@swc/core-win32-x64-msvc': 1.3.76 - dev: true - - /@types/argparse@1.0.38: - resolution: {integrity: sha512-ebDJ9b0e702Yr7pWgB0jzm+CX4Srzz8RcXtLJDJB+BSccqMa36uyH/zUsSYao5+BD1ytv3k3rPYCq4mAE1hsXA==} - dev: true - /@types/estree@1.0.1: resolution: {integrity: sha512-LG4opVs2ANWZ1TJoKc937iMmNstM/d0ae1vNbnBvBhqCSezgVUOzcLCqbI5elV8Vy6WKwKjaqR+zO9VKirBBCA==} dev: true - /@volar/language-core@1.10.0: - resolution: {integrity: sha512-ddyWwSYqcbEZNFHm+Z3NZd6M7Ihjcwl/9B5cZd8kECdimVXUFdFi60XHWD27nrWtUQIsUYIG7Ca1WBwV2u2LSQ==} - dependencies: - '@volar/source-map': 1.10.0 - dev: true - - /@volar/source-map@1.10.0: - resolution: {integrity: sha512-/ibWdcOzDGiq/GM1JU2eX8fH1bvAhl66hfe8yEgLEzg9txgr6qb5sQ/DEz5PcDL75tF5H5sCRRwn8Eu8ezi9mw==} - dependencies: - muggle-string: 0.3.1 - dev: true - - /@volar/typescript@1.10.0: - resolution: {integrity: sha512-OtqGtFbUKYC0pLNIk3mHQp5xWnvL1CJIUc9VE39VdZ/oqpoBh5jKfb9uJ45Y4/oP/WYTrif/Uxl1k8VTPz66Gg==} - dependencies: - '@volar/language-core': 1.10.0 - dev: true - - /@vue/compiler-core@3.3.4: - resolution: {integrity: sha512-cquyDNvZ6jTbf/+x+AgM2Arrp6G4Dzbb0R64jiG804HRMfRiFXWI6kqUVqZ6ZR0bQhIoQjB4+2bhNtVwndW15g==} - dependencies: - '@babel/parser': 7.22.10 - '@vue/shared': 3.3.4 - estree-walker: 2.0.2 - source-map-js: 1.0.2 - dev: true - - /@vue/compiler-dom@3.3.4: - resolution: {integrity: sha512-wyM+OjOVpuUukIq6p5+nwHYtj9cFroz9cwkfmP9O1nzH68BenTTv0u7/ndggT8cIQlnBeOo6sUT/gvHcIkLA5w==} - dependencies: - '@vue/compiler-core': 3.3.4 - '@vue/shared': 3.3.4 - dev: true - - /@vue/language-core@1.8.8(typescript@5.1.6): - resolution: {integrity: sha512-i4KMTuPazf48yMdYoebTkgSOJdFraE4pQf0B+FTOFkbB+6hAfjrSou/UmYWRsWyZV6r4Rc6DDZdI39CJwL0rWw==} - peerDependencies: - typescript: '*' - peerDependenciesMeta: - typescript: - optional: true - dependencies: - '@volar/language-core': 1.10.0 - '@volar/source-map': 1.10.0 - '@vue/compiler-dom': 3.3.4 - '@vue/reactivity': 3.3.4 - '@vue/shared': 3.3.4 - minimatch: 9.0.3 - muggle-string: 0.3.1 - typescript: 5.1.6 - vue-template-compiler: 2.7.14 - dev: true - - /@vue/reactivity@3.3.4: - resolution: {integrity: sha512-kLTDLwd0B1jG08NBF3R5rqULtv/f8x3rOFByTDz4J53ttIQEDmALqKqXY0J+XQeN0aV2FBxY8nJDf88yvOPAqQ==} - dependencies: - '@vue/shared': 3.3.4 - dev: true - - /@vue/shared@3.3.4: - resolution: {integrity: sha512-7OjdcV8vQ74eiz1TZLzZP4JwqM5fA94K6yntPS5Z25r9HDuGNzaGdgvwKYq6S+MxwF0TFRwe50fIR/MYnakdkQ==} - dev: true - - /@vue/typescript@1.8.8(typescript@5.1.6): - resolution: {integrity: sha512-jUnmMB6egu5wl342eaUH236v8tdcEPXXkPgj+eI/F6JwW/lb+yAU6U07ZbQ3MVabZRlupIlPESB7ajgAGixhow==} - dependencies: - '@volar/typescript': 1.10.0 - '@vue/language-core': 1.8.8(typescript@5.1.6) - transitivePeerDependencies: - - typescript - dev: true - - /ajv@6.12.6: - resolution: {integrity: sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==} - dependencies: - fast-deep-equal: 3.1.3 - fast-json-stable-stringify: 2.1.0 - json-schema-traverse: 0.4.1 - uri-js: 4.4.1 - dev: true - - /argparse@1.0.10: - resolution: {integrity: sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==} - dependencies: - sprintf-js: 1.0.3 - dev: true - - /balanced-match@1.0.2: - resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==} - dev: true - - /brace-expansion@2.0.1: - resolution: {integrity: sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==} - dependencies: - balanced-match: 1.0.2 - dev: true - - /colors@1.2.5: - resolution: {integrity: sha512-erNRLao/Y3Fv54qUa0LBB+//Uf3YwMUmdJinN20yMXm9zdKKqH9wt7R9IIVZ+K7ShzfpLV/Zg8+VyrBJYB4lpg==} - engines: {node: '>=0.1.90'} - dev: true - - /commander@9.5.0: - resolution: {integrity: sha512-KRs7WVDKg86PWiuAqhDrAQnTXZKraVcCc6vFdL14qrZ/DcWwuRo7VoiYXalXO7S5GKpqYiVEwCbgFDfxNHKJBQ==} - engines: {node: ^12.20.0 || >=14} - requiresBuild: true - dev: true - optional: true - - /de-indent@1.0.2: - resolution: {integrity: sha512-e/1zu3xH5MQryN2zdVaF0OrdNLUbvWxzMbi+iNA6Bky7l1RoP8a2fIbRocyHclXt/arDrrR6lL3TqFD9pMQTsg==} - dev: true - - /debug@4.3.4: - resolution: {integrity: sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==} - engines: {node: '>=6.0'} - peerDependencies: - supports-color: '*' - peerDependenciesMeta: - supports-color: - optional: true - dependencies: - ms: 2.1.2 - dev: true - - /esbuild@0.18.20: - resolution: {integrity: sha512-ceqxoedUrcayh7Y7ZX6NdbbDzGROiyVBgC4PriJThBKSVPWnnFHZAkfI1lJT8QFkOwH4qOS2SJkS4wvpGl8BpA==} - engines: {node: '>=12'} - hasBin: true - requiresBuild: true - optionalDependencies: - '@esbuild/android-arm': 0.18.20 - '@esbuild/android-arm64': 0.18.20 - '@esbuild/android-x64': 0.18.20 - '@esbuild/darwin-arm64': 0.18.20 - '@esbuild/darwin-x64': 0.18.20 - '@esbuild/freebsd-arm64': 0.18.20 - '@esbuild/freebsd-x64': 0.18.20 - '@esbuild/linux-arm': 0.18.20 - '@esbuild/linux-arm64': 0.18.20 - '@esbuild/linux-ia32': 0.18.20 - '@esbuild/linux-loong64': 0.18.20 - '@esbuild/linux-mips64el': 0.18.20 - '@esbuild/linux-ppc64': 0.18.20 - '@esbuild/linux-riscv64': 0.18.20 - '@esbuild/linux-s390x': 0.18.20 - '@esbuild/linux-x64': 0.18.20 - '@esbuild/netbsd-x64': 0.18.20 - '@esbuild/openbsd-x64': 0.18.20 - '@esbuild/sunos-x64': 0.18.20 - '@esbuild/win32-arm64': 0.18.20 - '@esbuild/win32-ia32': 0.18.20 - '@esbuild/win32-x64': 0.18.20 - dev: true - /estree-walker@2.0.2: resolution: {integrity: sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==} dev: true - /fast-deep-equal@3.1.3: - resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==} - dev: true - - /fast-json-stable-stringify@2.1.0: - resolution: {integrity: sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==} - dev: true - - /fs-extra@7.0.1: - resolution: {integrity: sha512-YJDaCJZEnBmcbw13fvdAM9AwNOJwOzrE4pqMqBq5nFiEqXUqHwlK4B+3pUw6JNvfSPtX05xFHtYy/1ni01eGCw==} - engines: {node: '>=6 <7 || >=8'} - dependencies: - graceful-fs: 4.2.11 - jsonfile: 4.0.0 - universalify: 0.1.2 - dev: true - /fsevents@2.3.2: resolution: {integrity: sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==} engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} @@ -703,10 +90,6 @@ packages: resolution: {integrity: sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==} dev: true - /graceful-fs@4.2.11: - resolution: {integrity: sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==} - dev: true - /has@1.0.3: resolution: {integrity: sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==} engines: {node: '>= 0.4.0'} @@ -714,114 +97,21 @@ packages: function-bind: 1.1.1 dev: true - /he@1.2.0: - resolution: {integrity: sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==} - hasBin: true - dev: true - - /import-lazy@4.0.0: - resolution: {integrity: sha512-rKtvo6a868b5Hu3heneU+L4yEQ4jYKLtjpnPeUdK7h0yzXGmyBTypknlkCvHFBqfX9YlorEiMM6Dnq/5atfHkw==} - engines: {node: '>=8'} - dev: true - /is-core-module@2.13.0: resolution: {integrity: sha512-Z7dk6Qo8pOCp3l4tsX2C5ZVas4V+UxwQodwZhLopL91TX8UyyHEXafPcyoeeWuLrwzHcr3igO78wNLwHJHsMCQ==} dependencies: has: 1.0.3 dev: true - /jju@1.4.0: - resolution: {integrity: sha512-8wb9Yw966OSxApiCt0K3yNJL8pnNeIv+OEq2YMidz4FKP6nonSRoOXc80iXY4JaN2FC11B9qsNmDsm+ZOfMROA==} - dev: true - - /json-schema-traverse@0.4.1: - resolution: {integrity: sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==} - dev: true - - /jsonfile@4.0.0: - resolution: {integrity: sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg==} - optionalDependencies: - graceful-fs: 4.2.11 - dev: true - - /kolorist@1.8.0: - resolution: {integrity: sha512-Y+60/zizpJ3HRH8DCss+q95yr6145JXZo46OTpFvDZWLfRCE4qChOyk1b26nMaNpfHHgxagk9dXT5OP0Tfe+dQ==} - dev: true - - /lodash.get@4.4.2: - resolution: {integrity: sha512-z+Uw/vLuy6gQe8cfaFWD7p0wVv8fJl3mbzXh33RS+0oW2wvUqiRXiQ69gLWSLpgB5/6sU+r6BlQR0MBILadqTQ==} - dev: true - - /lodash.isequal@4.5.0: - resolution: {integrity: sha512-pDo3lu8Jhfjqls6GkMgpahsF9kCyayhgykjyLMNFTKWrpVdAQtYyB4muAMWozBB4ig/dtWAmsMxLEI8wuz+DYQ==} - dev: true - - /lodash@4.17.21: - resolution: {integrity: sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==} - dev: true - - /lru-cache@6.0.0: - resolution: {integrity: sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==} - engines: {node: '>=10'} - dependencies: - yallist: 4.0.0 - dev: true - - /minimatch@9.0.3: - resolution: {integrity: sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg==} - engines: {node: '>=16 || 14 >=14.17'} - dependencies: - brace-expansion: 2.0.1 - dev: true - - /ms@2.1.2: - resolution: {integrity: sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==} - dev: true - - /muggle-string@0.3.1: - resolution: {integrity: sha512-ckmWDJjphvd/FvZawgygcUeQCxzvohjFO5RxTjj4eq8kw359gFF3E1brjfI+viLMxss5JrHTDRHZvu2/tuy0Qg==} - dev: true - - /nanoid@3.3.6: - resolution: {integrity: sha512-BGcqMMJuToF7i1rt+2PWSNVnWIkGCU78jBG3RxO/bZlnZPK2Cmi2QaffxGO/2RvWi9sL+FAiRiXMgsyxQ1DIDA==} - engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} - hasBin: true - dev: true - /path-parse@1.0.7: resolution: {integrity: sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==} dev: true - /picocolors@1.0.0: - resolution: {integrity: sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==} - dev: true - /picomatch@2.3.1: resolution: {integrity: sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==} engines: {node: '>=8.6'} dev: true - /postcss@8.4.27: - resolution: {integrity: sha512-gY/ACJtJPSmUFPDCHtX78+01fHa64FaU4zaaWfuh1MhGJISufJAH4cun6k/8fwsHYeK4UQmENQK+tRLCFJE8JQ==} - engines: {node: ^10 || ^12 || >=14} - dependencies: - nanoid: 3.3.6 - picocolors: 1.0.0 - source-map-js: 1.0.2 - dev: true - - /punycode@2.3.0: - resolution: {integrity: sha512-rRV+zQD8tVFys26lAGR9WUuS4iUAngJScM+ZRSKtvl5tKeZ2t5bvdNFdNHBW9FWR4guGHlgmsZ1G7BSm2wTbuA==} - engines: {node: '>=6'} - dev: true - - /resolve@1.19.0: - resolution: {integrity: sha512-rArEXAgsBG4UgRGcynxWIWKFvh/XZCcS8UJdHhwy91zwAvCZIbcs+vAbflgBnNjYMs/i/i+/Ux6IZhML1yPvxg==} - dependencies: - is-core-module: 2.13.0 - path-parse: 1.0.7 - dev: true - /resolve@1.22.4: resolution: {integrity: sha512-PXNdCiPqDqeUou+w1C2eTQbNfxKSuMxqTCuvlmmMsk1NWHL5fRrhY6Pl0qEYYc6+QqGClco1Qj8XnjPego4wfg==} hasBin: true @@ -839,197 +129,17 @@ packages: fsevents: 2.3.2 dev: true - /semver@7.5.4: - resolution: {integrity: sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==} - engines: {node: '>=10'} - hasBin: true - dependencies: - lru-cache: 6.0.0 - dev: true - - /source-map-js@1.0.2: - resolution: {integrity: sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==} - engines: {node: '>=0.10.0'} - dev: true - - /source-map@0.6.1: - resolution: {integrity: sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==} - engines: {node: '>=0.10.0'} - dev: true - - /sprintf-js@1.0.3: - resolution: {integrity: sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==} - dev: true - - /string-argv@0.3.2: - resolution: {integrity: sha512-aqD2Q0144Z+/RqG52NeHEkZauTAUWJO8c6yTftGJKO3Tja5tUgIfmIl6kExvhtxSDP7fXB6DvzkfMpCd/F3G+Q==} - engines: {node: '>=0.6.19'} - dev: true - - /strip-json-comments@3.1.1: - resolution: {integrity: sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==} - engines: {node: '>=8'} - dev: true - /supports-preserve-symlinks-flag@1.0.0: resolution: {integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==} engines: {node: '>= 0.4'} dev: true - /to-fast-properties@2.0.0: - resolution: {integrity: sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==} - engines: {node: '>=4'} - dev: true - /tslib@2.6.1: resolution: {integrity: sha512-t0hLfiEKfMUoqhG+U1oid7Pva4bbDPHYfJNiB7BiIjRkj1pyC++4N3huJfqY6aRH6VTB0rvtzQwjM4K6qpfOig==} dev: true - /typescript@5.0.4: - resolution: {integrity: sha512-cW9T5W9xY37cc+jfEnaUvX91foxtHkza3Nw3wkoF4sSlKn0MONdkdEndig/qPBWXNkmplh3NzayQzCiHM4/hqw==} - engines: {node: '>=12.20'} - hasBin: true - dev: true - /typescript@5.1.6: resolution: {integrity: sha512-zaWCozRZ6DLEWAWFrVDz1H6FVXzUSfTy5FUMWsQlU8Ym5JP9eO4xkTIROFCQvhQf61z6O/G6ugw3SgAnvvm+HA==} engines: {node: '>=14.17'} hasBin: true dev: true - - /universalify@0.1.2: - resolution: {integrity: sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==} - engines: {node: '>= 4.0.0'} - dev: true - - /uri-js@4.4.1: - resolution: {integrity: sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==} - dependencies: - punycode: 2.3.0 - dev: true - - /uuid@9.0.0: - resolution: {integrity: sha512-MXcSTerfPa4uqyzStbRoTgt5XIe3x5+42+q1sDuy3R5MDk66URdLMOZe5aPX/SQd+kuYAh0FdP/pO28IkQyTeg==} - hasBin: true - dev: true - - /validator@13.11.0: - resolution: {integrity: sha512-Ii+sehpSfZy+At5nPdnyMhx78fEoPDkR2XW/zimHEL3MyGJQOCQ7WeP20jPYRz7ZCpcKLB21NxuXHF3bxjStBQ==} - engines: {node: '>= 0.10'} - dev: true - - /vite-plugin-dts@3.5.2(rollup@3.28.0)(typescript@5.1.6)(vite@4.4.9): - resolution: {integrity: sha512-iKc851+jdHEoN1ifbOEsoMs+/Zg26PE1EyO2Jc+4apOWRoaeK2zRJnaStgUuJaVaEcAjTqWzpNgCAMq7iO6DWA==} - engines: {node: ^14.18.0 || >=16.0.0} - peerDependencies: - typescript: '*' - vite: '*' - peerDependenciesMeta: - vite: - optional: true - dependencies: - '@microsoft/api-extractor': 7.36.4 - '@rollup/pluginutils': 5.0.2(rollup@3.28.0) - '@vue/language-core': 1.8.8(typescript@5.1.6) - debug: 4.3.4 - kolorist: 1.8.0 - typescript: 5.1.6 - vite: 4.4.9 - vue-tsc: 1.8.8(typescript@5.1.6) - transitivePeerDependencies: - - '@types/node' - - rollup - - supports-color - dev: true - - /vite-plugin-top-level-await@1.3.1(rollup@3.28.0)(vite@4.4.9): - resolution: {integrity: sha512-55M1h4NAwkrpxPNOJIBzKZFihqLUzIgnElLSmPNPMR2Fn9+JHKaNg3sVX1Fq+VgvuBksQYxiD3OnwQAUu7kaPQ==} - peerDependencies: - vite: '>=2.8' - dependencies: - '@rollup/plugin-virtual': 3.0.1(rollup@3.28.0) - '@swc/core': 1.3.76 - uuid: 9.0.0 - vite: 4.4.9 - transitivePeerDependencies: - - '@swc/helpers' - - rollup - dev: true - - /vite-plugin-wasm@3.2.2(vite@4.4.9): - resolution: {integrity: sha512-cdbBUNR850AEoMd5nvLmnyeq63CSfoP1ctD/L2vLk/5+wsgAPlAVAzUK5nGKWO/jtehNlrSSHLteN+gFQw7VOA==} - peerDependencies: - vite: ^2 || ^3 || ^4 - dependencies: - vite: 4.4.9 - dev: true - - /vite@4.4.9: - resolution: {integrity: sha512-2mbUn2LlUmNASWwSCNSJ/EG2HuSRTnVNaydp6vMCm5VIqJsjMfbIWtbH2kDuwUVW5mMUKKZvGPX/rqeqVvv1XA==} - engines: {node: ^14.18.0 || >=16.0.0} - hasBin: true - peerDependencies: - '@types/node': '>= 14' - less: '*' - lightningcss: ^1.21.0 - sass: '*' - stylus: '*' - sugarss: '*' - terser: ^5.4.0 - peerDependenciesMeta: - '@types/node': - optional: true - less: - optional: true - lightningcss: - optional: true - sass: - optional: true - stylus: - optional: true - sugarss: - optional: true - terser: - optional: true - dependencies: - esbuild: 0.18.20 - postcss: 8.4.27 - rollup: 3.28.0 - optionalDependencies: - fsevents: 2.3.2 - dev: true - - /vue-template-compiler@2.7.14: - resolution: {integrity: sha512-zyA5Y3ArvVG0NacJDkkzJuPQDF8RFeRlzV2vLeSnhSpieO6LK2OVbdLPi5MPPs09Ii+gMO8nY4S3iKQxBxDmWQ==} - dependencies: - de-indent: 1.0.2 - he: 1.2.0 - dev: true - - /vue-tsc@1.8.8(typescript@5.1.6): - resolution: {integrity: sha512-bSydNFQsF7AMvwWsRXD7cBIXaNs/KSjvzWLymq/UtKE36697sboX4EccSHFVxvgdBlI1frYPc/VMKJNB7DFeDQ==} - hasBin: true - peerDependencies: - typescript: '*' - dependencies: - '@vue/language-core': 1.8.8(typescript@5.1.6) - '@vue/typescript': 1.8.8(typescript@5.1.6) - semver: 7.5.4 - typescript: 5.1.6 - dev: true - - /yallist@4.0.0: - resolution: {integrity: sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==} - dev: true - - /z-schema@5.0.5: - resolution: {integrity: sha512-D7eujBWkLa3p2sIpJA0d1pr7es+a7m0vFAnZLlCEKq/Ij2k0MLi9Br2UPxoxdYystm5K1yeBGzub0FlYUEWj2Q==} - engines: {node: '>=8.0.0'} - hasBin: true - dependencies: - lodash.get: 4.4.2 - lodash.isequal: 4.5.0 - validator: 13.11.0 - optionalDependencies: - commander: 9.5.0 - dev: true diff --git a/rollup.config.js b/rollup.config.js index c580882..c83d0d6 100644 --- a/rollup.config.js +++ b/rollup.config.js @@ -1,17 +1,36 @@ import { defineConfig } from "rollup"; import path from "node:path"; -import url from "node:url" +import url from "node:url"; import Typescript from "@rollup/plugin-typescript"; import Wasm from "@rollup/plugin-wasm"; -const dirname = path.dirname(url.fileURLToPath(import.meta.url)) +const dirname = path.dirname(url.fileURLToPath(import.meta.url)); -export default defineConfig({ - plugins: [Typescript(), Wasm({targetEnv: "auto-inline"})], - input: path.resolve(dirname, "src/library.ts"), - output: { - dir: "dist", - format: "es", - sourcemap: "inline" - } -}) +export default [ + defineConfig({ + plugins: [Typescript(), Wasm({ targetEnv: "auto-inline" })], + input: path.resolve(dirname, "src/library.ts"), + output: [ + { + name: "blurhash-c-wasm", + entryFileNames: "blurhash-c-wasm.js", + dir: "dist", + format: "module", + sourcemap: "inline", + }, + ], + }), + defineConfig({ + plugins: [Typescript(), Wasm({ targetEnv: "auto-inline" })], + input: path.resolve(dirname, "src/library.ts"), + output: [ + { + name: "blurhash-c-wasm", + entryFileNames: "blurhash-c-wasm.cjs", + dir: "dist", + format: "cjs", + sourcemap: "inline", + }, + ], + }), +]; diff --git a/src/library.ts b/src/library.ts index 8f72362..f66f894 100644 --- a/src/library.ts +++ b/src/library.ts @@ -3,21 +3,34 @@ import wasm from "./blurhash-decode.wasm"; type InstanceType = { memory: WebAssembly.Memory; - malloc: CallableFunction; - free: CallableFunction; - decodeToArray: CallableFunction; - isValidBlurhash: CallableFunction; + malloc: (bytes: number) => number; + free: (ptr: number) => void; + decodeToArray: ( + stringPtr: number, + width: number, + height: number, + punch: number, + nChannels: number, + pixelsArrayPtr: number + ) => number; + isValidBlurhash: (stringPtr: number) => number; }; -const wasmInstance = new WebAssembly.Instance(await wasm()); -const instance = wasmInstance.exports as InstanceType; +const wasmInitializationError = "The WASM module has not been initialized"; +const failed = -1; +const youAreRequiredToGiveThe = (thing: string) => + `You are required to give the ${thing}.`; +const blurHashStringRequiredError = youAreRequiredToGiveThe("Blurhash string"); +let wasmInstance: WebAssembly.Instance | undefined; +let instance: InstanceType | undefined; function encodeStringToWasmArray(string: string): number { + if (!instance) throw Error(wasmInitializationError); const encoder = new TextEncoder(); const encodedString = encoder.encode(string); const stringPtr: number = instance.malloc(encodedString.byteLength); const stringBuf = new Uint8Array( - instance.memory.buffer, + instance.memory.buffer, stringPtr, encodedString.byteLength + 1 ); @@ -28,6 +41,16 @@ function encodeStringToWasmArray(string: string): number { return stringPtr; } +/** + * Initialize the WASM instance. This is to support browsers without top level await. + */ +export async function initWasm() { + wasmInstance = await WebAssembly.instantiate( + (await wasm()) as WebAssembly.Module + ); + instance = wasmInstance.exports as InstanceType; +} + /** * Decode a Blurhash string into a Pixel Array that you can use to generate a Blurhash image. * @param blurhashString A valid Blurhash string. @@ -40,19 +63,27 @@ export function decode( width: number, height: number ): Uint8ClampedArray { - if (!width || !height) { - throw Error("You are required to give the width or height.") + if (!instance) throw Error(wasmInitializationError); + + if (!blurhashString) { + throw Error(blurHashStringRequiredError); + } + if (!width) { + throw Error(youAreRequiredToGiveThe("width")); + } + if (!height) { + throw Error(youAreRequiredToGiveThe("height")); } const pixelsPtrSize = width * 4 * width; const pixelsPtr = instance.malloc(pixelsPtrSize); const pixelsBuf = new Uint8ClampedArray( - instance.memory.buffer, + instance.memory.buffer, pixelsPtr, pixelsPtrSize ); - const stringPtr: number = encodeStringToWasmArray(blurhashString); + const stringPtr = encodeStringToWasmArray(blurhashString); const result = instance.decodeToArray( stringPtr, @@ -62,16 +93,16 @@ export function decode( 4, pixelsPtr ); - if (result == -1) { - instance.free(pixelsPtr); + if (result == failed) { instance.free(stringPtr); + instance.free(pixelsPtr); throw Error("Decoding the Blurhash string has failed."); } const clonedBuffer = pixelsBuf.slice(0); - instance.free(pixelsPtr); instance.free(stringPtr); + instance.free(pixelsPtr); return clonedBuffer; } @@ -82,6 +113,12 @@ export function decode( * @returns `true` if your string is valid, `false` elsewise. */ export function isValidBlurhash(blurhashString: string) { + if (!instance) throw Error(wasmInitializationError); + + if (!blurhashString) { + throw Error(blurHashStringRequiredError); + } + const stringPtr = encodeStringToWasmArray(blurhashString); const result: number = instance.isValidBlurhash(stringPtr); instance.free(stringPtr); diff --git a/tsconfig.json b/tsconfig.json index 9401dbe..58e6cbd 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -25,7 +25,7 @@ // "moduleDetection": "auto", /* Control what method is used to detect module-format JS files. */ /* Modules */ - "module": "ES2022", /* Specify what module code is generated. */ + "module": "ES2015", /* Specify what module code is generated. */ "rootDir": "./src", /* Specify the root folder within your source files. */ "moduleResolution": "NodeNext", // "baseUrl": "./", /* Specify the base directory to resolve non-relative module names. */ diff --git a/vite.config.js b/vite.config.js deleted file mode 100644 index 178c860..0000000 --- a/vite.config.js +++ /dev/null @@ -1,27 +0,0 @@ -import { defineConfig } from "vite"; -import path from "node:path"; -import Wasm from "vite-plugin-wasm"; -import TopLevelAwait from "vite-plugin-top-level-await"; -import Dts from "vite-plugin-dts"; -import Typescript from "@rollup/plugin-typescript"; - -export default defineConfig({ - plugins: [Wasm(), TopLevelAwait(), Dts()], - build: { - // lib: { - // entry: path.resolve(__dirname, "src/library.ts"), - // name: "blurhash-c-wasm", - // formats: ["es"], - // }, - minify: false, - sourcemap: true, - rollupOptions: { - input: path.resolve(__dirname, "src/library.ts"), - output: { - dir: "dist", - format: "es", - sourcemap: "inline" - } - } - }, -});