diff --git a/.gitignore b/.gitignore index 2746628..c77fc9b 100644 --- a/.gitignore +++ b/.gitignore @@ -4,7 +4,6 @@ dist .output .vercel .netlify -netlify .vinxi # Environment @@ -27,3 +26,7 @@ gitignore # System Files .DS_Store Thumbs.db + +# wrangler files +.wrangler +.dev.vars diff --git a/app.config.ts b/app.config.ts index 9f495a7..a8d2783 100644 --- a/app.config.ts +++ b/app.config.ts @@ -5,7 +5,10 @@ import wasmpack from "vite-plugin-wasm-pack"; export default defineConfig({ server: { - preset: "vercel", + preset: "cloudflare-pages", + rollupConfig: { + external: ["node:async_hooks"] + } }, ssr: true, vite: { diff --git a/package.json b/package.json index cd94b9d..bf85232 100644 --- a/package.json +++ b/package.json @@ -5,7 +5,8 @@ "dev": "vinxi dev", "build": "vinxi build", "start": "vinxi start", - "presets": "node updatePresets" + "preview": "pnpm run build && npx wrangler pages dev", + "deploy": "pnpm run build && wrangler pages deploy" }, "dependencies": { "@codemirror/commands": "^6.6.0", @@ -29,9 +30,11 @@ "vinxi": "^0.3.11" }, "devDependencies": { + "@cloudflare/workers-types": "^4.20241011.0", "@unocss/transformer-variant-group": "^0.59.4", "prettier": "^3.3.3", - "vite-plugin-wasm-pack": "^0.1.12" + "vite-plugin-wasm-pack": "^0.1.12", + "wrangler": "^3.80.4" }, "pnpm": { "overrides": { diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 2805618..64b946d 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -70,6 +70,9 @@ importers: specifier: ^0.3.11 version: 0.3.11(@opentelemetry/api@1.8.0)(@types/node@20.12.8)(ioredis@5.4.1)(terser@5.31.0) devDependencies: + '@cloudflare/workers-types': + specifier: ^4.20241011.0 + version: 4.20241011.0 '@unocss/transformer-variant-group': specifier: ^0.59.4 version: 0.59.4 @@ -79,6 +82,9 @@ importers: vite-plugin-wasm-pack: specifier: ^0.1.12 version: 0.1.12 + wrangler: + specifier: ^3.80.4 + version: 3.80.4(@cloudflare/workers-types@4.20241011.0) packages: @@ -249,6 +255,47 @@ packages: resolution: {integrity: sha512-EeEjMobfuJrwoctj7FA1y1KEbM0+Q1xSjobIEyie9k4haVEBB7vkDvsasw1pM3rO39mL2akxIAzLMUAtrMHZhA==} engines: {node: '>=16.13'} + '@cloudflare/kv-asset-handler@0.3.4': + resolution: {integrity: sha512-YLPHc8yASwjNkmcDMQMY35yiWjoKAKnhUbPRszBRS0YgH+IXtsMp61j+yTcnCE3oO2DgP0U3iejLC8FTtKDC8Q==} + engines: {node: '>=16.13'} + + '@cloudflare/workerd-darwin-64@1.20241004.0': + resolution: {integrity: sha512-c2afR486NXDRcPm7RaTSRDnffFklPCXde/IeNVhEhBJ8O+pQhBOdDcGIy8zXPwMu0CYga0iHNZmpbsl+ZcHttA==} + engines: {node: '>=16'} + cpu: [x64] + os: [darwin] + + '@cloudflare/workerd-darwin-arm64@1.20241004.0': + resolution: {integrity: sha512-siD9fexv5lr2IpBczWV7OPgJvHj8/fJUrRAYCMcBURkfiwssK91coQeZlN1NdQ85aYELVgxDFoG+p86OS+ZzLw==} + engines: {node: '>=16'} + cpu: [arm64] + os: [darwin] + + '@cloudflare/workerd-linux-64@1.20241004.0': + resolution: {integrity: sha512-EtKGXO5fzRgX6UhDDLhjjEsB1QtliHb12zavZ/S0C8hKPz76II7MQ3Lls9kfB62fbdMP8L6vcqWPObEUcw6GSw==} + engines: {node: '>=16'} + cpu: [x64] + os: [linux] + + '@cloudflare/workerd-linux-arm64@1.20241004.0': + resolution: {integrity: sha512-XO7VBE1YaFf/o9tKO1PqDqaxkU2eAR2DLX7R0+R8p+q92sUDXyoxo48T3yJDfxWndnKJ6hSJfvKanw3Mq9Tisw==} + engines: {node: '>=16'} + cpu: [arm64] + os: [linux] + + '@cloudflare/workerd-windows-64@1.20241004.0': + resolution: {integrity: sha512-o+TmCYGq58jNUDbG73xOvd648XvJ2TicI++2BBoySklJXG6f4But5AwA8TxQgmeujR3vpBjPZKexEzcZSUOTtA==} + engines: {node: '>=16'} + cpu: [x64] + os: [win32] + + '@cloudflare/workers-shared@0.6.0': + resolution: {integrity: sha512-rfUCvb3hx4AsvdUZsxgk9lmgEnQehqV3jdtXLP/Xr0+P56n11T/0nXNMzmn7Nnv+IJFOV6X9NmFhuMz4sBPw7w==} + engines: {node: '>=16.7.0'} + + '@cloudflare/workers-types@4.20241011.0': + resolution: {integrity: sha512-emwBnuFB/2lS1z6NXAeBqrSL8Xwnr7YpgdLuchOmgu/igqBsLLNPBb4Qmgh3neFWUe9wbzQyx030836YF3c3Xw==} + '@codemirror/autocomplete@6.16.3': resolution: {integrity: sha512-Vl/tIeRVVUCRDuOG48lttBasNQu8usGgXQawBXI7WJAiUDSFOfzflmEsZFZo48mAvAaa4FZ/4/yLLxFtdJaKYA==} peerDependencies: @@ -291,18 +338,38 @@ packages: peerDependencies: solid-js: ^1.8 + '@cspotcode/source-map-support@0.8.1': + resolution: {integrity: sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==} + engines: {node: '>=12'} + '@deno/shim-deno-test@0.5.0': resolution: {integrity: sha512-4nMhecpGlPi0cSzT67L+Tm+GOJqvuk8gqHBziqcUQOarnuIax1z96/gJHCSIz2Z0zhxE6Rzwb3IZXPtFh51j+w==} '@deno/shim-deno@0.19.1': resolution: {integrity: sha512-8hYIpmDqpG76sn+UY1853RCi+CI7ZWz9tt37nfyDL8rwr6xbW0+GHUwCLcsGbh1uMIKURuJy6xtrIcnW+a0duA==} + '@esbuild-plugins/node-globals-polyfill@0.2.3': + resolution: {integrity: sha512-r3MIryXDeXDOZh7ih1l/yE9ZLORCd5e8vWg02azWRGj5SPTuoh69A2AIyn0Z31V/kHBfZ4HgWJ+OK3GTTwLmnw==} + peerDependencies: + esbuild: '*' + + '@esbuild-plugins/node-modules-polyfill@0.2.2': + resolution: {integrity: sha512-LXV7QsWJxRuMYvKbiznh+U1ilIop3g2TeKRzUxOG5X3YITc8JyyTa90BmLwqqv0YnX4v32CSlG+vsziZp9dMvA==} + peerDependencies: + esbuild: '*' + '@esbuild/aix-ppc64@0.20.2': resolution: {integrity: sha512-D+EBOJHXdNZcLJRBkhENNG8Wji2kgc9AZ9KiPr1JuZjsNtyHzrsfLRrY0tk2H2aoFu6RANO1y1iPPUCDYWkb5g==} engines: {node: '>=12'} cpu: [ppc64] os: [aix] + '@esbuild/android-arm64@0.17.19': + resolution: {integrity: sha512-KBMWvEZooR7+kzY0BtbTQn0OAYY7CsiydT63pVEaPtVYF0hXbUaOyZog37DKxK7NF3XacBJOpYT4adIJh+avxA==} + engines: {node: '>=12'} + cpu: [arm64] + os: [android] + '@esbuild/android-arm64@0.18.20': resolution: {integrity: sha512-Nz4rJcchGDtENV0eMKUNa6L12zz2zBDXuhj/Vjh18zGqB44Bi7MBMSXjgunJgjRhCmKOjnPuZp4Mb6OKqtMHLQ==} engines: {node: '>=12'} @@ -315,6 +382,12 @@ packages: cpu: [arm64] os: [android] + '@esbuild/android-arm@0.17.19': + resolution: {integrity: sha512-rIKddzqhmav7MSmoFCmDIb6e2W57geRsM94gV2l38fzhXMwq7hZoClug9USI2pFRGL06f4IOPHHpFNOkWieR8A==} + engines: {node: '>=12'} + cpu: [arm] + os: [android] + '@esbuild/android-arm@0.18.20': resolution: {integrity: sha512-fyi7TDI/ijKKNZTUJAQqiG5T7YjJXgnzkURqmGj13C6dCqckZBLdl4h7bkhHt/t0WP+zO9/zwroDvANaOqO5Sw==} engines: {node: '>=12'} @@ -327,6 +400,12 @@ packages: cpu: [arm] os: [android] + '@esbuild/android-x64@0.17.19': + resolution: {integrity: sha512-uUTTc4xGNDT7YSArp/zbtmbhO0uEEK9/ETW29Wk1thYUJBz3IVnvgEiEwEa9IeLyvnpKrWK64Utw2bgUmDveww==} + engines: {node: '>=12'} + cpu: [x64] + os: [android] + '@esbuild/android-x64@0.18.20': resolution: {integrity: sha512-8GDdlePJA8D6zlZYJV/jnrRAi6rOiNaCC/JclcXpB+KIuvfBN4owLtgzY2bsxnx666XjJx2kDPUmnTtR8qKQUg==} engines: {node: '>=12'} @@ -339,6 +418,12 @@ packages: cpu: [x64] os: [android] + '@esbuild/darwin-arm64@0.17.19': + resolution: {integrity: sha512-80wEoCfF/hFKM6WE1FyBHc9SfUblloAWx6FJkFWTWiCoht9Mc0ARGEM47e67W9rI09YoUxJL68WHfDRYEAvOhg==} + engines: {node: '>=12'} + cpu: [arm64] + os: [darwin] + '@esbuild/darwin-arm64@0.18.20': resolution: {integrity: sha512-bxRHW5kHU38zS2lPTPOyuyTm+S+eobPUnTNkdJEfAddYgEcll4xkT8DB9d2008DtTbl7uJag2HuE5NZAZgnNEA==} engines: {node: '>=12'} @@ -351,6 +436,12 @@ packages: cpu: [arm64] os: [darwin] + '@esbuild/darwin-x64@0.17.19': + resolution: {integrity: sha512-IJM4JJsLhRYr9xdtLytPLSH9k/oxR3boaUIYiHkAawtwNOXKE8KoU8tMvryogdcT8AU+Bflmh81Xn6Q0vTZbQw==} + engines: {node: '>=12'} + cpu: [x64] + os: [darwin] + '@esbuild/darwin-x64@0.18.20': resolution: {integrity: sha512-pc5gxlMDxzm513qPGbCbDukOdsGtKhfxD1zJKXjCCcU7ju50O7MeAZ8c4krSJcOIJGFR+qx21yMMVYwiQvyTyQ==} engines: {node: '>=12'} @@ -363,6 +454,12 @@ packages: cpu: [x64] os: [darwin] + '@esbuild/freebsd-arm64@0.17.19': + resolution: {integrity: sha512-pBwbc7DufluUeGdjSU5Si+P3SoMF5DQ/F/UmTSb8HXO80ZEAJmrykPyzo1IfNbAoaqw48YRpv8shwd1NoI0jcQ==} + engines: {node: '>=12'} + cpu: [arm64] + os: [freebsd] + '@esbuild/freebsd-arm64@0.18.20': resolution: {integrity: sha512-yqDQHy4QHevpMAaxhhIwYPMv1NECwOvIpGCZkECn8w2WFHXjEwrBn3CeNIYsibZ/iZEUemj++M26W3cNR5h+Tw==} engines: {node: '>=12'} @@ -375,6 +472,12 @@ packages: cpu: [arm64] os: [freebsd] + '@esbuild/freebsd-x64@0.17.19': + resolution: {integrity: sha512-4lu+n8Wk0XlajEhbEffdy2xy53dpR06SlzvhGByyg36qJw6Kpfk7cp45DR/62aPH9mtJRmIyrXAS5UWBrJT6TQ==} + engines: {node: '>=12'} + cpu: [x64] + os: [freebsd] + '@esbuild/freebsd-x64@0.18.20': resolution: {integrity: sha512-tgWRPPuQsd3RmBZwarGVHZQvtzfEBOreNuxEMKFcd5DaDn2PbBxfwLcj4+aenoh7ctXcbXmOQIn8HI6mCSw5MQ==} engines: {node: '>=12'} @@ -387,6 +490,12 @@ packages: cpu: [x64] os: [freebsd] + '@esbuild/linux-arm64@0.17.19': + resolution: {integrity: sha512-ct1Tg3WGwd3P+oZYqic+YZF4snNl2bsnMKRkb3ozHmnM0dGWuxcPTTntAF6bOP0Sp4x0PjSF+4uHQ1xvxfRKqg==} + engines: {node: '>=12'} + cpu: [arm64] + os: [linux] + '@esbuild/linux-arm64@0.18.20': resolution: {integrity: sha512-2YbscF+UL7SQAVIpnWvYwM+3LskyDmPhe31pE7/aoTMFKKzIc9lLbyGUpmmb8a8AixOL61sQ/mFh3jEjHYFvdA==} engines: {node: '>=12'} @@ -399,6 +508,12 @@ packages: cpu: [arm64] os: [linux] + '@esbuild/linux-arm@0.17.19': + resolution: {integrity: sha512-cdmT3KxjlOQ/gZ2cjfrQOtmhG4HJs6hhvm3mWSRDPtZ/lP5oe8FWceS10JaSJC13GBd4eH/haHnqf7hhGNLerA==} + engines: {node: '>=12'} + cpu: [arm] + os: [linux] + '@esbuild/linux-arm@0.18.20': resolution: {integrity: sha512-/5bHkMWnq1EgKr1V+Ybz3s1hWXok7mDFUMQ4cG10AfW3wL02PSZi5kFpYKrptDsgb2WAJIvRcDm+qIvXf/apvg==} engines: {node: '>=12'} @@ -411,6 +526,12 @@ packages: cpu: [arm] os: [linux] + '@esbuild/linux-ia32@0.17.19': + resolution: {integrity: sha512-w4IRhSy1VbsNxHRQpeGCHEmibqdTUx61Vc38APcsRbuVgK0OPEnQ0YD39Brymn96mOx48Y2laBQGqgZ0j9w6SQ==} + engines: {node: '>=12'} + cpu: [ia32] + os: [linux] + '@esbuild/linux-ia32@0.18.20': resolution: {integrity: sha512-P4etWwq6IsReT0E1KHU40bOnzMHoH73aXp96Fs8TIT6z9Hu8G6+0SHSw9i2isWrD2nbx2qo5yUqACgdfVGx7TA==} engines: {node: '>=12'} @@ -423,6 +544,12 @@ packages: cpu: [ia32] os: [linux] + '@esbuild/linux-loong64@0.17.19': + resolution: {integrity: sha512-2iAngUbBPMq439a+z//gE+9WBldoMp1s5GWsUSgqHLzLJ9WoZLZhpwWuym0u0u/4XmZ3gpHmzV84PonE+9IIdQ==} + engines: {node: '>=12'} + cpu: [loong64] + os: [linux] + '@esbuild/linux-loong64@0.18.20': resolution: {integrity: sha512-nXW8nqBTrOpDLPgPY9uV+/1DjxoQ7DoB2N8eocyq8I9XuqJ7BiAMDMf9n1xZM9TgW0J8zrquIb/A7s3BJv7rjg==} engines: {node: '>=12'} @@ -435,6 +562,12 @@ packages: cpu: [loong64] os: [linux] + '@esbuild/linux-mips64el@0.17.19': + resolution: {integrity: sha512-LKJltc4LVdMKHsrFe4MGNPp0hqDFA1Wpt3jE1gEyM3nKUvOiO//9PheZZHfYRfYl6AwdTH4aTcXSqBerX0ml4A==} + engines: {node: '>=12'} + cpu: [mips64el] + os: [linux] + '@esbuild/linux-mips64el@0.18.20': resolution: {integrity: sha512-d5NeaXZcHp8PzYy5VnXV3VSd2D328Zb+9dEq5HE6bw6+N86JVPExrA6O68OPwobntbNJ0pzCpUFZTo3w0GyetQ==} engines: {node: '>=12'} @@ -447,6 +580,12 @@ packages: cpu: [mips64el] os: [linux] + '@esbuild/linux-ppc64@0.17.19': + resolution: {integrity: sha512-/c/DGybs95WXNS8y3Ti/ytqETiW7EU44MEKuCAcpPto3YjQbyK3IQVKfF6nbghD7EcLUGl0NbiL5Rt5DMhn5tg==} + engines: {node: '>=12'} + cpu: [ppc64] + os: [linux] + '@esbuild/linux-ppc64@0.18.20': resolution: {integrity: sha512-WHPyeScRNcmANnLQkq6AfyXRFr5D6N2sKgkFo2FqguP44Nw2eyDlbTdZwd9GYk98DZG9QItIiTlFLHJHjxP3FA==} engines: {node: '>=12'} @@ -459,6 +598,12 @@ packages: cpu: [ppc64] os: [linux] + '@esbuild/linux-riscv64@0.17.19': + resolution: {integrity: sha512-FC3nUAWhvFoutlhAkgHf8f5HwFWUL6bYdvLc/TTuxKlvLi3+pPzdZiFKSWz/PF30TB1K19SuCxDTI5KcqASJqA==} + engines: {node: '>=12'} + cpu: [riscv64] + os: [linux] + '@esbuild/linux-riscv64@0.18.20': resolution: {integrity: sha512-WSxo6h5ecI5XH34KC7w5veNnKkju3zBRLEQNY7mv5mtBmrP/MjNBCAlsM2u5hDBlS3NGcTQpoBvRzqBcRtpq1A==} engines: {node: '>=12'} @@ -471,6 +616,12 @@ packages: cpu: [riscv64] os: [linux] + '@esbuild/linux-s390x@0.17.19': + resolution: {integrity: sha512-IbFsFbxMWLuKEbH+7sTkKzL6NJmG2vRyy6K7JJo55w+8xDk7RElYn6xvXtDW8HCfoKBFK69f3pgBJSUSQPr+4Q==} + engines: {node: '>=12'} + cpu: [s390x] + os: [linux] + '@esbuild/linux-s390x@0.18.20': resolution: {integrity: sha512-+8231GMs3mAEth6Ja1iK0a1sQ3ohfcpzpRLH8uuc5/KVDFneH6jtAJLFGafpzpMRO6DzJ6AvXKze9LfFMrIHVQ==} engines: {node: '>=12'} @@ -483,6 +634,12 @@ packages: cpu: [s390x] os: [linux] + '@esbuild/linux-x64@0.17.19': + resolution: {integrity: sha512-68ngA9lg2H6zkZcyp22tsVt38mlhWde8l3eJLWkyLrp4HwMUr3c1s/M2t7+kHIhvMjglIBrFpncX1SzMckomGw==} + engines: {node: '>=12'} + cpu: [x64] + os: [linux] + '@esbuild/linux-x64@0.18.20': resolution: {integrity: sha512-UYqiqemphJcNsFEskc73jQ7B9jgwjWrSayxawS6UVFZGWrAAtkzjxSqnoclCXxWtfwLdzU+vTpcNYhpn43uP1w==} engines: {node: '>=12'} @@ -495,6 +652,12 @@ packages: cpu: [x64] os: [linux] + '@esbuild/netbsd-x64@0.17.19': + resolution: {integrity: sha512-CwFq42rXCR8TYIjIfpXCbRX0rp1jo6cPIUPSaWwzbVI4aOfX96OXY8M6KNmtPcg7QjYeDmN+DD0Wp3LaBOLf4Q==} + engines: {node: '>=12'} + cpu: [x64] + os: [netbsd] + '@esbuild/netbsd-x64@0.18.20': resolution: {integrity: sha512-iO1c++VP6xUBUmltHZoMtCUdPlnPGdBom6IrO4gyKPFFVBKioIImVooR5I83nTew5UOYrk3gIJhbZh8X44y06A==} engines: {node: '>=12'} @@ -507,6 +670,12 @@ packages: cpu: [x64] os: [netbsd] + '@esbuild/openbsd-x64@0.17.19': + resolution: {integrity: sha512-cnq5brJYrSZ2CF6c35eCmviIN3k3RczmHz8eYaVlNasVqsNY+JKohZU5MKmaOI+KkllCdzOKKdPs762VCPC20g==} + engines: {node: '>=12'} + cpu: [x64] + os: [openbsd] + '@esbuild/openbsd-x64@0.18.20': resolution: {integrity: sha512-e5e4YSsuQfX4cxcygw/UCPIEP6wbIL+se3sxPdCiMbFLBWu0eiZOJ7WoD+ptCLrmjZBK1Wk7I6D/I3NglUGOxg==} engines: {node: '>=12'} @@ -519,6 +688,12 @@ packages: cpu: [x64] os: [openbsd] + '@esbuild/sunos-x64@0.17.19': + resolution: {integrity: sha512-vCRT7yP3zX+bKWFeP/zdS6SqdWB8OIpaRq/mbXQxTGHnIxspRtigpkUcDMlSCOejlHowLqII7K2JKevwyRP2rg==} + engines: {node: '>=12'} + cpu: [x64] + os: [sunos] + '@esbuild/sunos-x64@0.18.20': resolution: {integrity: sha512-kDbFRFp0YpTQVVrqUd5FTYmWo45zGaXe0X8E1G/LKFC0v8x0vWrhOWSLITcCn63lmZIxfOMXtCfti/RxN/0wnQ==} engines: {node: '>=12'} @@ -531,6 +706,12 @@ packages: cpu: [x64] os: [sunos] + '@esbuild/win32-arm64@0.17.19': + resolution: {integrity: sha512-yYx+8jwowUstVdorcMdNlzklLYhPxjniHWFKgRqH7IFlUEa0Umu3KuYplf1HUZZ422e3NU9F4LGb+4O0Kdcaag==} + engines: {node: '>=12'} + cpu: [arm64] + os: [win32] + '@esbuild/win32-arm64@0.18.20': resolution: {integrity: sha512-ddYFR6ItYgoaq4v4JmQQaAI5s7npztfV4Ag6NrhiaW0RrnOXqBkgwZLofVTlq1daVTQNhtI5oieTvkRPfZrePg==} engines: {node: '>=12'} @@ -543,6 +724,12 @@ packages: cpu: [arm64] os: [win32] + '@esbuild/win32-ia32@0.17.19': + resolution: {integrity: sha512-eggDKanJszUtCdlVs0RB+h35wNlb5v4TWEkq4vZcmVt5u/HiDZrTXe2bWFQUez3RgNHwx/x4sk5++4NSSicKkw==} + engines: {node: '>=12'} + cpu: [ia32] + os: [win32] + '@esbuild/win32-ia32@0.18.20': resolution: {integrity: sha512-Wv7QBi3ID/rROT08SABTS7eV4hX26sVduqDOTe1MvGMjNd3EjOz4b7zeexIR62GTIEKrfJXKL9LFxTYgkyeu7g==} engines: {node: '>=12'} @@ -555,6 +742,12 @@ packages: cpu: [ia32] os: [win32] + '@esbuild/win32-x64@0.17.19': + resolution: {integrity: sha512-lAhycmKnVOuRYNtRtatQR1LPQf2oYCkRGkSFnseDAKPl8lu5SOsK/e1sXe5a0Pc5kHIHe6P2I/ilntNv2xf3cA==} + engines: {node: '>=12'} + cpu: [x64] + os: [win32] + '@esbuild/win32-x64@0.18.20': resolution: {integrity: sha512-kTdfRcSiDfQca/y9QIkng02avJ+NCaQvrMejlsB3RRv5sE9rRoeBPISaZpKxHELzRxZyLvNts1P27W3wV+8geQ==} engines: {node: '>=12'} @@ -620,6 +813,9 @@ packages: '@jridgewell/trace-mapping@0.3.25': resolution: {integrity: sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==} + '@jridgewell/trace-mapping@0.3.9': + resolution: {integrity: sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==} + '@kobalte/core@0.13.4': resolution: {integrity: sha512-ElvazoxoQU/z5pQUdHtXAzjiZA60J+Fo36WgO+j8sMvycIGwrlv+Fdr+uXcLSm1onYOYoSG1+vumD3Ce5OYzzw==} peerDependencies: @@ -1112,6 +1308,9 @@ packages: '@types/micromatch@4.0.7': resolution: {integrity: sha512-C/FMQ8HJAZhTsDpl4wDKZdMeeW5USjgzOczUwTGbRc1ZopPgOhIEnxY2ZgUrsuyy4DwK1JVOJZKFakv3TbCKiA==} + '@types/node-forge@1.3.11': + resolution: {integrity: sha512-FQx220y22OKNTqaByeBGqHWYz4cl94tpcxeFdvBo3wjG6XPBuZ0BNgNZRV5J5TFmmcsJ4IzsLkmGRiQbnYsBEQ==} + '@types/node@20.12.8': resolution: {integrity: sha512-NU0rJLJnshZWdE/097cdCBbyW1h4hEg0xpovcoAQYHl8dnEyp/NAOiE45pvc+Bd1Dt+2r94v2eGFpQJ4R7g+2w==} @@ -1254,6 +1453,10 @@ packages: peerDependencies: acorn: '>=8.9.0' + acorn-walk@8.3.4: + resolution: {integrity: sha512-ueEepnujpqee2o5aIYnvHU6C0A42MNdsIDeqy5BydrkuC5R1ZuUFnm27EeFJGoEHJQgn3uleRvmTXaJgfXbt4g==} + engines: {node: '>=0.4.0'} + acorn@8.11.3: resolution: {integrity: sha512-Y9rRfJG5jcKOE0CLisYbojUjIrIEE7AGMzA/Sm4BslANhbS+cDMpgBdcPT91oJ7OuJ9hYJBx59RjbhxVnrF8Xg==} engines: {node: '>=0.4.0'} @@ -1312,6 +1515,9 @@ packages: argparse@2.0.1: resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==} + as-table@1.0.55: + resolution: {integrity: sha512-xvsWESUJn0JN421Xb9MQw6AsMHRCUknCe0Wjlxvjud80mU4E6hQf1A6NzQKcYNmYw62MfzEtXc+badstZP3JpQ==} + ast-types@0.16.1: resolution: {integrity: sha512-6t10qk83GOG8p0vKmaCr8eiilZwO171AvbROMtvvNiwrTly62t+7XkA8RdIIVbpMhCASAsxgAzdRSwh6nw/5Dg==} engines: {node: '>=4'} @@ -1359,6 +1565,9 @@ packages: bindings@1.5.0: resolution: {integrity: sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==} + blake3-wasm@2.1.5: + resolution: {integrity: sha512-F1+K8EbfOZE49dtoPtmxUQrpXaBIl3ICvasLh+nJta0xkz+9kF/7uet9fLnwKqhDrmj6g+6K3Tw9yQPUg2ka5g==} + boxen@7.1.1: resolution: {integrity: sha512-2hCgjEmP8YLWQ130n2FerGv7rYpfBmnmp9Uy2Le1vge6X3gZIfSmEzP5QTDElFxcvVcXlEn8Aq6MU/PZygIOog==} engines: {node: '>=14.16'} @@ -1414,6 +1623,9 @@ packages: caniuse-lite@1.0.30001615: resolution: {integrity: sha512-1IpazM5G3r38meiae0bHRnPhz+CBQ3ZLqbQMtrg+AsTPKAXgW38JNsXkyZ+v8waCsDmPq87lmfun5Q2AGysNEQ==} + capnp-ts@0.7.0: + resolution: {integrity: sha512-XKxXAC3HVPv7r674zP0VC3RTXz+/JKhfyw94ljvF80yynK6VkTnqE3jMuN8b3dUVmmc43TjyxjW4KTsmB3c86g==} + chalk@2.4.2: resolution: {integrity: sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==} engines: {node: '>=4'} @@ -1505,6 +1717,10 @@ packages: cookie-es@1.1.0: resolution: {integrity: sha512-L2rLOcK0wzWSfSDA33YR+PUHDG10a8px7rUHKWbGLP4YfbsMed2KFUw5fczvDPbT98DDe3LEzviswl810apTEw==} + cookie@0.7.2: + resolution: {integrity: sha512-yki5XnKuf750l50uGTllt6kKILY4nQ1eNIQatoXEByZ5dWgnKqbnqmTrBE5B4N7lrMJKQ2ytWMiTO2o0v6Ew/w==} + engines: {node: '>= 0.6'} + core-util-is@1.0.3: resolution: {integrity: sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==} @@ -1543,6 +1759,9 @@ packages: csstype@3.1.3: resolution: {integrity: sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==} + data-uri-to-buffer@2.0.2: + resolution: {integrity: sha512-ND9qDTLc6diwj+Xe5cdAgVTbLVdXbtxTJRXRhli8Mowuaan+0EJOtdqJ0QCHNSSPyoXGx9HX2/VMnKeC34AChA==} + dax-sh@0.39.2: resolution: {integrity: sha512-gpuGEkBQM+5y6p4cWaw9+ePy5TNon+fdwFVtTI8leU3UhwhsBfPewRxMXGuQNC+M2b/MDGMlfgpqynkcd0C3FQ==} @@ -1666,6 +1885,11 @@ packages: es-module-lexer@1.5.2: resolution: {integrity: sha512-l60ETUTmLqbVbVHv1J4/qj+M8nq7AwMzEcg3kmJDt9dCNrTk+yHcYFf/Kw75pMDwd9mPcIGCG5LcS20SxYRzFA==} + esbuild@0.17.19: + resolution: {integrity: sha512-XQ0jAPFkK/u3LcVRcvVHQcTIqD6E2H1fvZMA5dQPSOWb3suUbWbfbRf94pjc0bNzRYLfIrDRQXr7X+LHIm5oHw==} + engines: {node: '>=12'} + hasBin: true + esbuild@0.18.20: resolution: {integrity: sha512-ceqxoedUrcayh7Y7ZX6NdbbDzGROiyVBgC4PriJThBKSVPWnnFHZAkfI1lJT8QFkOwH4qOS2SJkS4wvpGl8BpA==} engines: {node: '>=12'} @@ -1687,6 +1911,10 @@ packages: resolution: {integrity: sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==} engines: {node: '>=0.8.0'} + escape-string-regexp@4.0.0: + resolution: {integrity: sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==} + engines: {node: '>=10'} + escape-string-regexp@5.0.0: resolution: {integrity: sha512-/veY75JbMK4j1yjvuUxuVsiS/hr/4iHs9FTT6cgTexxdE0Ly/glccBAkloH/DofkjRbZU3bnoj38mOmhkZ0lHw==} engines: {node: '>=12'} @@ -1696,6 +1924,9 @@ packages: engines: {node: '>=4'} hasBin: true + estree-walker@0.6.1: + resolution: {integrity: sha512-SqmZANLWS0mnatqbSfRP5g8OXZC12Fgg1IwNtLsyHDzJizORW4khDfjPqJZsemPWBB2uqykUah5YpQ6epsqC/w==} + estree-walker@2.0.2: resolution: {integrity: sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==} @@ -1729,6 +1960,10 @@ packages: resolution: {integrity: sha512-VyhnebXciFV2DESc+p6B+y0LjSm0krU4OgJN44qFAhBY0TJ+1V61tYD2+wHusZ6F9n5K+vl8k0sTy7PEfV4qpg==} engines: {node: '>=16.17'} + exit-hook@2.2.1: + resolution: {integrity: sha512-eNTPlAD67BmP31LDINZ3U7HSF8l57TxOY2PmBJ1shpCvpnxBF93mWCE8YHBnXs8qiUZJc9WDcWIeC3a2HIAMfw==} + engines: {node: '>=6'} + fast-fifo@1.3.2: resolution: {integrity: sha512-/d9sfos4yxzpwkDkuN7k2SqFKtYNmCTzgfEpz82x34IM9/zc8KGxQoXg1liNC/izpRM/MBdt44Nmx41ZWqk+FQ==} @@ -1808,6 +2043,9 @@ packages: get-port-please@3.1.2: resolution: {integrity: sha512-Gxc29eLs1fbn6LQ4jSU4vXjlwyZhF5HsGuMAa7gqBP4Rw4yxxltyDUuF5MBclFzDTXO+ACchGQoeela4DSfzdQ==} + get-source@2.0.12: + resolution: {integrity: sha512-X5+4+iD+HoSeEED+uwrQ07BOQr0kEDFMVqqpBuI+RaZBpBpHCuXxo70bjar6f0b0u/DQJsJ7ssurpP0V60Az+w==} + get-stream@6.0.1: resolution: {integrity: sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==} engines: {node: '>=10'} @@ -1824,6 +2062,9 @@ packages: resolution: {integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==} engines: {node: '>= 6'} + glob-to-regexp@0.4.1: + resolution: {integrity: sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==} + glob@10.3.12: resolution: {integrity: sha512-TCNv8vJ+xz4QiqTpfOJA7HvYv+tNIRHKfUWw/q+v2jdgN4ebz+KY9tGx5J4rHP0o84mNP+ApH66HRX8us3Khqg==} engines: {node: '>=16 || 14 >=14.17'} @@ -2104,6 +2345,9 @@ packages: peerDependencies: solid-js: ^1.4.7 + magic-string@0.25.9: + resolution: {integrity: sha512-RmF0AsMzgt25qzqqLc1+MbHmhdx0ojF2Fvs4XnOqz2ZOBXzzkEwc/dJQZCYHAn7v1jbVOjAZfK8msRn4BxO4VQ==} + magic-string@0.30.10: resolution: {integrity: sha512-iIRwTIf0QKV3UAnYK4PU8uiEc4SRh5jX0mwpIwETPpHdhVM4f53RSwS/vXvN1JhGX+Cs7B8qIq3d6AH49O5fAQ==} @@ -2155,6 +2399,11 @@ packages: resolution: {integrity: sha512-vqiC06CuhBTUdZH+RYl8sFrL096vA45Ok5ISO6sE/Mr1jRbGH4Csnhi8f3wKVl7x8mO4Au7Ir9D3Oyv1VYMFJw==} engines: {node: '>=12'} + miniflare@3.20241004.0: + resolution: {integrity: sha512-QSSmCR2V1AJnnpYwlyLXobKLSGiY1FlAiZYULMdGgOUThV7HJeSysDxsmPmrH+D4GQbmUERnmDdB6M6Rrz7uPg==} + engines: {node: '>=16.13'} + hasBin: true + minimatch@3.1.2: resolution: {integrity: sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==} @@ -2207,6 +2456,10 @@ packages: ms@2.1.3: resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==} + mustache@4.2.0: + resolution: {integrity: sha512-71ippSywq5Yb7/tVYyGbkBggbU8H3u5Rz56fH60jGFgr8uHwxs+aSKeqmluIVzM0m0kB7xQjKS6qPfd0b2ZoqQ==} + hasBin: true + nanoid@3.3.7: resolution: {integrity: sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==} engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} @@ -2287,6 +2540,9 @@ packages: ohash@1.1.3: resolution: {integrity: sha512-zuHHiGTYTA1sYJ/wZN+t5HKZaH23i4yI1HMwbuXm24Nid7Dv0KcuRlKoNKS9UNfAVSBlnGLcuQrnOKWOZoEGaw==} + ohash@1.1.4: + resolution: {integrity: sha512-FlDryZAahJmEF3VR3w1KogSEdWX3WhA5GPakFx4J81kEAiHyLMpdLLElS8n8dfNadMgAne/MywcvmogzscVt4g==} + on-finished@2.4.1: resolution: {integrity: sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==} engines: {node: '>= 0.8'} @@ -2355,6 +2611,9 @@ packages: path-to-regexp@6.2.2: resolution: {integrity: sha512-GQX3SSMokngb36+whdpRXE+3f9V8UzyAorlYvOGx87ufGHehNTn5lCxrKtLyZ4Yl/wEKnNnr98ZzOwwDZV5ogw==} + path-to-regexp@6.3.0: + resolution: {integrity: sha512-Yhpw4T9C6hPpgPeA28us07OJeqZ5EzQTkbfwuhsUg0c237RomFoETJgmp2sa3F/41gfLE6G5cqcYwznmeEeOlQ==} + path-type@5.0.0: resolution: {integrity: sha512-5HviZNaZcfqP95rwpv+1HDgUamezbqdSYTyzjTvwtJSnIH+3vnbmWsItli8OFEndS984VT55M3jduxZbX351gg==} engines: {node: '>=12'} @@ -2388,6 +2647,9 @@ packages: resolution: {integrity: sha512-mQUvGU6aUFQ+rNvTIAcZuWGRT9a6f6Yrg9bHs4ImKF+HZCEK+plBvnAZYSIQztknZF2qnzNtr6F8s0+IuptdlQ==} engines: {node: ^14.13.1 || >=16.0.0} + printable-characters@1.0.42: + resolution: {integrity: sha512-dKp+C4iXWK4vVYZmYSd0KBH5F/h1HoZRsbJ82AVKRO3PEo8L4lBS/vLwhVtpwwuYcoIsVY+1JYKR268yn480uQ==} + process-nextick-args@2.0.1: resolution: {integrity: sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==} @@ -2455,6 +2717,10 @@ packages: resolution: {integrity: sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==} engines: {node: '>=8'} + resolve.exports@2.0.2: + resolution: {integrity: sha512-X2UW6Nw3n/aMgDVy+0rSqgHlv39WZAlZrXCdnbyEiKm17DSqHX4MmQMaST3FbeWR5FTuRcUwYAziZajji0Y7mg==} + engines: {node: '>=10'} + resolve@1.22.8: resolution: {integrity: sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==} hasBin: true @@ -2467,6 +2733,13 @@ packages: resolution: {integrity: sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==} hasBin: true + rollup-plugin-inject@3.0.2: + resolution: {integrity: sha512-ptg9PQwzs3orn4jkgXJ74bfs5vYz1NCZlSQMBUA0wKcGp5i5pA1AO3fOUEte8enhGUC+iapTCzEWw2jEFFUO/w==} + deprecated: This package has been deprecated and is no longer maintained. Please use @rollup/plugin-inject. + + rollup-plugin-node-polyfills@0.2.1: + resolution: {integrity: sha512-4kCrKPTJ6sK4/gLL/U5QzVT8cxJcofO0OU74tnB19F40cmuAKSzH5/siithxlofFEjwvw1YAhPmbvGNA6jEroA==} + rollup-plugin-visualizer@5.12.0: resolution: {integrity: sha512-8/NU9jXcHRs7Nnj07PF2o4gjxmm9lXIrZ8r175bT9dK8qoLlvKTwRMArRCMgpMGlq8CTLugRvEmyMeMXIU2pNQ==} engines: {node: '>=14'} @@ -2477,6 +2750,9 @@ packages: rollup: optional: true + rollup-pluginutils@2.8.2: + resolution: {integrity: sha512-EEp9NhnUkwY8aif6bxgovPHMoMoNr2FulJziTndpt5H9RdwC47GSGuII9XxpSdzVGM0GWrNPHV6ie1LTNJPaLQ==} + rollup@4.17.2: resolution: {integrity: sha512-/9ClTJPByC0U4zNLowV1tMBe8yMEAxewtR3cUNX5BoEpGH3dQEWpJLr6CLp0fPdYRF/fzVOgvDb1zXuakwF5kQ==} engines: {node: '>=18.0.0', npm: '>=8.0.0'} @@ -2498,6 +2774,10 @@ packages: scule@1.3.0: resolution: {integrity: sha512-6FtHJEvt+pVMIB9IBY+IcCJ6Z5f1iQnytgyfKMhDKgmzYG+TeH/wx1y3l27rshSbLiSanrR9ffZDrEsmjlQF2g==} + selfsigned@2.4.1: + resolution: {integrity: sha512-th5B4L2U+eGLq1TVh7zNRGBapioSORUeymIydxgFpwww9d2qyKvtuPU2jJuHvYAwwqi2Y596QBL3eEqcPEYL8Q==} + engines: {node: '>=10'} + semver@6.3.1: resolution: {integrity: sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==} hasBin: true @@ -2622,9 +2902,16 @@ packages: resolution: {integrity: sha512-l3BikUxvPOcn5E74dZiq5BGsTb5yEwhaTSzccU6t4sDOH8NWJCstKO5QT2CvtFoK6F0saL7p9xHAqHOlCPJygA==} engines: {node: '>= 8'} + sourcemap-codec@1.4.8: + resolution: {integrity: sha512-9NykojV5Uih4lgo5So5dtw+f0JgJX30KCNI8gwhz2J9A15wD0Ml6tjHKwf6fTSa6fAdVBdZeNOs9eJ71qCk8vA==} + deprecated: Please use @jridgewell/sourcemap-codec instead + stackframe@1.3.4: resolution: {integrity: sha512-oeVtt7eWQS+Na6F//S4kJ2K2VbRlS9D43mAlMyVpVWovy9o+jfgH8O9agzANzaiLjclA0oYzUXEM4PurhSUChw==} + stacktracey@2.1.8: + resolution: {integrity: sha512-Kpij9riA+UNg7TnphqjH7/CzctQ/owJGNbFkfEeve4Z4uxT5+JapVLFXcsurIfN34gnTWZNJ/f7NMG0E8JDzTw==} + standard-as-callback@2.1.0: resolution: {integrity: sha512-qoRRSyROncaz1z0mvYqIE4lCd9p2R90i6GxW3uZv5ucSu8tU7B5HXUP1gG8pVZsYNVaXjk8ClXHPttLyxAL48A==} @@ -2635,6 +2922,10 @@ packages: std-env@3.7.0: resolution: {integrity: sha512-JPbdCEQLj1w5GilpiHAx3qJvFndqybBysA3qUOnznweH4QbNYUsW/ea8QzSrnh0vNsezMMw5bcVool8lM0gwzg==} + stoppable@1.1.0: + resolution: {integrity: sha512-KXDYZ9dszj6bzvnEMRYvxgeTHU74QBFL54XKtP3nyMuJ81CFYtABZ3bAzL2EdFUaEwJOBOgENyFj3R7oTzDyyw==} + engines: {node: '>=4', npm: '>=6'} + streamx@2.16.1: resolution: {integrity: sha512-m9QYj6WygWyWa3H1YY69amr4nVgy61xfjys7xO7kviL5rfIEc2naf+ewFiOA+aEJD7y0JO3h2GoiUv4TDwEGzQ==} @@ -2755,6 +3046,9 @@ packages: ufo@1.5.3: resolution: {integrity: sha512-Y7HYmWaFwPUmkoQCUIAYpKqkOf+SbVj/2fJJZ4RJMCfZp0rTGwRbzQD+HghfnhKOjL9E01okqz+ncJskGYfBNw==} + ufo@1.5.4: + resolution: {integrity: sha512-UsUk3byDzKd04EyoZ7U4DOlxQaD14JUKQl6/P7wiX4FNvUfm3XL246n9W5AmqwW5RSFJ27NAuM0iLscAOYUiGQ==} + unconfig@0.3.13: resolution: {integrity: sha512-N9Ph5NC4+sqtcOjPfHrRcHekBCadCXWTBzp2VYYbySOHW0PfD9XLCeXshTXjkPYwLrBr9AtSeU0CZmkYECJhng==} @@ -2774,6 +3068,9 @@ packages: resolution: {integrity: sha512-72RFADWFqKmUb2hmmvNODKL3p9hcB6Gt2DOQMis1SEBaV6a4MH8soBvzg+95CYhCKPFedut2JY9bMfrDl9D23g==} engines: {node: '>=14.0'} + unenv-nightly@2.0.0-20241009-125958-e8ea22f: + resolution: {integrity: sha512-hRxmKz1iSVRmuFx/vBdPsx7rX4o7Cas9vdjDNeUeWpQTK2LzU3Xy3Jz0zbo7MJX0bpqo/LEFCA+GPwsbl6zKEQ==} + unenv@1.9.0: resolution: {integrity: sha512-QKnFNznRxmbOF1hDgzpqrlIf6NC5sbZ2OJ+5Wl3OX8uM+LUJXbj4TXvLJCtwbPTmbMHCLIz6JLKNinNsMShK9g==} @@ -2973,6 +3270,21 @@ packages: resolution: {integrity: sha512-o0cyEG0e8GPzT4iGHphIOh0cJOV8fivsXxddQasHPHfoZf1ZexrfeA21w2NaEN1RHE+fXlfISmOE8R9N3u3Qig==} engines: {node: '>=12'} + workerd@1.20241004.0: + resolution: {integrity: sha512-TCFJ7Zw7svR3adg1fnlPWj/yXhjBnQloLEIJqdu57hli/GsgwlbomwrbM3mdMgbS+K9zYeaYqknXiBN0EXk3QQ==} + engines: {node: '>=16'} + hasBin: true + + wrangler@3.80.4: + resolution: {integrity: sha512-DyNvShtVH3k7ZyBndlIiwyRDXqtHr3g01hxwn4FfwKlAaT6EL0wb3KL3UGbsdpeM/xbJiUQxFQ4WuFBWgZS18Q==} + engines: {node: '>=16.17.0'} + hasBin: true + peerDependencies: + '@cloudflare/workers-types': ^4.20241004.0 + peerDependenciesMeta: + '@cloudflare/workers-types': + optional: true + wrap-ansi@7.0.0: resolution: {integrity: sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==} engines: {node: '>=10'} @@ -2984,6 +3296,21 @@ packages: wrappy@1.0.2: resolution: {integrity: sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==} + ws@8.18.0: + resolution: {integrity: sha512-8VbfWfHLbbwu3+N6OKsOMpBdT4kXPDDB9cJk2bJ6mh9ucxdlnNvH1e+roYkKmN9Nxw2yjz7VzeO9oOz2zJ04Pw==} + engines: {node: '>=10.0.0'} + peerDependencies: + bufferutil: ^4.0.1 + utf-8-validate: '>=5.0.2' + peerDependenciesMeta: + bufferutil: + optional: true + utf-8-validate: + optional: true + + xxhash-wasm@1.0.2: + resolution: {integrity: sha512-ibF0Or+FivM9lNrg+HGJfVX8WJqgo+kCLDc4vx6xMeTce7Aj+DLttKbxxRR/gNLSAelRc1omAPlJ77N/Jem07A==} + y18n@5.0.8: resolution: {integrity: sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==} engines: {node: '>=10'} @@ -3006,6 +3333,9 @@ packages: resolution: {integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==} engines: {node: '>=10'} + youch@3.3.4: + resolution: {integrity: sha512-UeVBXie8cA35DS6+nBkls68xaBBXCye0CNznrhszZjTbRVnJKQuNsyLKBTTL4ln1o1rh2PKtv35twV7irj5SEg==} + zip-stream@6.0.1: resolution: {integrity: sha512-zK7YHHz4ZXpW89AHXUPbQVGKI7uvkd3hzusTdotCg1UxyaVtg0zFJSTfW/Dq5f7OBBVnq6cZIaC8Ti4hb6dtCA==} engines: {node: '>= 14'} @@ -3233,6 +3563,32 @@ snapshots: dependencies: mime: 3.0.0 + '@cloudflare/kv-asset-handler@0.3.4': + dependencies: + mime: 3.0.0 + + '@cloudflare/workerd-darwin-64@1.20241004.0': + optional: true + + '@cloudflare/workerd-darwin-arm64@1.20241004.0': + optional: true + + '@cloudflare/workerd-linux-64@1.20241004.0': + optional: true + + '@cloudflare/workerd-linux-arm64@1.20241004.0': + optional: true + + '@cloudflare/workerd-windows-64@1.20241004.0': + optional: true + + '@cloudflare/workers-shared@0.6.0': + dependencies: + mime: 3.0.0 + zod: 3.23.8 + + '@cloudflare/workers-types@4.20241011.0': {} + '@codemirror/autocomplete@6.16.3(@codemirror/language@6.10.2)(@codemirror/state@6.4.1)(@codemirror/view@6.28.3)(@lezer/common@1.2.1)': dependencies: '@codemirror/language': 6.10.2 @@ -3302,6 +3658,10 @@ snapshots: '@floating-ui/dom': 1.6.7 solid-js: 1.9.2 + '@cspotcode/source-map-support@0.8.1': + dependencies: + '@jridgewell/trace-mapping': 0.3.9 + '@deno/shim-deno-test@0.5.0': {} '@deno/shim-deno@0.19.1': @@ -3309,135 +3669,211 @@ snapshots: '@deno/shim-deno-test': 0.5.0 which: 4.0.0 + '@esbuild-plugins/node-globals-polyfill@0.2.3(esbuild@0.17.19)': + dependencies: + esbuild: 0.17.19 + + '@esbuild-plugins/node-modules-polyfill@0.2.2(esbuild@0.17.19)': + dependencies: + esbuild: 0.17.19 + escape-string-regexp: 4.0.0 + rollup-plugin-node-polyfills: 0.2.1 + '@esbuild/aix-ppc64@0.20.2': optional: true + '@esbuild/android-arm64@0.17.19': + optional: true + '@esbuild/android-arm64@0.18.20': optional: true '@esbuild/android-arm64@0.20.2': optional: true + '@esbuild/android-arm@0.17.19': + optional: true + '@esbuild/android-arm@0.18.20': optional: true '@esbuild/android-arm@0.20.2': optional: true + '@esbuild/android-x64@0.17.19': + optional: true + '@esbuild/android-x64@0.18.20': optional: true '@esbuild/android-x64@0.20.2': optional: true + '@esbuild/darwin-arm64@0.17.19': + optional: true + '@esbuild/darwin-arm64@0.18.20': optional: true '@esbuild/darwin-arm64@0.20.2': optional: true + '@esbuild/darwin-x64@0.17.19': + optional: true + '@esbuild/darwin-x64@0.18.20': optional: true '@esbuild/darwin-x64@0.20.2': optional: true + '@esbuild/freebsd-arm64@0.17.19': + optional: true + '@esbuild/freebsd-arm64@0.18.20': optional: true '@esbuild/freebsd-arm64@0.20.2': optional: true + '@esbuild/freebsd-x64@0.17.19': + optional: true + '@esbuild/freebsd-x64@0.18.20': optional: true '@esbuild/freebsd-x64@0.20.2': optional: true + '@esbuild/linux-arm64@0.17.19': + optional: true + '@esbuild/linux-arm64@0.18.20': optional: true '@esbuild/linux-arm64@0.20.2': optional: true + '@esbuild/linux-arm@0.17.19': + optional: true + '@esbuild/linux-arm@0.18.20': optional: true '@esbuild/linux-arm@0.20.2': optional: true + '@esbuild/linux-ia32@0.17.19': + optional: true + '@esbuild/linux-ia32@0.18.20': optional: true '@esbuild/linux-ia32@0.20.2': optional: true + '@esbuild/linux-loong64@0.17.19': + optional: true + '@esbuild/linux-loong64@0.18.20': optional: true '@esbuild/linux-loong64@0.20.2': optional: true + '@esbuild/linux-mips64el@0.17.19': + optional: true + '@esbuild/linux-mips64el@0.18.20': optional: true '@esbuild/linux-mips64el@0.20.2': optional: true + '@esbuild/linux-ppc64@0.17.19': + optional: true + '@esbuild/linux-ppc64@0.18.20': optional: true '@esbuild/linux-ppc64@0.20.2': optional: true + '@esbuild/linux-riscv64@0.17.19': + optional: true + '@esbuild/linux-riscv64@0.18.20': optional: true '@esbuild/linux-riscv64@0.20.2': optional: true + '@esbuild/linux-s390x@0.17.19': + optional: true + '@esbuild/linux-s390x@0.18.20': optional: true '@esbuild/linux-s390x@0.20.2': optional: true + '@esbuild/linux-x64@0.17.19': + optional: true + '@esbuild/linux-x64@0.18.20': optional: true '@esbuild/linux-x64@0.20.2': optional: true + '@esbuild/netbsd-x64@0.17.19': + optional: true + '@esbuild/netbsd-x64@0.18.20': optional: true '@esbuild/netbsd-x64@0.20.2': optional: true + '@esbuild/openbsd-x64@0.17.19': + optional: true + '@esbuild/openbsd-x64@0.18.20': optional: true '@esbuild/openbsd-x64@0.20.2': optional: true + '@esbuild/sunos-x64@0.17.19': + optional: true + '@esbuild/sunos-x64@0.18.20': optional: true '@esbuild/sunos-x64@0.20.2': optional: true + '@esbuild/win32-arm64@0.17.19': + optional: true + '@esbuild/win32-arm64@0.18.20': optional: true '@esbuild/win32-arm64@0.20.2': optional: true + '@esbuild/win32-ia32@0.17.19': + optional: true + '@esbuild/win32-ia32@0.18.20': optional: true '@esbuild/win32-ia32@0.20.2': optional: true + '@esbuild/win32-x64@0.17.19': + optional: true + '@esbuild/win32-x64@0.18.20': optional: true @@ -3512,6 +3948,11 @@ snapshots: '@jridgewell/resolve-uri': 3.1.2 '@jridgewell/sourcemap-codec': 1.4.15 + '@jridgewell/trace-mapping@0.3.9': + dependencies: + '@jridgewell/resolve-uri': 3.1.2 + '@jridgewell/sourcemap-codec': 1.4.15 + '@kobalte/core@0.13.4(solid-js@1.9.2)': dependencies: '@floating-ui/dom': 1.6.7 @@ -4009,6 +4450,10 @@ snapshots: dependencies: '@types/braces': 3.0.4 + '@types/node-forge@1.3.11': + dependencies: + '@types/node': 20.12.8 + '@types/node@20.12.8': dependencies: undici-types: 5.26.5 @@ -4265,6 +4710,10 @@ snapshots: dependencies: acorn: 8.11.3 + acorn-walk@8.3.4: + dependencies: + acorn: 8.11.3 + acorn@8.11.3: {} agent-base@6.0.2: @@ -4327,6 +4776,10 @@ snapshots: argparse@2.0.1: {} + as-table@1.0.55: + dependencies: + printable-characters: 1.0.42 + ast-types@0.16.1: dependencies: tslib: 2.6.2 @@ -4368,6 +4821,8 @@ snapshots: dependencies: file-uri-to-path: 1.0.0 + blake3-wasm@2.1.5: {} + boxen@7.1.1: dependencies: ansi-align: 3.0.1 @@ -4427,7 +4882,7 @@ snapshots: giget: 1.2.3 jiti: 1.21.0 mlly: 1.7.0 - ohash: 1.1.3 + ohash: 1.1.4 pathe: 1.1.2 perfect-debounce: 1.0.0 pkg-types: 1.1.0 @@ -4439,6 +4894,13 @@ snapshots: caniuse-lite@1.0.30001615: {} + capnp-ts@0.7.0: + dependencies: + debug: 4.3.4 + tslib: 2.6.2 + transitivePeerDependencies: + - supports-color + chalk@2.4.2: dependencies: ansi-styles: 3.2.1 @@ -4538,6 +5000,8 @@ snapshots: cookie-es@1.1.0: {} + cookie@0.7.2: {} + core-util-is@1.0.3: {} crc-32@1.2.2: {} @@ -4566,6 +5030,8 @@ snapshots: csstype@3.1.3: {} + data-uri-to-buffer@2.0.2: {} + dax-sh@0.39.2: dependencies: '@deno/shim-deno': 0.19.1 @@ -4643,6 +5109,31 @@ snapshots: es-module-lexer@1.5.2: {} + esbuild@0.17.19: + optionalDependencies: + '@esbuild/android-arm': 0.17.19 + '@esbuild/android-arm64': 0.17.19 + '@esbuild/android-x64': 0.17.19 + '@esbuild/darwin-arm64': 0.17.19 + '@esbuild/darwin-x64': 0.17.19 + '@esbuild/freebsd-arm64': 0.17.19 + '@esbuild/freebsd-x64': 0.17.19 + '@esbuild/linux-arm': 0.17.19 + '@esbuild/linux-arm64': 0.17.19 + '@esbuild/linux-ia32': 0.17.19 + '@esbuild/linux-loong64': 0.17.19 + '@esbuild/linux-mips64el': 0.17.19 + '@esbuild/linux-ppc64': 0.17.19 + '@esbuild/linux-riscv64': 0.17.19 + '@esbuild/linux-s390x': 0.17.19 + '@esbuild/linux-x64': 0.17.19 + '@esbuild/netbsd-x64': 0.17.19 + '@esbuild/openbsd-x64': 0.17.19 + '@esbuild/sunos-x64': 0.17.19 + '@esbuild/win32-arm64': 0.17.19 + '@esbuild/win32-ia32': 0.17.19 + '@esbuild/win32-x64': 0.17.19 + esbuild@0.18.20: optionalDependencies: '@esbuild/android-arm': 0.18.20 @@ -4700,10 +5191,14 @@ snapshots: escape-string-regexp@1.0.5: {} + escape-string-regexp@4.0.0: {} + escape-string-regexp@5.0.0: {} esprima@4.0.1: {} + estree-walker@0.6.1: {} + estree-walker@2.0.2: {} estree-walker@3.0.3: @@ -4754,6 +5249,8 @@ snapshots: signal-exit: 4.1.0 strip-final-newline: 3.0.0 + exit-hook@2.2.1: {} + fast-fifo@1.3.2: {} fast-glob@3.3.2: @@ -4831,6 +5328,11 @@ snapshots: get-port-please@3.1.2: {} + get-source@2.0.12: + dependencies: + data-uri-to-buffer: 2.0.2 + source-map: 0.6.1 + get-stream@6.0.1: {} get-stream@8.0.1: {} @@ -4842,7 +5344,7 @@ snapshots: defu: 6.1.4 node-fetch-native: 1.6.4 nypm: 0.3.8 - ohash: 1.1.3 + ohash: 1.1.4 pathe: 1.1.2 tar: 6.2.1 @@ -4850,6 +5352,8 @@ snapshots: dependencies: is-glob: 4.0.3 + glob-to-regexp@0.4.1: {} + glob@10.3.12: dependencies: foreground-child: 3.1.1 @@ -5102,7 +5606,7 @@ snapshots: node-forge: 1.3.1 pathe: 1.1.2 std-env: 3.7.0 - ufo: 1.5.3 + ufo: 1.5.4 untun: 0.1.3 uqr: 0.1.2 transitivePeerDependencies: @@ -5139,6 +5643,10 @@ snapshots: dependencies: solid-js: 1.9.2 + magic-string@0.25.9: + dependencies: + sourcemap-codec: 1.4.8 + magic-string@0.30.10: dependencies: '@jridgewell/sourcemap-codec': 1.4.15 @@ -5178,6 +5686,25 @@ snapshots: mimic-fn@4.0.0: {} + miniflare@3.20241004.0: + dependencies: + '@cspotcode/source-map-support': 0.8.1 + acorn: 8.11.3 + acorn-walk: 8.3.4 + capnp-ts: 0.7.0 + exit-hook: 2.2.1 + glob-to-regexp: 0.4.1 + stoppable: 1.1.0 + undici: 5.28.4 + workerd: 1.20241004.0 + ws: 8.18.0 + youch: 3.3.4 + zod: 3.23.8 + transitivePeerDependencies: + - bufferutil + - supports-color + - utf-8-validate + minimatch@3.1.2: dependencies: brace-expansion: 1.1.11 @@ -5222,6 +5749,8 @@ snapshots: ms@2.1.3: {} + mustache@4.2.0: {} + nanoid@3.3.7: {} narrowing@1.5.0: {} @@ -5357,7 +5886,7 @@ snapshots: consola: 3.2.3 execa: 8.0.1 pathe: 1.1.2 - ufo: 1.5.3 + ufo: 1.5.4 object-assign@4.1.1: {} @@ -5369,6 +5898,8 @@ snapshots: ohash@1.1.3: {} + ohash@1.1.4: {} + on-finished@2.4.1: dependencies: ee-first: 1.1.1 @@ -5436,6 +5967,8 @@ snapshots: path-to-regexp@6.2.2: {} + path-to-regexp@6.3.0: {} + path-type@5.0.0: {} pathe@1.1.2: {} @@ -5462,6 +5995,8 @@ snapshots: pretty-bytes@6.1.1: {} + printable-characters@1.0.42: {} + process-nextick-args@2.0.1: {} process@0.11.10: {} @@ -5535,6 +6070,8 @@ snapshots: resolve-from@5.0.0: {} + resolve.exports@2.0.2: {} + resolve@1.22.8: dependencies: is-core-module: 2.13.1 @@ -5547,6 +6084,16 @@ snapshots: dependencies: glob: 7.2.3 + rollup-plugin-inject@3.0.2: + dependencies: + estree-walker: 0.6.1 + magic-string: 0.25.9 + rollup-pluginutils: 2.8.2 + + rollup-plugin-node-polyfills@0.2.1: + dependencies: + rollup-plugin-inject: 3.0.2 + rollup-plugin-visualizer@5.12.0(rollup@4.17.2): dependencies: open: 8.4.2 @@ -5556,6 +6103,10 @@ snapshots: optionalDependencies: rollup: 4.17.2 + rollup-pluginutils@2.8.2: + dependencies: + estree-walker: 0.6.1 + rollup@4.17.2: dependencies: '@types/estree': 1.0.5 @@ -5592,6 +6143,11 @@ snapshots: scule@1.3.0: {} + selfsigned@2.4.1: + dependencies: + '@types/node-forge': 1.3.11 + node-forge: 1.3.1 + semver@6.3.1: {} semver@7.6.0: @@ -5715,14 +6271,23 @@ snapshots: source-map@0.7.4: {} + sourcemap-codec@1.4.8: {} + stackframe@1.3.4: {} + stacktracey@2.1.8: + dependencies: + as-table: 1.0.55 + get-source: 2.0.12 + standard-as-callback@2.1.0: {} statuses@2.0.1: {} std-env@3.7.0: {} + stoppable@1.1.0: {} + streamx@2.16.1: dependencies: fast-fifo: 1.3.2 @@ -5835,6 +6400,8 @@ snapshots: ufo@1.5.3: {} + ufo@1.5.4: {} + unconfig@0.3.13: dependencies: '@antfu/utils': 0.7.7 @@ -5858,6 +6425,13 @@ snapshots: dependencies: '@fastify/busboy': 2.1.1 + unenv-nightly@2.0.0-20241009-125958-e8ea22f: + dependencies: + defu: 6.1.4 + ohash: 1.1.4 + pathe: 1.1.2 + ufo: 1.5.4 + unenv@1.9.0: dependencies: consola: 3.2.3 @@ -6116,6 +6690,41 @@ snapshots: dependencies: string-width: 5.1.2 + workerd@1.20241004.0: + optionalDependencies: + '@cloudflare/workerd-darwin-64': 1.20241004.0 + '@cloudflare/workerd-darwin-arm64': 1.20241004.0 + '@cloudflare/workerd-linux-64': 1.20241004.0 + '@cloudflare/workerd-linux-arm64': 1.20241004.0 + '@cloudflare/workerd-windows-64': 1.20241004.0 + + wrangler@3.80.4(@cloudflare/workers-types@4.20241011.0): + dependencies: + '@cloudflare/kv-asset-handler': 0.3.4 + '@cloudflare/workers-shared': 0.6.0 + '@esbuild-plugins/node-globals-polyfill': 0.2.3(esbuild@0.17.19) + '@esbuild-plugins/node-modules-polyfill': 0.2.2(esbuild@0.17.19) + blake3-wasm: 2.1.5 + chokidar: 3.6.0 + esbuild: 0.17.19 + miniflare: 3.20241004.0 + nanoid: 3.3.7 + path-to-regexp: 6.3.0 + resolve: 1.22.8 + resolve.exports: 2.0.2 + selfsigned: 2.4.1 + source-map: 0.6.1 + unenv: unenv-nightly@2.0.0-20241009-125958-e8ea22f + workerd: 1.20241004.0 + xxhash-wasm: 1.0.2 + optionalDependencies: + '@cloudflare/workers-types': 4.20241011.0 + fsevents: 2.3.3 + transitivePeerDependencies: + - bufferutil + - supports-color + - utf-8-validate + wrap-ansi@7.0.0: dependencies: ansi-styles: 4.3.0 @@ -6130,6 +6739,10 @@ snapshots: wrappy@1.0.2: {} + ws@8.18.0: {} + + xxhash-wasm@1.0.2: {} + y18n@5.0.8: {} yallist@3.1.1: {} @@ -6150,6 +6763,12 @@ snapshots: yocto-queue@0.1.0: {} + youch@3.3.4: + dependencies: + cookie: 0.7.2 + mustache: 4.2.0 + stacktracey: 2.1.8 + zip-stream@6.0.1: dependencies: archiver-utils: 5.0.2 diff --git a/src/app.css b/src/app.css index 751be9a..5b1a017 100644 --- a/src/app.css +++ b/src/app.css @@ -1,4 +1,4 @@ -.checkboard { +.checkerboard { background-image: repeating-conic-gradient(#ddd 0% 25%, #aaa 25% 50%); background-position: 50%; background-size: 10% 10%; diff --git a/src/components/SplitButton.tsx b/src/components/SplitButton.tsx index 679d667..dc1a593 100644 --- a/src/components/SplitButton.tsx +++ b/src/components/SplitButton.tsx @@ -10,6 +10,7 @@ type Props = { onPng: (resizeWidth, resizeHeight) => void; onSvg: () => void; compact: boolean; + disabled: boolean; }; export function SplitButton(props: Props) { const [customWidth, setCustomWidth] = createSignal(1000); @@ -27,14 +28,18 @@ export function SplitButton(props: Props) { return (
- + void; placeholder?: string; + onFocus: () => void; + onBlur: () => void; + ref: HTMLTextAreaElement | ((el: HTMLTextAreaElement) => void); }; /** No `value` prop b/c textarea cannot be controlled */ @@ -13,6 +16,9 @@ export function TextareaInput(props: TextareaProps) { class="bg-back-subtle min-h-[41.6px] px-3 py-2 rounded-md border focus:(outline-none ring-2 ring-fore-base ring-offset-2 ring-offset-back-base) placeholder:text-fore-subtle" onInput={(e) => onInput(e.target.value)} onChange={(e) => props.setValue(e.target.value)} + onFocus={props.onFocus} + onBlur={props.onBlur} + ref={props.ref} placeholder={props.placeholder} > ); @@ -24,7 +30,7 @@ type InputProps = { onInput: (s: string) => void; ref?: HTMLInputElement; class?: string; - onKeyDown?: (e: KeyboardEvent) => void + onKeyDown?: (e: KeyboardEvent) => void; }; /** UNCONTROLLED */ diff --git a/src/components/editor/QrEditor.tsx b/src/components/editor/QrEditor.tsx index f6d2c9b..3eb7b7f 100644 --- a/src/components/editor/QrEditor.tsx +++ b/src/components/editor/QrEditor.tsx @@ -25,6 +25,9 @@ import "virtual:blob-rewriter"; type Props = { class?: string; + onTextFocus: () => void; + onTextBlur: () => void; + textRef: (ref: HTMLTextAreaElement) => void; }; const FUNC_KEYS = "funcKeys"; @@ -288,6 +291,9 @@ export function Editor(props: Props) { setInputQr("text", s || "https://qrframe.kylezhe.ng")} + onFocus={props.onTextFocus} + onBlur={props.onTextBlur} + ref={props.textRef} /> diff --git a/src/components/preview/QrPreview.tsx b/src/components/preview/QrPreview.tsx index c336252..1ddbee3 100644 --- a/src/components/preview/QrPreview.tsx +++ b/src/components/preview/QrPreview.tsx @@ -1,9 +1,8 @@ -import { QrError } from "fuqr"; import Download from "lucide-solid/icons/download"; import Share2 from "lucide-solid/icons/share-2"; import Info from "lucide-solid/icons/info"; -import { Match, Show, Switch, type JSX } from "solid-js"; -import { useQrContext, type OutputQr } from "~/lib/QrContext"; +import { Match, onCleanup, Show, Switch, type JSX } from "solid-js"; +import { QrState, useQrContext } from "~/lib/QrContext"; import { ECL_LABELS, ECL_NAMES, @@ -20,48 +19,73 @@ import { Popover } from "@kobalte/core/popover"; type Props = { classList: JSX.CustomAttributes["classList"]; compact: boolean; + ref: HTMLDivElement; }; export function QrPreview(props: Props) { - const { inputQr, outputQr } = useQrContext(); + const { inputQr, output } = useQrContext(); return ( -
- - - - Data exceeds max capacity - - - {`Input cannot be encoded in ${ - // @ts-expect-error props.mode not null b/c InvalidEncoding requires mode - MODE_NAMES[inputQr.mode + 1] - } mode`} - - -
- } - > -
+
+
+ + + + + + + + + + + Data exceeds max capacity + + + {`Input cannot be encoded in ${ + // @ts-expect-error props.mode not null b/c InvalidEncoding requires mode + MODE_NAMES[inputQr.mode + 1] + } mode`} + + +
+ } + > -
- - - +
+ + +
); } function RenderedQrCode() { - const { render, error, addSvgParentRef, addCanvasRef } = useRenderContext(); + const { render, error, svgParentRefs, addSvgParentRef, canvasRefs, addCanvasRef } = useRenderContext(); + + let i = svgParentRefs.length + let j = canvasRefs.length + onCleanup(() => { + svgParentRefs.splice(i, 1) + canvasRefs.splice(j, 1) + }) + return ( <> -
+
OutputQr }; + const { output } = useQrContext(); return (
QR Metadata
-
-
- Version -
- {outputQr().version} ({outputQr().version * 4 + 17}x - {outputQr().version * 4 + 17} matrix) + +
+
+ Version +
+ {output().qr!.version} ({output().qr!.version * 4 + 17}x + {output().qr!.version * 4 + 17} matrix) +
+
+
+ Error tolerance{" "} +
+ {ECL_NAMES[output().qr!.ecl]} ({ECL_LABELS[output().qr!.ecl]}) +
+
+
+ Mask{" "} + + {MASK_KEY[output().qr!.mask]} + +
+
+ Encoding{" "} + + {MODE_KEY[output().qr!.mode]} +
-
- Error tolerance{" "} -
- {ECL_NAMES[outputQr().ecl]} ({ECL_LABELS[outputQr().ecl]}) -
-
-
- Mask{" "} - {MASK_KEY[outputQr().mask]} -
-
- Encoding{" "} - {MODE_KEY[outputQr().mode]} -
-
+
); } @@ -122,14 +152,14 @@ type DownloadProps = { }; function DownloadButtons(props: DownloadProps) { - const { outputQr } = useQrContext() as { outputQr: () => OutputQr }; + const { output } = useQrContext(); const { render, svgParentRefs, canvasRefs } = useRenderContext(); - const filename = () => outputQr().text.slice(0, 32); + const filename = () => output().qr!.text.slice(0, 32); const pngBlob = async (resizeWidth, resizeHeight) => { // 10px per module assuming 2 module margin - const minWidth = (outputQr().version * 4 + 17 + 4) * 10; + const minWidth = (output().qr!.version * 4 + 17 + 4) * 10; let outCanvas: HTMLCanvasElement; if (render()?.type === "canvas") { @@ -187,6 +217,8 @@ function DownloadButtons(props: DownloadProps) { URL.revokeObjectURL(url); }; + const disabled = () => output().state !== QrState.Ready; + return (
@@ -194,6 +226,7 @@ function DownloadButtons(props: DownloadProps) {
{ try { @@ -213,6 +246,7 @@ function DownloadButtons(props: DownloadProps) { @@ -222,6 +256,7 @@ function DownloadButtons(props: DownloadProps) { { let blob; @@ -259,7 +294,8 @@ function DownloadButtons(props: DownloadProps) { diff --git a/src/lib/QrContext.tsx b/src/lib/QrContext.tsx index d8efc93..41ac388 100644 --- a/src/lib/QrContext.tsx +++ b/src/lib/QrContext.tsx @@ -1,12 +1,22 @@ import { createContext, createMemo, + createSignal, useContext, type Accessor, type JSX, } from "solid-js"; -import { ECL, Mode, Mask, QrError, QrOptions, Version, generate } from "fuqr"; +import init, { + ECL, + Mode, + Mask, + QrError, + QrOptions, + Version, + generate, +} from "fuqr"; import { createStore, type SetStoreFunction } from "solid-js/store"; +import { isServer } from "solid-js/web"; type InputQr = { text: string; @@ -27,10 +37,37 @@ export type OutputQr = Readonly<{ matrix: Uint8Array; }>; +type Output = + | { + state: QrState.Ready; + qr: Readonly<{ + text: string; + version: number; + ecl: ECL; + mode: Mode; + mask: Mask; + matrix: Uint8Array; + }>; + } + | { + state: + | QrState.Loading + | QrState.InvalidEncoding + | QrState.ExceedsMaxCapacity; + qr: null; + }; + +export enum QrState { + InvalidEncoding = QrError.InvalidEncoding, + ExceedsMaxCapacity = QrError.ExceedsMaxCapacity, + Loading = 2, + Ready = 3, +} + export const QrContext = createContext<{ inputQr: InputQr; setInputQr: SetStoreFunction; - outputQr: Accessor; + output: Accessor; }>(); export function QrContextProvider(props: { children: JSX.Element }) { @@ -44,12 +81,24 @@ export function QrContextProvider(props: { children: JSX.Element }) { mask: null, }); - const outputQr = createMemo(() => { - // can't skip first render, b/c need to track deps + const [initDone, setInitDone] = createSignal(false); + + if (!isServer) { + init().then(() => { + setInitDone(true); + }); + } + + const output = createMemo(() => { + if (!initDone()) { + return { + state: QrState.Loading, + qr: null, + }; + } + try { // NOTE: WASM ptrs (QrOptions, Version) become null after leaving scope - // They can't be reused or stored - const qrOptions = new QrOptions() .min_version(new Version(inputQr.minVersion)) .strict_version(inputQr.strictVersion) @@ -59,11 +108,17 @@ export function QrContextProvider(props: { children: JSX.Element }) { .mode(inputQr.mode!); // null instead of undefined (wasm-pack type) return { - text: inputQr.text, - ...generate(inputQr.text, qrOptions), + state: QrState.Ready, + qr: { + text: inputQr.text, + ...generate(inputQr.text, qrOptions), + }, }; } catch (e) { - return e as QrError; + return { + state: e as QrState, + qr: null, + }; } }); @@ -72,7 +127,7 @@ export function QrContextProvider(props: { children: JSX.Element }) { value={{ inputQr, setInputQr, - outputQr, + output, }} > {props.children} diff --git a/src/lib/RenderContext.tsx b/src/lib/RenderContext.tsx index 9665205..d162474 100644 --- a/src/lib/RenderContext.tsx +++ b/src/lib/RenderContext.tsx @@ -10,7 +10,7 @@ import { import { createStore, unwrap, type SetStoreFunction } from "solid-js/store"; import { type Params, type ParamsSchema } from "./params"; import { clearToasts, toastError } from "~/components/ErrorToasts"; -import { useQrContext, type OutputQr } from "./QrContext"; +import { QrState, useQrContext, type OutputQr } from "./QrContext"; export const RenderContext = createContext<{ render: Accessor; @@ -46,7 +46,7 @@ type Render = { }; export function RenderContextProvider(props: { children: JSX.Element }) { - const { outputQr } = useQrContext(); + const { output } = useQrContext(); const [renderKey, setRenderKey] = createSignal("Square"); const [render, setRender] = createSignal(null); @@ -82,6 +82,7 @@ export function RenderContextProvider(props: { children: JSX.Element }) { // I could expose multiple versions of the set functions // but that seems much less maintainable that this createEffect(async () => { + if (output().state !== QrState.Ready) return const r = render(); // Track store without leaking extra params @@ -119,7 +120,7 @@ export function RenderContextProvider(props: { children: JSX.Element }) { worker!.postMessage({ type: r.type, url: r.url, - qr: outputQr(), + qr: output().qr, params: paramsCopy, timeoutId, }); diff --git a/src/routes/index.tsx b/src/routes/index.tsx index 609f11e..f3bace8 100644 --- a/src/routes/index.tsx +++ b/src/routes/index.tsx @@ -1,21 +1,23 @@ -import { clientOnly } from "@solidjs/start"; import { isServer, Portal } from "solid-js/web"; -import init from "fuqr"; import { Editor } from "~/components/editor/QrEditor"; import { ErrorToasts } from "~/components/ErrorToasts"; import { QrPreview } from "~/components/preview/QrPreview"; import { RenderContextProvider } from "~/lib/RenderContext"; import { createSignal, onCleanup } from "solid-js"; - -const QrContextProvider = clientOnly(async () => { - await init(); - return { - default: (await import("../lib/QrContext")).QrContextProvider, - }; -}); +import { QrContextProvider } from "~/lib/QrContext"; export default function Home() { + return ( + + + + + + ); +} + +function Temp() { // tracking mediaquery in js b/c rendering step draws to all mounted elements let desktop; if (isServer) { @@ -25,33 +27,79 @@ export default function Home() { const [matches, setMatches] = createSignal(mql.matches); const callback = (e) => setMatches(e.matches); mql.addEventListener("change", callback); + desktop = matches; + + const viewport = window.visualViewport!; + let prevHeight = viewport.height; + const detectMobileKeyboard = () => { + const prev = prevHeight; + prevHeight = viewport.height; + if (desktop() || !textFocused()) return; + if (viewport.height === prev) return; + if (viewport.height > prev) { + // closing mobile keyboard + textRef.blur(); + } + }; + viewport.addEventListener("resize", detectMobileKeyboard); + onCleanup(() => { mql.removeEventListener("change", callback); + window.removeEventListener("resize", detectMobileKeyboard); }); - desktop = matches; } + let qrPreview: HTMLDivElement; + let textRef: HTMLTextAreaElement; + + const [textFocused, setTextFocused] = createSignal(false); + const onFocus = () => { + setTextFocused(true); + }; + const onBlur = () => { + if (!desktop()) { + // firefox scrolls input behind sticky QrPreview + // adding/removing sticky + this scroll + animation + // gives roughly equivalent ux as chrome default + const before = `${qrPreview.getBoundingClientRect().top}px`; + qrPreview.animate([{ top: before }, { top: 0 }], { + // slow animation to prevent bounce + duration: 1000, + easing: "ease-out", + }); + window.scroll({ + top: 0, + left: 0, + behavior: "smooth", + }); + } + setTextFocused(false); + }; + return ( - - -
-
- - -
- - - -
-
-
+
+
+ (textRef = ref)} + /> + +
+ + + +
); } diff --git a/uno.config.ts b/uno.config.ts index f9cac2d..8e7624e 100644 --- a/uno.config.ts +++ b/uno.config.ts @@ -1,7 +1,7 @@ import { defineConfig } from "unocss"; import transformerVariantGroup from "@unocss/transformer-variant-group"; export default defineConfig({ - blocklist: ["m55"], + blocklist: ["m55", "resize"], transformers: [transformerVariantGroup()], theme: { colors: { diff --git a/wrangler.toml b/wrangler.toml new file mode 100644 index 0000000..2cbdc41 --- /dev/null +++ b/wrangler.toml @@ -0,0 +1,84 @@ +#:schema node_modules/wrangler/config-schema.json +name = "qrframe" +compatibility_date = "2024-10-11" +compatibility_flags = ["nodejs_compat"] +pages_build_output_dir = "./dist" + +# Automatically place your workloads in an optimal location to minimize latency. +# If you are running back-end logic in a Pages Function, running it closer to your back-end infrastructure +# rather than the end user may result in better performance. +# Docs: https://developers.cloudflare.com/pages/functions/smart-placement/#smart-placement +# [placement] +# mode = "smart" + +# Variable bindings. These are arbitrary, plaintext strings (similar to environment variables) +# Note: Use secrets to store sensitive data. +# Docs: https://developers.cloudflare.com/pages/functions/bindings/#environment-variables +# [vars] +# MY_VARIABLE = "production_value" + +# Bind the Workers AI model catalog. Run machine learning models, powered by serverless GPUs, on Cloudflare’s global network +# Docs: https://developers.cloudflare.com/pages/functions/bindings/#workers-ai +# [ai] +# binding = "AI" + +# Bind a D1 database. D1 is Cloudflare’s native serverless SQL database. +# Docs: https://developers.cloudflare.com/pages/functions/bindings/#d1-databases +# [[d1_databases]] +# binding = "MY_DB" +# database_name = "my-database" +# database_id = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx" + +# Bind a Durable Object. Durable objects are a scale-to-zero compute primitive based on the actor model. +# Durable Objects can live for as long as needed. Use these when you need a long-running "server", such as in realtime apps. +# Docs: https://developers.cloudflare.com/workers/runtime-apis/durable-objects +# [[durable_objects.bindings]] +# name = "MY_DURABLE_OBJECT" +# class_name = "MyDurableObject" +# script_name = 'my-durable-object' + +# Bind a KV Namespace. Use KV as persistent storage for small key-value pairs. +# Docs: https://developers.cloudflare.com/pages/functions/bindings/#kv-namespaces +# [[kv_namespaces]] +# binding = "MY_KV_NAMESPACE" +# id = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" + +# Bind a Queue producer. Use this binding to schedule an arbitrary task that may be processed later by a Queue consumer. +# Docs: https://developers.cloudflare.com/pages/functions/bindings/#queue-producers +# [[queues.producers]] +# binding = "MY_QUEUE" +# queue = "my-queue" + +# Bind an R2 Bucket. Use R2 to store arbitrarily large blobs of data, such as files. +# Docs: https://developers.cloudflare.com/pages/functions/bindings/#r2-buckets +# [[r2_buckets]] +# binding = "MY_BUCKET" +# bucket_name = "my-bucket" + +# Bind another Worker service. Use this binding to call another Worker without network overhead. +# Docs: https://developers.cloudflare.com/pages/functions/bindings/#service-bindings +# [[services]] +# binding = "MY_SERVICE" +# service = "my-service" + +# To use different bindings for preview and production environments, follow the examples below. +# When using environment-specific overrides for bindings, ALL bindings must be specified on a per-environment basis. +# Docs: https://developers.cloudflare.com/pages/functions/wrangler-configuration#environment-specific-overrides + +######## PREVIEW environment config ######## + +# [env.preview.vars] +# API_KEY = "xyz789" + +# [[env.preview.kv_namespaces]] +# binding = "MY_KV_NAMESPACE" +# id = "" + +######## PRODUCTION environment config ######## + +# [env.production.vars] +# API_KEY = "abc123" + +# [[env.production.kv_namespaces]] +# binding = "MY_KV_NAMESPACE" +# id = ""