-
Your average Hashrate: {{ number_formatter.format(hashrate) }} H/s
-
You have solved {{ total_solved }} {{ pluralize(total_solved, "challenge") }} in
- {{ number_formatter.format(total_solving_for / 1000) }}s
-
Your Hashrate on the last challenge: {{ number_formatter.format(hashrate_array.at(-1)!) }} H/s
+
+
-
You have not solved any challenges yet
-
Challenge: {{ challenge_loading_indicator }}
- {{ challenge }}
-
-
Nonce: {{ nonce }}
-
- Get Challenge
-
-
- Solve Challenge
- Solving challenge for {{ solving_for }}s...
-
-
-
- Challenge solved in {{ solveTime }}ms!
- Validating solution...
-
-
{{ challenge_error }}
-
-
-
-
- Auto solve
-
-
-
-
- Difficulty
-
-
-
-
-
\ No newline at end of file
+
\ No newline at end of file
diff --git a/example-app/app/pages/widget.vue b/example-app/app/pages/widget.vue
deleted file mode 100644
index af5a7e7..0000000
--- a/example-app/app/pages/widget.vue
+++ /dev/null
@@ -1,38 +0,0 @@
-
-
-
-
-
\ No newline at end of file
diff --git a/example-app/app/utils/worker-name.ts b/example-app/app/utils/worker-name.ts
deleted file mode 100644
index 7d7e09f..0000000
--- a/example-app/app/utils/worker-name.ts
+++ /dev/null
@@ -1,6 +0,0 @@
-const adjectives = ['swift', 'silent', 'hidden', 'clever', 'brave', 'sharp', 'shadow', 'crimson', 'bright', 'quiet', 'loud', 'happy', 'dark', 'evil', 'good', 'intelligent', 'lovely', 'mysterious', 'peaceful', 'powerful', 'pure', 'quiet', 'shiny', 'sleepy', 'strong', 'sweet', 'tall', 'warm', 'gentle', 'kind', 'nice', 'polite', 'rough', 'rude', 'scary', 'shy', 'silly', 'smart', 'strange', 'tough', 'ugly', 'vivid', 'wicked', 'wise', 'young', 'sleepy'];
-const nouns = ['fox', 'river', 'stone', 'cipher', 'link', 'comet', 'falcon', 'signal', 'anchor', 'spark', 'stone', 'comet', 'rocket', 'snake', 'snail', 'shark', 'elephant', 'cat', 'dog', 'whale', 'orca', 'cactus', 'flower', 'frog', 'toad', 'apple', 'strawberry', 'raspberry', 'lemon', 'bot', 'gopher', 'dinosaur', 'racoon', 'penguin', 'chameleon', 'atom', 'particle', 'witch', 'wizard', 'warlock', 'deer']
-
-export function getWorkerName() {
- return `${adjectives[Math.floor(Math.random() * adjectives.length)]}-${nouns[Math.floor(Math.random() * nouns.length)]}`;
-}
\ No newline at end of file
diff --git a/example-app/app/utils/worker.ts b/example-app/app/utils/worker.ts
deleted file mode 100644
index b5d05db..0000000
--- a/example-app/app/utils/worker.ts
+++ /dev/null
@@ -1,170 +0,0 @@
-// This worker just sits on another thread and waits for message to solve
-// challenges so that we dont block the render thread
-
-import {
- type WorkerRequest,
- type SolutionMessage,
- WorkerMessageType,
- WorkerResponseType,
- ChallengeStrategy,
-} from "~/types/pow";
-
-const worker_name = getWorkerName();
-let solver: SolverModule | null = null;
-
-let atomic_nonce: Int32Array | null = null;
-let atomic_solution: Int32Array | null = null;
-
-async function loadWasmSolver(module: WebAssembly.Module) {
- if (atomic_nonce === null || atomic_solution === null) {
- throw createError("Atomics not initialized");
- }
-
- console.debug(`[${worker_name}]: Loading WASM solver`);
-
- solver = await WebAssembly.instantiate(module, {
- env: {
- __get_solution: () => Atomics.load(atomic_solution!, 0),
- __set_solution: (value: number) => Atomics.store(atomic_solution!, 0, value),
- __cmpxchg_solution: (expected: number, replacement: number) => Atomics.compareExchange(atomic_solution!, 0, expected, replacement),
- __fetch_add_nonce: (value: number) => Atomics.add(atomic_nonce!, 0, value),
- __log: (ptr: number, len: number) => {
- const string_data = new Uint8Array(solver!.exports.memory.buffer, ptr, len);
- console.log(`[${worker_name}]: ${new TextDecoder().decode(string_data)}`);
- },
- }
- }) as unknown as SolverModule;
- console.debug(`[${worker_name}]: WASM solver loaded`);
-}
-
-onmessage = async (event: MessageEvent
) => {
- if (event.data.type === WorkerMessageType.Init) {
- console.log(`[${worker_name}]: Initializing...`);
-
- atomic_nonce = new Int32Array(event.data.sab, 0, 1);
- atomic_solution = new Int32Array(event.data.sab, 4, 1);
-
- try {
- await loadWasmSolver(event.data.module);
- } catch (error: any) {
- console.error(`[${worker_name}]: Failed to load WASM solver:`, error);
- postMessage({
- type: WorkerResponseType.Error,
- error: `Could not load WASM solver: ${error.message}`,
- } as SolutionMessage);
- return;
- }
-
- if (!solver) {
- console.error(`[${worker_name}]: Failed to load WASM solver`);
- postMessage({
- type: WorkerResponseType.Error,
- error: "Failed to load WASM solver",
- } as SolutionMessage);
- return;
- }
-
- postMessage({
- type: WorkerResponseType.Ok,
- } as SolutionMessage);
- return;
- }
-
- if (!solver) {
- postMessage({
- type: WorkerResponseType.Error,
- error: "WASM solver not loaded",
- } as SolutionMessage);
- return;
- }
-
- const { strategy } = event.data;
-
- const encoder = new TextEncoder();
-
- let solution: number;
- let target: string = event.data.target;
- let target_bytes, target_ptr;
- let memory;
- switch (strategy) {
- case ChallengeStrategy.LeadingZeroes:
- const { difficulty } = event.data;
- console.debug(`[${worker_name}]: recieved ${strategy} challenge: ${target}, difficulty: ${difficulty}`);
-
- target_bytes = encoder.encode(target);
-
- target_ptr = solver.exports.malloc(target_bytes.length);
- if (target_ptr === 0 || target_ptr === null) {
- console.error(`[${worker_name}]: Failed to allocate memory for challenge string`);
- postMessage({
- type: WorkerResponseType.Error,
- error: "Failed to allocate memory for challenge string",
- } as SolutionMessage);
- return;
- }
-
- memory = new Uint8Array(solver.exports.memory.buffer);
- memory.set(target_bytes, target_ptr);
-
- solution = solver.exports.solve_leaading_zeroes_challenge(
- target_ptr,
- target.length,
- difficulty,
- );
- console.debug(`[${worker_name}]: WASM solver found nonce: ${solution}`);
- break;
- case ChallengeStrategy.TargetNumber:
- const { salt } = event.data;
- console.debug(`[${worker_name}]: recieved ${strategy} challenge: ${target}, salt: ${salt}`);
-
- const salt_bytes = encoder.encode(salt);
- target_bytes = encoder.encode(target);
-
- const salt_ptr = solver.exports.malloc(salt_bytes.length);
- if (salt_ptr === 0 || salt_ptr === null) {
- console.error(`[${worker_name}]: Failed to allocate memory for salt string`);
- postMessage({
- type: WorkerResponseType.Error,
- error: "Failed to allocate memory for salt string",
- } as SolutionMessage);
- return;
- }
-
- target_ptr = solver.exports.malloc(target_bytes.length);
- if (target_ptr === 0 || target_ptr === null) {
- console.error(`[${worker_name}]: Failed to allocate memory for target string`);
- postMessage({
- type: WorkerResponseType.Error,
- error: "Failed to allocate memory for target string",
- } as SolutionMessage);
- return;
- }
-
- memory = new Uint8Array(solver.exports.memory.buffer);
- memory.set(salt_bytes, salt_ptr);
- memory.set(target_bytes, target_ptr);
-
- solution = solver.exports.solve_target_number_challenge(
- target_ptr,
- target_bytes.length,
- salt_ptr,
- salt_bytes.length,
- );
- console.debug(`[${worker_name}]: WASM solver found nonce: ${solution}`);
-
- break;
- }
-
- // we are just assuming that if its less than -1, its the min i32
- if (solution < 0) {
- return postMessage({
- type: WorkerResponseType.Error,
- error: "failed to solve challenge",
- } as SolutionMessage);
- }
-
- postMessage({
- type: WorkerResponseType.Solution,
- nonce: solution === -1 ? null : solution.toString()
- } as SolutionMessage);
-};
diff --git a/example-app/config.toml b/example-app/config.toml
index 175d496..4b8d716 100644
--- a/example-app/config.toml
+++ b/example-app/config.toml
@@ -1,7 +1,7 @@
strategy = "target_number"
[leading_zeroes]
-difficulty = 4
+difficulty = 2
[target_number]
-max_number = 10000
+max_number = 192
diff --git a/example-app/nuxt.config.ts b/example-app/nuxt.config.ts
index 9e2bc96..843a6d0 100644
--- a/example-app/nuxt.config.ts
+++ b/example-app/nuxt.config.ts
@@ -19,7 +19,7 @@ export default defineNuxtConfig({
}
},
},
- modules: ['@unocss/nuxt', ['nuxt-ssr-lit', { litElementPrefix: 'pow-' }]],
+ modules: ['@unocss/nuxt', ['nuxt-ssr-lit', { litElementPrefix: 'impost-' }]],
nitro: {
moduleSideEffects: ["@impost/widget"],
@@ -28,17 +28,9 @@ export default defineNuxtConfig({
},
},
- imports: {
- transform: {
- // only necessary in the monorepo since vite is going out to the
- // source of the widget and transforming it and clobbering it.
- exclude: [/impost/],
- }
- },
-
vue: {
compilerOptions: {
- isCustomElement: (tag) => tag.includes('pow-'),
+ isCustomElement: (tag) => tag.startsWith('impost-'),
},
},
diff --git a/example-app/package-lock.json b/example-app/package-lock.json
index 133031d..0d19301 100644
--- a/example-app/package-lock.json
+++ b/example-app/package-lock.json
@@ -8,10 +8,7 @@
"dependencies": {
"@impost/lib": "file:../packages/lib",
"@impost/widget": "file:../packages/widget",
- "@lit/reactive-element": "^2.1.1",
"js-toml": "^1.0.2",
- "lit-element": "^4.2.1",
- "lit-html": "^3.3.1",
"nuxt": "latest",
"nuxt-ssr-lit": "1.6.32",
"zod": "^4.1.12"
@@ -41,6 +38,9 @@
"name": "@impost/lib",
"version": "0.1.0",
"license": "BSL-1.0",
+ "dependencies": {
+ "uuidv7": "^1.0.2"
+ },
"devDependencies": {
"oxc-minify": "^0.97.0",
"tslib": "^2.6.2",
@@ -53,6 +53,9 @@
"name": "@impost/widget",
"version": "0.1.0",
"license": "BSL-1.0",
+ "dependencies": {
+ "comlink": "^4.4.2"
+ },
"devDependencies": {
"@types/node": "^20.11.24",
"lit": "^3.1.2",
@@ -110,6 +113,7 @@
"node_modules/@babel/core": {
"version": "7.28.5",
"license": "MIT",
+ "peer": true,
"dependencies": {
"@babel/code-frame": "^7.27.1",
"@babel/generator": "^7.28.5",
@@ -525,6 +529,293 @@
"version": "0.1.1",
"license": "MIT"
},
+ "node_modules/@emnapi/core": {
+ "version": "1.7.1",
+ "resolved": "https://registry.npmjs.org/@emnapi/core/-/core-1.7.1.tgz",
+ "integrity": "sha512-o1uhUASyo921r2XtHYOHy7gdkGLge8ghBEQHMWmyJFoXlpU58kIrhhN3w26lpQb6dspetweapMn2CSNwQ8I4wg==",
+ "license": "MIT",
+ "optional": true,
+ "dependencies": {
+ "@emnapi/wasi-threads": "1.1.0",
+ "tslib": "^2.4.0"
+ }
+ },
+ "node_modules/@emnapi/runtime": {
+ "version": "1.7.1",
+ "resolved": "https://registry.npmjs.org/@emnapi/runtime/-/runtime-1.7.1.tgz",
+ "integrity": "sha512-PVtJr5CmLwYAU9PZDMITZoR5iAOShYREoR45EyyLrbntV50mdePTgUn4AmOw90Ifcj+x2kRjdzr1HP3RrNiHGA==",
+ "license": "MIT",
+ "optional": true,
+ "dependencies": {
+ "tslib": "^2.4.0"
+ }
+ },
+ "node_modules/@emnapi/wasi-threads": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/@emnapi/wasi-threads/-/wasi-threads-1.1.0.tgz",
+ "integrity": "sha512-WI0DdZ8xFSbgMjR1sFsKABJ/C5OnRrjT06JXbZKexJGrDuPTzZdDYfFlsgcCXCyf+suG5QU2e/y1Wo2V/OapLQ==",
+ "license": "MIT",
+ "optional": true,
+ "dependencies": {
+ "tslib": "^2.4.0"
+ }
+ },
+ "node_modules/@esbuild/aix-ppc64": {
+ "version": "0.25.12",
+ "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.25.12.tgz",
+ "integrity": "sha512-Hhmwd6CInZ3dwpuGTF8fJG6yoWmsToE+vYgD4nytZVxcu1ulHpUQRAB1UJ8+N1Am3Mz4+xOByoQoSZf4D+CpkA==",
+ "cpu": [
+ "ppc64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "aix"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/android-arm": {
+ "version": "0.25.12",
+ "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.25.12.tgz",
+ "integrity": "sha512-VJ+sKvNA/GE7Ccacc9Cha7bpS8nyzVv0jdVgwNDaR4gDMC/2TTRc33Ip8qrNYUcpkOHUT5OZ0bUcNNVZQ9RLlg==",
+ "cpu": [
+ "arm"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "android"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/android-arm64": {
+ "version": "0.25.12",
+ "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.25.12.tgz",
+ "integrity": "sha512-6AAmLG7zwD1Z159jCKPvAxZd4y/VTO0VkprYy+3N2FtJ8+BQWFXU+OxARIwA46c5tdD9SsKGZ/1ocqBS/gAKHg==",
+ "cpu": [
+ "arm64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "android"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/android-x64": {
+ "version": "0.25.12",
+ "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.25.12.tgz",
+ "integrity": "sha512-5jbb+2hhDHx5phYR2By8GTWEzn6I9UqR11Kwf22iKbNpYrsmRB18aX/9ivc5cabcUiAT/wM+YIZ6SG9QO6a8kg==",
+ "cpu": [
+ "x64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "android"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/darwin-arm64": {
+ "version": "0.25.12",
+ "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.25.12.tgz",
+ "integrity": "sha512-N3zl+lxHCifgIlcMUP5016ESkeQjLj/959RxxNYIthIg+CQHInujFuXeWbWMgnTo4cp5XVHqFPmpyu9J65C1Yg==",
+ "cpu": [
+ "arm64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/darwin-x64": {
+ "version": "0.25.12",
+ "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.25.12.tgz",
+ "integrity": "sha512-HQ9ka4Kx21qHXwtlTUVbKJOAnmG1ipXhdWTmNXiPzPfWKpXqASVcWdnf2bnL73wgjNrFXAa3yYvBSd9pzfEIpA==",
+ "cpu": [
+ "x64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/freebsd-arm64": {
+ "version": "0.25.12",
+ "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.25.12.tgz",
+ "integrity": "sha512-gA0Bx759+7Jve03K1S0vkOu5Lg/85dou3EseOGUes8flVOGxbhDDh/iZaoek11Y8mtyKPGF3vP8XhnkDEAmzeg==",
+ "cpu": [
+ "arm64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "freebsd"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/freebsd-x64": {
+ "version": "0.25.12",
+ "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.25.12.tgz",
+ "integrity": "sha512-TGbO26Yw2xsHzxtbVFGEXBFH0FRAP7gtcPE7P5yP7wGy7cXK2oO7RyOhL5NLiqTlBh47XhmIUXuGciXEqYFfBQ==",
+ "cpu": [
+ "x64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "freebsd"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/linux-arm": {
+ "version": "0.25.12",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.25.12.tgz",
+ "integrity": "sha512-lPDGyC1JPDou8kGcywY0YILzWlhhnRjdof3UlcoqYmS9El818LLfJJc3PXXgZHrHCAKs/Z2SeZtDJr5MrkxtOw==",
+ "cpu": [
+ "arm"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/linux-arm64": {
+ "version": "0.25.12",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.25.12.tgz",
+ "integrity": "sha512-8bwX7a8FghIgrupcxb4aUmYDLp8pX06rGh5HqDT7bB+8Rdells6mHvrFHHW2JAOPZUbnjUpKTLg6ECyzvas2AQ==",
+ "cpu": [
+ "arm64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/linux-ia32": {
+ "version": "0.25.12",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.25.12.tgz",
+ "integrity": "sha512-0y9KrdVnbMM2/vG8KfU0byhUN+EFCny9+8g202gYqSSVMonbsCfLjUO+rCci7pM0WBEtz+oK/PIwHkzxkyharA==",
+ "cpu": [
+ "ia32"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/linux-loong64": {
+ "version": "0.25.12",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.25.12.tgz",
+ "integrity": "sha512-h///Lr5a9rib/v1GGqXVGzjL4TMvVTv+s1DPoxQdz7l/AYv6LDSxdIwzxkrPW438oUXiDtwM10o9PmwS/6Z0Ng==",
+ "cpu": [
+ "loong64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/linux-mips64el": {
+ "version": "0.25.12",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.25.12.tgz",
+ "integrity": "sha512-iyRrM1Pzy9GFMDLsXn1iHUm18nhKnNMWscjmp4+hpafcZjrr2WbT//d20xaGljXDBYHqRcl8HnxbX6uaA/eGVw==",
+ "cpu": [
+ "mips64el"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/linux-ppc64": {
+ "version": "0.25.12",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.25.12.tgz",
+ "integrity": "sha512-9meM/lRXxMi5PSUqEXRCtVjEZBGwB7P/D4yT8UG/mwIdze2aV4Vo6U5gD3+RsoHXKkHCfSxZKzmDssVlRj1QQA==",
+ "cpu": [
+ "ppc64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/linux-riscv64": {
+ "version": "0.25.12",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.25.12.tgz",
+ "integrity": "sha512-Zr7KR4hgKUpWAwb1f3o5ygT04MzqVrGEGXGLnj15YQDJErYu/BGg+wmFlIDOdJp0PmB0lLvxFIOXZgFRrdjR0w==",
+ "cpu": [
+ "riscv64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/linux-s390x": {
+ "version": "0.25.12",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.25.12.tgz",
+ "integrity": "sha512-MsKncOcgTNvdtiISc/jZs/Zf8d0cl/t3gYWX8J9ubBnVOwlk65UIEEvgBORTiljloIWnBzLs4qhzPkJcitIzIg==",
+ "cpu": [
+ "s390x"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
"node_modules/@esbuild/linux-x64": {
"version": "0.25.12",
"cpu": [
@@ -539,6 +830,150 @@
"node": ">=18"
}
},
+ "node_modules/@esbuild/netbsd-arm64": {
+ "version": "0.25.12",
+ "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.25.12.tgz",
+ "integrity": "sha512-xXwcTq4GhRM7J9A8Gv5boanHhRa/Q9KLVmcyXHCTaM4wKfIpWkdXiMog/KsnxzJ0A1+nD+zoecuzqPmCRyBGjg==",
+ "cpu": [
+ "arm64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "netbsd"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/netbsd-x64": {
+ "version": "0.25.12",
+ "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.25.12.tgz",
+ "integrity": "sha512-Ld5pTlzPy3YwGec4OuHh1aCVCRvOXdH8DgRjfDy/oumVovmuSzWfnSJg+VtakB9Cm0gxNO9BzWkj6mtO1FMXkQ==",
+ "cpu": [
+ "x64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "netbsd"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/openbsd-arm64": {
+ "version": "0.25.12",
+ "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.25.12.tgz",
+ "integrity": "sha512-fF96T6KsBo/pkQI950FARU9apGNTSlZGsv1jZBAlcLL1MLjLNIWPBkj5NlSz8aAzYKg+eNqknrUJ24QBybeR5A==",
+ "cpu": [
+ "arm64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "openbsd"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/openbsd-x64": {
+ "version": "0.25.12",
+ "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.25.12.tgz",
+ "integrity": "sha512-MZyXUkZHjQxUvzK7rN8DJ3SRmrVrke8ZyRusHlP+kuwqTcfWLyqMOE3sScPPyeIXN/mDJIfGXvcMqCgYKekoQw==",
+ "cpu": [
+ "x64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "openbsd"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/openharmony-arm64": {
+ "version": "0.25.12",
+ "resolved": "https://registry.npmjs.org/@esbuild/openharmony-arm64/-/openharmony-arm64-0.25.12.tgz",
+ "integrity": "sha512-rm0YWsqUSRrjncSXGA7Zv78Nbnw4XL6/dzr20cyrQf7ZmRcsovpcRBdhD43Nuk3y7XIoW2OxMVvwuRvk9XdASg==",
+ "cpu": [
+ "arm64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "openharmony"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/sunos-x64": {
+ "version": "0.25.12",
+ "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.25.12.tgz",
+ "integrity": "sha512-3wGSCDyuTHQUzt0nV7bocDy72r2lI33QL3gkDNGkod22EsYl04sMf0qLb8luNKTOmgF/eDEDP5BFNwoBKH441w==",
+ "cpu": [
+ "x64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "sunos"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/win32-arm64": {
+ "version": "0.25.12",
+ "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.25.12.tgz",
+ "integrity": "sha512-rMmLrur64A7+DKlnSuwqUdRKyd3UE7oPJZmnljqEptesKM8wx9J8gx5u0+9Pq0fQQW8vqeKebwNXdfOyP+8Bsg==",
+ "cpu": [
+ "arm64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/win32-ia32": {
+ "version": "0.25.12",
+ "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.25.12.tgz",
+ "integrity": "sha512-HkqnmmBoCbCwxUKKNPBixiWDGCpQGVsrQfJoVGYLPT41XWF8lHuE5N6WhVia2n4o5QK5M4tYr21827fNhi4byQ==",
+ "cpu": [
+ "ia32"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/win32-x64": {
+ "version": "0.25.12",
+ "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.25.12.tgz",
+ "integrity": "sha512-alJC0uCZpTFrSL0CCDjcgleBXPnCrEAhTBILpeAp7M/OFgoqtAetfBzX0xM00MUsVVPpVjlPuMbREqnZCXaTnA==",
+ "cpu": [
+ "x64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
"node_modules/@iconify/types": {
"version": "2.0.0",
"dev": true,
@@ -738,6 +1173,18 @@
"node": ">=8"
}
},
+ "node_modules/@napi-rs/wasm-runtime": {
+ "version": "1.0.7",
+ "resolved": "https://registry.npmjs.org/@napi-rs/wasm-runtime/-/wasm-runtime-1.0.7.tgz",
+ "integrity": "sha512-SeDnOO0Tk7Okiq6DbXmmBODgOAb9dp9gjlphokTUxmt8U3liIP1ZsozBahH69j/RJv+Rfs6IwUKHTgQYJ/HBAw==",
+ "license": "MIT",
+ "optional": true,
+ "dependencies": {
+ "@emnapi/core": "^1.5.0",
+ "@emnapi/runtime": "^1.5.0",
+ "@tybys/wasm-util": "^0.10.1"
+ }
+ },
"node_modules/@nodelib/fs.scandir": {
"version": "2.1.5",
"license": "MIT",
@@ -1082,6 +1529,166 @@
}
}
},
+ "node_modules/@oxc-minify/binding-android-arm64": {
+ "version": "0.96.0",
+ "resolved": "https://registry.npmjs.org/@oxc-minify/binding-android-arm64/-/binding-android-arm64-0.96.0.tgz",
+ "integrity": "sha512-lzeIEMu/v6Y+La5JSesq4hvyKtKBq84cgQpKYTYM/yGuNk2tfd5Ha31hnC+mTh48lp/5vZH+WBfjVUjjINCfug==",
+ "cpu": [
+ "arm64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "android"
+ ],
+ "engines": {
+ "node": "^20.19.0 || >=22.12.0"
+ }
+ },
+ "node_modules/@oxc-minify/binding-darwin-arm64": {
+ "version": "0.96.0",
+ "resolved": "https://registry.npmjs.org/@oxc-minify/binding-darwin-arm64/-/binding-darwin-arm64-0.96.0.tgz",
+ "integrity": "sha512-i0LkJAUXb4BeBFrJQbMKQPoxf8+cFEffDyLSb7NEzzKuPcH8qrVsnEItoOzeAdYam8Sr6qCHVwmBNEQzl7PWpw==",
+ "cpu": [
+ "arm64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
+ "engines": {
+ "node": "^20.19.0 || >=22.12.0"
+ }
+ },
+ "node_modules/@oxc-minify/binding-darwin-x64": {
+ "version": "0.96.0",
+ "resolved": "https://registry.npmjs.org/@oxc-minify/binding-darwin-x64/-/binding-darwin-x64-0.96.0.tgz",
+ "integrity": "sha512-C5vI0WPR+KPIFAD5LMOJk2J8iiT+Nv65vDXmemzXEXouzfEOLYNqnW+u6NSsccpuZHHWAiLyPFkYvKFduveAUQ==",
+ "cpu": [
+ "x64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
+ "engines": {
+ "node": "^20.19.0 || >=22.12.0"
+ }
+ },
+ "node_modules/@oxc-minify/binding-freebsd-x64": {
+ "version": "0.96.0",
+ "resolved": "https://registry.npmjs.org/@oxc-minify/binding-freebsd-x64/-/binding-freebsd-x64-0.96.0.tgz",
+ "integrity": "sha512-3//5DNx+xUjVBMLLk2sl6hfe4fwfENJtjVQUBXjxzwPuv8xgZUqASG4cRG3WqG5Qe8dV6SbCI4EgKQFjO4KCZA==",
+ "cpu": [
+ "x64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "freebsd"
+ ],
+ "engines": {
+ "node": "^20.19.0 || >=22.12.0"
+ }
+ },
+ "node_modules/@oxc-minify/binding-linux-arm-gnueabihf": {
+ "version": "0.96.0",
+ "resolved": "https://registry.npmjs.org/@oxc-minify/binding-linux-arm-gnueabihf/-/binding-linux-arm-gnueabihf-0.96.0.tgz",
+ "integrity": "sha512-WXChFKV7VdDk1NePDK1J31cpSvxACAVztJ7f7lJVYBTkH+iz5D0lCqPcE7a9eb7nC3xvz4yk7DM6dA9wlUQkQg==",
+ "cpu": [
+ "arm"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": "^20.19.0 || >=22.12.0"
+ }
+ },
+ "node_modules/@oxc-minify/binding-linux-arm-musleabihf": {
+ "version": "0.96.0",
+ "resolved": "https://registry.npmjs.org/@oxc-minify/binding-linux-arm-musleabihf/-/binding-linux-arm-musleabihf-0.96.0.tgz",
+ "integrity": "sha512-7B18glYMX4Z/YoqgE3VRLs/2YhVLxlxNKSgrtsRpuR8xv58xca+hEhiFwZN1Rn+NSMZ29Z33LWD7iYWnqYFvRA==",
+ "cpu": [
+ "arm"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": "^20.19.0 || >=22.12.0"
+ }
+ },
+ "node_modules/@oxc-minify/binding-linux-arm64-gnu": {
+ "version": "0.96.0",
+ "resolved": "https://registry.npmjs.org/@oxc-minify/binding-linux-arm64-gnu/-/binding-linux-arm64-gnu-0.96.0.tgz",
+ "integrity": "sha512-Yl+KcTldsEJNcaYxxonwAXZ2q3gxIzn3kXYQWgKWdaGIpNhOCWqF+KE5WLsldoh5Ro5SHtomvb8GM6cXrIBMog==",
+ "cpu": [
+ "arm64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": "^20.19.0 || >=22.12.0"
+ }
+ },
+ "node_modules/@oxc-minify/binding-linux-arm64-musl": {
+ "version": "0.96.0",
+ "resolved": "https://registry.npmjs.org/@oxc-minify/binding-linux-arm64-musl/-/binding-linux-arm64-musl-0.96.0.tgz",
+ "integrity": "sha512-rNqoFWOWaxwMmUY5fspd/h5HfvgUlA3sv9CUdA2MpnHFiyoJNovR7WU8tGh+Yn0qOAs0SNH0a05gIthHig14IA==",
+ "cpu": [
+ "arm64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": "^20.19.0 || >=22.12.0"
+ }
+ },
+ "node_modules/@oxc-minify/binding-linux-riscv64-gnu": {
+ "version": "0.96.0",
+ "resolved": "https://registry.npmjs.org/@oxc-minify/binding-linux-riscv64-gnu/-/binding-linux-riscv64-gnu-0.96.0.tgz",
+ "integrity": "sha512-3paajIuzGnukHwSI3YBjYVqbd72pZd8NJxaayaNFR0AByIm8rmIT5RqFXbq8j2uhtpmNdZRXiu0em1zOmIScWA==",
+ "cpu": [
+ "riscv64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": "^20.19.0 || >=22.12.0"
+ }
+ },
+ "node_modules/@oxc-minify/binding-linux-s390x-gnu": {
+ "version": "0.96.0",
+ "resolved": "https://registry.npmjs.org/@oxc-minify/binding-linux-s390x-gnu/-/binding-linux-s390x-gnu-0.96.0.tgz",
+ "integrity": "sha512-9ESrpkB2XG0lQ89JlsxlZa86iQCOs+jkDZLl6O+u5wb7ynUy21bpJJ1joauCOSYIOUlSy3+LbtJLiqi7oSQt5Q==",
+ "cpu": [
+ "s390x"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": "^20.19.0 || >=22.12.0"
+ }
+ },
"node_modules/@oxc-minify/binding-linux-x64-gnu": {
"version": "0.96.0",
"cpu": [
@@ -1110,6 +1717,214 @@
"node": "^20.19.0 || >=22.12.0"
}
},
+ "node_modules/@oxc-minify/binding-wasm32-wasi": {
+ "version": "0.96.0",
+ "resolved": "https://registry.npmjs.org/@oxc-minify/binding-wasm32-wasi/-/binding-wasm32-wasi-0.96.0.tgz",
+ "integrity": "sha512-bjGDjkGzo3GWU9Vg2qiFUrfoo5QxojPNV/2RHTlbIB5FWkkV4ExVjsfyqihFiAuj0NXIZqd2SAiEq9htVd3RFw==",
+ "cpu": [
+ "wasm32"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "dependencies": {
+ "@napi-rs/wasm-runtime": "^1.0.7"
+ },
+ "engines": {
+ "node": ">=14.0.0"
+ }
+ },
+ "node_modules/@oxc-minify/binding-win32-arm64-msvc": {
+ "version": "0.96.0",
+ "resolved": "https://registry.npmjs.org/@oxc-minify/binding-win32-arm64-msvc/-/binding-win32-arm64-msvc-0.96.0.tgz",
+ "integrity": "sha512-4L4DlHUT47qMWQuTyUghpncR3NZHWtxvd0G1KgSjVgXf+cXzFdWQCWZZtCU0yrmOoVCNUf4S04IFCJyAe+Ie7A==",
+ "cpu": [
+ "arm64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "engines": {
+ "node": "^20.19.0 || >=22.12.0"
+ }
+ },
+ "node_modules/@oxc-minify/binding-win32-x64-msvc": {
+ "version": "0.96.0",
+ "resolved": "https://registry.npmjs.org/@oxc-minify/binding-win32-x64-msvc/-/binding-win32-x64-msvc-0.96.0.tgz",
+ "integrity": "sha512-T2ijfqZLpV2bgGGocXV4SXTuMoouqN0asYTIm+7jVOLvT5XgDogf3ZvCmiEnSWmxl21+r5wHcs8voU2iUROXAg==",
+ "cpu": [
+ "x64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "engines": {
+ "node": "^20.19.0 || >=22.12.0"
+ }
+ },
+ "node_modules/@oxc-parser/binding-android-arm64": {
+ "version": "0.96.0",
+ "resolved": "https://registry.npmjs.org/@oxc-parser/binding-android-arm64/-/binding-android-arm64-0.96.0.tgz",
+ "integrity": "sha512-CofbPOiW1PG+hi8bgElJPK0ioHfw8nt4Vw9d+Q9JuMhygS6LbQyu1W6tIFZ1OPFofeFRdWus3vD29FBx+tvFOA==",
+ "cpu": [
+ "arm64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "android"
+ ],
+ "engines": {
+ "node": "^20.19.0 || >=22.12.0"
+ }
+ },
+ "node_modules/@oxc-parser/binding-darwin-arm64": {
+ "version": "0.96.0",
+ "resolved": "https://registry.npmjs.org/@oxc-parser/binding-darwin-arm64/-/binding-darwin-arm64-0.96.0.tgz",
+ "integrity": "sha512-+HZ2L1a/1BsUXYik8XqQwT2Tl5Z3jRQ/RRQiPV9UsB2skKyd91NLDlQlMpdhjLGs9Qe7Y42unFjRg2iHjIiwnw==",
+ "cpu": [
+ "arm64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
+ "engines": {
+ "node": "^20.19.0 || >=22.12.0"
+ }
+ },
+ "node_modules/@oxc-parser/binding-darwin-x64": {
+ "version": "0.96.0",
+ "resolved": "https://registry.npmjs.org/@oxc-parser/binding-darwin-x64/-/binding-darwin-x64-0.96.0.tgz",
+ "integrity": "sha512-GC8wH1W0XaCLyTeGsmyaMdnItiYQkqfTcn9Ygc55AWI+m11lCjQeoKDIsDCm/QwrKLCN07u3WWWsuPs5ubfXpA==",
+ "cpu": [
+ "x64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
+ "engines": {
+ "node": "^20.19.0 || >=22.12.0"
+ }
+ },
+ "node_modules/@oxc-parser/binding-freebsd-x64": {
+ "version": "0.96.0",
+ "resolved": "https://registry.npmjs.org/@oxc-parser/binding-freebsd-x64/-/binding-freebsd-x64-0.96.0.tgz",
+ "integrity": "sha512-8SeXi2FmlN15uPY5oM03cua5RXBDYmY34Uewongv6RUiAaU/kWxLvzuijpyNC+yQ1r4fC2LbWJhAsKpX5qkA6g==",
+ "cpu": [
+ "x64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "freebsd"
+ ],
+ "engines": {
+ "node": "^20.19.0 || >=22.12.0"
+ }
+ },
+ "node_modules/@oxc-parser/binding-linux-arm-gnueabihf": {
+ "version": "0.96.0",
+ "resolved": "https://registry.npmjs.org/@oxc-parser/binding-linux-arm-gnueabihf/-/binding-linux-arm-gnueabihf-0.96.0.tgz",
+ "integrity": "sha512-UEs+Zf6T2/FwQlLgv7gfZsKmY19sl3hK57r2BQVc2eCmCmF/deeqDcWyFjzkNLgdDDucY60PoNhNGClDm605uQ==",
+ "cpu": [
+ "arm"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": "^20.19.0 || >=22.12.0"
+ }
+ },
+ "node_modules/@oxc-parser/binding-linux-arm-musleabihf": {
+ "version": "0.96.0",
+ "resolved": "https://registry.npmjs.org/@oxc-parser/binding-linux-arm-musleabihf/-/binding-linux-arm-musleabihf-0.96.0.tgz",
+ "integrity": "sha512-1kuWvjR2+ORJMoyxt9LSbLcDhXZnL25XOuv9VmH6NmSPvLgewzuubSlm++W03x+U7SzWFilBsdwIHtD/0mjERw==",
+ "cpu": [
+ "arm"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": "^20.19.0 || >=22.12.0"
+ }
+ },
+ "node_modules/@oxc-parser/binding-linux-arm64-gnu": {
+ "version": "0.96.0",
+ "resolved": "https://registry.npmjs.org/@oxc-parser/binding-linux-arm64-gnu/-/binding-linux-arm64-gnu-0.96.0.tgz",
+ "integrity": "sha512-PHH4ETR1t0fymxuhpQNj3Z9t/78/zZa2Lj3Z3I0ZOd+/Ex+gtdhGoB5xYyy7lcYGAPMfZ+Gmr+dTCr1GYNZ3BA==",
+ "cpu": [
+ "arm64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": "^20.19.0 || >=22.12.0"
+ }
+ },
+ "node_modules/@oxc-parser/binding-linux-arm64-musl": {
+ "version": "0.96.0",
+ "resolved": "https://registry.npmjs.org/@oxc-parser/binding-linux-arm64-musl/-/binding-linux-arm64-musl-0.96.0.tgz",
+ "integrity": "sha512-fjDPbZjkqaDSTBe0FM8nZ9zBw4B/NF/I0gH7CfvNDwIj9smISaNFypYeomkvubORpnbX9ORhvhYwg3TxQ60OGA==",
+ "cpu": [
+ "arm64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": "^20.19.0 || >=22.12.0"
+ }
+ },
+ "node_modules/@oxc-parser/binding-linux-riscv64-gnu": {
+ "version": "0.96.0",
+ "resolved": "https://registry.npmjs.org/@oxc-parser/binding-linux-riscv64-gnu/-/binding-linux-riscv64-gnu-0.96.0.tgz",
+ "integrity": "sha512-59KAHd/6/LmjkdSAuJn0piKmwSavMasWNUKuYLX/UnqI5KkGIp14+LBwwaBG6KzOtIq1NrRCnmlL4XSEaNkzTg==",
+ "cpu": [
+ "riscv64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": "^20.19.0 || >=22.12.0"
+ }
+ },
+ "node_modules/@oxc-parser/binding-linux-s390x-gnu": {
+ "version": "0.96.0",
+ "resolved": "https://registry.npmjs.org/@oxc-parser/binding-linux-s390x-gnu/-/binding-linux-s390x-gnu-0.96.0.tgz",
+ "integrity": "sha512-VtupojtgahY8XmLwpVpM3C1WQEgMD1JxpB8lzUtdSLwosWaaz1EAl+VXWNuxTTZusNuLBtmR+F0qql22ISi/9g==",
+ "cpu": [
+ "s390x"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": "^20.19.0 || >=22.12.0"
+ }
+ },
"node_modules/@oxc-parser/binding-linux-x64-gnu": {
"version": "0.96.0",
"cpu": [
@@ -1138,6 +1953,54 @@
"node": "^20.19.0 || >=22.12.0"
}
},
+ "node_modules/@oxc-parser/binding-wasm32-wasi": {
+ "version": "0.96.0",
+ "resolved": "https://registry.npmjs.org/@oxc-parser/binding-wasm32-wasi/-/binding-wasm32-wasi-0.96.0.tgz",
+ "integrity": "sha512-TJ/sNPbVD4u6kUwm7sDKa5iRDEB8vd7ZIMjYqFrrAo9US1RGYOSvt6Ie9sDRekUL9fZhNsykvSrpmIj6dg/C2w==",
+ "cpu": [
+ "wasm32"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "dependencies": {
+ "@napi-rs/wasm-runtime": "^1.0.7"
+ },
+ "engines": {
+ "node": ">=14.0.0"
+ }
+ },
+ "node_modules/@oxc-parser/binding-win32-arm64-msvc": {
+ "version": "0.96.0",
+ "resolved": "https://registry.npmjs.org/@oxc-parser/binding-win32-arm64-msvc/-/binding-win32-arm64-msvc-0.96.0.tgz",
+ "integrity": "sha512-zCOhRB7MYVIHLj+2QYoTuLyaipiD8JG/ggUjfsMUaupRPpvwQNhsxINLIcTcb0AS+OsT7/OREhydjO74STqQzQ==",
+ "cpu": [
+ "arm64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "engines": {
+ "node": "^20.19.0 || >=22.12.0"
+ }
+ },
+ "node_modules/@oxc-parser/binding-win32-x64-msvc": {
+ "version": "0.96.0",
+ "resolved": "https://registry.npmjs.org/@oxc-parser/binding-win32-x64-msvc/-/binding-win32-x64-msvc-0.96.0.tgz",
+ "integrity": "sha512-J6zfx9TE0oS+TrqBUjMVMOi/d/j3HMj69Pip263pETOEPm788N0HXKPsc2X2jUfSTHzD9vmdjq0QFymbf2LhWg==",
+ "cpu": [
+ "x64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "engines": {
+ "node": "^20.19.0 || >=22.12.0"
+ }
+ },
"node_modules/@oxc-project/types": {
"version": "0.96.0",
"license": "MIT",
@@ -1145,6 +2008,166 @@
"url": "https://github.com/sponsors/Boshen"
}
},
+ "node_modules/@oxc-transform/binding-android-arm64": {
+ "version": "0.96.0",
+ "resolved": "https://registry.npmjs.org/@oxc-transform/binding-android-arm64/-/binding-android-arm64-0.96.0.tgz",
+ "integrity": "sha512-wOm+ZsqFvyZ7B9RefUMsj0zcXw77Z2pXA51nbSQyPXqr+g0/pDGxriZWP8Sdpz/e4AEaKPA9DvrwyOZxu7GRDQ==",
+ "cpu": [
+ "arm64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "android"
+ ],
+ "engines": {
+ "node": "^20.19.0 || >=22.12.0"
+ }
+ },
+ "node_modules/@oxc-transform/binding-darwin-arm64": {
+ "version": "0.96.0",
+ "resolved": "https://registry.npmjs.org/@oxc-transform/binding-darwin-arm64/-/binding-darwin-arm64-0.96.0.tgz",
+ "integrity": "sha512-td1sbcvzsyuoNRiNdIRodPXRtFFwxzPpC/6/yIUtRRhKn30XQcizxupIvQQVpJWWchxkphbBDh6UN+u+2CJ8Zw==",
+ "cpu": [
+ "arm64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
+ "engines": {
+ "node": "^20.19.0 || >=22.12.0"
+ }
+ },
+ "node_modules/@oxc-transform/binding-darwin-x64": {
+ "version": "0.96.0",
+ "resolved": "https://registry.npmjs.org/@oxc-transform/binding-darwin-x64/-/binding-darwin-x64-0.96.0.tgz",
+ "integrity": "sha512-xgqxnqhPYH2NYkgbqtnCJfhbXvxIf/pnhF/ig5UBK8PYpCEWIP/cfLpQRQ9DcQnRfuxi7RMIF6LdmB1AiS6Fkg==",
+ "cpu": [
+ "x64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
+ "engines": {
+ "node": "^20.19.0 || >=22.12.0"
+ }
+ },
+ "node_modules/@oxc-transform/binding-freebsd-x64": {
+ "version": "0.96.0",
+ "resolved": "https://registry.npmjs.org/@oxc-transform/binding-freebsd-x64/-/binding-freebsd-x64-0.96.0.tgz",
+ "integrity": "sha512-1i67OXdl/rvSkcTXqDlh6qGRXYseEmf0rl/R+/i88scZ/o3A+FzlX56sThuaPzSSv9eVgesnoYUjIBJELFc1oA==",
+ "cpu": [
+ "x64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "freebsd"
+ ],
+ "engines": {
+ "node": "^20.19.0 || >=22.12.0"
+ }
+ },
+ "node_modules/@oxc-transform/binding-linux-arm-gnueabihf": {
+ "version": "0.96.0",
+ "resolved": "https://registry.npmjs.org/@oxc-transform/binding-linux-arm-gnueabihf/-/binding-linux-arm-gnueabihf-0.96.0.tgz",
+ "integrity": "sha512-9MJBs0SWODsqyzO3eAnacXgJ/sZu1xqinjEwBzkcZ3tQI8nKhMADOzu2NzbVWDWujeoC8DESXaO08tujvUru+Q==",
+ "cpu": [
+ "arm"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": "^20.19.0 || >=22.12.0"
+ }
+ },
+ "node_modules/@oxc-transform/binding-linux-arm-musleabihf": {
+ "version": "0.96.0",
+ "resolved": "https://registry.npmjs.org/@oxc-transform/binding-linux-arm-musleabihf/-/binding-linux-arm-musleabihf-0.96.0.tgz",
+ "integrity": "sha512-BQom57I2ScccixljNYh2Wy+5oVZtF1LXiiUPxSLtDHbsanpEvV/+kzCagQpTjk1BVzSQzOxfEUWjvL7mY53pRQ==",
+ "cpu": [
+ "arm"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": "^20.19.0 || >=22.12.0"
+ }
+ },
+ "node_modules/@oxc-transform/binding-linux-arm64-gnu": {
+ "version": "0.96.0",
+ "resolved": "https://registry.npmjs.org/@oxc-transform/binding-linux-arm64-gnu/-/binding-linux-arm64-gnu-0.96.0.tgz",
+ "integrity": "sha512-kaqvUzNu8LL4aBSXqcqGVLFG13GmJEplRI2+yqzkgAItxoP/LfFMdEIErlTWLGyBwd0OLiNMHrOvkcCQRWadVg==",
+ "cpu": [
+ "arm64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": "^20.19.0 || >=22.12.0"
+ }
+ },
+ "node_modules/@oxc-transform/binding-linux-arm64-musl": {
+ "version": "0.96.0",
+ "resolved": "https://registry.npmjs.org/@oxc-transform/binding-linux-arm64-musl/-/binding-linux-arm64-musl-0.96.0.tgz",
+ "integrity": "sha512-EiG/L3wEkPgTm4p906ufptyblBgtiQWTubGg/JEw82f8uLRroayr5zhbUqx40EgH037a3SfJthIyLZi7XPRFJw==",
+ "cpu": [
+ "arm64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": "^20.19.0 || >=22.12.0"
+ }
+ },
+ "node_modules/@oxc-transform/binding-linux-riscv64-gnu": {
+ "version": "0.96.0",
+ "resolved": "https://registry.npmjs.org/@oxc-transform/binding-linux-riscv64-gnu/-/binding-linux-riscv64-gnu-0.96.0.tgz",
+ "integrity": "sha512-r01CY6OxKGtVeYnvH4mGmtkQMlLkXdPWWNXwo5o7fE2s/fgZPMpqh8bAuXEhuMXipZRJrjxTk1+ZQ4KCHpMn3Q==",
+ "cpu": [
+ "riscv64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": "^20.19.0 || >=22.12.0"
+ }
+ },
+ "node_modules/@oxc-transform/binding-linux-s390x-gnu": {
+ "version": "0.96.0",
+ "resolved": "https://registry.npmjs.org/@oxc-transform/binding-linux-s390x-gnu/-/binding-linux-s390x-gnu-0.96.0.tgz",
+ "integrity": "sha512-4djg2vYLGbVeS8YiA2K4RPPpZE4fxTGCX5g/bOMbCYyirDbmBAIop4eOAj8vOA9i1CcWbDtmp+PVJ1dSw7f3IQ==",
+ "cpu": [
+ "s390x"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": "^20.19.0 || >=22.12.0"
+ }
+ },
"node_modules/@oxc-transform/binding-linux-x64-gnu": {
"version": "0.96.0",
"cpu": [
@@ -1173,6 +2196,54 @@
"node": "^20.19.0 || >=22.12.0"
}
},
+ "node_modules/@oxc-transform/binding-wasm32-wasi": {
+ "version": "0.96.0",
+ "resolved": "https://registry.npmjs.org/@oxc-transform/binding-wasm32-wasi/-/binding-wasm32-wasi-0.96.0.tgz",
+ "integrity": "sha512-A91ARLiuZHGN4hBds9s7bW3czUuLuHLsV+cz44iF9j8e1zX9m2hNGXf/acQRbg/zcFUXmjz5nmk8EkZyob876w==",
+ "cpu": [
+ "wasm32"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "dependencies": {
+ "@napi-rs/wasm-runtime": "^1.0.7"
+ },
+ "engines": {
+ "node": ">=14.0.0"
+ }
+ },
+ "node_modules/@oxc-transform/binding-win32-arm64-msvc": {
+ "version": "0.96.0",
+ "resolved": "https://registry.npmjs.org/@oxc-transform/binding-win32-arm64-msvc/-/binding-win32-arm64-msvc-0.96.0.tgz",
+ "integrity": "sha512-IedJf40djKgDObomhYjdRAlmSYUEdfqX3A3M9KfUltl9AghTBBLkTzUMA7O09oo71vYf5TEhbFM7+Vn5vqw7AQ==",
+ "cpu": [
+ "arm64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "engines": {
+ "node": "^20.19.0 || >=22.12.0"
+ }
+ },
+ "node_modules/@oxc-transform/binding-win32-x64-msvc": {
+ "version": "0.96.0",
+ "resolved": "https://registry.npmjs.org/@oxc-transform/binding-win32-x64-msvc/-/binding-win32-x64-msvc-0.96.0.tgz",
+ "integrity": "sha512-0fI0P0W7bSO/GCP/N5dkmtB9vBqCA4ggo1WmXTnxNJVmFFOtcA1vYm1I9jl8fxo+sucW2WnlpnI4fjKdo3JKxA==",
+ "cpu": [
+ "x64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "engines": {
+ "node": "^20.19.0 || >=22.12.0"
+ }
+ },
"node_modules/@parcel/watcher": {
"version": "2.5.1",
"hasInstallScript": true,
@@ -1603,6 +2674,7 @@
"node_modules/@rollup/plugin-commonjs/node_modules/picomatch": {
"version": "4.0.3",
"license": "MIT",
+ "peer": true,
"engines": {
"node": ">=12"
},
@@ -1739,6 +2811,201 @@
"url": "https://github.com/sponsors/jonschlinkert"
}
},
+ "node_modules/@rollup/rollup-android-arm-eabi": {
+ "version": "4.53.2",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.53.2.tgz",
+ "integrity": "sha512-yDPzwsgiFO26RJA4nZo8I+xqzh7sJTZIWQOxn+/XOdPE31lAvLIYCKqjV+lNH/vxE2L2iH3plKxDCRK6i+CwhA==",
+ "cpu": [
+ "arm"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "android"
+ ]
+ },
+ "node_modules/@rollup/rollup-android-arm64": {
+ "version": "4.53.2",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.53.2.tgz",
+ "integrity": "sha512-k8FontTxIE7b0/OGKeSN5B6j25EuppBcWM33Z19JoVT7UTXFSo3D9CdU39wGTeb29NO3XxpMNauh09B+Ibw+9g==",
+ "cpu": [
+ "arm64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "android"
+ ]
+ },
+ "node_modules/@rollup/rollup-darwin-arm64": {
+ "version": "4.53.2",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.53.2.tgz",
+ "integrity": "sha512-A6s4gJpomNBtJ2yioj8bflM2oogDwzUiMl2yNJ2v9E7++sHrSrsQ29fOfn5DM/iCzpWcebNYEdXpaK4tr2RhfQ==",
+ "cpu": [
+ "arm64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "darwin"
+ ]
+ },
+ "node_modules/@rollup/rollup-darwin-x64": {
+ "version": "4.53.2",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.53.2.tgz",
+ "integrity": "sha512-e6XqVmXlHrBlG56obu9gDRPW3O3hLxpwHpLsBJvuI8qqnsrtSZ9ERoWUXtPOkY8c78WghyPHZdmPhHLWNdAGEw==",
+ "cpu": [
+ "x64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "darwin"
+ ]
+ },
+ "node_modules/@rollup/rollup-freebsd-arm64": {
+ "version": "4.53.2",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.53.2.tgz",
+ "integrity": "sha512-v0E9lJW8VsrwPux5Qe5CwmH/CF/2mQs6xU1MF3nmUxmZUCHazCjLgYvToOk+YuuUqLQBio1qkkREhxhc656ViA==",
+ "cpu": [
+ "arm64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "freebsd"
+ ]
+ },
+ "node_modules/@rollup/rollup-freebsd-x64": {
+ "version": "4.53.2",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.53.2.tgz",
+ "integrity": "sha512-ClAmAPx3ZCHtp6ysl4XEhWU69GUB1D+s7G9YjHGhIGCSrsg00nEGRRZHmINYxkdoJehde8VIsDC5t9C0gb6yqA==",
+ "cpu": [
+ "x64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "freebsd"
+ ]
+ },
+ "node_modules/@rollup/rollup-linux-arm-gnueabihf": {
+ "version": "4.53.2",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.53.2.tgz",
+ "integrity": "sha512-EPlb95nUsz6Dd9Qy13fI5kUPXNSljaG9FiJ4YUGU1O/Q77i5DYFW5KR8g1OzTcdZUqQQ1KdDqsTohdFVwCwjqg==",
+ "cpu": [
+ "arm"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@rollup/rollup-linux-arm-musleabihf": {
+ "version": "4.53.2",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.53.2.tgz",
+ "integrity": "sha512-BOmnVW+khAUX+YZvNfa0tGTEMVVEerOxN0pDk2E6N6DsEIa2Ctj48FOMfNDdrwinocKaC7YXUZ1pHlKpnkja/Q==",
+ "cpu": [
+ "arm"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@rollup/rollup-linux-arm64-gnu": {
+ "version": "4.53.2",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.53.2.tgz",
+ "integrity": "sha512-Xt2byDZ+6OVNuREgBXr4+CZDJtrVso5woFtpKdGPhpTPHcNG7D8YXeQzpNbFRxzTVqJf7kvPMCub/pcGUWgBjA==",
+ "cpu": [
+ "arm64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@rollup/rollup-linux-arm64-musl": {
+ "version": "4.53.2",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.53.2.tgz",
+ "integrity": "sha512-+LdZSldy/I9N8+klim/Y1HsKbJ3BbInHav5qE9Iy77dtHC/pibw1SR/fXlWyAk0ThnpRKoODwnAuSjqxFRDHUQ==",
+ "cpu": [
+ "arm64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@rollup/rollup-linux-loong64-gnu": {
+ "version": "4.53.2",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-gnu/-/rollup-linux-loong64-gnu-4.53.2.tgz",
+ "integrity": "sha512-8ms8sjmyc1jWJS6WdNSA23rEfdjWB30LH8Wqj0Cqvv7qSHnvw6kgMMXRdop6hkmGPlyYBdRPkjJnj3KCUHV/uQ==",
+ "cpu": [
+ "loong64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@rollup/rollup-linux-ppc64-gnu": {
+ "version": "4.53.2",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-gnu/-/rollup-linux-ppc64-gnu-4.53.2.tgz",
+ "integrity": "sha512-3HRQLUQbpBDMmzoxPJYd3W6vrVHOo2cVW8RUo87Xz0JPJcBLBr5kZ1pGcQAhdZgX9VV7NbGNipah1omKKe23/g==",
+ "cpu": [
+ "ppc64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@rollup/rollup-linux-riscv64-gnu": {
+ "version": "4.53.2",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.53.2.tgz",
+ "integrity": "sha512-fMjKi+ojnmIvhk34gZP94vjogXNNUKMEYs+EDaB/5TG/wUkoeua7p7VCHnE6T2Tx+iaghAqQX8teQzcvrYpaQA==",
+ "cpu": [
+ "riscv64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@rollup/rollup-linux-riscv64-musl": {
+ "version": "4.53.2",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.53.2.tgz",
+ "integrity": "sha512-XuGFGU+VwUUV5kLvoAdi0Wz5Xbh2SrjIxCtZj6Wq8MDp4bflb/+ThZsVxokM7n0pcbkEr2h5/pzqzDYI7cCgLQ==",
+ "cpu": [
+ "riscv64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@rollup/rollup-linux-s390x-gnu": {
+ "version": "4.53.2",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.53.2.tgz",
+ "integrity": "sha512-w6yjZF0P+NGzWR3AXWX9zc0DNEGdtvykB03uhonSHMRa+oWA6novflo2WaJr6JZakG2ucsyb+rvhrKac6NIy+w==",
+ "cpu": [
+ "s390x"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
"node_modules/@rollup/rollup-linux-x64-gnu": {
"version": "4.53.2",
"cpu": [
@@ -1761,6 +3028,71 @@
"linux"
]
},
+ "node_modules/@rollup/rollup-openharmony-arm64": {
+ "version": "4.53.2",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-openharmony-arm64/-/rollup-openharmony-arm64-4.53.2.tgz",
+ "integrity": "sha512-4VEd19Wmhr+Zy7hbUsFZ6YXEiP48hE//KPLCSVNY5RMGX2/7HZ+QkN55a3atM1C/BZCGIgqN+xrVgtdak2S9+A==",
+ "cpu": [
+ "arm64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "openharmony"
+ ]
+ },
+ "node_modules/@rollup/rollup-win32-arm64-msvc": {
+ "version": "4.53.2",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.53.2.tgz",
+ "integrity": "sha512-IlbHFYc/pQCgew/d5fslcy1KEaYVCJ44G8pajugd8VoOEI8ODhtb/j8XMhLpwHCMB3yk2J07ctup10gpw2nyMA==",
+ "cpu": [
+ "arm64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "win32"
+ ]
+ },
+ "node_modules/@rollup/rollup-win32-ia32-msvc": {
+ "version": "4.53.2",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.53.2.tgz",
+ "integrity": "sha512-lNlPEGgdUfSzdCWU176ku/dQRnA7W+Gp8d+cWv73jYrb8uT7HTVVxq62DUYxjbaByuf1Yk0RIIAbDzp+CnOTFg==",
+ "cpu": [
+ "ia32"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "win32"
+ ]
+ },
+ "node_modules/@rollup/rollup-win32-x64-gnu": {
+ "version": "4.53.2",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-gnu/-/rollup-win32-x64-gnu-4.53.2.tgz",
+ "integrity": "sha512-S6YojNVrHybQis2lYov1sd+uj7K0Q05NxHcGktuMMdIQ2VixGwAfbJ23NnlvvVV1bdpR2m5MsNBViHJKcA4ADw==",
+ "cpu": [
+ "x64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "win32"
+ ]
+ },
+ "node_modules/@rollup/rollup-win32-x64-msvc": {
+ "version": "4.53.2",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.53.2.tgz",
+ "integrity": "sha512-k+/Rkcyx//P6fetPoLMb8pBeqJBNGx81uuf7iljX9++yNBVRDQgD04L+SVXmXmh5ZP4/WOp4mWF0kmi06PW2tA==",
+ "cpu": [
+ "x64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "win32"
+ ]
+ },
"node_modules/@sindresorhus/is": {
"version": "7.1.1",
"license": "MIT",
@@ -1785,11 +3117,20 @@
"version": "1.2.12",
"license": "CC0-1.0"
},
+ "node_modules/@tybys/wasm-util": {
+ "version": "0.10.1",
+ "resolved": "https://registry.npmjs.org/@tybys/wasm-util/-/wasm-util-0.10.1.tgz",
+ "integrity": "sha512-9tTaPJLSiejZKx+Bmog4uSubteqTvFrVrURwkmHixBo0G4seD0zUxp98E1DzUBJxLQ3NPwXrGKDiVjwx/DpPsg==",
+ "license": "MIT",
+ "optional": true,
+ "dependencies": {
+ "tslib": "^2.4.0"
+ }
+ },
"node_modules/@types/eslint": {
"version": "9.6.1",
"dev": true,
"license": "MIT",
- "peer": true,
"dependencies": {
"@types/estree": "*",
"@types/json-schema": "*"
@@ -1799,7 +3140,6 @@
"version": "3.7.7",
"dev": true,
"license": "MIT",
- "peer": true,
"dependencies": {
"@types/eslint": "*",
"@types/estree": "*"
@@ -1812,13 +3152,13 @@
"node_modules/@types/json-schema": {
"version": "7.0.15",
"dev": true,
- "license": "MIT",
- "peer": true
+ "license": "MIT"
},
"node_modules/@types/node": {
"version": "24.10.1",
"devOptional": true,
"license": "MIT",
+ "peer": true,
"dependencies": {
"undici-types": "~7.16.0"
}
@@ -2342,7 +3682,9 @@
}
},
"node_modules/@vitejs/plugin-vue-jsx/node_modules/@rolldown/pluginutils": {
- "version": "1.0.0-beta.50",
+ "version": "1.0.0-beta.52",
+ "resolved": "https://registry.npmjs.org/@rolldown/pluginutils/-/pluginutils-1.0.0-beta.52.tgz",
+ "integrity": "sha512-/L0htLJZbaZFL1g9OHOblTxbCYIGefErJjtYOwgl9ZqNx27P3L0SDfjhhHIss32gu5NWgnxuT2a2Hnnv6QGHKA==",
"license": "MIT"
},
"node_modules/@volar/language-core": {
@@ -2447,6 +3789,7 @@
"node_modules/@vue/compiler-sfc": {
"version": "3.5.24",
"license": "MIT",
+ "peer": true,
"dependencies": {
"@babel/parser": "^7.28.5",
"@vue/compiler-core": "3.5.24",
@@ -2581,7 +3924,6 @@
"version": "1.14.1",
"dev": true,
"license": "MIT",
- "peer": true,
"dependencies": {
"@webassemblyjs/helper-numbers": "1.13.2",
"@webassemblyjs/helper-wasm-bytecode": "1.13.2"
@@ -2590,26 +3932,22 @@
"node_modules/@webassemblyjs/floating-point-hex-parser": {
"version": "1.13.2",
"dev": true,
- "license": "MIT",
- "peer": true
+ "license": "MIT"
},
"node_modules/@webassemblyjs/helper-api-error": {
"version": "1.13.2",
"dev": true,
- "license": "MIT",
- "peer": true
+ "license": "MIT"
},
"node_modules/@webassemblyjs/helper-buffer": {
"version": "1.14.1",
"dev": true,
- "license": "MIT",
- "peer": true
+ "license": "MIT"
},
"node_modules/@webassemblyjs/helper-numbers": {
"version": "1.13.2",
"dev": true,
"license": "MIT",
- "peer": true,
"dependencies": {
"@webassemblyjs/floating-point-hex-parser": "1.13.2",
"@webassemblyjs/helper-api-error": "1.13.2",
@@ -2619,14 +3957,12 @@
"node_modules/@webassemblyjs/helper-wasm-bytecode": {
"version": "1.13.2",
"dev": true,
- "license": "MIT",
- "peer": true
+ "license": "MIT"
},
"node_modules/@webassemblyjs/helper-wasm-section": {
"version": "1.14.1",
"dev": true,
"license": "MIT",
- "peer": true,
"dependencies": {
"@webassemblyjs/ast": "1.14.1",
"@webassemblyjs/helper-buffer": "1.14.1",
@@ -2638,7 +3974,6 @@
"version": "1.13.2",
"dev": true,
"license": "MIT",
- "peer": true,
"dependencies": {
"@xtuc/ieee754": "^1.2.0"
}
@@ -2647,7 +3982,6 @@
"version": "1.13.2",
"dev": true,
"license": "Apache-2.0",
- "peer": true,
"dependencies": {
"@xtuc/long": "4.2.2"
}
@@ -2655,14 +3989,12 @@
"node_modules/@webassemblyjs/utf8": {
"version": "1.13.2",
"dev": true,
- "license": "MIT",
- "peer": true
+ "license": "MIT"
},
"node_modules/@webassemblyjs/wasm-edit": {
"version": "1.14.1",
"dev": true,
"license": "MIT",
- "peer": true,
"dependencies": {
"@webassemblyjs/ast": "1.14.1",
"@webassemblyjs/helper-buffer": "1.14.1",
@@ -2678,7 +4010,6 @@
"version": "1.14.1",
"dev": true,
"license": "MIT",
- "peer": true,
"dependencies": {
"@webassemblyjs/ast": "1.14.1",
"@webassemblyjs/helper-wasm-bytecode": "1.13.2",
@@ -2691,7 +4022,6 @@
"version": "1.14.1",
"dev": true,
"license": "MIT",
- "peer": true,
"dependencies": {
"@webassemblyjs/ast": "1.14.1",
"@webassemblyjs/helper-buffer": "1.14.1",
@@ -2703,7 +4033,6 @@
"version": "1.14.1",
"dev": true,
"license": "MIT",
- "peer": true,
"dependencies": {
"@webassemblyjs/ast": "1.14.1",
"@webassemblyjs/helper-api-error": "1.13.2",
@@ -2717,7 +4046,6 @@
"version": "1.14.1",
"dev": true,
"license": "MIT",
- "peer": true,
"dependencies": {
"@webassemblyjs/ast": "1.14.1",
"@xtuc/long": "4.2.2"
@@ -2730,14 +4058,12 @@
"node_modules/@xtuc/ieee754": {
"version": "1.2.0",
"dev": true,
- "license": "BSD-3-Clause",
- "peer": true
+ "license": "BSD-3-Clause"
},
"node_modules/@xtuc/long": {
"version": "4.2.2",
"dev": true,
- "license": "Apache-2.0",
- "peer": true
+ "license": "Apache-2.0"
},
"node_modules/abbrev": {
"version": "3.0.1",
@@ -2759,6 +4085,7 @@
"node_modules/acorn": {
"version": "8.15.0",
"license": "MIT",
+ "peer": true,
"bin": {
"acorn": "bin/acorn"
},
@@ -2777,7 +4104,6 @@
"version": "1.0.4",
"dev": true,
"license": "MIT",
- "peer": true,
"engines": {
"node": ">=10.13.0"
},
@@ -2812,7 +4138,6 @@
"version": "2.1.1",
"dev": true,
"license": "MIT",
- "peer": true,
"dependencies": {
"ajv": "^8.0.0"
},
@@ -2829,7 +4154,6 @@
"version": "5.1.0",
"dev": true,
"license": "MIT",
- "peer": true,
"dependencies": {
"fast-deep-equal": "^3.1.3"
},
@@ -3108,6 +4432,7 @@
}
],
"license": "MIT",
+ "peer": true,
"dependencies": {
"baseline-browser-mapping": "^2.8.25",
"caniuse-lite": "^1.0.30001754",
@@ -3299,7 +4624,6 @@
"version": "1.0.4",
"dev": true,
"license": "MIT",
- "peer": true,
"engines": {
"node": ">=6.0"
}
@@ -4071,7 +5395,6 @@
"version": "5.1.1",
"dev": true,
"license": "BSD-2-Clause",
- "peer": true,
"dependencies": {
"esrecurse": "^4.3.0",
"estraverse": "^4.1.1"
@@ -4084,7 +5407,6 @@
"version": "4.3.0",
"dev": true,
"license": "BSD-2-Clause",
- "peer": true,
"dependencies": {
"estraverse": "^5.2.0"
},
@@ -4096,7 +5418,6 @@
"version": "5.3.0",
"dev": true,
"license": "BSD-2-Clause",
- "peer": true,
"engines": {
"node": ">=4.0"
}
@@ -4105,7 +5426,6 @@
"version": "4.3.0",
"dev": true,
"license": "BSD-2-Clause",
- "peer": true,
"engines": {
"node": ">=4.0"
}
@@ -4170,8 +5490,7 @@
"node_modules/fast-deep-equal": {
"version": "3.1.3",
"dev": true,
- "license": "MIT",
- "peer": true
+ "license": "MIT"
},
"node_modules/fast-fifo": {
"version": "1.3.2",
@@ -4211,8 +5530,7 @@
"url": "https://opencollective.com/fastify"
}
],
- "license": "BSD-3-Clause",
- "peer": true
+ "license": "BSD-3-Clause"
},
"node_modules/fastq": {
"version": "1.19.1",
@@ -4414,8 +5732,7 @@
"node_modules/glob-to-regexp": {
"version": "0.4.1",
"dev": true,
- "license": "BSD-2-Clause",
- "peer": true
+ "license": "BSD-2-Clause"
},
"node_modules/global-directory": {
"version": "4.0.1",
@@ -4500,7 +5817,6 @@
"version": "4.0.0",
"dev": true,
"license": "MIT",
- "peer": true,
"engines": {
"node": ">=8"
}
@@ -4877,7 +6193,6 @@
"version": "27.5.1",
"dev": true,
"license": "MIT",
- "peer": true,
"dependencies": {
"@types/node": "*",
"merge-stream": "^2.0.0",
@@ -4919,14 +6234,12 @@
"node_modules/json-parse-even-better-errors": {
"version": "2.3.1",
"dev": true,
- "license": "MIT",
- "peer": true
+ "license": "MIT"
},
"node_modules/json-schema-traverse": {
"version": "1.0.0",
"dev": true,
- "license": "MIT",
- "peer": true
+ "license": "MIT"
},
"node_modules/json5": {
"version": "2.2.3",
@@ -5077,7 +6390,6 @@
"version": "4.3.1",
"dev": true,
"license": "MIT",
- "peer": true,
"engines": {
"node": ">=6.11.5"
},
@@ -5228,13 +6540,19 @@
}
},
"node_modules/mime-types": {
- "version": "3.0.1",
+ "version": "3.0.2",
+ "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-3.0.2.tgz",
+ "integrity": "sha512-Lbgzdk0h4juoQ9fCKXW4by0UJqj+nOOrI9MJ1sSj4nI8aI2eo1qmvQEie4VD1glsS250n15LsWsYtCugiStS5A==",
"license": "MIT",
"dependencies": {
"mime-db": "^1.54.0"
},
"engines": {
- "node": ">= 0.6"
+ "node": ">=18"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/express"
}
},
"node_modules/mimic-fn": {
@@ -5346,8 +6664,7 @@
"node_modules/neo-async": {
"version": "2.6.2",
"dev": true,
- "license": "MIT",
- "peer": true
+ "license": "MIT"
},
"node_modules/nitropack": {
"version": "2.12.9",
@@ -5620,6 +6937,7 @@
"version": "4.2.1",
"resolved": "https://registry.npmjs.org/nuxt/-/nuxt-4.2.1.tgz",
"integrity": "sha512-OE5ONizgwkKhjTGlUYB3ksE+2q2/I30QIYFl3N1yYz1r2rwhunGA3puUvqkzXwgLQ3AdsNcigPDmyQsqjbSdoQ==",
+ "peer": true,
"dependencies": {
"@dxup/nuxt": "^0.2.1",
"@nuxt/cli": "^3.30.0",
@@ -5897,6 +7215,7 @@
"node_modules/oxc-parser": {
"version": "0.96.0",
"license": "MIT",
+ "peer": true,
"dependencies": {
"@oxc-project/types": "^0.96.0"
},
@@ -6105,6 +7424,7 @@
}
],
"license": "MIT",
+ "peer": true,
"dependencies": {
"nanoid": "^3.3.11",
"picocolors": "^1.1.1",
@@ -6673,7 +7993,6 @@
"version": "2.0.2",
"dev": true,
"license": "MIT",
- "peer": true,
"engines": {
"node": ">=0.10.0"
}
@@ -6718,6 +8037,7 @@
"node_modules/rollup": {
"version": "4.53.2",
"license": "MIT",
+ "peer": true,
"dependencies": {
"@types/estree": "1.0.8"
},
@@ -6853,7 +8173,6 @@
"version": "4.3.3",
"dev": true,
"license": "MIT",
- "peer": true,
"dependencies": {
"@types/json-schema": "^7.0.9",
"ajv": "^8.9.0",
@@ -7234,7 +8553,6 @@
"version": "8.1.1",
"dev": true,
"license": "MIT",
- "peer": true,
"dependencies": {
"has-flag": "^4.0.0"
},
@@ -7359,7 +8677,6 @@
"version": "5.3.14",
"dev": true,
"license": "MIT",
- "peer": true,
"dependencies": {
"@jridgewell/trace-mapping": "^0.3.25",
"jest-worker": "^27.4.5",
@@ -7443,6 +8760,7 @@
"node_modules/tinyglobby/node_modules/picomatch": {
"version": "4.0.3",
"license": "MIT",
+ "peer": true,
"engines": {
"node": ">=12"
},
@@ -7478,6 +8796,13 @@
"version": "0.0.3",
"license": "MIT"
},
+ "node_modules/tslib": {
+ "version": "2.8.1",
+ "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz",
+ "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==",
+ "license": "0BSD",
+ "optional": true
+ },
"node_modules/type-fest": {
"version": "5.2.0",
"license": "(MIT OR CC0-1.0)",
@@ -7971,6 +9296,7 @@
"node_modules/vite": {
"version": "7.2.2",
"license": "MIT",
+ "peer": true,
"dependencies": {
"esbuild": "^0.25.0",
"fdir": "^6.5.0",
@@ -8302,6 +9628,7 @@
"node_modules/vite/node_modules/picomatch": {
"version": "4.0.3",
"license": "MIT",
+ "peer": true,
"engines": {
"node": ">=12"
},
@@ -8316,6 +9643,7 @@
"node_modules/vue": {
"version": "3.5.24",
"license": "MIT",
+ "peer": true,
"dependencies": {
"@vue/compiler-dom": "3.5.24",
"@vue/compiler-sfc": "3.5.24",
@@ -8351,6 +9679,7 @@
"node_modules/vue-router": {
"version": "4.6.3",
"license": "MIT",
+ "peer": true,
"dependencies": {
"@vue/devtools-api": "^6.6.4"
},
@@ -8365,7 +9694,6 @@
"version": "2.4.4",
"dev": true,
"license": "MIT",
- "peer": true,
"dependencies": {
"glob-to-regexp": "^0.4.1",
"graceful-fs": "^4.1.2"
@@ -8389,7 +9717,6 @@
"version": "5.102.1",
"dev": true,
"license": "MIT",
- "peer": true,
"dependencies": {
"@types/eslint-scope": "^3.7.7",
"@types/estree": "^1.0.8",
@@ -8449,7 +9776,6 @@
"version": "1.52.0",
"dev": true,
"license": "MIT",
- "peer": true,
"engines": {
"node": ">= 0.6"
}
@@ -8458,7 +9784,6 @@
"version": "2.1.35",
"dev": true,
"license": "MIT",
- "peer": true,
"dependencies": {
"mime-db": "1.52.0"
},
diff --git a/example-app/package.json b/example-app/package.json
index 2d301c0..3ad50bf 100644
--- a/example-app/package.json
+++ b/example-app/package.json
@@ -1,5 +1,5 @@
{
- "name": "hello-nuxt",
+ "name": "example-app",
"private": true,
"type": "module",
"scripts": {
@@ -9,15 +9,13 @@
"preview": "nuxt preview"
},
"dependencies": {
- "@lit/reactive-element": "^2.1.1",
+ "@impost/lib": "workspace:*",
+ "@impost/widget": "workspace:*",
"js-toml": "^1.0.2",
- "lit-element": "^4.2.1",
- "lit-html": "^3.3.1",
"nuxt": "latest",
"nuxt-ssr-lit": "1.6.32",
- "zod": "^4.1.12",
- "@impost/lib": "file:../packages/lib",
- "@impost/widget": "file:../packages/widget"
+ "vue": "^3.5.25",
+ "zod": "^4.1.12"
},
"devDependencies": {
"@types/node": "^24.10.0",
diff --git a/example-app/server/api/pow/challenge.post.ts b/example-app/server/api/pow/challenge.post.ts
index e140f92..0d37684 100644
--- a/example-app/server/api/pow/challenge.post.ts
+++ b/example-app/server/api/pow/challenge.post.ts
@@ -13,26 +13,29 @@ export default defineEventHandler(async (event) => {
const body = await readValidatedBody(event, challengeSchema.safeParse);
if (!body.success) {
+ const errors = z.treeifyError(body.error);
+ const error_message = Object.entries(errors.errors).map(([key, value]) => `${key}: ${value}`).join('\n');
+
throw createError({
statusCode: 400,
- statusMessage: 'Validation failed'
+ statusMessage: error_message
})
}
- let target = body.data.challenge;
- let nonce = body.data.nonce;
+ let { challenge, nonce } = body.data;
+
+ const outstanding_challenge = outstandingChallenges.get(body.data.challenge)!;
+ // always delete the challenge on a solve attempt
+ clearTimeout(outstanding_challenge.timeout);
+ outstandingChallenges.delete(challenge);
// check if the challenge is valid
- let challenge_valid = await validate_challenge(outstandingChallenges.get(target)!.challenge, {
- challenge: target,
- nonce: nonce
+ let challenge_valid = await validate_challenge(outstandingChallenges.get(challenge)!.challenge, {
+ challenge,
+ nonce,
});
if (challenge_valid) {
- // clear the challenge
- clearTimeout(outstandingChallenges.get(target)!.timeout);
- outstandingChallenges.delete(target);
-
return {
message: 'Challenge solved'
};
diff --git a/justfile b/justfile
deleted file mode 100644
index 3d10f4c..0000000
--- a/justfile
+++ /dev/null
@@ -1,26 +0,0 @@
-build: build-widget
-
-wasm-opt-args := "--strip-debug --strip-dwarf --enable-tail-call --enable-bulk-memory -Oz"
-zig-build-args := "--release=fast"
-
-npm-runner := "npm"
-
-[working-directory: "solver"]
-build-wasm:
- zig build {{zig-build-args}}
- wasm-opt {{wasm-opt-args}} --enable-simd -o zig-out/bin/solver.wasm zig-out/bin/solver.wasm
- # The server does not support simd, so we disable it here
- wasm-opt {{wasm-opt-args}} --disable-simd -o zig-out/bin/validator.wasm zig-out/bin/validator.wasm
-
-[working-directory: "packages/lib"]
-build-lib: build-wasm
- {{npm-runner}} install
- {{npm-runner}} link
- {{npm-runner}} run build
-
-[working-directory: "packages/widget"]
-build-widget: build-lib
- {{npm-runner}} install
- {{npm-runner}} link @impost/lib
- {{npm-runner}} link
- {{npm-runner}} run build
diff --git a/package.json b/package.json
new file mode 100644
index 0000000..abc11a6
--- /dev/null
+++ b/package.json
@@ -0,0 +1,17 @@
+{
+ "name": "impost-monorepo",
+ "version": "0.0.0",
+ "private": true,
+ "scripts": {
+ "build": "pnpm build:all",
+ "build:all": "pnpm build:solver && pnpm build:lib && pnpm build:widget",
+ "build:solver": "pnpm --filter solver build",
+ "build:lib": "pnpm --filter lib build",
+ "build:widget": "pnpm --filter widget build",
+ "dev:example": "pnpm --filter example-app dev"
+ },
+ "devDependencies": {
+ "typescript": "^5.0.0"
+ },
+ "packageManager": "pnpm@10.21.0+sha512.da3337267e400fdd3d479a6c68079ac6db01d8ca4f67572083e722775a796788a7a9956613749e000fac20d424b594f7a791a5f4e2e13581c5ef947f26968a40"
+}
diff --git a/packages/lib/package-lock.json b/packages/lib/package-lock.json
index d643549..e66168c 100644
--- a/packages/lib/package-lock.json
+++ b/packages/lib/package-lock.json
@@ -2058,7 +2058,6 @@
"integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==",
"dev": true,
"license": "MIT",
- "peer": true,
"engines": {
"node": ">=12"
},
@@ -2332,7 +2331,6 @@
"integrity": "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==",
"dev": true,
"license": "Apache-2.0",
- "peer": true,
"bin": {
"tsc": "bin/tsc",
"tsserver": "bin/tsserver"
@@ -2383,7 +2381,6 @@
"integrity": "sha512-BxAKBWmIbrDgrokdGZH1IgkIk/5mMHDreLDmCJ0qpyJaAteP8NvMhkwr/ZCQNqNH97bw/dANTE9PDzqwJghfMQ==",
"dev": true,
"license": "MIT",
- "peer": true,
"dependencies": {
"esbuild": "^0.25.0",
"fdir": "^6.5.0",
diff --git a/packages/lib/package.json b/packages/lib/package.json
index f20e057..463c77f 100644
--- a/packages/lib/package.json
+++ b/packages/lib/package.json
@@ -36,4 +36,4 @@
"dependencies": {
"uuidv7": "^1.0.2"
}
-}
+}
\ No newline at end of file
diff --git a/packages/lib/src/solver.ts b/packages/lib/src/solver.ts
index 7161566..203334d 100644
--- a/packages/lib/src/solver.ts
+++ b/packages/lib/src/solver.ts
@@ -1,4 +1,5 @@
-import WASMSolverUrl from '../../../solver/zig-out/bin/solver.wasm?url&inline';
+import WASMSolverUrl from '../../solver/zig-out/bin/solver.wasm?url&inline';
+import { ChallengeStrategy, type Challenge, type ChallengeLeadingZeroes, type ChallengeTargetNumber } from '.';
type WasmExports = Record & {
"malloc": (byte_count: number) => number | null;
@@ -17,6 +18,7 @@ export type SolverEnv = {
__set_solution: (value: number) => void;
__cmpxchg_solution: (expected: number, replacement: number) => number;
__fetch_add_nonce: (value: number) => number;
+ __log: (str_ptr: number, str_len: number) => void;
};
export async function get_wasm_module(): Promise {
@@ -29,7 +31,18 @@ export async function init_solver(env: SolverEnv, module: WebAssembly.Module): P
}) as unknown as SolverModule;
}
-export function solve_leaading_zeroes_challenge(solver: SolverModule, challenge: { salt: string, difficulty: number }): number {
+export function solve_challenge(solver: SolverModule, challenge: Challenge): number {
+ switch (challenge.strategy) {
+ case ChallengeStrategy.LeadingZeroes:
+ return solve_leaading_zeroes_challenge(solver, challenge);
+ case ChallengeStrategy.TargetNumber:
+ return solve_target_number_challenge(solver, challenge);
+ default:
+ throw new Error("Invalid challenge strategy");
+ }
+}
+
+function solve_leaading_zeroes_challenge(solver: SolverModule, challenge: ChallengeLeadingZeroes): number {
const { salt, difficulty } = challenge;
const encoder = new TextEncoder();
@@ -56,7 +69,7 @@ export function solve_leaading_zeroes_challenge(solver: SolverModule, challenge:
return ret;
}
-export function solve_target_number_challenge(solver: SolverModule, challenge: { salt: string, target: string }): number {
+function solve_target_number_challenge(solver: SolverModule, challenge: ChallengeTargetNumber): number {
const { salt, target } = challenge;
const encoder = new TextEncoder();
diff --git a/packages/lib/src/validator.ts b/packages/lib/src/validator.ts
index 3c5185c..66432a1 100644
--- a/packages/lib/src/validator.ts
+++ b/packages/lib/src/validator.ts
@@ -1,5 +1,5 @@
-import { ChallengeAlgorithm, ChallengeStrategy, type Challenge } from '.';
-import WASMValidatorUrl from '../../../solver/zig-out/bin/validator.wasm?url&inline';
+import { ChallengeAlgorithm, ChallengeStrategy, type Challenge, type ChallengeLeadingZeroes, type ChallengeTargetNumber } from '.';
+import WASMValidatorUrl from '../../solver/zig-out/bin/validator.wasm?url&inline';
type WasmExports = Record & {
"malloc": (byte_count: number) => number | null;
@@ -18,11 +18,11 @@ function array_to_base64(buffer: ArrayBuffer): string {
return btoa(String.fromCharCode(...new Uint8Array(buffer)));
}
-async function generate_leading_zeroes_challenge(parameters: Object, difficulty: number): Promise {
+async function generate_leading_zeroes_challenge(parameters: Object, difficulty: number): Promise {
let parameters_str = Object.entries(parameters).map(([key, value]) => `${key}=${value}`).join("&");
let salt = `${array_to_base64(crypto.getRandomValues(new Uint8Array(32)).buffer)}?${parameters_str}`;
- let challenge: Challenge = {
+ let challenge: ChallengeLeadingZeroes = {
algorithm: ChallengeAlgorithm.Argon2id,
strategy: ChallengeStrategy.LeadingZeroes,
salt,
@@ -32,7 +32,7 @@ async function generate_leading_zeroes_challenge(parameters: Object, difficulty:
return challenge;
}
-async function generate_target_number_challenge(parameters: Object, max_number: number): Promise {
+async function generate_target_number_challenge(parameters: Object, max_number: number): Promise {
// in target number config, since we need to generate a target hash, we
// need to hash the salt + nonce, so the client knows what the target is
const validator = (await WebAssembly.instantiateStreaming(fetch(WASMValidatorUrl))).instance as unknown as ValidatorModule;
@@ -68,7 +68,7 @@ async function generate_target_number_challenge(parameters: Object, max_number:
let target_slice = new Uint8Array(validator.exports.memory.buffer.slice(target_ptr, target_ptr + target_len));
const target = new TextDecoder().decode(target_slice);
- let challenge: Challenge = {
+ let challenge: ChallengeTargetNumber = {
algorithm: ChallengeAlgorithm.Argon2id,
strategy: ChallengeStrategy.TargetNumber,
salt,
diff --git a/packages/lib/vite.config.ts b/packages/lib/vite.config.ts
index 6384f8c..9118a98 100644
--- a/packages/lib/vite.config.ts
+++ b/packages/lib/vite.config.ts
@@ -18,7 +18,7 @@ export default defineConfig({
preserveModules: false
}
},
- sourcemap: true
+ minify: true
},
resolve: {
alias: {
diff --git a/solver/.gitignore b/packages/solver/.gitignore
similarity index 100%
rename from solver/.gitignore
rename to packages/solver/.gitignore
diff --git a/solver/build.zig b/packages/solver/build.zig
similarity index 56%
rename from solver/build.zig
rename to packages/solver/build.zig
index 848d1d3..6a8d6bb 100644
--- a/solver/build.zig
+++ b/packages/solver/build.zig
@@ -2,17 +2,13 @@ const std = @import("std");
pub fn build(b: *std.Build) void {
const optimize = b.standardOptimizeOption(.{});
- const wasm_target = b.resolveTargetQuery(.{
- .cpu_arch = .wasm32,
- .os_tag = .freestanding,
- .cpu_features_add = std.Target.wasm.featureSet(&.{ .bulk_memory, .bulk_memory_opt, .simd128, .tail_call }),
- });
+ const target = b.standardTargetOptions(.{});
// solver
const solver_mod = b.addModule("solver", .{
.root_source_file = b.path("src/solver.zig"),
.optimize = optimize,
- .target = wasm_target,
+ .target = target,
});
const solver_exe = b.addExecutable(.{
@@ -20,10 +16,12 @@ pub fn build(b: *std.Build) void {
.root_module = solver_mod,
});
- solver_exe.entry = .disabled;
- solver_exe.rdynamic = true;
- solver_exe.lto = .full;
- solver_exe.link_gc_sections = true;
+ if (target.result.cpu.arch == .wasm32) {
+ solver_exe.entry = .disabled;
+ solver_exe.rdynamic = true;
+ solver_exe.link_gc_sections = true;
+ solver_exe.lto = .full;
+ }
b.installArtifact(solver_exe);
@@ -31,16 +29,18 @@ pub fn build(b: *std.Build) void {
const validator_mod = b.addModule("validator", .{
.root_source_file = b.path("src/validator.zig"),
.optimize = optimize,
- .target = wasm_target,
+ .target = target,
});
- const validator_exe = b.addLibrary(.{
+ const validator_exe = b.addExecutable(.{
.name = "validator",
.root_module = validator_mod,
});
- validator_exe.entry = .disabled;
- validator_exe.rdynamic = true;
+ if (target.result.cpu.arch == .wasm32) {
+ validator_exe.entry = .disabled;
+ validator_exe.rdynamic = true;
+ }
b.installArtifact(validator_exe);
}
diff --git a/packages/solver/package.json b/packages/solver/package.json
new file mode 100644
index 0000000..d53f225
--- /dev/null
+++ b/packages/solver/package.json
@@ -0,0 +1,11 @@
+{
+ "name": "solver",
+ "description": "Zig WASM POW solver, not an actual node package, just using this so that pnpm will build it for me",
+ "version": "0.1.0",
+ "private": true,
+ "scripts": {
+ "build": "pnpm run build:wasm && pnpm run minify",
+ "build:wasm": "zig build --release=fast -Dtarget=wasm32-freestanding -Dcpu=generic+bulk_memory+bulk_memory_opt+simd128+tail_call",
+ "minify": "wasm-opt --strip-debug --strip-dwarf -O4 -o zig-out/bin/solver.wasm zig-out/bin/solver.wasm && wasm-opt --strip-debug --strip-dwarf -O4 -o zig-out/bin/validator.wasm zig-out/bin/validator.wasm"
+ }
+}
\ No newline at end of file
diff --git a/solver/src/hasher.zig b/packages/solver/src/argon2.zig
similarity index 51%
rename from solver/src/hasher.zig
rename to packages/solver/src/argon2.zig
index 888b38e..d2d5945 100644
--- a/solver/src/hasher.zig
+++ b/packages/solver/src/argon2.zig
@@ -2,8 +2,8 @@ const std = @import("std");
const Allocator = std.mem.Allocator;
var argon2_params = std.crypto.pwhash.argon2.Params{
- .t = 4, // time cost
- .m = 256, // memory cost (in KiB)
+ .t = 3, // time cost
+ .m = 8192, // memory cost (in KiB)
.p = 1, // parallelism (this doesnt do anything because we are targeting wasm, and we do multithreading differently anyways)
};
@@ -11,21 +11,8 @@ const dk_len: usize = 32; // 16 or 32 byte key
var derived: [dk_len]u8 = undefined;
var buffer_hash_hex: [64]u8 = undefined;
-fn bytesToHex(bytes: []const u8, output: []u8) void {
- const hex_chars = "0123456789abcdef";
- var i: usize = 0;
- while (i < bytes.len) : (i += 1) {
- output[i * 2] = hex_chars[(bytes[i] >> 4)];
- output[i * 2 + 1] = hex_chars[bytes[i] & 0x0F];
- }
-}
-
pub fn hash(allocator: Allocator, challenge: []const u8, nonce: []const u8) ![]u8 {
try std.crypto.pwhash.argon2.kdf(allocator, &derived, nonce, challenge, argon2_params, .argon2id);
- var hash_bytes: [32]u8 = undefined;
- std.crypto.hash.sha2.Sha256.hash(&derived, @ptrCast(hash_bytes[0..].ptr), .{});
-
- bytesToHex(&hash_bytes, &buffer_hash_hex);
- return buffer_hash_hex[0..];
+ return derived[0..];
}
diff --git a/solver/src/solver.zig b/packages/solver/src/solver.zig
similarity index 58%
rename from solver/src/solver.zig
rename to packages/solver/src/solver.zig
index 744dc13..bd489a5 100644
--- a/solver/src/solver.zig
+++ b/packages/solver/src/solver.zig
@@ -1,23 +1,42 @@
const std = @import("std");
+const builtin = @import("builtin");
+
const Allocator = std.mem.Allocator;
+const utils = @import("utils.zig");
-const hasher = @import("hasher.zig");
+const argon2 = @import("argon2.zig");
-// var gpa: std.heap.GeneralPurposeAllocator(.{}) = .init;
-// var allocator = gpa.allocator();
-
-var allocator = std.heap.wasm_allocator;
+var gpa: std.heap.GeneralPurposeAllocator(.{}) = .init;
+var allocator = gpa.allocator();
extern fn __get_solution() i32;
extern fn __set_solution(value: i32) void;
extern fn __cmpxchg_solution(old: i32, new: i32) i32;
extern fn __fetch_add_nonce(value: i32) i32;
+extern fn __log(str_ptr: usize, str_len: usize) void;
-// fn log(comptime fmt: []const u8, args: anytype) void {
-// const formatted = std.fmt.allocPrint(allocator, fmt, args) catch return;
-// __log(@intFromPtr(formatted.ptr), formatted.len);
-// allocator.free(formatted);
-// }
+fn log(comptime level: std.log.Level, comptime scope: @TypeOf(.EnumLiteral), comptime fmt: []const u8, args: anytype) void {
+ if (comptime builtin.target.cpu.arch != .wasm32) {
+ std.log.defaultLog(level, scope, fmt, args);
+ return;
+ }
+
+ const log_level_str = switch (level) {
+ .err => "Error: ",
+ .warn => "Warning: ",
+ .info => "Info: ",
+ .debug => "Debug: ",
+ };
+
+ const formatted = std.fmt.allocPrint(allocator, fmt, args) catch return;
+ const log_str = std.fmt.allocPrint(allocator, "{s}{s}", .{ log_level_str, formatted }) catch return;
+ allocator.free(formatted);
+ __log(@intFromPtr(log_str.ptr), log_str.len);
+ allocator.free(log_str);
+}
+
+pub const std_options: std.Options = .{ .logFn = log };
+var hex_encoder = utils.HexEncoder{};
export fn malloc(byte_count: usize) ?*u8 {
const ptr = allocator.alloc(u8, byte_count) catch return null;
@@ -31,42 +50,21 @@ export fn free(ptr: ?*anyopaque, byte_count: usize) void {
}
}
-const SolveError = enum(u32) {
- InvalidDifficulty = 1,
- InvalidNonce = 2,
- NoSolution = 3,
- OutOfMemory = 4,
-};
-
-var solve_error: ?SolveError = null;
-export fn get_solve_error() u32 {
- if (solve_error) |err| {
- return @intFromEnum(err);
- }
- return 0;
-}
-
// returns nonce on success, -1 on failure
// to get the error, call get_solve_error
export fn solve_leaading_zeroes_challenge(challenge_ptr: [*]u8, challenge_len: usize, difficulty: u32) i32 {
- solve_error = null;
-
const challenge_slice = challenge_ptr[0..challenge_len];
if (difficulty < 1 or difficulty > 64) {
- solve_error = SolveError.InvalidDifficulty;
+ std.log.err("Invalid difficulty for leading zeroes\n", .{});
return -1;
}
- var target_prefix_buffer: [64]u8 = @splat('0');
- const target_prefix = target_prefix_buffer[0..difficulty];
-
const max_nonce_iterations: u64 = 1_000_000_000;
// 64 + 9 digits for nonce since the max nonce is 999_999_999 (not 1 billion since nonce < max_nonce_iterations)
var input_buffer: []u8 = allocator.alloc(u8, challenge_len + 9) catch {
- // log("Failed to allocate memory for challenge\n", .{});
- solve_error = SolveError.OutOfMemory;
+ std.log.err("Failed to allocate memory for challenge\n", .{});
return -1;
};
// dont leak memory :pepega:
@@ -83,34 +81,34 @@ export fn solve_leaading_zeroes_challenge(challenge_ptr: [*]u8, challenge_len: u
}
const nonce_str = std.fmt.bufPrint(input_buffer[challenge_len..], "{d}", .{nonce}) catch {
- solve_error = SolveError.InvalidNonce;
+ std.log.err("Failed to allocate memory for nonce\n", .{});
return -1;
};
- const hash_hex_slice = hasher.hash(allocator, input_buffer[0..challenge_len], input_buffer[challenge_len .. challenge_len + nonce_str.len]) catch {
- solve_error = SolveError.OutOfMemory;
+ const argon2_key = argon2.hash(allocator, input_buffer[0..challenge_len], input_buffer[challenge_len .. challenge_len + nonce_str.len]) catch {
+ std.log.err("Failed to hash argon2 key\n", .{});
return -1;
};
- if (std.mem.startsWith(u8, hash_hex_slice, target_prefix)) {
- // Found a solution!
- if (__cmpxchg_solution(-1, nonce) == -1) {
- // we found a solution, and we are the first to do so
- return nonce;
- } else {
- // we found a solution, but we are not the first to do so
- return 0;
- }
+ _ = hex_encoder.encode(argon2_key);
+ if (!hex_encoder.countZeroes(difficulty)) {
+ continue;
+ }
+
+ // Found a solution!
+ if (__cmpxchg_solution(-1, nonce) == -1) {
+ // we found a solution, and we are the first to do so
+ return nonce;
+ } else {
+ // we found a solution, but we are not the first to do so
+ return 0;
}
}
- solve_error = SolveError.NoSolution;
return -1;
}
export fn solve_target_number_challenge(target_ptr: [*]u8, target_len: usize, salt_ptr: [*]u8, salt_len: usize) i32 {
- solve_error = null;
-
const target_slice = target_ptr[0..target_len];
const salt_slice = salt_ptr[0..salt_len];
@@ -119,7 +117,6 @@ export fn solve_target_number_challenge(target_ptr: [*]u8, target_len: usize, sa
const max_digits = std.math.log10(max_nonce_iterations);
var input_buffer: []u8 = allocator.alloc(u8, salt_len + max_digits) catch {
- solve_error = SolveError.OutOfMemory;
return -1;
};
defer allocator.free(input_buffer);
@@ -133,16 +130,16 @@ export fn solve_target_number_challenge(target_ptr: [*]u8, target_len: usize, sa
}
const nonce_str = std.fmt.bufPrint(input_buffer[salt_len..], "{d}", .{nonce}) catch {
- solve_error = SolveError.InvalidNonce;
return -1;
};
- const hash_hex_slice = hasher.hash(allocator, input_buffer[0..salt_len], input_buffer[salt_len .. salt_len + nonce_str.len]) catch {
- solve_error = SolveError.OutOfMemory;
+ const argon2_key = argon2.hash(allocator, input_buffer[0..salt_len], input_buffer[salt_len .. salt_len + nonce_str.len]) catch {
return -1;
};
- if (std.mem.eql(u8, target_slice, hash_hex_slice)) {
+ const hex_slice = hex_encoder.encode(argon2_key);
+
+ if (std.mem.eql(u8, target_slice, hex_slice)) {
// Found a solution!
if (__cmpxchg_solution(-1, nonce) == -1) {
// we found a solution, and we are the first to do so
@@ -154,6 +151,5 @@ export fn solve_target_number_challenge(target_ptr: [*]u8, target_len: usize, sa
}
}
- solve_error = SolveError.NoSolution;
return -1;
}
diff --git a/packages/solver/src/utils.zig b/packages/solver/src/utils.zig
new file mode 100644
index 0000000..1fcc140
--- /dev/null
+++ b/packages/solver/src/utils.zig
@@ -0,0 +1,43 @@
+const std = @import("std");
+const Allocator = std.mem.Allocator;
+
+pub const HexEncoder = struct {
+ scratch: [64]u8 = undefined,
+ scratch_set: bool = false,
+
+ const Self = @This();
+
+ pub fn encode(self: *Self, bytes: []const u8) []u8 {
+ self.scratch_set = true;
+
+ const hex_chars = "0123456789abcdef";
+ var i: usize = 0;
+ while (i < bytes.len) : (i += 1) {
+ self.scratch[i * 2] = hex_chars[(bytes[i] >> 4)];
+ self.scratch[i * 2 + 1] = hex_chars[bytes[i] & 0x0F];
+ }
+
+ return &self.scratch;
+ }
+
+ // counts the number of leading hexidecimal zeroes in the scratch buffer
+ // which is set by encode
+ pub fn countZeroes(self: *Self, zeroes: usize) bool {
+ if (!self.scratch_set) {
+ return false;
+ }
+
+ if (zeroes > 64 or zeroes == 0) {
+ return false;
+ }
+
+ var i: usize = 0;
+ while (i < zeroes) : (i += 1) {
+ if (self.scratch[i] != '0') {
+ return false;
+ }
+ }
+
+ return true;
+ }
+};
diff --git a/solver/src/validator.zig b/packages/solver/src/validator.zig
similarity index 66%
rename from solver/src/validator.zig
rename to packages/solver/src/validator.zig
index f1ca850..42ea122 100644
--- a/solver/src/validator.zig
+++ b/packages/solver/src/validator.zig
@@ -1,9 +1,13 @@
const std = @import("std");
const Allocator = std.mem.Allocator;
-const hasher = @import("hasher.zig");
+const argon2 = @import("argon2.zig");
+const utils = @import("utils.zig");
-var allocator = std.heap.wasm_allocator;
+var gpa: std.heap.GeneralPurposeAllocator(.{}) = .init;
+var allocator = gpa.allocator();
+
+var hex_encoder = utils.HexEncoder{};
export fn malloc(byte_count: usize) ?*u8 {
const ptr = allocator.alloc(u8, byte_count) catch return null;
@@ -17,15 +21,6 @@ export fn free(ptr: ?*anyopaque, byte_count: usize) void {
}
}
-fn bytesToHex(bytes: []const u8, buf: []u8) void {
- const hex_chars = "0123456789abcdef";
- var i: usize = 0;
- while (i < bytes.len) : (i += 1) {
- buf[i * 2] = hex_chars[(bytes[i] >> 4)];
- buf[i * 2 + 1] = hex_chars[bytes[i] & 0x0F];
- }
-}
-
export fn validate_leading_zeroes_challenge(challenge_ptr: [*]u8, challenge_len: usize, nonce_ptr: [*]u8, nonce_len: usize, difficulty: u32) i32 {
const challenge_slice = challenge_ptr[0..challenge_len];
const nonce_slice = nonce_ptr[0..nonce_len];
@@ -34,12 +29,10 @@ export fn validate_leading_zeroes_challenge(challenge_ptr: [*]u8, challenge_len:
return -1;
}
- var target_prefix_buffer: [64]u8 = @splat('0');
- const target_prefix = target_prefix_buffer[0..difficulty];
+ const argon2_key = argon2.hash(allocator, challenge_slice, nonce_slice) catch return -2;
- const hash_hex_slice = hasher.hash(allocator, challenge_slice, nonce_slice) catch return -2;
-
- if (!std.mem.startsWith(u8, hash_hex_slice, target_prefix)) {
+ _ = hex_encoder.encode(argon2_key);
+ if (!hex_encoder.countZeroes(difficulty)) {
return -3;
}
@@ -51,9 +44,10 @@ export fn validate_target_number_challenge(target_ptr: [*]u8, target_len: usize,
const salt_slice = salt_ptr[0..salt_len];
const nonce_slice = nonce_ptr[0..nonce_len];
- const hash_hex_slice = hasher.hash(allocator, salt_slice, nonce_slice) catch return -2;
+ const argon2_key = argon2.hash(allocator, salt_slice, nonce_slice) catch return -2;
+ const hex_slice = hex_encoder.encode(argon2_key);
- if (!std.mem.eql(u8, target_slice, hash_hex_slice)) {
+ if (!std.mem.eql(u8, target_slice, hex_slice)) {
return -3;
}
@@ -63,12 +57,13 @@ export fn validate_target_number_challenge(target_ptr: [*]u8, target_len: usize,
export fn hash(challenge_ptr: [*]u8, challenge_len: usize, nonce_ptr: [*]u8, nonce_len: usize) u64 {
const challenge = challenge_ptr[0..challenge_len];
const nonce = nonce_ptr[0..nonce_len];
- const hash_slice = hasher.hash(allocator, challenge, nonce) catch return 0;
+ const argon2_key = argon2.hash(allocator, challenge, nonce) catch return 0;
+ const hex_slice = hex_encoder.encode(argon2_key);
// bs to get the compiler to not whine about hash_slice.len being a u5 annd thus cannot be shifted by 32
- var ret: u64 = hash_slice.len;
+ var ret: u64 = hex_slice.len;
ret <<= 32;
- ret |= @intFromPtr(hash_slice.ptr);
+ ret |= @intFromPtr(hex_slice.ptr);
return ret;
}
diff --git a/packages/widget/package-lock.json b/packages/widget/package-lock.json
index ff2b26c..3663bdd 100644
--- a/packages/widget/package-lock.json
+++ b/packages/widget/package-lock.json
@@ -8,6 +8,9 @@
"name": "@impost/widget",
"version": "0.1.0",
"license": "BSL-1.0",
+ "dependencies": {
+ "comlink": "^4.4.2"
+ },
"devDependencies": {
"@types/node": "^20.11.24",
"lit": "^3.1.2",
@@ -1433,7 +1436,6 @@
"integrity": "sha512-ZsJzA5thDQMSQO788d7IocwwQbI8B5OPzmqNvpf3NY/+MHDAS759Wo0gd2WQeXYt5AAAQjzcrTVC6SKCuYgoCQ==",
"dev": true,
"license": "MIT",
- "peer": true,
"dependencies": {
"undici-types": "~6.21.0"
}
@@ -1655,6 +1657,11 @@
"dev": true,
"license": "MIT"
},
+ "node_modules/comlink": {
+ "version": "4.4.2",
+ "resolved": "https://registry.npmjs.org/comlink/-/comlink-4.4.2.tgz",
+ "integrity": "sha512-OxGdvBmJuNKSCMO4NTl1L47VRp6xn2wG4F/2hYzB6tiCb709otOxtEYCSvK80PtjODfXXZu8ds+Nw5kVCjqd2g=="
+ },
"node_modules/compare-versions": {
"version": "6.1.1",
"resolved": "https://registry.npmjs.org/compare-versions/-/compare-versions-6.1.1.tgz",
@@ -2148,7 +2155,6 @@
"integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==",
"dev": true,
"license": "MIT",
- "peer": true,
"engines": {
"node": ">=12"
},
@@ -2422,7 +2428,6 @@
"integrity": "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==",
"dev": true,
"license": "Apache-2.0",
- "peer": true,
"bin": {
"tsc": "bin/tsc",
"tsserver": "bin/tsserver"
@@ -2461,7 +2466,6 @@
"integrity": "sha512-BxAKBWmIbrDgrokdGZH1IgkIk/5mMHDreLDmCJ0qpyJaAteP8NvMhkwr/ZCQNqNH97bw/dANTE9PDzqwJghfMQ==",
"dev": true,
"license": "MIT",
- "peer": true,
"dependencies": {
"esbuild": "^0.25.0",
"fdir": "^6.5.0",
diff --git a/packages/widget/package.json b/packages/widget/package.json
index 93d8f69..a8c22cf 100644
--- a/packages/widget/package.json
+++ b/packages/widget/package.json
@@ -23,6 +23,7 @@
"lit-element": "^3.1.2"
},
"devDependencies": {
+ "@impost/lib": "workspace:*",
"@types/node": "^20.11.24",
"lit": "^3.1.2",
"lit-element": "^3.1.2",
@@ -30,6 +31,7 @@
"tslib": "^2.6.2",
"typescript": "^5.3.3",
"vite": "npm:rolldown-vite@latest",
- "vite-plugin-dts": "^4.5.4"
+ "vite-plugin-dts": "^4.5.4",
+ "comlink": "^4.4.2"
}
}
\ No newline at end of file
diff --git a/packages/widget/src/pow-captcha.ts b/packages/widget/src/captcha.ts
similarity index 57%
rename from packages/widget/src/pow-captcha.ts
rename to packages/widget/src/captcha.ts
index d441202..3dc0565 100644
--- a/packages/widget/src/pow-captcha.ts
+++ b/packages/widget/src/captcha.ts
@@ -1,13 +1,15 @@
import { LitElement, html, css, isServer, type PropertyValues } from 'lit';
import { customElement, property, state } from 'lit/decorators.js';
-import { type ChallengeSolveRequest, type SolutionMessage, WorkerMessageType, type WorkerRequest, WorkerResponseType } from './types/worker';
-import { type Challenge, ChallengeStrategy } from '@impost/lib';
+import { type Challenge } from '@impost/lib';
import { get_wasm_module } from '@impost/lib/solver';
+import * as Comlink from 'comlink';
-import ChallengeWorker from './solver-worker?worker&inline';
+import SolverWorker from './solver-worker?worker&inline';
-@customElement('pow-captcha')
-export class PowCaptcha extends LitElement {
+type SolverWorkerAPI = Comlink.Remote;
+
+@customElement('impost-captcha')
+export class ImpostCaptcha extends LitElement {
static override styles = css`
:host {
display: block;
@@ -63,13 +65,13 @@ export class PowCaptcha extends LitElement {
.impost-footer div a:hover {
text-decoration: none;
}
- .hidden {
- display: none;
- }
`;
+ /// ================================================
+ /// Configuration
+ /// ================================================
+
- // one of: "load", "focus", "submit", "off"
@property({ type: String })
auto: "onload" | "onfocus" | "onsubmit" | "off" = "off";
@@ -79,24 +81,28 @@ export class PowCaptcha extends LitElement {
@property({ type: String })
challengejson: string = '';
+ @property({ type: Boolean })
+ showHashrate: boolean = false;
+
+ /// ================================================
+ /// Internals
+ /// ================================================
+
// needed to allow for multiple widgets on the same page if you wanted to
// do that for some reason
- uid: string = Math.floor(Math.random() * 100000).toString();
+ private uid: string = Math.floor(Math.random() * 100000).toString();
+
+ private _internals: ElementInternals | null = null;
+ static formAssociated = true;
@state()
- private solution: string = '';
-
- @state()
- private errorMessage: string = '';
+ private solution: string | null = null;
@state()
private challengeData: Challenge | null = null;
@state()
- private solved: boolean = false;
-
- @state()
- private isSolving: boolean = false;
+ private status: 'unsolved' | 'solving' | 'solved' | 'error' = 'unsolved';
@state()
private disabled: boolean = true;
@@ -104,18 +110,23 @@ export class PowCaptcha extends LitElement {
@state()
private hashRate: number = 0;
+
// stores the nonce and solution atomics
private sab: SharedArrayBuffer = new SharedArrayBuffer(8);
- private solverWorkers: Worker[] | null = null;
+ private solverWorkers: SolverWorkerAPI[] | null = null;
+ private nativeWorkers: Worker[] | null = null;
private solveStartTime: number | null = null;
private hashRateInterval: number | null = null;
override connectedCallback() {
super.connectedCallback();
+ this._internals = this.attachInternals();
this.fetchChallenge();
+ console.log(this._internals.form);
+
this.initWorkers();
switch (this.auto) {
@@ -127,7 +138,23 @@ export class PowCaptcha extends LitElement {
break;
case 'onsubmit':
if (this.parentElement?.nodeName === 'FORM') {
- this.parentElement.addEventListener('submit', () => this.solveChallenge());
+ this.parentElement.addEventListener('submit', async (ev) => {
+ if (this.status === 'solved') {
+ return;
+ }
+
+ ev.preventDefault();
+
+ await this.solveChallenge();
+
+ const form = this.parentElement as HTMLFormElement;
+
+ if (form.requestSubmit) {
+ form.requestSubmit();
+ } else {
+ form.submit();
+ }
+ });
}
break;
}
@@ -146,9 +173,10 @@ export class PowCaptcha extends LitElement {
this.hashRateInterval = null;
}
- for (const worker of this.solverWorkers || []) {
+ for (const worker of this.nativeWorkers || []) {
worker.terminate();
this.solverWorkers = null;
+ this.nativeWorkers = null;
}
}
@@ -157,7 +185,6 @@ export class PowCaptcha extends LitElement {
}
async fetchChallenge() {
- this.errorMessage = '';
if (this.challengeData !== null) {
return;
}
@@ -168,6 +195,7 @@ export class PowCaptcha extends LitElement {
return;
}
+ // challenge data must be provided by the user when using SSR
if (isServer) {
return;
}
@@ -179,16 +207,21 @@ export class PowCaptcha extends LitElement {
})
.catch(error => {
console.error('Error fetching challenge:', error);
- this.errorMessage = 'Failed to fetch challenge. Please try again.';
+ this.status = 'error';
});
}
async initWorkers() {
this.solverWorkers = [];
+ this.nativeWorkers = [];
const num_workers = navigator.hardwareConcurrency;
for (let i = 0; i < num_workers; i++) {
- this.solverWorkers.push(new ChallengeWorker());
+ const nativeWorker = new SolverWorker();
+ const comlinkWorker = Comlink.wrap(nativeWorker);
+
+ this.nativeWorkers.push(nativeWorker);
+ this.solverWorkers.push(comlinkWorker);
}
const atomics_view = new Int32Array(this.sab);
@@ -198,106 +231,53 @@ export class PowCaptcha extends LitElement {
let wasm_module = await get_wasm_module();
let worker_promises: Promise[] = [];
for (let i = 0; i < this.solverWorkers.length; i++) {
- console.log('Worker', i);
- const worker = this.solverWorkers[i]!;
-
- worker_promises.push(new Promise((resolve, reject) => {
- const message_handler = (event: MessageEvent) => {
- console.log('Worker', i, 'got message', event.data);
-
- if (event.data.type === WorkerResponseType.Error) {
- console.error("Worker error:", event.data.error);
- reject(event.data.error);
- }
-
- if (event.data.type === WorkerResponseType.InitOk) {
- resolve();
- }
-
- reject(new Error("Unexpected message from worker"));
- };
-
- const error_handler = (error: ErrorEvent) => {
- console.error("Worker error:", error);
- reject(error);
- };
-
- worker.addEventListener('message', message_handler);
- worker.addEventListener('error', error_handler);
-
- worker.postMessage({
- type: WorkerMessageType.Init,
- module: wasm_module,
- sab: this.sab,
- } as WorkerRequest);
- }));
+ const solver = this.solverWorkers[i]!;
+ worker_promises.push(solver.init(wasm_module, this.sab)); // Direct call to exposed `init` method
}
const timeoutMs = 10 * 1000;
let timeout: number;
const timeoutPromise = new Promise((_, reject) => {
timeout = setTimeout(() => {
- this.errorMessage = 'Failed to initialize workers in time. Please refresh the page.';
- reject(new Error(`Function timed out after ${timeoutMs}ms`));
+ reject(new Error(`Function timeout after ${timeoutMs}ms`));
}, timeoutMs);
});
await Promise.race([
- Promise.allSettled(worker_promises).then(() => {
+ Promise.allSettled(worker_promises).then(results => {
+ const failedInits = results.filter(r => r.status === 'rejected');
+ if (failedInits.length > 0) {
+ console.error('Some workers failed to initialize:', failedInits);
+ // we might want to collect all errors, and if every
+ // worker fails, we can throw, but carry on if only some
+ // fail. For now, we'll just throw if any fail.
+
+ throw new Error("One or more workers failed to initialize.");
+ }
+
console.log('All workers initialized');
+ return;
}),
timeoutPromise,
]).then(() => {
clearTimeout(timeout);
- });
- }
-
- async issueChallengeToWorker(worker: Worker, request: ChallengeSolveRequest): Promise {
- return new Promise((resolve, reject) => {
- const message_handler = (event: MessageEvent) => {
- worker.removeEventListener('message', message_handler);
- worker.removeEventListener('error', error_handler);
-
- resolve(event.data);
- };
-
- const error_handler = (error: ErrorEvent) => {
- worker.removeEventListener('error', error_handler);
- worker.removeEventListener('message', message_handler);
- console.error("Worker error:", error);
-
- reject(error);
- };
-
- worker.addEventListener('message', message_handler);
- worker.addEventListener('error', error_handler);
-
- switch (request.strategy) {
- case ChallengeStrategy.LeadingZeroes:
- worker.postMessage({
- strategy: ChallengeStrategy.LeadingZeroes,
- salt: request.salt,
- difficulty: request.difficulty,
- } as WorkerRequest);
- break;
- case ChallengeStrategy.TargetNumber:
- worker.postMessage({
- strategy: ChallengeStrategy.TargetNumber,
- target: request.target,
- salt: request.salt,
- } as WorkerRequest);
- break;
- }
+ }).catch(error => {
+ clearTimeout(timeout);
+ console.error("Worker initialization failed:", error);
+ this.status = 'error';
+ throw error;
});
}
async solveChallenge() {
if (!this.challengeData || this.solverWorkers === null) {
- this.errorMessage = 'Captcha is not ready. Please wait or refresh.';
+ // in all normal cases, this should be impossible
+ this.status = 'error';
return;
}
- if (this.solution !== '') {
+ if (this.solution !== null || this.status !== 'unsolved') {
+ // do not solve twice
return;
}
@@ -306,45 +286,23 @@ export class PowCaptcha extends LitElement {
const nonce = this.getCurrentWorkingNonce();
this.hashRate = (nonce / ((performance.now() - this.solveStartTime!) / 1000));
+ console.log(this.hashRate);
}, 250);
this.dispatchEvent(new CustomEvent('impost:solve', {
- detail: {
- solution: this.solution,
- },
+ detail: { challenge: this.challengeData, }, // empty solution
bubbles: true,
composed: true,
- }))
+ }));
- console.log(this.challengeData);
-
- this.isSolving = true;
- this.errorMessage = '';
- this.solution = '';
+ this.status = 'solving';
+ this.solution = null;
const atomics_view = new Int32Array(this.sab);
+ // reset atomics
Atomics.store(atomics_view, 0, 0);
Atomics.store(atomics_view, 1, -1);
- let request: ChallengeSolveRequest;
-
- switch (this.challengeData.strategy) {
- case ChallengeStrategy.LeadingZeroes:
- request = {
- strategy: ChallengeStrategy.LeadingZeroes,
- salt: this.challengeData.salt,
- difficulty: this.challengeData.difficulty,
- };
- break;
- case ChallengeStrategy.TargetNumber:
- request = {
- strategy: ChallengeStrategy.TargetNumber,
- target: this.challengeData.target,
- salt: this.challengeData.salt,
- };
- break;
- }
-
console.log('Sending challenge to workers...');
// TODO: the first response is not always the solution, due to cmpxchg
// blocking, some workers may block on the read, and as soon as they
@@ -352,40 +310,42 @@ export class PowCaptcha extends LitElement {
//
// We need to do a better job of tracking solvers, so if one worker
// errors out, we only error out if all workers have errored out.
- let worker_promises: Promise[] = [];
- for (let worker of this.solverWorkers) {
- // dispatch to all workers, func is async so it will not block
- worker_promises.push(this.issueChallengeToWorker(worker, request));
+ let worker_promises: Promise[] = [];
+ for (let solver of this.solverWorkers) {
+ worker_promises.push(solver.solve_challenge(this.challengeData as Challenge));
}
- let solution = await Promise.race(worker_promises);
+ try {
+ await Promise.race(worker_promises);
- if (solution.type === WorkerResponseType.Error) {
- this.errorMessage = solution.error;
- return;
+ // The true solution is stored in the SharedArrayBuffer.
+ this.solution = String(Atomics.load(atomics_view, 1));
+ this.status = 'solved';
+ } catch (error: any) {
+ console.error("Captcha solving failed:", error);
+ this.status = 'error';
+ } finally {
+ if (this.hashRateInterval !== null) {
+ clearInterval(this.hashRateInterval);
+ this.hashRateInterval = null;
+ }
}
- if (solution.type !== WorkerResponseType.Solution) {
- this.errorMessage = "Something went wrong, please try again later.";
- return;
- }
-
- this.solution = Atomics.load(atomics_view, 1).toString();
- this.isSolving = false;
- this.solved = true;
-
- if (this.hashRateInterval !== null) {
- clearInterval(this.hashRateInterval);
- this.hashRateInterval = null;
- }
-
- this.dispatchEvent(new CustomEvent('impost:solved', {
- detail: {
+ if (this.status === 'solved') {
+ this._internals!.setFormValue(JSON.stringify({
+ challenge: this.challengeData.salt,
solution: this.solution,
- },
- bubbles: true,
- composed: true,
- }))
+ }));
+
+ this.dispatchEvent(new CustomEvent('impost:solved', {
+ detail: {
+ challenge: this.challengeData,
+ solution: this.solution,
+ },
+ bubbles: true,
+ composed: true,
+ }));
+ }
}
solvePreventDefault(event: Event) {
@@ -400,12 +360,6 @@ export class PowCaptcha extends LitElement {
this.challengejson = '';
}
- if (this.errorMessage) {
- return html`
- ${this.errorMessage}
- `;
- }
-
if (this.challengeData === null) {
return html`
Loading captcha challenge...
@@ -416,9 +370,9 @@ export class PowCaptcha extends LitElement {
-
${this.solved ? 'Verified' : html`${this.isSolving ? 'Verifying...' : 'I am not a robot'}`}
+
${this.status === 'error' ? 'Something went wrong' : this.status === 'solved' ? 'Verified' : html`${this.status === 'solving' ? 'Verifying...' : 'I am not a robot'}`}