diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000..f8d592e --- /dev/null +++ b/.editorconfig @@ -0,0 +1,15 @@ +root = true + +[*] +charset = utf-8 +end_of_line = lf +indent_size = 4 +indent_style = space +insert_final_newline = true +max_line_length = 120 +tab_width = 4 +trim_trailing_whitespace = true + +[*.{cjs,js,mjs,ts,mts,json}] +indent_size = 2 +tab_width = 2 diff --git a/.gitignore b/.gitignore index 2f7896d..0ecd7db 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,4 @@ target/ +pkg/ +pkg-*/ +node_modules/ diff --git a/.idea/codeStyles/codeStyleConfig.xml b/.idea/codeStyles/codeStyleConfig.xml new file mode 100644 index 0000000..1a0176a --- /dev/null +++ b/.idea/codeStyles/codeStyleConfig.xml @@ -0,0 +1,5 @@ + + + + diff --git a/.idea/jsLibraryMappings.xml b/.idea/jsLibraryMappings.xml new file mode 100644 index 0000000..e648c01 --- /dev/null +++ b/.idea/jsLibraryMappings.xml @@ -0,0 +1,6 @@ + + + + + + diff --git a/.idea/prettier.xml b/.idea/prettier.xml new file mode 100644 index 0000000..15e69ed --- /dev/null +++ b/.idea/prettier.xml @@ -0,0 +1,8 @@ + + + + + diff --git a/Cargo.lock b/Cargo.lock index 3ff2f66..04b7a04 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -165,6 +165,7 @@ dependencies = [ name = "um_wasm" version = "0.1.0" dependencies = [ + "anyhow", "console_error_panic_hook", "umc_kuwo", "wasm-bindgen", diff --git a/build.sh b/build.sh index 678f9ef..cc58313 100755 --- a/build.sh +++ b/build.sh @@ -1,3 +1,4 @@ #!/bin/bash wasm-pack build --target bundler um_wasm/ +wasm-pack build --target nodejs -d pkg_node um_wasm/ diff --git a/um_crypto/kuwo/src/des/mod.rs b/um_crypto/kuwo/src/des/mod.rs index 893edc2..be903db 100644 --- a/um_crypto/kuwo/src/des/mod.rs +++ b/um_crypto/kuwo/src/des/mod.rs @@ -38,7 +38,7 @@ pub fn encrypt_ksing>(data: T, key: &[u8; 8]) -> Result { Ok(B64.encode(data)) } -pub fn decode_ekey>(data: &str, key: &[u8; 8]) -> Result { +pub fn decode_ekey(data: &str, key: &[u8; 8]) -> Result { let decoded = decrypt_ksing(data, key)?; Ok(decoded[16..].to_string()) } diff --git a/um_wasm/.gitignore b/um_wasm/.gitignore index 4e30131..a3af082 100644 --- a/um_wasm/.gitignore +++ b/um_wasm/.gitignore @@ -3,4 +3,5 @@ Cargo.lock bin/ pkg/ +pkg_*/ wasm-pack.log diff --git a/um_wasm/Cargo.toml b/um_wasm/Cargo.toml index 88a390d..300ba65 100644 --- a/um_wasm/Cargo.toml +++ b/um_wasm/Cargo.toml @@ -3,6 +3,9 @@ name = "um_wasm" version = "0.1.0" authors = ["鲁树人 "] edition = "2018" +description = "um_crypo in WebAssembly" +repository = "https://git.unlock-music.dev/lsr/lib_um_crypto_rust.git" +license = "Apache-2.0 + MIT" [lib] crate-type = ["cdylib", "rlib"] @@ -12,6 +15,7 @@ default = ["console_error_panic_hook"] [dependencies] wasm-bindgen = "0.2.84" +anyhow = "1.0.86" # The `console_error_panic_hook` crate provides better debugging of panics by # logging them with `console.error`. This is great for development, but requires diff --git a/um_wasm/src/errors.rs b/um_wasm/src/errors.rs new file mode 100644 index 0000000..ead1b6a --- /dev/null +++ b/um_wasm/src/errors.rs @@ -0,0 +1,22 @@ +use wasm_bindgen::JsError; + +#[derive(Debug)] +pub struct WasmError { + error: anyhow::Error, +} + +impl From for WasmError { + fn from(err: anyhow::Error) -> WasmError { + WasmError { error: err } + } +} + +impl From for JsError { + fn from(error: WasmError) -> Self { + JsError::new(&error.error.to_string()) + } +} + +pub fn map_js_error(error: anyhow::Error) -> wasm_bindgen::JsError { + JsError::new(&error.to_string()) +} diff --git a/um_wasm/src/exports/kuwo.rs b/um_wasm/src/exports/kuwo.rs new file mode 100644 index 0000000..f7c3f88 --- /dev/null +++ b/um_wasm/src/exports/kuwo.rs @@ -0,0 +1,9 @@ +use crate::errors::map_js_error; +use wasm_bindgen::prelude::wasm_bindgen; +use wasm_bindgen::JsError; + +#[wasm_bindgen(js_name=kuwoDecodeEKey)] +pub fn decode_ekey(ekey: &str) -> Result { + let ekey = umc_kuwo::des::decode_ekey(ekey, &umc_kuwo::SECRET_KEY).map_err(map_js_error)?; + Ok(ekey) +} diff --git a/um_wasm/src/exports/mod.rs b/um_wasm/src/exports/mod.rs new file mode 100644 index 0000000..77169f0 --- /dev/null +++ b/um_wasm/src/exports/mod.rs @@ -0,0 +1 @@ +pub mod kuwo; diff --git a/um_wasm/src/lib.rs b/um_wasm/src/lib.rs index 5a1262d..b48d59d 100644 --- a/um_wasm/src/lib.rs +++ b/um_wasm/src/lib.rs @@ -1,3 +1,5 @@ +mod errors; +pub mod exports; mod utils; use utils::set_panic_hook; diff --git a/um_wasm_loader/.gitignore b/um_wasm_loader/.gitignore new file mode 100644 index 0000000..e66b06e --- /dev/null +++ b/um_wasm_loader/.gitignore @@ -0,0 +1,5 @@ +node_modules/ +pkg/ +dist/ +/LICENSE* +/*.tgz diff --git a/um_wasm_loader/.npmrc b/um_wasm_loader/.npmrc new file mode 100644 index 0000000..d1d4aad --- /dev/null +++ b/um_wasm_loader/.npmrc @@ -0,0 +1 @@ +@um:registry=https://git.unlock-music.dev/api/packages/um/npm/ diff --git a/um_wasm_loader/Readme.MD b/um_wasm_loader/Readme.MD new file mode 100644 index 0000000..ef7f37d --- /dev/null +++ b/um_wasm_loader/Readme.MD @@ -0,0 +1,25 @@ +# @um/crypto + +用于 Unlock Music 的加解密支持库。 + +使用 Rust 编写,并使用 `wasm-pack` 转义到 WebAssembly 格式,用于在不同的平台(浏览器)运行。 + +## 使用 + +在项目根目录下,建立或更改 `.npmrc` 文件,确保下述行存在: + +``` +@um:registry=https://git.unlock-music.dev/api/packages/um/npm/ +``` + +使用你喜欢的包管理器安装,例如 `npm` 或 `pnpm`: + +```sh +# 使用 npm +npm install @um/crypto + +# 使用 pnpm +pnpm install @um/crypto +``` + +具体能干啥… 参考源码吧。 diff --git a/um_wasm_loader/Release.MD b/um_wasm_loader/Release.MD new file mode 100644 index 0000000..fec93fd --- /dev/null +++ b/um_wasm_loader/Release.MD @@ -0,0 +1,15 @@ +## 发包 + +- 到后台建立一个 API Token,确保有 `Packages` 的写权限: +- 编辑 `~/.npmrc`,加入下述两行并替换 `token` 为新申请的令牌: + + ```text + //git.unlock-music.dev/api/packages/um/npm/:_authToken=xxxxx123456789xxxxx + //git.unlock-music.dev/api/packages/npm/:_authToken=xxxxx123456789xxxxx + ``` + +- 使用 `publish` 指令发包: + + ```sh + pnpm publish --access=public + ``` diff --git a/um_wasm_loader/build.js b/um_wasm_loader/build.js new file mode 100644 index 0000000..034edeb --- /dev/null +++ b/um_wasm_loader/build.js @@ -0,0 +1,103 @@ +#!/usr/bin/env node + +const path = require('node:path'); +const os = require('node:os'); +const { spawn } = require('node:child_process'); +const { readFile, writeFile, copyFile, rm } = require('node:fs/promises'); + +/** + * Run and wait for command to complete. + * @param {string[]} command + * @param {SpawnOptionsWithStdioTuple} [opts] + * @returns {Promise} + */ +async function run(command, opts = undefined) { + return new Promise((resolve, reject) => { + console.log(`running: ${command.join(' ')}`); + const child = spawn(command[0], command.slice(1), { + stdio: ['ignore', 'inherit', 'inherit'], + ...opts, + }); + child.once('error', reject); + child.once('close', (code) => { + if (code === 0) { + resolve(); + } else { + reject(new Error(`process exit with code ${code}`)); + } + }); + }); +} + +/** + * @param {string} filepath + * @param {...([Buffer, Buffer])} binaryReplacements + */ +async function replaceBytes(filepath, ...binaryReplacements) { + let content = await readFile(filepath); + for (const [search, replace] of binaryReplacements) { + let idx = -1; + while ((idx = content.indexOf(search, idx + 1)) != -1) { + replace.copy(content, idx, 0, replace.length); + } + } + await writeFile(filepath, content); +} + +/** + * @param {string} filepath + * @param {...([RegExp|string, string|(...args: string) => unknown])} replacementRules + */ +async function replaceFileByRegex(filepath, ...replacementRules) { + let content = await readFile(filepath, 'utf-8'); + for (const [search, replace] of replacementRules) { + content = content.replace(search, replace); + } + await writeFile(filepath, content, 'utf-8'); +} + +async function main() { + const wasmSourceDir = path.join(__dirname, '..', 'um_wasm'); + const wasmOutDir = path.resolve(__dirname, 'pkg'); + const wasmDistDir = path.resolve(__dirname, 'dist'); + await rm(wasmOutDir, { recursive: true, force: true }); + const wasmRelOutDir = path.relative(wasmSourceDir, wasmOutDir); + await run(['wasm-pack', 'build', '--target', 'web', '--out-dir', wasmRelOutDir], { + cwd: path.resolve(__dirname, '..', 'um_wasm'), + }); + + // Remove unneeded files + await Promise.all([ + ...['.gitignore', 'package.json', 'README.md'].map((name) => { + return rm(path.join(wasmOutDir, name), { force: true }); + }), + rm(wasmDistDir, { recursive: true, force: true }), + ]); + + const homeDir = os.homedir(); + const dummyHome = '/h' + homeDir.slice(3).replace(/./g, '_') + '/'; + + // Patch some files... + await Promise.all([ + replaceFileByRegex(path.join(wasmOutDir, 'um_wasm.js'), [/export default (__wbg_init);/, 'export { $1 };']), + replaceFileByRegex(path.join(wasmOutDir, 'um_wasm.d.ts'), [/export default (function __wbg_init)/, 'export $1']), + replaceBytes(path.join(wasmOutDir, 'um_wasm_bg.wasm'), [ + Buffer.from(homeDir, 'utf-8'), + Buffer.from(dummyHome, 'utf-8'), + ]), + copyFile(path.join(__dirname, '../LICENSE_APACHE'), 'LICENSE_APACHE'), + copyFile(path.join(__dirname, '../LICENSE_MIT'), 'LICENSE_MIT'), + ]); + + // Ask rollup to build bundles. + await run(['pnpm', 'build:bundle']); +} + +main() + .catch((err) => { + console.error(err); + process.exit(1); + }) + .then(() => { + process.exit(0); + }); diff --git a/um_wasm_loader/package.json b/um_wasm_loader/package.json new file mode 100644 index 0000000..ff9107b --- /dev/null +++ b/um_wasm_loader/package.json @@ -0,0 +1,45 @@ +{ + "name": "@um/crypto", + "version": "0.0.0-alpha.1", + "description": "Project Unlock Music: 加解密支持库", + "scripts": { + "build": "node build.js", + "build:bundle": "rollup -c" + }, + "main": "dist/loader.js", + "module": "dist/loader.mjs", + "types": "dist/loader.d.ts", + "exports": { + ".": { + "import": "./dist/loader.mjs", + "require": "./dist/loader.js", + "types": "./dist/loader.d.ts" + }, + "./inline": { + "require": "./dist/loader-inline.js", + "import": "./dist/loader-inline.js", + "types": "./dist/loader.d.ts" + } + }, + "files": [ + "dist/", + "LICENSE*" + ], + "keywords": [], + "author": "", + "license": "MIT + APACHE 2.0", + "devDependencies": { + "@rollup/plugin-replace": "^5.0.7", + "@rollup/plugin-wasm": "^6.2.2", + "@types/node": "^22.5.2", + "prettier": "^3.3.3", + "rollup": "^4.21.2", + "rollup-plugin-dts": "^6.1.1", + "typescript": "^5.5.4" + }, + "prettier": { + "singleQuote": true, + "printWidth": 120, + "tabWidth": 2 + } +} diff --git a/um_wasm_loader/pnpm-lock.yaml b/um_wasm_loader/pnpm-lock.yaml new file mode 100644 index 0000000..0f3a770 --- /dev/null +++ b/um_wasm_loader/pnpm-lock.yaml @@ -0,0 +1,391 @@ +lockfileVersion: '6.0' + +settings: + autoInstallPeers: true + excludeLinksFromLockfile: false + +devDependencies: + '@rollup/plugin-replace': + specifier: ^5.0.7 + version: 5.0.7(rollup@4.21.2) + '@rollup/plugin-wasm': + specifier: ^6.2.2 + version: 6.2.2(rollup@4.21.2) + '@types/node': + specifier: ^22.5.2 + version: 22.5.2 + prettier: + specifier: ^3.3.3 + version: 3.3.3 + rollup: + specifier: ^4.21.2 + version: 4.21.2 + rollup-plugin-dts: + specifier: ^6.1.1 + version: 6.1.1(rollup@4.21.2)(typescript@5.5.4) + typescript: + specifier: ^5.5.4 + version: 5.5.4 + +packages: + + /@babel/code-frame@7.24.7: + resolution: {integrity: sha512-BcYH1CVJBO9tvyIZ2jVeXgSIMvGZ2FDRvDdOIVQyuklNKSsx+eppDEBq/g47Ayw+RqNFE+URvOShmf+f/qwAlA==} + engines: {node: '>=6.9.0'} + requiresBuild: true + dependencies: + '@babel/highlight': 7.24.7 + picocolors: 1.0.1 + dev: true + optional: true + + /@babel/helper-validator-identifier@7.24.7: + resolution: {integrity: sha512-rR+PBcQ1SMQDDyF6X0wxtG8QyLCgUB0eRAGguqRLfkCA87l7yAP7ehq8SNj96OOGTO8OBV70KhuFYcIkHXOg0w==} + engines: {node: '>=6.9.0'} + requiresBuild: true + dev: true + optional: true + + /@babel/highlight@7.24.7: + resolution: {integrity: sha512-EStJpq4OuY8xYfhGVXngigBJRWxftKX9ksiGDnmlY3o7B/V7KIAc9X4oiK87uPJSc/vs5L869bem5fhZa8caZw==} + engines: {node: '>=6.9.0'} + requiresBuild: true + dependencies: + '@babel/helper-validator-identifier': 7.24.7 + chalk: 2.4.2 + js-tokens: 4.0.0 + picocolors: 1.0.1 + dev: true + optional: true + + /@jridgewell/sourcemap-codec@1.5.0: + resolution: {integrity: sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==} + dev: true + + /@rollup/plugin-replace@5.0.7(rollup@4.21.2): + resolution: {integrity: sha512-PqxSfuorkHz/SPpyngLyg5GCEkOcee9M1bkxiVDr41Pd61mqP1PLOoDPbpl44SB2mQGKwV/In74gqQmGITOhEQ==} + engines: {node: '>=14.0.0'} + peerDependencies: + rollup: ^1.20.0||^2.0.0||^3.0.0||^4.0.0 + peerDependenciesMeta: + rollup: + optional: true + dependencies: + '@rollup/pluginutils': 5.1.0(rollup@4.21.2) + magic-string: 0.30.11 + rollup: 4.21.2 + dev: true + + /@rollup/plugin-wasm@6.2.2(rollup@4.21.2): + resolution: {integrity: sha512-gpC4R1G9Ni92ZIRTexqbhX7U+9estZrbhP+9SRb0DW9xpB9g7j34r+J2hqrcW/lRI7dJaU84MxZM0Rt82tqYPQ==} + engines: {node: '>=14.0.0'} + peerDependencies: + rollup: ^1.20.0||^2.0.0||^3.0.0||^4.0.0 + peerDependenciesMeta: + rollup: + optional: true + dependencies: + '@rollup/pluginutils': 5.1.0(rollup@4.21.2) + rollup: 4.21.2 + dev: true + + /@rollup/pluginutils@5.1.0(rollup@4.21.2): + resolution: {integrity: sha512-XTIWOPPcpvyKI6L1NHo0lFlCyznUEyPmPY1mc3KpPVDYulHSTvyeLNVW00QTLIAFNhR3kYnJTQHeGqU4M3n09g==} + engines: {node: '>=14.0.0'} + peerDependencies: + rollup: ^1.20.0||^2.0.0||^3.0.0||^4.0.0 + peerDependenciesMeta: + rollup: + optional: true + dependencies: + '@types/estree': 1.0.5 + estree-walker: 2.0.2 + picomatch: 2.3.1 + rollup: 4.21.2 + dev: true + + /@rollup/rollup-android-arm-eabi@4.21.2: + resolution: {integrity: sha512-fSuPrt0ZO8uXeS+xP3b+yYTCBUd05MoSp2N/MFOgjhhUhMmchXlpTQrTpI8T+YAwAQuK7MafsCOxW7VrPMrJcg==} + cpu: [arm] + os: [android] + requiresBuild: true + dev: true + optional: true + + /@rollup/rollup-android-arm64@4.21.2: + resolution: {integrity: sha512-xGU5ZQmPlsjQS6tzTTGwMsnKUtu0WVbl0hYpTPauvbRAnmIvpInhJtgjj3mcuJpEiuUw4v1s4BimkdfDWlh7gA==} + cpu: [arm64] + os: [android] + requiresBuild: true + dev: true + optional: true + + /@rollup/rollup-darwin-arm64@4.21.2: + resolution: {integrity: sha512-99AhQ3/ZMxU7jw34Sq8brzXqWH/bMnf7ZVhvLk9QU2cOepbQSVTns6qoErJmSiAvU3InRqC2RRZ5ovh1KN0d0Q==} + cpu: [arm64] + os: [darwin] + requiresBuild: true + dev: true + optional: true + + /@rollup/rollup-darwin-x64@4.21.2: + resolution: {integrity: sha512-ZbRaUvw2iN/y37x6dY50D8m2BnDbBjlnMPotDi/qITMJ4sIxNY33HArjikDyakhSv0+ybdUxhWxE6kTI4oX26w==} + cpu: [x64] + os: [darwin] + requiresBuild: true + dev: true + optional: true + + /@rollup/rollup-linux-arm-gnueabihf@4.21.2: + resolution: {integrity: sha512-ztRJJMiE8nnU1YFcdbd9BcH6bGWG1z+jP+IPW2oDUAPxPjo9dverIOyXz76m6IPA6udEL12reYeLojzW2cYL7w==} + cpu: [arm] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@rollup/rollup-linux-arm-musleabihf@4.21.2: + resolution: {integrity: sha512-flOcGHDZajGKYpLV0JNc0VFH361M7rnV1ee+NTeC/BQQ1/0pllYcFmxpagltANYt8FYf9+kL6RSk80Ziwyhr7w==} + cpu: [arm] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@rollup/rollup-linux-arm64-gnu@4.21.2: + resolution: {integrity: sha512-69CF19Kp3TdMopyteO/LJbWufOzqqXzkrv4L2sP8kfMaAQ6iwky7NoXTp7bD6/irKgknDKM0P9E/1l5XxVQAhw==} + cpu: [arm64] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@rollup/rollup-linux-arm64-musl@4.21.2: + resolution: {integrity: sha512-48pD/fJkTiHAZTnZwR0VzHrao70/4MlzJrq0ZsILjLW/Ab/1XlVUStYyGt7tdyIiVSlGZbnliqmult/QGA2O2w==} + cpu: [arm64] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@rollup/rollup-linux-powerpc64le-gnu@4.21.2: + resolution: {integrity: sha512-cZdyuInj0ofc7mAQpKcPR2a2iu4YM4FQfuUzCVA2u4HI95lCwzjoPtdWjdpDKyHxI0UO82bLDoOaLfpZ/wviyQ==} + cpu: [ppc64] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@rollup/rollup-linux-riscv64-gnu@4.21.2: + resolution: {integrity: sha512-RL56JMT6NwQ0lXIQmMIWr1SW28z4E4pOhRRNqwWZeXpRlykRIlEpSWdsgNWJbYBEWD84eocjSGDu/XxbYeCmwg==} + cpu: [riscv64] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@rollup/rollup-linux-s390x-gnu@4.21.2: + resolution: {integrity: sha512-PMxkrWS9z38bCr3rWvDFVGD6sFeZJw4iQlhrup7ReGmfn7Oukrr/zweLhYX6v2/8J6Cep9IEA/SmjXjCmSbrMQ==} + cpu: [s390x] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@rollup/rollup-linux-x64-gnu@4.21.2: + resolution: {integrity: sha512-B90tYAUoLhU22olrafY3JQCFLnT3NglazdwkHyxNDYF/zAxJt5fJUB/yBoWFoIQ7SQj+KLe3iL4BhOMa9fzgpw==} + cpu: [x64] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@rollup/rollup-linux-x64-musl@4.21.2: + resolution: {integrity: sha512-7twFizNXudESmC9oneLGIUmoHiiLppz/Xs5uJQ4ShvE6234K0VB1/aJYU3f/4g7PhssLGKBVCC37uRkkOi8wjg==} + cpu: [x64] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@rollup/rollup-win32-arm64-msvc@4.21.2: + resolution: {integrity: sha512-9rRero0E7qTeYf6+rFh3AErTNU1VCQg2mn7CQcI44vNUWM9Ze7MSRS/9RFuSsox+vstRt97+x3sOhEey024FRQ==} + cpu: [arm64] + os: [win32] + requiresBuild: true + dev: true + optional: true + + /@rollup/rollup-win32-ia32-msvc@4.21.2: + resolution: {integrity: sha512-5rA4vjlqgrpbFVVHX3qkrCo/fZTj1q0Xxpg+Z7yIo3J2AilW7t2+n6Q8Jrx+4MrYpAnjttTYF8rr7bP46BPzRw==} + cpu: [ia32] + os: [win32] + requiresBuild: true + dev: true + optional: true + + /@rollup/rollup-win32-x64-msvc@4.21.2: + resolution: {integrity: sha512-6UUxd0+SKomjdzuAcp+HAmxw1FlGBnl1v2yEPSabtx4lBfdXHDVsW7+lQkgz9cNFJGY3AWR7+V8P5BqkD9L9nA==} + cpu: [x64] + os: [win32] + requiresBuild: true + dev: true + optional: true + + /@types/estree@1.0.5: + resolution: {integrity: sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==} + dev: true + + /@types/node@22.5.2: + resolution: {integrity: sha512-acJsPTEqYqulZS/Yp/S3GgeE6GZ0qYODUR8aVr/DkhHQ8l9nd4j5x1/ZJy9/gHrRlFMqkO6i0I3E27Alu4jjPg==} + dependencies: + undici-types: 6.19.8 + dev: true + + /ansi-styles@3.2.1: + resolution: {integrity: sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==} + engines: {node: '>=4'} + requiresBuild: true + dependencies: + color-convert: 1.9.3 + dev: true + optional: true + + /chalk@2.4.2: + resolution: {integrity: sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==} + engines: {node: '>=4'} + requiresBuild: true + dependencies: + ansi-styles: 3.2.1 + escape-string-regexp: 1.0.5 + supports-color: 5.5.0 + dev: true + optional: true + + /color-convert@1.9.3: + resolution: {integrity: sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==} + requiresBuild: true + dependencies: + color-name: 1.1.3 + dev: true + optional: true + + /color-name@1.1.3: + resolution: {integrity: sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==} + requiresBuild: true + dev: true + optional: true + + /escape-string-regexp@1.0.5: + resolution: {integrity: sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==} + engines: {node: '>=0.8.0'} + requiresBuild: true + dev: true + optional: true + + /estree-walker@2.0.2: + resolution: {integrity: sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==} + dev: true + + /fsevents@2.3.3: + resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==} + engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} + os: [darwin] + requiresBuild: true + dev: true + optional: true + + /has-flag@3.0.0: + resolution: {integrity: sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==} + engines: {node: '>=4'} + requiresBuild: true + dev: true + optional: true + + /js-tokens@4.0.0: + resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==} + requiresBuild: true + dev: true + optional: true + + /magic-string@0.30.11: + resolution: {integrity: sha512-+Wri9p0QHMy+545hKww7YAu5NyzF8iomPL/RQazugQ9+Ez4Ic3mERMd8ZTX5rfK944j+560ZJi8iAwgak1Ac7A==} + dependencies: + '@jridgewell/sourcemap-codec': 1.5.0 + dev: true + + /picocolors@1.0.1: + resolution: {integrity: sha512-anP1Z8qwhkbmu7MFP5iTt+wQKXgwzf7zTyGlcdzabySa9vd0Xt392U0rVmz9poOaBj0uHJKyyo9/upk0HrEQew==} + requiresBuild: true + dev: true + optional: true + + /picomatch@2.3.1: + resolution: {integrity: sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==} + engines: {node: '>=8.6'} + dev: true + + /prettier@3.3.3: + resolution: {integrity: sha512-i2tDNA0O5IrMO757lfrdQZCc2jPNDVntV0m/+4whiDfWaTKfMNgR7Qz0NAeGz/nRqF4m5/6CLzbP4/liHt12Ew==} + engines: {node: '>=14'} + hasBin: true + dev: true + + /rollup-plugin-dts@6.1.1(rollup@4.21.2)(typescript@5.5.4): + resolution: {integrity: sha512-aSHRcJ6KG2IHIioYlvAOcEq6U99sVtqDDKVhnwt70rW6tsz3tv5OSjEiWcgzfsHdLyGXZ/3b/7b/+Za3Y6r1XA==} + engines: {node: '>=16'} + peerDependencies: + rollup: ^3.29.4 || ^4 + typescript: ^4.5 || ^5.0 + dependencies: + magic-string: 0.30.11 + rollup: 4.21.2 + typescript: 5.5.4 + optionalDependencies: + '@babel/code-frame': 7.24.7 + dev: true + + /rollup@4.21.2: + resolution: {integrity: sha512-e3TapAgYf9xjdLvKQCkQTnbTKd4a6jwlpQSJJFokHGaX2IVjoEqkIIhiQfqsi0cdwlOD+tQGuOd5AJkc5RngBw==} + engines: {node: '>=18.0.0', npm: '>=8.0.0'} + hasBin: true + dependencies: + '@types/estree': 1.0.5 + optionalDependencies: + '@rollup/rollup-android-arm-eabi': 4.21.2 + '@rollup/rollup-android-arm64': 4.21.2 + '@rollup/rollup-darwin-arm64': 4.21.2 + '@rollup/rollup-darwin-x64': 4.21.2 + '@rollup/rollup-linux-arm-gnueabihf': 4.21.2 + '@rollup/rollup-linux-arm-musleabihf': 4.21.2 + '@rollup/rollup-linux-arm64-gnu': 4.21.2 + '@rollup/rollup-linux-arm64-musl': 4.21.2 + '@rollup/rollup-linux-powerpc64le-gnu': 4.21.2 + '@rollup/rollup-linux-riscv64-gnu': 4.21.2 + '@rollup/rollup-linux-s390x-gnu': 4.21.2 + '@rollup/rollup-linux-x64-gnu': 4.21.2 + '@rollup/rollup-linux-x64-musl': 4.21.2 + '@rollup/rollup-win32-arm64-msvc': 4.21.2 + '@rollup/rollup-win32-ia32-msvc': 4.21.2 + '@rollup/rollup-win32-x64-msvc': 4.21.2 + fsevents: 2.3.3 + dev: true + + /supports-color@5.5.0: + resolution: {integrity: sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==} + engines: {node: '>=4'} + requiresBuild: true + dependencies: + has-flag: 3.0.0 + dev: true + optional: true + + /typescript@5.5.4: + resolution: {integrity: sha512-Mtq29sKDAEYP7aljRgtPOpTvOfbwRWlS6dPRzwjdE+C0R4brX/GUyhHSecbHMFLNBLcJIPt9nl9yG5TZ1weH+Q==} + engines: {node: '>=14.17'} + hasBin: true + dev: true + + /undici-types@6.19.8: + resolution: {integrity: sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw==} + dev: true diff --git a/um_wasm_loader/rollup.config.mjs b/um_wasm_loader/rollup.config.mjs new file mode 100644 index 0000000..3d0d46a --- /dev/null +++ b/um_wasm_loader/rollup.config.mjs @@ -0,0 +1,50 @@ +import { defineConfig } from 'rollup'; +import { wasm } from '@rollup/plugin-wasm'; +import replace from '@rollup/plugin-replace'; +import { dts } from 'rollup-plugin-dts'; + +function makePlugins({ sync }) { + const plugins = []; + plugins.push(wasm({ sync: sync ? ['pkg/um_wasm_bg.wasm'] : [] })); + plugins.push( + replace({ + preventAssignment: true, + values: { + 'process.env.UMC_INLINE_BUILD': JSON.stringify(String(sync ? 1 : 0)), + }, + }), + ); + return plugins; +} + +export default defineConfig([ + { + input: 'src/loader.mjs', + output: { + file: 'dist/loader.js', + format: 'cjs', + }, + plugins: [...makePlugins({ sync: false })], + }, + { + input: 'src/loader.mjs', + output: { + file: 'dist/loader.mjs', + format: 'es', + }, + plugins: [...makePlugins({ sync: false })], + }, + { + input: 'src/loader.mjs', + output: { + file: 'dist/loader-inline.js', + format: 'cjs', + }, + plugins: [...makePlugins({ sync: true })], + }, + { + input: './src/loader.d.ts', + output: [{ file: 'dist/loader.d.ts', format: 'es' }], + plugins: [dts()], + }, +]); diff --git a/um_wasm_loader/src/loader.d.ts b/um_wasm_loader/src/loader.d.ts new file mode 100644 index 0000000..d529846 --- /dev/null +++ b/um_wasm_loader/src/loader.d.ts @@ -0,0 +1,2 @@ +export * from '../pkg/um_wasm'; +export const ready: Promise; diff --git a/um_wasm_loader/src/loader.mjs b/um_wasm_loader/src/loader.mjs new file mode 100644 index 0000000..52c204e --- /dev/null +++ b/um_wasm_loader/src/loader.mjs @@ -0,0 +1,16 @@ +import umWasm from '../pkg/um_wasm_bg.wasm'; +import { __wbg_init, initSync } from '../pkg/um_wasm.js'; +export * from '../pkg/um_wasm.js'; + +function loader() { + if (process.env.UMC_INLINE_BUILD === '1') { + initSync({ module: umWasm() }); + return Promise.resolve(undefined); + } else { + return umWasm().then(async (wasm) => { + await __wbg_init({ module_or_path: wasm }); + }); + } +} + +export const ready = loader();